Merge branch 'master' into i18n
authorCarl Hetherington <cth@carlh.net>
Thu, 28 Feb 2013 18:46:42 +0000 (18:46 +0000)
committerCarl Hetherington <cth@carlh.net>
Thu, 28 Feb 2013 18:46:42 +0000 (18:46 +0000)
TRANSLATORS [new file with mode: 0644]
i18n.py [new file with mode: 0644]
src/lib/film.cc
src/lib/transcode_job.cc
src/lib/wscript
src/tools/dvdomatic.cc
src/tools/wscript
src/wscript
src/wx/wscript
wscript

diff --git a/TRANSLATORS b/TRANSLATORS
new file mode 100644 (file)
index 0000000..cbfc875
--- /dev/null
@@ -0,0 +1,13 @@
+Translating DVD-o-matic
+-----------------------
+
+1.  Run ./waf po
+
+This will generate build/src/lib/dvdomatic.pot and build/src/wx/libdvdomatic-wx.pot.
+
+For each file:
+
+2.  Open poEdit, "New catalogue from POT file", do translations, save as .po file.
+
+3.  Send to me.
+
diff --git a/i18n.py b/i18n.py
new file mode 100644 (file)
index 0000000..10eaa38
--- /dev/null
+++ b/i18n.py
@@ -0,0 +1,27 @@
+import glob
+import os
+from waflib import Logs
+
+def pot(dir, sources, name):
+    s = ""
+    for f in sources.split('\n'):
+        t = f.strip()
+        if len(t) > 0:
+            s += (os.path.join(dir, t)) + " "
+
+    Logs.info('Making %s.pot' % os.path.join('build', dir, name))
+    os.system('xgettext -d %s -s --keyword=_ -p %s -o %s.pot %s' % (name, os.path.join('build', dir), name, s))
+    
+
+def po_to_mo(dir, name):
+    for f in glob.glob(os.path.join(dir, 'po', '*.po')):
+        
+        lang = os.path.basename(f).replace('.po', '')
+        out = os.path.join('build', dir, 'mo', lang, '%s.mo' % name)
+        try:
+            os.makedirs(os.path.dirname(out))
+        except:
+            pass
+
+        os.system('msgfmt %s -o %s' % (f, out))
+        Logs.info('%s -> %s' % (f, out))
index 1cf161259a92e6f5e66b8f4128af396e2a7f9886..addaa0852d33ba7d1c8defe36f48e00d5b8eaae4 100644 (file)
@@ -52,6 +52,8 @@
 #include "audio_decoder.h"
 #include "external_audio_decoder.h"
 
+#include "i18n.h"
+
 using std::string;
 using std::stringstream;
 using std::multimap;
@@ -244,7 +246,7 @@ Film::make_dcp ()
        set_dci_date_today ();
        
        if (dcp_name().find ("/") != string::npos) {
-               throw BadSettingError ("name", "cannot contain slashes");
+               throw BadSettingError ("name", _("cannot contain slashes"));
        }
        
        log()->log (String::compose ("DVD-o-matic %1 git %2 using %3", dvdomatic_version, dvdomatic_git_commit, dependency_version_summary()));
index 87e9a47c4b6ca678d5b7978f04471f91babe5ebe..a4279ef8bf0f619e723b75f5d69e48ca6137fe81 100644 (file)
@@ -30,6 +30,8 @@
 #include "log.h"
 #include "encoder.h"
 
+#include "i18n.h"
+
 using std::string;
 using std::stringstream;
 using std::fixed;
@@ -49,7 +51,7 @@ TranscodeJob::TranscodeJob (shared_ptr<Film> f, DecodeOptions o)
 string
 TranscodeJob::name () const
 {
-       return String::compose ("Transcode %1", _film->name());
+       return String::compose (_("Transcode %1"), _film->name());
 }
 
 void
@@ -98,7 +100,7 @@ TranscodeJob::status () const
        s << Job::status ();
 
        if (!finished ()) {
-               s << "; " << fixed << setprecision (1) << fps << " frames per second";
+               s << "; " << fixed << setprecision (1) << fps << " " << _("frames per second");
        }
        
        return s.str ();
index eee04190c1119c19510cdd6f551d712dbe4c0d6c..59047c70dd0ca75a88007a520425412f50c4f130 100644 (file)
@@ -1,3 +1,55 @@
+import os
+import i18n
+
+sources = """
+          ab_transcode_job.cc
+         ab_transcoder.cc
+          audio_decoder.cc
+          audio_source.cc
+          config.cc
+          combiner.cc
+          cross.cc
+          dci_metadata.cc
+          dcp_content_type.cc
+          dcp_video_frame.cc
+          decoder.cc
+          decoder_factory.cc
+          delay_line.cc
+          dolby_cp750.cc
+          encoder.cc
+          examine_content_job.cc
+          external_audio_decoder.cc
+          filter_graph.cc
+          ffmpeg_compatibility.cc
+          ffmpeg_decoder.cc
+          film.cc
+          filter.cc
+          format.cc
+          gain.cc
+          image.cc
+          imagemagick_decoder.cc
+          job.cc
+          job_manager.cc
+          log.cc
+          lut.cc
+          matcher.cc
+          scp_dcp_job.cc
+          scaler.cc
+          server.cc
+          sound_processor.cc
+          stream.cc
+          subtitle.cc
+          timer.cc
+          transcode_job.cc
+          transcoder.cc
+          ui_signaller.cc
+          util.cc
+          version.cc
+          video_decoder.cc
+          video_source.cc
+          writer.cc
+          """
+
 def build(bld):
     if bld.env.STATIC:
         obj = bld(features = 'cxx cxxstlib')
@@ -13,53 +65,8 @@ def build(bld):
                  """
     if bld.env.TARGET_WINDOWS:
         obj.uselib += ' WINSOCK2'
-    obj.source = """
-                ab_transcode_job.cc
-                ab_transcoder.cc
-                 audio_decoder.cc
-                 audio_source.cc
-                config.cc
-                 combiner.cc
-                 cross.cc
-                dci_metadata.cc
-                dcp_content_type.cc
-                dcp_video_frame.cc
-                 decoder.cc
-                 decoder_factory.cc
-                 delay_line.cc
-                 dolby_cp750.cc
-                encoder.cc
-                examine_content_job.cc
-                external_audio_decoder.cc
-                 filter_graph.cc
-                 ffmpeg_compatibility.cc
-                 ffmpeg_decoder.cc
-                film.cc
-                filter.cc
-                format.cc
-                 gain.cc
-                 image.cc
-                 imagemagick_decoder.cc
-                job.cc
-                job_manager.cc
-                log.cc
-                lut.cc
-                 matcher.cc
-                 scp_dcp_job.cc
-                scaler.cc
-                server.cc
-                 sound_processor.cc
-                 stream.cc
-                 subtitle.cc
-                 timer.cc
-                transcode_job.cc
-                transcoder.cc
-                 ui_signaller.cc
-                util.cc
-                version.cc
-                 video_decoder.cc
-                 video_source.cc
-                 writer.cc
-                """
-
+    obj.source = sources
     obj.target = 'dvdomatic'
+
+def pot(bld):
+    i18n.pot(os.path.join('src', 'lib'), sources, 'libdvdomatic')
index 1b76132f604931f4bada50fc7c23d50eb74048ba..d1760c327a1af2aef7cf18306028192e632fc430 100644 (file)
@@ -60,6 +60,7 @@ static shared_ptr<Film> film;
 static std::string log_level;
 static std::string film_to_load;
 static wxMenu* jobs_menu = 0;
+static wxLocale* locale = 0;
 
 static void set_menu_sensitivity ();
 
@@ -68,9 +69,12 @@ class FilmChangedDialog
 public:
        FilmChangedDialog ()
        {
-               stringstream s;
-               s << "Save changes to film \"" << film->name() << "\" before closing?";
-               _dialog = new wxMessageDialog (0, std_to_wx (s.str()), _("Film changed"), wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION);
+               _dialog = new wxMessageDialog (
+                       0,
+                       std_to_wx (String::compose ("Save changes to film \"%1\" before closing?", film->name())),
+                       _("Film changed"),
+                       wxYES_NO | wxYES_DEFAULT | wxICON_QUESTION
+                       );
        }
 
        ~FilmChangedDialog ()
@@ -117,9 +121,9 @@ enum Sensitivity {
 map<wxMenuItem*, Sensitivity> menu_items;
        
 void
-add_item (wxMenu* menu, std::string text, int id, Sensitivity sens)
+add_item (wxMenu* menu, wxString text, int id, Sensitivity sens)
 {
-       wxMenuItem* item = menu->Append (id, std_to_wx (text));
+       wxMenuItem* item = menu->Append (id, text);
        menu_items.insert (make_pair (item, sens));
 }
 
@@ -153,32 +157,32 @@ void
 setup_menu (wxMenuBar* m)
 {
        wxMenu* file = new wxMenu;
-       add_item (file, "New...", ID_file_new, ALWAYS);
-       add_item (file, "&Open...", ID_file_open, ALWAYS);
+       add_item (file, _("New..."), ID_file_new, ALWAYS);
+       add_item (file, _("&Open..."), ID_file_open, ALWAYS);
        file->AppendSeparator ();
-       add_item (file, "&Save", ID_file_save, NEEDS_FILM);
+       add_item (file, _("&Save"), ID_file_save, NEEDS_FILM);
        file->AppendSeparator ();
-       add_item (file, "&Properties...", ID_file_properties, NEEDS_FILM);
+       add_item (file, _("&Properties..."), ID_file_properties, NEEDS_FILM);
        file->AppendSeparator ();
-       add_item (file, "&Quit", ID_file_quit, ALWAYS);
+       add_item (file, _("&Quit"), ID_file_quit, ALWAYS);
 
        wxMenu* edit = new wxMenu;
-       add_item (edit, "&Preferences...", ID_edit_preferences, ALWAYS);
+       add_item (edit, _("&Preferences..."), ID_edit_preferences, ALWAYS);
 
        jobs_menu = new wxMenu;
-       add_item (jobs_menu, "&Make DCP", ID_jobs_make_dcp, NEEDS_FILM);
-       add_item (jobs_menu, "&Send DCP to TMS", ID_jobs_send_dcp_to_tms, NEEDS_FILM);
-       add_item (jobs_menu, "S&how DCP", ID_jobs_show_dcp, NEEDS_FILM);
+       add_item (jobs_menu, _("&Make DCP"), ID_jobs_make_dcp, NEEDS_FILM);
+       add_item (jobs_menu, _("&Send DCP to TMS"), ID_jobs_send_dcp_to_tms, NEEDS_FILM);
+       add_item (jobs_menu, _("S&how DCP"), ID_jobs_show_dcp, NEEDS_FILM);
        jobs_menu->AppendSeparator ();
-       add_item (jobs_menu, "&Examine content", ID_jobs_examine_content, NEEDS_FILM);
+       add_item (jobs_menu, _("&Examine content"), ID_jobs_examine_content, NEEDS_FILM);
 
        wxMenu* help = new wxMenu;
-       add_item (help, "About", ID_help_about, ALWAYS);
+       add_item (help, _("About"), ID_help_about, ALWAYS);
 
-       m->Append (file, _("&File"));
-       m->Append (edit, _("&Edit"));
-       m->Append (jobs_menu, _("&Jobs"));
-       m->Append (help, _("&Help"));
+       m->Append (file, _(_("&File")));
+       m->Append (edit, _(_("&Edit")));
+       m->Append (jobs_menu, _(_("&Jobs")));
+       m->Append (help, _(_("&Help")));
 }
 
 bool
@@ -280,7 +284,7 @@ private:
        void file_changed (string f)
        {
                stringstream s;
-               s << "DVD-o-matic";
+               s << _("DVD-o-matic");
                if (!f.empty ()) {
                        s << " - " << f;
                }
@@ -430,6 +434,35 @@ static const wxCmdLineEntryDesc command_line_description[] = {
 };
 #endif
 
+void
+setup_i18n ()
+{
+       int language = wxLANGUAGE_DEFAULT;
+       if (wxLocale::IsAvailable (language)) {
+               locale = new wxLocale (language, wxLOCALE_LOAD_DEFAULT);
+               
+#ifdef __WXGTK__
+               locale->AddCatalogLookupPathPrefix (wxT ("/usr"));
+               locale->AddCatalogLookupPathPrefix (wxT ("/usr/local"));
+               locale->AddCatalogLookupPathPrefix (wxT ("build/src/wx/mo"));
+               locale->AddCatalogLookupPathPrefix (wxT ("build/src/tools/mo"));
+               wxStandardPaths* paths = (wxStandardPaths*) &wxStandardPaths::Get();
+               wxString prefix = paths->GetInstallPrefix();
+               locale->AddCatalogLookupPathPrefix (prefix);
+#endif
+
+               locale->AddCatalog ("libdvdomatic-wx");
+               locale->AddCatalog ("dvdomatic");
+               
+               if (!locale->IsOk()) {
+                       delete locale;
+                       locale = new wxLocale (wxLANGUAGE_ENGLISH);
+                       language = wxLANGUAGE_ENGLISH;
+               }
+       }
+}
+
 class App : public wxApp
 {
        bool OnInit ()
@@ -443,6 +476,7 @@ class App : public wxApp
 #endif         
                
                wxInitAllImageHandlers ();
+               setup_i18n ();
                
                dvdomatic_setup ();
 
@@ -451,7 +485,7 @@ class App : public wxApp
                                film.reset (new Film (film_to_load));
                                film->log()->set_level (log_level);
                        } catch (exception& e) {
-                               error_dialog (0, std_to_wx (String::compose ("Could not load film %1 (%2)", film_to_load, e.what())));
+                               error_dialog (0, std_to_wx (String::compose (wx_to_std (_("Could not load film %1 (%2)")), film_to_load, e.what())));
                        }
                }
 
index c843c61d832050ac88d076a476eb349f3a0d5638..de130ce17fedbde2d89e02387358e3e284575ac8 100644 (file)
@@ -1,3 +1,8 @@
+import os
+import glob
+from waflib import Logs
+import i18n
+
 def build(bld):
     for t in ['makedcp', 'servomatic_cli', 'servomatictest']:
         obj = bld(features = 'cxx cxxprogram')
@@ -17,3 +22,10 @@ def build(bld):
             if bld.env.TARGET_WINDOWS:
                 obj.source += ' ../../windows/dvdomatic.rc'
             obj.target = t
+
+def pot(bld):
+    i18n.pot(os.path.join('src', 'tools'), 'dvdomatic.cc', 'dvdomatic')
+
+def mo(bld):
+    i18n.po_to_mo(os.path.join('src', 'tools'), 'dvdomatic')
+
index 3f17b3e6ce026106366bca7733169797f46378bd..abe39894d4c306be92a4d5e7a52a3946eabeac2f 100644 (file)
@@ -7,3 +7,12 @@ def build(bld):
     bld.recurse('tools')
     if not bld.env.DISABLE_GUI:
         bld.recurse('wx')
+
+def pot(bld):
+    bld.recurse('lib')
+    bld.recurse('wx')
+    bld.recurse('tools')
+
+def mo(bld):
+    bld.recurse('wx')
+    bld.recurse('tools')
index d844b1f1b7a10e13e0810944295a4fc8898634c8..a0a4bbe8b27e85f3d9d166143e1bbd26ba1b2641 100644 (file)
@@ -1,3 +1,26 @@
+import os
+import glob
+from waflib import Logs
+import i18n
+
+sources = """
+          config_dialog.cc
+          dci_metadata_dialog.cc
+          dir_picker_ctrl.cc
+          film_editor.cc
+          film_viewer.cc
+          filter_dialog.cc
+          filter_view.cc
+          gain_calculator_dialog.cc
+          job_manager_view.cc
+          job_wrapper.cc
+          new_film_dialog.cc
+          properties_dialog.cc
+          server_dialog.cc
+          wx_util.cc
+          wx_ui_signaller.cc
+          """
+
 def configure(conf):
     conf.check_cfg(package = '', path = conf.options.wx_config, args = '--cppflags --cxxflags --libs', uselib_store = 'WXWIDGETS', mandatory = True)
 
@@ -12,22 +35,12 @@ def build(bld):
     obj.export_includes = ['.']
     obj.uselib = 'WXWIDGETS'
     obj.use = 'libdvdomatic'
-    obj.source = """
-                 config_dialog.cc
-                 dci_metadata_dialog.cc
-                 dir_picker_ctrl.cc
-                 film_editor.cc
-                 film_viewer.cc
-                 filter_dialog.cc
-                 filter_view.cc
-                 gain_calculator_dialog.cc
-                 job_manager_view.cc
-                 job_wrapper.cc
-                 new_film_dialog.cc
-                 properties_dialog.cc
-                 server_dialog.cc
-                 wx_util.cc
-                 wx_ui_signaller.cc
-                 """
-
+    obj.source = sources
     obj.target = 'dvdomatic-wx'
+
+def pot(bld):
+    i18n.pot(os.path.join('src', 'wx'), sources, 'libdvdomatic-wx')
+
+def mo(bld):
+    i18n.po_to_mo(os.path.join('src', 'wx'), 'libdvdomatic-wx')
+
diff --git a/wscript b/wscript
index 7d9b65320bb83b3afef0aa5228e4327da2c46318..edf01784bd094ecba926d77208c57b8bdd568032 100644 (file)
--- a/wscript
+++ b/wscript
@@ -198,6 +198,15 @@ def configure(conf):
                              define_name = 'HAVE_BUFFERSRC_H',
                              mandatory = False)
 
+    conf.find_program('msgfmt', var='MSGFMT')
+    
+    datadir = conf.env.DATADIR
+    if not datadir:
+        datadir = os.path.join(conf.env.PREFIX, 'share')
+    
+    conf.define('LOCALEDIR', os.path.join(datadir, 'locale'))
+    conf.define('DATADIR', datadir)
+
     conf.recurse('src')
     conf.recurse('test')
 
@@ -253,3 +262,9 @@ def create_version_cc(version):
 def post(ctx):
     if ctx.cmd == 'install':
         ctx.exec_command('/sbin/ldconfig')
+
+def pot(bld):
+    bld.recurse('src')
+
+def mo(bld):
+    bld.recurse('src')