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:
authorArsentiy Milchakov <a.milchakov@corp.mail.ru>2016-09-08 14:47:06 +0300
committerArsentiy Milchakov <a.milchakov@corp.mail.ru>2016-09-08 14:47:06 +0300
commit3320c9eddabd67330b6d132ba71cfc822f23fa95 (patch)
tree19ebe2cc9283e86657985e7c2273ee43e4502938 /indexer/editable_map_object.cpp
parenta43c309fc7adfbd853133debc712a86be3d149f9 (diff)
localized names part 3
Diffstat (limited to 'indexer/editable_map_object.cpp')
-rw-r--r--indexer/editable_map_object.cpp177
1 files changed, 170 insertions, 7 deletions
diff --git a/indexer/editable_map_object.cpp b/indexer/editable_map_object.cpp
index e7866b6a12..c7121920a9 100644
--- a/indexer/editable_map_object.cpp
+++ b/indexer/editable_map_object.cpp
@@ -13,6 +13,8 @@
namespace
{
+size_t const kFakeNamesCount = 2;
+
bool ExtractName(StringUtf8Multilang const & names, int8_t const langCode,
vector<osm::LocalizedName> & result)
{
@@ -70,6 +72,103 @@ bool IsProtocolSpecified(string const & website)
{
return GetProtocolNameLength(website) > 0;
}
+osm::FakeNames MakeFakeSource(StringUtf8Multilang const & source,
+ vector<int8_t> const & mwmLanguages, StringUtf8Multilang & fakeSource)
+{
+ string defaultName;
+ // Fake names works for mono language (official) speaking countries-only.
+ if (mwmLanguages.size() != 1 || !source.GetString(StringUtf8Multilang::kDefaultCode, defaultName))
+ {
+ return {};
+ }
+
+ osm::FakeNames fakeNames;
+ // Mwm name has higher priority then English name.
+ array<int8_t, kFakeNamesCount> fillCandidates = {{mwmLanguages.front(), StringUtf8Multilang::kEnglishCode}};
+ fakeSource = source;
+
+ string tempName;
+ for (auto const code : fillCandidates)
+ {
+ if (!source.GetString(code, tempName))
+ {
+ tempName = defaultName;
+ fakeSource.AddString(code, defaultName);
+ }
+
+ fakeNames.names.push_back({code, tempName});
+ }
+
+ fakeNames.defaultName = defaultName;
+
+ return fakeNames;
+}
+
+// Tries to set default name from the localized name. Returns false when there's no such localized name.
+bool TryToFillDefaultNameFromCode(int8_t const code, StringUtf8Multilang & names)
+{
+ string newDefaultName;
+ if (code != StringUtf8Multilang::kUnsupportedLanguageCode)
+ names.GetString(code, newDefaultName);
+
+ // Default name can not be empty.
+ if (!newDefaultName.empty())
+ {
+ names.AddString(StringUtf8Multilang::kDefaultCode, newDefaultName);
+ return true;
+ }
+
+ return false;
+}
+
+// Tries to set default name to any non-empty localized name.
+// This is the case when fake names were cleared.
+void TryToFillDefaultNameFromAnyLanguage(StringUtf8Multilang & names)
+{
+ names.ForEach([&names](int8_t langCode, string const & name)
+ {
+ if (name.empty() || langCode == StringUtf8Multilang::kDefaultCode)
+ return true;
+
+ names.AddString(StringUtf8Multilang::kDefaultCode, name);
+ return false;
+ });
+}
+
+void RemoveFakesFromName(osm::FakeNames const & fakeNames, StringUtf8Multilang & name)
+{
+ vector<int8_t> codesToExclude;
+ string defaultName;
+ name.GetString(StringUtf8Multilang::kDefaultCode, defaultName);
+
+ for (auto const & item : fakeNames.names)
+ {
+ string tempName;
+ if (!name.GetString(item.m_code, tempName))
+ continue;
+ // No need to save in case when name is empty, duplicate of default name or was not changed.
+ if (tempName.empty() || tempName == defaultName ||
+ (tempName == item.m_filledName && tempName == fakeNames.defaultName))
+ {
+ codesToExclude.push_back(item.m_code);
+ }
+ }
+
+ if (codesToExclude.empty())
+ return;
+
+ StringUtf8Multilang nameWithoutFakes;
+ name.ForEach([&codesToExclude, &nameWithoutFakes](int8_t langCode, string const & value)
+ {
+ auto const it = find(codesToExclude.begin(), codesToExclude.end(), langCode);
+ if (it == codesToExclude.end())
+ nameWithoutFakes.AddString(langCode, value);
+
+ return true;
+ });
+
+ name = nameWithoutFakes;
+}
} // namespace
namespace osm
@@ -112,7 +211,7 @@ vector<feature::Metadata::EType> const & EditableMapObject::GetEditableFields()
StringUtf8Multilang const & EditableMapObject::GetName() const { return m_name; }
-NamesDataSource EditableMapObject::GetNamesDataSource() const
+NamesDataSource EditableMapObject::GetNamesDataSource()
{
auto const mwmInfo = GetID().m_mwmId.GetInfo();
@@ -124,7 +223,10 @@ NamesDataSource EditableMapObject::GetNamesDataSource() const
auto const userLangCode = StringUtf8Multilang::GetLangIndex(languages::GetCurrentNorm());
- return GetNamesDataSource(m_name, mwmLanguages, userLangCode);
+ StringUtf8Multilang fakeSource;
+ m_fakeNames = MakeFakeSource(m_name, mwmLanguages, fakeSource);
+
+ return GetNamesDataSource(fakeSource, mwmLanguages, userLangCode);
}
// static
@@ -190,13 +292,14 @@ void EditableMapObject::SetName(StringUtf8Multilang const & name) { m_name = nam
void EditableMapObject::SetName(string name, int8_t langCode)
{
strings::Trim(name);
- if (name.empty())
- return;
- ASSERT_NOT_EQUAL(StringUtf8Multilang::kDefaultCode, langCode,
- ("Direct editing of default name is deprecated."));
+ if (m_namesAdvancedMode)
+ {
+ m_name.AddString(langCode, name);
+ return;
+ }
- if (!Editor::Instance().OriginalFeatureHasDefaultName(GetID()))
+ if (!name.empty() && !Editor::Instance().OriginalFeatureHasDefaultName(GetID()))
{
const auto mwmInfo = GetID().m_mwmId.GetInfo();
@@ -228,6 +331,43 @@ bool EditableMapObject::CanUseAsDefaultName(int8_t const lang, vector<int8_t> co
return false;
}
+// static
+void EditableMapObject::RemoveFakeNames(FakeNames const & fakeNames, StringUtf8Multilang & name)
+{
+ if (fakeNames.names.empty())
+ return;
+
+ int8_t newDefaultNameCode = StringUtf8Multilang::kUnsupportedLanguageCode;
+ size_t changedCount = 0;
+ string defaultName;
+ name.GetString(StringUtf8Multilang::kDefaultCode, defaultName);
+
+ // New default name calculation priority: 1. name on mwm language, 2. english name.
+ for (auto it = fakeNames.names.rbegin(); it != fakeNames.names.rend(); ++it)
+ {
+ string tempName;
+ if (!name.GetString(it->m_code, tempName))
+ continue;
+
+ if (tempName != it->m_filledName)
+ {
+ if (!tempName.empty())
+ newDefaultNameCode = it->m_code;
+
+ ++changedCount;
+ }
+ }
+
+ // If all previously filled fake names were changed - try to change the default name.
+ if (changedCount == fakeNames.names.size())
+ {
+ if (!TryToFillDefaultNameFromCode(newDefaultNameCode, name))
+ TryToFillDefaultNameFromAnyLanguage(name);
+ }
+
+ RemoveFakesFromName(fakeNames, name);
+}
+
void EditableMapObject::SetMercator(m2::PointD const & center) { m_mercator = center; }
void EditableMapObject::SetType(uint32_t featureType)
@@ -357,6 +497,29 @@ void EditableMapObject::SetOpeningHours(string const & openingHours)
void EditableMapObject::SetPointType() { m_geomType = feature::EGeomType::GEOM_POINT; }
+
+void EditableMapObject::RemoveBlankNames()
+{
+ StringUtf8Multilang nameWithoutBlanks;
+ m_name.ForEach([&nameWithoutBlanks](int8_t langCode, string const & name)
+ {
+ if (!name.empty())
+ nameWithoutBlanks.AddString(langCode, name);
+
+ return true;
+ });
+
+ m_name = nameWithoutBlanks;
+}
+
+void EditableMapObject::RemoveNeedlessNames()
+{
+ if (!IsNamesAdvancedModeEnabled())
+ RemoveFakeNames(m_fakeNames, m_name);
+
+ RemoveBlankNames();
+}
+
// static
bool EditableMapObject::ValidateBuildingLevels(string const & buildingLevels)
{