]> git.mxchange.org Git - flightgear.git/blobdiff - src/Main/locale.cxx
Update for changed SGPath::realpath signature
[flightgear.git] / src / Main / locale.cxx
index ae4cedf076e529932965cb4e82f4e4f815ab6792..fd7a5f2b5137aeb8a1f290a69db414f23bde2fb4 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 <cstdio>
+#include <boost/foreach.hpp>
+
 #include <simgear/props/props_io.hxx>
 #include <simgear/structure/exception.hxx>
 
@@ -53,9 +60,10 @@ FGLocale::~FGLocale()
  *
  * This software comes with no warranty. Use at your own risk.
  */
-const char*
+string_list
 FGLocale::getUserLanguage()
 {
+    string_list result;
     static char locale[100] = {0};
 
     if (GetLocaleInfo(LOCALE_USER_DEFAULT,
@@ -68,23 +76,35 @@ FGLocale::getUserLanguage()
         if (GetLocaleInfo(LOCALE_USER_DEFAULT,
                           LOCALE_SISO3166CTRYNAME,
                           locale+i, (int)(sizeof(locale)-i)))
-            return locale;
-
+        {
+            result.push_back(locale);
+            return result;
+        }
+        
         locale[--i] = 0;
         SG_LOG(SG_GENERAL, SG_WARN, "Failed to detected locale's country setting.");
-        return locale;
+        result.push_back(locale);
+        return result;
     }
 
-    return NULL;
+    return result;
 }
+#elif __APPLE__
+//  implemented in CocoaHelpers.mm
 #else
 /**
- * Determine locale/language settings on Linux (and Mac?).
+ * Determine locale/language settings on Linux/Unix.
  */
-const char*
+string_list
 FGLocale::getUserLanguage()
 {
-    return ::getenv("LANG");
+    string_list result;
+    const char* langEnv = ::getenv("LANG");
+    if (langEnv) {
+        result.push_back(langEnv);
+    }
+    
+    return result;
 }
 #endif
 
@@ -138,29 +158,42 @@ FGLocale::findLocaleNode(const string& language)
 bool
 FGLocale::selectLanguage(const char *language)
 {
-    // Use system setting when no language is given.
-    if ((language == NULL)||(language[0]==0))
-    {
-        language = getUserLanguage();
-        SG_LOG(SG_GENERAL, SG_INFO, "System language: " << ((language) ? language : "<unavailable>"));
+    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));
     }
 
-    // Use plain C locale if nothing is available.
-    if ((language == NULL)||(language[0]==0))
-    {
-        SG_LOG(SG_GENERAL, SG_WARN, "Unable to detect system language" );
-        language = "C";
+    
+    _currentLocale = NULL;
+    BOOST_FOREACH(string lang, languages) {
+        SG_LOG(SG_GENERAL, SG_DEBUG, "trying to find locale for " << lang );
+        _currentLocale = findLocaleNode(lang);
+        if (_currentLocale) {
+            SG_LOG(SG_GENERAL, SG_DEBUG, "found locale for " << lang << " at " << _currentLocale->getPath() );
+            break;
+        }
     }
+    
+    // load resource for system messages (translations for fgfs internal messages)
+    loadResource("sys");
+
+    // load resource for atc messages
+    loadResource("atc");
 
-    SGPropertyNode *locale = findLocaleNode(language);
-    if (!locale)
+    if (!_currentLocale)
     {
        SG_LOG(SG_GENERAL, SG_ALERT,
-              "No internationalization settings specified in preferences.xml" );
+              "System locale not found or no internationalization settings specified in preferences.xml. Using default (en)." );
        return false;
     }
 
-    _currentLocale = locale;
     return true;
 }
 
@@ -177,21 +210,21 @@ FGLocale::loadResource(SGPropertyNode* localeNode, const char* resource)
     if (!path_str)
     {
         SG_LOG(SG_GENERAL, SG_WARN, "No path in " << stringNode->getPath() << "/" << resource << ".");
-        return NULL;
+        return false;
     }
 
     path.append(path_str);
     SG_LOG(SG_GENERAL, SG_INFO, "Reading localized strings for '" <<
            localeNode->getStringValue("lang", "<none>")
-           <<"' from " << path.str());
+           <<"' from " << path);
 
     // load the actual file
     try
     {
-        readProperties(path.str(), stringNode->getNode(resource, 0, true));
+        readProperties(path, stringNode->getNode(resource, 0, true));
     } catch (const sg_exception &e)
     {
-        SG_LOG(SG_GENERAL, SG_ALERT, "Unable to read the localized strings from " << path.str() <<
+        SG_LOG(SG_GENERAL, SG_ALERT, "Unable to read the localized strings from " << path <<
                ". Error: " << e.getFormattedMessage());
         return false;
     }
@@ -264,14 +297,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;
         }
     }
@@ -299,6 +332,24 @@ FGLocale::getDefaultFont(const char* fallbackFont)
     return fallbackFont;
 }
 
+std::string FGLocale::localizedPrintf(const char* id, const char* resource, ... )
+{
+    va_list args;
+    va_start(args, resource);
+    string r = vlocalizedPrintf(id, resource, args);
+    va_end(args);
+    return r;
+}
+
+std::string FGLocale::vlocalizedPrintf(const char* id, const char* resource, va_list args)
+{
+    const char* format = getLocalizedString(id, resource);
+    int len = ::vsprintf(NULL, format, args);
+    char* buf = (char*) alloca(len);
+    ::vsprintf(buf, format, args);
+    return std::string(buf);
+}
+
 // Simple UTF8 to Latin1 encoder.
 void FGLocale::utf8toLatin1(string& s)
 {
@@ -348,3 +399,18 @@ void FGLocale::utf8toLatin1(string& s)
         pos++;
     }
 }
+
+const char* fgTrMsg(const char* key)
+{
+    return globals->get_locale()->getLocalizedString(key, "message");
+}
+
+std::string fgTrPrintfMsg(const char* key, ...)
+{
+    va_list args;
+    va_start(args, key);
+    string r = globals->get_locale()->vlocalizedPrintf(key, "message", args);
+    va_end(args);
+    return r;
+    
+}