From 2084395a89ea3e380c8a811d549cd31a39c43f70 Mon Sep 17 00:00:00 2001 From: Diogo Rodrigues Date: Thu, 23 May 2024 12:46:06 +0100 Subject: [PATCH] Place panel Signed-off-by: Diogo Rodrigues Merged place panels into single class Signed-off-by: Diogo Rodrigues Corrected width issue in small screens Signed-off-by: Diogo Rodrigues nits Signed-off-by: Diogo Rodrigues Add scrolls --- qt/CMakeLists.txt | 8 +- qt/draw_widget.cpp | 105 ++++---- qt/draw_widget.hpp | 14 +- qt/mainwindow.cpp | 18 +- qt/mainwindow.hpp | 7 +- qt/place_page_dialog_common.cpp | 56 ----- qt/place_page_dialog_common.hpp | 17 -- qt/place_page_dialog_developer.cpp | 132 ---------- qt/place_page_dialog_developer.hpp | 18 -- qt/place_page_dialog_user.hpp | 18 -- ...e_page_dialog_user.cpp => place_panel.cpp} | 233 ++++++++++++++++-- qt/place_panel.hpp | 51 ++++ 12 files changed, 361 insertions(+), 316 deletions(-) delete mode 100644 qt/place_page_dialog_common.cpp delete mode 100644 qt/place_page_dialog_common.hpp delete mode 100644 qt/place_page_dialog_developer.cpp delete mode 100644 qt/place_page_dialog_developer.hpp delete mode 100644 qt/place_page_dialog_user.hpp rename qt/{place_page_dialog_user.cpp => place_panel.cpp} (54%) create mode 100644 qt/place_panel.hpp diff --git a/qt/CMakeLists.txt b/qt/CMakeLists.txt index 8513577266..8c84870a1a 100644 --- a/qt/CMakeLists.txt +++ b/qt/CMakeLists.txt @@ -36,12 +36,8 @@ set(SRC mwms_borders_selection.hpp osm_auth_dialog.cpp osm_auth_dialog.hpp - place_page_dialog_common.cpp - place_page_dialog_common.hpp - place_page_dialog_developer.cpp - place_page_dialog_developer.hpp - place_page_dialog_user.cpp - place_page_dialog_user.hpp + place_panel.cpp + place_panel.hpp preferences_dialog.cpp preferences_dialog.hpp popup_menu_holder.cpp diff --git a/qt/draw_widget.cpp b/qt/draw_widget.cpp index 6ed66b365e..34b5ee5ee2 100644 --- a/qt/draw_widget.cpp +++ b/qt/draw_widget.cpp @@ -2,9 +2,7 @@ #include "qt/create_feature_dialog.hpp" #include "qt/editor_dialog.hpp" -#include "qt/place_page_dialog_common.hpp" -#include "qt/place_page_dialog_developer.hpp" -#include "qt/place_page_dialog_user.hpp" +#include "qt/place_panel.hpp" #include "qt/qt_common/helpers.hpp" #include "qt/routing_settings_dialog.hpp" #include "qt/screenshoter.hpp" @@ -81,15 +79,21 @@ void DrawMwmBorder(df::DrapeApi & drapeApi, std::string const & mwmName, } // namespace DrawWidget::DrawWidget(Framework & framework, std::unique_ptr && screenshotParams, - QWidget * parent) + PlacePanel * placePanel, QWidget * parent) : TBase(framework, screenshotParams != nullptr, parent) , m_rubberBand(nullptr) , m_emulatingLocation(false) + , m_placePanel(placePanel) { setFocusPolicy(Qt::StrongFocus); m_framework.SetPlacePageListeners([this]() { ShowPlacePage(); }, {} /* onClose */, {} /* onUpdate */, {} /*onSwitchFullScreen */); + + connect(m_placePanel, &PlacePanel::routeFrom, this, &DrawWidget::OnRouteFrom); + connect(m_placePanel, &PlacePanel::addStop, this, &DrawWidget::OnAddStop); + connect(m_placePanel, &PlacePanel::routeTo, this, &DrawWidget::OnRouteTo); + connect(m_placePanel, &PlacePanel::editPlace, this, &DrawWidget::OnEditPlace); auto & routingManager = m_framework.GetRoutingManager(); @@ -635,8 +639,11 @@ void DrawWidget::OnRouteRecommendation(RoutingManager::Recommendation recommenda } } -void DrawWidget::ShowPlacePage() +void DrawWidget::UpdatePlace() { + if (!m_framework.HasPlacePageInfo()) + return; + place_page::Info const & info = m_framework.GetCurrentPlacePageInfo(); search::ReverseGeocoder::Address address; if (info.IsFeature()) @@ -649,59 +656,59 @@ void DrawWidget::ShowPlacePage() address = m_framework.GetAddressAtPoint(info.GetMercator()); } - std::unique_ptr placePageDialog = nullptr; - bool developerMode; - if (settings::Get(settings::kDeveloperMode, developerMode) && developerMode) - placePageDialog = std::make_unique(this, info, address); - else - placePageDialog = std::make_unique(this, info, address); + m_placePanel->setPlace(info, address); +} - switch (placePageDialog->exec()) +void DrawWidget::ShowPlacePage() +{ + UpdatePlace(); + m_placePanel->showPlace(); +} + +void DrawWidget::HidePlacePage() +{ + m_placePanel->hidePlace(); +} + +void DrawWidget::OnRouteFrom(place_page::Info const & info) +{ + SetRoutePointAddMode(RouteMarkType::Start); + SubmitRoutingPoint(info.GetMercator(), true); +} + +void DrawWidget::OnAddStop(place_page::Info const & info) +{ + SetRoutePointAddMode(RouteMarkType::Intermediate); + SubmitRoutingPoint(info.GetMercator(), true); +} + +void DrawWidget::OnRouteTo(place_page::Info const & info) +{ + SetRoutePointAddMode(RouteMarkType::Finish); + SubmitRoutingPoint(info.GetMercator(), true); +} + +void DrawWidget::OnEditPlace(place_page::Info const & info) +{ + osm::EditableMapObject emo; + if (m_framework.GetEditableMapObject(info.GetID(), emo)) { - case place_page_dialog::EditPlace: - { - osm::EditableMapObject emo; - if (m_framework.GetEditableMapObject(info.GetID(), emo)) + EditorDialog dlg(this, emo); + int const result = dlg.exec(); + if (result == QDialog::Accepted) { - EditorDialog dlg(this, emo); - int const result = dlg.exec(); - if (result == QDialog::Accepted) - { - m_framework.SaveEditedMapObject(emo); - m_framework.UpdatePlacePageInfoForCurrentSelection(); - } - else if (result == QDialogButtonBox::DestructiveRole) - { - m_framework.DeleteFeature(info.GetID()); - } + m_framework.SaveEditedMapObject(emo); + m_framework.UpdatePlacePageInfoForCurrentSelection(); } - else + else if (result == QDialogButtonBox::DestructiveRole) { - LOG(LERROR, ("Error while trying to edit feature.")); + m_framework.DeleteFeature(info.GetID()); } } - break; - case place_page_dialog::RouteFrom: + else { - SetRoutePointAddMode(RouteMarkType::Start); - SubmitRoutingPoint(info.GetMercator(), true); + LOG(LERROR, ("Error while trying to edit feature.")); } - break; - case place_page_dialog::AddStop: - { - SetRoutePointAddMode(RouteMarkType::Intermediate); - SubmitRoutingPoint(info.GetMercator(), true); - } - break; - case place_page_dialog::RouteTo: - { - SetRoutePointAddMode(RouteMarkType::Finish); - SubmitRoutingPoint(info.GetMercator(), true); - } - break; - default: break; - } - m_framework.DeactivateMapSelection(); } void DrawWidget::SetRuler(bool enabled) diff --git a/qt/draw_widget.hpp b/qt/draw_widget.hpp index 63828d5564..ebfd2b68ea 100644 --- a/qt/draw_widget.hpp +++ b/qt/draw_widget.hpp @@ -4,6 +4,7 @@ #include "qt/routing_turns_visualizer.hpp" #include "qt/ruler.hpp" #include "qt/selection.hpp" +#include "qt/place_panel.hpp" #include "map/routing_manager.hpp" @@ -43,7 +44,7 @@ public Q_SLOTS: public: DrawWidget(Framework & framework, std::unique_ptr && screenshotParams, - QWidget * parent); + PlacePanel * placePanel, QWidget * parent); ~DrawWidget() override; std::string GetDistance(search::Result const & res) const; @@ -90,6 +91,13 @@ private: void SubmitBookmark(m2::PointD const & pt); void ShowPlacePage(); + void HidePlacePage(); + + void OnRouteFrom(place_page::Info const & info); + void OnAddStop(place_page::Info const & info); + void OnRouteTo(place_page::Info const & info); + void OnEditPlace(place_page::Info const & info); + void VisualizeMwmsBordersInRect(m2::RectD const & rect, bool withVertices, bool fromPackedPolygon, bool boundingBox); @@ -112,6 +120,8 @@ public: m_selectionMode = {}; } + void UpdatePlace(); + private: void ProcessSelectionMode(); std::optional m_selectionMode; @@ -120,5 +130,7 @@ private: std::unique_ptr m_screenshoter; Ruler m_ruler; RoutingTurnsVisualizer m_turnsVisualizer; + + PlacePanel * m_placePanel = nullptr; }; } // namespace qt diff --git a/qt/mainwindow.cpp b/qt/mainwindow.cpp index aab30b4968..01bf99051d 100644 --- a/qt/mainwindow.cpp +++ b/qt/mainwindow.cpp @@ -117,9 +117,12 @@ MainWindow::MainWindow(Framework & framework, }; } + CreateSearchBarAndPanel(); + CreatePlaceBarAndPanel(); + int const width = m_screenshotMode ? static_cast(screenshotParams->m_width) : 0; int const height = m_screenshotMode ? static_cast(screenshotParams->m_height) : 0; - m_pDrawWidget = new DrawWidget(framework, std::move(screenshotParams), this); + m_pDrawWidget = new DrawWidget(framework, std::move(screenshotParams), placePanel, this); QList gestures; gestures << Qt::PinchGesture; @@ -667,6 +670,8 @@ void MainWindow::OnPreferences() dlg.exec(); framework.EnterForeground(); + + m_pDrawWidget->UpdatePlace(); } #ifdef BUILD_DESIGNER @@ -833,6 +838,17 @@ void MainWindow::CreateSearchBarAndPanel() m_Docks[0]->setWidget(panel); } +void MainWindow::CreatePlaceBarAndPanel() +{ + CreatePanelImpl(1, Qt::LeftDockWidgetArea, tr("Place Information Page"), QKeySequence(), 0); + + placePanel = new PlacePanel(m_Docks[1]); + m_Docks[1]->setWidget(placePanel); + + connect(placePanel, &PlacePanel::showPlace, m_Docks[1], &QDockWidget::show); + connect(placePanel, &PlacePanel::hidePlace, m_Docks[1], &QDockWidget::hide); +} + void MainWindow::CreatePanelImpl(size_t i, Qt::DockWidgetArea area, QString const & name, QKeySequence const & hotkey, char const * slot) { diff --git a/qt/mainwindow.hpp b/qt/mainwindow.hpp index 88c1f90092..4c025602fd 100644 --- a/qt/mainwindow.hpp +++ b/qt/mainwindow.hpp @@ -1,6 +1,8 @@ #pragma once #include "qt/selection.hpp" +#include "qt/place_panel.hpp" + #include "map/routing_mark.hpp" #include "storage/storage_defines.hpp" @@ -32,12 +34,14 @@ class MainWindow : public QMainWindow, location::LocationObserver { DrawWidget * m_pDrawWidget = nullptr; // TODO(mgsergio): Make indexing more informative. - std::array m_Docks; + std::array m_Docks; QPushButton * m_downloadButton = nullptr; QPushButton * m_retryButton = nullptr; QLabel * m_downloadingStatusLabel = nullptr; + PlacePanel * placePanel = nullptr; + storage::CountryId m_lastCountry; std::unique_ptr const m_locationService; @@ -92,6 +96,7 @@ protected: QKeySequence const & hotkey, char const * slot); void CreateNavigationBar(); void CreateSearchBarAndPanel(); + void CreatePlaceBarAndPanel(); void CreateCountryStatusControls(); void SetLayerEnabled(LayerType type, bool enable); diff --git a/qt/place_page_dialog_common.cpp b/qt/place_page_dialog_common.cpp deleted file mode 100644 index ed6e213f9f..0000000000 --- a/qt/place_page_dialog_common.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include "qt/place_page_dialog_common.hpp" - -#include - -namespace place_page_dialog -{ -void addCommonButtons(QDialog * this_, QDialogButtonBox * dbb, bool shouldShowEditPlace) -{ - dbb->setCenterButtons(true); - - QPushButton * fromButton = new QPushButton("Route From"); - fromButton->setIcon(QIcon(":/navig64/point-start.png")); - fromButton->setAutoDefault(false); - this_->connect(fromButton, &QAbstractButton::clicked, this_, [this_] - { - this_->done(RouteFrom); - }); - dbb->addButton(fromButton, QDialogButtonBox::ActionRole); - - QPushButton * addStopButton = new QPushButton("Add Stop"); - addStopButton->setIcon(QIcon(":/navig64/point-intermediate.png")); - addStopButton->setAutoDefault(false); - this_->connect(addStopButton, &QAbstractButton::clicked, this_, [this_] - { - this_->done(AddStop); - }); - dbb->addButton(addStopButton, QDialogButtonBox::ActionRole); - - QPushButton * routeToButton = new QPushButton("Route To"); - routeToButton->setIcon(QIcon(":/navig64/point-finish.png")); - routeToButton->setAutoDefault(false); - this_->connect(routeToButton, &QAbstractButton::clicked, this_, [this_] - { - this_->done(RouteTo); - }); - dbb->addButton(routeToButton, QDialogButtonBox::ActionRole); - - QPushButton * closeButton = new QPushButton("Close"); - closeButton->setDefault(true); - this_->connect(closeButton, &QAbstractButton::clicked, this_, [this_] - { - this_->done(place_page_dialog::Close); - }); - dbb->addButton(closeButton, QDialogButtonBox::RejectRole); - - if (shouldShowEditPlace) - { - QPushButton * editButton = new QPushButton("Edit Place"); - this_->connect(editButton, &QAbstractButton::clicked, this_, [this_] - { - this_->done(place_page_dialog::EditPlace); - }); - dbb->addButton(editButton, QDialogButtonBox::AcceptRole); - } -} -} diff --git a/qt/place_page_dialog_common.hpp b/qt/place_page_dialog_common.hpp deleted file mode 100644 index 490d648fe5..0000000000 --- a/qt/place_page_dialog_common.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include -#include - -namespace place_page_dialog -{ -enum PressedButton : int { - Close = QDialog::Rejected, - RouteFrom, - AddStop, - RouteTo, - EditPlace -}; - -void addCommonButtons(QDialog * this_, QDialogButtonBox * dbb, bool shouldShowEditPlace); -} diff --git a/qt/place_page_dialog_developer.cpp b/qt/place_page_dialog_developer.cpp deleted file mode 100644 index bf19b93531..0000000000 --- a/qt/place_page_dialog_developer.cpp +++ /dev/null @@ -1,132 +0,0 @@ -#include "qt/place_page_dialog_common.hpp" -#include "qt/place_page_dialog_developer.hpp" - -#include "qt/qt_common/text_dialog.hpp" - -#include "map/place_page_info.hpp" - -#include -#include -#include -#include -#include - -#include - -PlacePageDialogDeveloper::PlacePageDialogDeveloper(QWidget * parent, place_page::Info const & info, - search::ReverseGeocoder::Address const & address) - : QDialog(parent) -{ - QVBoxLayout * layout = new QVBoxLayout(); - QGridLayout * grid = new QGridLayout(); - int row = 0; - - auto const addEntry = [grid, &row](std::string const & key, std::string const & value, bool isLink = false) - { - grid->addWidget(new QLabel(QString::fromStdString(key)), row, 0); - QLabel * label = new QLabel(QString::fromStdString(value)); - label->setTextInteractionFlags(Qt::TextSelectableByMouse); - if (isLink) - { - label->setOpenExternalLinks(true); - label->setTextInteractionFlags(Qt::TextBrowserInteraction); - label->setText(QString::fromStdString("" + value + "")); - } - grid->addWidget(label, row++, 1); - return label; - }; - - { - ms::LatLon const ll = info.GetLatLon(); - addEntry("lat, lon", strings::to_string_dac(ll.m_lat, 7) + ", " + strings::to_string_dac(ll.m_lon, 7)); - } - - addEntry("CountryId", info.GetCountryId()); - - auto const & title = info.GetTitle(); - if (!title.empty()) - addEntry("Title", title); - - if (auto const & subTitle = info.GetSubtitle(); !subTitle.empty()) - addEntry("Subtitle", subTitle); - - addEntry("Address", address.FormatAddress()); - - if (info.IsBookmark()) - { - grid->addWidget(new QLabel("Bookmark"), row, 0); - grid->addWidget(new QLabel("Yes"), row++, 1); - } - - if (info.IsMyPosition()) - { - grid->addWidget(new QLabel("MyPosition"), row, 0); - grid->addWidget(new QLabel("Yes"), row++, 1); - } - - if (info.HasApiUrl()) - { - grid->addWidget(new QLabel("Api URL"), row, 0); - grid->addWidget(new QLabel(QString::fromStdString(info.GetApiUrl())), row++, 1); - } - - if (info.IsFeature()) - { - addEntry("Feature ID", DebugPrint(info.GetID())); - addEntry("Raw Types", DebugPrint(info.GetTypes())); - } - - auto const layer = info.GetLayer(); - if (layer != feature::LAYER_EMPTY) - addEntry("Layer", std::to_string(layer)); - - using PropID = osm::MapObject::MetadataID; - - if (auto cuisines = info.FormatCuisines(); !cuisines.empty()) - addEntry(DebugPrint(PropID::FMD_CUISINE), cuisines); - - layout->addLayout(grid); - - QDialogButtonBox * dbb = new QDialogButtonBox(); - place_page_dialog::addCommonButtons(this, dbb, info.ShouldShowEditPlace()); - - if (auto const & descr = info.GetWikiDescription(); !descr.empty()) - { - QPushButton * wikiButton = new QPushButton("Wiki Description"); - connect(wikiButton, &QAbstractButton::clicked, this, [this, descr, title]() - { - auto textDialog = TextDialog(this, QString::fromStdString(descr), QString::fromStdString("Wikipedia: " + title)); - textDialog.exec(); - }); - dbb->addButton(wikiButton, QDialogButtonBox::ActionRole); - } - - info.ForEachMetadataReadable([&addEntry](PropID id, std::string const & value) - { - bool isLink = false; - switch (id) - { - case PropID::FMD_EMAIL: - case PropID::FMD_WEBSITE: - case PropID::FMD_CONTACT_FACEBOOK: - case PropID::FMD_CONTACT_INSTAGRAM: - case PropID::FMD_CONTACT_TWITTER: - case PropID::FMD_CONTACT_VK: - case PropID::FMD_CONTACT_LINE: - case PropID::FMD_WIKIPEDIA: - case PropID::FMD_WIKIMEDIA_COMMONS: - isLink = true; - break; - default: - break; - } - - addEntry(DebugPrint(id), value, isLink); - }); - - layout->addWidget(dbb); - setLayout(layout); - - auto const ppTitle = std::string("Place Page") + (info.IsBookmark() ? " (bookmarked)" : ""); - setWindowTitle(ppTitle.c_str()); -} diff --git a/qt/place_page_dialog_developer.hpp b/qt/place_page_dialog_developer.hpp deleted file mode 100644 index 075b58617b..0000000000 --- a/qt/place_page_dialog_developer.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "search/reverse_geocoder.hpp" - -#include - -namespace place_page -{ -class Info; -} - -class PlacePageDialogDeveloper : public QDialog -{ - Q_OBJECT -public: - PlacePageDialogDeveloper(QWidget * parent, place_page::Info const & info, - search::ReverseGeocoder::Address const & address); -}; diff --git a/qt/place_page_dialog_user.hpp b/qt/place_page_dialog_user.hpp deleted file mode 100644 index e02e52fb56..0000000000 --- a/qt/place_page_dialog_user.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "search/reverse_geocoder.hpp" - -#include - -namespace place_page -{ -class Info; -} - -class PlacePageDialogUser : public QDialog -{ - Q_OBJECT -public: - PlacePageDialogUser(QWidget * parent, place_page::Info const & info, - search::ReverseGeocoder::Address const & address); -}; diff --git a/qt/place_page_dialog_user.cpp b/qt/place_panel.cpp similarity index 54% rename from qt/place_page_dialog_user.cpp rename to qt/place_panel.cpp index b792cf305b..56acabb452 100644 --- a/qt/place_page_dialog_user.cpp +++ b/qt/place_panel.cpp @@ -1,5 +1,4 @@ -#include "qt/place_page_dialog_common.hpp" -#include "qt/place_page_dialog_user.hpp" +#include "qt/place_panel.hpp" #include "qt/qt_common/text_dialog.hpp" @@ -8,19 +7,20 @@ #include "platform/settings.hpp" #include +#include #include #include #include #include -#include #include #include namespace { -static int constexpr kMaxLengthOfPlacePageDescription = 500; -static int constexpr kMinWidthOfShortDescription = 390; +constexpr int kMaximumPanelWidthPixels = 390; +constexpr int kMinimumPanelWidthPixels = 200; +constexpr int kMaxLengthOfPlacePageDescription = 500; std::string getShortDescription(const std::string & description) { @@ -58,13 +58,68 @@ public: } }; -PlacePageDialogUser::PlacePageDialogUser(QWidget * parent, place_page::Info const & info, - search::ReverseGeocoder::Address const & address) - : QDialog(parent) +void PlacePanel::addCommonButtons(QDialogButtonBox * dbb, place_page::Info const & info) +{ + dbb->setCenterButtons(true); + + QPushButton * fromButton = new QPushButton("From"); + fromButton->setIcon(QIcon(":/navig64/point-start.png")); + fromButton->setAutoDefault(false); + connect(fromButton, &QAbstractButton::clicked, this, [this, info](){ routeFrom(info); }); + dbb->addButton(fromButton, QDialogButtonBox::ActionRole); + + QPushButton * addStopButton = new QPushButton("Stop"); + addStopButton->setIcon(QIcon(":/navig64/point-intermediate.png")); + addStopButton->setAutoDefault(false); + connect(addStopButton, &QAbstractButton::clicked, this, [this, info](){ addStop(info); }); + dbb->addButton(addStopButton, QDialogButtonBox::ActionRole); + + QPushButton * routeToButton = new QPushButton("To"); + routeToButton->setIcon(QIcon(":/navig64/point-finish.png")); + routeToButton->setAutoDefault(false); + connect(routeToButton, &QAbstractButton::clicked, this, [this, info](){ routeTo(info); }); + dbb->addButton(routeToButton, QDialogButtonBox::ActionRole); + + if (info.ShouldShowEditPlace()) + { + QPushButton * editButton = new QPushButton("Edit Place"); + connect(editButton, &QAbstractButton::clicked, this, [this, info](){ editPlace(info); }); + dbb->addButton(editButton, QDialogButtonBox::AcceptRole); + } +} + +PlacePanel::PlacePanel(QWidget * parent) + : QWidget(parent) +{ + setMaximumWidth(kMaximumPanelWidthPixels); + setMinimumWidth(kMinimumPanelWidthPixels); +} + +void PlacePanel::setPlace(place_page::Info const & info, search::ReverseGeocoder::Address const & address) +{ + bool developerMode; + if (settings::Get(settings::kDeveloperMode, developerMode) && developerMode) + updateInterfaceDeveloper(info, address); + else + updateInterfaceUser(info, address); +} + +void PlacePanel::updateInterfaceUser(place_page::Info const & info, search::ReverseGeocoder::Address const & address) { auto const & title = info.GetTitle(); + DeleteExistingLayout(); + QVBoxLayout * layout = new QVBoxLayout(); + + QScrollArea * scrollArea = new QScrollArea(); + scrollArea->setWidgetResizable(true); + scrollArea->setFrameShape(QFrame::NoFrame); + + QWidget *containerWidget = new QWidget(); + QVBoxLayout * innerLayout = new QVBoxLayout(containerWidget); + containerWidget->setLayout(innerLayout); + { QVBoxLayout * header = new QVBoxLayout(); @@ -89,12 +144,12 @@ PlacePageDialogUser::PlacePageDialogUser(QWidget * parent, place_page::Info cons header->addWidget(addressLabel); } - layout->addLayout(header); + innerLayout->addLayout(header); } { QHLine * line = new QHLine(); - layout->addWidget(line); + innerLayout->addWidget(line); } { @@ -249,24 +304,168 @@ PlacePageDialogUser::PlacePageDialogUser(QWidget * parent, place_page::Info cons data->setColumnStretch(0, 0); data->setColumnStretch(1, 1); - layout->addLayout(data); + innerLayout->addLayout(data); } - layout->addStretch(); + innerLayout->addStretch(); { QHLine * line = new QHLine(); - layout->addWidget(line); + innerLayout->addWidget(line); } + scrollArea->setWidget(containerWidget); + + layout->addWidget(scrollArea); + { QDialogButtonBox * dbb = new QDialogButtonBox(); - place_page_dialog::addCommonButtons(this, dbb, info.ShouldShowEditPlace()); + addCommonButtons(dbb, info); layout->addWidget(dbb, Qt::AlignCenter); } setLayout(layout); - - auto const ppTitle = std::string("Place Page") + (info.IsBookmark() ? " (bookmarked)" : ""); - setWindowTitle(ppTitle.c_str()); +} + +void PlacePanel::updateInterfaceDeveloper(place_page::Info const & info, + search::ReverseGeocoder::Address const & address) +{ + DeleteExistingLayout(); + + QVBoxLayout * layout = new QVBoxLayout(); + + QScrollArea * scrollArea = new QScrollArea(); + scrollArea->setWidgetResizable(true); + scrollArea->setFrameShape(QFrame::NoFrame); + + QWidget *containerWidget = new QWidget(); + QGridLayout * grid = new QGridLayout(containerWidget); + containerWidget->setLayout(grid); + + int row = 0; + + auto const addEntry = [grid, &row](std::string const & key, std::string const & value, bool isLink = false) + { + grid->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); + label->setTextInteractionFlags(Qt::TextBrowserInteraction); + label->setText(QString::fromStdString("" + value + "")); + } + grid->addWidget(label, row++, 1); + return label; + }; + + { + ms::LatLon const ll = info.GetLatLon(); + addEntry("lat, lon", strings::to_string_dac(ll.m_lat, 7) + ", " + strings::to_string_dac(ll.m_lon, 7)); + } + + addEntry("CountryId", info.GetCountryId()); + + auto const & title = info.GetTitle(); + if (!title.empty()) + addEntry("Title", title); + + if (auto const & subTitle = info.GetSubtitle(); !subTitle.empty()) + addEntry("Subtitle", subTitle); + + addEntry("Address", address.FormatAddress()); + + if (info.IsBookmark()) + { + grid->addWidget(new QLabel("Bookmark"), row, 0); + grid->addWidget(new QLabel("Yes"), row++, 1); + } + + if (info.IsMyPosition()) + { + grid->addWidget(new QLabel("MyPosition"), row, 0); + grid->addWidget(new QLabel("Yes"), row++, 1); + } + + if (info.HasApiUrl()) + { + grid->addWidget(new QLabel("Api URL"), row, 0); + grid->addWidget(new QLabel(QString::fromStdString(info.GetApiUrl())), row++, 1); + } + + if (info.IsFeature()) + { + addEntry("Feature ID", DebugPrint(info.GetID())); + addEntry("Raw Types", DebugPrint(info.GetTypes())); + } + + auto const layer = info.GetLayer(); + if (layer != feature::LAYER_EMPTY) + addEntry("Layer", std::to_string(layer)); + + using PropID = osm::MapObject::MetadataID; + + if (auto cuisines = info.FormatCuisines(); !cuisines.empty()) + addEntry(DebugPrint(PropID::FMD_CUISINE), cuisines); + + QDialogButtonBox * dbb = new QDialogButtonBox(); + addCommonButtons(dbb, info); + + if (auto const & descr = info.GetWikiDescription(); !descr.empty()) + { + QPushButton * wikiButton = new QPushButton("Wiki"); + connect(wikiButton, &QAbstractButton::clicked, this, [this, descr, title]() + { + auto textDialog = TextDialog(this, QString::fromStdString(descr), QString::fromStdString("Wikipedia: " + title)); + textDialog.exec(); + }); + dbb->addButton(wikiButton, QDialogButtonBox::ActionRole); + } + + info.ForEachMetadataReadable([&addEntry](PropID id, std::string const & value) + { + bool isLink = false; + switch (id) + { + case PropID::FMD_EMAIL: + case PropID::FMD_WEBSITE: + case PropID::FMD_CONTACT_FACEBOOK: + case PropID::FMD_CONTACT_INSTAGRAM: + case PropID::FMD_CONTACT_TWITTER: + case PropID::FMD_CONTACT_VK: + case PropID::FMD_CONTACT_LINE: + case PropID::FMD_WIKIPEDIA: + case PropID::FMD_WIKIMEDIA_COMMONS: + isLink = true; + break; + default: + break; + } + + addEntry(DebugPrint(id), value, isLink); + }); + + // Stretch last row, to make grid appear at the top of the panel. + grid->setRowStretch(row, 1); + // Stretch 2nd column + grid->setColumnStretch(1, 1); + + scrollArea->setWidget(containerWidget); + + layout->addWidget(scrollArea); + + layout->addWidget(dbb); + + setLayout(layout); +} + +void PlacePanel::DeleteExistingLayout() +{ + if (this->layout() != nullptr) + { + // Delete layout, and all sub-layouts and children widgets. + // https://stackoverflow.com/questions/7528680/how-to-delete-an-already-existing-layout-on-a-widget + QWidget().setLayout(this->layout()); + } } diff --git a/qt/place_panel.hpp b/qt/place_panel.hpp new file mode 100644 index 0000000000..04ee001eb1 --- /dev/null +++ b/qt/place_panel.hpp @@ -0,0 +1,51 @@ +#pragma once + +#include "search/reverse_geocoder.hpp" +#include +#include +#include + +namespace place_page +{ +class Info; +} + +namespace place_panel +{ +enum PressedButton : int +{ + Close = QDialog::Rejected, + RouteFrom, + AddStop, + RouteTo, + EditPlace +}; + +} + +class PlacePanel : public QWidget +{ + Q_OBJECT + +public: + PlacePanel(QWidget * parent); + + void setPlace(place_page::Info const & info, search::ReverseGeocoder::Address const & address); + +signals: + void showPlace(); + void hidePlace(); + void routeFrom(place_page::Info const & info); + void addStop(place_page::Info const & info); + void routeTo(place_page::Info const & info); + void editPlace(place_page::Info const & info); + +protected: + void addCommonButtons(QDialogButtonBox * dbb, place_page::Info const & info); + +private: + void updateInterfaceDeveloper(place_page::Info const & info, search::ReverseGeocoder::Address const & address); + void updateInterfaceUser(place_page::Info const & info, search::ReverseGeocoder::Address const & address); + + void DeleteExistingLayout(); +};