File indexing completed on 2025-01-19 03:50:45
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2002-16-10 0007 * Description : Item icon view interface - Album methods. 0008 * 0009 * SPDX-FileCopyrightText: 2002-2005 by Renchi Raju <renchi dot raju at gmail dot com> 0010 * SPDX-FileCopyrightText: 2002-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * SPDX-FileCopyrightText: 2009-2011 by Johannes Wienke <languitar at semipol dot de> 0012 * SPDX-FileCopyrightText: 2010-2011 by Andi Clemens <andi dot clemens at gmail dot com> 0013 * SPDX-FileCopyrightText: 2011-2013 by Michael G. Hansen <mike at mghansen dot de> 0014 * SPDX-FileCopyrightText: 2014-2015 by Mohamed_Anwer <m_dot_anwer at gmx dot com> 0015 * SPDX-FileCopyrightText: 2017 by Simon Frei <freisim93 at gmail dot com> 0016 * 0017 * SPDX-License-Identifier: GPL-2.0-or-later 0018 * 0019 * ============================================================ */ 0020 0021 #include "itemiconview_p.h" 0022 0023 namespace Digikam 0024 { 0025 0026 void ItemIconView::slotAllAlbumsLoaded() 0027 { 0028 disconnect(d->albumManager, SIGNAL(signalAllAlbumsLoaded()), 0029 this, SLOT(slotAllAlbumsLoaded())); 0030 0031 loadViewState(); 0032 d->leftSideBar->loadState(); 0033 d->rightSideBar->loadState(); 0034 d->rightSideBar->populateTags(); 0035 0036 // now that all albums have been loaded, activate the albumHistory 0037 0038 d->useAlbumHistory = true; 0039 Album* const album = d->albumManager->findAlbum(d->initialAlbumID); 0040 d->albumManager->setCurrentAlbums(QList<Album*>() << album); 0041 } 0042 0043 void ItemIconView::slotSortAlbums(int role) 0044 { 0045 ApplicationSettings* const settings = ApplicationSettings::instance(); 0046 0047 if (!settings) 0048 { 0049 return; 0050 } 0051 0052 settings->setAlbumSortRole((ApplicationSettings::AlbumSortRole) role); 0053 settings->saveSettings(); 0054 0055 // A dummy way to force the tree view to resort if the album sort role changed 0056 0057 PAlbum* const albumBeforeSorting = d->albumFolderSideBar->currentAlbum(); 0058 settings->setAlbumSortChanged(true); 0059 d->albumFolderSideBar->doSaveState(); 0060 d->albumFolderSideBar->doLoadState(); 0061 d->albumFolderSideBar->doSaveState(); 0062 d->albumFolderSideBar->doLoadState(); 0063 settings->setAlbumSortChanged(false); 0064 0065 if (d->leftSideBar->getActiveTab() == d->albumFolderSideBar) 0066 { 0067 d->albumFolderSideBar->setCurrentAlbum(albumBeforeSorting); 0068 } 0069 } 0070 0071 void ItemIconView::slotNewAlbum() 0072 { 0073 // TODO use the selection model of the view instead 0074 0075 d->albumModificationHelper->slotAlbumNew(d->albumFolderSideBar->currentAlbum()); 0076 } 0077 0078 void ItemIconView::slotDeleteAlbum() 0079 { 0080 d->albumModificationHelper->slotAlbumDelete(d->albumFolderSideBar->currentAlbum()); 0081 } 0082 0083 void ItemIconView::slotRenameAlbum() 0084 { 0085 d->albumModificationHelper->slotAlbumRename(d->albumFolderSideBar->currentAlbum()); 0086 } 0087 0088 void ItemIconView::slotAlbumsCleared() 0089 { 0090 Q_EMIT signalAlbumSelected(nullptr); 0091 } 0092 0093 void ItemIconView::slotAlbumHistoryBack(int steps) 0094 { 0095 QList<Album*> albums; 0096 QWidget* widget = nullptr; 0097 0098 d->albumHistory->back(albums, &widget, steps); 0099 0100 changeAlbumFromHistory(albums, widget); 0101 } 0102 0103 void ItemIconView::slotAlbumHistoryForward(int steps) 0104 { 0105 QList<Album*> albums; 0106 QWidget* widget = nullptr; 0107 0108 d->albumHistory->forward(albums, &widget, steps); 0109 0110 changeAlbumFromHistory(albums , widget); 0111 } 0112 0113 // TODO update, use SideBarWidget instead of QWidget 0114 0115 void ItemIconView::changeAlbumFromHistory(const QList<Album*>& album, QWidget* const widget) 0116 { 0117 if (!(album.isEmpty()) && widget) 0118 { 0119 // TODO update, temporary casting until signature is changed 0120 0121 SidebarWidget* const sideBarWidget = dynamic_cast<SidebarWidget*>(widget); 0122 0123 if (sideBarWidget) 0124 { 0125 sideBarWidget->changeAlbumFromHistory(album); 0126 slotLeftSideBarActivate(sideBarWidget); 0127 0128 if (sideBarWidget == d->labelsSideBar) 0129 { 0130 d->labelsSearchHandler->restoreSelectionFromHistory(d->albumHistory->neededLabels()); 0131 } 0132 } 0133 0134 d->parent->enableAlbumBackwardHistory(d->useAlbumHistory && !d->albumHistory->isBackwardEmpty()); 0135 d->parent->enableAlbumForwardHistory(d->useAlbumHistory && !d->albumHistory->isForwardEmpty()); 0136 } 0137 } 0138 0139 0140 void ItemIconView::slotSelectAlbum(const QUrl& url) 0141 { 0142 PAlbum* const album = d->albumManager->findPAlbum(url); 0143 0144 if (!album) 0145 { 0146 qCWarning(DIGIKAM_GENERAL_LOG) << "Unable to find album for " << url; 0147 return; 0148 } 0149 0150 slotLeftSideBarActivate(d->albumFolderSideBar); 0151 d->albumFolderSideBar->setCurrentAlbum(album); 0152 } 0153 0154 void ItemIconView::slotAlbumSelected(const QList<Album*>& albums) 0155 { 0156 Q_EMIT signalNoCurrentItem(); 0157 Q_EMIT signalAlbumSelected(nullptr); 0158 0159 if (albums.isEmpty() || !albums.first()) 0160 { 0161 d->iconView->openAlbum(QList<Album*>()); 0162 slotTogglePreviewMode(ItemInfo()); 0163 0164 return; 0165 } 0166 0167 Album* const album = albums.first(); 0168 0169 Q_EMIT signalAlbumSelected(album); 0170 0171 if (d->useAlbumHistory && !d->labelsSearchHandler->isRestoringSelectionFromHistory()) 0172 { 0173 if (!(d->leftSideBar->getActiveTab() == d->labelsSideBar)) 0174 { 0175 d->albumHistory->addAlbums(albums, d->leftSideBar->getActiveTab()); 0176 } 0177 else 0178 { 0179 if (albums.first()->isUsedByLabelsTree()) 0180 { 0181 d->albumHistory->addAlbums(albums, d->leftSideBar->getActiveTab(), d->labelsSideBar->selectedLabels()); 0182 } 0183 } 0184 } 0185 0186 d->parent->enableAlbumBackwardHistory(d->useAlbumHistory && !d->albumHistory->isBackwardEmpty()); 0187 d->parent->enableAlbumForwardHistory(d->useAlbumHistory && !d->albumHistory->isForwardEmpty()); 0188 0189 d->iconView->openAlbum(albums); 0190 0191 if (album->isRoot()) 0192 { 0193 d->stackedView->setViewMode(StackedView::WelcomePageMode); 0194 } 0195 else if (album->isTrashAlbum()) 0196 { 0197 PAlbum* const palbum = static_cast<PAlbum*>(album->parent()); 0198 0199 if (palbum) 0200 { 0201 slotTogglePreviewMode(ItemInfo()); 0202 QUrl url = palbum->fileUrl().adjusted(QUrl::StripTrailingSlash); 0203 d->trashView->model()->loadItemsForCollection(url.toLocalFile()); 0204 d->stackedView->setViewMode(StackedView::TrashViewMode); 0205 d->filterWidget->setEnabled(false); 0206 } 0207 } 0208 else 0209 { 0210 switch (viewMode()) 0211 { 0212 case StackedView::PreviewImageMode: 0213 case StackedView::MediaPlayerMode: 0214 case StackedView::WelcomePageMode: 0215 case StackedView::TrashViewMode: 0216 slotTogglePreviewMode(ItemInfo()); 0217 break; 0218 0219 default: 0220 break; 0221 } 0222 0223 d->filterWidget->setEnabled(true); 0224 } 0225 } 0226 0227 void ItemIconView::slotGotoAlbumAndItem(const ItemInfo& imageInfo) 0228 { 0229 qCDebug(DIGIKAM_GENERAL_LOG) << "going to " << imageInfo; 0230 0231 Q_EMIT signalNoCurrentItem(); 0232 0233 PAlbum* const album = AlbumManager::instance()->findPAlbum(imageInfo.albumId()); 0234 0235 d->albumFolderSideBar->setCurrentAlbum(album); 0236 slotLeftSideBarActivate(d->albumFolderSideBar); 0237 0238 // Set the activate item url to find in the Album View after 0239 // all items have be reloaded. 0240 0241 slotSetCurrentWhenAvailable(imageInfo.id()); 0242 0243 // And finally toggle album manager to handle album history and 0244 // reload all items. 0245 0246 d->albumManager->setCurrentAlbums(QList<Album*>() << album); 0247 } 0248 0249 void ItemIconView::slotGotoDateAndItem(const ItemInfo& imageInfo) 0250 { 0251 QDate date = imageInfo.dateTime().date(); 0252 0253 Q_EMIT signalNoCurrentItem(); 0254 0255 // Change to Date Album view. 0256 // Note, that this also opens the side bar if it is closed; this is 0257 // considered as a feature, because it highlights that the view was changed. 0258 0259 slotLeftSideBarActivate(d->dateViewSideBar); 0260 0261 // Set the activate item url to find in the Album View after 0262 // all items have be reloaded. 0263 0264 slotSetCurrentWhenAvailable(imageInfo.id()); 0265 0266 // Change the year and month of the iconItem (day is unused). 0267 0268 d->dateViewSideBar->gotoDate(date); 0269 } 0270 0271 void ItemIconView::slotGotoTagAndItem(int tagID) 0272 { 0273 // FIXME: Arnd: don't know yet how to get the iconItem passed through ... 0274 // then we would know how to use the following ... 0275 // KURL url(iconItem->imageInfo()->kurl()); 0276 // url.cleanPath(); 0277 0278 Q_EMIT signalNoCurrentItem(); 0279 0280 // Change to Tag Folder view. 0281 // Note, that this also opens the side bar if it is closed; this is 0282 // considered as a feature, because it highlights that the view was changed. 0283 0284 slotLeftSideBarActivate(d->tagViewSideBar); 0285 0286 // Set the current tag in the tag folder view. 0287 // TODO this slot should use a TAlbum pointer directly 0288 0289 TAlbum* const tag = AlbumManager::instance()->findTAlbum(tagID); 0290 0291 if (tag) 0292 { 0293 d->tagViewSideBar->setCurrentAlbum(tag); 0294 } 0295 else 0296 { 0297 qCDebug(DIGIKAM_GENERAL_LOG) << "Could not find a tag album for tag id " << tagID; 0298 } 0299 0300 // Set the activate item url to find in the Tag View after 0301 // all items have be reloaded. 0302 // FIXME: see above 0303 // d->iconView->setAlbumItemToFind(url); 0304 } 0305 0306 void ItemIconView::slotAlbumOpenInFileManager() 0307 { 0308 Album* const album = d->albumManager->currentAlbums().constFirst(); 0309 0310 if (!album || (album->type() != Album::PHYSICAL)) 0311 { 0312 return; 0313 } 0314 0315 if (album->isRoot()) 0316 { 0317 QMessageBox::critical(this, qApp->applicationName(), 0318 i18n("Cannot open the root album. It is not a physical location.")); 0319 return; 0320 } 0321 0322 QList<QUrl> urls = selectedInfoList(true, true).toImageUrlList(); 0323 0324 if (!urls.isEmpty()) 0325 { 0326 DFileOperations::openInFileManager(urls); 0327 } 0328 else 0329 { 0330 PAlbum* const palbum = dynamic_cast<PAlbum*>(album); 0331 0332 if (palbum) 0333 { 0334 QUrl url(QUrl::fromLocalFile(palbum->folderPath())); 0335 DFileOperations::openInFileManager(QList<QUrl>() << url); 0336 } 0337 } 0338 } 0339 0340 void ItemIconView::slotAlbumRefreshComplete() 0341 { 0342 // force reload. Should normally not be necessary, but we may have bugs 0343 0344 qlonglong currentId = currentInfo().id(); 0345 d->iconView->imageAlbumModel()->refresh(); 0346 0347 if (currentId != -1) 0348 { 0349 slotSetCurrentWhenAvailable(currentId); 0350 } 0351 } 0352 0353 void ItemIconView::slotAlbumPropsEdit() 0354 { 0355 d->albumModificationHelper->slotAlbumEdit(d->albumManager->currentPAlbum()); 0356 } 0357 0358 void ItemIconView::slotAlbumWriteMetadata() 0359 { 0360 Album* const album = d->albumManager->currentAlbums().constFirst(); 0361 0362 if (!album) 0363 { 0364 return; 0365 } 0366 0367 MetadataSynchronizer* const tool = new MetadataSynchronizer(AlbumList() << album, MetadataSynchronizer::WriteFromDatabaseToFile); 0368 tool->start(); 0369 } 0370 0371 void ItemIconView::slotAlbumReadMetadata() 0372 { 0373 Album* const album = d->albumManager->currentAlbums().constFirst(); 0374 0375 if (!album) 0376 { 0377 return; 0378 } 0379 0380 MetadataSynchronizer* const tool = new MetadataSynchronizer(AlbumList() << album, MetadataSynchronizer::ReadFromFileToDatabase); 0381 tool->setUseMultiCoreCPU(false); 0382 tool->start(); 0383 } 0384 0385 void ItemIconView::setRecurseAlbums(bool recursive) 0386 { 0387 d->iconView->imageAlbumModel()->setRecurseAlbums(recursive); 0388 } 0389 0390 Album* ItemIconView::currentAlbum() const 0391 { 0392 switch (viewMode()) 0393 { 0394 case StackedView::TableViewMode: 0395 return d->tableView->currentAlbum(); 0396 0397 case StackedView::PreviewImageMode: 0398 case StackedView::MediaPlayerMode: 0399 case StackedView::MapWidgetMode: 0400 case StackedView::IconViewMode: 0401 // all of these modes use the same selection model and data as the IconViewMode 0402 0403 return d->iconView->currentAlbum(); 0404 0405 default: 0406 return nullptr; 0407 } 0408 } 0409 0410 void ItemIconView::slotSetAsAlbumThumbnail(const ItemInfo& info) 0411 { 0412 d->utilities->setAsAlbumThumbnail(currentAlbum(), info); 0413 } 0414 0415 void ItemIconView::slotMoveSelectionToAlbum() 0416 { 0417 d->utilities->createNewAlbumForInfos(selectedInfoList(false, true), 0418 currentAlbum()); 0419 } 0420 0421 void ItemIconView::slotRefresh() 0422 { 0423 switch (viewMode()) 0424 { 0425 case StackedView::PreviewImageMode: 0426 d->stackedView->imagePreviewView()->reload(); 0427 break; 0428 0429 #ifdef HAVE_MEDIAPLAYER 0430 0431 case StackedView::MediaPlayerMode: 0432 d->stackedView->mediaPlayerView()->reload(); 0433 break; 0434 0435 #endif // HAVE_MEDIAPLAYER 0436 0437 default: 0438 Album* const album = currentAlbum(); 0439 0440 if (!album) 0441 { 0442 return; 0443 } 0444 0445 if (qApp->keyboardModifiers() != Qt::ControlModifier) 0446 { 0447 // force reloading of thumbnails 0448 0449 LoadingCacheInterface::cleanThumbnailCache(); 0450 0451 ThumbsGenerator* const tool = new ThumbsGenerator(true, album->id()); 0452 tool->start(); 0453 } 0454 0455 // if physical album, schedule a collection scan of current album's path 0456 0457 if (album->type() == Album::PHYSICAL) 0458 { 0459 NewItemsFinder* const tool2 = new NewItemsFinder(NewItemsFinder::ScheduleCollectionScan, 0460 QStringList() << static_cast<PAlbum*>(album)->folderPath()); 0461 0462 connect(tool2, SIGNAL(signalComplete()), 0463 this, SLOT(slotAlbumRefreshComplete())); 0464 0465 tool2->start(); 0466 } 0467 0468 break; 0469 } 0470 } 0471 0472 void ItemIconView::clearHistory() 0473 { 0474 d->albumHistory->clearHistory(); 0475 d->parent->enableAlbumBackwardHistory(false); 0476 d->parent->enableAlbumForwardHistory(false); 0477 } 0478 0479 void ItemIconView::getBackwardHistory(QStringList& titles) 0480 { 0481 d->albumHistory->getBackwardHistory(titles); 0482 0483 for (int i = 0 ; i < titles.size() ; ++i) 0484 { 0485 titles[i] = d->userPresentableAlbumTitle(titles.at(i)); 0486 } 0487 } 0488 0489 void ItemIconView::getForwardHistory(QStringList& titles) 0490 { 0491 d->albumHistory->getForwardHistory(titles); 0492 0493 for (int i = 0 ; i < titles.size() ; ++i) 0494 { 0495 titles[i] = d->userPresentableAlbumTitle(titles.at(i)); 0496 } 0497 } 0498 0499 } // namespace Digikam