changeset 2013:d24c304424d4

Updated gettext: improved language support under Windows. (special thanks to igorko :)
author thegusty999
date Mon, 31 Oct 2011 19:05:25 +0000
parents 02f0c1e2ba01
children 19f4755627c6
files src/core/gettext.cpp src/core/gettext.h src/gui/optionswindow.cpp
diffstat 3 files changed, 105 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/gettext.cpp	Mon Oct 31 01:15:43 2011 +0000
+++ b/src/core/gettext.cpp	Mon Oct 31 19:05:25 2011 +0000
@@ -23,10 +23,16 @@
 
 std::string Gettext::m_locale;
 
+#ifdef WIN32
+std::map <std::string, int> Gettext::winLanguageMappings_;
+#endif
+
 bool Gettext::m_changed;
 
 void Gettext::init(const char* locale, std::string pathToTranslationFiles)
 {
+	preInit ();
+
 	bindtextdomain ("defend_dwarfenwall",pathToTranslationFiles.c_str());
 	bind_textdomain_codeset ("defend_dwarfenwall","UTF-8");
 
@@ -102,6 +108,23 @@
 
 }
 
+
+void Gettext::preInit ()
+{
+#if WIN32
+	// Prepare the mappings.
+	// -1 for an entry means it's unsupported!
+	winLanguageMappings_["en"] = 0x0409; // en-US
+	winLanguageMappings_["de"] = 0x0407; // de-DE
+	winLanguageMappings_["it"] = 0x0410; // it-IT
+	winLanguageMappings_["pl"] = 0x0415;
+	winLanguageMappings_["pt"] = 0x0816; // pt-PT
+	winLanguageMappings_["ru"] = 0x0419;
+	winLanguageMappings_["uk"] = 1058;
+#endif
+}
+
+
 const char* Gettext::getLocale()
 {
 	return m_locale.c_str();
@@ -123,26 +146,31 @@
 
 	if (locale != m_locale)
 	{
-	    #ifdef WIN32
-            if (locale != "")
-            {
-                std::string win_locale(locale, 0, 2);
-                std::string env = "LANGUAGE=" + win_locale;
+#ifdef WIN32
+		if (locale != "")
+		{
+			std::string win_locale(locale, 0, 2);
+			std::string env = "LANGUAGE=" + win_locale;
 
-                _putenv(env.c_str());
-                SetEnvironmentVariable("LANGUAGE", win_locale.c_str());
+			_putenv(env.c_str());
+			SetEnvironmentVariable("LANGUAGE", win_locale.c_str());
 
-                char lang[50];
-                GetEnvironmentVariable("LANGUAGE",lang,50);
-                DEBUGX("current language (GetEnvironmentVariable) %s",lang);
-                DEBUGX("current language (getenv) %s",getenv("LANGUAGE"));
+			char lang[50];
+			GetEnvironmentVariable("LANGUAGE",lang,50);
+			DEBUGX("current language (GetEnvironmentVariable) %s",lang);
+			DEBUGX("current language (getenv) %s",getenv("LANGUAGE"));
 
-               m_locale = locale;
-               m_changed = true;
-               return;
-            }
+			if (setWinThreadLocale (win_locale) == 0)
+			{
+				DEBUG ("Could not change locale to %s", win_locale.c_str ());
+				return;
+			}
 
-        #endif
+			m_locale = locale;
+			m_changed = true;
+			return;
+		}
+#endif
         std::string extensions[3] = {".utf-8",".UTF-8",""};
 
         // try all possible extensions
@@ -184,3 +212,29 @@
 }
 
 
+#if WIN32
+bool Gettext::setWinThreadLocale (const std::string& newLocale)
+{
+	bool result (false);
+
+	int newCode = getLanguageCodeFromString (newLocale);
+	if (newCode == -1)
+		return false;
+	
+	DEBUG ("Setting locale to : %s", newLocale.c_str ());
+	result = SetThreadLocale (newCode);
+
+	return result;
+}
+
+int Gettext::getLanguageCodeFromString (const std::string& languageString)
+{
+	// Search for the language in the mapping.
+	std::map <std::string, int>::iterator it = winLanguageMappings_.find  (languageString);
+	if (it != winLanguageMappings_.end ())
+	{
+		return it->second;
+	}
+	return -1;
+}
+#endif // WIN32
\ No newline at end of file
--- a/src/core/gettext.h	Mon Oct 31 01:15:43 2011 +0000
+++ b/src/core/gettext.h	Mon Oct 31 19:05:25 2011 +0000
@@ -25,6 +25,7 @@
 
 #include <locale.h>
 #include <string>
+#include <map>
 
 /**
  * \class Gettext
@@ -60,7 +61,29 @@
 		 */
 		static bool getLocaleChanged();
 
+#ifdef WIN32
+		/**
+		 * \brief Specifig Windows locale setting function.
+		 */
+		static bool setWinThreadLocale (const std::string& newLocale);
+
+		/**
+		 * \brief Windows specific language code retrieval.
+		 * \param languageString the short language description, without locale (e.g. "de", "en", "it")
+		 * \note Make sure that the function preInit is called before this function, so the proper mappings are set up.
+		 * \return The language codes, like 0x0407 (German)
+		 */
+		static int getLanguageCodeFromString (const std::string& languageString);
+
+#endif
+
 	private:
+
+		/**
+		 * \brief Perform any OS specific pre-initialization steps.
+		 */
+		static void preInit ();
+
 		/**
 		 * \var std::string m_locale
 		 * \brief aktuelle Sprache
@@ -72,6 +95,10 @@
 		 * \brief Auf true gesetzt, wenn die Sprache gerade geaendert wurde (bis zum ersten Aufruf von getLocalChanged)
 		 */
 		static bool m_changed;
+
+#ifdef WIN32
+		static std::map <std::string, int> winLanguageMappings_;
+#endif
 };
 #endif
 
--- a/src/gui/optionswindow.cpp	Mon Oct 31 01:15:43 2011 +0000
+++ b/src/gui/optionswindow.cpp	Mon Oct 31 19:05:25 2011 +0000
@@ -22,6 +22,7 @@
 // The following includes are added to support video mode changes in the options window.
 #include <OGRE/OgreConfigFile.h>
 #include <OGRE/OgreException.h>
+#include <OGRE/OgreResourceGroupManager.h>
 
 OptionsWindow::OptionsWindow (Document* doc, OIS::Keyboard *keyboard)
 	:Window(doc)
@@ -770,6 +771,13 @@
 		DEBUGX("selected Language %s",item->getText().c_str());
 		StrListItem* sitem = static_cast<StrListItem*>(item);
 		Gettext::setLocale(sitem->m_data.c_str());
+
+#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
+		// A re-init seems to be needed on Windows.
+		// TODO:XXX: investigate - Augustin Preda, 2011.10.31
+		Ogre::StringVectorPtr path = Ogre::ResourceGroupManager::getSingleton().findResourceLocation("translation", "*");
+		Gettext::init(sitem->m_data.c_str(), path.get()->at(0));
+#endif
 	}
 
 	return true;