// 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>
{
}
+#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__
+// implemented in CocoaHelpers.mm
+#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"
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");
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;
}
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,
}
_currentLocale = locale;
+
+ // load resource for system messages (translations for fgfs internal messages)
+ loadResource("sys");
+
return true;
}
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;
}
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;
}
}
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)
{
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;
+
+}