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 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 #ifndef DIGIKAM_COLLECTION_MANAGER_H 0016 #define DIGIKAM_COLLECTION_MANAGER_H 0017 0018 // Qt includes 0019 0020 #include <QString> 0021 #include <QStringList> 0022 #include <QUrl> 0023 #include <QObject> 0024 0025 // Local includes 0026 0027 #include "digikam_export.h" 0028 0029 namespace Digikam 0030 { 0031 0032 class CollectionLocation; 0033 class AlbumRootChangeset; 0034 0035 class DIGIKAM_DATABASE_EXPORT CollectionManager : public QObject 0036 { 0037 Q_OBJECT 0038 0039 public: 0040 0041 enum LocationCheckResult 0042 { 0043 /// The check did not succeed, status unknown 0044 LocationInvalidCheck, 0045 0046 /// All right. The accompanying message may be empty. 0047 LocationAllRight, 0048 0049 /// Location can be added, but the user should be aware of a problem 0050 LocationHasProblems, 0051 0052 /// Adding the location will fail (e.g. there is already a location for the path) 0053 LocationNotAllowed 0054 }; 0055 0056 public: 0057 0058 static CollectionManager* instance(); 0059 static void cleanUp(); 0060 0061 /** 0062 * Disables the collection watch. 0063 * It will be reenabled as soon as refresh() is called 0064 * or any other action triggered. 0065 */ 0066 void setWatchDisabled(); 0067 0068 /** 0069 * Clears all locations and re-reads the lists of collection locations. 0070 * Enables the watch. 0071 */ 0072 void refresh(); 0073 0074 private Q_SLOTS: 0075 0076 void deviceAdded(const QString&); 0077 void deviceRemoved(const QString&); 0078 void accessibilityChanged(bool, const QString&); 0079 0080 private: 0081 0082 // Disabled 0083 CollectionManager(); 0084 explicit CollectionManager(QObject*) = delete; 0085 ~CollectionManager() override; 0086 0087 void clearLocations(); 0088 0089 Q_PRIVATE_SLOT(d, void slotTriggerUpdateVolumesList()) 0090 0091 Q_SIGNALS: // internal use only with slotTriggerUpdateVolumesList() 0092 0093 void triggerUpdateVolumesList(); 0094 0095 // ----------------------------------------------------------------------------- 0096 0097 /** @name Operations on Collection Location 0098 */ 0099 0100 //@{ 0101 0102 public: 0103 0104 /** 0105 * Add the given file system location as new collection location. 0106 * Type and availability will be detected. 0107 * On failure returns null. This would be the case if the given 0108 * url is already contained in another collection location. 0109 * You may pass an optional user-visible label that will be stored in the database. 0110 * The label has no further meaning and can be freely chosen. 0111 * 0112 * CollectionLocation objects returned are simple data containers. 0113 * If the corresponding location is returned, the data is still safe to access, 0114 * but does not represent anything. 0115 * Therefore, do not store returned objects, but prefer to retrieve them freshly. 0116 */ 0117 CollectionLocation addLocation(const QUrl& fileUrl, 0118 const QString& label = QString()); 0119 CollectionLocation addNetworkLocation(const QUrl& fileUrl, 0120 const QString& label = QString()); 0121 CollectionLocation refreshLocation(const CollectionLocation& location, int newType, 0122 const QStringList& pathList, 0123 const QString& label = QString()); 0124 0125 /** 0126 * Analyzes the given file path. Creates an info message 0127 * describing the result of identification or possible problems. 0128 * The text is i18n'ed and can be presented to the user. 0129 * The returned result enum describes the test result. 0130 */ 0131 LocationCheckResult checkLocation(const QUrl& fileUrl, QList<CollectionLocation>& assumeDeleted, 0132 QString* message = nullptr, QString* suggestedMessageIconName = nullptr); 0133 LocationCheckResult checkNetworkLocation(const QUrl& fileUrl, QList<CollectionLocation>& assumeDeleted, 0134 QString* message = nullptr, QString* suggestedMessageIconName = nullptr); 0135 0136 /** 0137 * Removes the given location. This means that all images contained on the 0138 * location will be removed from the database, all tags will be lost. 0139 */ 0140 void removeLocation(const CollectionLocation& location); 0141 0142 /** 0143 * Sets the label of the given location 0144 */ 0145 void setLabel(const CollectionLocation& location, const QString& label); 0146 0147 /** 0148 * Changes the CollectionLocation::Type of the given location 0149 */ 0150 void changeType(const CollectionLocation& location, int type); 0151 0152 /** 0153 * Checks the locations of type HardWired. If one of these is not available currently, 0154 * it is added to the list of disappeared locations. 0155 * This case may happen if a file system is changed, a backup restored or other actions 0156 * taken that change the UUID, although the data may still be available and mounted. 0157 * If there are hard-wired volumes available which are candidates for a newly appeared 0158 * volume (in fact those that do not contain any collections currently), they are 0159 * added to the map, identifier -> i18n'ed user presentable description. 0160 * The identifier can be used for changeVolume. 0161 */ 0162 QList<CollectionLocation> checkHardWiredLocations(); 0163 0164 /** 0165 * For a given disappeared location (retrieved from checkHardWiredLocations()) 0166 * retrieve a user-presentable technical description (excluding the CollectionLocation's label) 0167 * and a list of identifiers and corresponding user presentable strings of candidates 0168 * to where the given location may have been moved. 0169 */ 0170 void migrationCandidates(const CollectionLocation& disappearedLocation, 0171 QString* const technicalDescription, 0172 QStringList* const candidateIdentifiers, 0173 QStringList* const candidateDescriptions); 0174 0175 /** 0176 * Migrates the existing collection to a new volume, identified by an internal identifier 0177 * as returned by checkHardWiredLocations(). 0178 * Use this _only_ to react to changes like those detailed for checkHardWiredLocations; 0179 * the actual data pointed to shall be unchanged. 0180 */ 0181 void migrateToVolume(const CollectionLocation& location, const QString& identifier); 0182 0183 /** 0184 * Returns a list of all CollectionLocations stored in the database 0185 */ 0186 QList<CollectionLocation> allLocations(); 0187 0188 /** 0189 * Returns a list of all currently available CollectionLocations 0190 */ 0191 QList<CollectionLocation> allAvailableLocations(); 0192 0193 /** 0194 * Returns the location for the given album root id 0195 */ 0196 CollectionLocation locationForAlbumRootId(int id); 0197 0198 /** 0199 * Returns the CollectionLocation that contains the given album root. 0200 * The path must be an album root with isAlbumRoot() == true. 0201 * Returns 0 if no collection location matches. 0202 * Only available (or hidden, but available) locations are guaranteed to be found. 0203 */ 0204 CollectionLocation locationForAlbumRoot(const QUrl& fileUrl); 0205 CollectionLocation locationForAlbumRootPath(const QString& albumRootPath); 0206 0207 /** 0208 * Returns the CollectionLocation that contains the given path. 0209 * Equivalent to calling locationForAlbumRoot(albumRoot(fileUrl)). 0210 * Only available (or hidden, but available) locations are guaranteed to be found. 0211 */ 0212 CollectionLocation locationForUrl(const QUrl& fileUrl); 0213 CollectionLocation locationForPath(const QString& filePath); 0214 0215 private: 0216 0217 void updateLocations(); 0218 0219 Q_SIGNALS: 0220 0221 /** 0222 * Emitted when the status of a collection location changed. 0223 * This means that the location became available, hidden or unavailable. 0224 * 0225 * An added location will change its status after addition, 0226 * from Null to Available, Hidden or Unavailable. 0227 * 0228 * A removed location will change its status to Deleted 0229 * during the removal; in this case, you shall not use the object 0230 * passed with this signal with any method of CollectionManager. 0231 * 0232 * The second signal argument is of type CollectionLocation::Status 0233 * and describes the status before the state change occurred 0234 */ 0235 void locationStatusChanged(const CollectionLocation& location, int oldStatus); 0236 0237 /** 0238 * Emitted when the label of a collection location is changed 0239 */ 0240 void locationPropertiesChanged(const CollectionLocation& location); 0241 0242 //@} 0243 0244 // ----------------------------------------------------------------------------- 0245 0246 /** @name Operations on Albums 0247 */ 0248 0249 //@{ 0250 0251 public: 0252 0253 /** 0254 * Returns a list of the paths of all currently available root paths 0255 */ 0256 QStringList allAvailableAlbumRootPaths(); 0257 0258 /** 0259 * Returns the album root path with the given id. 0260 * Returns a null QString if the root path does not exist or is not available. 0261 */ 0262 QString albumRootPath(int id); 0263 0264 /** 0265 * Returns the album root label with the given id. 0266 * Returns a null QString if the root path does not exist or is not available. 0267 */ 0268 QString albumRootLabel(int id); 0269 0270 //@{ 0271 /** 0272 * For a given path, the part of the path that forms the album root is returned, 0273 * ending without a slash. Example: "/media/fotos/Paris 2007" gives "/media/fotos". 0274 * Only available (or hidden, but available) album roots are guaranteed to be found. 0275 */ 0276 QUrl albumRoot(const QUrl& fileUrl); 0277 QString albumRootPath(const QUrl& fileUrl); 0278 QString albumRootPath(const QString& filePath); 0279 //@} 0280 0281 /** 0282 * Returns true if the given path forms an album root. 0283 * It will return false if the path is a path below an album root, 0284 * or if the path does not belong to an album root. 0285 * Example: "/media/fotos/Paris 2007" is an album with album root "/media/fotos". 0286 * "/media/fotos" returns true, "/media/fotos/Paris 2007" and "/media" return false. 0287 * Only available (or hidden, but available) album roots are guaranteed to be found. 0288 */ 0289 bool isAlbumRoot(const QUrl& fileUrl); 0290 0291 /** 0292 * The file path should not end with the directory slash. Using CoreDbUrl's method is fine. 0293 */ 0294 bool isAlbumRoot(const QString& filePath); 0295 0296 //@{ 0297 /** 0298 * Returns the album part of the given file path, i.e. the album root path 0299 * at the beginning is removed and the second part, starting with "/", ending without a slash, 0300 * is returned. Example: "/media/fotos/Paris 2007" gives "/Paris 2007" 0301 * Returns a null QString if the file path is not located in an album root. 0302 * Returns "/" if the file path is an album root. 0303 * Note that trailing slashes are removed in the return value, regardless if there was 0304 * one or not. 0305 * Note that you have to feed a path/url pointing to a directory. File names cannot 0306 * be recognized as such by this method, and will be treated as a directory. 0307 */ 0308 QString album(const QUrl& fileUrl); 0309 QString album(const QString& filePath); 0310 QString album(const CollectionLocation& location, const QUrl& fileUrl); 0311 QString album(const CollectionLocation& location, const QString& filePath); 0312 //@} 0313 0314 //@{ 0315 /** 0316 * Returns just one album root, out of the list of available location, 0317 * the one that is most suitable to serve as a default, e.g. 0318 * to suggest as default place when the user wants to add files. 0319 */ 0320 QUrl oneAlbumRoot(); 0321 QString oneAlbumRootPath(); 0322 //@} 0323 0324 private Q_SLOTS: 0325 0326 void slotAlbumRootChange(const AlbumRootChangeset& changeset); 0327 0328 //@} 0329 0330 public: 0331 0332 class Private; 0333 0334 private: 0335 0336 static CollectionManager* m_instance; 0337 0338 Private* const d; 0339 0340 friend class Private; 0341 friend class CoreDbWatch; 0342 friend class CoreDbAccess; 0343 }; 0344 0345 } // namespace Digikam 0346 0347 #endif // DIGIKAM_COLLECTION_MANAGER_H