diff --git a/map/routing_manager.hpp b/map/routing_manager.hpp index efa6870d79..ec5dd914f2 100644 --- a/map/routing_manager.hpp +++ b/map/routing_manager.hpp @@ -289,6 +289,8 @@ public: void UpdatePreviewMode(); void CancelPreviewMode(); + routing::RouterType GetCurrentRouterType() const { return m_currentRouterType; } + private: /// \returns true if the route has warnings. bool InsertRoute(routing::Route const & route); diff --git a/qt/CMakeLists.txt b/qt/CMakeLists.txt index 4c1eb5b2df..9063ddccb4 100644 --- a/qt/CMakeLists.txt +++ b/qt/CMakeLists.txt @@ -50,6 +50,8 @@ set( place_page_dialog.hpp preferences_dialog.cpp preferences_dialog.hpp + routing_settings_dialog.cpp + routing_settings_dialog.hpp screenshoter.cpp screenshoter.hpp search_panel.cpp diff --git a/qt/draw_widget.cpp b/qt/draw_widget.cpp index e42526cb15..d70eec01d4 100644 --- a/qt/draw_widget.cpp +++ b/qt/draw_widget.cpp @@ -4,6 +4,7 @@ #include "qt/place_page_dialog.hpp" #include "qt/qt_common/helpers.hpp" #include "qt/qt_common/scale_slider.hpp" +#include "qt/routing_settings_dialog.hpp" #include "qt/screenshoter.hpp" #include "map/framework.hpp" @@ -390,7 +391,9 @@ void DrawWidget::SetMapStyle(MapStyle mapStyle) void DrawWidget::SubmitFakeLocationPoint(m2::PointD const & pt) { m_emulatingLocation = true; - auto const point = m_framework.P3dtoG(pt); + + m2::PointD const point = GetCoordsFromSettingsIfExists(true /* start */, pt); + m_framework.OnLocationUpdate(qt::common::MakeGpsInfo(point)); if (m_framework.GetRoutingManager().IsRoutingActive()) @@ -424,7 +427,8 @@ void DrawWidget::SubmitRoutingPoint(m2::PointD const & pt) RouteMarkData point; point.m_pointType = m_routePointAddMode; point.m_isMyPosition = false; - point.m_position = m_framework.P3dtoG(pt); + point.m_position = GetCoordsFromSettingsIfExists(false /* start */, pt); + routingManager.AddRoutePoint(std::move(point)); if (routingManager.GetRoutePoints().size() >= 2) @@ -581,4 +585,12 @@ void DrawWidget::RefreshDrawingRules() { SetMapStyle(MapStyleClear); } + +m2::PointD DrawWidget::GetCoordsFromSettingsIfExists(bool start, m2::PointD const & pt) +{ + if (auto optional = RoutingSettings::GetCoords(start)) + return MercatorBounds::FromLatLon(*optional); + + return m_framework.P3dtoG(pt); +} } // namespace qt diff --git a/qt/draw_widget.hpp b/qt/draw_widget.hpp index a17350cdb8..2f25165605 100644 --- a/qt/draw_widget.hpp +++ b/qt/draw_widget.hpp @@ -111,6 +111,8 @@ private: void UpdateCountryStatus(storage::CountryId const & countryId); + m2::PointD GetCoordsFromSettingsIfExists(bool start, m2::PointD const & pt); + QRubberBand * m_rubberBand; QPoint m_rubberBandOrigin; diff --git a/qt/mainwindow.cpp b/qt/mainwindow.cpp index d8c8f40a89..5272273a22 100644 --- a/qt/mainwindow.cpp +++ b/qt/mainwindow.cpp @@ -6,8 +6,9 @@ #include "qt/preferences_dialog.hpp" #include "qt/qt_common/helpers.hpp" #include "qt/qt_common/scale_slider.hpp" -#include "qt/search_panel.hpp" +#include "qt/routing_settings_dialog.hpp" #include "qt/screenshoter.hpp" +#include "qt/search_panel.hpp" #include "platform/settings.hpp" #include "platform/platform.hpp" @@ -185,6 +186,11 @@ MainWindow::MainWindow(Framework & framework, bool apiOpenGLES3, m_pDrawWidget->UpdateAfterSettingsChanged(); m_pDrawWidget->GetFramework().UploadUGC(nullptr /* onCompleteUploading */); + + if (RoutingSettings::IsCacheEnabled()) + RoutingSettings::LoadSettings(m_pDrawWidget->GetFramework()); + else + RoutingSettings::ResetSettings(); } #if defined(Q_WS_WIN) @@ -338,6 +344,12 @@ void MainWindow::CreateNavigationBar() auto clearAction = pToolBar->addAction(QIcon(":/navig64/clear-route.png"), tr("Clear route"), this, SLOT(OnClearRoute())); clearAction->setToolTip(tr("Clear route")); + + auto settingsRoutingAction = pToolBar->addAction(QIcon(":/navig64/settings-routing.png"), + tr("Routing settings"), this, + SLOT(OnRoutingSettings())); + settingsRoutingAction->setToolTip(tr("Routing settings")); + pToolBar->addSeparator(); m_pCreateFeatureAction = pToolBar->addAction(QIcon(":/navig64/select.png"), tr("Create Feature"), @@ -909,6 +921,12 @@ void MainWindow::OnClearRoute() m_pDrawWidget->ClearRoute(); } +void MainWindow::OnRoutingSettings() +{ + RoutingSettings dlg(this, m_pDrawWidget->GetFramework()); + dlg.ShowModal(); +} + void MainWindow::OnBookmarksAction() { BookmarkDialog dlg(this, m_pDrawWidget->GetFramework()); diff --git a/qt/mainwindow.hpp b/qt/mainwindow.hpp index a0d574091d..81bea0f366 100644 --- a/qt/mainwindow.hpp +++ b/qt/mainwindow.hpp @@ -120,6 +120,7 @@ protected Q_SLOTS: void OnIntermediatePointSelected(); void OnFollowRoute(); void OnClearRoute(); + void OnRoutingSettings(); void OnBookmarksAction(); diff --git a/qt/res/resources.qrc b/qt/res/resources.qrc index bc6715b05c..677819c994 100644 --- a/qt/res/resources.qrc +++ b/qt/res/resources.qrc @@ -27,6 +27,7 @@ geom.png phonepack.png bookmark.png + settings-routing.png logo.png diff --git a/qt/res/settings-routing.png b/qt/res/settings-routing.png new file mode 100644 index 0000000000..dda8971250 Binary files /dev/null and b/qt/res/settings-routing.png differ diff --git a/qt/routing_settings_dialog.cpp b/qt/routing_settings_dialog.cpp new file mode 100644 index 0000000000..80850e76de --- /dev/null +++ b/qt/routing_settings_dialog.cpp @@ -0,0 +1,225 @@ +#include "qt/routing_settings_dialog.hpp" + +#include "map/framework.hpp" + +#include "routing/router.hpp" + +#include "platform/settings.hpp" + +#include "base/logging.hpp" +#include "base/macros.hpp" +#include "base/string_utils.hpp" + +#include +#include +#include +#include + +namespace +{ +char constexpr kDelim[] = " ,\t"; +} // namespace + +namespace qt +{ +std::string const RoutingSettings::kUseCachedRoutingSettings = "use_cached_settings_desktop"; +std::string const RoutingSettings::kStartCoordsCachedSettings = "start_coords_desktop"; +std::string const RoutingSettings::kFinishCoordsCachedSettings = "finish_coords_desktop"; +std::string const RoutingSettings::kRouterTypeCachedSettings = "router_type_desktop"; + +// static +bool RoutingSettings::IsCacheEnabled() +{ + bool enable = false; + if (settings::Get(kUseCachedRoutingSettings, enable)) + return enable; + + return false; +} + +// static +void RoutingSettings::ResetSettings() +{ + settings::Set(kUseCachedRoutingSettings, false); + settings::Set(kStartCoordsCachedSettings, std::string()); + settings::Set(kFinishCoordsCachedSettings, std::string()); + settings::Set(kRouterTypeCachedSettings, static_cast(routing::RouterType::Vehicle)); +} + +// static +boost::optional RoutingSettings::GetCoordsFromString(std::string const & input) +{ + ms::LatLon coords{}; + strings::SimpleTokenizer iter(input, kDelim); + if (!iter) + return {}; + + if (!strings::to_double(*iter, coords.lat)) + return {}; + + ++iter; + + if (!strings::to_double(*iter, coords.lon)) + return {}; + + return {coords}; +} + +// static +boost::optional RoutingSettings::GetCoords(bool start) +{ + std::string input; + UNUSED_VALUE(settings::Get(start ? kStartCoordsCachedSettings + : kFinishCoordsCachedSettings, input)); + return GetCoordsFromString(input); +} + +// static +void RoutingSettings::LoadSettings(Framework & framework) +{ + int routerType = 0; + UNUSED_VALUE(settings::Get(kRouterTypeCachedSettings, routerType)); + + framework.GetRoutingManager().SetRouterImpl(static_cast(routerType)); +} + +RoutingSettings::RoutingSettings(QWidget * parent, Framework & framework) + : QDialog(parent), + m_framework(framework), + m_form(this), + m_startInput(new QLineEdit(this)), + m_finishInput(new QLineEdit(this)), + m_routerType(new QComboBox(this)), + m_alwaysCheckbox(new QCheckBox("", this)) +{ + setWindowTitle("Routing settings"); + + AddLineEdit("Start coords (lat, lon)", m_startInput); + AddLineEdit("Finish coords (lat, lon)", m_finishInput); + AddListWidgetWithRoutingTypes(); + AddCheckBox(); + AddButtonBox(); + + LoadSettings(); +} + +void RoutingSettings::AddLineEdit(std::string const & title, QLineEdit * lineEdit) +{ + std::string defaultText; + if (IsCacheEnabled()) + { + bool const isStart = lineEdit == m_startInput; + std::string const settingsName = isStart ? kStartCoordsCachedSettings.c_str() + : kFinishCoordsCachedSettings.c_str(); + UNUSED_VALUE(settings::Get(settingsName, defaultText)); + } + + lineEdit->setText(defaultText.c_str()); + + QString const label = QString(title.c_str()); + m_form.addRow(label, lineEdit); +} + +void RoutingSettings::AddCheckBox() +{ + m_form.addRow("Save for next sessions:", m_alwaysCheckbox); +} + +void RoutingSettings::AddButtonBox() +{ + auto * buttonBox = + new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this); + + m_form.addRow(buttonBox); + + QObject::connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + QObject::connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); +} + +void RoutingSettings::AddListWidgetWithRoutingTypes() +{ + using namespace routing; + m_routerType->insertItem(static_cast(RouterType::Vehicle), "car"); + m_routerType->insertItem(static_cast(RouterType::Pedestrian), "pedestrian"); + m_routerType->insertItem(static_cast(RouterType::Bicycle), "bicycle"); + m_routerType->insertItem(static_cast(RouterType::Taxi), "taxi"); + m_routerType->insertItem(static_cast(RouterType::Transit), "transit"); + + m_form.addRow("Choose router:", m_routerType); +} + +void RoutingSettings::ShowMessage(std::string const & message) +{ + QMessageBox msgBox; + msgBox.setText(message.c_str()); + msgBox.exec(); +} + +bool RoutingSettings::ValidateAndSaveCoordsFromInput() +{ + std::string const & startText = m_startInput->text().toStdString(); + std::string const & finishText = m_finishInput->text().toStdString(); + + if (!startText.empty() && !GetCoordsFromString(startText)) + return false; + + if (!finishText.empty() && !GetCoordsFromString(finishText)) + return false; + + settings::Set(kStartCoordsCachedSettings, startText); + settings::Set(kFinishCoordsCachedSettings, finishText); + + return true; +} + +void RoutingSettings::SaveSettings() +{ + settings::Set(kUseCachedRoutingSettings, true); + ValidateAndSaveCoordsFromInput(); + settings::Set(kRouterTypeCachedSettings, m_routerType->currentIndex()); +} + +void RoutingSettings::LoadSettings() +{ + std::string startCoordsText; + UNUSED_VALUE(settings::Get(kStartCoordsCachedSettings, startCoordsText)); + m_startInput->setText(startCoordsText.c_str()); + + std::string finishCoordsText; + UNUSED_VALUE(settings::Get(kFinishCoordsCachedSettings, finishCoordsText)); + m_finishInput->setText(finishCoordsText.c_str()); + + int routerType = 0; + UNUSED_VALUE(settings::Get(kRouterTypeCachedSettings, routerType)); + m_routerType->setCurrentIndex(routerType); + + m_framework.GetRoutingManager().SetRouterImpl(static_cast(routerType)); + + bool setChecked = false; + UNUSED_VALUE(settings::Get(kUseCachedRoutingSettings, setChecked)); + m_alwaysCheckbox->setChecked(setChecked); +} + +void RoutingSettings::ShowModal() +{ + if (exec() != QDialog::Accepted) + return; + + if (!ValidateAndSaveCoordsFromInput()) + { + ShowMessage("Bad start or finish coords input."); + ShowModal(); + return; + } + + int routerType = m_routerType->currentIndex(); + settings::Set(kRouterTypeCachedSettings, routerType); + m_framework.GetRoutingManager().SetRouterImpl( + static_cast(routerType)); + + if (m_alwaysCheckbox->isChecked()) + SaveSettings(); + else + settings::Set(kUseCachedRoutingSettings, false); +} +} // namespace qt diff --git a/qt/routing_settings_dialog.hpp b/qt/routing_settings_dialog.hpp new file mode 100644 index 0000000000..71e8d8dad0 --- /dev/null +++ b/qt/routing_settings_dialog.hpp @@ -0,0 +1,60 @@ +#pragma once + +#include "geometry/latlon.hpp" + +#include +#include +#include +#include +#include +#include + +#include + +#include "boost/optional.hpp" + +class Framework; + +namespace qt +{ +class RoutingSettings : public QDialog +{ +public: + static bool IsCacheEnabled(); + static boost::optional GetCoords(bool start); + static void LoadSettings(Framework & framework); + static void ResetSettings(); + + RoutingSettings(QWidget * parent, Framework & framework); + + void ShowModal(); + +private: + static std::string const kUseCachedRoutingSettings; + static std::string const kStartCoordsCachedSettings; + static std::string const kFinishCoordsCachedSettings; + static std::string const kRouterTypeCachedSettings; + + static boost::optional GetCoordsFromString(std::string const & input); + + void AddLineEdit(std::string const & title, QLineEdit * lineEdit); + void AddCheckBox(); + void AddButtonBox(); + void AddListWidgetWithRoutingTypes(); + + void ShowMessage(std::string const & message); + bool ValidateAndSaveCoordsFromInput(); + void SaveSettings(); + void LoadSettings(); + + Framework & m_framework; + QDialog m_dialog; + QFormLayout m_form; + + QLineEdit * m_startInput; + QLineEdit * m_finishInput; + + QComboBox * m_routerType; + QCheckBox * m_alwaysCheckbox; +}; +} // namespace qt diff --git a/xcode/qtMapsMe/qtMapsMe.xcodeproj/project.pbxproj b/xcode/qtMapsMe/qtMapsMe.xcodeproj/project.pbxproj index c68309e031..3c4a0cafb8 100644 --- a/xcode/qtMapsMe/qtMapsMe.xcodeproj/project.pbxproj +++ b/xcode/qtMapsMe/qtMapsMe.xcodeproj/project.pbxproj @@ -29,6 +29,8 @@ 34FFD30E1E9CEF010010AD12 /* liblocal_ads.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 34FFD30C1E9CEF010010AD12 /* liblocal_ads.a */; }; 34FFD30F1E9CEF490010AD12 /* map_widget.hpp in Sources */ = {isa = PBXBuildFile; fileRef = 34FFD2F21E9CEEA20010AD12 /* map_widget.hpp */; }; 34FFD3101E9CEF490010AD12 /* resources_common.qrc in Sources */ = {isa = PBXBuildFile; fileRef = 34FFD2FD1E9CEEA20010AD12 /* resources_common.qrc */; }; + 4415CD992271B1A200AA3A19 /* routing_settings_dialog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4415CD952271B1A200AA3A19 /* routing_settings_dialog.cpp */; }; + 4415CD9A2271B1A200AA3A19 /* screenshoter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4415CD962271B1A200AA3A19 /* screenshoter.cpp */; }; 450703071E9E6C7100E8C029 /* local_ads_symbols.txt in Resources */ = {isa = PBXBuildFile; fileRef = 450703061E9E6C7100E8C029 /* local_ads_symbols.txt */; }; 456B3FAC1EDEEB04009B3D1F /* build_common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 456B3F9E1EDEEB04009B3D1F /* build_common.cpp */; }; 456B3FAD1EDEEB04009B3D1F /* build_drules.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 456B3FA01EDEEB04009B3D1F /* build_drules.cpp */; }; @@ -208,7 +210,6 @@ 6729A5D11A693140007D5872 /* packed_polygons.bin in CopyFiles */, 6729A5CF1A693108007D5872 /* drules_proto.bin in CopyFiles */, 6729A5CB1A69309E007D5872 /* types.txt in CopyFiles */, - 4069ADA121495AE5005EB75C /* categories_cuisines.txt in CopyFiles */, 6729A5C11A693014007D5872 /* categories.txt in CopyFiles */, 6729A5C21A693014007D5872 /* classificator.txt in CopyFiles */, 6729A5C31A693014007D5872 /* countries.txt in CopyFiles */, @@ -247,7 +248,10 @@ 34FFD2FF1E9CEEA20010AD12 /* scale_slider.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = scale_slider.hpp; sourceTree = ""; }; 34FFD30B1E9CEF010010AD12 /* libicu.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libicu.a; path = "/Users/igrechuhin/Repo/omim/xcode/icu/../../../omim-build/xcode/Debug/libicu.a"; sourceTree = ""; }; 34FFD30C1E9CEF010010AD12 /* liblocal_ads.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblocal_ads.a; path = "/Users/igrechuhin/Repo/omim/xcode/local_ads/../../../omim-build/xcode/Debug/liblocal_ads.a"; sourceTree = ""; }; - 4069ADA021495AE4005EB75C /* categories_cuisines.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = categories_cuisines.txt; sourceTree = ""; }; + 4415CD952271B1A200AA3A19 /* routing_settings_dialog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = routing_settings_dialog.cpp; sourceTree = ""; }; + 4415CD962271B1A200AA3A19 /* screenshoter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = screenshoter.cpp; sourceTree = ""; }; + 4415CD972271B1A200AA3A19 /* routing_settings_dialog.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = routing_settings_dialog.hpp; sourceTree = ""; }; + 4415CD982271B1A200AA3A19 /* screenshoter.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = screenshoter.hpp; sourceTree = ""; }; 450703061E9E6C7100E8C029 /* local_ads_symbols.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = local_ads_symbols.txt; sourceTree = ""; }; 456B3F9E1EDEEB04009B3D1F /* build_common.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = build_common.cpp; path = build_style/build_common.cpp; sourceTree = ""; }; 456B3F9F1EDEEB04009B3D1F /* build_common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = build_common.h; path = build_style/build_common.h; sourceTree = ""; }; @@ -623,6 +627,10 @@ 6753454B1A404C6100A0A8C3 /* qtMapsMe */ = { isa = PBXGroup; children = ( + 4415CD952271B1A200AA3A19 /* routing_settings_dialog.cpp */, + 4415CD972271B1A200AA3A19 /* routing_settings_dialog.hpp */, + 4415CD962271B1A200AA3A19 /* screenshoter.cpp */, + 4415CD982271B1A200AA3A19 /* screenshoter.hpp */, 6753456C1A404CB200A0A8C3 /* about.cpp */, 6753456D1A404CB200A0A8C3 /* about.hpp */, 45D7ADA2210B519300160DE3 /* bookmark_dialog.cpp */, @@ -712,6 +720,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, Base, ); @@ -738,7 +747,6 @@ 6714E6031BD14016008AB603 /* resources-mdpi_dark in Resources */, 45B5B5991CA422C800D93E36 /* resources-hdpi_clear in Resources */, 34FFD3071E9CEEA20010AD12 /* minus.png in Resources */, - 4069ADA121495AE5005EB75C /* categories_cuisines.txt in Resources */, 45B5B5A51CA422EE00D93E36 /* resources-xhdpi_dark in Resources */, 671182F71C80E09A00CB8177 /* patterns.txt in Resources */, 34FFD3081E9CEEA20010AD12 /* plus.png in Resources */, @@ -781,6 +789,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 4415CD9A2271B1A200AA3A19 /* screenshoter.cpp in Sources */, 34FFD30F1E9CEF490010AD12 /* map_widget.hpp in Sources */, 45B5B58C1CA4219C00D93E36 /* create_feature_dialog.hpp in Sources */, 45B5B58D1CA4219C00D93E36 /* place_page_dialog.hpp in Sources */, @@ -794,6 +803,7 @@ 670D05961B0CBD320013A7AC /* search_panel.hpp in Sources */, 670D05981B0CBD320013A7AC /* update_dialog.hpp in Sources */, 6729A6691A69395E007D5872 /* resources.qrc in Sources */, + 4415CD992271B1A200AA3A19 /* routing_settings_dialog.cpp in Sources */, 34FFD3101E9CEF490010AD12 /* resources_common.qrc in Sources */, 456B3FB01EDEEB04009B3D1F /* build_statistics.cpp in Sources */, 456B3FAE1EDEEB04009B3D1F /* build_phone_pack.cpp in Sources */,