summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2025-05-25 14:22:30 +0200
committerCarl Hetherington <cth@carlh.net>2025-05-27 09:36:37 +0200
commit5661c34574fdac778dba0e3c3503f5792c41bb3c (patch)
treebd1022ef2dae2abe880714123bfebdb868edc91b
parenta8f06a40096a0cbd56c42602f8dc1ce4857af0d8 (diff)
Move i18n setup into 3 separate platform files.
-rw-r--r--src/lib/i18n_setup.h32
-rw-r--r--src/lib/i18n_setup_linux.cc60
-rw-r--r--src/lib/i18n_setup_osx.cc60
-rw-r--r--src/lib/i18n_setup_windows.cc69
-rw-r--r--src/lib/util.cc53
-rw-r--r--src/lib/util.h4
-rw-r--r--src/lib/wscript6
-rw-r--r--src/tools/dcpomatic.cc3
-rw-r--r--src/tools/dcpomatic_batch.cc3
-rw-r--r--src/tools/dcpomatic_combiner.cc3
-rw-r--r--src/tools/dcpomatic_disk.cc3
-rw-r--r--src/tools/dcpomatic_editor.cc3
-rw-r--r--src/tools/dcpomatic_kdm.cc3
-rw-r--r--src/tools/dcpomatic_player.cc3
-rw-r--r--src/tools/dcpomatic_playlist.cc3
-rw-r--r--src/tools/dcpomatic_server.cc4
-rw-r--r--src/tools/dcpomatic_verifier.cc3
-rw-r--r--src/wx/i18n_setup.h30
-rw-r--r--src/wx/i18n_setup_linux.cc71
-rw-r--r--src/wx/i18n_setup_osx.cc95
-rw-r--r--src/wx/i18n_setup_windows.cc62
-rw-r--r--src/wx/wscript5
-rw-r--r--src/wx/wx_util.cc116
-rw-r--r--src/wx/wx_util.h1
24 files changed, 507 insertions, 188 deletions
diff --git a/src/lib/i18n_setup.h b/src/lib/i18n_setup.h
new file mode 100644
index 000000000..8bb3af152
--- /dev/null
+++ b/src/lib/i18n_setup.h
@@ -0,0 +1,32 @@
+/*
+ Copyright (C) 2025 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ DCP-o-matic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include <boost/filesystem.hpp>
+#include <string>
+
+
+namespace dcpomatic {
+
+boost::filesystem::path mo_path();
+void setup_i18n(std::string forced_language);
+
+}
+
diff --git a/src/lib/i18n_setup_linux.cc b/src/lib/i18n_setup_linux.cc
new file mode 100644
index 000000000..21e7f2d61
--- /dev/null
+++ b/src/lib/i18n_setup_linux.cc
@@ -0,0 +1,60 @@
+/*
+ Copyright (C) 2025 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ DCP-o-matic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include "i18n_setup.h"
+#include <fmt/format.h>
+#include <boost/filesystem.hpp>
+#include <libintl.h>
+
+
+using std::string;
+
+
+boost::filesystem::path
+dcpomatic::mo_path()
+{
+ return LINUX_LOCALE_PREFIX;
+}
+
+
+void
+dcpomatic::setup_i18n(string forced_language)
+{
+ forced_language += ".UTF8";
+
+ if (!forced_language.empty()) {
+ /* Override our environment forced_languageuage. Note that the caller must not
+ free the string passed into putenv().
+ */
+ string s = fmt::format("LANGUAGE={}", forced_language);
+ putenv(strdup(s.c_str()));
+ s = fmt::format("LANG={}", forced_language);
+ putenv(strdup(s.c_str()));
+ s = fmt::format("LC_ALL={}", forced_language);
+ putenv(strdup(s.c_str()));
+ }
+
+ setlocale(LC_ALL, "");
+ textdomain("libdcpomatic2");
+
+ bindtextdomain("libdcpomatic2", mo_path().string().c_str());
+}
+
diff --git a/src/lib/i18n_setup_osx.cc b/src/lib/i18n_setup_osx.cc
new file mode 100644
index 000000000..7a7c63ce8
--- /dev/null
+++ b/src/lib/i18n_setup_osx.cc
@@ -0,0 +1,60 @@
+/*
+ Copyright (C) 2025 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ DCP-o-matic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include "i18n_setup.h"
+#include "variant.h"
+#include <fmt/format.h>
+#include <boost/filesystem.hpp>
+#include <libintl.h>
+
+
+using std::string;
+
+
+boost::filesystem::path
+dcpomatic::mo_path()
+{
+ return variant::dcpomatic_app() + "/Contents/Resources";
+}
+
+
+void
+dcpomatic::setup_i18n(string forced_language)
+{
+ if (!forced_language.empty()) {
+ /* Override our environment forced_languageuage. Note that the caller must not
+ free the string passed into putenv().
+ */
+ string s = fmt::format("LANGUAGE={}", forced_language);
+ putenv(strdup(s.c_str()));
+ s = fmt::format("LANG={}", forced_language);
+ putenv(strdup(s.c_str()));
+ s = fmt::format("LC_ALL={}", forced_language);
+ putenv(strdup(s.c_str()));
+ }
+
+ setlocale(LC_ALL, "");
+ textdomain("libdcpomatic2");
+
+ bindtextdomain("libdcpomatic2", mo_path().string().c_str());
+ bind_textdomain_codeset("libdcpomatic2", "UTF8");
+}
+
diff --git a/src/lib/i18n_setup_windows.cc b/src/lib/i18n_setup_windows.cc
new file mode 100644
index 000000000..7833972b6
--- /dev/null
+++ b/src/lib/i18n_setup_windows.cc
@@ -0,0 +1,69 @@
+/*
+ Copyright (C) 2025 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ DCP-o-matic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#define UNICODE 1
+
+
+#include "i18n_setup.h"
+#include <fmt/format.h>
+#include <boost/filesystem.hpp>
+#include <windows.h>
+#include <libintl.h>
+
+
+using std::string;
+
+
+boost::filesystem::path
+dcpomatic::mo_path()
+{
+ wchar_t buffer[512];
+ GetModuleFileName(0, buffer, 512 * sizeof(wchar_t));
+ boost::filesystem::path p(buffer);
+ p = p.parent_path();
+ p = p.parent_path();
+ p /= "locale";
+ return p;
+}
+
+
+void
+dcpomatic::setup_i18n(string forced_language)
+{
+ if (!forced_language.empty()) {
+ /* Override our environment language. Note that the caller must not
+ free the string passed into putenv().
+ */
+ auto s = fmt::format("LANGUAGE={}", forced_language);
+ putenv(strdup(s.c_str()));
+ s = fmt::format("LANG={}", forced_language);
+ putenv(strdup(s.c_str()));
+ s = fmt::format("LC_ALL={}", forced_language);
+ putenv(strdup(s.c_str()));
+ }
+
+ setlocale(LC_ALL, "");
+ textdomain("libdcpomatic2");
+
+ bindtextdomain("libdcpomatic2", mo_path().string().c_str());
+ bind_textdomain_codeset("libdcpomatic2", "UTF8");
+}
+
diff --git a/src/lib/util.cc b/src/lib/util.cc
index ac562afc1..eeab9f2d6 100644
--- a/src/lib/util.cc
+++ b/src/lib/util.cc
@@ -512,59 +512,6 @@ LIBDCP_ENABLE_WARNINGS
capture_ffmpeg_logs();
}
-#ifdef DCPOMATIC_WINDOWS
-boost::filesystem::path
-mo_path()
-{
- wchar_t buffer[512];
- GetModuleFileName(0, buffer, 512 * sizeof(wchar_t));
- boost::filesystem::path p(buffer);
- p = p.parent_path();
- p = p.parent_path();
- p /= "locale";
- return p;
-}
-#endif
-
-#ifdef DCPOMATIC_OSX
-boost::filesystem::path
-mo_path()
-{
- return variant::dcpomatic_app() + "/Contents/Resources";
-}
-#endif
-
-void
-dcpomatic_setup_gettext_i18n(string lang)
-{
-#ifdef DCPOMATIC_LINUX
- lang += ".UTF8";
-#endif
-
- if (!lang.empty()) {
- /* Override our environment language. Note that the caller must not
- free the string passed into putenv().
- */
- string s = String::compose("LANGUAGE=%1", lang);
- putenv(strdup(s.c_str()));
- s = String::compose("LANG=%1", lang);
- putenv(strdup(s.c_str()));
- s = String::compose("LC_ALL=%1", lang);
- putenv(strdup(s.c_str()));
- }
-
- setlocale(LC_ALL, "");
- textdomain("libdcpomatic2");
-
-#if defined(DCPOMATIC_WINDOWS) || defined(DCPOMATIC_OSX)
- bindtextdomain("libdcpomatic2", mo_path().string().c_str());
- bind_textdomain_codeset("libdcpomatic2", "UTF8");
-#endif
-
-#ifdef DCPOMATIC_LINUX
- bindtextdomain("libdcpomatic2", LINUX_LOCALE_PREFIX);
-#endif
-}
/** Compute a digest of the first and last `size' bytes of a set of files. */
string
diff --git a/src/lib/util.h b/src/lib/util.h
index 80ba4a1f6..79ac87db1 100644
--- a/src/lib/util.h
+++ b/src/lib/util.h
@@ -66,7 +66,6 @@ extern std::string seconds_to_approximate_hms(int);
extern double seconds(struct timeval);
extern void dcpomatic_setup();
extern void dcpomatic_setup_path_encoding();
-extern void dcpomatic_setup_gettext_i18n(std::string);
extern std::string digest_head_tail(std::vector<boost::filesystem::path>, boost::uintmax_t size);
extern std::string simple_digest(std::vector<boost::filesystem::path> paths);
extern void ensure_ui_thread();
@@ -75,9 +74,6 @@ extern std::string short_audio_channel_name(int);
extern bool valid_image_file(boost::filesystem::path);
extern bool valid_sound_file(boost::filesystem::path);
extern bool valid_j2k_file(boost::filesystem::path);
-#ifdef DCPOMATIC_WINDOWS
-extern boost::filesystem::path mo_path();
-#endif
extern std::string tidy_for_filename(std::string);
extern dcp::Size fit_ratio_within(float ratio, dcp::Size);
extern void set_backtrace_file(boost::filesystem::path);
diff --git a/src/lib/wscript b/src/lib/wscript
index dafd655fe..ea6994eb1 100644
--- a/src/lib/wscript
+++ b/src/lib/wscript
@@ -272,11 +272,11 @@ def build(bld):
if bld.env.TARGET_WINDOWS_64 or bld.env.TARGET_WINDOWS_32:
obj.uselib += ' WINSOCK2 DBGHELP SHLWAPI MSWSOCK BOOST_LOCALE SETUPAPI OLE32 UUID'
- obj.source += ' cross_windows.cc'
+ obj.source += ' cross_windows.cc i18n_setup_windows.cc'
if bld.env.TARGET_OSX:
- obj.source += ' cross_osx.cc cross_unix.cc'
+ obj.source += ' cross_osx.cc cross_unix.cc i18n_setup_osx.cc'
if bld.env.TARGET_LINUX:
- obj.source += ' cross_linux.cc cross_unix.cc'
+ obj.source += ' cross_linux.cc cross_unix.cc i18n_setup_linux.cc'
if bld.env.STATIC_DCPOMATIC:
obj.uselib += ' XMLPP'
diff --git a/src/tools/dcpomatic.cc b/src/tools/dcpomatic.cc
index b3b3d1c87..4ab9c03ed 100644
--- a/src/tools/dcpomatic.cc
+++ b/src/tools/dcpomatic.cc
@@ -38,6 +38,7 @@
#include "wx/hints_dialog.h"
#include "wx/html_dialog.h"
#include "wx/file_dialog.h"
+#include "wx/i18n_setup.h"
#include "wx/id.h"
#include "wx/job_manager_view.h"
#include "wx/kdm_dialog.h"
@@ -1685,7 +1686,7 @@ private:
hasn't yet been called and there aren't any filters etc.
set up yet.
*/
- dcpomatic_setup_i18n ();
+ dcpomatic::wx::setup_i18n();
/* Set things up, including filters etc.
which will now be internationalised correctly.
diff --git a/src/tools/dcpomatic_batch.cc b/src/tools/dcpomatic_batch.cc
index ed60aae37..c6a58f741 100644
--- a/src/tools/dcpomatic_batch.cc
+++ b/src/tools/dcpomatic_batch.cc
@@ -22,6 +22,7 @@
#include "wx/about_dialog.h"
#include "wx/dcpomatic_button.h"
#include "wx/full_config_dialog.h"
+#include "wx/i18n_setup.h"
#include "wx/id.h"
#include "wx/job_manager_view.h"
#include "wx/servers_list_dialog.h"
@@ -447,7 +448,7 @@ class App : public wxApp
hasn't yet been called and there aren't any filters etc.
set up yet.
*/
- dcpomatic_setup_i18n ();
+ dcpomatic::wx::setup_i18n();
/* Set things up, including filters etc.
which will now be internationalised correctly.
diff --git a/src/tools/dcpomatic_combiner.cc b/src/tools/dcpomatic_combiner.cc
index 38c8cf97f..67ca73539 100644
--- a/src/tools/dcpomatic_combiner.cc
+++ b/src/tools/dcpomatic_combiner.cc
@@ -22,6 +22,7 @@
#include "wx/dir_dialog.h"
#include "wx/dir_picker_ctrl.h"
#include "wx/editable_list.h"
+#include "wx/i18n_setup.h"
#include "wx/wx_signal_manager.h"
#include "wx/wx_util.h"
#include "wx/wx_variant.h"
@@ -244,7 +245,7 @@ public:
hasn't yet been called and there aren't any filters etc.
set up yet.
*/
- dcpomatic_setup_i18n ();
+ dcpomatic::wx::setup_i18n();
/* Set things up, including filters etc.
which will now be internationalised correctly.
diff --git a/src/tools/dcpomatic_disk.cc b/src/tools/dcpomatic_disk.cc
index c83d57b8f..be527eaab 100644
--- a/src/tools/dcpomatic_disk.cc
+++ b/src/tools/dcpomatic_disk.cc
@@ -21,6 +21,7 @@
#include "wx/drive_wipe_warning_dialog.h"
#include "wx/editable_list.h"
+#include "wx/i18n_setup.h"
#include "wx/id.h"
#include "wx/job_manager_view.h"
#include "wx/message_dialog.h"
@@ -477,7 +478,7 @@ public:
hasn't yet been called and there aren't any filters etc.
set up yet.
*/
- dcpomatic_setup_i18n ();
+ dcpomatic::wx::setup_i18n();
/* Set things up, including filters etc.
which will now be internationalised correctly.
diff --git a/src/tools/dcpomatic_editor.cc b/src/tools/dcpomatic_editor.cc
index e02f23b68..1cb79681d 100644
--- a/src/tools/dcpomatic_editor.cc
+++ b/src/tools/dcpomatic_editor.cc
@@ -22,6 +22,7 @@
#include "wx/about_dialog.h"
#include "wx/dcpomatic_spin_ctrl.h"
#include "wx/editable_list.h"
+#include "wx/i18n_setup.h"
#include "wx/id.h"
#include "wx/wx_signal_manager.h"
#include "wx/wx_util.h"
@@ -531,7 +532,7 @@ private:
hasn't yet been called and there aren't any filters etc.
set up yet.
*/
- dcpomatic_setup_i18n ();
+ dcpomatic::wx::setup_i18n();
/* Set things up, including filters etc.
which will now be internationalised correctly.
diff --git a/src/tools/dcpomatic_kdm.cc b/src/tools/dcpomatic_kdm.cc
index 95d9a25b1..843684103 100644
--- a/src/tools/dcpomatic_kdm.cc
+++ b/src/tools/dcpomatic_kdm.cc
@@ -22,6 +22,7 @@
#include "wx/about_dialog.h"
#include "wx/dcpomatic_button.h"
#include "wx/editable_list.h"
+#include "wx/i18n_setup.h"
#include "wx/id.h"
#include "wx/invalid_certificate_period_dialog.h"
#include "wx/file_dialog.h"
@@ -913,7 +914,7 @@ private:
hasn't yet been called and there aren't any filters etc.
set up yet.
*/
- dcpomatic_setup_i18n ();
+ dcpomatic::wx::setup_i18n();
/* Set things up, including filters etc.
which will now be internationalised correctly.
diff --git a/src/tools/dcpomatic_player.cc b/src/tools/dcpomatic_player.cc
index ab508f224..43c071556 100644
--- a/src/tools/dcpomatic_player.cc
+++ b/src/tools/dcpomatic_player.cc
@@ -21,6 +21,7 @@
#include "wx/about_dialog.h"
#include "wx/file_dialog.h"
#include "wx/film_viewer.h"
+#include "wx/i18n_setup.h"
#include "wx/id.h"
#include "wx/nag_dialog.h"
#include "wx/player_config_dialog.h"
@@ -1311,7 +1312,7 @@ private:
hasn't yet been called and there aren't any filters etc.
set up yet.
*/
- dcpomatic_setup_i18n ();
+ dcpomatic::wx::setup_i18n();
/* Set things up, including filters etc.
which will now be internationalised correctly.
diff --git a/src/tools/dcpomatic_playlist.cc b/src/tools/dcpomatic_playlist.cc
index 264afe27d..54b459634 100644
--- a/src/tools/dcpomatic_playlist.cc
+++ b/src/tools/dcpomatic_playlist.cc
@@ -22,6 +22,7 @@
#include "wx/about_dialog.h"
#include "wx/content_view.h"
#include "wx/dcpomatic_button.h"
+#include "wx/i18n_setup.h"
#include "wx/playlist_editor_config_dialog.h"
#include "wx/wx_signal_manager.h"
#include "wx/wx_util.h"
@@ -660,7 +661,7 @@ private:
hasn't yet been called and there aren't any filters etc.
set up yet.
*/
- dcpomatic_setup_i18n ();
+ dcpomatic::wx::setup_i18n();
/* Set things up, including filters etc.
which will now be internationalised correctly.
diff --git a/src/tools/dcpomatic_server.cc b/src/tools/dcpomatic_server.cc
index 669d32ec0..e5d8b0a90 100644
--- a/src/tools/dcpomatic_server.cc
+++ b/src/tools/dcpomatic_server.cc
@@ -18,6 +18,8 @@
*/
+
+#include "wx/i18n_setup.h"
#include "wx/id.h"
#include "wx/static_text.h"
#include "wx/wx_signal_manager.h"
@@ -301,7 +303,7 @@ private:
auto splash = maybe_show_splash ();
dcpomatic_setup_path_encoding ();
- dcpomatic_setup_i18n ();
+ dcpomatic::wx::setup_i18n();
dcpomatic_setup ();
Config::drop ();
diff --git a/src/tools/dcpomatic_verifier.cc b/src/tools/dcpomatic_verifier.cc
index 238efe552..f53f99e3d 100644
--- a/src/tools/dcpomatic_verifier.cc
+++ b/src/tools/dcpomatic_verifier.cc
@@ -29,6 +29,7 @@
#include "wx/dcpomatic_button.h"
#include "wx/dir_picker_ctrl.h"
#include "wx/editable_list.h"
+#include "wx/i18n_setup.h"
#include "wx/id.h"
#include "wx/verify_dcp_progress_panel.h"
#include "wx/verify_dcp_result_panel.h"
@@ -324,7 +325,7 @@ private:
hasn't yet been called and there aren't any filters etc.
set up yet.
*/
- dcpomatic_setup_i18n();
+ dcpomatic::wx::setup_i18n();
/* Set things up, including filters etc.
which will now be internationalised correctly.
diff --git a/src/wx/i18n_setup.h b/src/wx/i18n_setup.h
new file mode 100644
index 000000000..1ed4071c4
--- /dev/null
+++ b/src/wx/i18n_setup.h
@@ -0,0 +1,30 @@
+/*
+ Copyright (C) 2025 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ DCP-o-matic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+namespace dcpomatic {
+namespace wx {
+
+
+void setup_i18n();
+
+
+}
+}
diff --git a/src/wx/i18n_setup_linux.cc b/src/wx/i18n_setup_linux.cc
new file mode 100644
index 000000000..286ce4065
--- /dev/null
+++ b/src/wx/i18n_setup_linux.cc
@@ -0,0 +1,71 @@
+/*
+ Copyright (C) 2025 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ DCP-o-matic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include "i18n_setup.h"
+#include "wx_util.h"
+#include "lib/config.h"
+#include "lib/i18n_setup.h"
+#include <wx/wx.h>
+
+
+void
+dcpomatic::wx::setup_i18n()
+{
+ int language = wxLANGUAGE_DEFAULT;
+
+ auto config_lang = Config::instance()->language();
+ if (config_lang && !config_lang->empty ()) {
+ auto const li = wxLocale::FindLanguageInfo(std_to_wx (config_lang.get ()));
+ if (li) {
+ language = li->Language;
+ }
+ }
+
+ wxLocale* locale = nullptr;
+ if (wxLocale::IsAvailable (language)) {
+ locale = new wxLocale(language, wxLOCALE_LOAD_DEFAULT);
+
+ locale->AddCatalogLookupPathPrefix(std_to_wx(LINUX_LOCALE_PREFIX));
+
+ /* We have to include the wxWidgets .mo in our distribution,
+ so we rename it to avoid clashes with any other installation
+ of wxWidgets.
+ */
+ locale->AddCatalog(char_to_wx("dcpomatic2-wxstd"));
+
+ /* Fedora 29 (at least) installs wxstd3.mo instead of wxstd.mo */
+ locale->AddCatalog(char_to_wx("wxstd3"));
+
+ locale->AddCatalog(char_to_wx("wxstd"));
+ locale->AddCatalog(char_to_wx("libdcpomatic2-wx"));
+ locale->AddCatalog(char_to_wx("dcpomatic2"));
+
+ if (!locale->IsOk()) {
+ delete locale;
+ locale = new wxLocale (wxLANGUAGE_ENGLISH);
+ }
+ }
+
+ if (locale) {
+ dcpomatic::setup_i18n(wx_to_std(locale->GetCanonicalName()));
+ }
+}
+
diff --git a/src/wx/i18n_setup_osx.cc b/src/wx/i18n_setup_osx.cc
new file mode 100644
index 000000000..da1eb221f
--- /dev/null
+++ b/src/wx/i18n_setup_osx.cc
@@ -0,0 +1,95 @@
+/*
+ Copyright (C) 2025 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ DCP-o-matic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include "i18n_setup.h"
+#include "wx_util.h"
+#include "lib/config.h"
+#include "lib/i18n_setup.h"
+#include <wx/wx.h>
+#if wxCHECK_VERSION(3, 1, 6)
+#include <wx/uilocale.h>
+#endif
+#include <CoreFoundation/CoreFoundation.h>
+
+
+using std::string;
+
+
+void
+dcpomatic::wx::setup_i18n()
+{
+ wxLog::EnableLogging();
+
+#if wxCHECK_VERSION(3, 1, 6)
+ wxUILocale::UseDefault();
+#endif
+
+ auto get_locale_value = [](CFLocaleKey key) {
+ CFLocaleRef cflocale = CFLocaleCopyCurrent();
+ auto value = (CFStringRef) CFLocaleGetValue(cflocale, key);
+ char buffer[64];
+ CFStringGetCString(value, buffer, sizeof(buffer), kCFStringEncodingUTF8);
+ CFRelease(cflocale);
+ return string(buffer);
+ };
+
+ auto translations = new wxTranslations();
+
+ auto config_lang = Config::instance()->language();
+ if (config_lang && !config_lang->empty()) {
+ translations->SetLanguage(std_to_wx(*config_lang));
+ } else {
+ /* We want to use the user's preferred language. It seems that if we use the wxWidgets default we will get the
+ * language for the locale, which may not be what we want (e.g. for a machine in Germany, configured for DE locale,
+ * but with the preferred language set to English).
+ *
+ * Instead, the the language code from macOS then get the corresponding canonical language string with region,
+ * which wxTranslations::SetLanguage will accept.
+ */
+ auto const language_code = get_locale_value(kCFLocaleLanguageCode);
+ /* Ideally this would be wxUILocale (as wxLocale is deprecated) but we want to keep this building
+ * with the old wxWidgets we use for the older macOS builds.
+ */
+ auto const info = wxLocale::FindLanguageInfo(std_to_wx(language_code));
+ if (info) {
+#if wxCHECK_VERSION(3, 1, 6)
+ translations->SetLanguage(info->GetCanonicalWithRegion());
+#else
+ translations->SetLanguage(info->CanonicalName);
+#endif
+ }
+ }
+
+#ifdef DCPOMATIC_DEBUG
+ wxFileTranslationsLoader::AddCatalogLookupPathPrefix(char_to_wx("build/src/wx/mo"));
+ wxFileTranslationsLoader::AddCatalogLookupPathPrefix(char_to_wx("build/src/tools/mo"));
+#endif
+
+ translations->AddStdCatalog();
+ translations->AddCatalog(char_to_wx("libdcpomatic2-wx"));
+ translations->AddCatalog(char_to_wx("dcpomatic2"));
+
+ wxTranslations::Set(translations);
+
+ dcpomatic::setup_i18n(config_lang.get_value_or(""));
+}
+
+
diff --git a/src/wx/i18n_setup_windows.cc b/src/wx/i18n_setup_windows.cc
new file mode 100644
index 000000000..0fc4ecdd5
--- /dev/null
+++ b/src/wx/i18n_setup_windows.cc
@@ -0,0 +1,62 @@
+/*
+ Copyright (C) 2025 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ DCP-o-matic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include "i18n_setup.h"
+#include "wx_util.h"
+#include "lib/i18n_setup.h"
+#include <wx/wx.h>
+
+
+
+void
+dcpomatic::wx::setup_i18n()
+{
+ int language = wxLANGUAGE_DEFAULT;
+
+ auto config_lang = Config::instance()->language();
+ if (config_lang && !config_lang->empty()) {
+ if (auto const li = wxLocale::FindLanguageInfo(std_to_wx(config_lang.get()))) {
+ language = li->Language;
+ }
+ }
+
+ wxLocale* locale = nullptr;
+ if (wxLocale::IsAvailable(language)) {
+ locale = new wxLocale(language, wxLOCALE_LOAD_DEFAULT);
+
+ locale->AddCatalogLookupPathPrefix(std_to_wx(mo_path().string()));
+ locale->AddCatalog(char_to_wx("wxstd-3.1"));
+
+ locale->AddCatalog(char_to_wx("wxstd"));
+ locale->AddCatalog(char_to_wx("libdcpomatic2-wx"));
+ locale->AddCatalog(char_to_wx("dcpomatic2"));
+
+ if (!locale->IsOk()) {
+ delete locale;
+ locale = new wxLocale(wxLANGUAGE_ENGLISH);
+ }
+ }
+
+ if (locale) {
+ dcpomatic::setup_i18n(wx_to_std(locale->GetCanonicalName()));
+ }
+}
+
diff --git a/src/wx/wscript b/src/wx/wscript
index 6bb10511b..3dfc157e2 100644
--- a/src/wx/wscript
+++ b/src/wx/wscript
@@ -341,14 +341,17 @@ def build(bld):
obj.name = 'libdcpomatic2-wx'
obj.export_includes = ['..']
obj.uselib = 'BOOST_FILESYSTEM BOOST_THREAD BOOST_REGEX WXWIDGETS DCP SUB ZIP CXML RTAUDIO ICU AVUTIL '
+ obj.source = sources
if bld.env.TARGET_LINUX:
obj.uselib += 'GTK GL GLU '
+ obj.source += ' i18n_setup_linux.cc'
if bld.env.TARGET_WINDOWS_64 or bld.env.TARGET_WINDOWS_32:
obj.uselib += 'WINSOCK2 OLE32 DSOUND WINMM KSUSER GL GLU GLEW '
+ obj.source += ' i18n_setup_windows.cc'
if bld.env.TARGET_OSX:
obj.framework = ['CoreAudio', 'OpenGL']
+ obj.source += ' i18n_setup_osx.cc'
obj.use = 'libdcpomatic2'
- obj.source = sources
obj.target = 'dcpomatic2-wx'
i18n.po_to_mo(os.path.join('src', 'wx'), 'libdcpomatic2-wx', bld)
diff --git a/src/wx/wx_util.cc b/src/wx/wx_util.cc
index 932e4e0bd..afea3b209 100644
--- a/src/wx/wx_util.cc
+++ b/src/wx/wx_util.cc
@@ -421,122 +421,6 @@ checked_set(RegionSubtagWidget* widget, optional<dcp::LanguageTag::RegionSubtag>
}
-#ifdef DCPOMATIC_OSX
-
-void
-dcpomatic_setup_i18n()
-{
- wxLog::EnableLogging();
-
-#if wxCHECK_VERSION(3, 1, 6)
- wxUILocale::UseDefault();
-#endif
-
- auto get_locale_value = [](CFLocaleKey key) {
- CFLocaleRef cflocale = CFLocaleCopyCurrent();
- auto value = (CFStringRef) CFLocaleGetValue(cflocale, key);
- char buffer[64];
- CFStringGetCString(value, buffer, sizeof(buffer), kCFStringEncodingUTF8);
- CFRelease(cflocale);
- return string(buffer);
- };
-
- auto translations = new wxTranslations();
-
- auto config_lang = Config::instance()->language();
- if (config_lang && !config_lang->empty()) {
- translations->SetLanguage(std_to_wx(*config_lang));
- } else {
- /* We want to use the user's preferred language. It seems that if we use the wxWidgets default we will get the
- * language for the locale, which may not be what we want (e.g. for a machine in Germany, configured for DE locale,
- * but with the preferred language set to English).
- *
- * Instead, the the language code from macOS then get the corresponding canonical language string with region,
- * which wxTranslations::SetLanguage will accept.
- */
- auto const language_code = get_locale_value(kCFLocaleLanguageCode);
- /* Ideally this would be wxUILocale (as wxLocale is deprecated) but we want to keep this building
- * with the old wxWidgets we use for the older macOS builds.
- */
- auto const info = wxLocale::FindLanguageInfo(std_to_wx(language_code));
- if (info) {
-#if wxCHECK_VERSION(3, 1, 6)
- translations->SetLanguage(info->GetCanonicalWithRegion());
-#else
- translations->SetLanguage(info->CanonicalName);
-#endif
- }
- }
-
-#ifdef DCPOMATIC_DEBUG
- wxFileTranslationsLoader::AddCatalogLookupPathPrefix(char_to_wx("build/src/wx/mo"));
- wxFileTranslationsLoader::AddCatalogLookupPathPrefix(char_to_wx("build/src/tools/mo"));
-#endif
-
- translations->AddStdCatalog();
- translations->AddCatalog(char_to_wx("libdcpomatic2-wx"));
- translations->AddCatalog(char_to_wx("dcpomatic2"));
-
- wxTranslations::Set(translations);
-
- dcpomatic_setup_gettext_i18n(config_lang.get_value_or(""));
-}
-
-#else
-
-void
-dcpomatic_setup_i18n ()
-{
- int language = wxLANGUAGE_DEFAULT;
-
- auto config_lang = Config::instance()->language ();
- if (config_lang && !config_lang->empty ()) {
- auto const li = wxLocale::FindLanguageInfo (std_to_wx (config_lang.get ()));
- if (li) {
- language = li->Language;
- }
- }
-
- wxLocale* locale = nullptr;
- if (wxLocale::IsAvailable (language)) {
- locale = new wxLocale (language, wxLOCALE_LOAD_DEFAULT);
-
-#ifdef DCPOMATIC_WINDOWS
- locale->AddCatalogLookupPathPrefix (std_to_wx (mo_path().string()));
- locale->AddCatalog(char_to_wx("wxstd-3.1"));
-#endif
-
-#ifdef DCPOMATIC_LINUX
- locale->AddCatalogLookupPathPrefix(std_to_wx(LINUX_LOCALE_PREFIX));
-
- /* We have to include the wxWidgets .mo in our distribution,
- so we rename it to avoid clashes with any other installation
- of wxWidgets.
- */
- locale->AddCatalog(char_to_wx("dcpomatic2-wxstd"));
-
- /* Fedora 29 (at least) installs wxstd3.mo instead of wxstd.mo */
- locale->AddCatalog(char_to_wx("wxstd3"));
-#endif
-
- locale->AddCatalog(char_to_wx("wxstd"));
- locale->AddCatalog(char_to_wx("libdcpomatic2-wx"));
- locale->AddCatalog(char_to_wx("dcpomatic2"));
-
- if (!locale->IsOk()) {
- delete locale;
- locale = new wxLocale (wxLANGUAGE_ENGLISH);
- }
- }
-
- if (locale) {
- dcpomatic_setup_gettext_i18n (wx_to_std (locale->GetCanonicalName ()));
- }
-}
-
-#endif
-
-
int
wx_get (wxSpinCtrl* w)
{
diff --git a/src/wx/wx_util.h b/src/wx/wx_util.h
index 92cdd349b..114caab15 100644
--- a/src/wx/wx_util.h
+++ b/src/wx/wx_util.h
@@ -108,7 +108,6 @@ extern wxString std_to_wx (std::string);
/** Convert UTF8-encoded char array to wxString */
extern wxString char_to_wx(char const* s);
-extern void dcpomatic_setup_i18n ();
extern wxString context_translation(char const* s);
extern std::string string_client_data (wxClientData* o);
extern wxString time_to_timecode (dcpomatic::DCPTime t, double fps);