From 12dbcf2ee1792391a81d265ee8875ccf621033ca Mon Sep 17 00:00:00 2001 From: Jean-Marc Lasgouttes Date: Tue, 7 Aug 2007 22:24:47 +0000 Subject: [PATCH] [the "translation" patch series] Part 2: fixing document label translations * src/gettext.cpp (locale_init): factor some code; call Messages::init(). * LyX.cpp (exec): call Messages::init() after initializing package(). * Messages.cpp (init): new method, factor some code from get(). (get): change the method used to set the locale. Should be much more robust than it was (and simpler too). git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19360 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/LyX.cpp | 4 ++ src/Messages.cpp | 102 +++++++++++++++++++++++------------------------ src/Messages.h | 4 +- src/gettext.cpp | 20 ++-------- 4 files changed, 59 insertions(+), 71 deletions(-) diff --git a/src/LyX.cpp b/src/LyX.cpp index 9a13452855..c2b2b62845 100644 --- a/src/LyX.cpp +++ b/src/LyX.cpp @@ -413,6 +413,10 @@ int LyX::exec(int & argc, char * argv[]) } } + // Reinit the messages machinery in case package() knows + // something interesting about the locale directory. + Messages::init(); + if (!use_gui) { // FIXME: create a ConsoleApplication int exit_status = init(argc, argv); diff --git a/src/Messages.cpp b/src/Messages.cpp index cbead21106..66b974cfa1 100644 --- a/src/Messages.cpp +++ b/src/Messages.cpp @@ -56,13 +56,6 @@ using support::setEnv; Messages::Messages(string const & l) : lang_(l), warned_(false) { - if ( lang_.empty() ) { - char const * lc_msgs = 0; -#ifdef HAVE_LC_MESSAGES - lc_msgs = setlocale(LC_MESSAGES, NULL); -#endif - lang_ = lc_msgs ? lc_msgs : ""; - } // strip off any encoding suffix, i.e., assume 8-bit po files string::size_type i = lang_.find("."); lang_ = lang_.substr(0, i); @@ -71,68 +64,62 @@ Messages::Messages(string const & l) } -docstring const Messages::get(string const & m) const +void Messages::init() { - if (m.empty()) - return docstring(); - - // Look for the translated string in the cache. - TranslationCache::iterator it = cache_.find(m); - if (it != cache_.end()) - return it->second; - // The string was not found, use gettext to generate it: - - // In this order, see support/filetools.cpp: - string lang = getEnv("LC_ALL"); - if (lang.empty()) { - lang = getEnv("LC_MESSAGES"); - if (lang.empty()) { - lang = getEnv("LANG"); - if (lang.empty()) - lang = "C"; - } - } -#ifdef HAVE_LC_MESSAGES - char const * lc_msgs = setlocale(LC_MESSAGES, lang_.c_str()); -#endif - // setlocale fails (returns NULL) if the corresponding locale - // is not installed. - // On windows (mingw and cygwin) it always returns NULL. - // Since this method gets called for every translatable - // buffer string like e.g. "Figure:" we warn only once. -#if !defined(_WIN32) && !defined(__CYGWIN__) - if (!warned_ && !lc_msgs) { - warned_ = true; - lyxerr << "Locale " << lang_ << " could not be set" << endl; - } -#endif - // CTYPE controls what getmessage thinks what encoding the po file uses - char const * lc_ctype = setlocale(LC_CTYPE, NULL); - string oldCTYPE = lc_ctype ? lc_ctype : ""; - - setlocale(LC_CTYPE, lang_.c_str()); errno = 0; string const locale_dir = package().locale_dir().toFilesystemEncoding(); char const * c = bindtextdomain(PACKAGE, locale_dir.c_str()); int e = errno; if (e) { LYXERR(Debug::DEBUG) - << BOOST_CURRENT_FUNCTION << '\n' + << BOOST_CURRENT_FUNCTION << '\n' << "Error code: " << errno << '\n' - << "Lang, mess: " << lang_ << " " << m << '\n' << "Directory : " << package().locale_dir().absFilename() << '\n' << "Rtn value : " << c << endl; } if (!bind_textdomain_codeset(PACKAGE, ucs4_codeset)) { LYXERR(Debug::DEBUG) - << BOOST_CURRENT_FUNCTION << '\n' + << BOOST_CURRENT_FUNCTION << '\n' << "Error code: " << errno << '\n' << "Codeset : " << ucs4_codeset << '\n' << endl; } textdomain(PACKAGE); +} + + +docstring const Messages::get(string const & m) const +{ + if (m.empty()) + return docstring(); + + // Look for the translated string in the cache. + TranslationCache::iterator it = cache_.find(m); + if (it != cache_.end()) + return it->second; + + // The string was not found, use gettext to generate it + + string const oldLANGUAGE = getEnv("LANGUAGE"); + string const oldLC_ALL = getEnv("LC_ALL"); + if (!lang_.empty()) { + // This GNU extension overrides any language locale + // wrt gettext. + setEnv("LANGUAGE", lang_); + // However, setting LANGUAGE does nothing when the + // locale is "C". Therefore we set the locale to + // something that is believed to exist on most + // systems. The idea is that one should be able to + // load German documents even without having de_DE + // installed. + setEnv("LC_ALL", "en_US"); +#ifdef HAVE_LC_MESSAGES + setlocale(LC_MESSAGES, ""); +#endif + } + char const * tmp = m.c_str(); char const * msg = gettext(tmp); docstring translated; @@ -158,13 +145,18 @@ docstring const Messages::get(string const & m) const translated = from_ascii(tmp); } else { LYXERR(Debug::DEBUG) << "We got a translation" << endl; - char_type const * ucs4 = reinterpret_cast(msg); - translated = ucs4; + // m is actually not a char const * but ucs4 data + translated = reinterpret_cast(msg); } + + if (!lang_.empty()) { + // Reset everything as it was. + setEnv("LANGUAGE", oldLANGUAGE); + setEnv("LC_ALL", oldLC_ALL); #ifdef HAVE_LC_MESSAGES - setlocale(LC_MESSAGES, lang.c_str()); + setlocale(LC_MESSAGES, ""); #endif - setlocale(LC_CTYPE, oldCTYPE.c_str()); + } std::pair result = cache_.insert(std::make_pair(m, translated)); @@ -188,6 +180,10 @@ namespace lyx { Messages::Messages(string const & l) {} +void Messages::init() +{ +} + docstring const Messages::get(string const & m) const { diff --git a/src/Messages.h b/src/Messages.h index 36ee74a4c7..cb6af76e92 100644 --- a/src/Messages.h +++ b/src/Messages.h @@ -23,9 +23,11 @@ class Messages { public: /// messages in the language \p l. /// If \p l is empty, the language will be defined by the environment. - Messages(std::string const & l = ""); + Messages(std::string const & l = std::string()); /// docstring const get(std::string const & msg) const; + /// + static void init(); private: /// std::string lang_; diff --git a/src/gettext.cpp b/src/gettext.cpp index 3235992c08..08bbdee2fe 100644 --- a/src/gettext.cpp +++ b/src/gettext.cpp @@ -14,7 +14,6 @@ #include "gettext.h" #include "Messages.h" -#include "support/environment.h" #include "support/lstrings.h" #ifdef HAVE_LOCALE_H @@ -26,37 +25,24 @@ using std::string; namespace lyx { -using support::setEnv; - - docstring const _(string const & str) { return getGuiMessages().get(str); } -#ifdef ENABLE_NLS - void locale_init() { - // Disable, as otherwise it overrides everything else incl. the doc language - setEnv("LANGUAGE", ""); +#ifdef ENABLE_NLS # ifdef HAVE_LC_MESSAGES setlocale(LC_MESSAGES, ""); # endif setlocale(LC_CTYPE, ""); + Messages::init(); +#endif setlocale(LC_NUMERIC, "C"); } -#else // ENABLE_NLS - -void locale_init() -{ - setlocale(LC_NUMERIC, "C"); -} - -#endif - docstring const translateIfPossible(docstring const & name) { -- 2.39.2