diff --git a/coding/coding_tests/multilang_utf8_string_test.cpp b/coding/coding_tests/multilang_utf8_string_test.cpp index 2b76949e09..e32061dcc3 100644 --- a/coding/coding_tests/multilang_utf8_string_test.cpp +++ b/coding/coding_tests/multilang_utf8_string_test.cpp @@ -45,7 +45,7 @@ UNIT_TEST(MultilangString_Smoke) { StringUtf8Multilang s; - lang_string arr[] = { {"def", "default"}, + lang_string arr[] = { {"default", "default"}, {"en", "abcd"}, {"ru", "\xD0\xA0\xD0\xB0\xD1\x88\xD0\xBA\xD0\xB0"}, {"be", "\xE2\x82\xAC\xF0\xA4\xAD\xA2"} }; diff --git a/coding/multilang_utf8_string.cpp b/coding/multilang_utf8_string.cpp index 297d2c22d8..0a7a1d844e 100644 --- a/coding/multilang_utf8_string.cpp +++ b/coding/multilang_utf8_string.cpp @@ -1,10 +1,16 @@ #include "multilang_utf8_string.hpp" - - -char StringUtf8Multilang::GetLangIndex(string const & lang) const +char StringUtf8Multilang::m_priorities[] = { - char const * arr[] = { "def", + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63 +}; + +char StringUtf8Multilang::GetLangIndex(string const & lang) +{ + static char const * arr[] = { "default", "en", "ja", "fr", "ko_rm", "ar", "de", "ru", "sv", "zh", "fi", "ko", "ka", "he", "be", "nl", "ga", "ja_rm", "el", "it", "es", "th", "zh_pinyin", "ca", "cy", "hu", "hsb", "sr", "fa", "eu", "pl", @@ -75,3 +81,45 @@ bool StringUtf8Multilang::GetString(char lang, string & utf8s) const return false; } + +void StringUtf8Multilang::SetPreferableLanguages(vector const & langCodes) +{ + CHECK_EQUAL(langCodes.size(), 64, ()); + for (size_t i = 0; i < langCodes.size(); ++i) + { + char index = GetLangIndex(langCodes[i]); + if (index >= 0) + m_priorities[static_cast(index)] = i; + else + { + ASSERT(false, ("Invalid language code")); + } + CHECK_GREATER_OR_EQUAL(m_priorities[i], 0, ("Unsupported language", langCodes[i])); + } +} + +void StringUtf8Multilang::GetPreferableString(string & utf8s) const +{ + size_t i = 0; + size_t const sz = m_s.size(); + + int currPriority = 256; + while (i < sz) + { + size_t const next = GetNextIndex(i); + + int p = m_priorities[m_s[i] & 0x3F]; + if (p < currPriority) + { + ++i; + + currPriority = p; + utf8s.assign(m_s.c_str() + i, next - i); + + if (p == 0) + return; + } + + i = next; + } +} diff --git a/coding/multilang_utf8_string.hpp b/coding/multilang_utf8_string.hpp index 97a1a56d14..7ff829f01c 100644 --- a/coding/multilang_utf8_string.hpp +++ b/coding/multilang_utf8_string.hpp @@ -33,7 +33,9 @@ class StringUtf8Multilang string m_s; size_t GetNextIndex(size_t i) const; - char GetLangIndex(string const & lang) const; + static char GetLangIndex(string const & lang); + + static char m_priorities[64]; public: inline bool operator== (StringUtf8Multilang const & rhs) const @@ -52,6 +54,9 @@ public: AddString(l, utf8s); } + static void SetPreferableLanguages(vector const & langCodes); + /// Takes language priorities into an account + void GetPreferableString(string & utf8s) const; bool GetString(char lang, string & utf8s) const; bool GetString(string const & lang, string & utf8s) const { diff --git a/generator/osm2type.cpp b/generator/osm2type.cpp index 233958b06d..2b83551c8e 100644 --- a/generator/osm2type.cpp +++ b/generator/osm2type.cpp @@ -504,7 +504,7 @@ namespace ftype { else if (s == "name") { m_ok = true; - m_lang = "def"; + m_lang = "default"; } } }; diff --git a/indexer/feature.cpp b/indexer/feature.cpp index 54f18ad55a..259ace4c20 100644 --- a/indexer/feature.cpp +++ b/indexer/feature.cpp @@ -898,7 +898,7 @@ FeatureType::geom_stat_t FeatureType::GetTrianglesSize(int scale) const return geom_stat_t(sz, m_Triangles.size()); } -string FeatureType::GetDrawableName(char lang) const +string FeatureType::GetPreferredDrawableName() const { uint8_t const h = Header(); string res; @@ -908,7 +908,7 @@ string FeatureType::GetDrawableName(char lang) const if (!m_bCommonParsed) ParseCommon(); - GetName(lang, res); + GetName(res); if (res.empty() && GetFeatureType() == GEOM_AREA) res = m_Params.house.Get(); diff --git a/indexer/feature.hpp b/indexer/feature.hpp index 364a610a5f..654ccacc3d 100644 --- a/indexer/feature.hpp +++ b/indexer/feature.hpp @@ -201,13 +201,13 @@ public: return m_Params.layer; } - inline bool GetName(char lang, string & utf8s) const + inline void GetName(string & utf8s) const { if (!(Header() & feature::HEADER_HAS_NAME)) - return false; + return;// false; if (!m_bCommonParsed) ParseCommon(); - return m_Params.name.GetString(lang, utf8s); + m_Params.name.GetPreferableString(utf8s); } inline m2::RectD GetLimitRect() const @@ -371,7 +371,7 @@ public: /// For test cases only. string DebugString(int scale) const; - string GetDrawableName(char lang) const; + string GetPreferredDrawableName() const; /// @name Statistic functions. //@{ diff --git a/map/framework.cpp b/map/framework.cpp index 1795b4dc40..40dd044a6d 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -5,6 +5,7 @@ #include "drawer_yg.hpp" #include "feature_vec_model.hpp" #include "benchmark_provider.hpp" +#include "languages.hpp" #include "../indexer/feature_visibility.hpp" #include "../indexer/feature.hpp" @@ -137,7 +138,7 @@ namespace fwork m_renderState->m_isEmptyModelCurrent = false; - shared_ptr ptr(new di::DrawInfo(f.GetDrawableName(0))); + shared_ptr ptr(new di::DrawInfo(f.GetPreferredDrawableName())); using namespace get_pts; @@ -324,6 +325,11 @@ void FrameWork::AddRedrawCommandSure() boost::bind(&this_type::OnGpsUpdate, this, _1)); GetLocationManager().SetCompassObserver( boost::bind(&this_type::OnCompassUpdate, this, _1)); + + // set language priorities + languages::CodesT langCodes; + languages::GetCurrentSettings(langCodes); + StringUtf8Multilang::SetPreferableLanguages(langCodes); } template diff --git a/map/languages.cpp b/map/languages.cpp index bb7fe9a600..4b2dcca235 100644 --- a/map/languages.cpp +++ b/map/languages.cpp @@ -6,6 +6,7 @@ #include "../coding/file_reader.hpp" #include "../coding/strutil.hpp" +#include "../coding/multilang_utf8_string.hpp" #include "../platform/platform.hpp" @@ -54,6 +55,15 @@ namespace languages } }; + void GetCurrentSettings(CodesT & outLangCodes) + { + CodesAndNamesT res; + GetCurrentSettings(res); + outLangCodes.clear(); + for (CodesAndNamesT::iterator it = res.begin(); it != res.end(); ++it) + outLangCodes.push_back(it->first); + } + void GetCurrentSettings(CodesAndNamesT & outLanguages) { string settingsString; @@ -73,6 +83,9 @@ namespace languages CHECK_EQUAL(langs.size(), MAX_SUPPORTED_LANGUAGES, ()); string const saveString = JoinStrings(langs.begin(), langs.end(), LANG_DELIMETER); Settings::Set(SETTING_LANG_KEY, saveString); + + // apply new settings + StringUtf8Multilang::SetPreferableLanguages(langs); } bool GetSupportedLanguages(CodesAndNamesT & outLanguages) diff --git a/map/languages.hpp b/map/languages.hpp index dfea3a814d..871698231d 100644 --- a/map/languages.hpp +++ b/map/languages.hpp @@ -7,8 +7,9 @@ namespace languages { typedef vector > CodesAndNamesT; -typedef vector CodesT; + typedef vector CodesT; + void GetCurrentSettings(CodesT & outLangCodes); void GetCurrentSettings(CodesAndNamesT & outLanguages); void SaveSettings(CodesT const & langs); /// @return true if loaded default lang list which was used diff --git a/qt/searchwindow.cpp b/qt/searchwindow.cpp index f208678005..e08699e61c 100644 --- a/qt/searchwindow.cpp +++ b/qt/searchwindow.cpp @@ -28,7 +28,8 @@ FindTableWnd::FindTableWnd(QWidget * pParent, FindEditorWnd * pEditor, model_t * bool FindTableWnd::AddFeature(FeatureType const & f) { string utf8name; - if (f.GetName(0, utf8name) && !utf8name.empty()) + f.GetName(utf8name); + if (!utf8name.empty()) { // 200 rows is enough int const r = rowCount();