File indexing completed on 2025-01-05 03:53:47
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2004-06-15 0007 * Description : digiKam album types 0008 * 0009 * SPDX-FileCopyrightText: 2004-2005 by Renchi Raju <renchi dot raju at gmail dot com> 0010 * SPDX-FileCopyrightText: 2006-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * SPDX-FileCopyrightText: 2014-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 #ifndef DIGIKAM_ALBUM_H 0018 #define DIGIKAM_ALBUM_H 0019 0020 // Qt includes 0021 0022 #include <QMap> 0023 #include <QUrl> 0024 #include <QList> 0025 #include <QString> 0026 #include <QObject> 0027 #include <QMetaType> 0028 #include <QReadWriteLock> 0029 0030 // Local includes 0031 0032 #include "coredbalbuminfo.h" 0033 #include "digikam_export.h" 0034 0035 namespace Digikam 0036 { 0037 0038 /** 0039 * Album list type definition. 0040 */ 0041 class Album; 0042 typedef QList<Album*> AlbumList; 0043 0044 class CoreDbUrl; 0045 0046 /** 0047 * \class Album 0048 * \brief Abstract base class for all album types 0049 * 0050 * A class which provides an abstraction for a type Album. This class is meant to 0051 * be derived and every time a new Album Type is defined add a enum corresponding 0052 * to that to Album::Type 0053 * 0054 * This class provides a means of building a tree representation for 0055 * Albums @see Album::setParent(). 0056 */ 0057 class DIGIKAM_GUI_EXPORT Album 0058 { 0059 public: 0060 0061 enum Type 0062 { 0063 PHYSICAL=0, ///< A physical album type @see PAlbum 0064 TAG, ///< A tag album type @see TAlbum 0065 DATE, ///< A date album type @see DAlbum 0066 SEARCH, ///< A search album type @see SAlbum 0067 FACE ///< A faces album type @see FAlbum 0068 }; 0069 0070 /** 0071 * @return the parent album for this album 0072 */ 0073 Album* parent() const; 0074 0075 /** 0076 * @return the first child of this album or 0 if no children 0077 */ 0078 Album* firstChild() const; 0079 0080 /** 0081 * @return the last child of this album or 0 if no children 0082 */ 0083 Album* lastChild() const; 0084 0085 /** 0086 * @return the next sibling of this album of this album or 0 0087 * if no next sibling 0088 * @see AlbumIterator 0089 */ 0090 Album* next() const; 0091 0092 /** 0093 * @return the previous sibling of this album of this album or 0 if no 0094 * previous sibling 0095 * @see AlbumIterator 0096 */ 0097 Album* prev() const; 0098 0099 /** 0100 * @return the child of this album at row 0101 */ 0102 Album* childAtRow(int row) const; 0103 0104 /** 0105 * @return a list of all child Albums 0106 */ 0107 AlbumList childAlbums(bool recursive = false); 0108 0109 /** 0110 * @return a list of all child Albums 0111 */ 0112 QList<int> childAlbumIds(bool recursive = false); 0113 0114 /** 0115 * @return the type of album 0116 * @see Type 0117 */ 0118 Type type() const; 0119 0120 /** 0121 * Each album has a @p ID uniquely identifying it in the set of Albums of 0122 * a Type 0123 * 0124 * \note The @p ID for a root Album is always 0 0125 * 0126 * @return the @p ID of the album 0127 * @see globalID() 0128 */ 0129 int id() const; 0130 0131 /** 0132 * An album ID is only unique among the set of all Albums of its Type. 0133 * This is a global Identifier which will uniquely identifying the Album 0134 * among all Albums 0135 * 0136 * \note If you are adding a new Album Type make sure to update 0137 * this implementation. 0138 * 0139 * You can always get the @p ID of the album using something like 0140 * 0141 * \code 0142 * int albumID = rootAlbum->globalID() - album->globalID(); 0143 * \endcode 0144 * 0145 * @return the @p globalID of the album 0146 * @see id() 0147 */ 0148 int globalID() const; 0149 0150 /** 0151 * @return the @p childCount of the album 0152 */ 0153 int childCount() const; 0154 0155 /** 0156 * @return the @p rowFromAlbum of the album 0157 */ 0158 int rowFromAlbum() const; 0159 0160 /** 0161 * @return the @p title aka name of the album 0162 */ 0163 QString title() const; 0164 0165 /** 0166 * @return the kde url of the album 0167 */ 0168 virtual CoreDbUrl databaseUrl() const = 0; 0169 0170 /** 0171 * @return true is the album is a Root Album 0172 */ 0173 bool isRoot() const; 0174 0175 /** 0176 * @return true if the @p album is in the parent hierarchy 0177 * 0178 * @param album the album to check whether it belongs in the child 0179 * hierarchy 0180 */ 0181 bool isAncestorOf(Album* const album) const; 0182 0183 /** 0184 * @return true if the Album was created by Labels Tree 0185 * 0186 */ 0187 bool isUsedByLabelsTree() const; 0188 0189 /** 0190 * @return true if the album was created to be a trash 0191 * virtual album 0192 */ 0193 bool isTrashAlbum() const; 0194 0195 /** 0196 * This allows to associate some "extra" data to a Album. As one 0197 * Album can be used by several objects (often views) which all need 0198 * to add some data, you have to use a key to reference your extra data 0199 * within the Album. 0200 * 0201 * That way a Album can hold and provide access to all those views 0202 * separately. 0203 * 0204 * for eg, 0205 * 0206 * \code 0207 * album->setExtraData( this, searchFolderItem ); 0208 * \endcode 0209 * 0210 * and can later access the searchFolderItem by doing 0211 * 0212 * \code 0213 * SearchFolderItem *item = static_cast<SearchFolderItem*>(album->extraData(this)); 0214 * \endcode 0215 * 0216 * Note: you have to remove and destroy the data you associated yourself 0217 * when you don't need it anymore! 0218 * 0219 * @param key the key of the extra data 0220 * @param value the value of the extra data 0221 * @see extraData 0222 * @see removeExtraData 0223 */ 0224 void setExtraData(const void* const key, void* const value); 0225 0226 /** 0227 * Remove the associated extra data associated with @p key 0228 * 0229 * @param key the key of the extra data 0230 * @see setExtraData 0231 * @see extraData 0232 */ 0233 void removeExtraData(const void* const key); 0234 0235 /** 0236 * Retrieve the associated extra data associated with @p key 0237 * 0238 * @param key the key of the extra data 0239 * @see setExtraData 0240 * @see extraData 0241 */ 0242 void* extraData(const void* const key) const; 0243 0244 /** 0245 * Sets the property m_usedByLabelsTree to true if the search album 0246 * was created using the Colors and labels tree view 0247 * 0248 * @param isUsed => the status of the usage 0249 */ 0250 void setUsedByLabelsTree(bool isUsed); 0251 0252 /** 0253 * @brief Produces the global id 0254 * @param type The type of the album 0255 * @param id the (type-specific) id of the album 0256 * @return the global id 0257 */ 0258 static int globalID(Type type, int id); 0259 0260 protected: 0261 0262 /** 0263 * Constructor 0264 */ 0265 Album(Album::Type type, int id, bool root); 0266 0267 /** 0268 * Destructor 0269 * 0270 * this will also recursively delete all child Albums 0271 */ 0272 virtual ~Album(); 0273 0274 /** 0275 * Delete all child albums and also remove any associated extra data 0276 */ 0277 void clear(); 0278 0279 /** 0280 * @internal use only 0281 * 0282 * Set a new title for the album 0283 * 0284 * @param title new title for the album 0285 */ 0286 void setTitle(const QString& title); 0287 0288 /** 0289 * @internal use only 0290 * 0291 * Set the parent of the album 0292 * 0293 * @param parent set the parent album of album to @p parent 0294 */ 0295 void setParent(Album* const parent); 0296 0297 /** 0298 * @internal use only 0299 * 0300 * Insert an Album as a child for this album 0301 * 0302 * @param child the Album to add as child 0303 */ 0304 void insertChild(Album* const child); 0305 0306 /** 0307 * @internal use only 0308 * 0309 * Remove a Album from the children list for this album 0310 * 0311 * @param child the Album to remove 0312 */ 0313 void removeChild(Album* const child); 0314 0315 private: 0316 0317 // Disable 0318 Album() = delete; 0319 Album& operator==(const Album&) = delete; 0320 Q_DISABLE_COPY(Album) 0321 0322 private: 0323 0324 bool m_root; 0325 bool m_usedByLabelsTree; 0326 volatile bool m_albumInDeletion; 0327 0328 int m_id; 0329 0330 QString m_name; 0331 QString m_title; 0332 0333 QMap<const void*, void*> m_extraMap; 0334 0335 QList<Album*> m_childCache; 0336 mutable QReadWriteLock m_cacheLock; 0337 0338 Type m_type; 0339 0340 Album* m_parent; 0341 0342 friend class AlbumManager; 0343 }; 0344 0345 /** 0346 * \class PAlbum 0347 * 0348 * A Physical Album representation 0349 */ 0350 class DIGIKAM_GUI_EXPORT PAlbum : public Album 0351 { 0352 public: 0353 0354 /// Constructor for root album 0355 explicit PAlbum(const QString& title); 0356 0357 /// Constructor for album root albums 0358 PAlbum(int albumRoot, const QString& label); 0359 0360 /// Constructor for normal albums 0361 PAlbum(int albumRoot, const QString& parentPath, const QString& title, int id); 0362 0363 /// Constructor for Trash album 0364 PAlbum(const QString& parentPath, int albumRoot); 0365 ~PAlbum() override; 0366 0367 void setCaption(const QString& caption); 0368 void setCategory(const QString& category); 0369 void setDate(const QDate& date); 0370 0371 QString albumRootPath() const; 0372 QString albumRootLabel() const; 0373 int albumRootId() const; 0374 QString caption() const; 0375 QString category() const; 0376 QDate date() const; 0377 QString albumPath() const; 0378 QString prettyUrl() const; 0379 QString folderPath() const; 0380 CoreDbUrl databaseUrl() const override; 0381 QUrl fileUrl() const; 0382 qlonglong iconId() const; 0383 bool isAlbumRoot() const; 0384 0385 private: 0386 0387 /** 0388 * A special integer for Trash virtual folders Ids; 0389 * That gets decremented not incremented 0390 */ 0391 static int m_uniqueTrashId; 0392 0393 bool m_isAlbumRootAlbum; 0394 0395 int m_albumRootId; 0396 0397 QString m_path; 0398 QString m_parentPath; 0399 QString m_category; 0400 QString m_caption; 0401 qlonglong m_iconId; 0402 0403 QDate m_date; 0404 0405 friend class AlbumManager; 0406 }; 0407 0408 /** 0409 * \class TAlbum 0410 * 0411 * A Tag Album representation 0412 */ 0413 class DIGIKAM_GUI_EXPORT TAlbum : public Album 0414 { 0415 public: 0416 0417 TAlbum(const QString& title, int id, bool root=false); 0418 ~TAlbum() override; 0419 0420 /** 0421 * @return The tag path, e.g. "/People/Friend/John" if leadingSlash is true, 0422 * "People/Friend/John" if leadingSlash if false. 0423 * The root TAlbum returns "/" resp. "". 0424 */ 0425 QString tagPath(bool leadingSlash = true) const; 0426 QString standardIconName() const; 0427 CoreDbUrl databaseUrl() const override; 0428 QString prettyUrl() const; 0429 QString icon() const; 0430 qlonglong iconId() const; 0431 QList<int> tagIDs() const; 0432 0433 bool isInternalTag() const; 0434 bool hasProperty(const QString& key) const; 0435 QString property(const QString& key) const; 0436 QMap<QString, QString> properties() const; 0437 0438 private: 0439 0440 int m_pid; 0441 0442 QString m_icon; 0443 qlonglong m_iconId; 0444 0445 friend class AlbumManager; 0446 }; 0447 0448 /** 0449 * \class DAlbum 0450 * 0451 * A Date Album representation 0452 */ 0453 class DIGIKAM_GUI_EXPORT DAlbum : public Album 0454 { 0455 public: 0456 0457 enum Range 0458 { 0459 Month = 0, 0460 Year 0461 }; 0462 0463 public: 0464 0465 explicit DAlbum(const QDate& date, bool root=false, Range range=Month); 0466 ~DAlbum() override; 0467 0468 QDate date() const; 0469 Range range() const; 0470 CoreDbUrl databaseUrl() const override; 0471 0472 private: 0473 0474 static int m_uniqueID; 0475 QDate m_date; 0476 Range m_range; 0477 0478 friend class AlbumManager; 0479 }; 0480 0481 /** 0482 * \class SAlbum 0483 * 0484 * A Search Album representation 0485 */ 0486 class DIGIKAM_GUI_EXPORT SAlbum : public Album 0487 { 0488 public: 0489 0490 SAlbum(const QString& title, int id, bool root=false); 0491 ~SAlbum() override; 0492 0493 CoreDbUrl databaseUrl() const override; 0494 QString query() const; 0495 DatabaseSearch::Type searchType() const; 0496 bool isNormalSearch() const; 0497 bool isAdvancedSearch() const; 0498 bool isKeywordSearch() const; 0499 bool isTimelineSearch() const; 0500 bool isHaarSearch() const; 0501 bool isMapSearch() const; 0502 bool isDuplicatesSearch() const; 0503 0504 /** 0505 * Indicates whether this album is a temporary search or not. 0506 * 0507 * @return true if this is a temporary search album, else false 0508 */ 0509 bool isTemporarySearch() const; 0510 0511 QString displayTitle() const; 0512 0513 /** 0514 * Returns the title of search albums that is used to mark them as a 0515 * temporary search that isn't saved officially yet and is only used for 0516 * viewing purposes. 0517 * 0518 * @param type the type of the search to get the temporary title for 0519 * @param haarType there are several haar searches, so that this search type 0520 * needs a special handling 0521 * @return string that identifies this album uniquely as an unsaved search 0522 */ 0523 static QString getTemporaryTitle(DatabaseSearch::Type type, 0524 DatabaseSearch::HaarSearchType haarType = DatabaseSearch::HaarImageSearch); 0525 0526 /** 0527 * Returns the title for a temporary haar search depending on the sub-type 0528 * used for this search 0529 * 0530 * @param haarType type of the haar search to get the name for 0531 * @return string that identifies this album uniquely as an unsaved search 0532 */ 0533 static QString getTemporaryHaarTitle(DatabaseSearch::HaarSearchType haarType); 0534 0535 private: 0536 0537 void setSearch(DatabaseSearch::Type type, const QString& query); 0538 0539 private: 0540 0541 QString m_query; 0542 DatabaseSearch::Type m_searchType; 0543 0544 friend class AlbumManager; 0545 }; 0546 0547 /** 0548 * \class AlbumIterator 0549 * 0550 * Iterate over all children of this Album. 0551 * \note It will not include the specified album 0552 * 0553 * Example usage: 0554 * \code 0555 * AlbumIterator it(album); 0556 * while ( it.current() ) 0557 * { 0558 * qCDebug(DIGIKAM_GENERAL_LOG) << "Album: " << it.current()->title(); 0559 * ++it; 0560 * } 0561 * \endcode 0562 * 0563 * \warning Do not delete albums using this iterator. 0564 */ 0565 class DIGIKAM_GUI_EXPORT AlbumIterator 0566 { 0567 public: 0568 0569 explicit AlbumIterator(Album* const album); 0570 ~AlbumIterator(); 0571 0572 AlbumIterator& operator++(); 0573 Album* operator*(); 0574 Album* current() const; 0575 0576 private: 0577 0578 // Disable 0579 AlbumIterator() = delete; 0580 Q_DISABLE_COPY(AlbumIterator) 0581 0582 private: 0583 0584 Album* m_current; 0585 Album* m_root; 0586 }; 0587 0588 } // namespace Digikam 0589 0590 Q_DECLARE_METATYPE(Digikam::Album*) 0591 Q_DECLARE_METATYPE(QList<Digikam::TAlbum*>) 0592 0593 #endif // DIGIKAM_ALBUM_H