File indexing completed on 2023-05-30 11:30:45
0001 /** 0002 * Copyright (C) 2002-2004 Scott Wheeler <wheeler@kde.org> 0003 * 0004 * This program is free software; you can redistribute it and/or modify it under 0005 * the terms of the GNU General Public License as published by the Free Software 0006 * Foundation; either version 2 of the License, or (at your option) any later 0007 * version. 0008 * 0009 * This program is distributed in the hope that it will be useful, but WITHOUT ANY 0010 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 0011 * PARTICULAR PURPOSE. See the GNU General Public License for more details. 0012 * 0013 * You should have received a copy of the GNU General Public License along with 0014 * this program. If not, see <http://www.gnu.org/licenses/>. 0015 */ 0016 0017 #ifndef JUK_COLLECTIONLIST_H 0018 #define JUK_COLLECTIONLIST_H 0019 0020 #include <QHash> 0021 #include <QVector> 0022 #include <QReadWriteLock> 0023 0024 #include <KFileItem> 0025 0026 #include "playlist.h" 0027 #include "playlistitem.h" 0028 0029 class ViewMode; 0030 class KFileItemList; 0031 class KDirWatch; 0032 0033 /** 0034 * This type is for mapping QString track attributes like the album, artist 0035 * and track to an integer count representing the number of outstanding items 0036 * that hold the string. 0037 */ 0038 0039 typedef QHash<QString, int> TagCountDict; 0040 typedef QHashIterator<QString, int> TagCountDictIterator; 0041 0042 /** 0043 * We then have an array of dicts, one for each column in the list view. 0044 * The array is sparse (not every vector will have a TagCountDict so we use 0045 * pointers. 0046 */ 0047 0048 typedef QVector<TagCountDict *> TagCountDicts; 0049 0050 /** 0051 * This is the "collection", or all of the music files that have been opened 0052 * in any playlist and not explicitly removed from the collection. 0053 * 0054 * It is being implemented as a "semi-singleton" because I need universal access 0055 * to just one instance. However, because the collection needs initialization 0056 * parameters (that will not always be available when an instance is needed). 0057 * Hence there will be the familiar singleton "instance()" method along with an 0058 * "initialize()" method. 0059 */ 0060 0061 class CollectionListItem : public PlaylistItem 0062 { 0063 friend class Playlist; 0064 friend class CollectionList; 0065 friend class PlaylistItem; 0066 0067 public: 0068 virtual void refresh() override; 0069 PlaylistItem *itemForPlaylist(const Playlist *playlist); 0070 void updateCollectionDict(const QString &oldPath, const QString &newPath); 0071 void repaint() const; 0072 PlaylistItemList children() const { return m_children; } 0073 0074 protected: 0075 CollectionListItem(CollectionList *parent, const FileHandle &file); 0076 virtual ~CollectionListItem(); 0077 0078 void addChildItem(PlaylistItem *child); 0079 void removeChildItem(PlaylistItem *child); 0080 0081 /** 0082 * Returns true if the item is now up to date (even if this required a refresh) or 0083 * false if the item is invalid. 0084 */ 0085 bool checkCurrent(); 0086 0087 virtual CollectionListItem *collectionItem() override { return this; } 0088 0089 private: 0090 bool m_shuttingDown; 0091 PlaylistItemList m_children; 0092 }; 0093 0094 class CollectionList : public Playlist 0095 { 0096 friend class CollectionListItem; 0097 0098 Q_OBJECT 0099 0100 public: 0101 /** 0102 * A variety of unique value lists will be kept in the collection. This 0103 * enum can be used as an index into those structures. 0104 */ 0105 enum UniqueSetType { Artists = 0, Albums = 1, Genres = 2 }; 0106 0107 static CollectionList *instance(); 0108 static void initialize(PlaylistCollection *collection); 0109 0110 /** 0111 * Returns a unique set of values associated with the type specified. 0112 */ 0113 QStringList uniqueSet(UniqueSetType t) const; 0114 0115 CollectionListItem *lookup(const QString &file) const; 0116 0117 virtual CollectionListItem *createItem(const FileHandle &file, 0118 QTreeWidgetItem * = nullptr) override; 0119 0120 virtual void clearItems(const PlaylistItemList &items) override; 0121 0122 void setupTreeViewEntries(ViewMode *viewMode) const; 0123 0124 virtual bool canReload() const override { return true; } 0125 0126 void saveItemsToCache() const; 0127 0128 public slots: 0129 virtual void clear() override; 0130 0131 void slotCheckCache(); 0132 0133 void slotRemoveItem(const QString &file); 0134 void slotRefreshItem(const QString &file); 0135 0136 void slotNewItems(const KFileItemList &items); 0137 void slotRefreshItems(const QList<QPair<KFileItem, KFileItem> > &items); 0138 void slotDeleteItems(const KFileItemList &items); 0139 0140 protected: 0141 CollectionList(PlaylistCollection *collection); 0142 virtual ~CollectionList(); 0143 0144 virtual void dropEvent(QDropEvent *e) override; 0145 virtual void dragMoveEvent(QDragMoveEvent *e) override; 0146 0147 // These methods are used by CollectionListItem, which is a friend class. 0148 0149 void addToDict(const QString &file, CollectionListItem *item); 0150 void removeFromDict(const QString &file); 0151 0152 // These methods are also used by CollectionListItem, to manage the 0153 // strings used in generating the unique sets and tree view mode playlists. 0154 0155 QString addStringToDict(const QString &value, int column); 0156 void removeStringFromDict(const QString &value, int column); 0157 0158 void addWatched(const QString &file); 0159 void removeWatched(const QString &file); 0160 0161 virtual bool hasItem(const QString &file) const override; 0162 0163 signals: 0164 void signalCollectionChanged(); 0165 0166 /** 0167 * This is emitted when the set of columns that is visible is changed. 0168 * 0169 * \see Playlist::hideColumn() 0170 * \see Playlist::showColumn() 0171 * \see Playlist::isColumnVisible() 0172 */ 0173 void signalNewTag(const QString &, unsigned); 0174 void signalRemovedTag(const QString &, unsigned); 0175 0176 // Emitted once cached items are loaded, which allows for folder scanning 0177 // and invalid track detection to proceed. 0178 void cachedItemsLoaded(); 0179 0180 public slots: 0181 /** 0182 * Loads the CollectionListItems from the Cache. Should be called after program 0183 * initialization. 0184 */ 0185 void startLoadingCachedItems(); 0186 0187 /** 0188 * Loads a few items at a time. Intended to be single-shotted into the event 0189 * loop so that loading the music doesn't freeze the GUI. 0190 */ 0191 void loadNextBatchCachedItems(); 0192 0193 /** 0194 * Teardown from cache loading (e.g. a sort operation). Should 0195 * always be called if startLoadingCachedItems is called. 0196 */ 0197 void completedLoadingCachedItems(); 0198 0199 private: 0200 /** 0201 * Just the size of the above enum to keep from hard coding it in several 0202 * locations. 0203 */ 0204 static const int m_uniqueSetCount = 3; 0205 0206 static CollectionList *m_list; 0207 QHash<QString, CollectionListItem *> m_itemsDict; 0208 mutable QReadWriteLock m_itemsDictLock; 0209 KDirWatch *m_dirWatch; 0210 TagCountDicts m_columnTags; 0211 }; 0212 0213 #endif 0214 0215 // vim: set et sw=4 tw=0 sta: