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