]> git.mxchange.org Git - flightgear.git/blobdiff - src/Main/locale.cxx
Remove confusing reference to SDL/GLUT
[flightgear.git] / src / Main / locale.cxx
index 27aff0c8d546bdad44d111e5d979211539658350..1d30dfed0f3d086cd972d7ea1dfce642dd4358b6 100644 (file)
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
 
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+
+#include <boost/foreach.hpp>
+
 #include <simgear/props/props_io.hxx>
 #include <simgear/structure/exception.hxx>
 
@@ -37,12 +47,90 @@ FGLocale::~FGLocale()
 {
 }
 
+#ifdef _WIN32
+/**
+ * Determine locale/language settings on Windows.
+ *
+ * Copyright (C) 1997, 2002, 2003 Martin von Loewis
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies.
+ *
+ * This software comes with no warranty. Use at your own risk.
+ */
+string_list
+FGLocale::getUserLanguage()
+{
+    string_list result;
+    static char locale[100] = {0};
+
+    if (GetLocaleInfo(LOCALE_USER_DEFAULT,
+                      LOCALE_SISO639LANGNAME,
+                      locale, sizeof(locale)))
+    {
+        SG_LOG(SG_GENERAL, SG_DEBUG, "Detected locale's language setting: " << locale);
+        size_t i = strlen(locale);
+        locale[i++] = '_';
+        if (GetLocaleInfo(LOCALE_USER_DEFAULT,
+                          LOCALE_SISO3166CTRYNAME,
+                          locale+i, (int)(sizeof(locale)-i)))
+        {
+            result.push_back(locale);
+            return result;
+        }
+        
+        locale[--i] = 0;
+        SG_LOG(SG_GENERAL, SG_WARN, "Failed to detected locale's country setting.");
+        result.push_back(locale);
+        return result;
+    }
+
+    return result;
+}
+#elif __APPLE__
+
+// determine locale / langauge on Mac
+#include <CoreFoundation/CoreFoundation.h>
+
+string_list
+FGLocale::getUserLanguage()
+{
+    string_list result;
+    CFArrayRef langs = CFLocaleCopyPreferredLanguages();
+    
+    char buffer[64];
+    for (int i=0; i<CFArrayGetCount(langs); ++i) {
+        CFStringRef s = (CFStringRef) CFArrayGetValueAtIndex(langs, i);
+        CFStringGetCString(s, buffer, 64, kCFStringEncodingASCII);
+        result.push_back(buffer);
+    }
+    
+    CFRelease(langs);
+    return result;
+}
+
+#else
+/**
+ * Determine locale/language settings on Linux/Unix.
+ */
+string_list
+FGLocale::getUserLanguage()
+{
+    string_list result;
+    const char* langEnv = ::getenv("LANG");
+    if (langEnv) {
+        result.push_back(langEnv);
+    }
+    
+    return result;
+}
+#endif
+
 // Search property tree for matching locale description
 SGPropertyNode*
 FGLocale::findLocaleNode(const string& language)
 {
-    SG_LOG(SG_GENERAL, SG_INFO, "Searching language resource for locale: " << language);
-
     SGPropertyNode* node = NULL;
 
     // remove character encoding from the locale spec, i.e. "de_DE.utf8" => "de_DE"
@@ -54,15 +142,7 @@ FGLocale::findLocaleNode(const string& language)
             return node;
     }
 
-    // try country's default resource, i.e. "de_DE" => "de"
-    pos = language.find("_");
-    if ((pos != string::npos)&&(pos>0))
-    {
-        node = findLocaleNode(language.substr(0, pos));
-        if (node)
-            return node;
-    }
-
+    SG_LOG(SG_GENERAL, SG_DEBUG, "Searching language resource for locale: " << language);
     // search locale using full string
     vector<SGPropertyNode_ptr> localeList = _intl->getChildren("locale");
 
@@ -72,11 +152,23 @@ FGLocale::findLocaleNode(const string& language)
 
        for (size_t j = 0; j < langList.size(); j++)
        {
-          if (!language.compare(langList[j]->getStringValue()))
-             return localeList[i];
+           if (!language.compare(langList[j]->getStringValue()))
+           {
+               SG_LOG(SG_GENERAL, SG_INFO, "Found language resource for: " << language);
+               return localeList[i];
+           }
        }
     }
 
+    // try country's default resource, i.e. "de_DE" => "de"
+    pos = language.find("_");
+    if ((pos != string::npos)&&(pos>0))
+    {
+        node = findLocaleNode(language.substr(0, pos));
+        if (node)
+            return node;
+    }
+
     return NULL;
 }
 
@@ -85,18 +177,27 @@ FGLocale::findLocaleNode(const string& language)
 bool
 FGLocale::selectLanguage(const char *language)
 {
-    // Use environment setting when no language is given.
-    if ((language == NULL)||(language[0]==0))
-        language = ::getenv("LANG");
-
-    // Use plain C locale if nothing is available.
-    if (language == NULL)
-    {
-        SG_LOG(SG_GENERAL, SG_INFO, "Unable to detect the language" );
-        language = "C";
+    string_list languages = getUserLanguage();
+    if (languages.empty()) {
+        // Use plain C locale if nothing is available.
+        SG_LOG(SG_GENERAL, SG_WARN, "Unable to detect system language" );
+        languages.push_back("C");
+    }
+    
+    // if we were passed a language option, try it first
+    if ((language != NULL) && (strlen(language) > 0)) {
+        languages.insert(languages.begin(), string(language));
     }
 
-    SGPropertyNode *locale = findLocaleNode(language);
+    
+    SGPropertyNode *locale = NULL;
+    BOOST_FOREACH(string lang, languages) {
+        locale = findLocaleNode(lang);
+        if (locale) {
+            break;
+        }
+    }
+    
     if (!locale)
     {
        SG_LOG(SG_GENERAL, SG_ALERT,
@@ -105,6 +206,10 @@ FGLocale::selectLanguage(const char *language)
     }
 
     _currentLocale = locale;
+
+    // load resource for system messages (translations for fgfs internal messages)
+    loadResource("sys");
+
     return true;
 }
 
@@ -120,7 +225,7 @@ FGLocale::loadResource(SGPropertyNode* localeNode, const char* resource)
     const char *path_str = stringNode->getStringValue(resource, NULL);
     if (!path_str)
     {
-        SG_LOG(SG_GENERAL, SG_ALERT, "No path in " << stringNode->getPath() << "/" << resource << ".");
+        SG_LOG(SG_GENERAL, SG_WARN, "No path in " << stringNode->getPath() << "/" << resource << ".");
         return NULL;
     }
 
@@ -208,14 +313,14 @@ FGLocale::getLocalizedStrings(const char* id, const char* resource)
         if (_currentLocale)
         {
             simgear::PropertyList s = getLocalizedStrings(_currentLocale, id, resource);
-            if (s.size())
+            if (! s.empty())
                 return s;
         }
 
         if (_defaultLocale)
         {
             simgear::PropertyList s = getLocalizedStrings(_defaultLocale, id, resource);
-            if (s.size())
+            if (! s.empty())
                 return s;
         }
     }