From a9d1a151924707c338e631b192470d86d9ad0208 Mon Sep 17 00:00:00 2001 From: Harry Bond Date: Sun, 19 May 2024 20:40:36 +0100 Subject: [PATCH 01/36] [platform] remove redundant `=` from osm.org/go link tiny fix, looks a bit strange to have an empty query string Signed-off-by: Harry Bond --- platform/measurement_utils.cpp | 4 ++-- platform/platform_tests/measurement_tests.cpp | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/platform/measurement_utils.cpp b/platform/measurement_utils.cpp index 017e28cbf4..ddb2b0fc5e 100644 --- a/platform/measurement_utils.cpp +++ b/platform/measurement_utils.cpp @@ -215,8 +215,8 @@ string FormatOsmLink(double lat, double lon, int zoom) for (int i = 0; i < (zoom + 8) % 3; ++i) osmUrl += "-"; - - return osmUrl + "?m="; + // ?m tells OSM to display a marker + return osmUrl + "?m"; } bool OSMDistanceToMeters(string const & osmRawValue, double & outMeters) diff --git a/platform/platform_tests/measurement_tests.cpp b/platform/platform_tests/measurement_tests.cpp index 78146785fa..11ab0c9ab9 100644 --- a/platform/platform_tests/measurement_tests.cpp +++ b/platform/platform_tests/measurement_tests.cpp @@ -51,17 +51,17 @@ UNIT_TEST(LatLonToDMS_NoRounding) UNIT_TEST(FormatOsmLink) { // Zero point - TEST_EQUAL(FormatOsmLink(0, 0, 5), "https://osm.org/go/wAAAA-?m=", ()); + TEST_EQUAL(FormatOsmLink(0, 0, 5), "https://osm.org/go/wAAAA-?m", ()); // Eifel tower - TEST_EQUAL(FormatOsmLink(48.85825, 2.29450, 15), "https://osm.org/go/0BOdUs9e--?m=", ()); + TEST_EQUAL(FormatOsmLink(48.85825, 2.29450, 15), "https://osm.org/go/0BOdUs9e--?m", ()); // Buenos Aires - TEST_EQUAL(FormatOsmLink(-34.6061, -58.4360, 10), "https://osm.org/go/Mnx6SB?m=", ()); + TEST_EQUAL(FormatOsmLink(-34.6061, -58.4360, 10), "https://osm.org/go/Mnx6SB?m", ()); // Formally, lat = -90 and lat = 90 are the same for OSM links, but Mercator is valid until 85. auto link = FormatOsmLink(-90, -180, 10); - TEST(link == "https://osm.org/go/AAAAAA?m=" || link == "https://osm.org/go/~~~~~~?m=", (link)); + TEST(link == "https://osm.org/go/AAAAAA?m" || link == "https://osm.org/go/~~~~~~?m", (link)); link = FormatOsmLink(90, 180, 10); - TEST(link == "https://osm.org/go/AAAAAA?m=" || link == "https://osm.org/go/~~~~~~?m=", (link)); + TEST(link == "https://osm.org/go/AAAAAA?m" || link == "https://osm.org/go/~~~~~~?m", (link)); } UNIT_TEST(FormatSpeedNumeric) -- 2.45.3 From 2d421bd95a562117dfd71ce5a2c8314f7a9e36ea Mon Sep 17 00:00:00 2001 From: Matheus Gomes <86851490+matheusgomesms@users.noreply.github.com> Date: Sun, 19 May 2024 18:09:30 -0300 Subject: [PATCH 02/36] [strings] Fixed Portuguese exit strings (#8150) * Fixed PT exit strings Signed-off-by: Matheus Gomes <86851490+matheusgomesms@users.noreply.github.com> * Remove duplicate Signed-off-by: Matheus Gomes <86851490+matheusgomesms@users.noreply.github.com> --------- Signed-off-by: Matheus Gomes <86851490+matheusgomesms@users.noreply.github.com> --- data/strings/types_strings.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/data/strings/types_strings.txt b/data/strings/types_strings.txt index f40cb22c19..5c5275ec2d 100644 --- a/data/strings/types_strings.txt +++ b/data/strings/types_strings.txt @@ -11343,8 +11343,7 @@ nb = Utgang nl = Ga naar pl = Wyjście - pt = Sai - pt-BR = Sair + pt = Saída ro = Ieșire ru = Выход sk = Východ -- 2.45.3 From 8926620d1db950b2e07c39f4187b5e5e5cc35d44 Mon Sep 17 00:00:00 2001 From: Alexander Borsuk Date: Sun, 19 May 2024 23:10:08 +0200 Subject: [PATCH 03/36] [strings] Regenerated pt Signed-off-by: Alexander Borsuk --- android/app/src/main/res/values-pt-rBR/strings.xml | 1 - android/app/src/main/res/values-pt/strings.xml | 2 +- iphone/Maps/LocalizedStrings/pt-BR.lproj/Localizable.strings | 2 +- iphone/Maps/LocalizedStrings/pt.lproj/Localizable.strings | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/android/app/src/main/res/values-pt-rBR/strings.xml b/android/app/src/main/res/values-pt-rBR/strings.xml index fce8ef5017..d14b72a584 100644 --- a/android/app/src/main/res/values-pt-rBR/strings.xml +++ b/android/app/src/main/res/values-pt-rBR/strings.xml @@ -1061,7 +1061,6 @@ Entrada Entrada principal - Sair Laboratório médico Fisioterapeuta Medicina alternativa diff --git a/android/app/src/main/res/values-pt/strings.xml b/android/app/src/main/res/values-pt/strings.xml index c74ec48d95..58f08233ff 100644 --- a/android/app/src/main/res/values-pt/strings.xml +++ b/android/app/src/main/res/values-pt/strings.xml @@ -1124,7 +1124,7 @@ Entrada Entrada principal - Sai + Saída Gratuito Laboratório médico Fisioterapeuta diff --git a/iphone/Maps/LocalizedStrings/pt-BR.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/pt-BR.lproj/Localizable.strings index f084066e7b..a05b49d211 100644 --- a/iphone/Maps/LocalizedStrings/pt-BR.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/pt-BR.lproj/Localizable.strings @@ -1988,7 +1988,7 @@ /* This is for main/primary entrances, for secondary entrances see type.entrance */ "type.entrance.main" = "Entrada principal"; -"type.entrance.exit" = "Sair"; +"type.entrance.exit" = "Saída"; "type.fee.yes" = "$"; diff --git a/iphone/Maps/LocalizedStrings/pt.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/pt.lproj/Localizable.strings index 29f44b7365..bd25cf7bca 100644 --- a/iphone/Maps/LocalizedStrings/pt.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/pt.lproj/Localizable.strings @@ -1988,7 +1988,7 @@ /* This is for main/primary entrances, for secondary entrances see type.entrance */ "type.entrance.main" = "Entrada principal"; -"type.entrance.exit" = "Sai"; +"type.entrance.exit" = "Saída"; "type.fee.yes" = "$"; -- 2.45.3 From 5a11f41e4d7b52b1a376cf041295180e96f31377 Mon Sep 17 00:00:00 2001 From: Alexander Borsuk Date: Sun, 5 May 2024 19:51:30 +0200 Subject: [PATCH 04/36] Removed unnecessary system font logs All fonts are printed anyway at the end Signed-off-by: Alexander Borsuk --- platform/platform_android.cpp | 4 ---- platform/platform_linux.cpp | 3 --- 2 files changed, 7 deletions(-) diff --git a/platform/platform_android.cpp b/platform/platform_android.cpp index b6c0f1f8f0..7982a1e98d 100644 --- a/platform/platform_android.cpp +++ b/platform/platform_android.cpp @@ -218,7 +218,6 @@ void Platform::GetSystemFontNames(FilesList & res) const else wasRoboto = true; - LOG(LINFO, ("Found usable system font", name)); res.push_back(path + name); }); @@ -226,10 +225,7 @@ void Platform::GetSystemFontNames(FilesList & res) const { string droidSans = path + "DroidSans.ttf"; if (IsFileExistsByFullPath(droidSans)) - { - LOG(LINFO, ("Found usable system font", droidSans)); res.push_back(std::move(droidSans)); - } } } diff --git a/platform/platform_linux.cpp b/platform/platform_linux.cpp index be0f31505b..3f93e3063a 100644 --- a/platform/platform_linux.cpp +++ b/platform/platform_linux.cpp @@ -255,10 +255,7 @@ void Platform::GetSystemFontNames(FilesList & res) const { std::string path = sysPath + font; if (IsFileExistsByFullPath(path)) - { - LOG(LINFO, ("Found usable system font", path)); res.push_back(std::move(path)); - } } } } -- 2.45.3 From ff703e83d60a5f9c3cee9b97919397c9b08f6e2d Mon Sep 17 00:00:00 2001 From: Gonzalo Pesquero Date: Sun, 19 May 2024 14:32:15 -0700 Subject: [PATCH 05/36] [editor] Fix parsing of 'off' opening hours (#7652) * [editor] Fix parsing of some 'off' opening hours rules Signed-off-by: Gonzalo Pesquero * Update editor/editor_tests/ui2oh_test.cpp Signed-off-by: Alexander Borsuk <170263+biodranik@users.noreply.github.com> --------- Signed-off-by: Gonzalo Pesquero Signed-off-by: Alexander Borsuk <170263+biodranik@users.noreply.github.com> Co-authored-by: Alexander Borsuk <170263+biodranik@users.noreply.github.com> --- editor/editor_tests/ui2oh_test.cpp | 16 ++++++++++++++++ editor/ui2oh.cpp | 12 ++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/editor/editor_tests/ui2oh_test.cpp b/editor/editor_tests/ui2oh_test.cpp index 7dc021adb5..795d12b584 100644 --- a/editor/editor_tests/ui2oh_test.cpp +++ b/editor/editor_tests/ui2oh_test.cpp @@ -352,6 +352,22 @@ UNIT_TEST(OpeningHours2TimeTableSet_off) TEST_EQUAL(tt.GetExcludeTime()[0].GetStart().GetHourMinutes().GetHoursCount(), 11, ()); TEST_EQUAL(tt.GetExcludeTime()[0].GetEnd().GetHourMinutes().GetHoursCount(), 13, ()); } + { + OpeningHours oh("Mo off; Tu-Su 09:00-17:00"); + TEST(oh.IsValid(), ()); + + TimeTableSet tts; + + TEST(MakeTimeTableSet(oh, tts), ()); + TEST_EQUAL(tts.Size(), 1, ()); + + TEST_EQUAL(tts.GetUnhandledDays(), OpeningDays({osmoh::Weekday::Monday}), ()); + + auto const tt = tts.Get(0); + + TEST_EQUAL(tt.GetOpeningTime().GetStart().GetHourMinutes().GetHoursCount(), 9, ()); + TEST_EQUAL(tt.GetOpeningTime().GetEnd().GetHourMinutes().GetHoursCount(), 17, ()); + } } UNIT_TEST(OpeningHours2TimeTableSet_plus) diff --git a/editor/ui2oh.cpp b/editor/ui2oh.cpp index fdc4ced5a1..a40a958c00 100644 --- a/editor/ui2oh.cpp +++ b/editor/ui2oh.cpp @@ -340,9 +340,9 @@ bool MakeTimeTableSet(osmoh::OpeningHours const & oh, ui::TimeTableSet & tts) if (rulePart.GetModifier() == osmoh::RuleSequence::Modifier::Closed) { - // off modifier in the first part in oh is useless. + // Off modifier in the first part in oh is useless. Skip it. if (first == true) - return false; + continue; if (!ExcludeRulePart(rulePart, tts)) return false; @@ -376,6 +376,14 @@ bool MakeTimeTableSet(osmoh::OpeningHours const & oh, ui::TimeTableSet & tts) return false; } + // Check if no OH rule has been correctly processed. + if (first) + { + // No OH rule has been correctly processed. + // Set OH parsing as invalid. + return false; + } + return true; } } // namespace editor -- 2.45.3 From 3e6d7df08b97d19e5c4f5f5075bcf3686e38e159 Mon Sep 17 00:00:00 2001 From: Adolfo Jayme-Barrientos Date: Mon, 20 May 2024 01:19:28 -0600 Subject: [PATCH 06/36] Add some comment translations to .desktop file Signed-off-by: Adolfo Jayme-Barrientos --- qt/res/OrganicMaps.desktop | 3 +++ 1 file changed, 3 insertions(+) diff --git a/qt/res/OrganicMaps.desktop b/qt/res/OrganicMaps.desktop index 862815374d..017795f238 100644 --- a/qt/res/OrganicMaps.desktop +++ b/qt/res/OrganicMaps.desktop @@ -3,6 +3,9 @@ Type=Application Version=1.0 Name=Organic Maps Comment=Detailed Offline Maps of the World +Comment[ast]=Mapes detallaos del mundu ensin conexón +Comment[ca]=Mapes detallats del món sense connexió +Comment[es]=Mapas detallados del mundo sin conexión Comment[ru]=Подробная оффлайновая карта мира Icon=organicmaps TryExec=OMaps -- 2.45.3 From 6b6b9c229fcaf1502dc37c04e47c3f0da5717276 Mon Sep 17 00:00:00 2001 From: Alexander Borsuk Date: Mon, 20 May 2024 11:16:17 +0200 Subject: [PATCH 07/36] Reorganized contributors sections for clarity Signed-off-by: Alexander Borsuk --- CONTRIBUTORS | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 80b7df683e..003ea46ceb 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -7,6 +7,28 @@ Original MAPS.ME (MapsWithMe) design and implementation: Viktor Govako Siarhei Rachytski +-------------------------------------------------------------------------------- +Organic Maps contributions: +-------------------------------------------------------------------------------- + Alexander Borsuk + Roman Tsisyk + Viktor Govako + Caspar Nuël + Konstantin Pastbin + Nishant Bhandari + Sebastiao Sousa + +Organic Maps translations: + Karina Kordon + Konstantin Pastbin + Metehan Özyürek + Joan Montané + Luna Rose + + +-------------------------------------------------------------------------------- +MAPS.ME contributions (before Organic Maps was forked in 2020-2021): +-------------------------------------------------------------------------------- Code contributions: Dmitry Yunitski Lev Dragunov @@ -35,11 +57,6 @@ Code contributions: Alex Gontmakher Dima Korolev Max Grigorev - Roman Tsisyk - Caspar Nuël - Konstantin Pastbin - Nishant Bhandari - Sebastiao Sousa Porting to Tizen platform: Sergey Pisarchik @@ -63,11 +80,6 @@ Strings and translations: Vasily Korotkevich Mark N. Kuramochi Lidia Vasiljeva - Karina Kordon - Konstantin Pastbin - Metehan Özyürek - Joan Montané - Luna Rose Project management: Alexander Matveenko -- 2.45.3 From 2098646f8c12fb80381cfb9a5d1e8e6477172fd1 Mon Sep 17 00:00:00 2001 From: Alexander Borsuk Date: Sun, 19 May 2024 14:47:41 +0200 Subject: [PATCH 08/36] [ios] Set correct location service activity type for cycling Signed-off-by: Alexander Borsuk --- iphone/Maps/Core/Location/MWMLocationManager.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/iphone/Maps/Core/Location/MWMLocationManager.mm b/iphone/Maps/Core/Location/MWMLocationManager.mm index a0f50ddddd..464175c4d4 100644 --- a/iphone/Maps/Core/Location/MWMLocationManager.mm +++ b/iphone/Maps/Core/Location/MWMLocationManager.mm @@ -375,7 +375,7 @@ void setShowLocationAlert(BOOL needShow) { break; case GeoMode::PedestrianRouting: case GeoMode::BicycleRouting: - locationManager.activityType = CLActivityTypeFitness; + locationManager.activityType = CLActivityTypeOtherNavigation; break; } @@ -484,7 +484,7 @@ void setShowLocationAlert(BOOL needShow) { - (void)startUpdatingLocationFor:(CLLocationManager *)manager { LOG(LINFO, ("startUpdatingLocation")); - + [manager startUpdatingLocation]; if ([CLLocationManager headingAvailable]) [manager startUpdatingHeading]; -- 2.45.3 From 621eaaf67a0b44f415d2389e02da58a99eb5be72 Mon Sep 17 00:00:00 2001 From: Osyotr Date: Mon, 29 Apr 2024 00:18:04 +0300 Subject: [PATCH 09/36] Remove liboauthcpp Signed-off-by: Osyotr --- 3party/CMakeLists.txt | 1 - 3party/liboauthcpp/.gitignore | 9 - 3party/liboauthcpp/CMakeLists.txt | 21 - 3party/liboauthcpp/LICENSE | 21 - 3party/liboauthcpp/README.md | 172 ----- .../include/liboauthcpp/liboauthcpp.h | 286 -------- 3party/liboauthcpp/src/HMAC_SHA1.cpp | 59 -- 3party/liboauthcpp/src/HMAC_SHA1.h | 37 -- 3party/liboauthcpp/src/SHA1.cpp | 283 -------- 3party/liboauthcpp/src/SHA1.h | 148 ----- 3party/liboauthcpp/src/base64.cpp | 123 ---- 3party/liboauthcpp/src/base64.h | 4 - 3party/liboauthcpp/src/liboauthcpp.cpp | 621 ------------------ 3party/liboauthcpp/src/urlencode.cpp | 102 --- 3party/liboauthcpp/src/urlencode.h | 16 - android/app/src/main/cpp/CMakeLists.txt | 1 - coding/CMakeLists.txt | 1 - coding/base64.cpp | 4 +- coding/base64.hpp | 2 +- coding/sha1.cpp | 69 +- coding/sha1.hpp | 5 +- data/copyright.html | 3 - generator/pygen/CMakeLists.txt | 1 - iphone/Maps/Maps.xcodeproj/project.pbxproj | 4 - kml/pykmlib/CMakeLists.txt | 1 - search/pysearch/CMakeLists.txt | 1 - traffic/pytraffic/CMakeLists.txt | 1 - xcode/editor/editor.xcodeproj/project.pbxproj | 4 - xcode/ge0/ge0.xcodeproj/project.pbxproj | 4 - .../generator.xcodeproj/project.pbxproj | 4 - .../indexer/indexer.xcodeproj/project.pbxproj | 4 - xcode/kml/kml.xcodeproj/project.pbxproj | 4 - xcode/map/map.xcodeproj/project.pbxproj | 4 - .../oauthcpp.xcodeproj/project.pbxproj | 233 ------- .../omim.xcworkspace/contents.xcworkspacedata | 3 - .../platform.xcodeproj/project.pbxproj | 4 - xcode/qt/qt.xcodeproj/project.pbxproj | 4 - xcode/search/search.xcodeproj/project.pbxproj | 6 - .../traffic/traffic.xcodeproj/project.pbxproj | 4 - 39 files changed, 32 insertions(+), 2242 deletions(-) delete mode 100644 3party/liboauthcpp/.gitignore delete mode 100644 3party/liboauthcpp/CMakeLists.txt delete mode 100644 3party/liboauthcpp/LICENSE delete mode 100644 3party/liboauthcpp/README.md delete mode 100644 3party/liboauthcpp/include/liboauthcpp/liboauthcpp.h delete mode 100644 3party/liboauthcpp/src/HMAC_SHA1.cpp delete mode 100644 3party/liboauthcpp/src/HMAC_SHA1.h delete mode 100644 3party/liboauthcpp/src/SHA1.cpp delete mode 100644 3party/liboauthcpp/src/SHA1.h delete mode 100644 3party/liboauthcpp/src/base64.cpp delete mode 100644 3party/liboauthcpp/src/base64.h delete mode 100644 3party/liboauthcpp/src/liboauthcpp.cpp delete mode 100644 3party/liboauthcpp/src/urlencode.cpp delete mode 100644 3party/liboauthcpp/src/urlencode.h delete mode 100644 xcode/oauthcpp/oauthcpp.xcodeproj/project.pbxproj diff --git a/3party/CMakeLists.txt b/3party/CMakeLists.txt index 676d42ea79..97f45e2efa 100644 --- a/3party/CMakeLists.txt +++ b/3party/CMakeLists.txt @@ -57,7 +57,6 @@ endif() add_subdirectory(agg) add_subdirectory(bsdiff-courgette) -add_subdirectory(liboauthcpp) add_subdirectory(minizip) add_subdirectory(open-location-code) add_subdirectory(opening_hours) diff --git a/3party/liboauthcpp/.gitignore b/3party/liboauthcpp/.gitignore deleted file mode 100644 index a7baf33224..0000000000 --- a/3party/liboauthcpp/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -# Build (by)products -build/CMakeCache.txt -build/CMakeFiles -build/Makefile -build/cmake_install.cmake -build/liboauthcpp.a -build/simple_auth -build/simple_request -build/tests diff --git a/3party/liboauthcpp/CMakeLists.txt b/3party/liboauthcpp/CMakeLists.txt deleted file mode 100644 index e72b6b956c..0000000000 --- a/3party/liboauthcpp/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -project(oauthcpp) - -set(SRC - include/liboauthcpp/liboauthcpp.h - src/base64.cpp - src/HMAC_SHA1.cpp - src/SHA1.cpp - src/urlencode.cpp - src/liboauthcpp.cpp -) - -add_library(${PROJECT_NAME} ${SRC}) - -target_include_directories(${PROJECT_NAME} - PRIVATE src - PUBLIC include -) - -target_compile_options(${PROJECT_NAME} - PRIVATE $<$:-Wno-shorten-64-to-32> -) diff --git a/3party/liboauthcpp/LICENSE b/3party/liboauthcpp/LICENSE deleted file mode 100644 index 8d08adbe74..0000000000 --- a/3party/liboauthcpp/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -Copyright (c) 2011 Stanford University (liboauthcpp) -Copyright (C) 2011 by swatkat (swatkat.thinkdigitATgmailDOTcom) (libtwitcurl) - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/3party/liboauthcpp/README.md b/3party/liboauthcpp/README.md deleted file mode 100644 index cd787d6139..0000000000 --- a/3party/liboauthcpp/README.md +++ /dev/null @@ -1,172 +0,0 @@ -liboauthcpp ------------ - -liboauthcpp is a pure C++ library for performing OAuth requests. It -doesn't contain any networking code -- you provide for performing HTTP -requests yourself, however you like -- instead focusing on performing -OAuth-specific functionality and providing a nice interface for it. -If you already have infrastructure for making HTTP requests and are -looking to add OAuth support, liboauthcpp is for you. - -liboauthcpp currently implements OAuth 1.0a (see -http://tools.ietf.org/html/rfc5849). - -Buildbot --------- -[![Build Status](https://secure.travis-ci.org/sirikata/liboauthcpp.png)](http://travis-ci.org/sirikata/liboauthcpp) - -Requirements ------------- - -You should only need: - - * CMake - * A C++ compiler for your platform (e.g. g++, Microsoft Visual C++) - -Compiling ---------- - -The build process is simple: - - cd liboauthcpp - cd build - cmake . - make # or open Visual Studio and build the solution - -If your own project uses CMake you can also include -build/CMakeLists.txt directly into your project and reference the -target "oauthcpp", a static library, in your project. - -Percent (URL) Encoding ----------------------- - -To get correct results, you need to pass your URL properly encoded to -liboauthcpp. If you are not at all familiar, you should probably start -by reading the [URI Spec](http://tools.ietf.org/html/rfc3986), especially -Section 2. Alternatively, -[this article](http://blog.lunatech.com/2009/02/03/what-every-web-developer-must-know-about-url-encoding) -gives a more readable overview. - -The basic idea is that there are 3 classes of characters: reserved, -unreserved, and other. Reserved characters are special characters that -are used in the URI syntax itself, e.g. ':' (after the scheme), '/' -(the hierarchical path separator), and '?' (prefixing the query -string). Unreserved characters are characters that are always safe to -include unencoded, e.g. the alphanumerics. Other characters must -always be encoded, mainly covering special characters like ' ', '<' or -'>', and '{' or '}'. - -The basic rule is that reserved characters must be encoded if they -appear in any part of the URI when not being used as a -separator. Unreserved characters are always safe. And the other -characters they didn't know if they would be safe or not so they must -always be encoded. - -Unfortunately, the reserved set is a bit more complicated. They are -broken down into 'general delimiters' and 'sub delimiters'. The ones -already mentioned, like ':', can appear in many forms of URIs (say, -http, ftp, about, gopher, mailto, etc. Those are called general -delimiters. Others (e.g. '(', ')', '!', '$', '+', ',', '=', and more) -are called subdelimiters because their use depends on the URI -scheme. Worse, their use depends on the *part of the URI*. Depending -on the particular URI scheme, these may or may not have to be encoded, -and it might also depend on where they appear. (As an example, an '&' -in an http URI isn't an issue if it appears in the path -- before the -query string -- i.e. before a '?' appears. Worse, '=' can appear unencoded in -the path, or in a query parameter value, but not in a query parameter key since -it would be interpreted as the end of the key.) - -*Additionally*, in many cases it is permitted to encode a character -unnecessarily and the result is supposed to be the same. This means -that it's possible to percent encode some URLs in multiple ways -(e.g. encoding the unreserved set unnecessarily). It is possible, but not -guaranteed, that if you pass *exactly* the same URI to liboauthcpp and the -OAuth server, it will handle it regardless of the variant of encoding, so long -as it is a valid encoding. - -The short version: percent encoding a URL properly is non-trivial and -you can even encode the same URL multiple ways, but has to be done -correctly so that the OAuth signature can be computed. Sadly, -"correctly" in this case really means "in whatever way the server your -interacting with wants it encoded". - -Internally, liboauthcpp needs to do another step of percent encoding, -but the OAuth spec is very precise about how that works (none of these -scheme-dependent issues). liboauth applies this percent encoding, but -assumes that you have encoded your URLs properly. This assumption -makes sense since the actual request is made separately, and the URI -has to be specified in it, so you should already have a form which the -server will accept. - -However, in order to aid you, a very simple percent encoding API is exposed. It -should help you encode URLs minimally and in a way that many services accept. In -most cases you should use `HttpPercentEncodePath()`, -`HttpPercentEncodeQueryKey()`, and `HttpPercentEncodeQueryValue()` to encode -those parts of your http URL, then combine them and pass them to liboauthcpp for -signing. - - -Thread Safety -------------- - -liboauthcpp doesn't provide any thread safety guarantees. That said, there is -very little shared state, and some classes (e.g. Consumer) are naturally -immutable and therefore thread safe. Similarly, nearly the entire library uses -no static/shared state, so as long as you create separate objects for separate -threads, you should be safe. - -The one exception is nonces: the Client class needs to generate a nonce for -authorization. To do so, the random number generator needs to be seeded. We do -this with the current time, but fast, repeated use of the Client class from -different threads could result in the same nonce. To avoid requiring an entire -thread library just for this one case, you can call Client::initialize() -explicitly before using the Client from multiple threads. For single-threaded -use, you are not required to call it. - -Demos ------ -There are two demos included in the demos/ directory, and they are built by -default with the instructions above. In both, you enter key/secret information -and it generates URLs for you to visit (in a browser) and copy data back into -the program. - -simple_auth should be executed first. It starts with only a consumer key and -secret and performs 3-legged auth: you enter in consumer keys, it generates URLs -to authenticate the user and generate access tokens. It requires 3 steps: -request_token, authorize, and access_token (which correspond the URLs -accessed). At the end of this process, you'll be provided an access key/secret -pair which you can use to access actual resources. - -simple_request actually does something useful now that your application is -authorized. Enter your consumer key/secret and the access key/secret from -simple_auth (or which you've generated elsewhere) and it will generate a URL you -can use to access your home timeline in JSON format. It adds a parameter to ask -for only 5 entries (demonstrating that signing works properly over additional -query parameters). This is a one-step process -- it just gives you the URL and -you get the results in your browser. - -In both, the URLs accessed are specified at the top of the demo -files. simple_auth requires URLs for request_token, authorize_url, and -access_token. Some providers require additional parameters (notably an -oauth_callback for Twitter, even if its out of band, or oob), which you can also -specify in that location. simple_request only needs the URL of the resource -being accessed (i.e. the URL for the home_timeline JSON data used by default in -the demo), with optional parameters stored as a query string. - -Both demos only use GET requests with query strings, but all HTTP methods -(e.g. POST, PUT, DELETE) and approaches to sending parameters (e.g. HTTP -headers, url-encoded body) should be supported in the API. - -License -------- - -liboauthcpp is MIT licensed. See the LICENSE file for more details. - -liboauthcpp is mostly taken from libtwitcurl -(http://code.google.com/p/twitcurl/), which is similarly licensed. It -mostly serves to isolate the OAuth code from libtwitcurl's Twitter and -cURL specific code. - -libtwitcurl also borrowed code from other projects: -twitcurl uses HMAC_SHA1 from http://www.codeproject.com/KB/recipes/HMACSHA1class.aspx -twitcurl uses base64 from http://www.adp-gmbh.ch/cpp/common/base64.html diff --git a/3party/liboauthcpp/include/liboauthcpp/liboauthcpp.h b/3party/liboauthcpp/include/liboauthcpp/liboauthcpp.h deleted file mode 100644 index b510d43997..0000000000 --- a/3party/liboauthcpp/include/liboauthcpp/liboauthcpp.h +++ /dev/null @@ -1,286 +0,0 @@ -#ifndef __LIBOAUTHCPP_LIBOAUTHCPP_H__ -#define __LIBOAUTHCPP_LIBOAUTHCPP_H__ - -#include -#include -#include -#include -#include - -namespace OAuth { - -namespace Http { -typedef enum _RequestType -{ - Invalid = 0, - Head, - Get, - Post, - Delete, - Put -} RequestType; -} // namespace Http - -typedef std::list KeyValueList; -typedef std::multimap KeyValuePairs; - -typedef enum _LogLevel -{ - LogLevelNone = 0, - LogLevelDebug = 1 -} LogLevel; - -/** Set the log level. Log messages are sent to stderr. Currently, and for the - * foreseeable future, logging only consists of debug messages to help track - * down protocol implementation issues. - */ -void SetLogLevel(LogLevel lvl); - -/** Deprecated. Complete percent encoding of URLs. Equivalent to - * PercentEncode. - */ -std::string URLEncode(const std::string& decoded); - -/** Percent encode a string value. This version is *thorough* about - * encoding: it encodes all reserved characters (even those safe in - * http URLs) and "other" characters not specified by the URI - * spec. If you're looking to encode http:// URLs, see the - * HttpEncode* functions. - */ -std::string PercentEncode(const std::string& decoded); - -/** Percent encodes the path portion of an http URL (i.e. the /foo/bar - * in http://foo/bar?a=1&b=2). This encodes minimally, so reserved - * subdelimiters that have no meaning in the path are *not* encoded. - */ -std::string HttpEncodePath(const std::string& decoded); - -/** Percent encodes a query string key in an http URL (i.e. 'a', 'b' in - * http://foo/bar?a=1&b=2). This encodes minimally, so reserved subdelimiters - * that have no meaning in the query string are *not* encoded. - */ -std::string HttpEncodeQueryKey(const std::string& decoded); - -/** Percent encodes a query string value in an http URL (i.e. '1', '2' in - * http://foo/bar?a=1&b=2). This encodes minimally, so reserved subdelimiters - * that have no meaning in the query string are *not* encoded. - */ -std::string HttpEncodeQueryValue(const std::string& decoded); - -/** Parses key value pairs into a map. - * \param encoded the encoded key value pairs, i.e. the url encoded parameters - * \returns a map of string keys to string values - * \throws ParseError if the encoded data cannot be decoded - */ -KeyValuePairs ParseKeyValuePairs(const std::string& encoded); - -class ParseError : public std::runtime_error { -public: - ParseError(const std::string msg) - : std::runtime_error(msg) - {} -}; - -class MissingKeyError : public std::runtime_error { -public: - MissingKeyError(const std::string msg) - : std::runtime_error(msg) - {} -}; - -/** A consumer of OAuth-protected services. It is the client to an - * OAuth service provider and is usually registered with the service - * provider, resulting in a consumer *key* and *secret* used to - * identify the consumer. The key is included in all requests and the - * secret is used to *sign* all requests. Signed requests allow the - * consumer to securely perform operations, including kicking off - * three-legged authentication to enable performing operations on - * behalf of a user of the service provider. - */ -class Consumer { -public: - Consumer(const std::string& key, const std::string& secret); - - const std::string& key() const { return mKey; } - const std::string& secret() const { return mSecret; } - -private: - const std::string mKey; - const std::string mSecret; -}; - -/** An OAuth credential used to request authorization or a protected - * resource. - * - * Tokens in OAuth comprise a *key* and a *secret*. The key is - * included in requests to identify the token being used, but the - * secret is used only in the signature, to prove that the requester - * is who the server gave the token to. - * - * When first negotiating the authorization, the consumer asks for a - * *request token* that the live user authorizes with the service - * provider. The consumer then exchanges the request token for an - * *access token* that can be used to access protected resources. - */ -class Token { -public: - Token(const std::string& key, const std::string& secret); - Token(const std::string& key, const std::string& secret, const std::string& pin); - - /** Construct a token, extracting the key and secret from a set of - * key-value pairs (e.g. those parsed from an request or access - * token request). - */ - static Token extract(const KeyValuePairs& response); - /** Construct a token, extracting the key and secret from a raw, - * encoded response. - */ - static Token extract(const std::string& requestTokenResponse); - - const std::string& key() const { return mKey; } - const std::string& secret() const { return mSecret; } - - const std::string& pin() const { return mPin; } - void setPin(const std::string& pin_) { mPin = pin_; } - -private: - - const std::string mKey; - const std::string mSecret; - std::string mPin; -}; - -class Client { -public: - /** Perform static initialization. This will be called automatically, but - * you can call it explicitly to ensure thread safety. If you do not call - * this explicitly before using the Client class, the same nonce may be - * generated twice. - */ - static void initialize(); - /** Alternative initialize method which lets you specify the seed and - * control the timestamp used in generating signatures. This only exists - * for testing purposes and should not be used in practice. - */ - static void initialize(int nonce, time_t timestamp); - - /** Exposed for testing only. - */ - static void __resetInitialize(); - - /** Construct an OAuth Client using only a consumer key and - * secret. You can use this to start a three-legged - * authentication (to acquire an access token for a user) or for - * simple two-legged authentication (signing with empty access - * token info). - * - * \param consumer Consumer information. The caller must ensure - * it remains valid during the lifetime of this object - */ - Client(const Consumer* consumer); - /** Construct an OAuth Client with consumer key and secret (yours) - * and access token key and secret (acquired and stored during - * three-legged authentication). - * - * \param consumer Consumer information. The caller must ensure - * it remains valid during the lifetime of this object - * \param token Access token information. The caller must ensure - * it remains valid during the lifetime of this object - */ - Client(const Consumer* consumer, const Token* token); - - ~Client(); - - /** Build an OAuth HTTP header for the given request. This version provides - * only the field value. - * - * \param eType the HTTP request type, e.g. GET or POST - * \param rawUrl the raw request URL (should include query parameters) - * \param rawData the raw HTTP request data (can be empty) - * \param includeOAuthVerifierPin if true, adds oauth_verifier parameter - * \returns a string containing the HTTP header - */ - std::string getHttpHeader(const Http::RequestType eType, - const std::string& rawUrl, - const std::string& rawData = "", - const bool includeOAuthVerifierPin = false); - /** Build an OAuth HTTP header for the given request. This version gives a - * fully formatted header, i.e. including the header field name. - * - * \param eType the HTTP request type, e.g. GET or POST - * \param rawUrl the raw request URL (should include query parameters) - * \param rawData the raw HTTP request data (can be empty) - * \param includeOAuthVerifierPin if true, adds oauth_verifier parameter - * \returns a string containing the HTTP header - */ - std::string getFormattedHttpHeader(const Http::RequestType eType, - const std::string& rawUrl, - const std::string& rawData = "", - const bool includeOAuthVerifierPin = false); - /** Build an OAuth HTTP header for the given request. - * - * \param eType the HTTP request type, e.g. GET or POST - * \param rawUrl the raw request URL (should include query parameters) - * \param rawData the raw HTTP request data (can be empty) - * \param includeOAuthVerifierPin if true, adds oauth_verifier parameter - * \returns a string containing the query string, including the query - * parameters in the rawUrl - */ - std::string getURLQueryString(const Http::RequestType eType, - const std::string& rawUrl, - const std::string& rawData = "", - const bool includeOAuthVerifierPin = false); -private: - /** Disable default constructur -- must provide consumer - * information. - */ - Client(); - - static bool initialized; - static int testingNonce; - static time_t testingTimestamp; - - /* OAuth data */ - const Consumer* mConsumer; - const Token* mToken; - std::string m_nonce; - std::string m_timeStamp; - - /* OAuth related utility methods */ - bool buildOAuthTokenKeyValuePairs( const bool includeOAuthVerifierPin, /* in */ - const std::string& rawData, /* in */ - const std::string& oauthSignature, /* in */ - KeyValuePairs& keyValueMap /* out */, - const bool urlEncodeValues /* in */, - const bool generateTimestamp /* in */); - - bool getStringFromOAuthKeyValuePairs( const KeyValuePairs& rawParamMap, /* in */ - std::string& rawParams, /* out */ - const std::string& paramsSeperator /* in */ ); - - typedef enum _ParameterStringType { - QueryStringString, - AuthorizationHeaderString - } ParameterStringType; - // Utility for building OAuth HTTP header or query string. The string type - // controls the separator and also filters parameters: for query strings, - // all parameters are included. For HTTP headers, only auth parameters are - // included. - std::string buildOAuthParameterString( - ParameterStringType string_type, - const Http::RequestType eType, - const std::string& rawUrl, - const std::string& rawData, - const bool includeOAuthVerifierPin); - - bool getSignature( const Http::RequestType eType, /* in */ - const std::string& rawUrl, /* in */ - const KeyValuePairs& rawKeyValuePairs, /* in */ - std::string& oAuthSignature /* out */ ); - - void generateNonceTimeStamp(); -}; - -} // namespace OAuth - -#endif // __LIBOAUTHCPP_LIBOAUTHCPP_H__ diff --git a/3party/liboauthcpp/src/HMAC_SHA1.cpp b/3party/liboauthcpp/src/HMAC_SHA1.cpp deleted file mode 100644 index 59b2766a54..0000000000 --- a/3party/liboauthcpp/src/HMAC_SHA1.cpp +++ /dev/null @@ -1,59 +0,0 @@ -//****************************************************************************** -//* HMAC_SHA1.cpp : Implementation of HMAC SHA1 algorithm -//* Comfort to RFC 2104 -//* -//****************************************************************************** -#include "HMAC_SHA1.h" -#include -#include - - -void CHMAC_SHA1::HMAC_SHA1(BYTE *text, int text_len, BYTE *key, int key_len, BYTE *digest) -{ - memset(SHA1_Key, 0, SHA1_BLOCK_SIZE); - - /* repeated 64 times for values in ipad and opad */ - memset(m_ipad, 0x36, sizeof(m_ipad)); - memset(m_opad, 0x5c, sizeof(m_opad)); - - /* STEP 1 */ - if (key_len > SHA1_BLOCK_SIZE) - { - CSHA1::Reset(); - CSHA1::Update((UINT_8 *)key, key_len); - CSHA1::Final(); - - CSHA1::GetHash((UINT_8 *)SHA1_Key); - } - else - memcpy(SHA1_Key, key, key_len); - - /* STEP 2 */ - for (int i=0; i<(int)sizeof(m_ipad); i++) - { - m_ipad[i] ^= SHA1_Key[i]; - } - - /* STEP 4 */ - CSHA1::Reset(); - CSHA1::Update((UINT_8 *)m_ipad, sizeof(m_ipad)); - CSHA1::Update((UINT_8 *)text, text_len); - CSHA1::Final(); - - char szReport[SHA1_DIGEST_LENGTH]; - CSHA1::GetHash((UINT_8 *)szReport); - - /* STEP 5 */ - for (int j=0; j<(int)sizeof(m_opad); j++) - { - m_opad[j] ^= SHA1_Key[j]; - } - - /*STEP 7 */ - CSHA1::Reset(); - CSHA1::Update((UINT_8 *)m_opad, sizeof(m_opad)); - CSHA1::Update((UINT_8 *)szReport, SHA1_DIGEST_LENGTH); - CSHA1::Final(); - - CSHA1::GetHash((UINT_8 *)digest); -} diff --git a/3party/liboauthcpp/src/HMAC_SHA1.h b/3party/liboauthcpp/src/HMAC_SHA1.h deleted file mode 100644 index 19c6b5e237..0000000000 --- a/3party/liboauthcpp/src/HMAC_SHA1.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - 100% free public domain implementation of the HMAC-SHA1 algorithm - by Chien-Chung, Chung (Jim Chung) -*/ - - -#ifndef __HMAC_SHA1_H__ -#define __HMAC_SHA1_H__ - -#include "SHA1.h" - -typedef unsigned char BYTE ; - -class CHMAC_SHA1 : public CSHA1 -{ -public: - - enum { - SHA1_DIGEST_LENGTH = 20, - SHA1_BLOCK_SIZE = 64 - } ; - -private: - BYTE m_ipad[SHA1_BLOCK_SIZE]; - BYTE m_opad[SHA1_BLOCK_SIZE]; - - // This holds one SHA1 block's worth of data, zero padded if necessary. - char SHA1_Key[SHA1_BLOCK_SIZE]; - -public: - CHMAC_SHA1() {} - - void HMAC_SHA1(BYTE *text, int text_len, BYTE *key, int key_len, BYTE *digest); -}; - - -#endif /* __HMAC_SHA1_H__ */ diff --git a/3party/liboauthcpp/src/SHA1.cpp b/3party/liboauthcpp/src/SHA1.cpp deleted file mode 100644 index ebd4615395..0000000000 --- a/3party/liboauthcpp/src/SHA1.cpp +++ /dev/null @@ -1,283 +0,0 @@ -/* - 100% free public domain implementation of the SHA-1 algorithm - by Dominik Reichl - Web: http://www.dominik-reichl.de/ - - Version 1.6 - 2005-02-07 (thanks to Howard Kapustein for patches) - - You can set the endianness in your files, no need to modify the - header file of the CSHA1 class any more - - Aligned data support - - Made support/compilation of the utility functions (ReportHash - and HashFile) optional (useful, if bytes count, for example in - embedded environments) - - Version 1.5 - 2005-01-01 - - 64-bit compiler compatibility added - - Made variable wiping optional (define SHA1_WIPE_VARIABLES) - - Removed unnecessary variable initializations - - ROL32 improvement for the Microsoft compiler (using _rotl) - - ======== Test Vectors (from FIPS PUB 180-1) ======== - - SHA1("abc") = - A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D - - SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = - 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 - - SHA1(A million repetitions of "a") = - 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F -*/ - -#include "SHA1.h" -#include - -#ifdef SHA1_UTILITY_FUNCTIONS -#define SHA1_MAX_FILE_BUFFER 8000 -#endif - -// Rotate x bits to the left -#ifndef ROL32 -#ifdef _MSC_VER -#define ROL32(_val32, _nBits) _rotl(_val32, _nBits) -#else -#define ROL32(_val32, _nBits) (((_val32)<<(_nBits))|((_val32)>>(32-(_nBits)))) -#endif -#endif - -#ifdef SHA1_LITTLE_ENDIAN -#define SHABLK0(i) (m_block->l[i] = \ - (ROL32(m_block->l[i],24) & 0xFF00FF00) | (ROL32(m_block->l[i],8) & 0x00FF00FF)) -#else -#define SHABLK0(i) (m_block->l[i]) -#endif - -#define SHABLK(i) (m_block->l[i&15] = ROL32(m_block->l[(i+13)&15] ^ m_block->l[(i+8)&15] \ - ^ m_block->l[(i+2)&15] ^ m_block->l[i&15],1)) - -CSHA1::CSHA1() -{ - m_block = (SHA1_WORKSPACE_BLOCK *)m_workspace; - - Reset(); -} - -CSHA1::~CSHA1() -{ - Reset(); -} - -void CSHA1::Reset() -{ - // SHA1 initialization constants - m_state[0] = 0x67452301; - m_state[1] = 0xEFCDAB89; - m_state[2] = 0x98BADCFE; - m_state[3] = 0x10325476; - m_state[4] = 0xC3D2E1F0; - - m_count[0] = 0; - m_count[1] = 0; -} - -void CSHA1::Transform(UINT_32 *state, UINT_8 *buffer) -{ - // Copy state[] to working vars - UINT_32 a = state[0], b = state[1], c = state[2], d = state[3], e = state[4]; - - memcpy(m_block, buffer, 64); - -// SHA-1 rounds -#define _R0(v,w,x,y,z,i) { z+=((w&(x^y))^y)+SHABLK0(i)+0x5A827999+ROL32(v,5); w=ROL32(w,30); } -#define _R1(v,w,x,y,z,i) { z+=((w&(x^y))^y)+SHABLK(i)+0x5A827999+ROL32(v,5); w=ROL32(w,30); } -#define _R2(v,w,x,y,z,i) { z+=(w^x^y)+SHABLK(i)+0x6ED9EBA1+ROL32(v,5); w=ROL32(w,30); } -#define _R3(v,w,x,y,z,i) { z+=(((w|x)&y)|(w&x))+SHABLK(i)+0x8F1BBCDC+ROL32(v,5); w=ROL32(w,30); } -#define _R4(v,w,x,y,z,i) { z+=(w^x^y)+SHABLK(i)+0xCA62C1D6+ROL32(v,5); w=ROL32(w,30); } - - // 4 rounds of 20 operations each. Loop unrolled. - _R0(a,b,c,d,e, 0); _R0(e,a,b,c,d, 1); _R0(d,e,a,b,c, 2); _R0(c,d,e,a,b, 3); - _R0(b,c,d,e,a, 4); _R0(a,b,c,d,e, 5); _R0(e,a,b,c,d, 6); _R0(d,e,a,b,c, 7); - _R0(c,d,e,a,b, 8); _R0(b,c,d,e,a, 9); _R0(a,b,c,d,e,10); _R0(e,a,b,c,d,11); - _R0(d,e,a,b,c,12); _R0(c,d,e,a,b,13); _R0(b,c,d,e,a,14); _R0(a,b,c,d,e,15); - _R1(e,a,b,c,d,16); _R1(d,e,a,b,c,17); _R1(c,d,e,a,b,18); _R1(b,c,d,e,a,19); - _R2(a,b,c,d,e,20); _R2(e,a,b,c,d,21); _R2(d,e,a,b,c,22); _R2(c,d,e,a,b,23); - _R2(b,c,d,e,a,24); _R2(a,b,c,d,e,25); _R2(e,a,b,c,d,26); _R2(d,e,a,b,c,27); - _R2(c,d,e,a,b,28); _R2(b,c,d,e,a,29); _R2(a,b,c,d,e,30); _R2(e,a,b,c,d,31); - _R2(d,e,a,b,c,32); _R2(c,d,e,a,b,33); _R2(b,c,d,e,a,34); _R2(a,b,c,d,e,35); - _R2(e,a,b,c,d,36); _R2(d,e,a,b,c,37); _R2(c,d,e,a,b,38); _R2(b,c,d,e,a,39); - _R3(a,b,c,d,e,40); _R3(e,a,b,c,d,41); _R3(d,e,a,b,c,42); _R3(c,d,e,a,b,43); - _R3(b,c,d,e,a,44); _R3(a,b,c,d,e,45); _R3(e,a,b,c,d,46); _R3(d,e,a,b,c,47); - _R3(c,d,e,a,b,48); _R3(b,c,d,e,a,49); _R3(a,b,c,d,e,50); _R3(e,a,b,c,d,51); - _R3(d,e,a,b,c,52); _R3(c,d,e,a,b,53); _R3(b,c,d,e,a,54); _R3(a,b,c,d,e,55); - _R3(e,a,b,c,d,56); _R3(d,e,a,b,c,57); _R3(c,d,e,a,b,58); _R3(b,c,d,e,a,59); - _R4(a,b,c,d,e,60); _R4(e,a,b,c,d,61); _R4(d,e,a,b,c,62); _R4(c,d,e,a,b,63); - _R4(b,c,d,e,a,64); _R4(a,b,c,d,e,65); _R4(e,a,b,c,d,66); _R4(d,e,a,b,c,67); - _R4(c,d,e,a,b,68); _R4(b,c,d,e,a,69); _R4(a,b,c,d,e,70); _R4(e,a,b,c,d,71); - _R4(d,e,a,b,c,72); _R4(c,d,e,a,b,73); _R4(b,c,d,e,a,74); _R4(a,b,c,d,e,75); - _R4(e,a,b,c,d,76); _R4(d,e,a,b,c,77); _R4(c,d,e,a,b,78); _R4(b,c,d,e,a,79); - -#undef _R0 -#undef _R1 -#undef _R2 -#undef _R3 -#undef _R4 - - // Add the working vars back into state - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - state[4] += e; - - // Wipe variables -#ifdef SHA1_WIPE_VARIABLES - a = b = c = d = e = 0; -#endif -} - -// Use this function to hash in binary data and strings -void CSHA1::Update(UINT_8 *data, UINT_32 len) -{ - UINT_32 i, j; - - j = (m_count[0] >> 3) & 63; - - if((m_count[0] += len << 3) < (len << 3)) m_count[1]++; - - m_count[1] += (len >> 29); - - if((j + len) > 63) - { - i = 64 - j; - memcpy(&m_buffer[j], data, i); - Transform(m_state, m_buffer); - - for(; i + 63 < len; i += 64) Transform(m_state, &data[i]); - - j = 0; - } - else i = 0; - - memcpy(&m_buffer[j], &data[i], len - i); -} - -#ifdef SHA1_UTILITY_FUNCTIONS -// Hash in file contents -bool CSHA1::HashFile(char *szFileName) -{ - unsigned long ulFileSize, ulRest, ulBlocks; - unsigned long i; - UINT_8 uData[SHA1_MAX_FILE_BUFFER]; - FILE *fIn; - - if(szFileName == NULL) return false; - - fIn = fopen(szFileName, "rb"); - if(fIn == NULL) return false; - - fseek(fIn, 0, SEEK_END); - ulFileSize = (unsigned long)ftell(fIn); - fseek(fIn, 0, SEEK_SET); - - if(ulFileSize != 0) - { - ulBlocks = ulFileSize / SHA1_MAX_FILE_BUFFER; - ulRest = ulFileSize % SHA1_MAX_FILE_BUFFER; - } - else - { - ulBlocks = 0; - ulRest = 0; - } - - for(i = 0; i < ulBlocks; i++) - { - size_t nread = fread(uData, 1, SHA1_MAX_FILE_BUFFER, fIn); - assert(nread == SHA1_MAX_FILE_BUFFER); - Update((UINT_8 *)uData, SHA1_MAX_FILE_BUFFER); - } - - if(ulRest != 0) - { - size_t nread = fread(uData, 1, ulRest, fIn); - assert(nread == ulRest); - Update((UINT_8 *)uData, ulRest); - } - - fclose(fIn); fIn = NULL; - return true; -} -#endif - -void CSHA1::Final() -{ - UINT_32 i; - UINT_8 finalcount[8]; - - for(i = 0; i < 8; i++) - finalcount[i] = (UINT_8)((m_count[((i >= 4) ? 0 : 1)] - >> ((3 - (i & 3)) * 8) ) & 255); // Endian independent - - Update((UINT_8 *)"\200", 1); - - while ((m_count[0] & 504) != 448) - Update((UINT_8 *)"\0", 1); - - Update(finalcount, 8); // Cause a SHA1Transform() - - for(i = 0; i < 20; i++) - { - m_digest[i] = (UINT_8)((m_state[i >> 2] >> ((3 - (i & 3)) * 8) ) & 255); - } - - // Wipe variables for security reasons -#ifdef SHA1_WIPE_VARIABLES - i = 0; - memset(m_buffer, 0, 64); - memset(m_state, 0, 20); - memset(m_count, 0, 8); - memset(finalcount, 0, 8); - Transform(m_state, m_buffer); -#endif -} - -#ifdef SHA1_UTILITY_FUNCTIONS -// Get the final hash as a pre-formatted string -void CSHA1::ReportHash(char *szReport, unsigned char uReportType) -{ - unsigned char i; - char szTemp[16]; - - if(szReport == NULL) return; - - if(uReportType == REPORT_HEX) - { - snprintf(szTemp, sizeof(szTemp), "%02X", m_digest[0]); - strcat(szReport, szTemp); - - for(i = 1; i < 20; i++) - { - snprintf(szTemp, sizeof(szTemp), " %02X", m_digest[i]); - strcat(szReport, szTemp); - } - } - else if(uReportType == REPORT_DIGIT) - { - snprintf(szTemp, sizeof(szTemp), "%u", m_digest[0]); - strcat(szReport, szTemp); - - for(i = 1; i < 20; i++) - { - snprintf(szTemp, sizeof(szTemp), " %u", m_digest[i]); - strcat(szReport, szTemp); - } - } - else strcpy(szReport, "Error: Unknown report type!"); -} -#endif - -// Get the raw message digest -void CSHA1::GetHash(UINT_8 *puDest) -{ - memcpy(puDest, m_digest, 20); -} diff --git a/3party/liboauthcpp/src/SHA1.h b/3party/liboauthcpp/src/SHA1.h deleted file mode 100644 index 794285d4fd..0000000000 --- a/3party/liboauthcpp/src/SHA1.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - 100% free public domain implementation of the SHA-1 algorithm - by Dominik Reichl - Web: http://www.dominik-reichl.de/ - - Version 1.6 - 2005-02-07 (thanks to Howard Kapustein for patches) - - You can set the endianness in your files, no need to modify the - header file of the CSHA1 class any more - - Aligned data support - - Made support/compilation of the utility functions (ReportHash - and HashFile) optional (useful, if bytes count, for example in - embedded environments) - - Version 1.5 - 2005-01-01 - - 64-bit compiler compatibility added - - Made variable wiping optional (define SHA1_WIPE_VARIABLES) - - Removed unnecessary variable initializations - - ROL32 improvement for the Microsoft compiler (using _rotl) - - ======== Test Vectors (from FIPS PUB 180-1) ======== - - SHA1("abc") = - A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D - - SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = - 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 - - SHA1(A million repetitions of "a") = - 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F -*/ - -#ifndef ___SHA1_HDR___ -#define ___SHA1_HDR___ - -#if !defined(SHA1_UTILITY_FUNCTIONS) && !defined(SHA1_NO_UTILITY_FUNCTIONS) -#define SHA1_UTILITY_FUNCTIONS -#endif - -#include // Needed for memset and memcpy - -#ifdef SHA1_UTILITY_FUNCTIONS -#include // Needed for file access and sprintf -#include // Needed for strcat and strcpy -#endif - -#ifdef _MSC_VER -#include -#endif - -// You can define the endian mode in your files, without modifying the SHA1 -// source files. Just #define SHA1_LITTLE_ENDIAN or #define SHA1_BIG_ENDIAN -// in your files, before including the SHA1.h header file. If you don't -// define anything, the class defaults to little endian. - -#if !defined(SHA1_LITTLE_ENDIAN) && !defined(SHA1_BIG_ENDIAN) -#define SHA1_LITTLE_ENDIAN -#endif - -// Same here. If you want variable wiping, #define SHA1_WIPE_VARIABLES, if -// not, #define SHA1_NO_WIPE_VARIABLES. If you don't define anything, it -// defaults to wiping. - -#if !defined(SHA1_WIPE_VARIABLES) && !defined(SHA1_NO_WIPE_VARIABLES) -#define SHA1_WIPE_VARIABLES -#endif - -///////////////////////////////////////////////////////////////////////////// -// Define 8- and 32-bit variables - -#ifndef UINT_32 - -#ifdef _MSC_VER - -#define UINT_8 unsigned __int8 -#define UINT_32 unsigned __int32 - -#else - -#define UINT_8 unsigned char - -#if (ULONG_MAX == 0xFFFFFFFF && UINT_MAX < ULONG_MAX) -#define UINT_32 unsigned long -#else -#define UINT_32 unsigned int -#endif - -#endif -#endif - -///////////////////////////////////////////////////////////////////////////// -// Declare SHA1 workspace - -typedef union -{ - UINT_8 c[64]; - UINT_32 l[16]; -} SHA1_WORKSPACE_BLOCK; - -class CSHA1 -{ -public: -#ifdef SHA1_UTILITY_FUNCTIONS - // Two different formats for ReportHash(...) - enum - { - REPORT_HEX = 0, - REPORT_DIGIT = 1 - }; -#endif - - // Constructor and Destructor - CSHA1(); - ~CSHA1(); - - UINT_32 m_state[5]; - UINT_32 m_count[2]; - UINT_32 __reserved1[1]; - UINT_8 m_buffer[64]; - UINT_8 m_digest[20]; - UINT_32 __reserved2[3]; - - void Reset(); - - // Update the hash value - void Update(UINT_8 *data, UINT_32 len); -#ifdef SHA1_UTILITY_FUNCTIONS - bool HashFile(char *szFileName); -#endif - - // Finalize hash and report - void Final(); - - // Report functions: as pre-formatted and raw data -#ifdef SHA1_UTILITY_FUNCTIONS - void ReportHash(char *szReport, unsigned char uReportType = REPORT_HEX); -#endif - void GetHash(UINT_8 *puDest); - -private: - // Private SHA-1 transformation - void Transform(UINT_32 *state, UINT_8 *buffer); - - // Member variables - UINT_8 m_workspace[64]; - SHA1_WORKSPACE_BLOCK *m_block; // SHA1 pointer to the byte array above -}; - -#endif diff --git a/3party/liboauthcpp/src/base64.cpp b/3party/liboauthcpp/src/base64.cpp deleted file mode 100644 index c0bb07cd02..0000000000 --- a/3party/liboauthcpp/src/base64.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - base64.cpp and base64.h - - Copyright (C) 2004-2008 Ren Nyffenegger - - This source code is provided 'as-is', without any express or implied - warranty. In no event will the author be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this source code must not be misrepresented; you must not - claim that you wrote the original source code. If you use this source code - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original source code. - - 3. This notice may not be removed or altered from any source distribution. - - Ren Nyffenegger rene.nyffenegger@adp-gmbh.ch - -*/ - -#include "base64.h" -#include - -static const std::string base64_chars = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; - - -static inline bool is_base64(unsigned char c) { - return (isalnum(c) || (c == '+') || (c == '/')); -} - -std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) { - std::string ret; - int i = 0; - int j = 0; - unsigned char char_array_3[3]; - unsigned char char_array_4[4]; - - while (in_len--) { - char_array_3[i++] = *(bytes_to_encode++); - if (i == 3) { - char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; - char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); - char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); - char_array_4[3] = char_array_3[2] & 0x3f; - - for(i = 0; (i <4) ; i++) - ret += base64_chars[char_array_4[i]]; - i = 0; - } - } - - if (i) - { - for(j = i; j < 3; j++) - char_array_3[j] = '\0'; - - char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; - char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); - char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); - char_array_4[3] = char_array_3[2] & 0x3f; - - for (j = 0; (j < i + 1); j++) - ret += base64_chars[char_array_4[j]]; - - while((i++ < 3)) - ret += '='; - - } - - return ret; - -} - -std::string base64_decode(std::string const& encoded_string) { - int in_len = encoded_string.size(); - int i = 0; - int j = 0; - int in_ = 0; - unsigned char char_array_4[4], char_array_3[3]; - std::string ret; - - while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { - char_array_4[i++] = encoded_string[in_]; in_++; - if (i ==4) { - for (i = 0; i <4; i++) - char_array_4[i] = base64_chars.find(char_array_4[i]); - - char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); - char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); - char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; - - for (i = 0; (i < 3); i++) - ret += char_array_3[i]; - i = 0; - } - } - - if (i) { - for (j = i; j <4; j++) - char_array_4[j] = 0; - - for (j = 0; j <4; j++) - char_array_4[j] = base64_chars.find(char_array_4[j]); - - char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); - char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); - char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; - - for (j = 0; (j < i - 1); j++) ret += char_array_3[j]; - } - - return ret; -} diff --git a/3party/liboauthcpp/src/base64.h b/3party/liboauthcpp/src/base64.h deleted file mode 100644 index 65d5db8b22..0000000000 --- a/3party/liboauthcpp/src/base64.h +++ /dev/null @@ -1,4 +0,0 @@ -#include - -std::string base64_encode(unsigned char const* , unsigned int len); -std::string base64_decode(std::string const& s); diff --git a/3party/liboauthcpp/src/liboauthcpp.cpp b/3party/liboauthcpp/src/liboauthcpp.cpp deleted file mode 100644 index 8850b7f25f..0000000000 --- a/3party/liboauthcpp/src/liboauthcpp.cpp +++ /dev/null @@ -1,621 +0,0 @@ -#include -#include "HMAC_SHA1.h" -#include "base64.h" -#include "urlencode.h" -#include -#include -#include - -namespace OAuth { - -namespace Defaults -{ - /* Constants */ - const int BUFFSIZE = 1024; - const int BUFFSIZE_LARGE = 1024; - const std::string CONSUMERKEY_KEY = "oauth_consumer_key"; - const std::string CALLBACK_KEY = "oauth_callback"; - const std::string VERSION_KEY = "oauth_version"; - const std::string SIGNATUREMETHOD_KEY = "oauth_signature_method"; - const std::string SIGNATURE_KEY = "oauth_signature"; - const std::string TIMESTAMP_KEY = "oauth_timestamp"; - const std::string NONCE_KEY = "oauth_nonce"; - const std::string TOKEN_KEY = "oauth_token"; - const std::string TOKENSECRET_KEY = "oauth_token_secret"; - const std::string VERIFIER_KEY = "oauth_verifier"; - - const std::string AUTHHEADER_FIELD = "Authorization: "; - const std::string AUTHHEADER_PREFIX = "OAuth "; -}; - -/** std::string -> std::string conversion function */ -typedef std::string(*StringConvertFunction)(const std::string&); - -LogLevel gLogLevel = LogLevelNone; - -void SetLogLevel(LogLevel lvl) { - gLogLevel = lvl; -} -#define LOG(lvl, msg) \ - do { \ - if (lvl <= gLogLevel) std::cerr << "OAUTH: " << msg << std::endl; \ - } while(0) - -std::string PercentEncode(const std::string& decoded) { - return urlencode(decoded, URLEncode_Everything); -} - -std::string URLEncode(const std::string& decoded) { - return PercentEncode(decoded); -} - -std::string HttpEncodePath(const std::string& decoded) { - return urlencode(decoded, URLEncode_Path); -} - -std::string HttpEncodeQueryKey(const std::string& decoded) { - return urlencode(decoded, URLEncode_QueryKey); -} - -std::string HttpEncodeQueryValue(const std::string& decoded) { - return urlencode(decoded, URLEncode_QueryValue); -} - -namespace { -std::string PassThrough(const std::string& decoded) { - return decoded; -} - -std::string RequestTypeString(const Http::RequestType rt) { - switch(rt) { - case Http::Invalid: return "Invalid Request Type"; break; - case Http::Head: return "HEAD"; break; - case Http::Get: return "GET"; break; - case Http::Post: return "POST"; break; - case Http::Delete: return "DELETE"; break; - case Http::Put: return "PUT"; break; - default: return "Unknown Request Type"; break; - } - return ""; -} -} - -// Parse a single key-value pair -static std::pair ParseKeyValuePair(const std::string& encoded) { - std::size_t eq_pos = encoded.find("="); - if (eq_pos == std::string::npos) - throw ParseError("Failed to find '=' in key-value pair."); - return std::pair( - encoded.substr(0, eq_pos), - encoded.substr(eq_pos+1) - ); -} - -KeyValuePairs ParseKeyValuePairs(const std::string& encoded) { - KeyValuePairs result; - - if (encoded.length() == 0) return result; - - // Split by & - std::size_t last_amp = 0; - // We can bail when the last one "found" was the end of the string - while(true) { - std::size_t next_amp = encoded.find('&', last_amp+1); - std::string keyval = - (next_amp == std::string::npos) ? - encoded.substr(last_amp) : - encoded.substr(last_amp, next_amp-last_amp); - result.insert(ParseKeyValuePair(keyval)); - // Track spot after the & so the first iteration works without dealing - // with -1 index - last_amp = next_amp+1; - - // Exit condition - if (next_amp == std::string::npos) break; - } - return result; -} - -// Helper for parameters in key-value pair lists that should only appear -// once. Either replaces an existing entry or adds a new entry. -static void ReplaceOrInsertKeyValuePair(KeyValuePairs& kvp, const std::string& key, const std::string& value) { - assert(kvp.count(key) <= 1); - KeyValuePairs::iterator it = kvp.find(key); - if (it != kvp.end()) - it->second = value; - else - kvp.insert(KeyValuePairs::value_type(key, value)); -} - -Consumer::Consumer(const std::string& key, const std::string& secret) - : mKey(key), mSecret(secret) -{ -} - - - -Token::Token(const std::string& key, const std::string& secret) - : mKey(key), mSecret(secret) -{ -} - -Token::Token(const std::string& key, const std::string& secret, const std::string& pin) - : mKey(key), mSecret(secret), mPin(pin) -{ -} - -Token Token::extract(const std::string& response) { - return Token::extract(ParseKeyValuePairs(response)); -} - -Token Token::extract(const KeyValuePairs& response) { - std::string token_key, token_secret; - - KeyValuePairs::const_iterator it = response.find(Defaults::TOKEN_KEY); - if (it == response.end()) - throw MissingKeyError("Couldn't find oauth_token in response"); - token_key = it->second; - - it = response.find(Defaults::TOKENSECRET_KEY); - if (it == response.end()) - throw MissingKeyError("Couldn't find oauth_token_secret in response"); - token_secret = it->second; - - return Token(token_key, token_secret); -} - - -bool Client::initialized = false; -int Client::testingNonce = 0; -time_t Client::testingTimestamp = 0; - -void Client::initialize() { - if(!initialized) { - srand( time( NULL ) ); - initialized = true; - } -} - -void Client::initialize(int nonce, time_t timestamp) { - if(!initialized) { - testingNonce = nonce; - testingTimestamp = timestamp; - initialized = true; - } -} - -void Client::__resetInitialize() { - testingNonce = 0; - testingTimestamp = 0; - initialized = false; -} - -Client::Client(const Consumer* consumer) - : mConsumer(consumer), - mToken(NULL) -{ -} - -Client::Client(const Consumer* consumer, const Token* token) - : mConsumer(consumer), - mToken(token) -{ -} - - -Client::~Client() -{ -} - - - -/*++ -* @method: Client::generateNonceTimeStamp -* -* @description: this method generates nonce and timestamp for OAuth header -* -* @input: none -* -* @output: none -* -* @remarks: internal method -* -*--*/ -void Client::generateNonceTimeStamp() -{ - // Make sure the random seed has been initialized - Client::initialize(); - - char szTime[Defaults::BUFFSIZE]; - char szRand[Defaults::BUFFSIZE]; - memset( szTime, 0, Defaults::BUFFSIZE ); - memset( szRand, 0, Defaults::BUFFSIZE ); - - // Any non-zero timestamp triggers testing mode with fixed values. Fixing - // both values makes life easier because generating a signature is - // idempotent -- otherwise using macros can cause double evaluation and - // incorrect results because of repeated calls to rand(). - snprintf( szRand, sizeof(szRand), "%x", ((testingTimestamp != 0) ? testingNonce : rand()) ); - snprintf( szTime, sizeof(szTime), "%ld", ((testingTimestamp != 0) ? testingTimestamp : time( NULL )) ); - - m_nonce.assign( szTime ); - m_nonce.append( szRand ); - - m_timeStamp.assign( szTime ); -} - -/*++ -* @method: Client::buildOAuthTokenKeyValuePairs -* -* @description: this method prepares key-value pairs required for OAuth header -* and signature generation. -* -* @input: includeOAuthVerifierPin - flag to indicate whether oauth_verifer key-value -* pair needs to be included. oauth_verifer is only -* used during exchanging request token with access token. -* rawData - url encoded data. this is used during signature generation. -* oauthSignature - base64 and url encoded OAuth signature. -* generateTimestamp - If true, then generate new timestamp for nonce. -* -* @input: urlEncodeValues - if true, URLEncode the values inserted into the -* output keyValueMap -* @output: keyValueMap - map in which key-value pairs are populated -* -* @remarks: internal method -* -*--*/ -bool Client::buildOAuthTokenKeyValuePairs( const bool includeOAuthVerifierPin, - const std::string& rawData, - const std::string& oauthSignature, - KeyValuePairs& keyValueMap, - const bool urlEncodeValues, - const bool generateTimestamp ) -{ - // Encodes value part of key-value pairs depending on type of output (query - // string vs. HTTP headers. - StringConvertFunction value_encoder = (urlEncodeValues ? HttpEncodeQueryValue : PassThrough); - - /* Generate nonce and timestamp if required */ - if( generateTimestamp ) - { - generateNonceTimeStamp(); - } - - /* Consumer key and its value */ - ReplaceOrInsertKeyValuePair(keyValueMap, Defaults::CONSUMERKEY_KEY, value_encoder(mConsumer->key())); - - /* Nonce key and its value */ - ReplaceOrInsertKeyValuePair(keyValueMap, Defaults::NONCE_KEY, value_encoder(m_nonce)); - - /* Signature if supplied */ - if( oauthSignature.length() ) - { - // Signature is exempt from encoding. The procedure for - // computing it already percent-encodes it as required by the - // spec for both query string and Auth header - // methods. Therefore, it's pass-through in both cases. - ReplaceOrInsertKeyValuePair(keyValueMap, Defaults::SIGNATURE_KEY, oauthSignature); - } - - /* Signature method, only HMAC-SHA1 as of now */ - ReplaceOrInsertKeyValuePair(keyValueMap, Defaults::SIGNATUREMETHOD_KEY, std::string( "HMAC-SHA1" )); - - /* Timestamp */ - ReplaceOrInsertKeyValuePair(keyValueMap, Defaults::TIMESTAMP_KEY, value_encoder(m_timeStamp)); - - /* Token */ - if( mToken && mToken->key().length() ) - { - ReplaceOrInsertKeyValuePair(keyValueMap, Defaults::TOKEN_KEY, value_encoder(mToken->key())); - } - - /* Verifier */ - if( includeOAuthVerifierPin && mToken && mToken->pin().length() ) - { - ReplaceOrInsertKeyValuePair(keyValueMap, Defaults::VERIFIER_KEY, value_encoder(mToken->pin())); - } - - /* Version */ - ReplaceOrInsertKeyValuePair(keyValueMap, Defaults::VERSION_KEY, std::string( "1.0" )); - - /* Data if it's present */ - if( rawData.length() ) - { - /* Data should already be urlencoded once */ - std::string dummyStrKey; - std::string dummyStrValue; - size_t nPos = rawData.find_first_of( "=" ); - if( std::string::npos != nPos ) - { - dummyStrKey = rawData.substr( 0, nPos ); - dummyStrValue = rawData.substr( nPos + 1 ); - ReplaceOrInsertKeyValuePair(keyValueMap, dummyStrKey, dummyStrValue); - } - } - - return ( keyValueMap.size() ) ? true : false; -} - -/*++ -* @method: Client::getSignature -* -* @description: this method calculates HMAC-SHA1 signature of OAuth header -* -* @input: eType - HTTP request type -* rawUrl - raw url of the HTTP request -* rawKeyValuePairs - key-value pairs containing OAuth headers and HTTP data -* -* @output: oAuthSignature - base64 and url encoded signature -* -* @remarks: internal method -* -*--*/ -bool Client::getSignature( const Http::RequestType eType, - const std::string& rawUrl, - const KeyValuePairs& rawKeyValuePairs, - std::string& oAuthSignature ) -{ - std::string rawParams; - std::string paramsSeperator; - std::string sigBase; - - /* Initially empty signature */ - oAuthSignature.assign( "" ); - - /* Build a string using key-value pairs */ - paramsSeperator = "&"; - getStringFromOAuthKeyValuePairs( rawKeyValuePairs, rawParams, paramsSeperator ); - LOG(LogLevelDebug, "Normalized parameters: " << rawParams); - - /* Start constructing base signature string. Refer http://dev.twitter.com/auth#intro */ - switch( eType ) - { - case Http::Head: - { - sigBase.assign( "HEAD&" ); - } - break; - - case Http::Get: - { - sigBase.assign( "GET&" ); - } - break; - - case Http::Post: - { - sigBase.assign( "POST&" ); - } - break; - - case Http::Delete: - { - sigBase.assign( "DELETE&" ); - } - break; - - case Http::Put: - { - sigBase.assign( "PUT&" ); - } - break; - - default: - { - return false; - } - break; - } - sigBase.append( PercentEncode( rawUrl ) ); - sigBase.append( "&" ); - sigBase.append( PercentEncode( rawParams ) ); - LOG(LogLevelDebug, "Signature base string: " << sigBase); - - /* Now, hash the signature base string using HMAC_SHA1 class */ - CHMAC_SHA1 objHMACSHA1; - std::string secretSigningKey; - unsigned char strDigest[Defaults::BUFFSIZE_LARGE]; - - memset( strDigest, 0, Defaults::BUFFSIZE_LARGE ); - - /* Signing key is composed of consumer_secret&token_secret */ - secretSigningKey.assign( PercentEncode(mConsumer->secret()) ); - secretSigningKey.append( "&" ); - if( mToken && mToken->secret().length() ) - { - secretSigningKey.append( PercentEncode(mToken->secret()) ); - } - - objHMACSHA1.HMAC_SHA1( (unsigned char*)sigBase.c_str(), - sigBase.length(), - (unsigned char*)secretSigningKey.c_str(), - secretSigningKey.length(), - strDigest ); - - /* Do a base64 encode of signature */ - std::string base64Str = base64_encode( strDigest, 20 /* SHA 1 digest is 160 bits */ ); - LOG(LogLevelDebug, "Signature: " << base64Str); - - /* Do an url encode */ - oAuthSignature = PercentEncode( base64Str ); - LOG(LogLevelDebug, "Percent-encoded Signature: " << oAuthSignature); - - return ( oAuthSignature.length() ) ? true : false; -} - -std::string Client::getHttpHeader(const Http::RequestType eType, - const std::string& rawUrl, - const std::string& rawData, - const bool includeOAuthVerifierPin) -{ - return Defaults::AUTHHEADER_PREFIX + buildOAuthParameterString(AuthorizationHeaderString, eType, rawUrl, rawData, includeOAuthVerifierPin); -} - -std::string Client::getFormattedHttpHeader(const Http::RequestType eType, - const std::string& rawUrl, - const std::string& rawData, - const bool includeOAuthVerifierPin) -{ - return Defaults::AUTHHEADER_FIELD + Defaults::AUTHHEADER_PREFIX + buildOAuthParameterString(AuthorizationHeaderString, eType, rawUrl, rawData, includeOAuthVerifierPin); -} - -std::string Client::getURLQueryString(const Http::RequestType eType, - const std::string& rawUrl, - const std::string& rawData, - const bool includeOAuthVerifierPin) -{ - return buildOAuthParameterString(QueryStringString, eType, rawUrl, rawData, includeOAuthVerifierPin); -} - -std::string Client::buildOAuthParameterString( - ParameterStringType string_type, - const Http::RequestType eType, - const std::string& rawUrl, - const std::string& rawData, - const bool includeOAuthVerifierPin) -{ - KeyValuePairs rawKeyValuePairs; - std::string rawParams; - std::string oauthSignature; - std::string paramsSeperator; - std::string pureUrl( rawUrl ); - - LOG(LogLevelDebug, "Signing request " << RequestTypeString(eType) << " " << rawUrl << " " << rawData); - - std::string separator; - bool do_urlencode; - if (string_type == AuthorizationHeaderString) { - separator = ","; - do_urlencode = false; - } - else { // QueryStringString - separator = "&"; - do_urlencode = true; - } - - /* Clear header string initially */ - rawKeyValuePairs.clear(); - - /* If URL itself contains ?key=value, then extract and put them in map */ - size_t nPos = rawUrl.find_first_of( "?" ); - if( std::string::npos != nPos ) - { - /* Get only URL */ - pureUrl = rawUrl.substr( 0, nPos ); - - /* Get only key=value data part */ - std::string dataPart = rawUrl.substr( nPos + 1 ); - rawKeyValuePairs = ParseKeyValuePairs(dataPart); - } - - // NOTE: We always request URL encoding on the first pass so that the - // signature generation works properly. This *relies* on - // buildOAuthTokenKeyValuePairs overwriting values when we do the second - // pass to get the values in the form we actually want. The signature and - // rawdata are the only things that change, but the signature is only used - // in the second pass and the rawdata is already encoded, regardless of - // request type. - - /* Build key-value pairs needed for OAuth request token, without signature */ - buildOAuthTokenKeyValuePairs( includeOAuthVerifierPin, rawData, std::string( "" ), rawKeyValuePairs, true, true ); - - /* Get url encoded base64 signature using request type, url and parameters */ - getSignature( eType, pureUrl, rawKeyValuePairs, oauthSignature ); - - /* Now, again build key-value pairs with signature this time */ - buildOAuthTokenKeyValuePairs( includeOAuthVerifierPin, std::string( "" ), oauthSignature, rawKeyValuePairs, do_urlencode, false ); - - /* Get OAuth header in string format. If we're getting the Authorization - * header, we need to filter out other parameters. - */ - if (string_type == AuthorizationHeaderString) { - KeyValuePairs oauthKeyValuePairs; - std::vector oauth_keys; - oauth_keys.push_back(Defaults::CONSUMERKEY_KEY); - oauth_keys.push_back(Defaults::NONCE_KEY); - oauth_keys.push_back(Defaults::SIGNATURE_KEY); - oauth_keys.push_back(Defaults::SIGNATUREMETHOD_KEY); - oauth_keys.push_back(Defaults::TIMESTAMP_KEY); - oauth_keys.push_back(Defaults::TOKEN_KEY); - oauth_keys.push_back(Defaults::VERIFIER_KEY); - oauth_keys.push_back(Defaults::VERSION_KEY); - - for(size_t i = 0; i < oauth_keys.size(); i++) { - assert(rawKeyValuePairs.count(oauth_keys[i]) <= 1); - KeyValuePairs::iterator oauth_key_it = rawKeyValuePairs.find(oauth_keys[i]); - if (oauth_key_it != rawKeyValuePairs.end()) - ReplaceOrInsertKeyValuePair(oauthKeyValuePairs, oauth_keys[i], oauth_key_it->second); - } - getStringFromOAuthKeyValuePairs( oauthKeyValuePairs, rawParams, separator ); - } - else if (string_type == QueryStringString) { - getStringFromOAuthKeyValuePairs( rawKeyValuePairs, rawParams, separator ); - } - - /* Build authorization header */ - return rawParams; -} - -/*++ -* @method: Client::getStringFromOAuthKeyValuePairs -* -* @description: this method builds a sorted string from key-value pairs -* -* @input: rawParamMap - key-value pairs map -* paramsSeperator - sepearator, either & or , -* -* @output: rawParams - sorted string of OAuth parameters -* -* @remarks: internal method -* -*--*/ -bool Client::getStringFromOAuthKeyValuePairs( const KeyValuePairs& rawParamMap, - std::string& rawParams, - const std::string& paramsSeperator ) -{ - rawParams.assign( "" ); - if( rawParamMap.size() ) - { - KeyValueList keyValueList; - std::string dummyStr; - - /* Push key-value pairs to a list of strings */ - keyValueList.clear(); - KeyValuePairs::const_iterator itMap = rawParamMap.begin(); - for( ; itMap != rawParamMap.end(); itMap++ ) - { - dummyStr.assign( itMap->first ); - dummyStr.append( "=" ); - if( paramsSeperator == "," ) - { - dummyStr.append( "\"" ); - } - dummyStr.append( itMap->second ); - if( paramsSeperator == "," ) - { - dummyStr.append( "\"" ); - } - keyValueList.push_back( dummyStr ); - } - - /* Sort key-value pairs based on key name */ - keyValueList.sort(); - - /* Now, form a string */ - dummyStr.assign( "" ); - KeyValueList::iterator itKeyValue = keyValueList.begin(); - for( ; itKeyValue != keyValueList.end(); itKeyValue++ ) - { - if( dummyStr.length() ) - { - dummyStr.append( paramsSeperator ); - } - dummyStr.append( itKeyValue->c_str() ); - } - rawParams.assign( dummyStr ); - } - return ( rawParams.length() ) ? true : false; -} - - -} // namespace OAuth diff --git a/3party/liboauthcpp/src/urlencode.cpp b/3party/liboauthcpp/src/urlencode.cpp deleted file mode 100644 index 9ad5f3b172..0000000000 --- a/3party/liboauthcpp/src/urlencode.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include "urlencode.h" -#include - -std::string char2hex( char dec ) -{ - char dig1 = (dec&0xF0)>>4; - char dig2 = (dec&0x0F); - if ( 0<= dig1 && dig1<= 9) dig1+=48; //0,48 in ascii - if (10<= dig1 && dig1<=15) dig1+=65-10; //A,65 in ascii - if ( 0<= dig2 && dig2<= 9) dig2+=48; - if (10<= dig2 && dig2<=15) dig2+=65-10; - - std::string r; - r.append( &dig1, 1); - r.append( &dig2, 1); - return r; -} - -std::string urlencode( const std::string &c, URLEncodeType enctype) -{ - - std::string escaped; - int max = c.length(); - for(int i=0; i -#include - -std::string char2hex( char dec ); -enum URLEncodeType { - URLEncode_Everything, - URLEncode_Path, - URLEncode_QueryKey, - URLEncode_QueryValue, -}; -std::string urlencode( const std::string &c, URLEncodeType enctype ); - -#endif // __URLENCODE_H__ diff --git a/android/app/src/main/cpp/CMakeLists.txt b/android/app/src/main/cpp/CMakeLists.txt index 21741e397f..5203f653be 100644 --- a/android/app/src/main/cpp/CMakeLists.txt +++ b/android/app/src/main/cpp/CMakeLists.txt @@ -98,7 +98,6 @@ target_link_libraries(${PROJECT_NAME} # base # opening_hours # pugixml - # oauthcpp # expat # freetype # minizip diff --git a/coding/CMakeLists.txt b/coding/CMakeLists.txt index b9972aa0a5..38a388ceca 100644 --- a/coding/CMakeLists.txt +++ b/coding/CMakeLists.txt @@ -100,7 +100,6 @@ target_link_libraries(${PROJECT_NAME} succinct ICU::uc ICU::i18n # For transliteration. - oauthcpp # For base64_encode and base64_decode minizip ZLIB::ZLIB ) diff --git a/coding/base64.cpp b/coding/base64.cpp index 9800ce308d..ed15238088 100644 --- a/coding/base64.cpp +++ b/coding/base64.cpp @@ -31,10 +31,10 @@ std::string Decode(const std::string & val) [](char c) { return c == '\0'; }); } -std::string Encode(const std::string & val) +std::string Encode(std::string_view val) { using namespace boost::archive::iterators; - using It = base64_from_binary>; + using It = base64_from_binary>; auto tmp = std::string(It(std::begin(val)), It(std::end(val))); return tmp.append((3 - val.size() % 3) % 3, '='); } diff --git a/coding/base64.hpp b/coding/base64.hpp index 8f3e8cb678..bf2c752c01 100644 --- a/coding/base64.hpp +++ b/coding/base64.hpp @@ -4,6 +4,6 @@ namespace base64 { -std::string Encode(std::string const & bytesToEncode); +std::string Encode(std::string_view bytesToEncode); std::string Decode(std::string const & base64CharsToDecode); } // namespace base64 diff --git a/coding/sha1.cpp b/coding/sha1.cpp index 384ba43cb7..cb226dfa92 100644 --- a/coding/sha1.cpp +++ b/coding/sha1.cpp @@ -1,20 +1,36 @@ #include "coding/sha1.hpp" +#include "coding/base64.hpp" #include "coding/internal/file_data.hpp" #include "coding/reader.hpp" #include "base/assert.hpp" #include "base/logging.hpp" -#include "base/macros.hpp" -#include "3party/liboauthcpp/src/SHA1.h" -#include "3party/liboauthcpp/src/base64.h" +#include +#include #include #include namespace coding { +namespace +{ +SHA1::Hash ExtractHash(boost::uuids::detail::sha1 & sha1) +{ + uint32_t digest[5]; + sha1.get_digest(digest); + for (auto & b : digest) + b = boost::core::byteswap(b); + + SHA1::Hash result; + static_assert(result.size() == sizeof(digest)); + std::copy_n(reinterpret_cast(digest), sizeof(digest), std::begin(result)); + return result; +} +} + // static SHA1::Hash SHA1::Calculate(std::string const & filePath) { @@ -23,7 +39,8 @@ SHA1::Hash SHA1::Calculate(std::string const & filePath) base::FileData file(filePath, base::FileData::Op::READ); uint64_t const fileSize = file.Size(); - CSHA1 sha1; + boost::uuids::detail::sha1 sha1; + uint64_t currSize = 0; uint32_t constexpr kFileBufferSize = 8192; unsigned char buffer[kFileBufferSize]; @@ -31,15 +48,10 @@ SHA1::Hash SHA1::Calculate(std::string const & filePath) { auto const toRead = std::min(kFileBufferSize, static_cast(fileSize - currSize)); file.Read(currSize, buffer, toRead); - sha1.Update(buffer, toRead); + sha1.process_bytes(buffer, toRead); currSize += toRead; } - sha1.Final(); - - Hash result; - ASSERT_EQUAL(result.size(), ARRAY_SIZE(sha1.m_digest), ()); - std::copy(std::begin(sha1.m_digest), std::end(sha1.m_digest), std::begin(result)); - return result; + return ExtractHash(sha1); } catch (Reader::Exception const & ex) { @@ -52,39 +64,14 @@ SHA1::Hash SHA1::Calculate(std::string const & filePath) std::string SHA1::CalculateBase64(std::string const & filePath) { auto const sha1 = Calculate(filePath); - return base64_encode(sha1.data(), sha1.size()); + return base64::Encode(std::string_view(reinterpret_cast(sha1.data()), sha1.size())); } // static -SHA1::Hash SHA1::CalculateForString(std::string const & str) +SHA1::Hash SHA1::CalculateForString(std::string_view str) { - CSHA1 sha1; - std::vector dat(str.begin(), str.end()); - sha1.Update(dat.data(), static_cast(dat.size())); - sha1.Final(); - - Hash result; - ASSERT_EQUAL(result.size(), ARRAY_SIZE(sha1.m_digest), ()); - std::copy(std::begin(sha1.m_digest), std::end(sha1.m_digest), std::begin(result)); - return result; -} - -// static -std::string SHA1::CalculateForStringFormatted(std::string const & str) -{ - auto const hashRaw = CalculateForString(str); - - std::ostringstream os; - for (auto const value : hashRaw) - os << std::hex << static_cast(value); - - return os.str(); -} - -// static -std::string SHA1::CalculateBase64ForString(std::string const & str) -{ - auto const sha1 = CalculateForString(str); - return base64_encode(sha1.data(), sha1.size()); + boost::uuids::detail::sha1 sha1; + sha1.process_bytes(str.data(), str.size()); + return ExtractHash(sha1); } } // coding diff --git a/coding/sha1.hpp b/coding/sha1.hpp index 58b8e3a1cb..b5ecb24efa 100644 --- a/coding/sha1.hpp +++ b/coding/sha1.hpp @@ -15,9 +15,6 @@ public: static Hash Calculate(std::string const & filePath); static std::string CalculateBase64(std::string const & filePath); - static Hash CalculateForString(std::string const & str); - // String representation of 40-number hex digit. - static std::string CalculateForStringFormatted(std::string const & str); - static std::string CalculateBase64ForString(std::string const & str); + static Hash CalculateForString(std::string_view str); }; } // coding diff --git a/data/copyright.html b/data/copyright.html index 32b479ade9..cd113b92ce 100644 --- a/data/copyright.html +++ b/data/copyright.html @@ -179,9 +179,6 @@
  • libkdtree++
    © 2004-2007 Martin F. Krafft, parts are © 2004-2008 Paul Harris and © 2007-2008 Sylvain Bougerel; Artistic License
  • -
  • liboauthcpp
    - © 2011 Stanford University, © 2011 swatkat (libtwitcurl); MIT License
  • -
  • MAPS.ME
    © 2020 My.com B.V. (Mail.Ru Group); Apache License
  • diff --git a/generator/pygen/CMakeLists.txt b/generator/pygen/CMakeLists.txt index 3583d44913..9a062e2f35 100644 --- a/generator/pygen/CMakeLists.txt +++ b/generator/pygen/CMakeLists.txt @@ -37,7 +37,6 @@ omim_link_libraries( succinct pugixml tess2 - oauthcpp sqlite3 ${CMAKE_DL_LIBS} ZLIB::ZLIB diff --git a/iphone/Maps/Maps.xcodeproj/project.pbxproj b/iphone/Maps/Maps.xcodeproj/project.pbxproj index 696fa524d1..700e4b6035 100644 --- a/iphone/Maps/Maps.xcodeproj/project.pbxproj +++ b/iphone/Maps/Maps.xcodeproj/project.pbxproj @@ -617,7 +617,6 @@ FA853BBB26BC3B8A0026D455 /* libkml.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA853BBA26BC3B8A0026D455 /* libkml.a */; }; FA853BBD26BC3B8A0026D455 /* libmap.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA853BBC26BC3B8A0026D455 /* libmap.a */; }; FA853BBF26BC3B8A0026D455 /* minizip.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA853BBE26BC3B8A0026D455 /* minizip.framework */; }; - FA853BC126BC3B8A0026D455 /* liboauthcpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA853BC026BC3B8A0026D455 /* liboauthcpp.a */; }; FA853BC326BC3B8A0026D455 /* libopening_hours.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA853BC226BC3B8A0026D455 /* libopening_hours.a */; }; FA853BC526BC3B8A0026D455 /* libplatform.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA853BC426BC3B8A0026D455 /* libplatform.a */; }; FA853BC726BC3B8A0026D455 /* libprotobuf.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA853BC626BC3B8A0026D455 /* libprotobuf.a */; }; @@ -1622,7 +1621,6 @@ FA853BBA26BC3B8A0026D455 /* libkml.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libkml.a; sourceTree = BUILT_PRODUCTS_DIR; }; FA853BBC26BC3B8A0026D455 /* libmap.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libmap.a; sourceTree = BUILT_PRODUCTS_DIR; }; FA853BBE26BC3B8A0026D455 /* minizip.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = minizip.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - FA853BC026BC3B8A0026D455 /* liboauthcpp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = liboauthcpp.a; sourceTree = BUILT_PRODUCTS_DIR; }; FA853BC226BC3B8A0026D455 /* libopening_hours.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libopening_hours.a; sourceTree = BUILT_PRODUCTS_DIR; }; FA853BC426BC3B8A0026D455 /* libplatform.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libplatform.a; sourceTree = BUILT_PRODUCTS_DIR; }; FA853BC626BC3B8A0026D455 /* libprotobuf.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libprotobuf.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1719,7 +1717,6 @@ FA853BBB26BC3B8A0026D455 /* libkml.a in Frameworks */, FA853BBD26BC3B8A0026D455 /* libmap.a in Frameworks */, FA853BBF26BC3B8A0026D455 /* minizip.framework in Frameworks */, - FA853BC126BC3B8A0026D455 /* liboauthcpp.a in Frameworks */, FA853BC326BC3B8A0026D455 /* libopening_hours.a in Frameworks */, FA853BC526BC3B8A0026D455 /* libplatform.a in Frameworks */, FA853BC726BC3B8A0026D455 /* libprotobuf.a in Frameworks */, @@ -1865,7 +1862,6 @@ FA853BBA26BC3B8A0026D455 /* libkml.a */, FA853BBC26BC3B8A0026D455 /* libmap.a */, FA853BBE26BC3B8A0026D455 /* minizip.framework */, - FA853BC026BC3B8A0026D455 /* liboauthcpp.a */, FA853BC226BC3B8A0026D455 /* libopening_hours.a */, FA853BC426BC3B8A0026D455 /* libplatform.a */, FA853BC626BC3B8A0026D455 /* libprotobuf.a */, diff --git a/kml/pykmlib/CMakeLists.txt b/kml/pykmlib/CMakeLists.txt index 52f2bfb193..4989a0170a 100644 --- a/kml/pykmlib/CMakeLists.txt +++ b/kml/pykmlib/CMakeLists.txt @@ -21,7 +21,6 @@ omim_link_libraries( base ICU::i18n cppjansson - oauthcpp protobuf pugixml expat::expat diff --git a/search/pysearch/CMakeLists.txt b/search/pysearch/CMakeLists.txt index 38badf2900..ff049a01a6 100644 --- a/search/pysearch/CMakeLists.txt +++ b/search/pysearch/CMakeLists.txt @@ -26,7 +26,6 @@ omim_link_libraries( bsdiff ICU::i18n cppjansson - oauthcpp opening_hours protobuf pugixml diff --git a/traffic/pytraffic/CMakeLists.txt b/traffic/pytraffic/CMakeLists.txt index 0dd0c16d96..698628fc76 100644 --- a/traffic/pytraffic/CMakeLists.txt +++ b/traffic/pytraffic/CMakeLists.txt @@ -37,7 +37,6 @@ omim_link_libraries( coding base cppjansson - oauthcpp protobuf pugixml opening_hours diff --git a/xcode/editor/editor.xcodeproj/project.pbxproj b/xcode/editor/editor.xcodeproj/project.pbxproj index 1a2a0b58f1..231a6c11de 100644 --- a/xcode/editor/editor.xcodeproj/project.pbxproj +++ b/xcode/editor/editor.xcodeproj/project.pbxproj @@ -55,7 +55,6 @@ FACB76B926B89DFB00810C9C /* match_by_geometry_test.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3D05248A200F630000F24998 /* match_by_geometry_test.cpp */; }; FACB76BB26B89FFE00810C9C /* libbase.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FACB76BA26B89FFE00810C9C /* libbase.a */; }; FACB76BD26B8A00400810C9C /* libgeometry.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FACB76BC26B8A00400810C9C /* libgeometry.a */; }; - FACB76BF26B8A00B00810C9C /* liboauthcpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FACB76BE26B8A00B00810C9C /* liboauthcpp.a */; }; FACB76C126B8A01100810C9C /* libpugixml.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FACB76C026B8A01100810C9C /* libpugixml.a */; }; FACB76C326B8A03600810C9C /* libcoding.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FACB76C226B8A03600810C9C /* libcoding.a */; }; FACB76C526B8A04200810C9C /* libindexer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FACB76C426B8A04200810C9C /* libindexer.a */; }; @@ -129,7 +128,6 @@ F60F02ED1C92CBF1003A0AF6 /* editor_notes.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = editor_notes.hpp; sourceTree = ""; }; FACB76BA26B89FFE00810C9C /* libbase.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libbase.a; sourceTree = BUILT_PRODUCTS_DIR; }; FACB76BC26B8A00400810C9C /* libgeometry.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libgeometry.a; sourceTree = BUILT_PRODUCTS_DIR; }; - FACB76BE26B8A00B00810C9C /* liboauthcpp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = liboauthcpp.a; sourceTree = BUILT_PRODUCTS_DIR; }; FACB76C026B8A01100810C9C /* libpugixml.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libpugixml.a; sourceTree = BUILT_PRODUCTS_DIR; }; FACB76C226B8A03600810C9C /* libcoding.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libcoding.a; sourceTree = BUILT_PRODUCTS_DIR; }; FACB76C426B8A04200810C9C /* libindexer.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libindexer.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -168,7 +166,6 @@ FACB76D926B8A22000810C9C /* libcppjansson.a in Frameworks */, FACB76BB26B89FFE00810C9C /* libbase.a in Frameworks */, FACB76C326B8A03600810C9C /* libcoding.a in Frameworks */, - FACB76BF26B8A00B00810C9C /* liboauthcpp.a in Frameworks */, FACB76D726B8A18F00810C9C /* libsuccinct.a in Frameworks */, FACB76BD26B8A00400810C9C /* libgeometry.a in Frameworks */, FACB76C926B8A08800810C9C /* libplatform.a in Frameworks */, @@ -299,7 +296,6 @@ FACB76C426B8A04200810C9C /* libindexer.a */, FACB76C226B8A03600810C9C /* libcoding.a */, FACB76C026B8A01100810C9C /* libpugixml.a */, - FACB76BE26B8A00B00810C9C /* liboauthcpp.a */, FACB76BC26B8A00400810C9C /* libgeometry.a */, FACB76BA26B89FFE00810C9C /* libbase.a */, ); diff --git a/xcode/ge0/ge0.xcodeproj/project.pbxproj b/xcode/ge0/ge0.xcodeproj/project.pbxproj index b58b6070c3..38afee7bbd 100644 --- a/xcode/ge0/ge0.xcodeproj/project.pbxproj +++ b/xcode/ge0/ge0.xcodeproj/project.pbxproj @@ -11,7 +11,6 @@ 391A145C23E0FC7F00A448F4 /* libplatform.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 391A145B23E0FC7F00A448F4 /* libplatform.a */; }; 391A145E23E0FC8400A448F4 /* libcoding.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 391A145D23E0FC8400A448F4 /* libcoding.a */; }; 391A146023E0FC8700A448F4 /* libbase.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 391A145F23E0FC8700A448F4 /* libbase.a */; }; - 391A146223E0FC8B00A448F4 /* liboauthcpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 391A146123E0FC8B00A448F4 /* liboauthcpp.a */; }; 391A146623E0FC9A00A448F4 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 391A146523E0FC9A00A448F4 /* libz.tbd */; }; 39C29BD023E19B3C009ECB47 /* parser.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 39C29BCC23E19B3C009ECB47 /* parser.hpp */; }; 39C29BD123E19B3C009ECB47 /* parser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 39C29BCD23E19B3C009ECB47 /* parser.cpp */; }; @@ -32,7 +31,6 @@ 391A145B23E0FC7F00A448F4 /* libplatform.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libplatform.a; sourceTree = BUILT_PRODUCTS_DIR; }; 391A145D23E0FC8400A448F4 /* libcoding.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libcoding.a; sourceTree = BUILT_PRODUCTS_DIR; }; 391A145F23E0FC8700A448F4 /* libbase.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libbase.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 391A146123E0FC8B00A448F4 /* liboauthcpp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = liboauthcpp.a; sourceTree = BUILT_PRODUCTS_DIR; }; 391A146523E0FC9A00A448F4 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; 39C29BCC23E19B3C009ECB47 /* parser.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = parser.hpp; path = ../../ge0/parser.hpp; sourceTree = ""; }; 39C29BCD23E19B3C009ECB47 /* parser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = parser.cpp; path = ../../ge0/parser.cpp; sourceTree = ""; }; @@ -53,7 +51,6 @@ buildActionMask = 2147483647; files = ( 391A146623E0FC9A00A448F4 /* libz.tbd in Frameworks */, - 391A146223E0FC8B00A448F4 /* liboauthcpp.a in Frameworks */, 391A146023E0FC8700A448F4 /* libbase.a in Frameworks */, 391A145E23E0FC8400A448F4 /* libcoding.a in Frameworks */, 391A145C23E0FC7F00A448F4 /* libplatform.a in Frameworks */, @@ -75,7 +72,6 @@ isa = PBXGroup; children = ( 391A146523E0FC9A00A448F4 /* libz.tbd */, - 391A146123E0FC8B00A448F4 /* liboauthcpp.a */, 391A145F23E0FC8700A448F4 /* libbase.a */, 391A145D23E0FC8400A448F4 /* libcoding.a */, 391A145B23E0FC7F00A448F4 /* libplatform.a */, diff --git a/xcode/generator/generator.xcodeproj/project.pbxproj b/xcode/generator/generator.xcodeproj/project.pbxproj index 579d8a82cc..298044a7ef 100644 --- a/xcode/generator/generator.xcodeproj/project.pbxproj +++ b/xcode/generator/generator.xcodeproj/project.pbxproj @@ -33,7 +33,6 @@ FACB777726B90CF200810C9C /* minizip.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FACB777626B90CF200810C9C /* minizip.framework */; }; FACB777926B90CFB00810C9C /* libprotobuf.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FACB777826B90CFB00810C9C /* libprotobuf.a */; }; FACB777B26B90D0700810C9C /* librouting_common.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FACB777A26B90D0700810C9C /* librouting_common.a */; }; - FACB777D26B90E5B00810C9C /* liboauthcpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FACB777C26B90E5B00810C9C /* liboauthcpp.a */; }; FACB777F26B90E7C00810C9C /* libmap.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FACB777E26B90E7C00810C9C /* libmap.a */; }; FACB778126B90E9800810C9C /* libtransit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FACB778026B90E9800810C9C /* libtransit.a */; }; FACB778326B90EAC00810C9C /* librouting.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FACB778226B90EAC00810C9C /* librouting.a */; }; @@ -331,7 +330,6 @@ FACB777626B90CF200810C9C /* minizip.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = minizip.framework; sourceTree = BUILT_PRODUCTS_DIR; }; FACB777826B90CFB00810C9C /* libprotobuf.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libprotobuf.a; sourceTree = BUILT_PRODUCTS_DIR; }; FACB777A26B90D0700810C9C /* librouting_common.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = librouting_common.a; sourceTree = BUILT_PRODUCTS_DIR; }; - FACB777C26B90E5B00810C9C /* liboauthcpp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = liboauthcpp.a; sourceTree = BUILT_PRODUCTS_DIR; }; FACB777E26B90E7C00810C9C /* libmap.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libmap.a; sourceTree = BUILT_PRODUCTS_DIR; }; FACB778026B90E9800810C9C /* libtransit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libtransit.a; sourceTree = BUILT_PRODUCTS_DIR; }; FACB778226B90EAC00810C9C /* librouting.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = librouting.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -611,7 +609,6 @@ FACB778D26B9118900810C9C /* libeditor.a in Frameworks */, FACB778B26B9112200810C9C /* libtess2.a in Frameworks */, FACB778726B90ECD00810C9C /* libopening_hours.a in Frameworks */, - FACB777D26B90E5B00810C9C /* liboauthcpp.a in Frameworks */, FACB777926B90CFB00810C9C /* libprotobuf.a in Frameworks */, FACB777726B90CF200810C9C /* minizip.framework in Frameworks */, FACB777326B90CCF00810C9C /* libcppjansson.a in Frameworks */, @@ -704,7 +701,6 @@ FACB778226B90EAC00810C9C /* librouting.a */, FACB778026B90E9800810C9C /* libtransit.a */, FACB777E26B90E7C00810C9C /* libmap.a */, - FACB777C26B90E5B00810C9C /* liboauthcpp.a */, FACB777A26B90D0700810C9C /* librouting_common.a */, FACB777826B90CFB00810C9C /* libprotobuf.a */, FACB777626B90CF200810C9C /* minizip.framework */, diff --git a/xcode/indexer/indexer.xcodeproj/project.pbxproj b/xcode/indexer/indexer.xcodeproj/project.pbxproj index 0493c2b635..1e1e941116 100644 --- a/xcode/indexer/indexer.xcodeproj/project.pbxproj +++ b/xcode/indexer/indexer.xcodeproj/project.pbxproj @@ -200,7 +200,6 @@ FACB7C2026B919AD00810C9C /* libgeometry.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FACB7C1C26B919AD00810C9C /* libgeometry.a */; }; FACB7C2126B919AD00810C9C /* libplatform.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FACB7C1D26B919AD00810C9C /* libplatform.a */; }; FACB7C2326B919C700810C9C /* libicu.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FACB7C2226B919C700810C9C /* libicu.a */; }; - FACB7C2526B919CC00810C9C /* liboauthcpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FACB7C2426B919CC00810C9C /* liboauthcpp.a */; }; FACB7C2726B919D300810C9C /* libprotobuf.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FACB7C2626B919D300810C9C /* libprotobuf.a */; }; FACB7C2926B919E600810C9C /* libgenerator_tests_support.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FACB7C2826B919E600810C9C /* libgenerator_tests_support.a */; }; FACB7C2B26B919F500810C9C /* libeditor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FACB7C2A26B919F500810C9C /* libeditor.a */; }; @@ -429,7 +428,6 @@ FACB7C1C26B919AD00810C9C /* libgeometry.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libgeometry.a; sourceTree = BUILT_PRODUCTS_DIR; }; FACB7C1D26B919AD00810C9C /* libplatform.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libplatform.a; sourceTree = BUILT_PRODUCTS_DIR; }; FACB7C2226B919C700810C9C /* libicu.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libicu.a; sourceTree = BUILT_PRODUCTS_DIR; }; - FACB7C2426B919CC00810C9C /* liboauthcpp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = liboauthcpp.a; sourceTree = BUILT_PRODUCTS_DIR; }; FACB7C2626B919D300810C9C /* libprotobuf.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libprotobuf.a; sourceTree = BUILT_PRODUCTS_DIR; }; FACB7C2826B919E600810C9C /* libgenerator_tests_support.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libgenerator_tests_support.a; sourceTree = BUILT_PRODUCTS_DIR; }; FACB7C2A26B919F500810C9C /* libeditor.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libeditor.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -457,7 +455,6 @@ FACB7C2F26B91A1100810C9C /* libopening_hours.a in Frameworks */, FACB7C3D26B9478200810C9C /* libsuccinct.a in Frameworks */, FACB7C2926B919E600810C9C /* libgenerator_tests_support.a in Frameworks */, - FACB7C2526B919CC00810C9C /* liboauthcpp.a in Frameworks */, FACB7C1F26B919AD00810C9C /* libcoding.a in Frameworks */, FACB7C2326B919C700810C9C /* libicu.a in Frameworks */, FACB7C3B26B9476200810C9C /* libstorage.a in Frameworks */, @@ -528,7 +525,6 @@ FACB7C2A26B919F500810C9C /* libeditor.a */, FACB7C2826B919E600810C9C /* libgenerator_tests_support.a */, FACB7C2626B919D300810C9C /* libprotobuf.a */, - FACB7C2426B919CC00810C9C /* liboauthcpp.a */, FACB7C2226B919C700810C9C /* libicu.a */, FACB7C1A26B919AD00810C9C /* libbase.a */, FACB7C1B26B919AD00810C9C /* libcoding.a */, diff --git a/xcode/kml/kml.xcodeproj/project.pbxproj b/xcode/kml/kml.xcodeproj/project.pbxproj index ab4188dba2..6327b789d8 100644 --- a/xcode/kml/kml.xcodeproj/project.pbxproj +++ b/xcode/kml/kml.xcodeproj/project.pbxproj @@ -25,7 +25,6 @@ FA67C85526BB372E00B33DCA /* libindexer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA67C85426BB372E00B33DCA /* libindexer.a */; }; FA67C85726BB373800B33DCA /* libgeometry.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA67C85626BB373800B33DCA /* libgeometry.a */; }; FA67C85926BB374300B33DCA /* libicu.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA67C85826BB374300B33DCA /* libicu.a */; }; - FA67C85B26BB374E00B33DCA /* liboauthcpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA67C85A26BB374E00B33DCA /* liboauthcpp.a */; }; FA67C85D26BB376300B33DCA /* libprotobuf.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA67C85C26BB376300B33DCA /* libprotobuf.a */; }; FA67C85F26BB377800B33DCA /* libsuccinct.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FA67C85E26BB377800B33DCA /* libsuccinct.a */; }; /* End PBXBuildFile section */ @@ -79,7 +78,6 @@ FA67C85426BB372E00B33DCA /* libindexer.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libindexer.a; sourceTree = BUILT_PRODUCTS_DIR; }; FA67C85626BB373800B33DCA /* libgeometry.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libgeometry.a; sourceTree = BUILT_PRODUCTS_DIR; }; FA67C85826BB374300B33DCA /* libicu.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libicu.a; sourceTree = BUILT_PRODUCTS_DIR; }; - FA67C85A26BB374E00B33DCA /* liboauthcpp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = liboauthcpp.a; sourceTree = BUILT_PRODUCTS_DIR; }; FA67C85C26BB376300B33DCA /* libprotobuf.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libprotobuf.a; sourceTree = BUILT_PRODUCTS_DIR; }; FA67C85E26BB377800B33DCA /* libsuccinct.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libsuccinct.a; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -98,7 +96,6 @@ files = ( FA67C85F26BB377800B33DCA /* libsuccinct.a in Frameworks */, FA67C85D26BB376300B33DCA /* libprotobuf.a in Frameworks */, - FA67C85B26BB374E00B33DCA /* liboauthcpp.a in Frameworks */, FA67C85926BB374300B33DCA /* libicu.a in Frameworks */, FA67C85726BB373800B33DCA /* libgeometry.a in Frameworks */, FA67C85526BB372E00B33DCA /* libindexer.a in Frameworks */, @@ -180,7 +177,6 @@ children = ( FA67C85E26BB377800B33DCA /* libsuccinct.a */, FA67C85C26BB376300B33DCA /* libprotobuf.a */, - FA67C85A26BB374E00B33DCA /* liboauthcpp.a */, FA67C85826BB374300B33DCA /* libicu.a */, FA67C85626BB373800B33DCA /* libgeometry.a */, FA67C85426BB372E00B33DCA /* libindexer.a */, diff --git a/xcode/map/map.xcodeproj/project.pbxproj b/xcode/map/map.xcodeproj/project.pbxproj index e4c015879b..97d510969c 100644 --- a/xcode/map/map.xcodeproj/project.pbxproj +++ b/xcode/map/map.xcodeproj/project.pbxproj @@ -113,7 +113,6 @@ FAA8388226BB3C92002E54C6 /* libprotobuf.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FAA8388126BB3C92002E54C6 /* libprotobuf.a */; }; FAA8388426BB3CBE002E54C6 /* libcppjansson.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FAA8388326BB3CBE002E54C6 /* libcppjansson.a */; }; FAA8388626BB3CC3002E54C6 /* libexpat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FAA8388526BB3CC3002E54C6 /* libexpat.a */; }; - FAA8388826BB3CDB002E54C6 /* liboauthcpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FAA8388726BB3CDB002E54C6 /* liboauthcpp.a */; }; FAA8388A26BB3CE4002E54C6 /* libdrape.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FAA8388926BB3CE4002E54C6 /* libdrape.a */; }; /* End PBXBuildFile section */ @@ -257,7 +256,6 @@ FAA8388126BB3C92002E54C6 /* libprotobuf.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libprotobuf.a; sourceTree = BUILT_PRODUCTS_DIR; }; FAA8388326BB3CBE002E54C6 /* libcppjansson.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libcppjansson.a; sourceTree = BUILT_PRODUCTS_DIR; }; FAA8388526BB3CC3002E54C6 /* libexpat.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libexpat.a; sourceTree = BUILT_PRODUCTS_DIR; }; - FAA8388726BB3CDB002E54C6 /* liboauthcpp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = liboauthcpp.a; sourceTree = BUILT_PRODUCTS_DIR; }; FAA8388926BB3CE4002E54C6 /* libdrape.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libdrape.a; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -275,7 +273,6 @@ buildActionMask = 2147483647; files = ( FAA8388A26BB3CE4002E54C6 /* libdrape.a in Frameworks */, - FAA8388826BB3CDB002E54C6 /* liboauthcpp.a in Frameworks */, FAA8388626BB3CC3002E54C6 /* libexpat.a in Frameworks */, FAA8388426BB3CBE002E54C6 /* libcppjansson.a in Frameworks */, FAA8387826BB3C92002E54C6 /* libbase.a in Frameworks */, @@ -302,7 +299,6 @@ isa = PBXGroup; children = ( FAA8388926BB3CE4002E54C6 /* libdrape.a */, - FAA8388726BB3CDB002E54C6 /* liboauthcpp.a */, FAA8388526BB3CC3002E54C6 /* libexpat.a */, FAA8388326BB3CBE002E54C6 /* libcppjansson.a */, FAA8387726BB3C92002E54C6 /* libbase.a */, diff --git a/xcode/oauthcpp/oauthcpp.xcodeproj/project.pbxproj b/xcode/oauthcpp/oauthcpp.xcodeproj/project.pbxproj deleted file mode 100644 index f45c806684..0000000000 --- a/xcode/oauthcpp/oauthcpp.xcodeproj/project.pbxproj +++ /dev/null @@ -1,233 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 54; - objects = { - -/* Begin PBXBuildFile section */ - 340C21011C3E5EED00111D22 /* base64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 340C20F81C3E5EED00111D22 /* base64.cpp */; }; - 340C21021C3E5EED00111D22 /* base64.h in Headers */ = {isa = PBXBuildFile; fileRef = 340C20F91C3E5EED00111D22 /* base64.h */; }; - 340C21031C3E5EED00111D22 /* HMAC_SHA1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 340C20FA1C3E5EED00111D22 /* HMAC_SHA1.cpp */; }; - 340C21041C3E5EED00111D22 /* HMAC_SHA1.h in Headers */ = {isa = PBXBuildFile; fileRef = 340C20FB1C3E5EED00111D22 /* HMAC_SHA1.h */; }; - 340C21051C3E5EED00111D22 /* liboauthcpp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 340C20FC1C3E5EED00111D22 /* liboauthcpp.cpp */; }; - 340C21061C3E5EED00111D22 /* SHA1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 340C20FD1C3E5EED00111D22 /* SHA1.cpp */; }; - 340C21071C3E5EED00111D22 /* SHA1.h in Headers */ = {isa = PBXBuildFile; fileRef = 340C20FE1C3E5EED00111D22 /* SHA1.h */; }; - 340C21081C3E5EED00111D22 /* urlencode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 340C20FF1C3E5EED00111D22 /* urlencode.cpp */; }; - 340C21091C3E5EED00111D22 /* urlencode.h in Headers */ = {isa = PBXBuildFile; fileRef = 340C21001C3E5EED00111D22 /* urlencode.h */; }; - 340C210B1C3E5EF600111D22 /* liboauthcpp.h in Headers */ = {isa = PBXBuildFile; fileRef = 340C210A1C3E5EF600111D22 /* liboauthcpp.h */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 340C20EF1C3E5E5000111D22 /* liboauthcpp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = liboauthcpp.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 340C20F81C3E5EED00111D22 /* base64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = base64.cpp; path = src/base64.cpp; sourceTree = ""; }; - 340C20F91C3E5EED00111D22 /* base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = base64.h; path = src/base64.h; sourceTree = ""; }; - 340C20FA1C3E5EED00111D22 /* HMAC_SHA1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HMAC_SHA1.cpp; path = src/HMAC_SHA1.cpp; sourceTree = ""; }; - 340C20FB1C3E5EED00111D22 /* HMAC_SHA1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HMAC_SHA1.h; path = src/HMAC_SHA1.h; sourceTree = ""; }; - 340C20FC1C3E5EED00111D22 /* liboauthcpp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = liboauthcpp.cpp; path = src/liboauthcpp.cpp; sourceTree = ""; }; - 340C20FD1C3E5EED00111D22 /* SHA1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SHA1.cpp; path = src/SHA1.cpp; sourceTree = ""; }; - 340C20FE1C3E5EED00111D22 /* SHA1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SHA1.h; path = src/SHA1.h; sourceTree = ""; }; - 340C20FF1C3E5EED00111D22 /* urlencode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = urlencode.cpp; path = src/urlencode.cpp; sourceTree = ""; }; - 340C21001C3E5EED00111D22 /* urlencode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = urlencode.h; path = src/urlencode.h; sourceTree = ""; }; - 340C210A1C3E5EF600111D22 /* liboauthcpp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = liboauthcpp.h; path = include/liboauthcpp/liboauthcpp.h; sourceTree = ""; }; - 34F558701DBF4AB300A4FC11 /* common-debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "common-debug.xcconfig"; path = "../common-debug.xcconfig"; sourceTree = ""; }; - 34F558711DBF4AB300A4FC11 /* common-release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "common-release.xcconfig"; path = "../common-release.xcconfig"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 340C20EC1C3E5E5000111D22 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 340C20E61C3E5E5000111D22 = { - isa = PBXGroup; - children = ( - 34F558701DBF4AB300A4FC11 /* common-debug.xcconfig */, - 34F558711DBF4AB300A4FC11 /* common-release.xcconfig */, - 340C20F71C3E5EA200111D22 /* liboauthcpp */, - 340C20F01C3E5E5000111D22 /* Products */, - ); - sourceTree = ""; - }; - 340C20F01C3E5E5000111D22 /* Products */ = { - isa = PBXGroup; - children = ( - 340C20EF1C3E5E5000111D22 /* liboauthcpp.a */, - ); - name = Products; - sourceTree = ""; - }; - 340C20F71C3E5EA200111D22 /* liboauthcpp */ = { - isa = PBXGroup; - children = ( - 340C20F81C3E5EED00111D22 /* base64.cpp */, - 340C20F91C3E5EED00111D22 /* base64.h */, - 340C20FA1C3E5EED00111D22 /* HMAC_SHA1.cpp */, - 340C20FB1C3E5EED00111D22 /* HMAC_SHA1.h */, - 340C20FC1C3E5EED00111D22 /* liboauthcpp.cpp */, - 340C210A1C3E5EF600111D22 /* liboauthcpp.h */, - 340C20FD1C3E5EED00111D22 /* SHA1.cpp */, - 340C20FE1C3E5EED00111D22 /* SHA1.h */, - 340C20FF1C3E5EED00111D22 /* urlencode.cpp */, - 340C21001C3E5EED00111D22 /* urlencode.h */, - ); - name = liboauthcpp; - path = ../../3party/liboauthcpp; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - 340C20ED1C3E5E5000111D22 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 340C21041C3E5EED00111D22 /* HMAC_SHA1.h in Headers */, - 340C21021C3E5EED00111D22 /* base64.h in Headers */, - 340C21091C3E5EED00111D22 /* urlencode.h in Headers */, - 340C210B1C3E5EF600111D22 /* liboauthcpp.h in Headers */, - 340C21071C3E5EED00111D22 /* SHA1.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 340C20EE1C3E5E5000111D22 /* oauthcpp */ = { - isa = PBXNativeTarget; - buildConfigurationList = 340C20F31C3E5E5000111D22 /* Build configuration list for PBXNativeTarget "oauthcpp" */; - buildPhases = ( - 340C20EB1C3E5E5000111D22 /* Sources */, - 340C20EC1C3E5E5000111D22 /* Frameworks */, - 340C20ED1C3E5E5000111D22 /* Headers */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = oauthcpp; - productName = oauthcpp; - productReference = 340C20EF1C3E5E5000111D22 /* liboauthcpp.a */; - productType = "com.apple.product-type.library.static"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 340C20E71C3E5E5000111D22 /* Project object */ = { - isa = PBXProject; - attributes = { - BuildIndependentTargetsInParallel = YES; - DefaultBuildSystemTypeForWorkspace = Latest; - LastUpgradeCheck = 1510; - TargetAttributes = { - 340C20EE1C3E5E5000111D22 = { - CreatedOnToolsVersion = 7.2; - }; - }; - }; - buildConfigurationList = 340C20EA1C3E5E5000111D22 /* Build configuration list for PBXProject "oauthcpp" */; - compatibilityVersion = "Xcode 12.0"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 340C20E61C3E5E5000111D22; - productRefGroup = 340C20F01C3E5E5000111D22 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 340C20EE1C3E5E5000111D22 /* oauthcpp */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - 340C20EB1C3E5E5000111D22 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 340C21081C3E5EED00111D22 /* urlencode.cpp in Sources */, - 340C21011C3E5EED00111D22 /* base64.cpp in Sources */, - 340C21031C3E5EED00111D22 /* HMAC_SHA1.cpp in Sources */, - 340C21061C3E5EED00111D22 /* SHA1.cpp in Sources */, - 340C21051C3E5EED00111D22 /* liboauthcpp.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 340C20F11C3E5E5000111D22 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 34F558701DBF4AB300A4FC11 /* common-debug.xcconfig */; - buildSettings = { - GCC_WARN_INHIBIT_ALL_WARNINGS = YES; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "$(OMIM_ROOT)/3party/liboauthcpp/include", - ); - }; - name = Debug; - }; - 340C20F21C3E5E5000111D22 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 34F558711DBF4AB300A4FC11 /* common-release.xcconfig */; - buildSettings = { - GCC_WARN_INHIBIT_ALL_WARNINGS = YES; - HEADER_SEARCH_PATHS = ( - "$(inherited)", - "$(OMIM_ROOT)/3party/liboauthcpp/include", - ); - }; - name = Release; - }; - 340C20F41C3E5E5000111D22 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - EXECUTABLE_PREFIX = lib; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 340C20F51C3E5E5000111D22 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - EXECUTABLE_PREFIX = lib; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 340C20EA1C3E5E5000111D22 /* Build configuration list for PBXProject "oauthcpp" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 340C20F11C3E5E5000111D22 /* Debug */, - 340C20F21C3E5E5000111D22 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 340C20F31C3E5E5000111D22 /* Build configuration list for PBXNativeTarget "oauthcpp" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 340C20F41C3E5E5000111D22 /* Debug */, - 340C20F51C3E5E5000111D22 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 340C20E71C3E5E5000111D22 /* Project object */; -} diff --git a/xcode/omim.xcworkspace/contents.xcworkspacedata b/xcode/omim.xcworkspace/contents.xcworkspacedata index 360962cb85..a323158abc 100644 --- a/xcode/omim.xcworkspace/contents.xcworkspacedata +++ b/xcode/omim.xcworkspace/contents.xcworkspacedata @@ -60,9 +60,6 @@ - - diff --git a/xcode/platform/platform.xcodeproj/project.pbxproj b/xcode/platform/platform.xcodeproj/project.pbxproj index 6ae985d2a9..1ee9d96c60 100644 --- a/xcode/platform/platform.xcodeproj/project.pbxproj +++ b/xcode/platform/platform.xcodeproj/project.pbxproj @@ -128,7 +128,6 @@ FAA8389326BB48EF002E54C6 /* libbase.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FAA8389226BB48EF002E54C6 /* libbase.a */; }; FAA8389526BB48F4002E54C6 /* libcoding.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FAA8389426BB48F4002E54C6 /* libcoding.a */; }; FAA8389726BB4906002E54C6 /* minizip.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAA8389626BB4906002E54C6 /* minizip.framework */; }; - FAA8389926BB490C002E54C6 /* liboauthcpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FAA8389826BB490C002E54C6 /* liboauthcpp.a */; }; FAA8389A26BB4931002E54C6 /* libplatform_tests_support.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 675340E91C58C496002CF0D9 /* libplatform_tests_support.a */; }; FAA8389C26BB4948002E54C6 /* libgeometry.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FAA8389B26BB4948002E54C6 /* libgeometry.a */; }; FADA4B2626F529BD000FF3CA /* languages.hpp in Headers */ = {isa = PBXBuildFile; fileRef = FADA4B2426F529B5000FF3CA /* languages.hpp */; }; @@ -259,7 +258,6 @@ FAA8389226BB48EF002E54C6 /* libbase.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libbase.a; sourceTree = BUILT_PRODUCTS_DIR; }; FAA8389426BB48F4002E54C6 /* libcoding.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libcoding.a; sourceTree = BUILT_PRODUCTS_DIR; }; FAA8389626BB4906002E54C6 /* minizip.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = minizip.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - FAA8389826BB490C002E54C6 /* liboauthcpp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = liboauthcpp.a; sourceTree = BUILT_PRODUCTS_DIR; }; FAA8389B26BB4948002E54C6 /* libgeometry.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libgeometry.a; sourceTree = BUILT_PRODUCTS_DIR; }; FADA4B2426F529B5000FF3CA /* languages.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = languages.hpp; sourceTree = ""; }; FADA4B2526F529B9000FF3CA /* locale.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = locale.hpp; sourceTree = ""; }; @@ -286,7 +284,6 @@ files = ( FAA8389C26BB4948002E54C6 /* libgeometry.a in Frameworks */, FAA8389A26BB4931002E54C6 /* libplatform_tests_support.a in Frameworks */, - FAA8389926BB490C002E54C6 /* liboauthcpp.a in Frameworks */, FAA8389726BB4906002E54C6 /* minizip.framework in Frameworks */, FAA8389526BB48F4002E54C6 /* libcoding.a in Frameworks */, FAA8389326BB48EF002E54C6 /* libbase.a in Frameworks */, @@ -302,7 +299,6 @@ isa = PBXGroup; children = ( FAA8389B26BB4948002E54C6 /* libgeometry.a */, - FAA8389826BB490C002E54C6 /* liboauthcpp.a */, FAA8389626BB4906002E54C6 /* minizip.framework */, FAA8389426BB48F4002E54C6 /* libcoding.a */, FAA8389226BB48EF002E54C6 /* libbase.a */, diff --git a/xcode/qt/qt.xcodeproj/project.pbxproj b/xcode/qt/qt.xcodeproj/project.pbxproj index 53be07f2b0..fef8f8c95a 100644 --- a/xcode/qt/qt.xcodeproj/project.pbxproj +++ b/xcode/qt/qt.xcodeproj/project.pbxproj @@ -9,7 +9,6 @@ /* Begin PBXBuildFile section */ 3462FD891DC1DE4600906FD7 /* libeditor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3462FD881DC1DE4600906FD7 /* libeditor.a */; }; 3462FD8D1DC1E03300906FD7 /* libpugixml.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3462FD8C1DC1E03300906FD7 /* libpugixml.a */; }; - 3462FD8F1DC1E05D00906FD7 /* liboauthcpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3462FD8E1DC1E05D00906FD7 /* liboauthcpp.a */; }; 3475E0E41DBF593D004C7E69 /* libtracking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3475E0E31DBF593D004C7E69 /* libtracking.a */; }; 348FE6871F7BBF7A00AAA4AF /* libmwm_diff.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 348FE6881F7BBF7A00AAA4AF /* libmwm_diff.a */; }; 348FE6891F7BBF9300AAA4AF /* libbsdiff.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 348FE68A1F7BBF9300AAA4AF /* libbsdiff.a */; }; @@ -229,7 +228,6 @@ /* Begin PBXFileReference section */ 3462FD881DC1DE4600906FD7 /* libeditor.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libeditor.a; path = "../../../omim-build/xcode/Release/libeditor.a"; sourceTree = ""; }; 3462FD8C1DC1E03300906FD7 /* libpugixml.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpugixml.a; path = "../../../omim-build/xcode/Release/libpugixml.a"; sourceTree = ""; }; - 3462FD8E1DC1E05D00906FD7 /* liboauthcpp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liboauthcpp.a; path = "../../../omim-build/xcode/Release/liboauthcpp.a"; sourceTree = ""; }; 3475E0E31DBF593D004C7E69 /* libtracking.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libtracking.a; path = "../../../omim-xcode-build/Debug/libtracking.a"; sourceTree = ""; }; 348FE6881F7BBF7A00AAA4AF /* libmwm_diff.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libmwm_diff.a; sourceTree = BUILT_PRODUCTS_DIR; }; 348FE68A1F7BBF9300AAA4AF /* libbsdiff.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libbsdiff.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -392,7 +390,6 @@ 671E79221E6A508600B2859B /* libopenlr.a in Frameworks */, 671E78E51E6A4E1A00B2859B /* librouting_common.a in Frameworks */, 672292B11DE307DC005BA3A7 /* libtraffic.a in Frameworks */, - 3462FD8F1DC1E05D00906FD7 /* liboauthcpp.a in Frameworks */, 3462FD8D1DC1E03300906FD7 /* libpugixml.a in Frameworks */, 3462FD891DC1DE4600906FD7 /* libeditor.a in Frameworks */, 3475E0E41DBF593D004C7E69 /* libtracking.a in Frameworks */, @@ -474,7 +471,6 @@ 675345A51A40534F00A0A8C3 /* CoreFoundation.framework */, 675345A31A40534500A0A8C3 /* IOKit.framework */, 672292B01DE307DC005BA3A7 /* libtraffic.a */, - 3462FD8E1DC1E05D00906FD7 /* liboauthcpp.a */, 3462FD8C1DC1E03300906FD7 /* libpugixml.a */, 3462FD881DC1DE4600906FD7 /* libeditor.a */, 3475E0E31DBF593D004C7E69 /* libtracking.a */, diff --git a/xcode/search/search.xcodeproj/project.pbxproj b/xcode/search/search.xcodeproj/project.pbxproj index ee90a7f8b7..cbf84d9776 100644 --- a/xcode/search/search.xcodeproj/project.pbxproj +++ b/xcode/search/search.xcodeproj/project.pbxproj @@ -58,7 +58,6 @@ 34F5583D1DBF2E2700A4FC11 /* libeditor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F5583C1DBF2E2700A4FC11 /* libeditor.a */; }; 34F5583F1DBF2E3400A4FC11 /* libpugixml.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F5583E1DBF2E3400A4FC11 /* libpugixml.a */; }; 34F558411DBF2E4F00A4FC11 /* libcppjansson.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F558401DBF2E4F00A4FC11 /* libcppjansson.a */; }; - 34F558431DBF2E6500A4FC11 /* liboauthcpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F558421DBF2E6500A4FC11 /* liboauthcpp.a */; }; 34F558451DBF2E7600A4FC11 /* libopening_hours.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F558441DBF2E7600A4FC11 /* libopening_hours.a */; }; 34F558471DBF2E8100A4FC11 /* libsuccinct.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F558461DBF2E8100A4FC11 /* libsuccinct.a */; }; 34F558491DBF2EC700A4FC11 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F558481DBF2EC700A4FC11 /* libz.tbd */; }; @@ -104,7 +103,6 @@ 39AEF86D1FB45E1600943FC9 /* libicu.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 39AEF8481FB45C8900943FC9 /* libicu.a */; }; 39AEF86E1FB45E1600943FC9 /* libsuccinct.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F558461DBF2E8100A4FC11 /* libsuccinct.a */; }; 39AEF86F1FB45E1600943FC9 /* libopening_hours.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F558441DBF2E7600A4FC11 /* libopening_hours.a */; }; - 39AEF8701FB45E1600943FC9 /* liboauthcpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F558421DBF2E6500A4FC11 /* liboauthcpp.a */; }; 39AEF8711FB45E1600943FC9 /* libcppjansson.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F558401DBF2E4F00A4FC11 /* libcppjansson.a */; }; 39AEF8721FB45E1600943FC9 /* libpugixml.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F5583E1DBF2E3400A4FC11 /* libpugixml.a */; }; 39AEF8731FB45E1600943FC9 /* libeditor.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F5583C1DBF2E2700A4FC11 /* libeditor.a */; }; @@ -348,7 +346,6 @@ 34F5583C1DBF2E2700A4FC11 /* libeditor.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libeditor.a; path = "../../../omim-xcode-build/Debug/libeditor.a"; sourceTree = ""; }; 34F5583E1DBF2E3400A4FC11 /* libpugixml.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpugixml.a; path = "../../../omim-xcode-build/Debug/libpugixml.a"; sourceTree = ""; }; 34F558401DBF2E4F00A4FC11 /* libcppjansson.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcppjansson.a; path = "../../../omim-xcode-build/Debug/libcppjansson.a"; sourceTree = ""; }; - 34F558421DBF2E6500A4FC11 /* liboauthcpp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liboauthcpp.a; path = "../../../omim-xcode-build/Debug/liboauthcpp.a"; sourceTree = ""; }; 34F558441DBF2E7600A4FC11 /* libopening_hours.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libopening_hours.a; path = "../../../omim-xcode-build/Debug/libopening_hours.a"; sourceTree = ""; }; 34F558461DBF2E8100A4FC11 /* libsuccinct.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libsuccinct.a; path = "../../../omim-xcode-build/Debug/libsuccinct.a"; sourceTree = ""; }; 34F558481DBF2EC700A4FC11 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; @@ -547,7 +544,6 @@ 39AEF86E1FB45E1600943FC9 /* libsuccinct.a in Frameworks */, 39AEF8711FB45E1600943FC9 /* libcppjansson.a in Frameworks */, 39B2B96C1FB4633200AB85A1 /* libtess2.a in Frameworks */, - 39AEF8701FB45E1600943FC9 /* liboauthcpp.a in Frameworks */, 39B2B96A1FB4631400AB85A1 /* libbsdiff.a in Frameworks */, 39B2B9681FB4630000AB85A1 /* libmwm_diff.a in Frameworks */, 39AEF8731FB45E1600943FC9 /* libeditor.a in Frameworks */, @@ -575,7 +571,6 @@ 39AEF8471FB45C8900943FC9 /* libicu.a in Frameworks */, 34F558471DBF2E8100A4FC11 /* libsuccinct.a in Frameworks */, 34F558451DBF2E7600A4FC11 /* libopening_hours.a in Frameworks */, - 34F558431DBF2E6500A4FC11 /* liboauthcpp.a in Frameworks */, 34F558411DBF2E4F00A4FC11 /* libcppjansson.a in Frameworks */, 34F5583F1DBF2E3400A4FC11 /* libpugixml.a in Frameworks */, 34F5583D1DBF2E2700A4FC11 /* libeditor.a in Frameworks */, @@ -651,7 +646,6 @@ 34F558481DBF2EC700A4FC11 /* libz.tbd */, 34F558461DBF2E8100A4FC11 /* libsuccinct.a */, 34F558441DBF2E7600A4FC11 /* libopening_hours.a */, - 34F558421DBF2E6500A4FC11 /* liboauthcpp.a */, 34F558401DBF2E4F00A4FC11 /* libcppjansson.a */, 34F5583E1DBF2E3400A4FC11 /* libpugixml.a */, 34F5583C1DBF2E2700A4FC11 /* libeditor.a */, diff --git a/xcode/traffic/traffic.xcodeproj/project.pbxproj b/xcode/traffic/traffic.xcodeproj/project.pbxproj index 1060bad0d6..537ade9768 100644 --- a/xcode/traffic/traffic.xcodeproj/project.pbxproj +++ b/xcode/traffic/traffic.xcodeproj/project.pbxproj @@ -20,7 +20,6 @@ FAFD414226BBE3FC00D1DE1B /* libcoding.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FAFD414126BBE3FC00D1DE1B /* libcoding.a */; }; FAFD414426BBE88000D1DE1B /* libplatform.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FAFD414326BBE88000D1DE1B /* libplatform.a */; }; FAFD414626BBE88700D1DE1B /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = FAFD414526BBE88700D1DE1B /* libz.tbd */; }; - FAFD414826BBE8F200D1DE1B /* liboauthcpp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FAFD414726BBE8F200D1DE1B /* liboauthcpp.a */; }; FAFD414A26BBE98B00D1DE1B /* libindexer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FAFD414926BBE98B00D1DE1B /* libindexer.a */; }; FAFD414C26BBE9BB00D1DE1B /* libicu.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FAFD414B26BBE9BB00D1DE1B /* libicu.a */; }; FAFD414E26BBE9C300D1DE1B /* libgeometry.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FAFD414D26BBE9C300D1DE1B /* libgeometry.a */; }; @@ -48,7 +47,6 @@ FAFD414126BBE3FC00D1DE1B /* libcoding.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libcoding.a; sourceTree = BUILT_PRODUCTS_DIR; }; FAFD414326BBE88000D1DE1B /* libplatform.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libplatform.a; sourceTree = BUILT_PRODUCTS_DIR; }; FAFD414526BBE88700D1DE1B /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; - FAFD414726BBE8F200D1DE1B /* liboauthcpp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = liboauthcpp.a; sourceTree = BUILT_PRODUCTS_DIR; }; FAFD414926BBE98B00D1DE1B /* libindexer.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libindexer.a; sourceTree = BUILT_PRODUCTS_DIR; }; FAFD414B26BBE9BB00D1DE1B /* libicu.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libicu.a; sourceTree = BUILT_PRODUCTS_DIR; }; FAFD414D26BBE9C300D1DE1B /* libgeometry.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libgeometry.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -77,7 +75,6 @@ FAFD414E26BBE9C300D1DE1B /* libgeometry.a in Frameworks */, FAFD414C26BBE9BB00D1DE1B /* libicu.a in Frameworks */, FAFD414A26BBE98B00D1DE1B /* libindexer.a in Frameworks */, - FAFD414826BBE8F200D1DE1B /* liboauthcpp.a in Frameworks */, FAFD414626BBE88700D1DE1B /* libz.tbd in Frameworks */, FAFD414426BBE88000D1DE1B /* libplatform.a in Frameworks */, FAFD414026BBE3FC00D1DE1B /* libbase.a in Frameworks */, @@ -145,7 +142,6 @@ FAFD414D26BBE9C300D1DE1B /* libgeometry.a */, FAFD414B26BBE9BB00D1DE1B /* libicu.a */, FAFD414926BBE98B00D1DE1B /* libindexer.a */, - FAFD414726BBE8F200D1DE1B /* liboauthcpp.a */, FAFD414526BBE88700D1DE1B /* libz.tbd */, FAFD414326BBE88000D1DE1B /* libplatform.a */, FAFD413F26BBE3FC00D1DE1B /* libbase.a */, -- 2.45.3 From 4ecf03a008ec4f025e41b8302fd48ac918cf4b83 Mon Sep 17 00:00:00 2001 From: Jerry <4341884+jm355@users.noreply.github.com> Date: Mon, 20 May 2024 19:34:04 +0000 Subject: [PATCH 10/36] Always show next turn option (#7196) * Add option to always show the next turn during navigation Signed-off-by: Jeremiah Miller * Fix build errors Signed-off-by: Jeremiah Miller * Revert adding a setting to always show the next turn, set up the routing session to know when the device is in landscape position, and if it is, don't show the next turn (unless the old logic applies), but show it by default. Signed-off-by: Jeremiah Miller * Move landscape check to map framework Signed-off-by: Jeremiah Miller * Address review comments Signed-off-by: Jeremiah Miller * Always show next turn string, make the top bar take up less space in landscape mode Signed-off-by: Jeremiah Miller * Remove unecessary landscape check Signed-off-by: Jeremiah Miller * Update routing_manager.hpp Signed-off-by: Jerry <4341884+jm355@users.noreply.github.com> --------- Signed-off-by: Jeremiah Miller Signed-off-by: Jerry <4341884+jm355@users.noreply.github.com> Co-authored-by: Jeremiah --- .../main/res/layout-land/layout_nav_top.xml | 125 ++++++++++++++++++ routing/routing_session.cpp | 13 +- 2 files changed, 128 insertions(+), 10 deletions(-) create mode 100644 android/app/src/main/res/layout-land/layout_nav_top.xml diff --git a/android/app/src/main/res/layout-land/layout_nav_top.xml b/android/app/src/main/res/layout-land/layout_nav_top.xml new file mode 100644 index 0000000000..681ec9c838 --- /dev/null +++ b/android/app/src/main/res/layout-land/layout_nav_top.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/routing/routing_session.cpp b/routing/routing_session.cpp index ffe83356a4..e38dca26d1 100644 --- a/routing/routing_session.cpp +++ b/routing/routing_session.cpp @@ -425,26 +425,19 @@ void RoutingSession::GetRouteFollowingInfo(FollowingInfo & info) const info.m_completionPercent = GetCompletionPercent(); - double const timeToNearestTurnSec = m_route->GetCurrentTimeToNearestTurnSec(); - // Lane information and next street name. - if (distanceToTurnMeters < kShowLanesMinDistInMeters || timeToNearestTurnSec < 60.0) + info.m_displayedStreetName = info.m_targetName; + info.m_lanes.clear(); + if (distanceToTurnMeters < kShowLanesMinDistInMeters || m_route->GetCurrentTimeToNearestTurnSec() < 60.0) { - info.m_displayedStreetName = info.m_targetName; // There are two nested loops below. Outer one is for lanes and inner one (ctor of // SingleLaneInfo) is // for each lane's directions. The size of turn.m_lanes is relatively small. Less than 10 in // most cases. - info.m_lanes.clear(); info.m_lanes.reserve(turn.m_lanes.size()); for (size_t j = 0; j < turn.m_lanes.size(); ++j) info.m_lanes.emplace_back(turn.m_lanes[j]); } - else - { - info.m_displayedStreetName = ""; - info.m_lanes.clear(); - } // Pedestrian info. info.m_pedestrianTurn = (distanceToTurnMeters < kShowPedestrianTurnInMeters) -- 2.45.3 From 141a7b311f06c3e80c1470054b9b87d4e459a285 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Sun, 19 May 2024 19:55:09 +0100 Subject: [PATCH 11/36] Improve page dialog user Signed-off-by: Diogo Rodrigues --- qt/place_page_dialog_user.cpp | 56 +++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 9 deletions(-) diff --git a/qt/place_page_dialog_user.cpp b/qt/place_page_dialog_user.cpp index 89e3766790..fc91da28c4 100644 --- a/qt/place_page_dialog_user.cpp +++ b/qt/place_page_dialog_user.cpp @@ -22,6 +22,21 @@ namespace static int constexpr kMaxLengthOfPlacePageDescription = 500; static int constexpr kMinWidthOfShortDescription = 390; +std::string getShortDescription(std::string description) +{ + size_t paragraphStart = description.find("

    "); + size_t paragraphEnd = description.find("

    "); + if (paragraphStart == 0 && paragraphEnd != std::string::npos) + description = description.substr(3, paragraphEnd-3); + + if (description.length() > kMaxLengthOfPlacePageDescription) + { + description = description.substr(0, kMaxLengthOfPlacePageDescription-3) + "..."; + } + + return description; +} + std::string_view stripSchemeFromURI(std::string_view uri) { for (std::string_view prefix : {"https://", "http://"}) { @@ -52,14 +67,23 @@ PlacePageDialogUser::PlacePageDialogUser(QWidget * parent, place_page::Info cons { QVBoxLayout * header = new QVBoxLayout(); - if (!title.empty()) - header->addWidget(new QLabel(QString::fromStdString("

    " + title + "

    "))); + if (!title.empty()){ + QLabel * titleLabel = new QLabel(QString::fromStdString("

    " + title + "

    ")); + titleLabel->setWordWrap(true); + header->addWidget(titleLabel); + } - if (auto subTitle = info.GetSubtitle(); !subTitle.empty()) - header->addWidget(new QLabel(QString::fromStdString(subTitle))); + if (auto subTitle = info.GetSubtitle(); !subTitle.empty()){ + QLabel * subtitleLabel = new QLabel(QString::fromStdString(subTitle)); + subtitleLabel->setWordWrap(true); + header->addWidget(subtitleLabel); + } - if (auto addressFormatted = address.FormatAddress(); !addressFormatted.empty()) - header->addWidget(new QLabel(QString::fromStdString(addressFormatted))); + if (auto addressFormatted = address.FormatAddress(); !addressFormatted.empty()){ + QLabel * addressLabel = new QLabel(QString::fromStdString(addressFormatted)); + addressLabel->setWordWrap(true); + header->addWidget(addressLabel); + } layout->addLayout(header); } @@ -79,6 +103,7 @@ PlacePageDialogUser::PlacePageDialogUser(QWidget * parent, place_page::Info cons data->addWidget(new QLabel(QString::fromStdString(key)), row, 0); QLabel * label = new QLabel(QString::fromStdString(value)); label->setTextInteractionFlags(Qt::TextSelectableByMouse); + label->setWordWrap(true); if (isLink) { label->setOpenExternalLinks(true); @@ -106,7 +131,14 @@ PlacePageDialogUser::PlacePageDialogUser(QWidget * parent, place_page::Info cons // Description if (auto description = info.GetWikiDescription(); !description.empty()) { - QPushButton * wikiButton = new QPushButton("Wikipedia Description"); + auto descriptionShort = getShortDescription(description); + + QLabel * value = new QLabel(QString::fromStdString(descriptionShort)); + value->setWordWrap(true); + + data->addWidget(value, row++, 0, 1, 2); + + QPushButton * wikiButton = new QPushButton("More...", value); wikiButton->setAutoDefault(false); connect(wikiButton, &QAbstractButton::clicked, this, [this, description, title]() { @@ -179,7 +211,6 @@ PlacePageDialogUser::PlacePageDialogUser(QWidget * parent, place_page::Info cons addSocialNetworkWidget("Facebook", feature::Metadata::EType::FMD_CONTACT_FACEBOOK); addSocialNetworkWidget("Instagram", feature::Metadata::EType::FMD_CONTACT_INSTAGRAM); - addSocialNetworkWidget("Instagram", feature::Metadata::EType::FMD_CONTACT_INSTAGRAM); addSocialNetworkWidget("Twitter", feature::Metadata::EType::FMD_CONTACT_TWITTER); addSocialNetworkWidget("VK", feature::Metadata::EType::FMD_CONTACT_VK); addSocialNetworkWidget("Line", feature::Metadata::EType::FMD_CONTACT_LINE); @@ -187,11 +218,13 @@ PlacePageDialogUser::PlacePageDialogUser(QWidget * parent, place_page::Info cons if (auto wikimedia_commons = info.GetMetadata(feature::Metadata::EType::FMD_WIKIMEDIA_COMMONS); !wikimedia_commons.empty()) { + data->addWidget(new QLabel("Wikimedia Commons"), row, 0); + QLabel * value = new QLabel(QString::fromStdString("Wikimedia Commons")); value->setOpenExternalLinks(true); value->setTextInteractionFlags(Qt::TextBrowserInteraction); - data->addWidget(value, row++, 0); + data->addWidget(value, row++, 1); } // Level fragment @@ -209,9 +242,14 @@ PlacePageDialogUser::PlacePageDialogUser(QWidget * parent, place_page::Info cons addEntry("Coordinates", strings::to_string_dac(ll.m_lat, 7) + ", " + strings::to_string_dac(ll.m_lon, 7)); } + data->setColumnStretch(0, 0); + data->setColumnStretch(1, 1); + layout->addLayout(data); } + layout->addStretch(); + { QHLine * line = new QHLine(); layout->addWidget(line); -- 2.45.3 From 45f6239b508ed69a76421b7d890c9dbfce02c794 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20W=C3=BCthrich?= Date: Sun, 19 May 2024 18:08:32 -0600 Subject: [PATCH 12/36] [ios] Interrupt podcasts instead of duck them during TTS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers to interrupt spoken content during TTS. Signed-off-by: Fabian Wüthrich --- iphone/Maps/Core/TextToSpeech/MWMTextToSpeech.mm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/iphone/Maps/Core/TextToSpeech/MWMTextToSpeech.mm b/iphone/Maps/Core/TextToSpeech/MWMTextToSpeech.mm index 44ff8f9244..25beda5598 100644 --- a/iphone/Maps/Core/TextToSpeech/MWMTextToSpeech.mm +++ b/iphone/Maps/Core/TextToSpeech/MWMTextToSpeech.mm @@ -247,7 +247,9 @@ using Observers = NSHashTable; } if (![[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback mode:mode - options:AVAudioSessionCategoryOptionMixWithOthers | AVAudioSessionCategoryOptionDuckOthers + options: + AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers | + AVAudioSessionCategoryOptionDuckOthers error:nil] || ![[AVAudioSession sharedInstance] setActive:YES error:nil]) return; -- 2.45.3 From 4ce2c6ae78bc9d8c09b13e7fea1316dbdc74be1e Mon Sep 17 00:00:00 2001 From: Kiryl <79797627+kirylkaveryn@users.noreply.github.com> Date: Wed, 22 May 2024 06:28:22 +0400 Subject: [PATCH 13/36] [bookmarks] Reuse the MarkGroupId during the category reloading (#8234) [bookmarks] reuse category id for files with the same name Signed-off-by: Kiryl Kaveryn --- map/bookmark_manager.cpp | 50 +++++++++++++++++++++++++++----- map/bookmark_manager.hpp | 5 +++- map/map_tests/bookmarks_test.cpp | 15 ++++++---- 3 files changed, 56 insertions(+), 14 deletions(-) diff --git a/map/bookmark_manager.cpp b/map/bookmark_manager.cpp index dc2d370439..4c3ed85924 100644 --- a/map/bookmark_manager.cpp +++ b/map/bookmark_manager.cpp @@ -472,10 +472,10 @@ void BookmarkManager::OnEditSessionClosed() { ASSERT_GREATER(m_openedEditSessionsCount, 0, ()); if (--m_openedEditSessionsCount == 0) - NotifyChanges(); + NotifyChanges(true /* saveChangesOnDisk */); } -void BookmarkManager::NotifyChanges() +void BookmarkManager::NotifyChanges(bool saveChangesOnDisk) { CHECK_THREAD_CHECKER(m_threadChecker, ()); @@ -510,7 +510,11 @@ void BookmarkManager::NotifyChanges() categoriesToSave.push_back(groupId); } - SaveBookmarks(categoriesToSave); + // During the category reloading/updating the file saving should be skipped + // because of the file is already up to date. + if (saveChangesOnDisk) + SaveBookmarks(categoriesToSave); + SendBookmarksChanges(m_bookmarksChangesTracker); } m_bookmarksChangesTracker.ResetChanges(); @@ -1549,6 +1553,17 @@ std::string BookmarkManager::GetCategoryFileName(kml::MarkGroupId categoryId) co return GetBmCategory(categoryId)->GetFileName(); } +kml::MarkGroupId BookmarkManager::GetCategoryByFileName(std::string const & fileName) const +{ + CHECK_THREAD_CHECKER(m_threadChecker, ()); + for (auto const & c : m_categories) + { + if (c.second->GetFileName() == fileName) + return c.second->GetID(); + } + return kml::kInvalidMarkGroupId; +} + m2::RectD BookmarkManager::GetCategoryRect(kml::MarkGroupId categoryId, bool addIconsSize) const { CHECK_THREAD_CHECKER(m_threadChecker, ()); @@ -2326,6 +2341,17 @@ kml::MarkGroupId BookmarkManager::CreateBookmarkCategory(std::string const & nam return groupId; } +void BookmarkManager::UpdateBookmarkCategory(kml::MarkGroupId & groupId, kml::CategoryData && data, bool autoSave /* = true */) +{ + CHECK_THREAD_CHECKER(m_threadChecker, ()); + CHECK_NOT_EQUAL(m_categories.count(groupId), 0, ()); + // The current implementation reloads the provided group. + /// @todo implement more accurate merging instead of full reloading + ClearGroup(groupId); + m_categories.emplace(groupId, std::make_unique(std::move(data), autoSave)); + m_changesTracker.OnAddGroup(groupId); +} + BookmarkCategory * BookmarkManager::CreateBookmarkCompilation(kml::CategoryData && data) { CHECK_THREAD_CHECKER(m_threadChecker, ()); @@ -2478,6 +2504,7 @@ void BookmarkManager::CreateCategories(KMLDataCollection && dataCollection, bool CHECK_THREAD_CHECKER(m_threadChecker, ()); kml::GroupIdSet loadedGroups; + bool isUpdating = false; for (auto const & [fileName, fileDataPtr] : dataCollection) { auto & fileData = *fileDataPtr; @@ -2517,9 +2544,16 @@ void BookmarkManager::CreateCategories(KMLDataCollection && dataCollection, bool UserMarkIdStorage::Instance().EnableSaving(false); + auto groupId = GetCategoryByFileName(fileName); // Set autoSave = false now to avoid useless saving in NotifyChanges(). // autoSave flag will be assigned in the end of this function. - auto const groupId = CreateBookmarkCategory(std::move(categoryData), false /* autoSave */); + if (groupId != kml::kInvalidMarkGroupId) + { + isUpdating = true; + UpdateBookmarkCategory(groupId, std::move(categoryData), false /* autoSave */); + } + else + groupId = CreateBookmarkCategory(std::move(categoryData), false /* autoSave */); loadedGroups.insert(groupId); auto * group = GetBmCategory(groupId); group->SetFileName(fileName); @@ -2578,7 +2612,9 @@ void BookmarkManager::CreateCategories(KMLDataCollection && dataCollection, bool } m_restoringCache.clear(); - NotifyChanges(); + // During the updating process the file shouldn't be re-saved on disk because it should be already up to date. + // In other case race condition may occur when multiple devices are used. + NotifyChanges(!isUpdating /* saveChangesOnDisk */); for (auto const & groupId : loadedGroups) GetBmCategory(groupId)->EnableAutoSave(autoSave); @@ -2908,7 +2944,7 @@ void BookmarkManager::SetNotificationsEnabled(bool enabled) m_notificationsEnabled = enabled; if (m_notificationsEnabled && m_openedEditSessionsCount == 0) - NotifyChanges(); + NotifyChanges(true /* saveChangesOnDisk */); } bool BookmarkManager::AreNotificationsEnabled() const @@ -3444,5 +3480,5 @@ bool BookmarkManager::EditSession::DeleteBmCategory(kml::MarkGroupId groupId) void BookmarkManager::EditSession::NotifyChanges() { - m_bmManager.NotifyChanges(); + m_bmManager.NotifyChanges(true /* saveChangesOnDisk */); } diff --git a/map/bookmark_manager.hpp b/map/bookmark_manager.hpp index 491cea6326..786dcc39c4 100644 --- a/map/bookmark_manager.hpp +++ b/map/bookmark_manager.hpp @@ -267,6 +267,7 @@ public: kml::MarkGroupId CreateBookmarkCategory(kml::CategoryData && data, bool autoSave = true); kml::MarkGroupId CreateBookmarkCategory(std::string const & name, bool autoSave = true); + void UpdateBookmarkCategory(kml::MarkGroupId & groupId, kml::CategoryData && data, bool autoSave); BookmarkCategory * CreateBookmarkCompilation(kml::CategoryData && data); @@ -593,7 +594,7 @@ private: void OnEditSessionOpened(); void OnEditSessionClosed(); - void NotifyChanges(); + void NotifyChanges(bool saveChangesOnDisk); void SaveState() const; void LoadState(); @@ -626,6 +627,8 @@ private: kml::MarkGroupId CheckAndCreateDefaultCategory(); void CheckAndResetLastIds(); + kml::MarkGroupId GetCategoryByFileName(std::string const & fileName) const; + std::unique_ptr CollectBmGroupKMLData(BookmarkCategory const * group) const; KMLDataCollectionPtr PrepareToSaveBookmarks(kml::GroupIdCollection const & groupIdCollection); diff --git a/map/map_tests/bookmarks_test.cpp b/map/map_tests/bookmarks_test.cpp index 2aa05f48a2..0ba604fda7 100644 --- a/map/map_tests/bookmarks_test.cpp +++ b/map/map_tests/bookmarks_test.cpp @@ -1070,8 +1070,9 @@ UNIT_CLASS_TEST(Runner, Bookmarks_SpecialXMLNames) BookmarkManager bmManager(BM_CALLBACKS); bmManager.EnableTestMode(true); + auto const file1Name = "file1"; BookmarkManager::KMLDataCollection kmlDataCollection1; - kmlDataCollection1.emplace_back("" /* filePath */, + kmlDataCollection1.emplace_back(file1Name /* filePath */, LoadKmlData(MemReader(kmlString3, strlen(kmlString3)), KmlFileType::Text)); bmManager.CreateCategories(std::move(kmlDataCollection1)); @@ -1096,23 +1097,25 @@ UNIT_CLASS_TEST(Runner, Bookmarks_SpecialXMLNames) bmManager.GetEditSession().DeleteBmCategory(catId); + auto const file2Name = "file2"; BookmarkManager::KMLDataCollection kmlDataCollection2; - kmlDataCollection2.emplace_back("" /* filePath */, LoadKmlFile(fileNameTmp, GetActiveKmlFileType())); + kmlDataCollection2.emplace_back(file1Name /* filePath */, LoadKmlFile(fileNameTmp, GetActiveKmlFileType())); bmManager.CreateCategories(std::move(kmlDataCollection2)); BookmarkManager::KMLDataCollection kmlDataCollection3; - kmlDataCollection3.emplace_back("" /* filePath */, + kmlDataCollection3.emplace_back(file2Name /* filePath */, LoadKmlData(MemReader(kmlString3, strlen(kmlString3)), KmlFileType::Text)); bmManager.CreateCategories(std::move(kmlDataCollection3)); TEST_EQUAL(bmManager.GetBmGroupsCount(), 2, ()); - auto const catId2 = bmManager.GetSortedBmGroupIdList().back(); - auto const catId3 = bmManager.GetSortedBmGroupIdList().front(); + auto const catId2 = bmManager.GetSortedBmGroupIdList().front(); + auto const catId3 = bmManager.GetSortedBmGroupIdList().back(); TEST_EQUAL(bmManager.GetUserMarkIds(catId2).size(), 1, ()); TEST_EQUAL(bmManager.GetCategoryName(catId2), expectedName, ()); - TEST(bmManager.GetCategoryFileName(catId2).empty(), ()); + TEST_EQUAL(bmManager.GetCategoryFileName(catId2), file1Name, ()); + TEST_EQUAL(bmManager.GetCategoryFileName(catId3), file2Name, ()); auto const bmId1 = *bmManager.GetUserMarkIds(catId2).begin(); auto const * bm1 = bmManager.GetBookmark(bmId1); -- 2.45.3 From 115782d817b6fc6f93a1878e54fbf20ed5f9a5b8 Mon Sep 17 00:00:00 2001 From: Arthur-GYT Date: Sat, 18 May 2024 20:20:14 +0200 Subject: [PATCH 14/36] [editor] Limit website menu field for some types of amenity Signed-off-by: Arthur-GYT --- .../organicmaps/editor/EditorFragment.java | 27 ++++++++++++------- data/editor.config | 9 +++++++ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/android/app/src/main/java/app/organicmaps/editor/EditorFragment.java b/android/app/src/main/java/app/organicmaps/editor/EditorFragment.java index 24026ff007..bea41f41fb 100644 --- a/android/app/src/main/java/app/organicmaps/editor/EditorFragment.java +++ b/android/app/src/main/java/app/organicmaps/editor/EditorFragment.java @@ -426,23 +426,23 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe mEditPhoneLink = blockPhone.findViewById(R.id.edit_phone); mEditPhoneLink.setOnClickListener(this); mPhone.setOnClickListener(this); - initBlock(view, Metadata.MetadataType.FMD_WEBSITE, R.id.block_website, + View websiteBlock = initBlock(view, Metadata.MetadataType.FMD_WEBSITE, R.id.block_website, R.drawable.ic_website, R.string.website, InputType.TYPE_TEXT_VARIATION_URI); - initBlock(view, Metadata.MetadataType.FMD_WEBSITE_MENU, R.id.block_website_menu, + View websiteMenuBlock = initBlock(view, Metadata.MetadataType.FMD_WEBSITE_MENU, R.id.block_website_menu, R.drawable.ic_website_menu, R.string.website_menu, InputType.TYPE_TEXT_VARIATION_URI); - initBlock(view, Metadata.MetadataType.FMD_EMAIL, R.id.block_email, + View emailBlock = initBlock(view, Metadata.MetadataType.FMD_EMAIL, R.id.block_email, R.drawable.ic_email, R.string.email, InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS); - initBlock(view, Metadata.MetadataType.FMD_CONTACT_FACEBOOK, R.id.block_facebook, + View facebookContactBlock = initBlock(view, Metadata.MetadataType.FMD_CONTACT_FACEBOOK, R.id.block_facebook, R.drawable.ic_facebook_white, R.string.facebook, InputType.TYPE_TEXT_VARIATION_URI); - initBlock(view, Metadata.MetadataType.FMD_CONTACT_INSTAGRAM, R.id.block_instagram, + View instagramContactBlock = initBlock(view, Metadata.MetadataType.FMD_CONTACT_INSTAGRAM, R.id.block_instagram, R.drawable.ic_instagram_white, R.string.instagram, InputType.TYPE_TEXT_VARIATION_URI); - initBlock(view, Metadata.MetadataType.FMD_CONTACT_TWITTER, R.id.block_twitter, + View twitterContactBlock = initBlock(view, Metadata.MetadataType.FMD_CONTACT_TWITTER, R.id.block_twitter, R.drawable.ic_twitterx_white, R.string.twitter, InputType.TYPE_TEXT_VARIATION_URI); - initBlock(view, Metadata.MetadataType.FMD_CONTACT_VK, R.id.block_vk, + View vkContactBlock = initBlock(view, Metadata.MetadataType.FMD_CONTACT_VK, R.id.block_vk, R.drawable.ic_vk_white, R.string.vk, InputType.TYPE_TEXT_VARIATION_URI); - initBlock(view, Metadata.MetadataType.FMD_CONTACT_LINE, R.id.block_line, + View lineContactBlock = initBlock(view, Metadata.MetadataType.FMD_CONTACT_LINE, R.id.block_line, R.drawable.ic_line_white, R.string.editor_line_social_network, InputType.TYPE_TEXT_VARIATION_URI); - initBlock(view, Metadata.MetadataType.FMD_OPERATOR, R.id.block_operator, + View operatorBlock = initBlock(view, Metadata.MetadataType.FMD_OPERATOR, R.id.block_operator, R.drawable.ic_operator, R.string.editor_operator, 0); View blockCuisine = view.findViewById(R.id.block_cuisine); @@ -469,6 +469,15 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe mDetailsBlocks.put(Metadata.MetadataType.FMD_PHONE_NUMBER, blockPhone); mDetailsBlocks.put(Metadata.MetadataType.FMD_CUISINE, blockCuisine); mDetailsBlocks.put(Metadata.MetadataType.FMD_INTERNET, blockWifi); + mDetailsBlocks.put(Metadata.MetadataType.FMD_WEBSITE, websiteBlock); + mDetailsBlocks.put(Metadata.MetadataType.FMD_WEBSITE_MENU, websiteMenuBlock); + mDetailsBlocks.put(Metadata.MetadataType.FMD_EMAIL, emailBlock); + mDetailsBlocks.put(Metadata.MetadataType.FMD_CONTACT_FACEBOOK, facebookContactBlock); + mDetailsBlocks.put(Metadata.MetadataType.FMD_CONTACT_INSTAGRAM, instagramContactBlock); + mDetailsBlocks.put(Metadata.MetadataType.FMD_CONTACT_TWITTER, twitterContactBlock); + mDetailsBlocks.put(Metadata.MetadataType.FMD_CONTACT_VK, vkContactBlock); + mDetailsBlocks.put(Metadata.MetadataType.FMD_CONTACT_LINE, lineContactBlock); + mDetailsBlocks.put(Metadata.MetadataType.FMD_OPERATOR, operatorBlock); } private static TextInputEditText findInput(View blockWithInput) diff --git a/data/editor.config b/data/editor.config index 7dc14ce47c..1213162e6a 100644 --- a/data/editor.config +++ b/data/editor.config @@ -209,6 +209,7 @@ + @@ -229,6 +230,7 @@ + @@ -267,6 +269,7 @@ + @@ -343,6 +346,7 @@ + @@ -354,6 +358,7 @@ + @@ -1051,6 +1056,8 @@ + + @@ -1074,6 +1081,7 @@ + @@ -1096,6 +1104,7 @@ + -- 2.45.3 From 3c45518d1fd9837d740821c825dd9cc5744e9dd8 Mon Sep 17 00:00:00 2001 From: Beatriz Mira Mendes Date: Tue, 2 Apr 2024 12:03:19 +0100 Subject: [PATCH 15/36] [android] Fix: Display list of stop points in ruler and transit mode properly in RTL Changes made: - In MultilineLayoutManager.java: if called with LAYOUT_DIRECTION_RTL tag, the layout is now properly written. - In RoutinBottomMenuController.java: MultilineLayoutManager class is now called with the new parameter, the mTransitFrame's layout direction. - In DotDividerItemDecoration.java: to properly place the dots between the elements in the list, these elements are iterated from right to left when the layout direction is RTL. Signed-off-by: Beatriz Mira Mendes --- .../routing/RoutingBottomMenuController.java | 4 ++-- .../recycler/DotDividerItemDecoration.java | 6 ++++-- .../widget/recycler/MultilineLayoutManager.java | 16 +++++++++++++--- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/android/app/src/main/java/app/organicmaps/routing/RoutingBottomMenuController.java b/android/app/src/main/java/app/organicmaps/routing/RoutingBottomMenuController.java index d2ff7ab2b1..748cb17855 100644 --- a/android/app/src/main/java/app/organicmaps/routing/RoutingBottomMenuController.java +++ b/android/app/src/main/java/app/organicmaps/routing/RoutingBottomMenuController.java @@ -176,7 +176,7 @@ final class RoutingBottomMenuController implements View.OnClickListener UiUtils.show(mTransitFrame); RecyclerView rv = mTransitFrame.findViewById(R.id.transit_recycler_view); TransitStepAdapter adapter = new TransitStepAdapter(); - rv.setLayoutManager(new MultilineLayoutManager()); + rv.setLayoutManager(new MultilineLayoutManager(mTransitFrame.getLayoutDirection())); rv.setNestedScrollingEnabled(false); rv.removeItemDecoration(mTransitViewDecorator); rv.addItemDecoration(mTransitViewDecorator); @@ -206,7 +206,7 @@ final class RoutingBottomMenuController implements View.OnClickListener { UiUtils.show(rv); final TransitStepAdapter adapter = new TransitStepAdapter(); - rv.setLayoutManager(new MultilineLayoutManager()); + rv.setLayoutManager(new MultilineLayoutManager(mTransitFrame.getLayoutDirection())); rv.setNestedScrollingEnabled(false); rv.removeItemDecoration(mTransitViewDecorator); rv.addItemDecoration(mTransitViewDecorator); diff --git a/android/app/src/main/java/app/organicmaps/widget/recycler/DotDividerItemDecoration.java b/android/app/src/main/java/app/organicmaps/widget/recycler/DotDividerItemDecoration.java index 77b5964f77..d3fff7b4d8 100644 --- a/android/app/src/main/java/app/organicmaps/widget/recycler/DotDividerItemDecoration.java +++ b/android/app/src/main/java/app/organicmaps/widget/recycler/DotDividerItemDecoration.java @@ -41,7 +41,10 @@ public class DotDividerItemDecoration extends RecyclerView.ItemDecoration return; int childCount = parent.getChildCount(); - for (int i = 0; i < childCount - 1; i++) + boolean parentLayoutRTL = (parent.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL); + + for (int i = parentLayoutRTL ? childCount - 1 : 0; parentLayoutRTL ? i > 0 : i < childCount - 1; + i += parentLayoutRTL ? -1 : 1) { View child = parent.getChildAt(i); @@ -53,7 +56,6 @@ public class DotDividerItemDecoration extends RecyclerView.ItemDecoration int bottom = top + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); - mDivider.draw(c); } } diff --git a/android/app/src/main/java/app/organicmaps/widget/recycler/MultilineLayoutManager.java b/android/app/src/main/java/app/organicmaps/widget/recycler/MultilineLayoutManager.java index 0c3c9ed105..84326e1068 100644 --- a/android/app/src/main/java/app/organicmaps/widget/recycler/MultilineLayoutManager.java +++ b/android/app/src/main/java/app/organicmaps/widget/recycler/MultilineLayoutManager.java @@ -8,9 +8,12 @@ import androidx.recyclerview.widget.RecyclerView; public class MultilineLayoutManager extends RecyclerView.LayoutManager { - public MultilineLayoutManager() + private boolean reverseLayout = false; + + public MultilineLayoutManager(int layoutDirection) { setAutoMeasureEnabled(true); + reverseLayout = layoutDirection == View.LAYOUT_DIRECTION_RTL; } @Override @@ -25,6 +28,8 @@ public class MultilineLayoutManager extends RecyclerView.LayoutManager { detachAndScrapAttachedViews(recycler); + assertInLayoutOrScroll(null); + int widthUsed = 0; int heightUsed = 0; int lineHeight = 0; @@ -55,7 +60,11 @@ public class MultilineLayoutManager extends RecyclerView.LayoutManager } lineHeight = 0; } - layoutDecorated(child, widthUsed, heightUsed, widthUsed + width, heightUsed + height); + if (reverseLayout) + layoutDecoratedWithMargins(child, getWidth() - widthUsed - width, heightUsed, + getWidth() - widthUsed, heightUsed + height); + else + layoutDecorated(child, widthUsed, heightUsed, widthUsed + width, heightUsed + height); widthUsed += width; itemsCountOneLine++; } @@ -63,7 +72,7 @@ public class MultilineLayoutManager extends RecyclerView.LayoutManager private int squeezeChildIntoLine(int widthUsed, int heightUsed, @NonNull View child) { - if (!(child instanceof SqueezingInterface)) + if (!(child instanceof SqueezingInterface)) return getDecoratedMeasuredWidth(child); int availableWidth = getWidth() - widthUsed - getDecoratedRight(child); @@ -79,6 +88,7 @@ public class MultilineLayoutManager extends RecyclerView.LayoutManager public interface SqueezingInterface { void squeezeTo(@Dimension int width); + @Dimension int getMinimumAcceptableSize(); } -- 2.45.3 From 10b01c93d82fd2950437c59c4c62dce33b273a65 Mon Sep 17 00:00:00 2001 From: David Martinez <47610359+dvdmrtnz@users.noreply.github.com> Date: Mon, 20 May 2024 16:53:01 +0200 Subject: [PATCH 16/36] [placepage] Show all types Signed-off-by: David Martinez <47610359+dvdmrtnz@users.noreply.github.com> --- indexer/map_object.cpp | 23 ++++++++++++++++++++++- indexer/map_object.hpp | 5 ++++- map/place_page_info.cpp | 2 +- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/indexer/map_object.cpp b/indexer/map_object.cpp index 5cca6e0cf0..3d5a447ae5 100644 --- a/indexer/map_object.cpp +++ b/indexer/map_object.cpp @@ -85,7 +85,7 @@ std::string_view MapObject::GetPostcode() const return m_metadata.Get(MetadataID::FMD_POSTCODE); } -string MapObject::GetLocalizedType() const +std::string MapObject::GetLocalizedType() const { ASSERT(!m_types.Empty(), ()); feature::TypesHolder copy(m_types); @@ -94,6 +94,27 @@ string MapObject::GetLocalizedType() const return platform::GetLocalizedTypeName(classif().GetReadableObjectName(copy.GetBestType())); } +std::string MapObject::GetAllLocalizedTypes() const +{ + ASSERT(!m_types.Empty(), ()); + feature::TypesHolder copy(m_types); + copy.SortBySpec(); + + std::ostringstream oss; + bool first = true; + for (auto const type : copy) + { + if (!first) + oss << feature::kFieldsSeparator; + first = false; + + auto localizedType = platform::GetLocalizedTypeName(classif().GetReadableObjectName(type)); + oss << localizedType; + } + + return oss.str(); +} + std::string_view MapObject::GetMetadata(MetadataID type) const { return m_metadata.Get(type); diff --git a/indexer/map_object.hpp b/indexer/map_object.hpp index 98e912c659..46a5f96bc5 100644 --- a/indexer/map_object.hpp +++ b/indexer/map_object.hpp @@ -103,8 +103,11 @@ public: void AssignMetadata(feature::Metadata & dest) const { dest = m_metadata; } protected: - /// @returns "the best" type to display in UI. + /// @returns "the best" single type to display in UI. std::string GetLocalizedType() const; + + /// @returns all types separated by kFieldsSeparator to display in UI. + std::string GetAllLocalizedTypes() const; FeatureID m_featureID; m2::PointD m_mercator; diff --git a/map/place_page_info.cpp b/map/place_page_info.cpp index 1fdcbcd188..1fd7066d79 100644 --- a/map/place_page_info.cpp +++ b/map/place_page_info.cpp @@ -122,7 +122,7 @@ std::string Info::FormatSubtitle(bool withType) const append(m_bookmarkCategoryName); if (withType) - append(GetLocalizedType()); + append(GetAllLocalizedTypes()); // Flats. auto const flats = GetMetadata(feature::Metadata::FMD_FLATS); -- 2.45.3 From d898cf16ac26f6d7fb514441a9f01ae887ffe9f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20W=C3=BCthrich?= Date: Thu, 16 May 2024 09:18:47 -0600 Subject: [PATCH 17/36] [ios] Improve TTS voice selection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit allows a user to select more voices (e.g. English (United States), English (India)). Currently, it's only possible to select a subset of the available voices on iOS. For example, if a user selects English as TTS language, an Australian voice is selected because en_AU comes before en_US in the voice list of iOS. Fixes #6840 Fixes #3222 Fixes #2178 Signed-off-by: Fabian Wüthrich --- .../Core/TextToSpeech/MWMTextToSpeech+CPP.h | 3 +- .../Maps/Core/TextToSpeech/MWMTextToSpeech.mm | 37 ++++++++---------- iphone/Maps/Maps.xcodeproj/project.pbxproj | 38 ++++++++++++++++++- .../CarPlay}/CarPlayServiceTests.swift | 0 .../Core/TextToSpeech/MWMTextToSpeechTests.mm | 28 ++++++++++++++ .../Settings/MWMTTSSettingsViewController.mm | 24 ++++++------ 6 files changed, 94 insertions(+), 36 deletions(-) rename iphone/Maps/Tests/{ => Classes/CarPlay}/CarPlayServiceTests.swift (100%) create mode 100644 iphone/Maps/Tests/Core/TextToSpeech/MWMTextToSpeechTests.mm diff --git a/iphone/Maps/Core/TextToSpeech/MWMTextToSpeech+CPP.h b/iphone/Maps/Core/TextToSpeech/MWMTextToSpeech+CPP.h index 53ad52d3fa..7baa6ddfc5 100644 --- a/iphone/Maps/Core/TextToSpeech/MWMTextToSpeech+CPP.h +++ b/iphone/Maps/Core/TextToSpeech/MWMTextToSpeech+CPP.h @@ -9,10 +9,11 @@ // * name in bcp47; // * localized name; - (std::vector>)availableLanguages; +- (std::pair)standardLanguage; @end namespace tts { -std::string translatedTwine(std::string const & twine); +std::string translateLocale(std::string const & localeString); } // namespace tts diff --git a/iphone/Maps/Core/TextToSpeech/MWMTextToSpeech.mm b/iphone/Maps/Core/TextToSpeech/MWMTextToSpeech.mm index 25beda5598..20dd5703b9 100644 --- a/iphone/Maps/Core/TextToSpeech/MWMTextToSpeech.mm +++ b/iphone/Maps/Core/TextToSpeech/MWMTextToSpeech.mm @@ -27,15 +27,15 @@ std::vector> availableLanguages() using namespace routing::turns::sound; std::vector> result; - for (auto const & p : kLanguageList) + for (auto const & [twineRouting, _] : kLanguageList) { - for (std::pair const & lang : native) + for (auto const & [twineVoice, bcp47Voice] : native) { - if (lang.first == p.first) + if (twineVoice == twineRouting) { - // Twine names are equal. Make a pair: bcp47 name, localized name. - result.emplace_back(make_pair(lang.second, p.second)); - break; + auto pair = std::make_pair(bcp47Voice, tts::translateLocale(bcp47Voice)); + if (std::find(result.begin(), result.end(), pair) == result.end()) + result.emplace_back(std::move(pair)); } } } @@ -91,7 +91,7 @@ using Observers = NSHashTable; std::pair const lan = std::make_pair(preferedLanguageBcp47.UTF8String, - tts::translatedTwine(bcp47ToTwineLanguage(preferedLanguageBcp47))); + tts::translateLocale(preferedLanguageBcp47.UTF8String)); if (find(_availableLanguages.begin(), _availableLanguages.end(), lan) != _availableLanguages.end()) @@ -123,6 +123,9 @@ using Observers = NSHashTable; self.speechSynthesizer.delegate = nil; } - (std::vector>)availableLanguages { return _availableLanguages; } +- (std::pair)standardLanguage { + return std::make_pair(kDefaultLanguage.UTF8String, tts::translateLocale(kDefaultLanguage.UTF8String)); +} - (void)setNotificationsLocale:(NSString *)locale { NSUserDefaults * ud = NSUserDefaults.standardUserDefaults; [ud setObject:locale forKey:kUserDefaultsTTSLanguageBcp47]; @@ -184,10 +187,6 @@ using Observers = NSHashTable; AVSpeechSynthesisVoice * voice = nil; for (NSString * loc in candidateLocales) { - if ([loc isEqualToString:@"en-US"]) - voice = [AVSpeechSynthesisVoice voiceWithIdentifier:AVSpeechSynthesisVoiceIdentifierAlex]; - if (voice) - break; voice = [AVSpeechSynthesisVoice voiceWithLanguage:loc]; if (voice) break; @@ -301,16 +300,12 @@ using Observers = NSHashTable; namespace tts { -std::string translatedTwine(std::string const & twine) +std::string translateLocale(std::string const & localeString) { - auto const & list = routing::turns::sound::kLanguageList; - auto const it = - find_if(list.begin(), list.end(), - [&twine](std::pair const & pair) { return pair.first == twine; }); - - if (it != list.end()) - return it->second; - else - return ""; + NSString * nsLocaleString = [NSString stringWithUTF8String: localeString.c_str()]; + NSLocale * locale = [[NSLocale alloc] initWithLocaleIdentifier: nsLocaleString]; + NSString * localizedName = [locale localizedStringForLocaleIdentifier:nsLocaleString]; + localizedName = [localizedName capitalizedString]; + return std::string(localizedName.UTF8String); } } // namespace tts diff --git a/iphone/Maps/Maps.xcodeproj/project.pbxproj b/iphone/Maps/Maps.xcodeproj/project.pbxproj index 700e4b6035..6c7637cdc6 100644 --- a/iphone/Maps/Maps.xcodeproj/project.pbxproj +++ b/iphone/Maps/Maps.xcodeproj/project.pbxproj @@ -260,6 +260,7 @@ 47F86CFF20C936FC00FEE291 /* TabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47F86CFE20C936FC00FEE291 /* TabView.swift */; }; 47F86D0120C93D8D00FEE291 /* TabViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47F86D0020C93D8D00FEE291 /* TabViewController.swift */; }; 4A300ED51C6DCFD400140018 /* countries-strings in Resources */ = {isa = PBXBuildFile; fileRef = 4A300ED31C6DCFD400140018 /* countries-strings */; }; + 4B4153B52BF9695500EE4B02 /* MWMTextToSpeechTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B4153B42BF9695500EE4B02 /* MWMTextToSpeechTests.mm */; }; 6741A9421BF340DE002C974C /* sound-strings in Resources */ = {isa = PBXBuildFile; fileRef = 5605022E1B6211E100169CAD /* sound-strings */; }; 6741A9451BF340DE002C974C /* classificator.txt in Resources */ = {isa = PBXBuildFile; fileRef = EE026F0511D6AC0D00645242 /* classificator.txt */; }; 6741A9491BF340DE002C974C /* countries.txt in Resources */ = {isa = PBXBuildFile; fileRef = FA46DA2B12D4166E00968C36 /* countries.txt */; }; @@ -1164,6 +1165,7 @@ 4A7D89C21B2EBF3B00AC843E /* resources-mdpi_dark */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "resources-mdpi_dark"; path = "../../data/resources-mdpi_dark"; sourceTree = ""; }; 4A7D89C31B2EBF3B00AC843E /* resources-xhdpi_dark */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "resources-xhdpi_dark"; path = "../../data/resources-xhdpi_dark"; sourceTree = ""; }; 4A7D89C41B2EBF3B00AC843E /* resources-xxhdpi_dark */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "resources-xxhdpi_dark"; path = "../../data/resources-xxhdpi_dark"; sourceTree = ""; }; + 4B4153B42BF9695500EE4B02 /* MWMTextToSpeechTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MWMTextToSpeechTests.mm; sourceTree = ""; }; 5605022E1B6211E100169CAD /* sound-strings */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "sound-strings"; path = "../../data/sound-strings"; sourceTree = ""; }; 6741AA5D1BF340DE002C974C /* Organic Maps (Debug).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Organic Maps (Debug).app"; sourceTree = BUILT_PRODUCTS_DIR; }; 6B15907026623AE500944BBA /* 00_NotoSansThai-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "00_NotoSansThai-Regular.ttf"; path = "../../data/00_NotoSansThai-Regular.ttf"; sourceTree = ""; }; @@ -2611,6 +2613,38 @@ path = TabView; sourceTree = ""; }; + 4B4153B62BF9709100EE4B02 /* Core */ = { + isa = PBXGroup; + children = ( + 4B4153B72BF970A000EE4B02 /* TextToSpeech */, + ); + path = Core; + sourceTree = ""; + }; + 4B4153B72BF970A000EE4B02 /* TextToSpeech */ = { + isa = PBXGroup; + children = ( + 4B4153B42BF9695500EE4B02 /* MWMTextToSpeechTests.mm */, + ); + path = TextToSpeech; + sourceTree = ""; + }; + 4B4153B82BF970B800EE4B02 /* Classes */ = { + isa = PBXGroup; + children = ( + 4B4153B92BF970BD00EE4B02 /* CarPlay */, + ); + path = Classes; + sourceTree = ""; + }; + 4B4153B92BF970BD00EE4B02 /* CarPlay */ = { + isa = PBXGroup; + children = ( + ED1ADA322BC6B1B40029209F /* CarPlayServiceTests.swift */, + ); + path = CarPlay; + sourceTree = ""; + }; 97B4E9271851DAB300BEC5D7 /* Custom Views */ = { isa = PBXGroup; children = ( @@ -2977,7 +3011,8 @@ ED1ADA312BC6B19E0029209F /* Tests */ = { isa = PBXGroup; children = ( - ED1ADA322BC6B1B40029209F /* CarPlayServiceTests.swift */, + 4B4153B82BF970B800EE4B02 /* Classes */, + 4B4153B62BF9709100EE4B02 /* Core */, ); path = Tests; sourceTree = ""; @@ -4476,6 +4511,7 @@ buildActionMask = 2147483647; files = ( ED1ADA332BC6B1B40029209F /* CarPlayServiceTests.swift in Sources */, + 4B4153B52BF9695500EE4B02 /* MWMTextToSpeechTests.mm in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/iphone/Maps/Tests/CarPlayServiceTests.swift b/iphone/Maps/Tests/Classes/CarPlay/CarPlayServiceTests.swift similarity index 100% rename from iphone/Maps/Tests/CarPlayServiceTests.swift rename to iphone/Maps/Tests/Classes/CarPlay/CarPlayServiceTests.swift diff --git a/iphone/Maps/Tests/Core/TextToSpeech/MWMTextToSpeechTests.mm b/iphone/Maps/Tests/Core/TextToSpeech/MWMTextToSpeechTests.mm new file mode 100644 index 0000000000..9d7bbddb0e --- /dev/null +++ b/iphone/Maps/Tests/Core/TextToSpeech/MWMTextToSpeechTests.mm @@ -0,0 +1,28 @@ +#import +#import "MWMTextToSpeech+CPP.h" + +@interface MWMTextToSpeechTest : XCTestCase + +@end + +@implementation MWMTextToSpeechTest + +- (void)testAvailableLanguages { + MWMTextToSpeech * tts = [MWMTextToSpeech tts]; + std::vector> langs = tts.availableLanguages; + auto const defaultLang = std::make_pair("en-US", "English (United States)"); + XCTAssertTrue(std::find(langs.begin(), langs.end(), defaultLang) != langs.end()); +} +- (void)testTranslateLocaleWithTwineString { + XCTAssertEqual(tts::translateLocale("en"), "English"); +} + +- (void)testTranslateLocaleWithBcp47String { + XCTAssertEqual(tts::translateLocale("en-US"), "English (United States)"); +} + +- (void)testTranslateLocaleWithUnknownString { + XCTAssertEqual(tts::translateLocale("unknown"), ""); +} + +@end diff --git a/iphone/Maps/UI/Settings/MWMTTSSettingsViewController.mm b/iphone/Maps/UI/Settings/MWMTTSSettingsViewController.mm index 6f0b215925..963be3f5d0 100644 --- a/iphone/Maps/UI/Settings/MWMTTSSettingsViewController.mm +++ b/iphone/Maps/UI/Settings/MWMTTSSettingsViewController.mm @@ -241,21 +241,20 @@ struct StreetNamesCellStrategy : BaseCellStategy MWMTextToSpeech * tts = [MWMTextToSpeech tts]; m_languages.reserve(3); - auto const & v = tts.availableLanguages; - NSAssert(!v.empty(), @"Vector can't be empty!"); - pair const standart = v.front(); - m_languages.push_back(standart); + pair const standard = tts.standardLanguage; + m_languages.push_back(standard); using namespace tts; NSString * currentBcp47 = [AVSpeechSynthesisVoice currentLanguageCode]; string const currentBcp47Str = currentBcp47.UTF8String; - string const currentTwineStr = bcp47ToTwineLanguage(currentBcp47); - if (currentBcp47Str != standart.first && !currentBcp47Str.empty()) + if (currentBcp47Str != standard.first && !currentBcp47Str.empty()) { - string const translated = translatedTwine(currentTwineStr); - pair const cur{currentBcp47Str, translated}; + auto const & v = tts.availableLanguages; + NSAssert(!v.empty(), @"Vector can't be empty!"); + std::string const translated = translateLocale(currentBcp47Str); + auto cur = std::make_pair(currentBcp47Str, translated); if (translated.empty() || find(v.begin(), v.end(), cur) != v.end()) - m_languages.push_back(cur); + m_languages.push_back(std::move(cur)); else self.isLocaleLanguageAbsent = YES; } @@ -263,11 +262,10 @@ struct StreetNamesCellStrategy : BaseCellStategy NSString * nsSavedLanguage = [MWMTextToSpeech savedLanguage]; if (nsSavedLanguage.length) { - string const savedLanguage = nsSavedLanguage.UTF8String; - if (savedLanguage != currentBcp47Str && savedLanguage != standart.first && + std::string const savedLanguage = nsSavedLanguage.UTF8String; + if (savedLanguage != currentBcp47Str && savedLanguage != standard.first && !savedLanguage.empty()) - m_languages.emplace_back( - make_pair(savedLanguage, translatedTwine(bcp47ToTwineLanguage(nsSavedLanguage)))); + m_languages.emplace_back(savedLanguage, translateLocale(savedLanguage)); } } -- 2.45.3 From a800fb6b5afe7c0871caa6a463301fd86cbe1f49 Mon Sep 17 00:00:00 2001 From: Kiryl Kaveryn Date: Sun, 12 May 2024 16:14:43 +0400 Subject: [PATCH 18/36] [ios] add ic_placepage_website_menu.svg icon Signed-off-by: Kiryl Kaveryn --- .../Contents.json | 15 +++++++++++++++ .../ic_placepage_website_menu.svg | 1 + 2 files changed, 16 insertions(+) create mode 100644 iphone/Maps/Images.xcassets/Place Page/ic_placepage_website_menu.imageset/Contents.json create mode 100644 iphone/Maps/Images.xcassets/Place Page/ic_placepage_website_menu.imageset/ic_placepage_website_menu.svg diff --git a/iphone/Maps/Images.xcassets/Place Page/ic_placepage_website_menu.imageset/Contents.json b/iphone/Maps/Images.xcassets/Place Page/ic_placepage_website_menu.imageset/Contents.json new file mode 100644 index 0000000000..18870ad222 --- /dev/null +++ b/iphone/Maps/Images.xcassets/Place Page/ic_placepage_website_menu.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "ic_placepage_website_menu.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iphone/Maps/Images.xcassets/Place Page/ic_placepage_website_menu.imageset/ic_placepage_website_menu.svg b/iphone/Maps/Images.xcassets/Place Page/ic_placepage_website_menu.imageset/ic_placepage_website_menu.svg new file mode 100644 index 0000000000..44d8f8326c --- /dev/null +++ b/iphone/Maps/Images.xcassets/Place Page/ic_placepage_website_menu.imageset/ic_placepage_website_menu.svg @@ -0,0 +1 @@ + \ No newline at end of file -- 2.45.3 From 031356be6363c59343987ad9bd571a1aeacdb759 Mon Sep 17 00:00:00 2001 From: Kiryl Kaveryn Date: Sun, 12 May 2024 16:17:42 +0400 Subject: [PATCH 19/36] [ios] implement the website:menu to the PlacePage Signed-off-by: Kiryl Kaveryn --- .../PlacePageData/Common/PlacePageInfoData.h | 1 + .../PlacePageData/Common/PlacePageInfoData.mm | 2 +- .../Components/PlacePageInfoViewController.swift | 16 +++++++++++++++- .../Maps/UI/PlacePage/PlacePageInteractor.swift | 6 +++++- .../PlacePageManager/MWMPlacePageManager.mm | 4 ++++ .../PlacePageManager/MWMPlacePageManagerHelper.h | 1 + .../MWMPlacePageManagerHelper.mm | 5 +++++ 7 files changed, 32 insertions(+), 3 deletions(-) diff --git a/iphone/CoreApi/CoreApi/PlacePageData/Common/PlacePageInfoData.h b/iphone/CoreApi/CoreApi/PlacePageData/Common/PlacePageInfoData.h index b110605b94..93ea1ae20f 100644 --- a/iphone/CoreApi/CoreApi/PlacePageData/Common/PlacePageInfoData.h +++ b/iphone/CoreApi/CoreApi/PlacePageData/Common/PlacePageInfoData.h @@ -31,6 +31,7 @@ NS_ASSUME_NONNULL_BEGIN @property(nonatomic, readonly, nullable) NSString *capacity; @property(nonatomic, readonly, nullable) NSString *wheelchair; @property(nonatomic, readonly, nullable) NSString *driveThrough; +@property(nonatomic, readonly, nullable) NSString *websiteMenu; @end diff --git a/iphone/CoreApi/CoreApi/PlacePageData/Common/PlacePageInfoData.mm b/iphone/CoreApi/CoreApi/PlacePageData/Common/PlacePageInfoData.mm index b71d94be6d..0495fa5889 100644 --- a/iphone/CoreApi/CoreApi/PlacePageData/Common/PlacePageInfoData.mm +++ b/iphone/CoreApi/CoreApi/PlacePageData/Common/PlacePageInfoData.mm @@ -83,7 +83,7 @@ using namespace osm; if (value == "yes") _driveThrough = NSLocalizedString(@"drive_through", nil); break; - + case MetadataID::FMD_WEBSITE_MENU: _websiteMenu = ToNSString(value); break; default: break; } diff --git a/iphone/Maps/UI/PlacePage/Components/PlacePageInfoViewController.swift b/iphone/Maps/UI/PlacePage/Components/PlacePageInfoViewController.swift index 82c090cdcc..35d90dc27c 100644 --- a/iphone/Maps/UI/PlacePage/Components/PlacePageInfoViewController.swift +++ b/iphone/Maps/UI/PlacePage/Components/PlacePageInfoViewController.swift @@ -50,6 +50,7 @@ class InfoItemViewController: UIViewController { protocol PlacePageInfoViewControllerDelegate: AnyObject { func didPressCall() func didPressWebsite() + func didPressWebsiteMenu() func didPressKayak() func didPressWikipedia() func didPressWikimediaCommons() @@ -78,6 +79,7 @@ class PlacePageInfoViewController: UIViewController { private var rawOpeningHoursView: InfoItemViewController? private var phoneView: InfoItemViewController? private var websiteView: InfoItemViewController? + private var websiteMenuView: InfoItemViewController? private var kayakView: InfoItemViewController? private var wikipediaView: InfoItemViewController? private var wikimediaCommonsView: InfoItemViewController? @@ -158,7 +160,19 @@ class PlacePageInfoViewController: UIViewController { self?.delegate?.didCopy(website) }) } - + + if let websiteMenu = placePageInfoData.websiteMenu { + websiteView = createInfoItem(L("website_menu"), + icon: UIImage(named: "ic_placepage_website_menu"), + style: .link, + tapHandler: { [weak self] in + self?.delegate?.didPressWebsiteMenu() + }, + longPressHandler: { [weak self] in + self?.delegate?.didCopy(websiteMenu) + }) + } + if let wikipedia = placePageInfoData.wikipedia { wikipediaView = createInfoItem(L("read_in_wikipedia"), icon: UIImage(named: "ic_placepage_wiki"), diff --git a/iphone/Maps/UI/PlacePage/PlacePageInteractor.swift b/iphone/Maps/UI/PlacePage/PlacePageInteractor.swift index 8a0f9c7f85..b29512eee6 100644 --- a/iphone/Maps/UI/PlacePage/PlacePageInteractor.swift +++ b/iphone/Maps/UI/PlacePage/PlacePageInteractor.swift @@ -32,7 +32,11 @@ extension PlacePageInteractor: PlacePageInfoViewControllerDelegate { func didPressWebsite() { MWMPlacePageManagerHelper.openWebsite(placePageData) } - + + func didPressWebsiteMenu() { + MWMPlacePageManagerHelper.openWebsiteMenu(placePageData) + } + func didPressKayak() { let kUDDidShowKayakInformationDialog = "kUDDidShowKayakInformationDialog" diff --git a/iphone/Maps/UI/PlacePage/PlacePageManager/MWMPlacePageManager.mm b/iphone/Maps/UI/PlacePage/PlacePageManager/MWMPlacePageManager.mm index f5bd1edf54..779c5e90d4 100644 --- a/iphone/Maps/UI/PlacePage/PlacePageManager/MWMPlacePageManager.mm +++ b/iphone/Maps/UI/PlacePage/PlacePageManager/MWMPlacePageManager.mm @@ -232,6 +232,10 @@ using namespace storage; [self.ownerViewController openUrl:data.infoData.website]; } +- (void)openWebsiteMenu:(PlacePageData *)data { + [self.ownerViewController openUrl:data.infoData.websiteMenu]; +} + - (void)openKayak:(PlacePageData *)data { [self.ownerViewController openUrl:data.infoData.kayak]; } diff --git a/iphone/Maps/UI/PlacePage/PlacePageManager/MWMPlacePageManagerHelper.h b/iphone/Maps/UI/PlacePage/PlacePageManager/MWMPlacePageManagerHelper.h index 5bca1ace42..b2e3964b0e 100644 --- a/iphone/Maps/UI/PlacePage/PlacePageManager/MWMPlacePageManagerHelper.h +++ b/iphone/Maps/UI/PlacePage/PlacePageManager/MWMPlacePageManagerHelper.h @@ -8,6 +8,7 @@ + (void)addBusiness; + (void)addPlace:(CLLocationCoordinate2D)coordinate; + (void)openWebsite:(PlacePageData *)data; ++ (void)openWebsiteMenu:(PlacePageData *)data; + (void)openKayak:(PlacePageData *)data; + (void)openWikipedia:(PlacePageData *)data; + (void)openWikimediaCommons:(PlacePageData *)data; diff --git a/iphone/Maps/UI/PlacePage/PlacePageManager/MWMPlacePageManagerHelper.mm b/iphone/Maps/UI/PlacePage/PlacePageManager/MWMPlacePageManagerHelper.mm index 8d7470ec3e..ae1124836c 100644 --- a/iphone/Maps/UI/PlacePage/PlacePageManager/MWMPlacePageManagerHelper.mm +++ b/iphone/Maps/UI/PlacePage/PlacePageManager/MWMPlacePageManagerHelper.mm @@ -15,6 +15,7 @@ - (void)addBusiness; - (void)addPlace:(CLLocationCoordinate2D)coordinate; - (void)openWebsite:(PlacePageData *)data; +- (void)openWebsiteMenu:(PlacePageData *)data; - (void)openKayak:(PlacePageData *)data; - (void)openWikipedia:(PlacePageData *)data; - (void)openWikimediaCommons:(PlacePageData *)data; @@ -72,6 +73,10 @@ [[MWMMapViewControlsManager manager].placePageManager openWebsite:data]; } ++ (void)openWebsiteMenu:(PlacePageData *)data { + [[MWMMapViewControlsManager manager].placePageManager openWebsiteMenu:data]; +} + + (void)openKayak:(PlacePageData *)data { [[MWMMapViewControlsManager manager].placePageManager openKayak:data]; } -- 2.45.3 From 3f5ad40239420f5a87227fcc718cefec5d52d1a3 Mon Sep 17 00:00:00 2001 From: Kiryl Kaveryn Date: Sun, 12 May 2024 16:18:52 +0400 Subject: [PATCH 20/36] [strings] add website_menu string for ios Signed-off-by: Kiryl Kaveryn --- data/strings/strings.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/strings/strings.txt b/data/strings/strings.txt index 12a1d4ef4b..962d550788 100644 --- a/data/strings/strings.txt +++ b/data/strings/strings.txt @@ -30257,7 +30257,7 @@ [website_menu] comment = Restaurant or other food place's menu URL field in the Editor - tags = android + tags = android,ios en = Menu Link af = Kieslys skakel ar = رابط القائمة -- 2.45.3 From 1a3c209d81c818ce102c7c57c9e8bb8c35811523 Mon Sep 17 00:00:00 2001 From: Kiryl Kaveryn Date: Sun, 12 May 2024 16:19:13 +0400 Subject: [PATCH 21/36] [strings] regenerated Signed-off-by: Kiryl Kaveryn --- iphone/Maps/LocalizedStrings/ar.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/az.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/be.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/bg.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/ca.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/cs.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/da.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/de.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/el.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/en-GB.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/en.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/es-MX.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/es.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/et.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/eu.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/fa.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/fi.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/fr.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/he.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/hi.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/hu.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/id.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/it.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/ja.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/ko.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/mr.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/nb.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/nl.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/pl.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/pt-BR.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/pt.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/ro.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/ru.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/sk.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/sv.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/sw.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/th.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/tr.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/uk.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/vi.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/zh-Hans.lproj/Localizable.strings | 3 +++ iphone/Maps/LocalizedStrings/zh-Hant.lproj/Localizable.strings | 3 +++ 42 files changed, 126 insertions(+) diff --git a/iphone/Maps/LocalizedStrings/ar.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/ar.lproj/Localizable.strings index 32b01e44ca..170ddb18bf 100644 --- a/iphone/Maps/LocalizedStrings/ar.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/ar.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "الشراء من السيارة"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "رابط القائمة"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/az.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/az.lproj/Localizable.strings index d6ad24ca1d..55671d0a43 100644 --- a/iphone/Maps/LocalizedStrings/az.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/az.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Sürüşmə"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Menyu keçidi"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/be.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/be.lproj/Localizable.strings index 4cf7a4b6f0..116b838f96 100644 --- a/iphone/Maps/LocalizedStrings/be.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/be.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "З акенцам для кіроўцаў"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Спасылка на меню"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/bg.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/bg.lproj/Localizable.strings index b4516bef08..873dcc99e8 100644 --- a/iphone/Maps/LocalizedStrings/bg.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/bg.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "С прозорец за шофьори"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Връзка към менюто"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/ca.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/ca.lproj/Localizable.strings index 498b26323b..60d183d02c 100644 --- a/iphone/Maps/LocalizedStrings/ca.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/ca.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Servei al cotxe"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Enllaç del menú"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/cs.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/cs.lproj/Localizable.strings index 9c01188342..ef21d6a029 100644 --- a/iphone/Maps/LocalizedStrings/cs.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/cs.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Průjezd"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Odkaz na menu"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/da.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/da.lproj/Localizable.strings index d0ec940b04..d0cc1b8166 100644 --- a/iphone/Maps/LocalizedStrings/da.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/da.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Køre gennem"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Link til menu"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/de.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/de.lproj/Localizable.strings index b142c25266..b00a841059 100644 --- a/iphone/Maps/LocalizedStrings/de.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/de.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Drive-through"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Link zur Speisekarte"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/el.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/el.lproj/Localizable.strings index 95b29fcf4a..1f9958f5ab 100644 --- a/iphone/Maps/LocalizedStrings/el.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/el.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Οδηγώ μέσα από"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Σύνδεσμος μενού"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/en-GB.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/en-GB.lproj/Localizable.strings index b61447a62f..602ebaa971 100644 --- a/iphone/Maps/LocalizedStrings/en-GB.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/en-GB.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Drive-through"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Menu Link"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/en.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/en.lproj/Localizable.strings index 41bd5c4aea..8c3e9cf071 100644 --- a/iphone/Maps/LocalizedStrings/en.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/en.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Drive-through"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Menu Link"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/es-MX.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/es-MX.lproj/Localizable.strings index 18a30bb529..2daccf0d78 100644 --- a/iphone/Maps/LocalizedStrings/es-MX.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/es-MX.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Servicio al auto"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Enlace al menú"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/es.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/es.lproj/Localizable.strings index d6753fd2df..06edad3b8d 100644 --- a/iphone/Maps/LocalizedStrings/es.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/es.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Servicio al auto"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Enlace al menú"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/et.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/et.lproj/Localizable.strings index a19567c35c..e558df4b98 100644 --- a/iphone/Maps/LocalizedStrings/et.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/et.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Läbi sõit"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Menüü link"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/eu.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/eu.lproj/Localizable.strings index 8200bbaf07..7efebb7602 100644 --- a/iphone/Maps/LocalizedStrings/eu.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/eu.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Drive-through"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Menuaren esteka"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/fa.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/fa.lproj/Localizable.strings index 2655b85a9c..692c0a2535 100644 --- a/iphone/Maps/LocalizedStrings/fa.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/fa.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "رانندگی از طریق"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "لینک منو"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/fi.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/fi.lproj/Localizable.strings index 0c4bac560c..b7eba80608 100644 --- a/iphone/Maps/LocalizedStrings/fi.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/fi.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Ajaa läpi"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Valikkolinkki"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/fr.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/fr.lproj/Localizable.strings index b182483093..0a5939be3c 100644 --- a/iphone/Maps/LocalizedStrings/fr.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/fr.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Au volant"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Lien vers le menu"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/he.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/he.lproj/Localizable.strings index 4c384fb3dd..1da3a274e5 100644 --- a/iphone/Maps/LocalizedStrings/he.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/he.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "דרייב ת'רו"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "קישור לתפריט"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/hi.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/hi.lproj/Localizable.strings index 7a20343081..8fb6a7db7a 100644 --- a/iphone/Maps/LocalizedStrings/hi.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/hi.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "ड्राइव करते हुए किसी जगह से गुजरना"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "मेनू लिंक"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/hu.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/hu.lproj/Localizable.strings index 1af0666608..7ca5fd7656 100644 --- a/iphone/Maps/LocalizedStrings/hu.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/hu.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Drive-through"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Menü link"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/id.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/id.lproj/Localizable.strings index a3804d9b6e..3fea0bad9a 100644 --- a/iphone/Maps/LocalizedStrings/id.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/id.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Berkendara melewati"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Tautan menu"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/it.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/it.lproj/Localizable.strings index ecfb077ab0..3f660dd190 100644 --- a/iphone/Maps/LocalizedStrings/it.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/it.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Accesso con auto"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Link al menu"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/ja.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/ja.lproj/Localizable.strings index 5e4936804d..d218276fbb 100644 --- a/iphone/Maps/LocalizedStrings/ja.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/ja.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "ドライブスルー"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "メニューリンク"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/ko.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/ko.lproj/Localizable.strings index 3975df0562..8fc1d64a5b 100644 --- a/iphone/Maps/LocalizedStrings/ko.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/ko.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "드라이브 스루"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "메뉴 링크"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/mr.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/mr.lproj/Localizable.strings index ad9e869123..5befb93ee8 100644 --- a/iphone/Maps/LocalizedStrings/mr.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/mr.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "मार्गे चला"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "मेनू लिंक"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/nb.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/nb.lproj/Localizable.strings index 122209bacd..e54b00f421 100644 --- a/iphone/Maps/LocalizedStrings/nb.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/nb.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Gjennomkjøring"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Lenke til menyen"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/nl.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/nl.lproj/Localizable.strings index b78185802b..03dab15211 100644 --- a/iphone/Maps/LocalizedStrings/nl.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/nl.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Drive-though"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Menulink"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/pl.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/pl.lproj/Localizable.strings index 7d0427fd47..00cc5aa3f4 100644 --- a/iphone/Maps/LocalizedStrings/pl.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/pl.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Przejazd"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Link do menu"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/pt-BR.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/pt-BR.lproj/Localizable.strings index a05b49d211..1414a4e8ae 100644 --- a/iphone/Maps/LocalizedStrings/pt-BR.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/pt-BR.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Drive-through"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Link do menu"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/pt.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/pt.lproj/Localizable.strings index bd25cf7bca..1f74554cd2 100644 --- a/iphone/Maps/LocalizedStrings/pt.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/pt.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Drive-through"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Link do menu"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/ro.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/ro.lproj/Localizable.strings index e70ca9f85b..bda2e8d55f 100644 --- a/iphone/Maps/LocalizedStrings/ro.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/ro.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Servire în mașină"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Legătura de meniu"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/ru.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/ru.lproj/Localizable.strings index 691564581a..f4d9ed98ae 100644 --- a/iphone/Maps/LocalizedStrings/ru.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/ru.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "С окошком для водителей"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Ссылка на меню"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/sk.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/sk.lproj/Localizable.strings index 21d577b043..65b13cc2b7 100644 --- a/iphone/Maps/LocalizedStrings/sk.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/sk.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Drive-thru"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Odkaz na menu"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/sv.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/sv.lproj/Localizable.strings index d12dd5ea84..63881b8ebf 100644 --- a/iphone/Maps/LocalizedStrings/sv.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/sv.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Genomkörning"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Länk till meny"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/sw.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/sw.lproj/Localizable.strings index 12fb178b44..f3cd0f1fc1 100644 --- a/iphone/Maps/LocalizedStrings/sw.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/sw.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Kuendesha-kupitia"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Kiungo cha menyu"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/th.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/th.lproj/Localizable.strings index 344e2d2757..3203d1069a 100644 --- a/iphone/Maps/LocalizedStrings/th.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/th.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "ขับรถผ่าน"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "ลิงค์เมนู"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/tr.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/tr.lproj/Localizable.strings index 03e1f1b28b..e9ebf7b285 100644 --- a/iphone/Maps/LocalizedStrings/tr.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/tr.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Arabaya servis"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Menü bağlantısı"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/uk.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/uk.lproj/Localizable.strings index 56e3fcf49a..b7a1a19ce1 100644 --- a/iphone/Maps/LocalizedStrings/uk.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/uk.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "З віконцем для водіїв"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Посилання на меню"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/vi.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/vi.lproj/Localizable.strings index 2c51f4b6d9..7e3f4bacd0 100644 --- a/iphone/Maps/LocalizedStrings/vi.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/vi.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "Lái xe qua"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "Liên kết thực đơn"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/zh-Hans.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/zh-Hans.lproj/Localizable.strings index b95d6cf188..7f0d0455b0 100644 --- a/iphone/Maps/LocalizedStrings/zh-Hans.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/zh-Hans.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "驾车通过"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "菜单链接"; + /********** Types **********/ diff --git a/iphone/Maps/LocalizedStrings/zh-Hant.lproj/Localizable.strings b/iphone/Maps/LocalizedStrings/zh-Hant.lproj/Localizable.strings index d3e731520c..61dd4c99c1 100644 --- a/iphone/Maps/LocalizedStrings/zh-Hant.lproj/Localizable.strings +++ b/iphone/Maps/LocalizedStrings/zh-Hant.lproj/Localizable.strings @@ -1293,6 +1293,9 @@ "drive_through" = "免下車服務"; +/* Restaurant or other food place's menu URL field in the Editor */ +"website_menu" = "選單連結"; + /********** Types **********/ -- 2.45.3 From f22068c0523d00748801b9f8f922e13f4b63c473 Mon Sep 17 00:00:00 2001 From: Kiryl Kaveryn Date: Sun, 12 May 2024 17:29:51 +0400 Subject: [PATCH 22/36] [ios] add support for the `website_menu` to the Edit/Add place screen Signed-off-by: Kiryl Kaveryn --- iphone/Maps/UI/Editor/MWMEditorViewController.mm | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/iphone/Maps/UI/Editor/MWMEditorViewController.mm b/iphone/Maps/UI/Editor/MWMEditorViewController.mm index 4b47e4e481..9530334753 100644 --- a/iphone/Maps/UI/Editor/MWMEditorViewController.mm +++ b/iphone/Maps/UI/Editor/MWMEditorViewController.mm @@ -478,6 +478,17 @@ void registerCellsForTableView(std::vector const & cells, UITab keyboardType:UIKeyboardTypeURL]; break; } + case MetadataID::FMD_WEBSITE_MENU: + { + [self configTextViewCell:cell + cellID:cellID + icon:@"ic_placepage_website_menu" + placeholder:L(@"website_menu") + errorMessage:L(@"error_enter_correct_web") + isValid:isValid + keyboardType:UIKeyboardTypeURL]; + break; + } case MetadataID::FMD_EMAIL: { [self configTextViewCell:cell -- 2.45.3 From 1d5013e892be54d8e4b80843326be6c3c4bb0fc2 Mon Sep 17 00:00:00 2001 From: Viktor Govako Date: Sun, 5 May 2024 23:56:38 -0300 Subject: [PATCH 23/36] Removed regex dependency. Signed-off-by: Viktor Govako --- base/base_tests/regexp_test.cpp | 25 ++++++++++++++++++------- base/string_utils.cpp | 1 + base/string_utils.hpp | 10 ---------- drape/glyph_manager.cpp | 3 +-- indexer/search_string_utils.cpp | 2 +- kml/types.cpp | 2 +- search/string_utils.cpp | 2 ++ 7 files changed, 24 insertions(+), 21 deletions(-) diff --git a/base/base_tests/regexp_test.cpp b/base/base_tests/regexp_test.cpp index 6c4fa912a0..5408cc51d1 100644 --- a/base/base_tests/regexp_test.cpp +++ b/base/base_tests/regexp_test.cpp @@ -1,10 +1,19 @@ #include "testing/testing.hpp" #include "base/stl_helpers.hpp" -#include "base/string_utils.hpp" #include + +namespace regexp_test +{ +template +void ForEachMatched(std::string const & s, std::regex const & regex, Fn && fn) +{ + for (std::sregex_token_iterator cur(s.begin(), s.end(), regex), end; cur != end; ++cur) + fn(*cur); +} + UNIT_TEST(RegExp_Or) { std::regex exp("\\.mwm\\.(downloading2?$|resume2?$)"); @@ -29,7 +38,7 @@ UNIT_TEST(RegExp_ForEachMatched) { std::string const s = "6.66, 9.99"; std::vector v; - strings::ForEachMatched(s, exp, base::MakeBackInsertFunctor(v)); + ForEachMatched(s, exp, base::MakeBackInsertFunctor(v)); TEST_EQUAL(v.size(), 1, ()); TEST_EQUAL(v[0], s, ()); } @@ -38,7 +47,7 @@ UNIT_TEST(RegExp_ForEachMatched) std::string const s1 = "6.66, 9.99"; std::string const s2 = "-5.55, -7.77"; std::vector v; - strings::ForEachMatched(s1 + " 180 , bfuewib 365@" + s2, exp, base::MakeBackInsertFunctor(v)); + ForEachMatched(s1 + " 180 , bfuewib 365@" + s2, exp, base::MakeBackInsertFunctor(v)); TEST_EQUAL(v.size(), 2, ()); TEST_EQUAL(v[0], s1, ()); TEST_EQUAL(v[1], s2, ()); @@ -47,7 +56,7 @@ UNIT_TEST(RegExp_ForEachMatched) { std::string const s = "X6.66, 9.99"; std::vector v; - strings::ForEachMatched(s, exp, base::MakeBackInsertFunctor(v)); + ForEachMatched(s, exp, base::MakeBackInsertFunctor(v)); TEST_EQUAL(v.size(), 1, ()); TEST_EQUAL(v[0], std::string(s.begin() + 1, s.end()), ()); } @@ -55,7 +64,7 @@ UNIT_TEST(RegExp_ForEachMatched) { std::string const s = "6.66, 9.99X"; std::vector v; - strings::ForEachMatched(s, exp, base::MakeBackInsertFunctor(v)); + ForEachMatched(s, exp, base::MakeBackInsertFunctor(v)); TEST_EQUAL(v.size(), 1, ()); TEST_EQUAL(v[0], std::string(s.begin(), s.end() - 1), ()); } @@ -63,14 +72,16 @@ UNIT_TEST(RegExp_ForEachMatched) { std::string const s = "6.66X, 9.99"; std::vector v; - strings::ForEachMatched(s, exp, base::MakeBackInsertFunctor(v)); + ForEachMatched(s, exp, base::MakeBackInsertFunctor(v)); TEST_EQUAL(v.size(), 0, ()); } { std::string const s = "6.66, X9.99"; std::vector v; - strings::ForEachMatched(s, exp, base::MakeBackInsertFunctor(v)); + ForEachMatched(s, exp, base::MakeBackInsertFunctor(v)); TEST_EQUAL(v.size(), 0, ()); } } + +} // namespace regexp_test diff --git a/base/string_utils.cpp b/base/string_utils.cpp index 8b83d76535..c7229e26c1 100644 --- a/base/string_utils.cpp +++ b/base/string_utils.cpp @@ -1,6 +1,7 @@ #include "base/string_utils.hpp" #include "base/assert.hpp" +#include "base/stl_helpers.hpp" #include #include diff --git a/base/string_utils.hpp b/base/string_utils.hpp index 178576a0f1..f3db1127da 100644 --- a/base/string_utils.hpp +++ b/base/string_utils.hpp @@ -2,7 +2,6 @@ #include "base/buffer_vector.hpp" #include "base/checked_cast.hpp" -#include "base/stl_helpers.hpp" #include #include @@ -11,8 +10,6 @@ #include #include #include -#include -#include #include #include #include @@ -635,13 +632,6 @@ typename Container::value_type JoinStrings(Container const & container, Delimite return JoinStrings(begin(container), end(container), delimiter); } -template -void ForEachMatched(std::string const & s, std::regex const & regex, Fn && fn) -{ - for (std::sregex_token_iterator cur(s.begin(), s.end(), regex), end; cur != end; ++cur) - fn(*cur); -} - // Computes the minimum number of insertions, deletions and // alterations of characters needed to transform one string into // another. The function works in O(length1 * length2) time and diff --git a/drape/glyph_manager.cpp b/drape/glyph_manager.cpp index 4791899f9b..8e38654325 100644 --- a/drape/glyph_manager.cpp +++ b/drape/glyph_manager.cpp @@ -10,12 +10,11 @@ #include "base/string_utils.hpp" #include "base/logging.hpp" #include "base/macros.hpp" -#include "base/math.hpp" +#include "base/stl_helpers.hpp" #include #include #include -#include #include #include diff --git a/indexer/search_string_utils.cpp b/indexer/search_string_utils.cpp index 09835ae800..e964fca0e1 100644 --- a/indexer/search_string_utils.cpp +++ b/indexer/search_string_utils.cpp @@ -6,9 +6,9 @@ #include "base/dfa_helpers.hpp" #include "base/mem_trie.hpp" +#include "base/stl_helpers.hpp" #include -#include #include #include diff --git a/kml/types.cpp b/kml/types.cpp index 308d9aacdc..68d96d34ba 100644 --- a/kml/types.cpp +++ b/kml/types.cpp @@ -3,9 +3,9 @@ #include "kml/minzoom_quadtree.hpp" #include "base/macros.hpp" +#include "base/stl_helpers.hpp" #include "base/string_utils.hpp" -#include namespace kml { diff --git a/search/string_utils.cpp b/search/string_utils.cpp index f16747c1b8..9658ee3c11 100644 --- a/search/string_utils.cpp +++ b/search/string_utils.cpp @@ -2,6 +2,8 @@ #include "indexer/search_string_utils.hpp" +#include "base/stl_helpers.hpp" + namespace search { -- 2.45.3 From 4ba9c8e54dc336a4ee8fb70f6ddbd5f3ff361e53 Mon Sep 17 00:00:00 2001 From: Viktor Govako Date: Wed, 8 May 2024 22:04:23 -0300 Subject: [PATCH 24/36] [generator][search] Fixed rewriting sections. Signed-off-by: Viktor Govako --- coding/coding_tests/files_container_tests.cpp | 42 +++++++++++++++++++ generator/search_index_builder.cpp | 5 +++ 2 files changed, 47 insertions(+) diff --git a/coding/coding_tests/files_container_tests.cpp b/coding/coding_tests/files_container_tests.cpp index 6b49eea188..3d694605c0 100644 --- a/coding/coding_tests/files_container_tests.cpp +++ b/coding/coding_tests/files_container_tests.cpp @@ -217,6 +217,48 @@ UNIT_TEST(FilesContainer_RewriteExisting) FileWriter::DeleteFileX(fName); } +/// @todo To make this test work, need to review FilesContainerW::GetWriter logic. +/* +UNIT_TEST(FilesContainer_ConsecutiveRewriteExisting) +{ + string const fName = "files_container.tmp"; + FileWriter::DeleteFileX(fName); + + char const * key[] = { "3", "2", "1" }; + char const * value[] = { "prolog", "data", "epilog" }; + + // fill container + { + FilesContainerW writer(fName); + + for (size_t i = 0; i < ARRAY_SIZE(key); ++i) + { + auto w = writer.GetWriter(key[i]); + w->Write(value[i], strlen(value[i])); + } + } + + char const * buf0 = "xxx"; + char const * buf1 = "yyy"; + { + FilesContainerW writer(fName, FileWriter::OP_WRITE_EXISTING); + + { + auto w = writer.GetWriter(key[0]); + w->Write(buf0, strlen(buf0)); + } + + { + auto w = writer.GetWriter(key[1]); + w->Write(buf1, strlen(buf1)); + } + } + + char const * values[] = { buf0, buf1, value[2] }; + CheckContainer(fName, key, values, 3); +} +*/ + UNIT_TEST(FilesMappingContainer_Handle) { string const fName = "files_container.tmp"; diff --git a/generator/search_index_builder.cpp b/generator/search_index_builder.cpp index eef9f64292..9e270fa0b0 100644 --- a/generator/search_index_builder.cpp +++ b/generator/search_index_builder.cpp @@ -648,9 +648,14 @@ bool BuildSearchIndexFromDataFile(std::string const & country, feature::Generate writer->Seek(endOffset); } + /// @todo FilesContainerW::Write with section overriding invalidates current container instance + /// (@see FilesContainerW::GetWriter), thus we can't make 2 consecutive Write calls. { FilesContainerW writeContainer(readContainer.GetFileName(), FileWriter::OP_WRITE_EXISTING); writeContainer.Write(streetsFilePath, FEATURE2STREET_FILE_TAG); + } + { + FilesContainerW writeContainer(readContainer.GetFileName(), FileWriter::OP_WRITE_EXISTING); writeContainer.Write(placesFilePath, FEATURE2PLACE_FILE_TAG); } } -- 2.45.3 From 6a5d934b40dbebfa817fe361f8fd89ae05ee6c5a Mon Sep 17 00:00:00 2001 From: Viktor Govako Date: Sun, 5 May 2024 12:52:03 -0300 Subject: [PATCH 25/36] [generator][search] Restore external postcodes. Signed-off-by: Viktor Govako --- base/base_tests/string_utils_test.cpp | 8 ++ base/string_utils.cpp | 15 +++ base/string_utils.hpp | 1 + .../test_mwm_builder.cpp | 17 ++- .../test_mwm_builder.hpp | 12 +- generator/generator_tool/generator_tool.cpp | 25 +--- generator/postcode_points_builder.cpp | 114 +++++++----------- routing/routing_tests/mwm_hierarchy_test.cpp | 2 + .../postcode_points_tests.cpp | 103 ++++++++++------ tools/python/maps_generator/generator/env.py | 8 -- .../generator/stages_declaration.py | 17 +-- .../var/etc/map_generator.ini.default | 2 + 12 files changed, 163 insertions(+), 161 deletions(-) diff --git a/base/base_tests/string_utils_test.cpp b/base/base_tests/string_utils_test.cpp index 027b6c75e9..f0b0b071b8 100644 --- a/base/base_tests/string_utils_test.cpp +++ b/base/base_tests/string_utils_test.cpp @@ -1270,4 +1270,12 @@ UNIT_TEST(Trim) strings::Trim(str, "tsgn"); TEST_EQUAL(str, "ri", ()); + + std::string_view v = "\"abc "; + strings::Trim(v, "\" "); + TEST_EQUAL(v, "abc", ()); + + v = "aaa"; + strings::Trim(v, "a"); + TEST(v.empty(), ()); } diff --git a/base/string_utils.cpp b/base/string_utils.cpp index c7229e26c1..c664960199 100644 --- a/base/string_utils.cpp +++ b/base/string_utils.cpp @@ -233,6 +233,21 @@ void Trim(std::string_view & sv) sv = {}; } +void Trim(std::string_view & s, std::string_view anyOf) +{ + auto i = s.find_first_not_of(anyOf); + if (i != std::string_view::npos) + { + s.remove_prefix(i); + + i = s.find_last_not_of(anyOf); + ASSERT(i != std::string_view::npos, ()); + s.remove_suffix(s.size() - i - 1); + } + else + s = {}; +} + void Trim(std::string & s, std::string_view anyOf) { boost::trim_if(s, boost::is_any_of(anyOf)); diff --git a/base/string_utils.hpp b/base/string_utils.hpp index f3db1127da..74398480b8 100644 --- a/base/string_utils.hpp +++ b/base/string_utils.hpp @@ -108,6 +108,7 @@ void AsciiToLower(std::string & s); void Trim(std::string & s); void Trim(std::string_view & sv); /// Remove any characters that contain in "anyOf" on left and right side of string s +void Trim(std::string_view & s, std::string_view anyOf); void Trim(std::string & s, std::string_view anyOf); // Replace the first match of the search substring in the input with the format string. diff --git a/generator/generator_tests_support/test_mwm_builder.cpp b/generator/generator_tests_support/test_mwm_builder.cpp index 7c7f3d8870..b6004c0417 100644 --- a/generator/generator_tests_support/test_mwm_builder.cpp +++ b/generator/generator_tests_support/test_mwm_builder.cpp @@ -7,12 +7,10 @@ #include "generator/feature_merger.hpp" #include "generator/feature_sorter.hpp" #include "generator/generator_tests_support/test_feature.hpp" -#include "generator/postcode_points_builder.hpp" #include "generator/search_index_builder.hpp" #include "indexer/city_boundary.hpp" #include "indexer/data_header.hpp" -#include "indexer/feature_data.hpp" #include "indexer/feature_meta.hpp" #include "indexer/features_offsets_table.hpp" #include "indexer/ftypes_matcher.hpp" @@ -30,7 +28,6 @@ #include "defines.hpp" -#include namespace generator { @@ -130,10 +127,12 @@ bool TestMwmBuilder::Add(FeatureBuilder & fb) return true; } -void TestMwmBuilder::SetUKPostcodesData(string const & postcodesPath, - std::shared_ptr const & countryInfoGetter) +void TestMwmBuilder::SetPostcodesData(string const & postcodesPath, + indexer::PostcodePointsDatasetType postcodesType, + std::shared_ptr const & countryInfoGetter) { - m_ukPostcodesPath = postcodesPath; + m_postcodesPath = postcodesPath; + m_postcodesType = postcodesType; m_postcodesCountryInfoGetter = countryInfoGetter; } @@ -170,11 +169,11 @@ void TestMwmBuilder::Finish() true /* forceRebuild */, 1 /* threadsCount */), ("Can't build search index.")); - if (!m_ukPostcodesPath.empty() && m_postcodesCountryInfoGetter) + if (!m_postcodesPath.empty() && m_postcodesCountryInfoGetter) { CHECK(indexer::BuildPostcodePointsWithInfoGetter(m_file.GetDirectory(), m_file.GetCountryName(), - indexer::PostcodePointsDatasetType::UK, - m_ukPostcodesPath, true /* forceRebuild */, + m_postcodesType, + m_postcodesPath, true /* forceRebuild */, *m_postcodesCountryInfoGetter), ("Can't build postcodes section.")); } diff --git a/generator/generator_tests_support/test_mwm_builder.hpp b/generator/generator_tests_support/test_mwm_builder.hpp index d2ca60ca42..7b52950068 100644 --- a/generator/generator_tests_support/test_mwm_builder.hpp +++ b/generator/generator_tests_support/test_mwm_builder.hpp @@ -1,6 +1,7 @@ #pragma once #include "generator/cities_boundaries_builder.hpp" +#include "generator/postcode_points_builder.hpp" #include "indexer/data_header.hpp" @@ -41,8 +42,10 @@ public: void AddSafe(TestFeature const & feature); bool Add(feature::FeatureBuilder & fb); - void SetUKPostcodesData(std::string const & postcodesPath, - std::shared_ptr const & countryInfoGetter); + void SetPostcodesData(std::string const & postcodesPath, + indexer::PostcodePointsDatasetType postcodesType, + std::shared_ptr const & countryInfoGetter); + void SetMwmLanguages(std::vector const & languages); void Finish(); @@ -53,8 +56,11 @@ private: std::vector m_languages; std::unique_ptr m_collector; TestIdToBoundariesTable m_boundariesTable; + std::shared_ptr m_postcodesCountryInfoGetter; - std::string m_ukPostcodesPath; + std::string m_postcodesPath; + indexer::PostcodePointsDatasetType m_postcodesType; + uint32_t m_version = 0; }; } // namespace tests_support diff --git a/generator/generator_tool/generator_tool.cpp b/generator/generator_tool/generator_tool.cpp index 87e48a4be8..82af930723 100644 --- a/generator/generator_tool/generator_tool.cpp +++ b/generator/generator_tool/generator_tool.cpp @@ -18,7 +18,6 @@ #include "generator/platform_helpers.hpp" #include "generator/popular_places_section_builder.hpp" #include "generator/postcode_points_builder.hpp" -#include "generator/processor_factory.hpp" #include "generator/raw_generator.hpp" #include "generator/restriction_generator.hpp" #include "generator/road_access_generator.hpp" @@ -29,14 +28,10 @@ #include "generator/traffic_generator.hpp" #include "generator/transit_generator.hpp" #include "generator/transit_generator_experimental.hpp" -#include "generator/translator_factory.hpp" #include "generator/unpack_mwm.hpp" #include "generator/utils.hpp" #include "generator/wiki_url_dumper.hpp" -#include "routing/cross_mwm_ids.hpp" -#include "routing/speed_camera_prohibition.hpp" - #include "storage/country_parent_getter.hpp" #include "indexer/classificator_loader.hpp" @@ -55,12 +50,6 @@ #include "defines.hpp" -#include -#include -#include -#include -#include - #include namespace @@ -387,23 +376,13 @@ MAIN_WITH_ERROR_HANDLING([](int argc, char ** argv) if (!FLAGS_uk_postcodes_dataset.empty() || !FLAGS_us_postcodes_dataset.empty()) { - if (!countryParentGetter) - { - LOG(LCRITICAL, - ("Countries file is needed. Please set countries file name (countries.txt). " - "File must be located in data directory.")); - return EXIT_FAILURE; - } - - auto const topmostCountry = (*countryParentGetter)(country); bool res = true; - if (topmostCountry == "United Kingdom" && !FLAGS_uk_postcodes_dataset.empty()) + if (!FLAGS_uk_postcodes_dataset.empty() && strings::StartsWith(country, "UK_")) { res = indexer::BuildPostcodePoints(path, country, indexer::PostcodePointsDatasetType::UK, FLAGS_uk_postcodes_dataset, true /*forceRebuild*/); } - else if (topmostCountry == "United States of America" && - !FLAGS_us_postcodes_dataset.empty()) + else if (!FLAGS_us_postcodes_dataset.empty() && strings::StartsWith(country, "US_")) { res = indexer::BuildPostcodePoints(path, country, indexer::PostcodePointsDatasetType::US, FLAGS_us_postcodes_dataset, true /*forceRebuild*/); diff --git a/generator/postcode_points_builder.cpp b/generator/postcode_points_builder.cpp index 5f83ff7186..39692d527f 100644 --- a/generator/postcode_points_builder.cpp +++ b/generator/postcode_points_builder.cpp @@ -11,7 +11,6 @@ #include "platform/platform.hpp" -#include "coding/map_uint32_to_val.hpp" #include "coding/reader.hpp" #include "coding/reader_writer_ops.hpp" #include "coding/writer.hpp" @@ -26,14 +25,13 @@ #include "base/scope_guard.hpp" #include "base/string_utils.hpp" -#include #include -#include -#include #include #include "defines.hpp" +namespace indexer +{ namespace { struct FieldIndices @@ -44,32 +42,36 @@ struct FieldIndices size_t m_datasetCount = 0; }; -template +using ZipIndexValue = std::pair; + void GetPostcodes(std::string const & filename, storage::CountryId const & countryId, - FieldIndices const & fieldIndices, char separator, bool hasHeader, - std::function const & transformPostcode, - storage::CountryInfoGetter const & infoGetter, std::vector & valueMapping, - std::vector> & keyValuePairs) + FieldIndices const & fieldIndices, char const * separator, bool hasHeader, + storage::CountryInfoGetter const & infoGetter, + std::vector & valueMapping, std::vector & keyValuePairs) { - CHECK_LESS(fieldIndices.m_postcodeIndex, fieldIndices.m_datasetCount, ()); - CHECK_LESS(fieldIndices.m_latIndex, fieldIndices.m_datasetCount, ()); - CHECK_LESS(fieldIndices.m_longIndex, fieldIndices.m_datasetCount, ()); - std::ifstream data; - data.exceptions(std::fstream::failbit | std::fstream::badbit); - data.open(filename); - data.exceptions(std::fstream::badbit); + ASSERT(!filename.empty(), ()); + std::ifstream data(filename); + if (!data.is_open()) + { + LOG(LERROR, ("Can't open postcodes file:", filename)); + return; + } std::string line; - size_t index = 0; - if (hasHeader && !getline(data, line)) + if (hasHeader && !std::getline(data, line)) return; while (std::getline(data, line)) { - std::vector fields; - strings::ParseCSVRow(line, separator, fields); - CHECK_EQUAL(fields.size(), fieldIndices.m_datasetCount, (line)); + std::vector fields; + strings::Tokenize(std::string_view(line), separator, [&fields](std::string_view v) + { + strings::Trim(v, "\" "); + // Maybe empty, checks below should work for actual values. + fields.push_back(v); + }); + CHECK_GREATER_OR_EQUAL(fields.size(), fieldIndices.m_datasetCount, (line)); double lat; CHECK(strings::to_double(fields[fieldIndices.m_latIndex], lat), (line)); @@ -84,67 +86,46 @@ void GetPostcodes(std::string const & filename, storage::CountryId const & count if (std::find(countries.begin(), countries.end(), countryId) == countries.end()) continue; - auto postcode = fields[fieldIndices.m_postcodeIndex]; - if (!transformPostcode(postcode)) - continue; - - CHECK_EQUAL(valueMapping.size(), index, ()); + keyValuePairs.emplace_back(search::NormalizeAndSimplifyString(fields[fieldIndices.m_postcodeIndex]), + valueMapping.size()); valueMapping.push_back(p); - keyValuePairs.emplace_back(search::NormalizeAndSimplifyString(postcode), Value(index)); - ++index; } } -template void GetUKPostcodes(std::string const & filename, storage::CountryId const & countryId, storage::CountryInfoGetter const & infoGetter, - std::vector & valueMapping, std::vector> & keyValuePairs) + std::vector & valueMapping, std::vector & keyValuePairs) { - // Original dataset uses UK National Grid UTM coordinates. - // It was converted to WGS84 by https://pypi.org/project/OSGridConverter/. + // * Follow these steps to prepare GB dataset: https://github.com/osm-search/gb-postcode-data + // * Direct from Nominatim: https://nominatim.org/data/gb_postcodes.csv.gz + FieldIndices ukFieldIndices; ukFieldIndices.m_postcodeIndex = 0; ukFieldIndices.m_latIndex = 1; ukFieldIndices.m_longIndex = 2; ukFieldIndices.m_datasetCount = 3; - auto const transformUkPostcode = [](std::string & postcode) { - // UK postcodes formats are: aana naa, ana naa, an naa, ann naa, aan naa, aann naa. - - // Do not index outer postcodes. - if (postcode.size() < 5) - return false; - - // Space is skipped in dataset for |aana naa| and |aann naa| to make it fit 7 symbols in csv. - // Let's fix it here. - if (postcode.find(' ') == std::string::npos) - postcode.insert(static_cast(postcode.size() - 3), " "); - - return true; - }; - - GetPostcodes(filename, countryId, ukFieldIndices, ',' /* separator */, false /* hasHeader */, - transformUkPostcode, infoGetter, valueMapping, keyValuePairs); + GetPostcodes(filename, countryId, ukFieldIndices, "," /* separator */, true /* hasHeader */, + infoGetter, valueMapping, keyValuePairs); } -template void GetUSPostcodes(std::string const & filename, storage::CountryId const & countryId, storage::CountryInfoGetter const & infoGetter, - std::vector & valueMapping, std::vector> & keyValuePairs) + std::vector & valueMapping, std::vector & keyValuePairs) { - // Zip;City;State;Latitude;Longitude;Timezone;Daylight savings time flag;geopoint + // * Get data source from here: https://simplemaps.com/data/us-zips + // "zip","lat","lng","city","state_id","state_name", ... + // * From Nominatim (IDK the origins) https://nominatim.org/data/us_postcodes.csv.gz + FieldIndices usFieldIndices; usFieldIndices.m_postcodeIndex = 0; - usFieldIndices.m_latIndex = 3; - usFieldIndices.m_longIndex = 4; - usFieldIndices.m_datasetCount = 8; + usFieldIndices.m_latIndex = 1; + usFieldIndices.m_longIndex = 2; + usFieldIndices.m_datasetCount = 3; // actually, there are more fields, but doesn't matter here - auto const transformUsPostcode = [](std::string & postcode) { return true; }; - - std::vector> usPostcodesKeyValuePairs; - std::vector usPostcodesValueMapping; - GetPostcodes(filename, countryId, usFieldIndices, ';' /* separator */, true /* hasHeader */, - transformUsPostcode, infoGetter, valueMapping, keyValuePairs); + // US dataset may contain complex json values, but doesn't matter for parsing first 3 entries. + GetPostcodes(filename, countryId, usFieldIndices, "," /* separator */, true /* hasHeader */, + infoGetter, valueMapping, keyValuePairs); } bool BuildPostcodePointsImpl(FilesContainerR & container, storage::CountryId const & country, @@ -152,9 +133,6 @@ bool BuildPostcodePointsImpl(FilesContainerR & container, storage::CountryId con std::string const & tmpName, storage::CountryInfoGetter const & infoGetter, Writer & writer) { - using Key = strings::UniString; - using Value = Uint64IndexValue; - CHECK_EQUAL(writer.Pos(), 0, ()); search::PostcodePoints::Header header; @@ -165,7 +143,7 @@ bool BuildPostcodePointsImpl(FilesContainerR & container, storage::CountryId con header.m_trieOffset = base::asserted_cast(writer.Pos()); - std::vector> postcodesKeyValuePairs; + std::vector postcodesKeyValuePairs; std::vector valueMapping; switch (type) { @@ -185,8 +163,8 @@ bool BuildPostcodePointsImpl(FilesContainerR & container, storage::CountryId con { FileWriter tmpWriter(tmpName); - SingleValueSerializer serializer; - trie::Build>( + SingleValueSerializer serializer; + trie::Build( tmpWriter, serializer, postcodesKeyValuePairs); } @@ -218,8 +196,6 @@ bool BuildPostcodePointsImpl(FilesContainerR & container, storage::CountryId con } } // namespace -namespace indexer -{ bool BuildPostcodePointsWithInfoGetter(std::string const & path, storage::CountryId const & country, PostcodePointsDatasetType type, std::string const & datasetPath, bool forceRebuild, diff --git a/routing/routing_tests/mwm_hierarchy_test.cpp b/routing/routing_tests/mwm_hierarchy_test.cpp index 3b30e9e55b..c0067a79e5 100644 --- a/routing/routing_tests/mwm_hierarchy_test.cpp +++ b/routing/routing_tests/mwm_hierarchy_test.cpp @@ -19,6 +19,8 @@ UNIT_TEST(CountryParentGetter_Smoke) TEST_EQUAL(getter("Israel"), "Israel Region", ()); TEST_EQUAL(getter("Palestine"), "Palestine Region", ()); TEST_EQUAL(getter("Jerusalem"), "", ()); + TEST_EQUAL(getter("US_New York_New York"), "New York", ()); + TEST_EQUAL(getter("UK_England_West Midlands"), "United Kingdom", ()); } uint16_t GetCountryID(std::shared_ptr const & mwmIDs, std::string mwmName) diff --git a/search/search_integration_tests/postcode_points_tests.cpp b/search/search_integration_tests/postcode_points_tests.cpp index a2c85a04aa..7c264be125 100644 --- a/search/search_integration_tests/postcode_points_tests.cpp +++ b/search/search_integration_tests/postcode_points_tests.cpp @@ -15,30 +15,23 @@ #include "coding/point_coding.hpp" #include "base/file_name_utils.hpp" -#include "base/math.hpp" -#include "base/stl_helpers.hpp" -#include "base/string_utils.hpp" -#include -#include -#include -#include +namespace postcode_points_tests +{ using namespace generator::tests_support; using namespace platform::tests_support; using namespace search::tests_support; using namespace search; using namespace std; -namespace -{ class PostcodePointsTest : public SearchTest { }; -UNIT_CLASS_TEST(PostcodePointsTest, Smoke) +UNIT_CLASS_TEST(PostcodePointsTest, SmokeUK) { - string const countryName = "Wonderland"; + string const countryName = "United Kingdom"; Platform & platform = GetPlatform(); auto const & writableDir = platform.WritableDir(); @@ -46,22 +39,19 @@ UNIT_CLASS_TEST(PostcodePointsTest, Smoke) auto const postcodesRelativePath = base::JoinPath(writableDir, testFile); ScopedFile const osmScopedFile(testFile, + "header\n" "aa11 0bb, 1.0, 1.0\n" "aa11 1bb, 2.0, 2.0\n" - // Missing space. Postcode should be converted to |aa11 2bb| - // for index. - "aa112bb, 3.0, 3.0\n" - // Put here some wrong location to make sure outer postcode - // will be skipped in index and calculated from inners. - "aa11, 100.0, 1.0\n"); + "aa11 2bb, 3.0, 3.0\n" + ); auto infoGetter = std::make_shared(); - infoGetter->AddCountry(storage::CountryDef( - countryName, + infoGetter->AddCountry(storage::CountryDef(countryName, m2::RectD(mercator::FromLatLon(0.99, 0.99), mercator::FromLatLon(3.01, 3.01)))); - auto const id = BuildCountry(countryName, [&](TestMwmBuilder & builder) { - builder.SetUKPostcodesData(postcodesRelativePath, infoGetter); + auto const id = BuildCountry(countryName, [&](TestMwmBuilder & builder) + { + builder.SetPostcodesData(postcodesRelativePath, indexer::PostcodePointsDatasetType::UK, infoGetter); }); auto handle = m_dataSource.GetMwmHandleById(id); @@ -74,34 +64,65 @@ UNIT_CLASS_TEST(PostcodePointsTest, Smoke) vector points; p.Get(NormalizeAndSimplifyString("aa11 0bb"), points); TEST_EQUAL(points.size(), 1, ()); - TEST(base::AlmostEqualAbs(points[0], mercator::FromLatLon(1.0, 1.0), kMwmPointAccuracy), - ()); + TEST(base::AlmostEqualAbs(points[0], mercator::FromLatLon(1.0, 1.0), kMwmPointAccuracy), ()); } { vector points; p.Get(NormalizeAndSimplifyString("aa11 1bb"), points); TEST_EQUAL(points.size(), 1, ()); - TEST(base::AlmostEqualAbs(points[0], mercator::FromLatLon(2.0, 2.0), kMwmPointAccuracy), - ()); + TEST(base::AlmostEqualAbs(points[0], mercator::FromLatLon(2.0, 2.0), kMwmPointAccuracy), ()); } { vector points; p.Get(NormalizeAndSimplifyString("aa11 2bb"), points); TEST_EQUAL(points.size(), 1, ()); - TEST(base::AlmostEqualAbs(points[0], mercator::FromLatLon(3.0, 3.0), kMwmPointAccuracy), - ()); + TEST(base::AlmostEqualAbs(points[0], mercator::FromLatLon(3.0, 3.0), kMwmPointAccuracy), ()); } { vector points; p.Get(NormalizeAndSimplifyString("aa11"), points); TEST_EQUAL(points.size(), 3, ()); sort(points.begin(), points.end()); - TEST(base::AlmostEqualAbs(points[0], mercator::FromLatLon(1.0, 1.0), kMwmPointAccuracy), - ()); - TEST(base::AlmostEqualAbs(points[1], mercator::FromLatLon(2.0, 2.0), kMwmPointAccuracy), - ()); - TEST(base::AlmostEqualAbs(points[2], mercator::FromLatLon(3.0, 3.0), kMwmPointAccuracy), - ()); + TEST(base::AlmostEqualAbs(points[0], mercator::FromLatLon(1.0, 1.0), kMwmPointAccuracy), ()); + TEST(base::AlmostEqualAbs(points[1], mercator::FromLatLon(2.0, 2.0), kMwmPointAccuracy), ()); + TEST(base::AlmostEqualAbs(points[2], mercator::FromLatLon(3.0, 3.0), kMwmPointAccuracy), ()); + } +} + +UNIT_CLASS_TEST(PostcodePointsTest, SmokeUS) +{ + string const countryName = "United States of America"; + + Platform & platform = GetPlatform(); + auto const & writableDir = platform.WritableDir(); + string const testFile = "postcodes.csv"; + auto const postcodesRelativePath = base::JoinPath(writableDir, testFile); + + ScopedFile const osmScopedFile(testFile, + "header\n" + R"("00601","18.18027","-66.75266","Adjuntas","PR","Puerto Rico","TRUE","","16834","100.9","72001","Adjuntas","{""72001"": 98.74, ""72141"": 1.26}","Adjuntas|Utuado","72001|72141","FALSE","FALSE","America/Puerto_Rico")" + ); + + auto infoGetter = std::make_shared(); + infoGetter->AddCountry(storage::CountryDef(countryName, + m2::RectD(mercator::FromLatLon(0, -180), mercator::FromLatLon(90, 0)))); + + auto const id = BuildCountry(countryName, [&](TestMwmBuilder & builder) + { + builder.SetPostcodesData(postcodesRelativePath, indexer::PostcodePointsDatasetType::UK, infoGetter); + }); + + auto handle = m_dataSource.GetMwmHandleById(id); + auto value = handle.GetValue(); + CHECK(value, ()); + TEST(value->m_cont.IsExist(POSTCODE_POINTS_FILE_TAG), ()); + + PostcodePoints p(*value); + { + vector points; + p.Get(NormalizeAndSimplifyString("00601"), points); + TEST_EQUAL(points.size(), 1, ()); + TEST(base::AlmostEqualAbs(points[0], mercator::FromLatLon(18.18027, -66.75266), kMwmPointAccuracy), ()); } } @@ -116,6 +137,7 @@ UNIT_CLASS_TEST(PostcodePointsTest, SearchPostcode) // Use the same latitude for easier center calculation. ScopedFile const osmScopedFile(testFile, + "header\n" "BA6 7JP, 5.0, 4.0\n" "BA6 8JP, 5.0, 6.0\n"); @@ -124,8 +146,9 @@ UNIT_CLASS_TEST(PostcodePointsTest, SearchPostcode) countryName, m2::RectD(mercator::FromLatLon(3.0, 3.0), mercator::FromLatLon(7.0, 7.0)))); - auto const id = BuildCountry(countryName, [&](TestMwmBuilder & builder) { - builder.SetUKPostcodesData(postcodesRelativePath, infoGetter); + auto const id = BuildCountry(countryName, [&](TestMwmBuilder & builder) + { + builder.SetPostcodesData(postcodesRelativePath, indexer::PostcodePointsDatasetType::UK, infoGetter); }); auto test = [&](string const & query, m2::PointD const & expected) { @@ -161,6 +184,7 @@ UNIT_CLASS_TEST(PostcodePointsTest, SearchStreetWithPostcode) ScopedFile const osmScopedFile( testFile, + "header\n" "AA5 6KL, 4.0, 4.0\n" "BB7 8MN, 6.0, 6.0\n" "XX6 7KL, 4.0, 6.0\n" @@ -207,8 +231,10 @@ UNIT_CLASS_TEST(PostcodePointsTest, SearchStreetWithPostcode) TestStreet streetY(vector{mercator::FromLatLon(5.99, 3.99), mercator::FromLatLon(6.01, 4.01)}, "Main street", "en"); - auto const id = BuildCountry(countryName, [&](TestMwmBuilder & builder) { - builder.SetUKPostcodesData(postcodesRelativePath, infoGetter); + auto const id = BuildCountry(countryName, [&](TestMwmBuilder & builder) + { + builder.SetPostcodesData(postcodesRelativePath, indexer::PostcodePointsDatasetType::UK, infoGetter); + builder.Add(streetA); builder.Add(houseA); builder.Add(streetB); @@ -233,4 +259,5 @@ UNIT_CLASS_TEST(PostcodePointsTest, SearchStreetWithPostcode) test("Main street XX6 7KL ", streetX); test("Main street YY8 9MN ", streetY); } -} // namespace + +} // namespace postcode_points_tests diff --git a/tools/python/maps_generator/generator/env.py b/tools/python/maps_generator/generator/env.py index 989afcd6d6..5cef2e3909 100644 --- a/tools/python/maps_generator/generator/env.py +++ b/tools/python/maps_generator/generator/env.py @@ -311,14 +311,6 @@ class PathProvider: def food_translations_path(self) -> AnyStr: return os.path.join(self.intermediate_data_path, "translations_food.json") - @property - def uk_postcodes_path(self) -> AnyStr: - return os.path.join(self.intermediate_data_path, "uk_postcodes") - - @property - def us_postcodes_path(self) -> AnyStr: - return os.path.join(self.intermediate_data_path, "us_postcodes") - @property def cities_boundaries_path(self) -> AnyStr: return os.path.join(self.intermediate_data_path, "cities_boundaries.bin") diff --git a/tools/python/maps_generator/generator/stages_declaration.py b/tools/python/maps_generator/generator/stages_declaration.py index 15192c7f3b..f1240c7811 100644 --- a/tools/python/maps_generator/generator/stages_declaration.py +++ b/tools/python/maps_generator/generator/stages_declaration.py @@ -222,10 +222,6 @@ class StageMwm(Stage): @country_stage -@depends_from_internal( - D(settings.UK_POSTCODES_URL, PathProvider.uk_postcodes_path, "p"), - D(settings.US_POSTCODES_URL, PathProvider.us_postcodes_path, "p"), -) class StageIndex(Stage): def apply(self, env: Env, country, **kwargs): if country == WORLD_NAME: @@ -233,13 +229,12 @@ class StageIndex(Stage): elif country == WORLD_COASTS_NAME: steps.step_coastline_index(env, country, **kwargs) else: - if env.production: - kwargs.update( - { - "uk_postcodes_dataset": env.paths.uk_postcodes_path, - "us_postcodes_dataset": env.paths.us_postcodes_path, - } - ) + kwargs.update( + { + "uk_postcodes_dataset": settings.UK_POSTCODES_URL, + "us_postcodes_dataset": settings.US_POSTCODES_URL, + } + ) steps.step_index(env, country, **kwargs) diff --git a/tools/python/maps_generator/var/etc/map_generator.ini.default b/tools/python/maps_generator/var/etc/map_generator.ini.default index 1980e5f528..7f337affd3 100644 --- a/tools/python/maps_generator/var/etc/map_generator.ini.default +++ b/tools/python/maps_generator/var/etc/map_generator.ini.default @@ -76,6 +76,8 @@ NEED_BUILD_WORLD_ROADS: false # FOOD_TRANSLATIONS_URL: # SRTM_PATH: # ISOLINES_PATH: + +# Local path (not url!) to .csv files. # UK_POSTCODES_URL: # US_POSTCODES_URL: -- 2.45.3 From 734d23969a12cac94cf64dd85eeb3cf38f9039fc Mon Sep 17 00:00:00 2001 From: Viktor Govako Date: Sat, 18 May 2024 13:14:29 -0300 Subject: [PATCH 26/36] [search] Update postcode search. Signed-off-by: Viktor Govako --- base/base_tests/string_utils_test.cpp | 15 +++++++--- base/string_utils.cpp | 20 +++++++++++-- base/string_utils.hpp | 3 ++ .../indexer_tests/postcodes_matcher_tests.cpp | 30 +++++++++---------- search/geocoder.cpp | 23 +++++++++----- search/intermediate_result.cpp | 15 +++++----- search/postcode_points.cpp | 30 +++++++++++-------- search/processor.cpp | 9 ++++-- 8 files changed, 92 insertions(+), 53 deletions(-) diff --git a/base/base_tests/string_utils_test.cpp b/base/base_tests/string_utils_test.cpp index f0b0b071b8..bddeb2366f 100644 --- a/base/base_tests/string_utils_test.cpp +++ b/base/base_tests/string_utils_test.cpp @@ -6,11 +6,7 @@ #include #include #include -#include -#include #include -#include -#include #include #include #include @@ -1279,3 +1275,14 @@ UNIT_TEST(Trim) strings::Trim(v, "a"); TEST(v.empty(), ()); } + +UNIT_TEST(ToLower_ToUpper) +{ + std::string s = "AbC0;9z"; + + strings::AsciiToLower(s); + TEST_EQUAL(s, "abc0;9z", ()); + + strings::AsciiToUpper(s); + TEST_EQUAL(s, "ABC0;9Z", ()); +} diff --git a/base/string_utils.cpp b/base/string_utils.cpp index c664960199..01e7d245be 100644 --- a/base/string_utils.cpp +++ b/base/string_utils.cpp @@ -64,6 +64,8 @@ bool ToReal(char const * start, T & result) } // namespace +UniString UniString::kSpace = MakeUniString(" "); + bool UniString::IsEqualAscii(char const * s) const { return (size() == strlen(s) && std::equal(begin(), end(), s)); @@ -207,8 +209,8 @@ void AsciiToLower(std::string & s) std::transform(s.begin(), s.end(), s.begin(), [](char in) { char constexpr diff = 'z' - 'Z'; - static_assert(diff == 'a' - 'A', ""); - static_assert(diff > 0, ""); + static_assert(diff == 'a' - 'A'); + static_assert(diff > 0); if (in >= 'A' && in <= 'Z') return char(in + diff); @@ -216,6 +218,20 @@ void AsciiToLower(std::string & s) }); } +void AsciiToUpper(std::string & s) +{ + std::transform(s.begin(), s.end(), s.begin(), [](char in) + { + char constexpr diff = 'z' - 'Z'; + static_assert(diff == 'a' - 'A'); + static_assert(diff > 0); + + if (in >= 'a' && in <= 'z') + return char(in - diff); + return in; + }); +} + void Trim(std::string & s) { boost::trim_if(s, ::isspace); diff --git a/base/string_utils.hpp b/base/string_utils.hpp index 74398480b8..27c666b9d0 100644 --- a/base/string_utils.hpp +++ b/base/string_utils.hpp @@ -29,6 +29,8 @@ class UniString : public buffer_vector using BaseT = buffer_vector; public: + static UniString kSpace; + using value_type = UniChar; UniString() = default; @@ -101,6 +103,7 @@ void NormalizeDigits(UniString & us); size_t CountNormLowerSymbols(UniString const & s, UniString const & lowStr); void AsciiToLower(std::string & s); +void AsciiToUpper(std::string & s); // All triming functions return a reference on an input string. // They do in-place trimming. In general, it does not work for any unicode whitespace except diff --git a/indexer/indexer_tests/postcodes_matcher_tests.cpp b/indexer/indexer_tests/postcodes_matcher_tests.cpp index fcda954077..3d7a23846a 100644 --- a/indexer/indexer_tests/postcodes_matcher_tests.cpp +++ b/indexer/indexer_tests/postcodes_matcher_tests.cpp @@ -1,22 +1,23 @@ -#include "../../testing/testing.hpp" +#include "testing/testing.hpp" #include "indexer/postcodes_matcher.hpp" -#include "indexer/search_delimiters.hpp" -#include "indexer/search_string_utils.hpp" -#include "base/stl_helpers.hpp" -#include "base/string_utils.hpp" -using namespace strings; +namespace postcodes_matcher_test +{ +using namespace search; -namespace search -{ -namespace v2 -{ -namespace -{ UNIT_TEST(PostcodesMatcher_Smoke) { + /// @todo We are not _complete_ here, because G4 is also a postcode prefix (Glasgow, Scotland) + /// like BN1 or BN3 (Brighton). + TEST(!LooksLikePostcode("G4", false /* handleAsPrefix */), ()); + TEST(LooksLikePostcode("G4", true /* handleAsPrefix */), ()); + TEST(LooksLikePostcode("BN1", false /* handleAsPrefix */), ()); + TEST(LooksLikePostcode("BN3 ", false /* handleAsPrefix */), ()); + TEST(LooksLikePostcode("BN1", true /* handleAsPrefix */), ()); + TEST(LooksLikePostcode("BN3 ", true /* handleAsPrefix */), ()); + TEST(LooksLikePostcode("141701", false /* handleAsPrefix */), ()); TEST(LooksLikePostcode("141", true /* handleAsPrefix */), ()); TEST(LooksLikePostcode("BA6 8JP", true /* handleAsPrefix */), ()); @@ -37,6 +38,5 @@ UNIT_TEST(PostcodesMatcher_Smoke) TEST(!LooksLikePostcode("москва", true /* handleAsPrefix */), ()); TEST(!LooksLikePostcode("39 с 79", true /* handleAsPrefix */), ()); } -} // namespace -} // namespace v2 -} // namespace search + +} // namespace postcodes_matcher_test diff --git a/search/geocoder.cpp b/search/geocoder.cpp index 953fafad73..738ad403ce 100644 --- a/search/geocoder.cpp +++ b/search/geocoder.cpp @@ -72,7 +72,6 @@ size_t constexpr kPostcodesRectsCacheSize = 10; size_t constexpr kSuburbsRectsCacheSize = 10; size_t constexpr kLocalityRectsCacheSize = 10; -UniString const kUniSpace(MakeUniString(" ")); struct ScopedMarkTokens { @@ -685,7 +684,7 @@ void Geocoder::InitLayer(Model::Type type, TokenRange const & tokenRange, Featur layer.m_type = type; layer.m_tokenRange = tokenRange; - JoinQueryTokens(m_params, layer.m_tokenRange, kUniSpace /* sep */, layer.m_subQuery); + JoinQueryTokens(m_params, layer.m_tokenRange, UniString::kSpace /* sep */, layer.m_subQuery); layer.m_lastTokenIsPrefix = !layer.m_tokenRange.Empty() && m_params.IsPrefixToken(layer.m_tokenRange.End() - 1); } @@ -1165,20 +1164,28 @@ void Geocoder::WithPostcodes(BaseContext & ctx, Fn && fn) TokenRange const tokenRange(startToken, endToken); + // Find features by exact postcode match from OSM data. auto postcodes = RetrievePostcodeFeatures(*m_context, TokenSlice(m_params, tokenRange)); - if (m_context->m_value.m_cont.IsExist(POSTCODE_POINTS_FILE_TAG)) + + // Get _around postcode_ features from additional _external postcodes_ section. + // Do not emit _around postcode_ only features if we don't have some other tokens to match (avoid lags). + if (tokenRange.Size() < numTokens && m_context->m_value.m_cont.IsExist(POSTCODE_POINTS_FILE_TAG)) { auto & postcodePoints = m_postcodePointsCache.Get(*m_context); UniString postcodeQuery; - JoinQueryTokens(m_params, tokenRange, kUniSpace /* sep */, postcodeQuery); + JoinQueryTokens(m_params, tokenRange, UniString::kSpace /* sep */, postcodeQuery); vector points; postcodePoints.Get(postcodeQuery, points); + + // PostcodePoints::Get returns many points for "BN1" or one point for "BN1 3LJ". + // Do aggregate rects for a _wide_ postcode prefix match. + m2::RectD rect; for (auto const & p : points) - { - auto const rect = mercator::RectByCenterXYAndOffset(p, postcodePoints.GetRadius()); - postcodes = postcodes.Union(RetrieveGeometryFeatures(*m_context, rect, RectId::Postcode)); - } + rect.Add(mercator::RectByCenterXYAndOffset(p, postcodePoints.GetRadius())); + + postcodes = postcodes.Union(RetrieveGeometryFeatures(*m_context, rect, RectId::Postcode)); } + SCOPE_GUARD(cleanup, [&]() { m_postcodes.Clear(); }); if (!postcodes.IsEmpty()) diff --git a/search/intermediate_result.cpp b/search/intermediate_result.cpp index 82e7a01ea5..2c9a7a8219 100644 --- a/search/intermediate_result.cpp +++ b/search/intermediate_result.cpp @@ -4,13 +4,11 @@ #include "storage/country_info_getter.hpp" -#include "indexer/categories_holder.hpp" #include "indexer/classificator.hpp" #include "indexer/feature.hpp" #include "indexer/feature_algo.hpp" #include "indexer/feature_utils.hpp" #include "indexer/ftypes_matcher.hpp" -#include "indexer/map_object.hpp" #include "indexer/road_shields_parser.hpp" #include "platform/measurement_utils.hpp" @@ -183,13 +181,14 @@ RankerResult::RankerResult(FeatureType & ft, std::string const & fileName) RankerResult::RankerResult(double lat, double lon) : m_str("(" + measurement_utils::FormatLatLon(lat, lon) + ")"), m_resultType(Type::LatLon) { - m_region.SetParams(string(), mercator::FromLatLon(lat, lon)); + m_region.SetParams({}, mercator::FromLatLon(lat, lon)); } RankerResult::RankerResult(m2::PointD const & coord, string_view postcode) : m_str(postcode), m_resultType(Type::Postcode) { - m_region.SetParams(string(), coord); + strings::AsciiToUpper(m_str); + m_region.SetParams({}, coord); } bool RankerResult::GetCountryId(storage::CountryInfoGetter const & infoGetter, uint32_t ftype, @@ -257,11 +256,11 @@ void FillDetails(FeatureType & ft, Result::Details & details) return; std::string_view airportIata = ft.GetMetadata(feature::Metadata::FMD_AIRPORT_IATA); - + std::string brand {ft.GetMetadata(feature::Metadata::FMD_BRAND)}; if (!brand.empty()) brand = platform::GetLocalizedBrandName(brand); - + /// @todo Avoid temporary string when OpeningHours (boost::spirit) will allow string_view. std::string const openHours(ft.GetMetadata(feature::Metadata::FMD_OPEN_HOURS)); if (!openHours.empty()) @@ -314,7 +313,7 @@ void FillDetails(FeatureType & ft, Result::Details & details) description += feature::kFieldsSeparator; description += sv; }; - + append(stars); append(airportIata); append(roadShield); @@ -323,7 +322,7 @@ void FillDetails(FeatureType & ft, Result::Details & details) append(cuisine); append(recycling); append(fee); - + details.m_description = std::move(description); details.m_isInitialized = true; diff --git a/search/postcode_points.cpp b/search/postcode_points.cpp index 5bea52afc5..f93c9ce97c 100644 --- a/search/postcode_points.cpp +++ b/search/postcode_points.cpp @@ -6,8 +6,6 @@ #include "coding/reader_wrapper.hpp" -#include "geometry/mercator.hpp" - #include "base/checked_cast.hpp" #include "base/string_utils.hpp" @@ -16,10 +14,12 @@ #include "defines.hpp" -using namespace std; namespace search { +using namespace std; +using namespace strings; + void PostcodePoints::Header::Read(Reader & reader) { NonOwningReaderSource source(reader); @@ -61,7 +61,7 @@ PostcodePoints::PostcodePoints(MwmValue const & value) m_radius = kPostcodeRadiusMultiplier * 0.5 * sqrt(area / count); } -void PostcodePoints::Get(strings::UniString const & postcode, bool recursive, +void PostcodePoints::Get(UniString const & postcode, bool recursive, vector & points) const { if (!m_root || !m_points || !m_trieSubReader || !m_pointsSubReader || postcode.empty()) @@ -72,9 +72,9 @@ void PostcodePoints::Get(strings::UniString const & postcode, bool recursive, while (postcodeIt != postcode.end()) { - auto it = find_if(trieIt->m_edges.begin(), trieIt->m_edges.end(), [&](auto const & edge) { - return strings::StartsWith(postcodeIt, postcode.end(), edge.m_label.begin(), - edge.m_label.end()); + auto it = find_if(trieIt->m_edges.begin(), trieIt->m_edges.end(), [&](auto const & edge) + { + return StartsWith(postcodeIt, postcode.end(), edge.m_label.begin(), edge.m_label.end()); }); if (it == trieIt->m_edges.end()) return; @@ -87,7 +87,8 @@ void PostcodePoints::Get(strings::UniString const & postcode, bool recursive, return; vector indexes; - trieIt->m_values.ForEach([&indexes](auto const & v) { + trieIt->m_values.ForEach([&indexes](auto const & v) + { indexes.push_back(base::asserted_cast(v.m_featureId)); }); @@ -95,10 +96,11 @@ void PostcodePoints::Get(strings::UniString const & postcode, bool recursive, { trie::ForEachRef( *trieIt, - [&indexes](auto const & /* s */, auto const & v) { + [&indexes](auto const & /* s */, auto const & v) + { indexes.push_back(base::asserted_cast(v.m_featureId)); }, - strings::UniString{}); + UniString{}); } points.resize(indexes.size()); @@ -106,15 +108,17 @@ void PostcodePoints::Get(strings::UniString const & postcode, bool recursive, CHECK(m_points->Get(indexes[i], points[i]), ()); } -void PostcodePoints::Get(strings::UniString const & postcode, vector & points) const +void PostcodePoints::Get(UniString const & postcode, vector & points) const { points.clear(); + + // Do exact match. Get(postcode, false /* recursive */, points); if (!points.empty()) return; - auto static const space = strings::MakeUniString(" "); - Get(postcode + space, true /* recursive */, points); + // Special process for UK(GB) postcodes where prefix (before a space) means _wide_ range. + Get(postcode + UniString::kSpace, true /* recursive */, points); } PostcodePoints & PostcodePointsCache::Get(MwmContext const & context) diff --git a/search/processor.cpp b/search/processor.cpp index e4076232c1..7b2a0ac8aa 100644 --- a/search/processor.cpp +++ b/search/processor.cpp @@ -770,12 +770,14 @@ void Processor::SearchPostcode() string_view query(m_query.m_query); strings::Trim(query); + /// @todo So, "G4 " now doesn't match UK (Glasgow) postcodes as prefix :) if (!LooksLikePostcode(query, !m_query.m_prefix.empty())) return; vector> infos; m_dataSource.GetMwmsInfo(infos); + auto const normQuery = NormalizeAndSimplifyString(query); for (auto const & info : infos) { auto handle = m_dataSource.GetMwmHandleById(MwmSet::MwmId(info)); @@ -785,10 +787,10 @@ void Processor::SearchPostcode() if (!value.m_cont.IsExist(POSTCODE_POINTS_FILE_TAG)) continue; + /// @todo Well, ok for now, but we do only full or "prefix-rect" match w/o possible errors, with only one result. PostcodePoints postcodes(value); - vector points; - postcodes.Get(NormalizeAndSimplifyString(query), points); + postcodes.Get(normQuery, points); if (points.empty()) continue; @@ -797,8 +799,9 @@ void Processor::SearchPostcode() r.Add(p); m_emitter.AddResultNoChecks(m_ranker.MakeResult( - RankerResult(r.Center(), query), true /* needAddress */, false /* needHighlighting */)); + RankerResult(r.Center(), query), true /* needAddress */, true /* needHighlighting */)); m_emitter.Emit(); + return; } } -- 2.45.3 From 2f1f05af8bb356e9dc5cc883f2efd74ee60d7dae Mon Sep 17 00:00:00 2001 From: Viktor Govako Date: Sat, 18 May 2024 13:51:37 -0300 Subject: [PATCH 27/36] [search] Show "postal_code" string in search result UI. Signed-off-by: Viktor Govako --- .../main/cpp/app/organicmaps/SearchEngine.cpp | 5 +- .../CarPlay/MWMCarPlaySearchResultObject.mm | 5 +- .../Search/TableView/MWMSearchCommonCell.mm | 7 +-- .../TableView/MWMSearchTableViewController.mm | 3 - qt/search_panel.cpp | 57 ++++++++++++------- qt/search_panel.hpp | 7 ++- search/result.cpp | 28 +++++---- search/result.hpp | 4 +- 8 files changed, 65 insertions(+), 51 deletions(-) diff --git a/android/app/src/main/cpp/app/organicmaps/SearchEngine.cpp b/android/app/src/main/cpp/app/organicmaps/SearchEngine.cpp index 0532215dc5..a66019d449 100644 --- a/android/app/src/main/cpp/app/organicmaps/SearchEngine.cpp +++ b/android/app/src/main/cpp/app/organicmaps/SearchEngine.cpp @@ -106,12 +106,11 @@ jobject ToJavaResult(Result const & result, search::ProductInfo const & productI jni::TScopedLocalRef featureId(env, usermark_helper::CreateFeatureId(env, isFeature ? result.GetFeatureID() : kEmptyFeatureId)); - std::string const localizedType = isFeature ? result.GetLocalizedFeatureType() : ""; - jni::TScopedLocalRef featureType(env, jni::ToJavaString(env, localizedType)); + jni::TScopedLocalRef featureType(env, jni::ToJavaString(env, result.GetLocalizedFeatureType())); jni::TScopedLocalRef address(env, jni::ToJavaString(env, result.GetAddress())); jni::TScopedLocalRef dist(env, ToJavaDistance(env, distance)); - jni::TScopedLocalRef description(env, jni::ToJavaString(env, isFeature ? result.GetFeatureDescription() : "")); + jni::TScopedLocalRef description(env, jni::ToJavaString(env, result.GetFeatureDescription())); jni::TScopedLocalRef desc(env, env->NewObject(g_descriptionClass, g_descriptionConstructor, featureId.get(), featureType.get(), address.get(), diff --git a/iphone/Maps/Classes/CarPlay/MWMCarPlaySearchResultObject.mm b/iphone/Maps/Classes/CarPlay/MWMCarPlaySearchResultObject.mm index 93e39fc0d0..05d9d172db 100644 --- a/iphone/Maps/Classes/CarPlay/MWMCarPlaySearchResultObject.mm +++ b/iphone/Maps/Classes/CarPlay/MWMCarPlaySearchResultObject.mm @@ -27,10 +27,7 @@ MWMSearchItemType type = [MWMSearch resultTypeWithRow:row]; if (type == MWMSearchItemTypeRegular) { auto const & result = [MWMSearch resultWithContainerIndex:containerIndex]; - NSString *localizedTypeName = @""; - if (result.GetResultType() == search::Result::Type::Feature) - localizedTypeName = @(result.GetLocalizedFeatureType().c_str()); - + NSString *localizedTypeName = @(result.GetLocalizedFeatureType().c_str()); self.title = result.GetString().empty() ? localizedTypeName : @(result.GetString().c_str()); self.address = @(result.GetAddress().c_str()); auto const pivot = result.GetFeatureCenter(); diff --git a/iphone/Maps/UI/Search/TableView/MWMSearchCommonCell.mm b/iphone/Maps/UI/Search/TableView/MWMSearchCommonCell.mm index 987c5701dd..44cdcc2e00 100644 --- a/iphone/Maps/UI/Search/TableView/MWMSearchCommonCell.mm +++ b/iphone/Maps/UI/Search/TableView/MWMSearchCommonCell.mm @@ -31,11 +31,8 @@ self.locationLabel.text = @(result.GetAddress().c_str()); [self.locationLabel sizeToFit]; - - if (result.GetResultType() == search::Result::Type::Feature) - self.infoLabel.text = @(result.GetFeatureDescription().c_str()); - else - self.infoLabel.text = @(""); + + self.infoLabel.text = @(result.GetFeatureDescription().c_str()); CLLocation * lastLocation = [MWMLocationManager lastLocation]; double distanceInMeters = 0.0; diff --git a/iphone/Maps/UI/Search/TableView/MWMSearchTableViewController.mm b/iphone/Maps/UI/Search/TableView/MWMSearchTableViewController.mm index d493995915..1998f9bf02 100644 --- a/iphone/Maps/UI/Search/TableView/MWMSearchTableViewController.mm +++ b/iphone/Maps/UI/Search/TableView/MWMSearchTableViewController.mm @@ -8,9 +8,6 @@ namespace { NSString *GetLocalizedTypeName(search::Result const &result) { - if (result.GetResultType() != search::Result::Type::Feature) - return @""; - return @(result.GetLocalizedFeatureType().c_str()); } } diff --git a/qt/search_panel.cpp b/qt/search_panel.cpp index 048975c1a2..e8bb0c4e41 100644 --- a/qt/search_panel.cpp +++ b/qt/search_panel.cpp @@ -6,8 +6,6 @@ #include "map/bookmark_manager.hpp" #include "map/framework.hpp" -#include "platform/platform.hpp" - #include "base/assert.hpp" #include @@ -86,9 +84,9 @@ SearchPanel::SearchPanel(DrawWidget * drawWidget, QWidget * parent) namespace { -QTableWidgetItem * CreateItem(QString const & s) +QTableWidgetItem * CreateItem(std::string const & s) { - QTableWidgetItem * item = new QTableWidgetItem(s); + QTableWidgetItem * item = new QTableWidgetItem(QString::fromStdString(s)); item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); return item; } @@ -104,7 +102,7 @@ void SearchPanel::ClearResults() { ClearTable(); m_results.Clear(); - m_pDrawWidget->GetFramework().GetBookmarkManager().GetEditSession().ClearGroup(UserMark::Type::SEARCH); + GetFramework().GetBookmarkManager().GetEditSession().ClearGroup(UserMark::Type::SEARCH); } void SearchPanel::StartBusyIndicator() @@ -153,16 +151,29 @@ void SearchPanel::OnEverywhereSearchResults(uint64_t timestamp, search::Results int const rowCount = m_pTable->rowCount(); m_pTable->insertRow(rowCount); m_pTable->setCellWidget(rowCount, 1, new QLabel(strHigh)); - m_pTable->setItem(rowCount, 2, CreateItem(QString::fromStdString(res.GetAddress()))); + m_pTable->setItem(rowCount, 2, CreateItem(res.GetAddress())); - if (res.GetResultType() == search::Result::Type::Feature) + bool showDistance = true; + switch (res.GetResultType()) { - m_pTable->setItem(rowCount, 0, CreateItem(QString::fromStdString(res.GetLocalizedFeatureType()))); - m_pTable->setItem(rowCount, 3, CreateItem(QString::fromStdString(m_pDrawWidget->GetDistance(res)))); + case search::Result::Type::SuggestFromFeature: + case search::Result::Type::PureSuggest: + showDistance = false; + break; + case search::Result::Type::Feature: + case search::Result::Type::Postcode: + m_pTable->setItem(rowCount, 0, CreateItem(res.GetLocalizedFeatureType())); + break; + case search::Result::Type::LatLon: + m_pTable->setItem(rowCount, 0, CreateItem("LatLon")); + break; } + + if (showDistance) + m_pTable->setItem(rowCount, 3, CreateItem(m_pDrawWidget->GetDistance(res))); } - m_pDrawWidget->GetFramework().FillSearchResultsMarks(true /* clear */, m_results); + GetFramework().FillSearchResultsMarks(true /* clear */, m_results); if (m_results.IsEndMarker()) StopBusyIndicator(); @@ -177,8 +188,8 @@ bool SearchPanel::Try3dModeCmd(std::string const & str) if (!is3dModeOn && !is3dBuildingsOn && !is3dModeOff) return false; - m_pDrawWidget->GetFramework().Save3dMode(is3dModeOn || is3dBuildingsOn, is3dBuildingsOn); - m_pDrawWidget->GetFramework().Allow3dMode(is3dModeOn || is3dBuildingsOn, is3dBuildingsOn); + GetFramework().Save3dMode(is3dModeOn || is3dBuildingsOn, is3dBuildingsOn); + GetFramework().Allow3dMode(is3dModeOn || is3dBuildingsOn, is3dBuildingsOn); return true; } @@ -192,8 +203,8 @@ bool SearchPanel::TryTrafficSimplifiedColorsCmd(std::string const & str) return false; bool const isSimplified = simplifiedMode; - m_pDrawWidget->GetFramework().GetTrafficManager().SetSimplifiedColorScheme(isSimplified); - m_pDrawWidget->GetFramework().SaveTrafficSimplifiedColors(isSimplified); + GetFramework().GetTrafficManager().SetSimplifiedColorScheme(isSimplified); + GetFramework().SaveTrafficSimplifiedColors(isSimplified); return true; } @@ -228,7 +239,7 @@ void SearchPanel::OnSearchTextChanged(QString const & str) if (normalized.empty()) { - m_pDrawWidget->GetFramework().GetSearchAPI().CancelAllSearches(); + GetFramework().GetSearchAPI().CancelAllSearches(); // hide X button m_pClearButton->setVisible(false); @@ -251,7 +262,7 @@ void SearchPanel::OnSearchTextChanged(QString const & str) } }; - if (m_pDrawWidget->GetFramework().GetSearchAPI().SearchEverywhere(std::move(params))) + if (GetFramework().GetSearchAPI().SearchEverywhere(std::move(params))) StartBusyIndicator(); } else if (m_mode == Mode::Viewport) @@ -273,12 +284,12 @@ void SearchPanel::OnSearchTextChanged(QString const & str) // clearing the table would require additional care (or, most likely, we would need a better // API). This is similar to the Android and iOS clients where we do not show the list of // results in the viewport search mode. - m_pDrawWidget->GetFramework().FillSearchResultsMarks(true /* clear */, results); + GetFramework().FillSearchResultsMarks(true /* clear */, results); StopBusyIndicator(); } }; - m_pDrawWidget->GetFramework().GetSearchAPI().SearchInViewport(std::move(params)); + GetFramework().GetSearchAPI().SearchInViewport(std::move(params)); } } @@ -321,13 +332,13 @@ void SearchPanel::OnSearchPanelItemClicked(int row, int) else { // center viewport on clicked item - m_pDrawWidget->GetFramework().ShowSearchResult(m_results[row]); + GetFramework().ShowSearchResult(m_results[row]); } } void SearchPanel::hideEvent(QHideEvent *) { - m_pDrawWidget->GetFramework().GetSearchAPI().CancelSearch(search::Mode::Everywhere); + GetFramework().GetSearchAPI().CancelSearch(search::Mode::Everywhere); } void SearchPanel::OnAnimationTimer() @@ -347,4 +358,10 @@ void SearchPanel::OnClearButton() { m_pEditor->setText(""); } + +Framework & SearchPanel::GetFramework() const +{ + return m_pDrawWidget->GetFramework(); +} + } // namespace qt diff --git a/qt/search_panel.hpp b/qt/search_panel.hpp index 41aaa6907d..6878ce9fa5 100644 --- a/qt/search_panel.hpp +++ b/qt/search_panel.hpp @@ -5,8 +5,6 @@ #include "base/thread_checker.hpp" -#include - #include #include #include @@ -17,6 +15,8 @@ class QPushButton; class QTableWidget; class QTimer; +class Framework; + namespace qt { class DrawWidget; @@ -68,5 +68,8 @@ private slots: bool Try3dModeCmd(std::string const & str); bool TryTrafficSimplifiedColorsCmd(std::string const & str); + +private: + Framework & GetFramework() const; }; } // namespace qt diff --git a/search/result.cpp b/search/result.cpp index a13674b994..80d8a115b8 100644 --- a/search/result.cpp +++ b/search/result.cpp @@ -87,24 +87,30 @@ std::string GetLocalizedTypeName(uint32_t type) std::string Result::GetLocalizedFeatureType() const { - ASSERT_EQUAL(m_resultType, Type::Feature, ()); - return GetLocalizedTypeName(m_mainType); + switch (m_resultType) + { + case Type::Feature: return GetLocalizedTypeName(m_mainType); + case Type::Postcode: return platform::GetLocalizedString("postal_code"); + default: return {}; + } } std::string Result::GetFeatureDescription() const { - ASSERT_EQUAL(m_resultType, Type::Feature, ()); - std::string featureDescription; + std::string res = GetLocalizedFeatureType(); + if (res.empty()) + return res; - auto const append = [&featureDescription](std::string_view sv) + auto const append = [&res](std::string_view sv) { - if (!featureDescription.empty()) - featureDescription += feature::kFieldsSeparator; - featureDescription += sv; + if (!res.empty()) + res += feature::kFieldsSeparator; + res += sv; }; - if (!m_str.empty()) - append(GetLocalizedTypeName(m_mainType)); + // Clear, because GetLocalizedFeatureType will be shown as main title. + if (m_str.empty()) + res.clear(); if (m_mainType != m_matchedType && m_matchedType != 0) append(GetLocalizedTypeName(m_matchedType)); @@ -112,7 +118,7 @@ std::string Result::GetFeatureDescription() const if (!GetDescription().empty()) append(GetDescription()); - return featureDescription; + return res; } m2::PointD Result::GetFeatureCenter() const diff --git a/search/result.hpp b/search/result.hpp index d642d50ac0..9b2a56b5ac 100644 --- a/search/result.hpp +++ b/search/result.hpp @@ -91,10 +91,8 @@ public: uint32_t GetFeatureType() const; bool IsSameType(uint32_t type) const; - // Precondition: GetResultType() == Type::Feature. std::string GetLocalizedFeatureType() const; - - // Precondition: GetResultType() == Type::Feature. + // Secondary title for the result. std::string GetFeatureDescription() const; // Center point of a feature. -- 2.45.3 From 64c87030f3fa70ff3af1acaa1841caa47d6bb33c Mon Sep 17 00:00:00 2001 From: Kiryl Kaveryn Date: Mon, 6 May 2024 17:53:21 +0400 Subject: [PATCH 28/36] [ios] hide the `export all` button when there are no bookmarks Signed-off-by: Kiryl Kaveryn --- .../Categories/BMCViewModel/BMCDefaultViewModel.swift | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/iphone/Maps/Bookmarks/Categories/BMCViewModel/BMCDefaultViewModel.swift b/iphone/Maps/Bookmarks/Categories/BMCViewModel/BMCDefaultViewModel.swift index 88adf9c2c7..31fd9ad90b 100644 --- a/iphone/Maps/Bookmarks/Categories/BMCViewModel/BMCDefaultViewModel.swift +++ b/iphone/Maps/Bookmarks/Categories/BMCViewModel/BMCDefaultViewModel.swift @@ -32,7 +32,10 @@ final class BMCDefaultViewModel: NSObject { } private func setActions() { - actions = [.create, .exportAll] + actions = [.create] + if !manager.areAllCategoriesEmpty() { + actions.append(.exportAll) + } } private func setNotifications() { @@ -121,8 +124,8 @@ extension BMCDefaultViewModel { let category = categories[index] categories.remove(at: index) - manager.deleteCategory(category.categoryId) view?.delete(at: [IndexPath(row: index, section: section)]) + manager.deleteCategory(category.categoryId) } func checkCategory(name: String) -> Bool { @@ -165,6 +168,10 @@ extension BMCDefaultViewModel: BookmarksObserver { reloadData() } + func onBookmarksCategoryDeleted(_ groupId: MWMMarkGroupID) { + reloadData() + } + func onBookmarkDeleted(_: MWMMarkID) { reloadData() } -- 2.45.3 From 276e2be9538635db85a03619aca276424a2ed909 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 22 May 2024 21:35:31 +0100 Subject: [PATCH 29/36] Update qt/place_page_dialog_user.cpp Co-authored-by: Alexander Borsuk <170263+biodranik@users.noreply.github.com> Signed-off-by: Diogo Rodrigues --- qt/place_page_dialog_user.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qt/place_page_dialog_user.cpp b/qt/place_page_dialog_user.cpp index fc91da28c4..093e304a07 100644 --- a/qt/place_page_dialog_user.cpp +++ b/qt/place_page_dialog_user.cpp @@ -79,7 +79,8 @@ PlacePageDialogUser::PlacePageDialogUser(QWidget * parent, place_page::Info cons header->addWidget(subtitleLabel); } - if (auto addressFormatted = address.FormatAddress(); !addressFormatted.empty()){ + if (auto const addressFormatted = address.FormatAddress(); !addressFormatted.empty()) + { QLabel * addressLabel = new QLabel(QString::fromStdString(addressFormatted)); addressLabel->setWordWrap(true); header->addWidget(addressLabel); -- 2.45.3 From 32b3a1777f262bbea98790e5d3676cdbaee36e27 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 22 May 2024 21:35:42 +0100 Subject: [PATCH 30/36] Update qt/place_page_dialog_user.cpp Co-authored-by: Alexander Borsuk <170263+biodranik@users.noreply.github.com> Signed-off-by: Diogo Rodrigues --- qt/place_page_dialog_user.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qt/place_page_dialog_user.cpp b/qt/place_page_dialog_user.cpp index 093e304a07..8d83eeca41 100644 --- a/qt/place_page_dialog_user.cpp +++ b/qt/place_page_dialog_user.cpp @@ -73,7 +73,8 @@ PlacePageDialogUser::PlacePageDialogUser(QWidget * parent, place_page::Info cons header->addWidget(titleLabel); } - if (auto subTitle = info.GetSubtitle(); !subTitle.empty()){ + if (auto const subTitle = info.GetSubtitle(); !subTitle.empty()) + { QLabel * subtitleLabel = new QLabel(QString::fromStdString(subTitle)); subtitleLabel->setWordWrap(true); header->addWidget(subtitleLabel); -- 2.45.3 From 09bef9d299cf5f3d82a7d945fe4ec9b651802ab7 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 22 May 2024 21:35:51 +0100 Subject: [PATCH 31/36] Update qt/place_page_dialog_user.cpp Co-authored-by: Alexander Borsuk <170263+biodranik@users.noreply.github.com> Signed-off-by: Diogo Rodrigues --- qt/place_page_dialog_user.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qt/place_page_dialog_user.cpp b/qt/place_page_dialog_user.cpp index 8d83eeca41..a78d50808f 100644 --- a/qt/place_page_dialog_user.cpp +++ b/qt/place_page_dialog_user.cpp @@ -67,7 +67,8 @@ PlacePageDialogUser::PlacePageDialogUser(QWidget * parent, place_page::Info cons { QVBoxLayout * header = new QVBoxLayout(); - if (!title.empty()){ + if (!title.empty()) + { QLabel * titleLabel = new QLabel(QString::fromStdString("

    " + title + "

    ")); titleLabel->setWordWrap(true); header->addWidget(titleLabel); -- 2.45.3 From 22175493bb6ad71ed0473c663e87b03e1b0184c4 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 22 May 2024 21:36:01 +0100 Subject: [PATCH 32/36] Update qt/place_page_dialog_user.cpp Co-authored-by: Alexander Borsuk <170263+biodranik@users.noreply.github.com> Signed-off-by: Diogo Rodrigues --- qt/place_page_dialog_user.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qt/place_page_dialog_user.cpp b/qt/place_page_dialog_user.cpp index a78d50808f..cd31a1f1b4 100644 --- a/qt/place_page_dialog_user.cpp +++ b/qt/place_page_dialog_user.cpp @@ -24,8 +24,8 @@ static int constexpr kMinWidthOfShortDescription = 390; std::string getShortDescription(std::string description) { - size_t paragraphStart = description.find("

    "); - size_t paragraphEnd = description.find("

    "); + auto const paragraphStart = description.find("

    "); + auto const paragraphEnd = description.find("

    "); if (paragraphStart == 0 && paragraphEnd != std::string::npos) description = description.substr(3, paragraphEnd-3); -- 2.45.3 From 62f5c0fac2a378f53f9d49750ace0200319dc659 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 22 May 2024 21:36:14 +0100 Subject: [PATCH 33/36] Update qt/place_page_dialog_user.cpp Co-authored-by: Alexander Borsuk <170263+biodranik@users.noreply.github.com> Signed-off-by: Diogo Rodrigues --- qt/place_page_dialog_user.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qt/place_page_dialog_user.cpp b/qt/place_page_dialog_user.cpp index cd31a1f1b4..a2eddf429f 100644 --- a/qt/place_page_dialog_user.cpp +++ b/qt/place_page_dialog_user.cpp @@ -27,7 +27,7 @@ std::string getShortDescription(std::string description) auto const paragraphStart = description.find("

    "); auto const paragraphEnd = description.find("

    "); if (paragraphStart == 0 && paragraphEnd != std::string::npos) - description = description.substr(3, paragraphEnd-3); + description = description.substr(3, paragraphEnd - 3); if (description.length() > kMaxLengthOfPlacePageDescription) { -- 2.45.3 From 4003f380546407a71dd4216457a644433efa3646 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 22 May 2024 21:36:29 +0100 Subject: [PATCH 34/36] Update qt/place_page_dialog_user.cpp Co-authored-by: Alexander Borsuk <170263+biodranik@users.noreply.github.com> Signed-off-by: Diogo Rodrigues --- qt/place_page_dialog_user.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/qt/place_page_dialog_user.cpp b/qt/place_page_dialog_user.cpp index a2eddf429f..892210f948 100644 --- a/qt/place_page_dialog_user.cpp +++ b/qt/place_page_dialog_user.cpp @@ -30,9 +30,7 @@ std::string getShortDescription(std::string description) description = description.substr(3, paragraphEnd - 3); if (description.length() > kMaxLengthOfPlacePageDescription) - { - description = description.substr(0, kMaxLengthOfPlacePageDescription-3) + "..."; - } + description = description.substr(0, kMaxLengthOfPlacePageDescription - 3) + "..."; return description; } -- 2.45.3 From 795ad453c4fcaaedfaa721abaf4cdc93f4e3821e Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 22 May 2024 21:45:23 +0100 Subject: [PATCH 35/36] Reimplemented getShortDescription to reduce number of reallocations Signed-off-by: Diogo Rodrigues --- qt/place_page_dialog_user.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/qt/place_page_dialog_user.cpp b/qt/place_page_dialog_user.cpp index 892210f948..825652c2ae 100644 --- a/qt/place_page_dialog_user.cpp +++ b/qt/place_page_dialog_user.cpp @@ -24,15 +24,18 @@ static int constexpr kMinWidthOfShortDescription = 390; std::string getShortDescription(std::string description) { - auto const paragraphStart = description.find("

    "); - auto const paragraphEnd = description.find("

    "); + std::string_view view(description); + + auto const paragraphStart = view.find("

    "); + auto const paragraphEnd = view.find("

    "); + if (paragraphStart == 0 && paragraphEnd != std::string::npos) - description = description.substr(3, paragraphEnd - 3); + view = view.substr(3, paragraphEnd - 3); - if (description.length() > kMaxLengthOfPlacePageDescription) - description = description.substr(0, kMaxLengthOfPlacePageDescription - 3) + "..."; + if (view.length() > kMaxLengthOfPlacePageDescription) + return std::string(view.substr(0, kMaxLengthOfPlacePageDescription - 3)) + "..."; - return description; + return std::string(view); } std::string_view stripSchemeFromURI(std::string_view uri) { -- 2.45.3 From 83be8750fb4aad7e9d958aa655337fda789cd682 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Wed, 22 May 2024 22:48:42 +0100 Subject: [PATCH 36/36] nits: getShortDescription Signed-off-by: Diogo Rodrigues --- qt/place_page_dialog_user.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qt/place_page_dialog_user.cpp b/qt/place_page_dialog_user.cpp index 825652c2ae..76118f12bd 100644 --- a/qt/place_page_dialog_user.cpp +++ b/qt/place_page_dialog_user.cpp @@ -22,7 +22,7 @@ namespace static int constexpr kMaxLengthOfPlacePageDescription = 500; static int constexpr kMinWidthOfShortDescription = 390; -std::string getShortDescription(std::string description) +std::string getShortDescription(const std::string & description) { std::string_view view(description); @@ -133,7 +133,7 @@ PlacePageDialogUser::PlacePageDialogUser(QWidget * parent, place_page::Info cons } // Description - if (auto description = info.GetWikiDescription(); !description.empty()) + if (const auto & description = info.GetWikiDescription(); !description.empty()) { auto descriptionShort = getShortDescription(description); -- 2.45.3