File indexing completed on 2025-01-19 03:53:19

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2004-06-15
0007  * Description : Albums manager interface - Generic Album helpers.
0008  *
0009  * SPDX-FileCopyrightText: 2006-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  * SPDX-FileCopyrightText: 2006-2011 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
0011  * SPDX-FileCopyrightText: 2015      by Mohamed_Anwer <m_dot_anwer at gmx dot com>
0012  *
0013  * SPDX-License-Identifier: GPL-2.0-or-later
0014  *
0015  * ============================================================ */
0016 
0017 #include "albummanager_p.h"
0018 
0019 namespace Digikam
0020 {
0021 
0022 void AlbumManager::setCurrentAlbums(const QList<Album*>& albums)
0023 {
0024     if (albums.isEmpty())
0025     {
0026         return;
0027     }
0028 
0029     d->currentAlbums.clear();
0030 
0031     /**
0032      * Filter out the null pointers
0033      */
0034     Q_FOREACH (Album* const album, albums)
0035     {
0036         if (album)
0037         {
0038             d->currentAlbums << album;
0039         }
0040     }
0041 
0042     /**
0043      * Sort is needed to identify selection correctly, ex AlbumHistory
0044      */
0045     std::sort(d->currentAlbums.begin(), d->currentAlbums.end());
0046 
0047     Q_EMIT signalAlbumCurrentChanged(d->currentAlbums);
0048 }
0049 
0050 AlbumList AlbumManager::currentAlbums() const
0051 {
0052     return d->currentAlbums;
0053 }
0054 
0055 void AlbumManager::clearCurrentAlbums()
0056 {
0057     d->currentAlbums.clear();
0058 
0059     Q_EMIT signalAlbumCurrentChanged(d->currentAlbums);
0060 }
0061 
0062 Album* AlbumManager::findAlbum(int gid) const
0063 {
0064     return d->allAlbumsIdHash.value(gid);
0065 }
0066 
0067 Album* AlbumManager::findAlbum(Album::Type type, int id) const
0068 {
0069     return findAlbum(Album::globalID(type, id));
0070 }
0071 
0072 QHash<int, QString> AlbumManager::albumTitles() const
0073 {
0074     QHash<int, QString> hash;
0075     AlbumIterator it(d->rootPAlbum);
0076 
0077     while (it.current())
0078     {
0079         PAlbum* const a = (PAlbum*)(*it);
0080         hash.insert(a->id(), a->title());
0081         ++it;
0082     }
0083 
0084     return hash;
0085 }
0086 
0087 bool AlbumManager::isMovingAlbum(Album* album) const
0088 {
0089     return d->currentlyMovingAlbum == album;
0090 }
0091 
0092 bool AlbumManager::hasDirectChildAlbumWithTitle(Album* parent, const QString& title)
0093 {
0094     Album* sibling = parent->firstChild();
0095 
0096     while (sibling)
0097     {
0098         if (sibling->title() == title)
0099         {
0100             return true;
0101         }
0102 
0103         sibling = sibling->next();
0104     }
0105 
0106     return false;
0107 }
0108 
0109 void AlbumManager::notifyAlbumDeletion(Album* album)
0110 {
0111     invalidateGuardedPointers(album);
0112 }
0113 
0114 void AlbumManager::slotAlbumsJobResult()
0115 {
0116     if (!d->albumListJob)
0117     {
0118         return;
0119     }
0120 
0121     if (d->albumListJob->hasErrors())
0122     {
0123         qCWarning(DIGIKAM_GENERAL_LOG) << "Failed to list albums";
0124 
0125         // Pop-up a message about the error.
0126 
0127         DNotificationWrapper(QString(), d->albumListJob->errorsList().first(),
0128                              nullptr, i18n("digiKam"));
0129     }
0130 
0131     d->albumListJob = nullptr;
0132 }
0133 
0134 void AlbumManager::slotAlbumsJobData(const QHash<int, int>& albumsStatHash)
0135 {
0136     if (albumsStatHash.isEmpty())
0137     {
0138         return;
0139     }
0140 
0141     d->pAlbumsCount = albumsStatHash;
0142 
0143     Q_EMIT signalPAlbumsDirty(albumsStatHash);
0144 }
0145 
0146 void AlbumManager::updateAlbumPathHash()
0147 {
0148     // Update AlbumDict. basically clear it and rebuild from scratch
0149 
0150     d->albumPathHash.clear();
0151     AlbumIterator it(d->rootPAlbum);
0152     PAlbum* subAlbum = nullptr;
0153 
0154     while ((subAlbum = static_cast<PAlbum*>(it.current())) != nullptr)
0155     {
0156         d->albumPathHash[PAlbumPath(subAlbum)] = subAlbum;
0157         ++it;
0158     }
0159 }
0160 
0161 void AlbumManager::addGuardedPointer(Album* album, Album** pointer)
0162 {
0163     if (album)
0164     {
0165         d->guardedPointers.insert(album, pointer);
0166     }
0167 }
0168 
0169 void AlbumManager::removeGuardedPointer(Album* album, Album** pointer)
0170 {
0171     if (album)
0172     {
0173         d->guardedPointers.remove(album, pointer);
0174     }
0175 }
0176 
0177 void AlbumManager::changeGuardedPointer(Album* oldAlbum, Album* album, Album** pointer)
0178 {
0179     if (oldAlbum)
0180     {
0181         d->guardedPointers.remove(oldAlbum, pointer);
0182     }
0183 
0184     if (album)
0185     {
0186         d->guardedPointers.insert(album, pointer);
0187     }
0188 }
0189 
0190 void AlbumManager::invalidateGuardedPointers(Album* album)
0191 {
0192     if (!album)
0193     {
0194         return;
0195     }
0196 
0197     QMultiHash<Album*, Album**>::iterator it = d->guardedPointers.find(album);
0198 
0199     for ( ; it != d->guardedPointers.end() && it.key() == album ; ++it)
0200     {
0201         if (it.value())
0202         {
0203             *(it.value()) = nullptr;
0204         }
0205     }
0206 }
0207 
0208 void AlbumManager::getAlbumItemsCount()
0209 {
0210     d->albumItemCountTimer->stop();
0211 
0212     if (!ApplicationSettings::instance()->getShowFolderTreeViewItemsCount())
0213     {
0214         return;
0215     }
0216 
0217     if (d->albumListJob)
0218     {
0219         disconnect(d->albumListJob, nullptr, this, nullptr);
0220 
0221         d->albumListJob->cancel();
0222         d->albumListJob = nullptr;
0223     }
0224 
0225     AlbumsDBJobInfo jInfo;
0226     jInfo.setFoldersJob();
0227     d->albumListJob = DBJobsManager::instance()->startAlbumsJobThread(jInfo);
0228 
0229     connect(d->albumListJob, SIGNAL(finished()),
0230             this, SLOT(slotAlbumsJobResult()));
0231 
0232     connect(d->albumListJob, SIGNAL(foldersData(QHash<int,int>)),
0233             this, SLOT(slotAlbumsJobData(QHash<int,int>)));
0234 }
0235 
0236 void AlbumManager::slotAlbumChange(const AlbumChangeset& changeset)
0237 {
0238     if (d->changingDB || !d->rootPAlbum)
0239     {
0240         return;
0241     }
0242 
0243     switch (changeset.operation())
0244     {
0245         case AlbumChangeset::Added:
0246         case AlbumChangeset::Deleted:
0247         {
0248             if (!d->scanPAlbumsTimer->isActive())
0249             {
0250                 d->scanPAlbumsTimer->start();
0251             }
0252 
0253             break;
0254         }
0255 
0256         case AlbumChangeset::Renamed:
0257         case AlbumChangeset::PropertiesChanged:
0258         {
0259             // mark for rescan
0260 
0261             d->changedPAlbums << changeset.albumId();
0262 
0263             if (!d->updatePAlbumsTimer->isActive())
0264             {
0265                 d->updatePAlbumsTimer->start();
0266             }
0267 
0268             break;
0269         }
0270 
0271         case AlbumChangeset::Unknown:
0272         {
0273             break;
0274         }
0275     }
0276 }
0277 
0278 qlonglong AlbumManager::getItemFromAlbum(Album* const album, const QString& fileName)
0279 {
0280     return CoreDbAccess().db()->getItemFromAlbum(album->id(), fileName);
0281 }
0282 
0283 } // namespace Digikam