Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--map/languages.cpp5
-rw-r--r--platform/platform.pro2
-rw-r--r--platform/platform_tests/language_test.cpp36
-rw-r--r--platform/platform_tests/platform_tests.pro1
-rw-r--r--platform/preferred_languages.cpp114
-rw-r--r--platform/preferred_languages.hpp13
6 files changed, 170 insertions, 1 deletions
diff --git a/map/languages.cpp b/map/languages.cpp
index 0815b7b0d4..cbf9b7de2b 100644
--- a/map/languages.cpp
+++ b/map/languages.cpp
@@ -10,6 +10,7 @@
#include "../coding/multilang_utf8_string.hpp"
#include "../platform/platform.hpp"
+#include "../platform/preferred_languages.hpp"
#include "../std/algorithm.hpp"
#include "../std/sstream.hpp"
@@ -96,8 +97,9 @@ namespace languages
void GetCurrentSettings(CodesAndNamesT & outLanguages)
{
string settingsString;
+ // get preffered languages from the system
if (!Settings::Get(SETTING_LANG_KEY, settingsString))
- settingsString = DEFAULT_LANGUAGES; // @TODO get preffered languages from the system
+ settingsString = languages::PreferredLanguages();
CodesT currentCodes;
Collector c(currentCodes);
@@ -133,4 +135,5 @@ namespace languages
}
return !outLanguages.empty();
}
+
}
diff --git a/platform/platform.pro b/platform/platform.pro
index be31118f99..201d86856a 100644
--- a/platform/platform.pro
+++ b/platform/platform.pro
@@ -50,6 +50,8 @@ HEADERS += \
download_manager.hpp \
location.hpp \
concurrent_runner.hpp \
+ preferred_languages.hpp \
SOURCES += \
location_manager.cpp \
+ preferred_languages.cpp \
diff --git a/platform/platform_tests/language_test.cpp b/platform/platform_tests/language_test.cpp
new file mode 100644
index 0000000000..012f12cb98
--- /dev/null
+++ b/platform/platform_tests/language_test.cpp
@@ -0,0 +1,36 @@
+#include "../../testing/testing.hpp"
+
+#include "../../std/string.hpp"
+#include "../../std/vector.hpp"
+
+namespace languages
+{
+ void FilterLanguages(vector<string> & langs);
+}
+
+UNIT_TEST(LangFilter)
+{
+ vector<string> v;
+ v.push_back("en");
+ v.push_back("en-GB");
+ v.push_back("zh");
+ v.push_back("es-SP");
+ v.push_back("zh-penyn");
+ v.push_back("en-US");
+ v.push_back("ru_RU");
+ v.push_back("es");
+
+ languages::FilterLanguages(v);
+
+ vector<string> c;
+ c.push_back("en");
+ c.push_back("zh");
+ c.push_back("es");
+ c.push_back("ru");
+
+ TEST_EQUAL(v.size(), c.size(), (v, c));
+ for (size_t i = 0; i < c.size(); ++i)
+ {
+ TEST_EQUAL(c[i], v[i], (v, c));
+ }
+}
diff --git a/platform/platform_tests/platform_tests.pro b/platform/platform_tests/platform_tests.pro
index da14c67e16..2363eac358 100644
--- a/platform/platform_tests/platform_tests.pro
+++ b/platform/platform_tests/platform_tests.pro
@@ -27,3 +27,4 @@ SOURCES += \
download_test.cpp \
jansson_test.cpp \
concurrent_runner_test.cpp \
+ language_test.cpp \
diff --git a/platform/preferred_languages.cpp b/platform/preferred_languages.cpp
new file mode 100644
index 0000000000..130f3fb055
--- /dev/null
+++ b/platform/preferred_languages.cpp
@@ -0,0 +1,114 @@
+#include "preferred_languages.hpp"
+
+#include "../base/string_utils.hpp"
+#include "../base/logging.hpp"
+
+#include "../std/target_os.hpp"
+#include "../std/set.hpp"
+
+#if defined(OMIM_OS_MAC) || defined(OMIM_OS_IPHONE)
+ #include <CoreFoundation/CFLocale.h>
+ #include <CoreFoundation/CFString.h>
+
+#elif defined(OMIM_OS_WINDOWS)
+ // @TODO
+
+#else
+ #error "Define language preferences for your platform"
+
+#endif
+
+namespace languages
+{
+
+class LangFilter
+{
+ set<string> & m_known;
+public:
+ LangFilter(set<string> & known) : m_known(known) {}
+ bool operator()(string const & t)
+ {
+ return !m_known.insert(t).second;
+ }
+};
+
+class NormalizeFilter
+{
+public:
+ void operator()(string & t)
+ {
+ strings::SimpleTokenizer const iter(t, "-_ ");
+ if (iter)
+ t = *iter;
+ else
+ {
+ LOG(LWARNING, ("Invalid language"));
+ }
+ }
+};
+
+void FilterLanguages(vector<string> & langs)
+{
+ // normalize languages: en-US -> en, ru_RU -> ru etc.
+ for_each(langs.begin(), langs.end(), NormalizeFilter());
+ { // tmp storage
+ set<string> known;
+ // remove duplicate languages
+ langs.erase(remove_if(langs.begin(), langs.end(), LangFilter(known)), langs.end());
+ }
+}
+
+void SystemPreferredLanguages(vector<string> & languages)
+{
+#if defined(OMIM_OS_MAC) || defined(OMIM_OS_IPHONE)
+ // Mac and iOS implementation
+ CFArrayRef langs = CFLocaleCopyPreferredLanguages();
+ char buf[30];
+ for (CFIndex i = 0; i < CFArrayGetCount(langs); ++i)
+ {
+ CFStringRef strRef = (CFStringRef)CFArrayGetValueAtIndex(langs, i);
+ CFStringGetCString(strRef, buf, 30, kCFStringEncodingUTF8);
+ languages.push_back(buf);
+ }
+ CFRelease(langs);
+
+#elif defined(OMIM_OS_WINDOWS)
+ // @TODO Windows implementation
+#else
+ #error "Define language preferences for your platform"
+#endif
+
+ FilterLanguages(languages);
+}
+
+string PreferredLanguages()
+{
+ vector<string> arr;
+
+ SystemPreferredLanguages(arr);
+
+ // generate output string
+ string result;
+ for (size_t i = 0; i < arr.size(); ++i)
+ {
+ result.append(arr[i]);
+ result.push_back('|');
+ }
+ if (result.empty())
+ result = "default";
+ else
+ result.resize(result.size() - 1);
+ return result;
+}
+
+string CurrentLanguage()
+{
+ vector<string> arr;
+ SystemPreferredLanguages(arr);
+ if (arr.empty())
+ return "en";
+ else
+ return arr[0];
+}
+
+}
diff --git a/platform/preferred_languages.hpp b/platform/preferred_languages.hpp
new file mode 100644
index 0000000000..a492fefbe9
--- /dev/null
+++ b/platform/preferred_languages.hpp
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "../std/string.hpp"
+
+namespace languages
+{
+
+/// @return system language preferences in the form "en|ru|es|zh"
+string PreferredLanguages();
+/// @return language code for current user in the form "en"
+string CurrentLanguage();
+
+}