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

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2007-04-09
0007  * Description : Collection location management - location helpers.
0008  *
0009  * SPDX-FileCopyrightText: 2007-2009 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
0010  *
0011  * SPDX-License-Identifier: GPL-2.0-or-later
0012  *
0013  * ============================================================ */
0014 
0015 #include "collectionmanager_p.h"
0016 
0017 namespace Digikam
0018 {
0019 
0020 QStringList CollectionManager::allAvailableAlbumRootPaths()
0021 {
0022     QReadLocker readLocker(&d->lock);
0023 
0024     QStringList list;
0025 
0026     Q_FOREACH (AlbumRootLocation* const location, d->locations)
0027     {
0028         if (location->status() == CollectionLocation::LocationAvailable)
0029         {
0030             list << location->albumRootPath();
0031         }
0032     }
0033 
0034     return list;
0035 }
0036 
0037 QString CollectionManager::albumRootPath(int id)
0038 {
0039     QReadLocker readLocker(&d->lock);
0040 
0041     CollectionLocation* const location = d->locations.value(id);
0042 
0043     if (location && location->status() == CollectionLocation::LocationAvailable)
0044     {
0045         return location->albumRootPath();
0046     }
0047 
0048     return QString();
0049 }
0050 
0051 QString CollectionManager::albumRootLabel(int id)
0052 {
0053     QReadLocker readLocker(&d->lock);
0054 
0055     CollectionLocation* const location = d->locations.value(id);
0056 
0057     if (location && location->status() == CollectionLocation::LocationAvailable)
0058     {
0059         return location->label();
0060     }
0061 
0062     return QString();
0063 }
0064 
0065 QUrl CollectionManager::albumRoot(const QUrl& fileUrl)
0066 {
0067     return QUrl::fromLocalFile(albumRootPath(fileUrl.adjusted(QUrl::StripTrailingSlash).toLocalFile()));
0068 }
0069 
0070 QString CollectionManager::albumRootPath(const QUrl& fileUrl)
0071 {
0072     return albumRootPath(fileUrl.adjusted(QUrl::StripTrailingSlash).toLocalFile());
0073 }
0074 
0075 QString CollectionManager::albumRootPath(const QString& givenPath)
0076 {
0077     QReadLocker readLocker(&d->lock);
0078 
0079     Q_FOREACH (AlbumRootLocation* const location, d->locations)
0080     {
0081         QString rootPath = location->albumRootPath();
0082         QString filePath = QDir::fromNativeSeparators(givenPath);
0083 
0084         if (!rootPath.isEmpty() && filePath.startsWith(rootPath))
0085         {
0086             // see also bug #221155 for extra checks
0087 
0088             if ((filePath == rootPath) || filePath.startsWith(rootPath + QLatin1Char('/')))
0089             {
0090                 return location->albumRootPath();
0091             }
0092         }
0093     }
0094 
0095     return QString();
0096 }
0097 
0098 bool CollectionManager::isAlbumRoot(const QUrl& fileUrl)
0099 {
0100     return isAlbumRoot(fileUrl.adjusted(QUrl::StripTrailingSlash).toLocalFile());
0101 }
0102 
0103 bool CollectionManager::isAlbumRoot(const QString& filePath)
0104 {
0105     QReadLocker readLocker(&d->lock);
0106 
0107     Q_FOREACH (AlbumRootLocation* const location, d->locations)
0108     {
0109         if (filePath == location->albumRootPath())
0110         {   // cppcheck-suppress useStlAlgorithm
0111             return true;
0112         }
0113     }
0114 
0115     return false;
0116 }
0117 
0118 QString CollectionManager::album(const QUrl& fileUrl)
0119 {
0120     return album(fileUrl.adjusted(QUrl::StripTrailingSlash).toLocalFile());
0121 }
0122 
0123 QString CollectionManager::album(const QString& filePath)
0124 {
0125     QReadLocker readLocker(&d->lock);
0126 
0127     Q_FOREACH (AlbumRootLocation* const location, d->locations)
0128     {
0129         QString rootPath = location->albumRootPath();
0130 
0131         if (rootPath.isEmpty() || !filePath.startsWith(rootPath))
0132         {
0133             continue;
0134         }
0135 
0136         QString album = filePath.mid(rootPath.length());
0137 
0138         if (album.isEmpty() ||( album == QLatin1String("/")))
0139         {
0140             return QLatin1String("/");
0141         }
0142         else if (album.startsWith(QLatin1Char('/')))
0143         {
0144             if (album.endsWith(QLatin1Char('/')))
0145             {
0146                 album.chop(1);
0147             }
0148 
0149             return album;
0150         }
0151     }
0152 
0153     return QString();
0154 }
0155 
0156 QString CollectionManager::album(const CollectionLocation& location, const QUrl& fileUrl)
0157 {
0158     return album(location, fileUrl.adjusted(QUrl::StripTrailingSlash).toLocalFile());
0159 }
0160 
0161 QString CollectionManager::album(const CollectionLocation& location, const QString& filePath)
0162 {
0163     if (location.isNull())
0164     {
0165         return QString();
0166     }
0167 
0168     QString absolutePath = location.albumRootPath();
0169 
0170     if (filePath == absolutePath)
0171     {
0172         return QLatin1String("/");
0173     }
0174     else
0175     {
0176         QString album = filePath.mid(absolutePath.length());
0177 
0178         if (album.endsWith(QLatin1Char('/')))
0179         {
0180             album.chop(1);
0181         }
0182 
0183         return album;
0184     }
0185 }
0186 
0187 QUrl CollectionManager::oneAlbumRoot()
0188 {
0189     return QUrl::fromLocalFile(oneAlbumRootPath());
0190 }
0191 
0192 QString CollectionManager::oneAlbumRootPath()
0193 {
0194     QReadLocker readLocker(&d->lock);
0195 
0196     Q_FOREACH (AlbumRootLocation* const location, d->locations)
0197     {
0198         if (location->status() == CollectionLocation::LocationAvailable)
0199         {   // cppcheck-suppress useStlAlgorithm
0200             return location->albumRootPath();
0201         }
0202     }
0203 
0204     return QString();
0205 }
0206 
0207 void CollectionManager::slotAlbumRootChange(const AlbumRootChangeset& changeset)
0208 {
0209     if (d->changingDB)
0210     {
0211         return;
0212     }
0213 
0214     switch (changeset.operation())
0215     {
0216         case AlbumRootChangeset::Added:
0217         case AlbumRootChangeset::Deleted:
0218             updateLocations();
0219             break;
0220 
0221         case AlbumRootChangeset::PropertiesChanged:
0222         {
0223             // label has changed
0224 
0225             CollectionLocation toBeEmitted;
0226 
0227             {
0228                 QReadLocker readLocker(&d->lock);
0229                 AlbumRootLocation* const location = d->locations.value(changeset.albumRootId());
0230 
0231                 if (location)
0232                 {
0233                     QList<AlbumRootInfo> infos = CoreDbAccess().db()->getAlbumRoots();
0234 
0235                     Q_FOREACH (const AlbumRootInfo& info, infos)
0236                     {
0237                         if (info.id == location->id())
0238                         {    // cppcheck-suppress useStlAlgorithm
0239                             location->setLabel(info.label);
0240                             toBeEmitted = *location;
0241                             break;
0242                         }
0243                     }
0244                 }
0245             }
0246 
0247             if (!toBeEmitted.isNull())
0248             {
0249                 Q_EMIT locationPropertiesChanged(toBeEmitted);
0250             }
0251 
0252             break;
0253         }
0254 
0255         case AlbumRootChangeset::Unknown:
0256             break;
0257     }
0258 }
0259 
0260 } // namespace Digikam