File indexing completed on 2025-01-19 03:58:12
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2008-05-30 0007 * Description : GPS search sidebar tab contents. 0008 * 0009 * SPDX-FileCopyrightText: 2008-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * SPDX-FileCopyrightText: 2009 by Johannes Wienke <languitar at semipol dot de> 0011 * SPDX-FileCopyrightText: 2010-2011 by Michael G. Hansen <mike at mghansen dot de> 0012 * SPDX-FileCopyrightText: 2014 by Mohamed_Anwer <m_dot_anwer at gmx dot com> 0013 * 0014 * SPDX-License-Identifier: GPL-2.0-or-later 0015 * 0016 * ============================================================ */ 0017 0018 #include "gpssearchview.h" 0019 0020 // Qt includes 0021 0022 #include <QLabel> 0023 #include <QLayout> 0024 #include <QPushButton> 0025 #include <QSplitter> 0026 #include <QToolButton> 0027 #include <QTimer> 0028 #include <QMenu> 0029 #include <QActionGroup> 0030 #include <QAction> 0031 #include <QApplication> 0032 #include <QStyle> 0033 #include <QLineEdit> 0034 #include <QInputDialog> 0035 #include <QIcon> 0036 0037 // KDE includes 0038 0039 #include <klocalizedstring.h> 0040 #include <kconfiggroup.h> 0041 0042 // Local includes 0043 0044 #include "digikam_debug.h" 0045 #include "searchtreeview.h" 0046 #include "editablesearchtreeview.h" 0047 #include "iteminfojob.h" 0048 #include "coredbsearchxml.h" 0049 #include "gpsmarkertiler.h" 0050 #include "gpsiteminfosorter.h" 0051 #include "searchtextbardb.h" 0052 #include "dtextedit.h" 0053 0054 namespace Digikam 0055 { 0056 0057 class Q_DECL_HIDDEN GPSSearchView::Private 0058 { 0059 0060 public: 0061 0062 explicit Private() 0063 : saveBtn (nullptr), 0064 nameEdit (nullptr), 0065 imageInfoJob (), 0066 searchGPSBar (nullptr), 0067 searchTreeView (nullptr), 0068 splitter (nullptr), 0069 mapSearchWidget (nullptr), 0070 gpsMarkerTiler (nullptr), 0071 imageAlbumModel (nullptr), 0072 imageFilterModel (nullptr), 0073 selectionModel (nullptr), 0074 searchModel (nullptr), 0075 sortOrderOptionsHelper (nullptr) 0076 { 0077 } 0078 0079 static const QString configSplitterStateEntry; 0080 QToolButton* saveBtn; 0081 DTextEdit* nameEdit; 0082 ItemInfoJob imageInfoJob; 0083 SearchTextBarDb* searchGPSBar; 0084 EditableSearchTreeView* searchTreeView; 0085 QSplitter* splitter; 0086 MapWidget* mapSearchWidget; 0087 GPSMarkerTiler* gpsMarkerTiler; 0088 ItemAlbumModel* imageAlbumModel; 0089 ItemFilterModel* imageFilterModel; 0090 QItemSelectionModel* selectionModel; 0091 SearchModel* searchModel; 0092 GPSItemInfoSorter* sortOrderOptionsHelper; 0093 QString nonGeonlocatedItemsXml; 0094 }; 0095 0096 const QString GPSSearchView::Private::configSplitterStateEntry(QLatin1String("SplitterState")); 0097 0098 /** 0099 * @brief Constructor 0100 * @param parent the parent object. 0101 * @param searchModel The model that stores the searches. 0102 * @param imageFilterModel The image model used by displaying the selected images on map. 0103 * @param itemSelectionModel The selection model corresponding to the imageFilterModel. 0104 */ 0105 GPSSearchView::GPSSearchView(QWidget* const parent, 0106 SearchModel* const searchModel, 0107 SearchModificationHelper* const searchModificationHelper, 0108 ItemFilterModel* const imageFilterModel, 0109 QItemSelectionModel* const itemSelectionModel) 0110 : QWidget (parent), 0111 StateSavingObject(this), 0112 d (new Private) 0113 { 0114 setAttribute(Qt::WA_DeleteOnClose); 0115 0116 /// @todo Really? 0117 0118 setAcceptDrops(true); 0119 0120 d->imageAlbumModel = qobject_cast<ItemAlbumModel*>(imageFilterModel->sourceModel()); 0121 d->selectionModel = itemSelectionModel; 0122 d->imageFilterModel = imageFilterModel; 0123 d->searchModel = searchModel; 0124 0125 // --------------------------------------------------------------- 0126 0127 QVBoxLayout* const vlay = new QVBoxLayout(this); 0128 0129 QFrame* const mapPanel = new QFrame(this); 0130 mapPanel->setMinimumWidth(256); 0131 mapPanel->setMinimumHeight(256); 0132 QVBoxLayout* const vlay2 = new QVBoxLayout(mapPanel); 0133 d->mapSearchWidget = new MapWidget(mapPanel); 0134 d->mapSearchWidget->setBackend(QLatin1String("marble")); 0135 d->mapSearchWidget->setShowThumbnails(true); 0136 0137 d->gpsMarkerTiler = new GPSMarkerTiler(this, d->imageFilterModel, d->selectionModel); 0138 d->mapSearchWidget->setGroupedModel(d->gpsMarkerTiler); 0139 0140 mapPanel->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); 0141 mapPanel->setLineWidth(style()->pixelMetric(QStyle::PM_DefaultFrameWidth)); 0142 0143 d->sortOrderOptionsHelper = new GPSItemInfoSorter(this); 0144 d->sortOrderOptionsHelper->addToMapWidget(d->mapSearchWidget); 0145 0146 vlay2->addWidget(d->mapSearchWidget); 0147 vlay2->setContentsMargins(QMargins()); 0148 vlay2->setSpacing(0); 0149 0150 // --------------------------------------------------------------- 0151 0152 DHBox* const hbox = new DHBox(this); 0153 hbox->setContentsMargins(QMargins()); 0154 hbox->setSpacing(qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing), 0155 QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing))); 0156 0157 d->nameEdit = new DTextEdit(hbox); 0158 d->nameEdit->setLinesVisible(1); 0159 d->nameEdit->setWhatsThis(i18n("Enter the name of the current map search to save in the " 0160 "\"Map Searches\" view.")); 0161 0162 d->saveBtn = new QToolButton(hbox); 0163 d->saveBtn->setIcon(QIcon::fromTheme(QLatin1String("document-save"))); 0164 d->saveBtn->setEnabled(false); 0165 d->saveBtn->setToolTip(i18n("Save current map search to a new virtual album.")); 0166 d->saveBtn->setWhatsThis(i18n("If this button is pressed, the current map search " 0167 "will be saved to a new search " 0168 "virtual album using the name " 0169 "set on the left side.")); 0170 0171 // --------------------------------------------------------------- 0172 0173 d->searchTreeView = new EditableSearchTreeView(this, d->searchModel, searchModificationHelper); 0174 d->searchTreeView->filteredModel()->setFilterSearchType(DatabaseSearch::MapSearch); 0175 d->searchTreeView->filteredModel()->setListTemporarySearches(true); 0176 d->searchTreeView->setAlbumManagerCurrentAlbum(true); 0177 d->searchGPSBar = new SearchTextBarDb(this, QLatin1String("GPSSearchViewSearchGPSBar")); 0178 d->searchGPSBar->setModel(d->searchTreeView->filteredModel(), AbstractAlbumModel::AlbumIdRole, AbstractAlbumModel::AlbumTitleRole); 0179 d->searchGPSBar->setFilterModel(d->searchTreeView->albumFilterModel()); 0180 0181 // --------------------------------------------------------------- 0182 0183 d->splitter = new QSplitter(Qt::Vertical, this); 0184 0185 QFrame* const frameTop = new QFrame(d->splitter); 0186 QVBoxLayout* const vlayTop = new QVBoxLayout(frameTop); 0187 vlayTop->addWidget(mapPanel); 0188 vlayTop->addWidget(d->mapSearchWidget->getControlWidget()); 0189 0190 d->mapSearchWidget->setAvailableMouseModes(MouseModePan | 0191 MouseModeRegionSelection | 0192 MouseModeZoomIntoGroup | 0193 MouseModeRegionSelectionFromIcon | 0194 MouseModeFilter | 0195 MouseModeSelectThumbnail); 0196 0197 d->mapSearchWidget->setVisibleMouseModes(MouseModePan | 0198 MouseModeZoomIntoGroup | 0199 MouseModeFilter | 0200 MouseModeSelectThumbnail); 0201 0202 /** 0203 * construct a second row of control actions below the control widget 0204 * @todo Should we still replace the icons of the actions with text as discussed during the sprint? 0205 */ 0206 QWidget* const secondActionRow = new QWidget(); 0207 QHBoxLayout* const secondActionRowHBox = new QHBoxLayout(); 0208 secondActionRowHBox->setContentsMargins(QMargins()); 0209 secondActionRow->setLayout(secondActionRowHBox); 0210 0211 QLabel* const secondActionRowLabel = new QLabel(i18n("Search by area:")); 0212 secondActionRowHBox->addWidget(secondActionRowLabel); 0213 0214 QToolButton* const tbRegionSelection = new QToolButton(secondActionRow); 0215 tbRegionSelection->setDefaultAction(d->mapSearchWidget->getControlAction(QLatin1String("mousemode-regionselectionmode"))); 0216 secondActionRowHBox->addWidget(tbRegionSelection); 0217 0218 QToolButton* const tbRegionFromIcon = new QToolButton(secondActionRow); 0219 tbRegionFromIcon->setDefaultAction(d->mapSearchWidget->getControlAction(QLatin1String("mousemode-regionselectionfromiconmode"))); 0220 secondActionRowHBox->addWidget(tbRegionFromIcon); 0221 0222 QToolButton* const tbClearRegionSelection = new QToolButton(secondActionRow); 0223 tbClearRegionSelection->setDefaultAction(d->mapSearchWidget->getControlAction(QLatin1String("mousemode-removecurrentregionselection"))); 0224 secondActionRowHBox->addWidget(tbClearRegionSelection); 0225 0226 secondActionRowHBox->addStretch(10); 0227 vlayTop->addWidget(secondActionRow); 0228 0229 // end of the second action row 0230 0231 // Show Non Geolocated Items row 0232 0233 QWidget* const nonGeolocatedActionRow = new QWidget(); 0234 QVBoxLayout* const thirdActionRowVBox = new QVBoxLayout(); 0235 thirdActionRowVBox->setContentsMargins(QMargins()); 0236 nonGeolocatedActionRow->setLayout(thirdActionRowVBox); 0237 0238 QPushButton* const nonGeolocatedBtn = new QPushButton(nonGeolocatedActionRow); 0239 nonGeolocatedBtn->setText(i18n("Show Non-Geolocated Items")); 0240 nonGeolocatedBtn->setIcon(QIcon::fromTheme(QLatin1String("emblem-unmounted"))); 0241 thirdActionRowVBox->addWidget(nonGeolocatedBtn); 0242 0243 thirdActionRowVBox->addStretch(10); 0244 vlayTop->addWidget(nonGeolocatedActionRow); 0245 0246 // end of the third action row 0247 0248 vlayTop->addWidget(hbox); 0249 vlayTop->setStretchFactor(mapPanel, 10); 0250 vlayTop->setContentsMargins(QMargins()); 0251 vlayTop->setSpacing(qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing), 0252 QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing))); 0253 QFrame* const frameBottom = new QFrame(d->splitter); 0254 QVBoxLayout* const vlayBottom = new QVBoxLayout(frameBottom); 0255 vlayBottom->addWidget(d->searchTreeView); 0256 vlayBottom->addWidget(d->searchGPSBar); 0257 vlayBottom->setContentsMargins(QMargins()); 0258 vlayBottom->setSpacing(qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing), 0259 QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing))); 0260 0261 d->splitter->addWidget(frameTop); 0262 d->splitter->addWidget(frameBottom); 0263 0264 // --------------------------------------------------------------- 0265 0266 vlay->addWidget(d->splitter); 0267 0268 // --------------------------------------------------------------- 0269 0270 connect(d->searchTreeView, SIGNAL(currentAlbumChanged(Album*)), 0271 this, SLOT(slotAlbumSelected(Album*))); 0272 0273 connect(d->saveBtn, SIGNAL(clicked()), 0274 this, SLOT(slotSaveGPSSAlbum())); 0275 0276 connect(d->nameEdit, SIGNAL(textChanged()), 0277 this, SLOT(slotCheckNameEditGPSConditions())); 0278 0279 connect(d->nameEdit, SIGNAL(returnPressed()), 0280 d->saveBtn, SLOT(animateClick())); 0281 0282 connect(d->mapSearchWidget, SIGNAL(signalRegionSelectionChanged()), 0283 this, SLOT(slotRegionSelectionChanged())); 0284 0285 connect(d->gpsMarkerTiler, SIGNAL(signalModelFilteredImages(QList<qlonglong>)), 0286 this, SLOT(slotMapSoloItems(QList<qlonglong>))); 0287 0288 connect(d->mapSearchWidget, SIGNAL(signalRemoveCurrentFilter()), 0289 this, SLOT(slotRemoveCurrentFilter())); 0290 0291 connect(nonGeolocatedBtn, SIGNAL(clicked()), 0292 d->mapSearchWidget->getControlAction(QLatin1String("mousemode-removecurrentregionselection")), SIGNAL(triggered())); 0293 0294 connect(nonGeolocatedBtn, SIGNAL(clicked()), 0295 this, SLOT(showNonGeolocatedItems())); 0296 0297 // --------------------------------------------------------------- 0298 0299 slotCheckNameEditGPSConditions(); 0300 } 0301 0302 GPSSearchView::~GPSSearchView() 0303 { 0304 delete d; 0305 } 0306 0307 void GPSSearchView::setConfigGroup(const KConfigGroup& group) 0308 { 0309 StateSavingObject::setConfigGroup(group); 0310 d->searchTreeView->setConfigGroup(group); 0311 } 0312 0313 void GPSSearchView::doLoadState() 0314 { 0315 KConfigGroup group = getConfigGroup(); 0316 0317 if (group.hasKey(entryName(d->configSplitterStateEntry))) 0318 { 0319 const QByteArray splitterState = QByteArray::fromBase64(group.readEntry(entryName(d->configSplitterStateEntry), QByteArray())); 0320 0321 if (!splitterState.isEmpty()) 0322 { 0323 d->splitter->restoreState(splitterState); 0324 } 0325 } 0326 0327 d->sortOrderOptionsHelper->setSortOptions(GPSItemInfoSorter::SortOptions(group.readEntry(entryName(QLatin1String("Sort Order")), int(d->sortOrderOptionsHelper->getSortOptions())))); 0328 0329 const KConfigGroup groupMapWidget = KConfigGroup(&group, entryName(QLatin1String("GPSSearch Map Widget"))); 0330 0331 d->mapSearchWidget->readSettingsFromGroup(&groupMapWidget); 0332 0333 d->searchTreeView->loadState(); 0334 0335 AlbumManager::instance()->clearCurrentAlbums(); 0336 0337 d->searchTreeView->clearSelection(); 0338 } 0339 0340 void GPSSearchView::doSaveState() 0341 { 0342 KConfigGroup group = getConfigGroup(); 0343 0344 group.writeEntry(entryName(d->configSplitterStateEntry), d->splitter->saveState().toBase64()); 0345 group.writeEntry(entryName(QLatin1String("Sort Order")), int(d->sortOrderOptionsHelper->getSortOptions())); 0346 0347 KConfigGroup groupMapWidget = KConfigGroup(&group, entryName(QLatin1String("GPSSearch Map Widget"))); 0348 d->mapSearchWidget->saveSettingsToGroup(&groupMapWidget); 0349 d->searchTreeView->saveState(); 0350 0351 group.sync(); 0352 } 0353 0354 /** 0355 * @brief Sets the widget active or inactive. 0356 * 0357 * Called when the GPSSearch tab becomes the current/not current tab. 0358 * 0359 * @param state When true, the widget is enabled. 0360 */ 0361 void GPSSearchView::setActive(bool state) 0362 { 0363 if (!state) 0364 { 0365 // make sure we reset the custom filters set by the map: 0366 0367 Q_EMIT signalMapSoloItems(QList<qlonglong>(), QLatin1String("gpssearch")); 0368 d->mapSearchWidget->setActive(false); 0369 } 0370 else 0371 { 0372 d->mapSearchWidget->setActive(true); 0373 0374 if (d->searchTreeView->currentAlbum()) 0375 { 0376 AlbumManager::instance()->setCurrentAlbums(QList<Album*>() << d->searchTreeView->currentAlbum()); 0377 } 0378 0379 slotClearImages(); 0380 } 0381 } 0382 0383 void GPSSearchView::changeAlbumFromHistory(SAlbum* const album) 0384 { 0385 d->searchTreeView->setCurrentAlbums(QList<Album*>() << album); 0386 } 0387 0388 /** 0389 * This slot saves the current album. 0390 */ 0391 void GPSSearchView::slotSaveGPSSAlbum() 0392 { 0393 QString name = d->nameEdit->text(); 0394 0395 if (!checkName(name)) 0396 { 0397 return; 0398 } 0399 0400 createNewGPSSearchAlbum(name); 0401 } 0402 0403 /** 0404 * This slot is called when a new selection is made. It creates a new Search Album. 0405 */ 0406 void GPSSearchView::slotRegionSelectionChanged() 0407 { 0408 const GeoCoordinates::Pair newRegionSelection = d->mapSearchWidget->getRegionSelection(); 0409 const bool haveRegionSelection = newRegionSelection.first.hasCoordinates(); 0410 0411 if (haveRegionSelection) 0412 { 0413 slotCheckNameEditGPSConditions(); 0414 createNewGPSSearchAlbum(SAlbum::getTemporaryTitle(DatabaseSearch::MapSearch)); 0415 } 0416 else 0417 { 0418 // reset the search rectangle of the temporary album: 0419 0420 createNewGPSSearchAlbum(SAlbum::getTemporaryTitle(DatabaseSearch::MapSearch)); 0421 d->gpsMarkerTiler->removeCurrentRegionSelection(); 0422 d->searchTreeView->clearSelection(); 0423 slotClearImages(); 0424 } 0425 0426 // also remove any filters which may have been there 0427 0428 slotRemoveCurrentFilter(); 0429 0430 slotRefreshMap(); 0431 } 0432 0433 /** 0434 * @brief This function creates a new Search Album. 0435 * @param name The name of the new album. 0436 */ 0437 void GPSSearchView::createNewGPSSearchAlbum(const QString& name) 0438 { 0439 /* 0440 AlbumManager::instance()->clearCurrentAlbums(); 0441 */ 0442 // We query the database here 0443 0444 const GeoCoordinates::Pair coordinates = d->mapSearchWidget->getRegionSelection(); 0445 const bool haveCoordinates = coordinates.first.hasCoordinates(); 0446 0447 if (haveCoordinates) 0448 { 0449 d->gpsMarkerTiler->setRegionSelection(coordinates); 0450 } 0451 0452 // NOTE: coordinates as lon1, lat1, lon2, lat2 (or West, North, East, South) 0453 // as left/top, right/bottom rectangle. 0454 0455 QList<qreal> coordinatesList = QList<qreal>() << 0456 coordinates.first.lon() << coordinates.first.lat() << 0457 coordinates.second.lon() << coordinates.second.lat(); 0458 0459 if (!haveCoordinates) 0460 { 0461 /// @todo We need to create a search album with invalid coordinates 0462 0463 coordinatesList.clear(); 0464 coordinatesList << -200 << -200 << -200 << -200; 0465 } 0466 0467 qCDebug(DIGIKAM_GENERAL_LOG) << "West, North, East, South: " << coordinatesList; 0468 0469 SearchXmlWriter writer; 0470 writer.writeGroup(); 0471 writer.writeField(QLatin1String("position"), SearchXml::Inside); 0472 writer.writeAttribute(QLatin1String("type"), QLatin1String("rectangle")); 0473 writer.writeValue(coordinatesList); 0474 writer.finishField(); 0475 writer.finishGroup(); 0476 0477 SAlbum* const salbum = AlbumManager::instance()->createSAlbum(name, DatabaseSearch::MapSearch, writer.xml()); 0478 AlbumManager::instance()->setCurrentAlbums(QList<Album*>() << salbum); 0479 d->imageInfoJob.allItemsFromAlbum(salbum); 0480 d->searchTreeView->setCurrentAlbums(QList<Album*>() << salbum); 0481 d->imageAlbumModel->openAlbum(QList<Album*>() << salbum); 0482 } 0483 0484 /** 0485 * @brief An album is selected in the saved searches list. 0486 * @param a This album will be selected. 0487 */ 0488 void GPSSearchView::slotAlbumSelected(Album* a) 0489 { 0490 /// @todo This re-sets the region selection unwantedly... 0491 0492 SAlbum* const salbum = dynamic_cast<SAlbum*>(a); 0493 0494 if (!salbum) 0495 { 0496 return; 0497 } 0498 0499 SearchXmlReader reader(salbum->query()); 0500 reader.readToFirstField(); 0501 QStringView type = reader.attributes().value(QLatin1String("type")); 0502 0503 if (type == QLatin1String("rectangle")) 0504 { 0505 const QList<double> list = reader.valueToDoubleList(); 0506 0507 const GeoCoordinates::Pair coordinates( 0508 GeoCoordinates(list.at(1), list.at(0)), 0509 GeoCoordinates(list.at(3), list.at(2)) 0510 ); 0511 0512 /// @todo Currently, invalid coordinates are stored as -200: 0513 0514 if (list.at(1) != -200) 0515 { 0516 d->mapSearchWidget->setRegionSelection(coordinates); 0517 d->gpsMarkerTiler->setRegionSelection(coordinates); 0518 } 0519 else 0520 { 0521 d->mapSearchWidget->clearRegionSelection(); 0522 d->gpsMarkerTiler->removeCurrentRegionSelection(); 0523 } 0524 0525 slotCheckNameEditGPSConditions(); 0526 } 0527 0528 d->imageInfoJob.allItemsFromAlbum(salbum); 0529 } 0530 0531 /** 0532 * @brief Checks whether the newly added search name already exists. 0533 * @param name The name of the current search. 0534 */ 0535 bool GPSSearchView::checkName(QString& name) 0536 { 0537 bool checked = checkAlbum(name); 0538 0539 while (!checked) 0540 { 0541 QString label = i18n("Search name already exists.\n" 0542 "Please enter a new name:"); 0543 bool ok; 0544 QString newTitle = QInputDialog::getText(this, 0545 i18nc("@title:window", "Name Exists"), 0546 label, 0547 QLineEdit::Normal, 0548 name, 0549 &ok); 0550 0551 if (!ok) 0552 { 0553 return false; 0554 } 0555 0556 name = newTitle; 0557 checked = checkAlbum(name); 0558 } 0559 0560 return true; 0561 } 0562 0563 /** 0564 * @brief Checks whether the newly added album name already exists. 0565 * @param name The name of the album. 0566 */ 0567 bool GPSSearchView::checkAlbum(const QString& name) const 0568 { 0569 const AlbumList list = AlbumManager::instance()->allSAlbums(); 0570 0571 for (AlbumList::ConstIterator it = list.constBegin() ; it != list.constEnd() ; ++it) 0572 { 0573 const SAlbum* const album = (SAlbum*)(*it); 0574 0575 if (album->title() == name) 0576 { 0577 return false; 0578 } 0579 } 0580 0581 return true; 0582 } 0583 0584 /** 0585 * @brief Remove the current filter. 0586 */ 0587 void GPSSearchView::slotRemoveCurrentFilter() 0588 { 0589 d->gpsMarkerTiler->setPositiveFilterIsActive(false); 0590 const QList<qlonglong> emptyIdList; 0591 Q_EMIT signalMapSoloItems(emptyIdList, QLatin1String("gpssearch")); 0592 slotRefreshMap(); 0593 d->mapSearchWidget->slotUpdateActionsEnabled(); 0594 } 0595 0596 /** 0597 * @brief Enable or disable the album saving controls. 0598 */ 0599 void GPSSearchView::slotCheckNameEditGPSConditions() 0600 { 0601 if (d->mapSearchWidget->getRegionSelection().first.hasCoordinates()) 0602 { 0603 d->nameEdit->setEnabled(true); 0604 0605 if (!d->nameEdit->text().isEmpty()) 0606 { 0607 d->saveBtn->setEnabled(true); 0608 } 0609 } 0610 else 0611 { 0612 d->nameEdit->setEnabled(false); 0613 d->saveBtn->setEnabled(false); 0614 } 0615 } 0616 0617 /** 0618 * @brief Slot which gets called when the user makes items 'solo' on the map 0619 * @param gpsList List of GPSInfos which are 'solo' 0620 */ 0621 void GPSSearchView::slotMapSoloItems(const QList<qlonglong>& idList) 0622 { 0623 Q_EMIT signalMapSoloItems(idList, QLatin1String("gpssearch")); 0624 d->mapSearchWidget->slotUpdateActionsEnabled(); 0625 } 0626 0627 void GPSSearchView::showNonGeolocatedItems() 0628 { 0629 if (d->nonGeonlocatedItemsXml.isEmpty()) 0630 { 0631 SearchXmlWriter writer; 0632 writer.setFieldOperator((SearchXml::standardFieldOperator())); 0633 writer.writeGroup(); 0634 writer.writeField(QLatin1String("nogps"), SearchXml::Equal); 0635 writer.finishField(); 0636 writer.finishGroup(); 0637 writer.finish(); 0638 d->nonGeonlocatedItemsXml = writer.xml(); 0639 } 0640 0641 QString title = SAlbum::getTemporaryTitle(DatabaseSearch::MapSearch); 0642 SAlbum* album = AlbumManager::instance()->findSAlbum(title); 0643 0644 int id; 0645 0646 if (album) 0647 { 0648 id = album->id(); 0649 CoreDbAccess().db()->updateSearch(id, DatabaseSearch::AdvancedSearch, 0650 SAlbum::getTemporaryTitle(DatabaseSearch::AdvancedSearch), 0651 d->nonGeonlocatedItemsXml); 0652 } 0653 else 0654 { 0655 id = CoreDbAccess().db()->addSearch(DatabaseSearch::AdvancedSearch, 0656 SAlbum::getTemporaryTitle(DatabaseSearch::AdvancedSearch), 0657 d->nonGeonlocatedItemsXml); 0658 } 0659 0660 album = new SAlbum(i18n("Non Geo-located Items"), id); 0661 0662 if (album) 0663 { 0664 AlbumManager::instance()->setCurrentAlbums(QList<Album*>() << album); 0665 } 0666 } 0667 0668 0669 void GPSSearchView::slotRefreshMap() 0670 { 0671 d->mapSearchWidget->refreshMap(); 0672 } 0673 0674 void GPSSearchView::slotClearImages() 0675 { 0676 if (d->mapSearchWidget->getActiveState()) 0677 { 0678 d->imageAlbumModel->clearItemInfos(); 0679 } 0680 } 0681 0682 } // namespace Digikam 0683 0684 #include "moc_gpssearchview.cpp"