collectionlist.h 6.49 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/**
 * Copyright (C) 2002-2004 Scott Wheeler <wheeler@kde.org>
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */
16

Michael Pyne's avatar
Michael Pyne committed
17 18
#ifndef JUK_COLLECTIONLIST_H
#define JUK_COLLECTIONLIST_H
19

20 21
#include <QHash>
#include <QVector>
22

23
#include "playlist.h"
24 25
#include "playlistitem.h"

26
class ViewMode;
27 28 29
class KFileItem;
class KFileItemList;
class KDirWatch;
30 31 32 33 34 35 36

/**
 * This type is for mapping QString track attributes like the album, artist
 * and track to an integer count representing the number of outstanding items
 * that hold the string.
 */

37 38
typedef QHash<QString, int> TagCountDict;
typedef QHashIterator<QString, int> TagCountDictIterator;
39 40

/**
41 42 43
 * We then have an array of dicts, one for each column in the list view.
 * The array is sparse (not every vector will have a TagCountDict so we use
 * pointers.
44 45
 */

46
typedef QVector<TagCountDict *> TagCountDicts;
47

48
/**
49 50 51 52
 * This is the "collection", or all of the music files that have been opened
 * in any playlist and not explicitly removed from the collection.
 *
 * It is being implemented as a "semi-singleton" because I need universal access
53 54
 * to just one instance.  However, because the collection needs initialization
 * parameters (that will not always be available when an instance is needed).
55 56 57
 * Hence there will be the familiar singleton "instance()" method allong with an
 * "initialize()" method.
 */
58

59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
class CollectionListItem : public PlaylistItem
{
    friend class Playlist;
    friend class CollectionList;
    friend class PlaylistItem;

public:
    virtual void refresh();
    PlaylistItem *itemForPlaylist(const Playlist *playlist);
    void updateCollectionDict(const QString &oldPath, const QString &newPath);
    void repaint() const;
    PlaylistItemList children() const { return m_children; }

protected:
    CollectionListItem(CollectionList *parent, const FileHandle &file);
    virtual ~CollectionListItem();

    void addChildItem(PlaylistItem *child);
    void removeChildItem(PlaylistItem *child);

    /**
     * Returns true if the item is now up to date (even if this required a refresh) or
     * false if the item is invalid.
     */
    bool checkCurrent();

    virtual CollectionListItem *collectionItem() { return this; }

private:
    bool m_shuttingDown;
    PlaylistItemList m_children;
};

92
class CollectionList : public Playlist
93
{
94 95
    friend class CollectionListItem;

96
    Q_OBJECT
97

98
public:
99 100 101 102 103 104
    /**
     * A variety of unique value lists will be kept in the collection.  This
     * enum can be used as an index into those structures.
     */
    enum UniqueSetType { Artists = 0, Albums = 1, Genres = 2 };

105
    static CollectionList *instance();
106
    static void initialize(PlaylistCollection *collection);
107

108 109 110
    /**
     * Returns a unique set of values associated with the type specified.
     */
111
    QStringList uniqueSet(UniqueSetType t) const;
112

113
    CollectionListItem *lookup(const QString &file) const;
114

115
    virtual CollectionListItem *createItem(const FileHandle &file,
116
                                     QTreeWidgetItem * = nullptr);
117

118 119
    void emitVisibleColumnsChanged() { emit signalVisibleColumnsChanged(); }

120 121
    virtual void clearItems(const PlaylistItemList &items);

122 123
    void setupTreeViewEntries(ViewMode *viewMode) const;

124 125
    virtual bool canReload() const { return true; }

126 127
    void saveItemsToCache() const;

128
public slots:
129
    virtual void paste();
130
    virtual void clear();
131
    void slotCheckCache();
132 133 134

    void slotRemoveItem(const QString &file);
    void slotRefreshItem(const QString &file);
135

136
    void slotNewItems(const KFileItemList &items);
137
    void slotRefreshItems(const QList<QPair<KFileItem, KFileItem> > &items);
138
    void slotDeleteItems(const KFileItemList &items);
139

140
protected:
141
    CollectionList(PlaylistCollection *collection);
142
    virtual ~CollectionList();
143

144 145
    virtual void dropEvent(QDropEvent *e);
    virtual void dragMoveEvent(QDragMoveEvent *e);
146

147
    // These methods are used by CollectionListItem, which is a friend class.
148

149
    void addToDict(const QString &file, CollectionListItem *item) { m_itemsDict.insert(file, item); }
150
    void removeFromDict(const QString &file) { m_itemsDict.remove(file); }
151

152 153 154
    // These methods are also used by CollectionListItem, to manage the
    // strings used in generating the unique sets and tree view mode playlists.

155 156
    QString addStringToDict(const QString &value, int column);
    void removeStringFromDict(const QString &value, int column);
157

158 159
    void addWatched(const QString &file);
    void removeWatched(const QString &file);
160

161
    virtual bool hasItem(const QString &file) const { return m_itemsDict.contains(file); }
162

163 164
signals:
    void signalCollectionChanged();
165

166 167 168 169 170 171 172 173
    /**
     * This is emitted when the set of columns that is visible is changed.
     *
     * \see Playlist::hideColumn()
     * \see Playlist::showColumn()
     * \see Playlsit::isColumnVisible()
     */
    void signalVisibleColumnsChanged();
174 175 176
    void signalNewTag(const QString &, unsigned);
    void signalRemovedTag(const QString &, unsigned);

177 178 179 180
    // Emitted once cached items are loaded, which allows for folder scanning
    // and invalid track detection to proceed.
    void cachedItemsLoaded();

Michael Pyne's avatar
Michael Pyne committed
181 182 183 184 185
public slots:
    /**
     * Loads the CollectionListItems from the Cache.  Should be called after program
     * initialization.
     */
186 187 188 189 190 191 192 193 194
    void startLoadingCachedItems();

    /**
     * Loads a few items at a time. Intended to be single-shotted into the event
     * loop so that loading the music doesn't freeze the GUI.
     */
    void loadNextBatchCachedItems();

    /**
Michael Pyne's avatar
Michael Pyne committed
195
     * Teardown from cache loading (e.g. a sort operation). Should
196 197 198
     * always be called if startLoadingCachedItems is called.
     */
    void completedLoadingCachedItems();
Michael Pyne's avatar
Michael Pyne committed
199

200
private:
201 202 203 204 205 206
    /**
     * Just the size of the above enum to keep from hard coding it in several
     * locations.
     */
    static const int m_uniqueSetCount = 3;

207
    static CollectionList *m_list;
208
    QHash<QString, CollectionListItem *> m_itemsDict;
209
    KDirWatch *m_dirWatch;
210
    TagCountDicts m_columnTags;
211 212
};

213
#endif
214 215

// vim: set et sw=4 tw=0 sta: