Some i18n stuff.
authorCarl Hetherington <cth@carlh.net>
Fri, 22 Feb 2013 23:36:32 +0000 (23:36 +0000)
committerCarl Hetherington <cth@carlh.net>
Fri, 22 Feb 2013 23:36:32 +0000 (23:36 +0000)
TRANSLATORS [new file with mode: 0644]
i18n.py [new file with mode: 0644]
src/lib/film.cc
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..d553183
--- /dev/null
+++ b/i18n.py
@@ -0,0 +1,16 @@
+import glob
+import os
+from waflib import Logs
+
+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 600cdfa02165c0ac5da089ceeea67e5dbd75359d..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;
index 1b76132f604931f4bada50fc7c23d50eb74048ba..be61bf433abe435cf4344e18c8b6d4ba1f7fb995 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,32 @@ 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
+               
+               if (!locale->IsOk()) {
+                       delete locale;
+                       locale = new wxLocale (wxLANGUAGE_ENGLISH);
+                       language = wxLANGUAGE_ENGLISH;
+               }
+       }
+}
+
 class App : public wxApp
 {
        bool OnInit ()
@@ -443,6 +473,7 @@ class App : public wxApp
 #endif         
                
                wxInitAllImageHandlers ();
+               setup_i18n ();
                
                dvdomatic_setup ();
 
@@ -451,7 +482,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..8af3d06a5fd3bd254311c03cce540525b0d2fa20 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):
+    os.system('xgettext -d dvdomatic -s --keyword=_ -p build/src/tools -o dvdomatic.pot %s' % os.path.join('src', 'tools', 'dvdomatic.cc'))
+
+def mo(bld):
+    i18n.po_to_mo(os.path.join('src', 'tools'), 'dvdomatic')
+
index ed497ff0c3f5b6f68ab1d21bbc962ff772cf7460..abe39894d4c306be92a4d5e7a52a3946eabeac2f 100644 (file)
@@ -11,3 +11,8 @@ def build(bld):
 def pot(bld):
     bld.recurse('lib')
     bld.recurse('wx')
+    bld.recurse('tools')
+
+def mo(bld):
+    bld.recurse('wx')
+    bld.recurse('tools')
index ef1d1c083f225fc20ba442c09a062cbd03ac2c43..95cdbc8f02b5b779f83f8fb3dbaf7cb31111750c 100644 (file)
@@ -1,4 +1,7 @@
 import os
+import glob
+from waflib import Logs
+import i18n
 
 sources = """
           config_dialog.cc
@@ -42,4 +45,8 @@ def pot(bld):
         if len(t) > 0:
             s += (os.path.join('src', 'wx', t)) + " "
 
-    os.system('xgettext -d libdvdomatic -s --keyword=_ -p build/src/wx -o libdvdomatic-wx.pot %s' % s)
+    os.system('xgettext -d libdvdomatic-wx -s --keyword=_ -p build/src/wx -o libdvdomatic-wx.pot %s' % s)
+
+def mo(bld):
+    i18n.po_to_mo(os.path.join('src', 'wx'), 'libdvdomatic-wx')
+
diff --git a/wscript b/wscript
index cce8c240e57aa93770de6893f7f500d0cc447e33..2a5c549518e944ec4270192f37db4b1887031a17 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')
 
@@ -256,3 +265,6 @@ def post(ctx):
 
 def pot(bld):
     bld.recurse('src')
+
+def mo(bld):
+    bld.recurse('src')