playlistitem.h 6.72 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_PLAYLISTITEM_H
#define JUK_PLAYLISTITEM_H
19

Michael Pyne's avatar
Michael Pyne committed
20
#include <QExplicitlySharedDataPointer>
21
#include <QVector>
22
#include <QTreeWidgetItem>
23

24
#include "tagguesser.h"
25
#include "filehandle.h"
26
#include "juk_debug.h"
Frerich Raabe's avatar
Frerich Raabe committed
27

28
class Playlist;
29
class PlaylistItem;
30
class CollectionListItem;
Dirk Mueller's avatar
Dirk Mueller committed
31
class CollectionList;
32

33
typedef QVector<PlaylistItem *> PlaylistItemList;
34

35
/**
36
 * Items for the Playlist and the baseclass for CollectionListItem.
37 38 39 40 41 42
 * The constructors and destructor are protected and new items should be
 * created via Playlist::createItem().  Items should be removed by
 * Playlist::clear(), Playlist::deleteFromDisk(), Playlist::clearItem() or
 * Playlist::clearItem().
 */

43
class PlaylistItem : public QTreeWidgetItem
44
{
Frerich Raabe's avatar
Frerich Raabe committed
45 46 47 48 49 50 51 52 53
    friend class Playlist;
    friend class SearchPlaylist;
    friend class UpcomingPlaylist;
    friend class CollectionList;
    friend class CollectionListItem;
    friend class Pointer;

public:
    enum ColumnType { TrackColumn       = 0,
54 55 56 57 58 59 60 61 62 63 64
                      ArtistColumn      = 1,
                      AlbumColumn       = 2,
                      CoverColumn       = 3,
                      TrackNumberColumn = 4,
                      GenreColumn       = 5,
                      YearColumn        = 6,
                      LengthColumn      = 7,
                      BitrateColumn     = 8,
                      CommentColumn     = 9,
                      FileNameColumn    = 10,
                      FullPathColumn    = 11 };
Frerich Raabe's avatar
Frerich Raabe committed
65

66 67 68 69 70 71 72
    /**
     * A helper class to implement guarded pointer semantics.
     */

    class Pointer
    {
    public:
73 74 75 76 77 78 79 80 81 82 83
        Pointer() : m_item(0) {}
        Pointer(PlaylistItem *item);
        Pointer(const Pointer &p);
        ~Pointer();
        Pointer &operator=(PlaylistItem *item);
        bool operator==(const Pointer &p) const { return m_item == p.m_item; }
        bool operator!=(const Pointer &p) const { return m_item != p.m_item; }
        PlaylistItem *operator->() const { return m_item; }
        PlaylistItem &operator*() const { return *m_item; }
        operator PlaylistItem*() const { return m_item; }
        static void clear(PlaylistItem *item);
84 85

    private:
86
        PlaylistItem *m_item;
87
        static QMap<PlaylistItem *, QVector<Pointer *> > m_map;
88
    };
89
    friend class Pointer;
90

91
    static int lastColumn() { return FullPathColumn; }
92

93
    void setFile(const FileHandle &file);
94
    void setFile(const QString &file);
95
    FileHandle file() const;
96

97
    virtual QString text(int column) const;
98
    virtual void setText(int column, const QString &text);
99

100
    void setPlaying(bool playing = true, bool master = true);
101

102
    void guessTagInfo(TagGuesser::Type type);
103

104
    Playlist *playlist() const;
105

106
    virtual CollectionListItem *collectionItem() { return m_collectionItem; }
107

108 109 110 111 112 113 114
    /**
     * This is an identifier for the playlist item which will remain unique
     * throughout the process lifetime. It stays constant once the PlaylistItem
     * is created.
     */
    quint32 trackId() const { return m_trackId; }

115 116 117 118
    /**
     * The widths of items are cached when they're updated for us in computations
     * in the "weighted" listview column width mode.
     */
119
    QVector<int> cachedWidths() const;
120

121
    /**
122
     * This just refreshes from the in memory data.  This may seem pointless at
123 124
     * first, but this data is shared between all of the list view items that are
     * based on the same file, so if another one of those items changes its data
125 126
     * it is important to refresh the others.
     */
127
    virtual void refresh();
128 129 130 131 132

    /**
     * This rereads the tag from disk.  This affects all PlaylistItems based on
     * the same file.
     */
133
    virtual void refreshFromDisk();
134

135 136 137
    /**
     * Asks the item's playlist to remove the item (which uses deleteLater()).
     */
138
    virtual void clear();
139

140 141 142
    /**
     * Returns properly casted item below this one.
     */
143
    PlaylistItem *itemBelow() { return static_cast<PlaylistItem *>(treeWidget()->itemBelow(this)); }
144 145 146 147

    /**
     * Returns properly casted item above this one.
     */
148
    PlaylistItem *itemAbove() { return static_cast<PlaylistItem *>(treeWidget()->itemAbove(this)); }
149

150
    /**
Yuri Chornoivan's avatar
Yuri Chornoivan committed
151
     * Returns a reference to the list of the currently playing items, with the
152 153 154 155 156
     * first being the "master" item (i.e. the item from which the next track is
     * chosen).
     */
    static const PlaylistItemList &playingItems() { return m_playingItems; }

157
protected:
158
    /**
159
     * Items should always be created using Playlist::createItem() or through a
160
     * subclass or friend class.
161
     */
162
    PlaylistItem(CollectionListItem *item, Playlist *parent);
163
    PlaylistItem(CollectionListItem *item, Playlist *parent, QTreeWidgetItem *after);
164 165

    /**
Yuri Chornoivan's avatar
Yuri Chornoivan committed
166
     * This is the constructor that should be used by subclasses.
167
     */
168
    PlaylistItem(CollectionList *parent);
169

170 171 172 173 174 175
    /**
     * See the class documentation for an explanation of construction and deletion
     * of PlaylistItems.
     */
    virtual ~PlaylistItem();

Kacper Kasper's avatar
Kacper Kasper committed
176
    virtual int compare(const QTreeWidgetItem *item, int column, bool ascending) const;
177
    int compare(const PlaylistItem *firstItem, const PlaylistItem *secondItem, int column, bool ascending) const;
178

179
    bool operator<(const QTreeWidgetItem &other) const override;
Kacper Kasper's avatar
Kacper Kasper committed
180

181 182
    bool isValid() const;

183 184
    void setTrackId(quint32 id);

185 186 187 188
    /**
     * Shared data between all PlaylistItems from the same track (incl. the CollectionItem
     * representing said track.
     */
Michael Pyne's avatar
Michael Pyne committed
189
    struct Data : public QSharedData
190
    {
191
        FileHandle fileHandle; // Set within CollectionList
192
        QVector<QString> metadata; ///< Artist, album, or genre tags.  Other columns unfilled
193
        QVector<int> cachedWidths;
194
    };
195

Michael Pyne's avatar
Michael Pyne committed
196
    using DataPtr = QExplicitlySharedDataPointer<Data>;
197
    DataPtr sharedData() const { return d; }
198 199

private:
Michael Pyne's avatar
Michael Pyne committed
200
    DataPtr d;
201

202
    void setup(CollectionListItem *item);
203

204
    CollectionListItem *m_collectionItem;
205
    quint32 m_trackId;
206
    bool m_watched;
207
    static PlaylistItemList m_playingItems;
208 209
};

210
inline QDebug operator<<(QDebug s, const PlaylistItem &item)
211
{
212
    s << item.text(PlaylistItem::TrackColumn);
213 214 215
    return s;
}

216
#endif
217 218

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