// static void EditableMapObject::RemoveFakeNames(FakeNames const & fakeNames, StringUtf8Multilang & name) { if (fakeNames.m_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.m_names.rbegin(); it != fakeNames.m_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.m_names.size()) { if (!TryToFillDefaultNameFromCode(newDefaultNameCode, name)) TryToFillDefaultNameFromAnyLanguage(name); } RemoveFakesFromName(fakeNames, name); }
void TestMultilangString(lang_string const * arr, size_t count) { StringUtf8Multilang s; for (size_t i = 0; i < count; ++i) { string src(arr[i].m_str); TEST(utf8::is_valid(src.begin(), src.end()), ()); s.AddString(arr[i].m_lang, src); string comp; TEST(s.GetString(arr[i].m_lang, comp), ()); TEST_EQUAL(src, comp, ()); } for (size_t i = 0; i < count; ++i) { string comp; TEST(s.GetString(arr[i].m_lang, comp), ()); TEST_EQUAL(arr[i].m_str, comp, ()); } string test; TEST(!s.GetString("xxx", test), ()); }
void EditableMapObject::RemoveBlankAndDuplicationsForDefault() { StringUtf8Multilang editedName; string defaultName; m_name.GetString(StringUtf8Multilang::kDefaultCode, defaultName); m_name.ForEach([&defaultName, &editedName](int8_t langCode, string const & name) { auto const duplicate = langCode != StringUtf8Multilang::kDefaultCode && defaultName == name; if (!name.empty() && !duplicate) editedName.AddString(langCode, name); }); m_name = editedName; }
void Read(TSrc & src, uint8_t header) { using namespace feature; if (header & HEADER_HAS_NAME) name.Read(src); if (header & HEADER_HAS_LAYER) layer = ReadPrimitiveFromSource<int8_t>(src); if (header & HEADER_HAS_ADDINFO) { switch (header & HEADER_GEOTYPE_MASK) { case HEADER_GEOM_POINT: rank = ReadPrimitiveFromSource<uint8_t>(src); break; case HEADER_GEOM_LINE: utils::ReadString(src, ref); break; case HEADER_GEOM_AREA: case HEADER_GEOM_POINT_EX: house.Read(src); break; } } }
void Write(TSink & sink, uint8_t header) const { using namespace feature; if (header & HEADER_HAS_NAME) name.Write(sink); if (header & HEADER_HAS_LAYER) WriteToSink(sink, layer); if (header & HEADER_HAS_ADDINFO) { switch (header & HEADER_GEOTYPE_MASK) { case HEADER_GEOM_POINT: WriteToSink(sink, rank); break; case HEADER_GEOM_LINE: utils::WriteString(sink, ref); break; case HEADER_GEOM_AREA: case HEADER_GEOM_POINT_EX: house.Write(sink); break; } } }
void FeatureType::SetNames(StringUtf8Multilang const & newNames) { m_params.name.Clear(); // Validate passed string to clean up empty names (if any). newNames.ForEach([this](int8_t langCode, string const & name) -> bool { if (!name.empty()) m_params.name.AddString(langCode, name); return true; }); if (m_params.name.IsEmpty()) SetHeader(~feature::HEADER_HAS_NAME & Header()); else SetHeader(feature::HEADER_HAS_NAME | Header()); }
// static NamesDataSource EditableMapObject::GetNamesDataSource(StringUtf8Multilang const & source, vector<int8_t> const & mwmLanguages, int8_t const userLangCode) { NamesDataSource result; auto & names = result.names; auto & mandatoryCount = result.mandatoryNamesCount; // Push Mwm languages. mandatoryCount = PushMwmLanguages(source, mwmLanguages, names); // Push english name. if (ExtractName(source, StringUtf8Multilang::kEnglishCode, names)) ++mandatoryCount; // Push user's language. if (ExtractName(source, userLangCode, names)) ++mandatoryCount; // Push other languages. source.ForEach([&names, mandatoryCount](int8_t const code, string const & name) { // Exclude default name. if (StringUtf8Multilang::kDefaultCode == code) return; auto const mandatoryNamesEnd = names.begin() + mandatoryCount; // Exclude languages which are already in container (languages with top priority). auto const it = find_if( names.begin(), mandatoryNamesEnd, [code](LocalizedName const & localizedName) { return localizedName.m_code == code; }); if (mandatoryNamesEnd == it) names.emplace_back(code, name); }); return result; }
void EditorDialog::OnSave() { // Store all edits. if (m_feature.IsNameEditable()) { StringUtf8Multilang names; for (int8_t langCode = StringUtf8Multilang::kDefaultCode; langCode < StringUtf8Multilang::kMaxSupportedLanguages; ++langCode) { QLineEdit * le = findChild<QLineEdit *>(StringUtf8Multilang::GetLangByCode(langCode)); if (!le) continue; string const name = le->text().toStdString(); if (!name.empty()) names.AddString(langCode, name); } m_feature.SetName(names); } if (m_feature.IsAddressEditable()) { m_feature.SetHouseNumber(findChild<QLineEdit *>(kHouseNumberObjectName)->text().toStdString()); QString const editedStreet = findChild<QComboBox *>(kStreetObjectName)->currentText(); QStringList const names = editedStreet.split(" / ", QString::SkipEmptyParts); QString const localized = names.size() > 1 ? names.at(1) : QString(); if (!names.empty()) m_feature.SetStreet({names.at(0).toStdString(), localized.toStdString()}); else m_feature.SetStreet({}); m_feature.SetPostcode(findChild<QLineEdit *>(kPostcodeObjectName)->text().toStdString()); } for (osm::Props const prop : m_feature.GetEditableProperties()) { if (prop == osm::Props::Internet) { QComboBox * cmb = findChild<QComboBox *>(kInternetObjectName); string const str = cmb->currentText().toStdString(); osm::Internet v = osm::Internet::Unknown; if (str == DebugPrint(osm::Internet::Wlan)) v = osm::Internet::Wlan; else if (str == DebugPrint(osm::Internet::Wired)) v = osm::Internet::Wired; else if (str == DebugPrint(osm::Internet::No)) v = osm::Internet::No; else if (str == DebugPrint(osm::Internet::Yes)) v = osm::Internet::Yes; m_feature.SetInternet(v); continue; } QLineEdit * editor = findChild<QLineEdit *>(QString::fromStdString(DebugPrint(prop))); if (!editor) continue; string const v = editor->text().toStdString(); switch (prop) { case osm::Props::Phone: m_feature.SetPhone(v); break; case osm::Props::Fax: m_feature.SetFax(v); break; case osm::Props::Email: m_feature.SetEmail(v); break; case osm::Props::Website: m_feature.SetWebsite(v); break; case osm::Props::Internet: ASSERT(false, ("Is handled separately above.")); case osm::Props::Cuisine: { vector<string> cuisines; strings::Tokenize(v, ";", MakeBackInsertFunctor(cuisines)); m_feature.SetCuisines(cuisines); } break; case osm::Props::OpeningHours: m_feature.SetOpeningHours(v); break; case osm::Props::Stars: { int num; if (strings::to_int(v, num)) m_feature.SetStars(num); } break; case osm::Props::Operator: m_feature.SetOperator(v); break; case osm::Props::Elevation: { double ele; if (strings::to_double(v, ele)) m_feature.SetElevation(ele); } break; case osm::Props::Wikipedia: m_feature.SetWikipedia(v); break; case osm::Props::Flats: m_feature.SetFlats(v); break; case osm::Props::BuildingLevels: m_feature.SetBuildingLevels(v); break; } } accept(); }