forked from organicmaps/organicmaps
Get user preferred languages on 1st startup and use them for text dislpaying
@TODO windows implementation
This commit is contained in:
parent
62c19e2429
commit
a64b3355df
6 changed files with 170 additions and 1 deletions
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -50,6 +50,8 @@ HEADERS += \
|
|||
download_manager.hpp \
|
||||
location.hpp \
|
||||
concurrent_runner.hpp \
|
||||
preferred_languages.hpp \
|
||||
|
||||
SOURCES += \
|
||||
location_manager.cpp \
|
||||
preferred_languages.cpp \
|
||||
|
|
36
platform/platform_tests/language_test.cpp
Normal file
36
platform/platform_tests/language_test.cpp
Normal file
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -27,3 +27,4 @@ SOURCES += \
|
|||
download_test.cpp \
|
||||
jansson_test.cpp \
|
||||
concurrent_runner_test.cpp \
|
||||
language_test.cpp \
|
||||
|
|
114
platform/preferred_languages.cpp
Normal file
114
platform/preferred_languages.cpp
Normal file
|
@ -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];
|
||||
}
|
||||
|
||||
}
|
13
platform/preferred_languages.hpp
Normal file
13
platform/preferred_languages.hpp
Normal file
|
@ -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();
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue