From bc5df5cc9c2b11524938281f1b2043b185373020 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 22 Feb 2013 23:36:32 +0000 Subject: [PATCH] Some i18n stuff. --- TRANSLATORS | 13 ++++++++ i18n.py | 16 +++++++++ src/lib/film.cc | 2 ++ src/tools/dvdomatic.cc | 75 +++++++++++++++++++++++++++++------------- src/tools/wscript | 12 +++++++ src/wscript | 5 +++ src/wx/wscript | 9 ++++- wscript | 12 +++++++ 8 files changed, 121 insertions(+), 23 deletions(-) create mode 100644 TRANSLATORS create mode 100644 i18n.py diff --git a/TRANSLATORS b/TRANSLATORS new file mode 100644 index 000000000..cbfc875d4 --- /dev/null +++ b/TRANSLATORS @@ -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 index 000000000..d5531834b --- /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)) diff --git a/src/lib/film.cc b/src/lib/film.cc index 600cdfa02..addaa0852 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -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; diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 1b76132f6..be61bf433 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -60,6 +60,7 @@ static shared_ptr 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 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()))); } } diff --git a/src/tools/wscript b/src/tools/wscript index c843c61d8..8af3d06a5 100644 --- a/src/tools/wscript +++ b/src/tools/wscript @@ -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') + diff --git a/src/wscript b/src/wscript index ed497ff0c..abe39894d 100644 --- a/src/wscript +++ b/src/wscript @@ -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') diff --git a/src/wx/wscript b/src/wx/wscript index ef1d1c083..95cdbc8f0 100644 --- a/src/wx/wscript +++ b/src/wx/wscript @@ -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 cce8c240e..2a5c54951 100644 --- 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') -- 2.30.2