File indexing completed on 2025-01-05 03:58:37

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2009-12-01
0007  * Description : world map widget library - UI Setup
0008  *
0009  * SPDX-FileCopyrightText: 2010-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  * SPDX-FileCopyrightText: 2009-2011 by Michael G. Hansen <mike at mghansen dot de>
0011  * SPDX-FileCopyrightText:      2014 by Justus Schwartz <justus at gmx dot li>
0012  *
0013  * SPDX-License-Identifier: GPL-2.0-or-later
0014  *
0015  * ============================================================ */
0016 
0017 #include "mapwidget_p.h"
0018 
0019 namespace Digikam
0020 {
0021 
0022 QAction* MapWidget::getControlAction(const QString& actionName)
0023 {
0024     if      (actionName == QLatin1String("zoomin"))
0025     {
0026         return d->actionZoomIn;
0027     }
0028     else if (actionName == QLatin1String("zoomout"))
0029     {
0030         return d->actionZoomOut;
0031     }
0032     else if (actionName == QLatin1String("mousemode-regionselectionmode"))
0033     {
0034         return d->actionSetRegionSelectionMode;
0035     }
0036     else if (actionName == QLatin1String("mousemode-removecurrentregionselection"))
0037     {
0038         return d->actionRemoveCurrentRegionSelection;
0039     }
0040     else if (actionName == QLatin1String("mousemode-regionselectionfromiconmode"))
0041     {
0042         return d->actionSetRegionSelectionFromIconMode;
0043     }
0044     else if (actionName == QLatin1String("mousemode-removefilter"))
0045     {
0046         return d->actionRemoveFilter;
0047     }
0048 
0049     return nullptr;
0050 }
0051 
0052 QWidget* MapWidget::getControlWidget()
0053 {
0054     if (!d->controlWidget)
0055     {
0056         d->controlWidget                           = new QWidget(this);
0057         QHBoxLayout* const controlWidgetHBoxLayout = new QHBoxLayout(d->controlWidget);
0058         controlWidgetHBoxLayout->setContentsMargins(QMargins());
0059 
0060         QPushButton* const configurationButton = new QPushButton(d->controlWidget);
0061         configurationButton->setIcon(QIcon::fromTheme(QLatin1String("globe")));
0062         controlWidgetHBoxLayout->addWidget(configurationButton);
0063         configurationButton->setToolTip(i18n("Map settings"));
0064         configurationButton->setMenu(d->configurationMenu);
0065 
0066         QToolButton* const zoomInButton = new QToolButton(d->controlWidget);
0067         controlWidgetHBoxLayout->addWidget(zoomInButton);
0068         zoomInButton->setDefaultAction(d->actionZoomIn);
0069 
0070         QToolButton* const zoomOutButton = new QToolButton(d->controlWidget);
0071         controlWidgetHBoxLayout->addWidget(zoomOutButton);
0072         zoomOutButton->setDefaultAction(d->actionZoomOut);
0073 
0074         QToolButton* const showThumbnailsButton = new QToolButton(d->controlWidget);
0075         controlWidgetHBoxLayout->addWidget(showThumbnailsButton);
0076         showThumbnailsButton->setDefaultAction(d->actionShowThumbnails);
0077 
0078         QFrame* const vline1 = new QFrame(d->controlWidget);
0079         vline1->setLineWidth(1);
0080         vline1->setMidLineWidth(0);
0081         vline1->setFrameShape(QFrame::VLine);
0082         vline1->setFrameShadow(QFrame::Sunken);
0083         vline1->setMinimumSize(2, 0);
0084         vline1->updateGeometry();
0085         controlWidgetHBoxLayout->addWidget(vline1);
0086 
0087         QToolButton* const increaseThumbnailSizeButton = new QToolButton(d->controlWidget);
0088         controlWidgetHBoxLayout->addWidget(increaseThumbnailSizeButton);
0089         increaseThumbnailSizeButton->setDefaultAction(d->actionIncreaseThumbnailSize);
0090 
0091         QToolButton* const decreaseThumbnailSizeButton = new QToolButton(d->controlWidget);
0092         controlWidgetHBoxLayout->addWidget(decreaseThumbnailSizeButton);
0093         decreaseThumbnailSizeButton->setDefaultAction(d->actionDecreaseThumbnailSize);
0094 
0095         /* --- --- --- */
0096 
0097         d->mouseModesHolder                           = new QWidget(d->controlWidget);
0098         QHBoxLayout* const mouseModesHolderHBoxLayout = new QHBoxLayout(d->mouseModesHolder);
0099         mouseModesHolderHBoxLayout->setContentsMargins(QMargins());
0100         controlWidgetHBoxLayout->addWidget(d->mouseModesHolder);
0101 
0102         QFrame* const vline2 = new QFrame(d->mouseModesHolder);
0103         vline2->setLineWidth(1);
0104         vline2->setMidLineWidth(0);
0105         vline2->setFrameShape(QFrame::VLine);
0106         vline2->setFrameShadow(QFrame::Sunken);
0107         vline2->setMinimumSize(2, 0);
0108         vline2->updateGeometry();
0109         mouseModesHolderHBoxLayout->addWidget(vline2);
0110 
0111         d->setPanModeButton = new QToolButton(d->mouseModesHolder);
0112         mouseModesHolderHBoxLayout->addWidget(d->setPanModeButton);
0113         d->setPanModeButton->setDefaultAction(d->actionSetPanMode);
0114 
0115         d->setSelectionModeButton = new QToolButton(d->mouseModesHolder);
0116         mouseModesHolderHBoxLayout->addWidget(d->setSelectionModeButton);
0117         d->setSelectionModeButton->setDefaultAction(d->actionSetRegionSelectionMode);
0118 
0119         d->setRegionSelectionFromIconModeButton = new QToolButton(d->mouseModesHolder);
0120         mouseModesHolderHBoxLayout->addWidget(d->setRegionSelectionFromIconModeButton);
0121         d->setRegionSelectionFromIconModeButton->setDefaultAction(d->actionSetRegionSelectionFromIconMode);
0122 
0123         d->removeCurrentSelectionButton = new QToolButton(d->mouseModesHolder);
0124         mouseModesHolderHBoxLayout->addWidget(d->removeCurrentSelectionButton);
0125         d->removeCurrentSelectionButton->setDefaultAction(d->actionRemoveCurrentRegionSelection);
0126 
0127         d->setZoomModeButton = new QToolButton(d->mouseModesHolder);
0128         mouseModesHolderHBoxLayout->addWidget(d->setZoomModeButton);
0129         d->setZoomModeButton->setDefaultAction(d->actionSetZoomIntoGroupMode);
0130 
0131         d->setFilterModeButton = new QToolButton(d->mouseModesHolder);
0132         mouseModesHolderHBoxLayout->addWidget(d->setFilterModeButton);
0133         d->setFilterModeButton->setDefaultAction(d->actionSetFilterMode);
0134 
0135         d->removeFilterModeButton = new QToolButton(d->mouseModesHolder);
0136         mouseModesHolderHBoxLayout->addWidget(d->removeFilterModeButton);
0137         d->removeFilterModeButton->setDefaultAction(d->actionRemoveFilter);
0138 
0139         d->setSelectThumbnailMode = new QToolButton(d->mouseModesHolder);
0140         mouseModesHolderHBoxLayout->addWidget(d->setSelectThumbnailMode);
0141         d->setSelectThumbnailMode->setDefaultAction(d->actionSetSelectThumbnailMode);
0142 
0143         d->buttonStickyMode = new QToolButton(d->controlWidget);
0144         controlWidgetHBoxLayout->addWidget(d->buttonStickyMode);
0145         d->buttonStickyMode->setDefaultAction(d->actionStickyMode);
0146 
0147         d->hBoxForAdditionalControlWidgetItems = new QWidget(d->controlWidget);
0148         QHBoxLayout *hBoxForAdditionalControlWidgetItemsHBoxLayout = new QHBoxLayout(d->hBoxForAdditionalControlWidgetItems);
0149         hBoxForAdditionalControlWidgetItemsHBoxLayout->setContentsMargins(QMargins());
0150         controlWidgetHBoxLayout->addWidget(d->hBoxForAdditionalControlWidgetItems);
0151 
0152         d->loadTracksFromAlbums = new QToolButton(d->controlWidget);
0153         hBoxForAdditionalControlWidgetItemsHBoxLayout->addWidget(d->loadTracksFromAlbums);
0154         d->loadTracksFromAlbums->setDefaultAction(d->actionLoadTracksFromAlbums);
0155 
0156         setVisibleMouseModes(s->visibleMouseModes);
0157         setVisibleExtraActions(d->visibleExtraActions);
0158 
0159         // add stretch after the controls:
0160 
0161         QHBoxLayout* const hBoxLayout = reinterpret_cast<QHBoxLayout*>(d->controlWidget->layout());
0162 
0163         if (hBoxLayout)
0164         {
0165             hBoxLayout->addStretch();
0166         }
0167     }
0168 
0169     // make sure the menu exists, even if no backend has been set:
0170 
0171     rebuildConfigurationMenu();
0172 
0173     return d->controlWidget;
0174 }
0175 
0176 void MapWidget::addWidgetToControlWidget(QWidget* const newWidget)
0177 {
0178     // make sure the control widget exists
0179 
0180     if (!d->controlWidget)
0181     {
0182         getControlWidget();
0183     }
0184 
0185     QHBoxLayout* const hBoxLayout = reinterpret_cast<QHBoxLayout*>(d->hBoxForAdditionalControlWidgetItems->layout());
0186 
0187     if (hBoxLayout)
0188     {
0189         hBoxLayout->addWidget(newWidget);
0190     }
0191 }
0192 
0193 void MapWidget::setActive(const bool state)
0194 {
0195     const bool oldState = s->activeState;
0196     s->activeState      = state;
0197 
0198     if (d->currentBackend)
0199     {
0200         d->currentBackend->setActive(state);
0201     }
0202 
0203     if (s->markerModel)
0204     {
0205         s->markerModel->setActive(state);
0206     }
0207 
0208     if (state)
0209     {
0210         // do we have a map widget shown?
0211 
0212         if ((d->stackedLayout->count() == 1) && d->currentBackend)
0213         {
0214             setMapWidgetInFrame(d->currentBackend->mapWidget());
0215 
0216             // call this slot manually in case the backend was ready right away:
0217 
0218             if (d->currentBackend->isReady())
0219             {
0220                 slotBackendReadyChanged(d->currentBackendName);
0221             }
0222             else
0223             {
0224                 rebuildConfigurationMenu();
0225             }
0226         }
0227     }
0228 
0229     if (state && !oldState && s->tileGrouper->getClustersDirty())
0230     {
0231         slotRequestLazyReclustering();
0232     }
0233 }
0234 
0235 bool MapWidget::getActiveState()
0236 {
0237     return s->activeState;
0238 }
0239 
0240 void MapWidget::setVisibleMouseModes(const GeoMouseModes mouseModes)
0241 {
0242     s->visibleMouseModes = mouseModes;
0243 
0244     if (d->mouseModesHolder)
0245     {
0246         d->mouseModesHolder->setVisible(s->visibleMouseModes);
0247         d->setSelectionModeButton->setVisible(s->visibleMouseModes.testFlag(MouseModeRegionSelection));
0248         d->removeCurrentSelectionButton->setVisible(s->visibleMouseModes.testFlag(MouseModeRegionSelection));
0249         d->setPanModeButton->setVisible(s->visibleMouseModes.testFlag(MouseModePan));
0250         d->setZoomModeButton->setVisible(s->visibleMouseModes.testFlag(MouseModeZoomIntoGroup));
0251         d->setRegionSelectionFromIconModeButton->setVisible(s->visibleMouseModes.testFlag(MouseModeRegionSelectionFromIcon));
0252         d->setFilterModeButton->setVisible(s->visibleMouseModes.testFlag(MouseModeFilter));
0253         d->removeFilterModeButton->setVisible(s->visibleMouseModes.testFlag(MouseModeFilter));
0254         d->setSelectThumbnailMode->setVisible(s->visibleMouseModes.testFlag(MouseModeSelectThumbnail));
0255     }
0256 }
0257 
0258 void MapWidget::setAvailableMouseModes(const GeoMouseModes mouseModes)
0259 {
0260     s->availableMouseModes = mouseModes;
0261 }
0262 
0263 bool MapWidget::getStickyModeState() const
0264 {
0265     return d->actionStickyMode->isChecked();
0266 }
0267 
0268 void MapWidget::setStickyModeState(const bool state)
0269 {
0270     d->actionStickyMode->setChecked(state);
0271 
0272     slotUpdateActionsEnabled();
0273 }
0274 
0275 void MapWidget::setVisibleExtraActions(const GeoExtraActions actions)
0276 {
0277     d->visibleExtraActions = actions;
0278 
0279     if (d->buttonStickyMode)
0280     {
0281         d->buttonStickyMode->setVisible(actions.testFlag(ExtraActionSticky));
0282     }
0283 
0284     if (d->loadTracksFromAlbums)
0285     {
0286         d->loadTracksFromAlbums->setVisible(actions.testFlag(ExtraLoadTracks));
0287     }
0288 
0289     slotUpdateActionsEnabled();
0290 }
0291 
0292 void MapWidget::setEnabledExtraActions(const GeoExtraActions actions)
0293 {
0294     d->availableExtraActions = actions;
0295 
0296     slotUpdateActionsEnabled();
0297 }
0298 
0299 void MapWidget::slotStickyModeChanged()
0300 {
0301     slotUpdateActionsEnabled();
0302 
0303     Q_EMIT signalStickyModeChanged();
0304 }
0305 
0306 void MapWidget::setAllowModifications(const bool state)
0307 {
0308     s->modificationsAllowed = state;
0309 
0310     slotUpdateActionsEnabled();
0311     slotRequestLazyReclustering();
0312 }
0313 
0314 void MapWidget::slotMouseModeChanged(QAction* triggeredAction)
0315 {
0316     // determine the new mouse mode:
0317 
0318     const QVariant triggeredActionData = triggeredAction->data();
0319     const GeoMouseModes newMouseMode   = triggeredActionData.value<Digikam::GeoMouseModes>();
0320 
0321     if (newMouseMode == s->currentMouseMode)
0322     {
0323         return;
0324     }
0325 
0326     // store the new mouse mode:
0327 
0328     s->currentMouseMode = newMouseMode;
0329 
0330     if (d->currentBackend)
0331     {
0332         d->currentBackend->mouseModeChanged();
0333     }
0334 
0335     Q_EMIT signalMouseModeChanged(s->currentMouseMode);
0336 
0337     /// @todo Update action availability?
0338 }
0339 
0340 void MapWidget::setMouseMode(const GeoMouseModes mouseMode)
0341 {
0342     s->currentMouseMode = mouseMode;
0343 
0344     if (currentBackendReady())
0345     {
0346         d->currentBackend->mouseModeChanged();
0347     }
0348 
0349     slotUpdateActionsEnabled();
0350 }
0351 
0352 void MapWidget::setSortOptionsMenu(QMenu* const sortMenu)
0353 {
0354     d->sortMenu = sortMenu;
0355 
0356     rebuildConfigurationMenu();
0357 }
0358 
0359 void MapWidget::slotUpdateActionsEnabled()
0360 {
0361     if (!s->activeState)
0362     {
0363         // this widget is not active, no need to update the action availability
0364 
0365         return;
0366     }
0367 
0368     d->actionDecreaseThumbnailSize->setEnabled((s->showThumbnails)&&(s->thumbnailSize>GeoIfaceMinThumbnailSize));
0369 
0370     /// @todo Define an upper limit for the thumbnail size!
0371 
0372     d->actionIncreaseThumbnailSize->setEnabled(s->showThumbnails);
0373 
0374     d->actionSetRegionSelectionMode->setEnabled(s->availableMouseModes.testFlag(MouseModeRegionSelection));
0375 
0376     d->actionSetPanMode->setEnabled(s->availableMouseModes.testFlag(MouseModePan));
0377     d->actionSetZoomIntoGroupMode->setEnabled(s->availableMouseModes.testFlag(MouseModeZoomIntoGroup));
0378     d->actionSetRegionSelectionFromIconMode->setEnabled(s->availableMouseModes.testFlag(MouseModeRegionSelectionFromIcon));
0379     d->actionSetFilterMode->setEnabled(s->availableMouseModes.testFlag(MouseModeFilter));
0380     d->actionSetSelectThumbnailMode->setEnabled(s->availableMouseModes.testFlag(MouseModeSelectThumbnail));
0381 
0382     // the 'Remove X' actions are only available if the corresponding X is actually there:
0383 
0384     bool clearRegionSelectionAvailable = s->availableMouseModes.testFlag(MouseModeRegionSelection);
0385 
0386     if (clearRegionSelectionAvailable && s->markerModel)
0387     {
0388         clearRegionSelectionAvailable = s->markerModel->getGlobalGroupState() & RegionSelectedMask;
0389     }
0390 
0391     d->actionRemoveCurrentRegionSelection->setEnabled(clearRegionSelectionAvailable);
0392     bool clearFilterAvailable = s->availableMouseModes.testFlag(MouseModeRegionSelectionFromIcon);
0393 
0394     if (clearFilterAvailable && s->markerModel)
0395     {
0396         clearFilterAvailable = s->markerModel->getGlobalGroupState() & FilteredPositiveMask;
0397     }
0398 
0399     d->actionRemoveFilter->setEnabled(clearFilterAvailable);
0400 
0401     d->actionStickyMode->setEnabled(d->availableExtraActions.testFlag(ExtraActionSticky));
0402 
0403     /// @todo Only set the icons if they have to be changed!
0404 
0405     d->actionStickyMode->setIcon(QIcon::fromTheme(QLatin1String(d->actionStickyMode->isChecked()
0406                                                                 ? "document-encrypted"
0407                                                                 : "document-decrypt")));
0408     d->actionShowThumbnails->setIcon(d->actionShowThumbnails->isChecked()
0409                                      ? QIcon::fromTheme(QLatin1String("folder-pictures"))
0410                                      : GeoIfaceGlobalObject::instance()->getMarkerPixmap(QLatin1String("marker-icon-16x16")));
0411 
0412     // make sure the action for the current mouse mode is checked
0413 
0414     const QList<QAction*> mouseModeActions = d->mouseModeActionGroup->actions();
0415 
0416     Q_FOREACH (QAction* const action, mouseModeActions)
0417     {
0418         if (action->data().value<GeoMouseModes>() == s->currentMouseMode)
0419         {   // cppcheck-suppress useStlAlgorithm
0420             action->setChecked(true);
0421             break;
0422         }
0423     }
0424 }
0425 
0426 void MapWidget::rebuildConfigurationMenu()
0427 {
0428     d->configurationMenu->clear();
0429     const QList<QAction*> backendSelectionActions = d->actionGroupBackendSelection->actions();
0430 
0431     for (int i = 0 ; i < backendSelectionActions.count() ; ++i)
0432     {
0433         QAction* const backendAction = backendSelectionActions.at(i);
0434 
0435         if (backendAction->data().toString() == d->currentBackendName)
0436         {
0437             backendAction->setChecked(true);
0438         }
0439 
0440         d->configurationMenu->addAction(backendAction);
0441     }
0442 
0443     if (currentBackendReady())
0444     {
0445         d->currentBackend->addActionsToConfigurationMenu(d->configurationMenu);
0446     }
0447 
0448     if (s->showThumbnails)
0449     {
0450         d->configurationMenu->addSeparator();
0451 
0452         if (d->sortMenu)
0453         {
0454             d->configurationMenu->addMenu(d->sortMenu);
0455         }
0456 
0457         d->configurationMenu->addAction(d->actionPreviewSingleItems);
0458         d->configurationMenu->addAction(d->actionPreviewGroupedItems);
0459         d->configurationMenu->addAction(d->actionShowNumbersOnItems);
0460     }
0461 
0462     slotUpdateActionsEnabled();
0463 }
0464 
0465 void MapWidget::createActions()
0466 {
0467     d->actionZoomIn  = new QAction(this);
0468     d->actionZoomIn->setIcon(QIcon::fromTheme(QLatin1String("zoom-in")));
0469     d->actionZoomIn->setToolTip(i18n("Zoom in"));
0470 
0471     connect(d->actionZoomIn, &QAction::triggered,
0472             this, &MapWidget::slotZoomIn);
0473 
0474     d->actionZoomOut = new QAction(this);
0475     d->actionZoomOut->setIcon(QIcon::fromTheme(QLatin1String("zoom-out")));
0476     d->actionZoomOut->setToolTip(i18n("Zoom out"));
0477 
0478     connect(d->actionZoomOut, &QAction::triggered,
0479             this, &MapWidget::slotZoomOut);
0480 
0481     d->actionShowThumbnails = new QAction(this);
0482     d->actionShowThumbnails->setToolTip(i18n("Switch between markers and thumbnails."));
0483     d->actionShowThumbnails->setCheckable(true);
0484     d->actionShowThumbnails->setChecked(true);
0485 
0486     connect(d->actionShowThumbnails, &QAction::triggered,
0487             this, &MapWidget::slotShowThumbnailsChanged);
0488 
0489     // create backend selection entries:
0490 
0491     d->actionGroupBackendSelection = new QActionGroup(this);
0492     d->actionGroupBackendSelection->setExclusive(true);
0493 
0494     connect(d->actionGroupBackendSelection, &QActionGroup::triggered,
0495             this, &MapWidget::slotChangeBackend);
0496 
0497     createActionsForBackendSelection();
0498 
0499     d->configurationMenu         = new QMenu(this);
0500     d->actionPreviewSingleItems  = new QAction(i18n("Preview single items"), this);
0501     d->actionPreviewSingleItems->setCheckable(true);
0502     d->actionPreviewSingleItems->setChecked(true);
0503     d->actionPreviewGroupedItems = new QAction(i18n("Preview grouped items"), this);
0504     d->actionPreviewGroupedItems->setCheckable(true);
0505     d->actionPreviewGroupedItems->setChecked(true);
0506     d->actionShowNumbersOnItems  = new QAction(i18n("Show numbers"), this);
0507     d->actionShowNumbersOnItems->setCheckable(true);
0508     d->actionShowNumbersOnItems->setChecked(true);
0509 
0510     d->actionIncreaseThumbnailSize = new QAction(this);
0511     d->actionIncreaseThumbnailSize->setIcon(QIcon::fromTheme(QLatin1String("list-add")));
0512     d->actionIncreaseThumbnailSize->setToolTip(i18n("Increase the thumbnail size on the map"));
0513     d->actionDecreaseThumbnailSize = new QAction(this);
0514     d->actionDecreaseThumbnailSize->setIcon(QIcon::fromTheme(QLatin1String("list-remove")));
0515     d->actionDecreaseThumbnailSize->setToolTip(i18n("Decrease the thumbnail size on the map"));
0516 
0517     d->actionRemoveCurrentRegionSelection = new QAction(this);
0518 /*
0519     d->actionRemoveCurrentRegionSelection->setEnabled(false);
0520 */
0521     d->actionRemoveCurrentRegionSelection->setIcon(QIcon::fromTheme(QLatin1String("edit-clear")));
0522     d->actionRemoveCurrentRegionSelection->setToolTip(i18n("Remove the current region selection"));
0523 
0524     d->mouseModeActionGroup = new QActionGroup(this);
0525     d->mouseModeActionGroup->setExclusive(true);
0526 
0527     d->actionSetRegionSelectionMode = new QAction(d->mouseModeActionGroup);
0528     d->actionSetRegionSelectionMode->setCheckable(true);
0529     d->actionSetRegionSelectionMode->setIcon(QIcon::fromTheme(QLatin1String("select-rectangular")));
0530     d->actionSetRegionSelectionMode->setToolTip(i18n("Select images by drawing a rectangle"));
0531     d->actionSetRegionSelectionMode->setData(QVariant::fromValue<Digikam::GeoMouseModes>(MouseModeRegionSelection));
0532 
0533     d->actionSetPanMode = new QAction(d->mouseModeActionGroup);
0534     d->actionSetPanMode->setCheckable(true);
0535     d->actionSetPanMode->setToolTip(i18n("Pan mode"));
0536     d->actionSetPanMode->setIcon(QIcon::fromTheme(QLatin1String("transform-move")));
0537     d->actionSetPanMode->setChecked(true);
0538     d->actionSetPanMode->setData(QVariant::fromValue<Digikam::GeoMouseModes>(MouseModePan));
0539 
0540     d->actionSetZoomIntoGroupMode = new QAction(d->mouseModeActionGroup);
0541     d->actionSetZoomIntoGroupMode->setCheckable(true);
0542     d->actionSetZoomIntoGroupMode->setToolTip(i18n("Zoom into a group"));
0543     d->actionSetZoomIntoGroupMode->setIcon(QIcon::fromTheme(QLatin1String("zoom-fit-best")));
0544     d->actionSetZoomIntoGroupMode->setData(QVariant::fromValue<Digikam::GeoMouseModes>(MouseModeZoomIntoGroup));
0545 
0546     d->actionSetRegionSelectionFromIconMode = new QAction(d->mouseModeActionGroup);
0547     d->actionSetRegionSelectionFromIconMode->setCheckable(true);
0548     d->actionSetRegionSelectionFromIconMode->setToolTip(i18n("Create a region selection from a thumbnail"));
0549     d->actionSetRegionSelectionFromIconMode->setIcon(QIcon::fromTheme(QLatin1String("edit-node")));
0550     d->actionSetRegionSelectionFromIconMode->setData(QVariant::fromValue<Digikam::GeoMouseModes>(MouseModeRegionSelectionFromIcon));
0551 
0552     d->actionSetFilterMode = new QAction(d->mouseModeActionGroup);
0553     d->actionSetFilterMode->setCheckable(true);
0554     d->actionSetFilterMode->setToolTip(i18n("Filter images"));
0555     d->actionSetFilterMode->setIcon(QIcon::fromTheme(QLatin1String("view-filter")));
0556     d->actionSetFilterMode->setData(QVariant::fromValue<Digikam::GeoMouseModes>(MouseModeFilter));
0557 
0558     d->actionRemoveFilter = new QAction(this);
0559     d->actionRemoveFilter->setToolTip(i18n("Remove the current filter"));
0560     d->actionRemoveFilter->setIcon(QIcon::fromTheme(QLatin1String("window-close")));
0561 
0562     d->actionSetSelectThumbnailMode = new QAction(d->mouseModeActionGroup);
0563     d->actionSetSelectThumbnailMode->setCheckable(true);
0564     d->actionSetSelectThumbnailMode->setToolTip(i18n("Select images"));
0565     d->actionSetSelectThumbnailMode->setIcon(QIcon::fromTheme(QLatin1String("edit-select")));
0566     d->actionSetSelectThumbnailMode->setData(QVariant::fromValue<Digikam::GeoMouseModes>(MouseModeSelectThumbnail));
0567 
0568     d->actionStickyMode = new QAction(this);
0569     d->actionStickyMode->setCheckable(true);
0570     d->actionStickyMode->setToolTip(i18n("Lock the map position"));
0571 
0572     d->actionLoadTracksFromAlbums = new QAction(this);
0573     d->actionLoadTracksFromAlbums->setToolTip(i18n("Load tracks from albums"));
0574     d->actionLoadTracksFromAlbums->setIcon(QIcon::fromTheme(QLatin1String("draw-polyline")));
0575 
0576     connect(d->actionStickyMode, &QAction::triggered,
0577             this, &MapWidget::slotStickyModeChanged);
0578 
0579     connect(d->actionIncreaseThumbnailSize, &QAction::triggered,
0580             this, &MapWidget::slotIncreaseThumbnailSize);
0581 
0582     connect(d->actionDecreaseThumbnailSize, &QAction::triggered,
0583             this, &MapWidget::slotDecreaseThumbnailSize);
0584 
0585     connect(d->actionPreviewSingleItems, &QAction::changed,
0586             this, &MapWidget::slotItemDisplaySettingsChanged);
0587 
0588     connect(d->actionPreviewGroupedItems, &QAction::changed,
0589             this, &MapWidget::slotItemDisplaySettingsChanged);
0590 
0591     connect(d->actionShowNumbersOnItems, &QAction::changed,
0592             this, &MapWidget::slotItemDisplaySettingsChanged);
0593 
0594     connect(d->mouseModeActionGroup, &QActionGroup::triggered,
0595             this, &MapWidget::slotMouseModeChanged);
0596 
0597     connect(d->actionRemoveFilter, &QAction::triggered,
0598             this, &MapWidget::signalRemoveCurrentFilter);
0599 
0600     connect(d->actionRemoveCurrentRegionSelection, &QAction::triggered,
0601             this, &MapWidget::slotRemoveCurrentRegionSelection);
0602 
0603     connect(d->actionLoadTracksFromAlbums, &QAction::triggered,
0604             this, &MapWidget::signalLoadTracksFromAlbums);
0605 }
0606 
0607 void MapWidget::createActionsForBackendSelection()
0608 {
0609     // delete the existing actions:
0610 
0611     qDeleteAll(d->actionGroupBackendSelection->actions());
0612 
0613     // create actions for all backends:
0614 
0615     for (int i = 0 ; i < d->loadedBackends.size() ; ++i)
0616     {
0617         const QString backendName    = d->loadedBackends.at(i)->backendName();
0618         QAction* const backendAction = new QAction(d->actionGroupBackendSelection);
0619         backendAction->setData(backendName);
0620         backendAction->setText(d->loadedBackends.at(i)->backendHumanName());
0621         backendAction->setCheckable(true);
0622     }
0623 }
0624 
0625 void MapWidget::dropEvent(QDropEvent* event)
0626 {
0627     // remove the drag marker:
0628 /*
0629     d->currentBackend->updateDragDropMarker(QPoint(), 0);
0630 */
0631     if (!d->dragDropHandler)
0632     {
0633         event->ignore();
0634         return;
0635     }
0636 
0637     GeoCoordinates dropCoordinates;
0638 
0639 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
0640 
0641     if (!d->currentBackend->geoCoordinates(event->position().toPoint(), &dropCoordinates))
0642 
0643 #else
0644 
0645     if (!d->currentBackend->geoCoordinates(event->pos(), &dropCoordinates))
0646 
0647 #endif
0648 
0649     {
0650         return;
0651     }
0652 
0653     // the drag and drop handler handled the drop if it returned true here
0654 
0655     if (d->dragDropHandler->dropEvent(event, dropCoordinates))
0656     {
0657         event->acceptProposedAction();
0658     }
0659 }
0660 
0661 void MapWidget::dragLeaveEvent(QDragLeaveEvent* event)
0662 {
0663     Q_UNUSED(event);
0664 
0665     // remove the marker:
0666 /*
0667     d->currentBackend->updateDragDropMarker(QPoint(), 0);
0668 */
0669 }
0670 
0671 void MapWidget::dragEnterEvent(QDragEnterEvent* event)
0672 {
0673     /// @todo ignore drops if no marker tiler or model can accept them
0674 
0675     if (!d->dragDropHandler)
0676     {
0677         event->ignore();
0678         return;
0679     }
0680 
0681     if (d->dragDropHandler->accepts(event) == Qt::IgnoreAction)
0682     {
0683         event->ignore();
0684         return;
0685     }
0686 
0687     /// @todo need data about the dragged object: #markers, selected, icon, ...
0688 
0689     event->accept();
0690 }
0691 
0692 void MapWidget::dragMoveEvent(QDragMoveEvent* event)
0693 {
0694     if (!d->dragDropHandler)
0695     {
0696         event->ignore();
0697         return;
0698     }
0699 
0700     event->accept();
0701 }
0702 
0703 } // namespace Digikam