widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #00203
[Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
SirVer has proposed merging lp:~widelands-dev/widelands/martin_i18n into lp:widelands.
Requested reviews:
SirVer (sirver)
For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/martin_i18n/+merge/49202
Martin explored wesnoths code and duplicated their ideas to properly fix i18n under linux.
--
https://code.launchpad.net/~widelands-dev/widelands/martin_i18n/+merge/49202
Your team Widelands Developers is subscribed to branch lp:~widelands-dev/widelands/martin_i18n.
=== modified file 'src/i18n.cc'
--- src/i18n.cc 2010-11-01 21:43:46 +0000
+++ src/i18n.cc 2011-02-10 10:00:41 +0000
@@ -19,6 +19,7 @@
#include "i18n.h"
#include "log.h"
+#include "profile/profile.h"
#include <config.h>
@@ -27,6 +28,12 @@
#include <cstdlib>
#include <utility>
+#ifdef __APPLE__
+#define SETLOCALE libintl_setlocale
+#else
+#define SETLOCALE std::setlocale
+#endif
+
extern int _nl_msg_cat_cntr;
namespace i18n {
@@ -36,6 +43,7 @@
/// \see grab_texdomain()
std::vector<std::pair<std::string, std::string> > textdomains;
+std::string env_locale;
std::string locale;
std::string localedir;
@@ -70,8 +78,8 @@
char const * const dom = domain.c_str();
char const * const ldir = localedir.c_str();
+ bindtextdomain(dom, ldir);
bind_textdomain_codeset(dom, "UTF-8");
- bindtextdomain(dom, ldir);
// log("textdomain %s @ %s\n", dom, ldir);
textdomain(dom);
textdomains.push_back(std::make_pair(dom, ldir));
@@ -100,55 +108,106 @@
}
/**
- * Set the locale to the given string
+ * Initialize locale to English.
+ * Save system language (for later selection).
+ * Code inspired by wesnoth.org
+ */
+void init_locale() {
+#ifdef _WIN32
+ env_locale = "";
+ locale = "English";
+ SETLOCALE(LC_ALL, "English");
+#else
+ env_locale = getenv("LANG"); // save environment variable
+ locale = "C";
+ SETLOCALE(LC_ALL, "C");
+ SETLOCALE(LC_MESSAGES, "");
+#endif
+}
+
+/**
+ * Set the locale to the given string.
+ * Code inspired by wesnoth.org
*/
void set_locale(std::string name) {
std::string lang(name);
+#ifndef _WIN32
+#ifndef __AMIGAOS4__
+ unsetenv ("LANGUAGE"); // avoid problems with this variable
+#endif
+#endif
+
+ log("selected language: %s\n", lang.empty()?"(system language)":lang.c_str());
+
+ std::string alt_str;
+ if (lang.empty()) {
+ // reload system language, if selected
+ lang = env_locale;
+ alt_str = env_locale + ",";
+ } else {
+ // otherwise, read alternatives from file
+ Profile loc("txts/locales");
+ Section * s = &loc.pull_section("alternatives");
+ alt_str = s->get_string(lang.c_str(), lang.c_str());
+ alt_str += ",";
+ }
+
// Somehow setlocale doesn't behave same on
// some systems.
#ifdef __BEOS__
setenv ("LANG", lang.c_str(), 1);
setenv ("LC_ALL", lang.c_str(), 1);
+ locale = lang;
#endif
#ifdef __APPLE__
setenv ("LANGUAGE", lang.c_str(), 1);
+ setenv ("LANG", lang.c_str(), 1);
setenv ("LC_ALL", lang.c_str(), 1);
+ locale = lang;
#endif
-
#ifdef _WIN32
putenv(const_cast<char *>((std::string("LANG=") + lang).c_str()));
+ locale = lang;
#endif
#ifdef linux
- // hopefully this gets gettext to run on all linux distributions - some like
- // ubuntu are very problematic with setting language variables.
- // If this doesn't solve the problem on your linux-distribution, here comes
- // a quote from
- // http://www.gnu.org/software/automake/manual/
- // gettext/Locale-Environment-Variables.html
- //
- // Some systems, unfortunately, set LC_ALL in /etc/profile or in similar
- // initialization files. As a user, you therefore have to unset this
- // variable if you want to set LANG and optionally some of the other LC_xxx
- // variables.
-
- /* If lang is empty, fill it with $LANG */
- if (lang.size() < 1)
- if (char const * const l = getenv("LANG"))
- lang = l;
- /* Than set the variables */
- setenv ("LANG", lang.c_str(), 1);
- setenv ("LANGUAGE", lang.c_str(), 1);
- log
- ("LANG %s, LANGUAGE %s:%s\n",
- lang.c_str(), lang.c_str(), + lang.substr(0, 2).c_str());
+ char * res = NULL;
+ char const * encoding[] = {"", ".utf-8", "@euro", ".UTF-8"};
+ std::size_t found = alt_str.find(',', 0);
+ bool leave_while = false;
+ while (found != std::string::npos) {
+ std::string base_locale = alt_str.substr(0, int(found));
+ alt_str = alt_str.erase(0, int(found) + 1);
+
+ for (int j = 0; j < 4; ++j) {
+ std::string try_locale = base_locale + encoding[j];
+ res = SETLOCALE(LC_MESSAGES, try_locale.c_str());
+ if (res) {
+ locale = try_locale;
+ log("using locale %s\n", try_locale.c_str());
+ leave_while = true;
+ break;
+ } else {
+ //log("locale is not working: %s\n", try_locale.c_str());
+ }
+ }
+ if (leave_while) break;
+
+ found = alt_str.find(',', 0);
+ }
+ if (leave_while) {
+ setenv("LANG", locale.c_str(), 1);
+ } else {
+ log("No corresponding locale was found!\n");
+ }
/* Finally make changes known. */
++_nl_msg_cat_cntr;
#endif
- setlocale(LC_ALL, ""); // call to libintl
- locale = lang.c_str();
+
+ SETLOCALE(LC_NUMERIC, NULL);
+ SETLOCALE(LC_ALL, NULL);
if (textdomains.size()) {
char const * const domain = textdomains.back().first.c_str();
=== modified file 'src/i18n.h'
--- src/i18n.h 2010-04-12 09:11:24 +0000
+++ src/i18n.h 2011-02-10 10:00:41 +0000
@@ -48,6 +48,7 @@
~Textdomain() {release_textdomain();}
};
+void init_locale();
void set_locale(std::string);
std::string const & get_locale();
=== modified file 'src/wlapplication.cc'
--- src/wlapplication.cc 2010-12-14 12:36:29 +0000
+++ src/wlapplication.cc 2011-02-10 10:00:41 +0000
@@ -286,6 +286,7 @@
init_settings();
if (m_default_datadirs)
setup_searchpaths(m_commandline["EXENAME"]);
+ init_language(); // search paths must already be set up
cleanup_replays();
init_hardware();
@@ -780,16 +781,6 @@
//then parse the commandline - overwrites conffile settings
handle_commandline_parameters();
- // Set Locale and grab default domain
- i18n::set_locale(s.get_string("language", ""));
-
- std::string localedir = s.get_string("localedir", INSTALL_LOCALEDIR);
- i18n::set_localedir(find_relative_locale_path(localedir));
-
- i18n::grab_textdomain("widelands");
-
- log("using locale %s\n", i18n::get_locale().c_str());
-
set_input_grab(s.get_bool("inputgrab", false));
set_mouse_swap(s.get_bool("swapmouse", false));
@@ -835,6 +826,23 @@
}
/**
+ * Initialize language settings
+ */
+void WLApplication::init_language() {
+ // retrieve configuration settings
+ Section & s = g_options.pull_section("global");
+
+ // Initialize locale and grab "widelands" textdomain
+ i18n::init_locale();
+ std::string localedir = s.get_string("localedir", INSTALL_LOCALEDIR);
+ i18n::set_localedir(find_relative_locale_path(localedir));
+ i18n::grab_textdomain("widelands");
+
+ // Set locale corresponding to selected language
+ i18n::set_locale(s.get_string("language", ""));
+}
+
+/**
* Remember the last settings: write them into the config file
*/
void WLApplication::shutdown_settings()
=== modified file 'src/wlapplication.h'
--- src/wlapplication.h 2010-11-21 11:44:22 +0000
+++ src/wlapplication.h 2011-02-10 10:00:41 +0000
@@ -222,6 +222,7 @@
bool poll_event(SDL_Event &, bool throttle);
bool init_settings();
+ void init_language();
std::string find_relative_locale_path(std::string localedir);
void shutdown_settings();
=== added file 'txts/locales'
--- txts/locales 1970-01-01 00:00:00 +0000
+++ txts/locales 2011-02-10 10:00:41 +0000
@@ -0,0 +1,44 @@
+[alternatives]
+ar="ar,ar_AR,ar_AE,ar_BH,ar_DZ,ar_EG,ar_IN,ar_IQ,ar_JO,ar_KW,ar_LB,ar_LY,ar_MA,ar_OM,ar_QA,ar_SA,ar_SD,ar_SY,ar_TN,ar_YE"
+ca="ca,ca_ES,ca_ES@valencia,ca_FR,ca_IT"
+cs="cs,cs_CZ"
+da="da,da_DK"
+de="de,de_DE,de_AT,de_CH,de_LI,de_LU,de_BE"
+en="en,en_US,en_GB,en_AU,en_CA,en_AG,en_BW,en_DK,en_HK,en_IE,en_IN,en_NG,en_NZ,en_PH,en_SG,en_ZA,en_ZW"
+en_AU="en_AU,en,en_US,en_GB"
+en_CA="en_CA,en,en_US,en_GB"
+en_GB="en_GB,en,en_US"
+eo="eo,eo_XX"
+es="es,es_ES,es_MX,es_US"
+et="et,et_EE"
+eu="eu,eu_ES,eu_FR"
+fa="fa,fa_IR"
+fi="fi,fi_FI"
+fr="fr,fr_FR,fr_CH,fr_BE,fr_CA,fr_LU"
+gl="ga,gl_ES"
+he="he,he_IL"
+hu="hu,hu_HU"
+ia="ia"
+id="id,id_ID"
+it="it,it_IT,it_CH"
+ja="ja,ja_JP"
+ko="ko,ko_KR"
+la="la,la_AU"
+ms="ms,ms_MY"
+nb="nb,nb_NO"
+nl="nl,nl_NL,nl_BE,nl_AW"
+nn="nn,nn_NO"
+oc="oc,oc_FR"
+pl="pl,pl_PL"
+pt="pt,pt_PT,pt_BR"
+pt_BR="pt_BR,pt,pt_PT"
+ru="ru,ru_RU,ru_UA"
+si="si,si_LK"
+sk="sk,sk_SK"
+sl="sl,sl_SI"
+sr="sr,sr_RS,sr_ME"
+sv="sv,sv_FI,sv_SE"
+tr="tr,tr_TR,tr_CY"
+uk="uk,uk_UA"
+vi="vi,vi_VN"
+
Follow ups
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: Martin, 2011-02-18
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: SirVer, 2011-02-18
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: Nasenbaer, 2011-02-17
-
[Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: noreply, 2011-02-17
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: Nasenbaer, 2011-02-17
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: Jari Hautio, 2011-02-17
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: Hans Joachim Desserud, 2011-02-17
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: Martin, 2011-02-16
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: Nasenbaer, 2011-02-16
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: Nasenbaer, 2011-02-16
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: Martin, 2011-02-15
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: Nasenbaer, 2011-02-14
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: Tino, 2011-02-14
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: SirVer, 2011-02-14
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: Martin, 2011-02-14
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: SirVer, 2011-02-13
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: Martin, 2011-02-12
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: Martin, 2011-02-12
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: SirVer, 2011-02-12
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: Martin, 2011-02-12
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: Hans Joachim Desserud, 2011-02-11
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: SirVer, 2011-02-11
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: Martin, 2011-02-11
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: Nasenbaer, 2011-02-11
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: Jari Hautio, 2011-02-10
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: Tino, 2011-02-10
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: Martin, 2011-02-10
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: Martin, 2011-02-10
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: SirVer, 2011-02-10
-
Re: [Merge] lp:~widelands-dev/widelands/martin_i18n into lp:widelands
From: SirVer, 2011-02-10