File indexing completed on 2023-10-03 04:07: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_PLAYLISTITEM_H 0018 #define JUK_PLAYLISTITEM_H 0019 0020 #include <QExplicitlySharedDataPointer> 0021 #include <QVector> 0022 #include <QHash> 0023 #include <QTreeWidgetItem> 0024 0025 #include "tagguesser.h" 0026 #include "filehandle.h" 0027 #include "juk_debug.h" 0028 0029 class Playlist; 0030 class PlaylistItem; 0031 class CollectionListItem; 0032 class CollectionList; 0033 0034 typedef QVector<PlaylistItem *> PlaylistItemList; 0035 0036 /** 0037 * Items for the Playlist and the baseclass for CollectionListItem. 0038 * The constructors and destructor are protected and new items should be 0039 * created via Playlist::createItem(). Items should be removed by 0040 * Playlist::clear(), Playlist::deleteFromDisk(), Playlist::clearItem() or 0041 * Playlist::clearItem(). 0042 */ 0043 0044 class PlaylistItem : public QTreeWidgetItem 0045 { 0046 friend class Playlist; 0047 friend class SearchPlaylist; 0048 friend class UpcomingPlaylist; 0049 friend class CollectionList; 0050 friend class CollectionListItem; 0051 friend class Pointer; 0052 0053 public: 0054 enum ColumnType { TrackColumn = 0, 0055 ArtistColumn = 1, 0056 AlbumColumn = 2, 0057 CoverColumn = 3, 0058 TrackNumberColumn = 4, 0059 GenreColumn = 5, 0060 YearColumn = 6, 0061 LengthColumn = 7, 0062 BitrateColumn = 8, 0063 CommentColumn = 9, 0064 FileNameColumn = 10, 0065 FullPathColumn = 11 }; 0066 0067 /** 0068 * A helper class to implement guarded pointer semantics. 0069 */ 0070 0071 class Pointer 0072 { 0073 public: 0074 Pointer() : m_item(0) {} 0075 Pointer(PlaylistItem *item); 0076 Pointer(const Pointer &p); 0077 ~Pointer(); 0078 Pointer &operator=(PlaylistItem *item); 0079 bool operator==(const Pointer &p) const { return m_item == p.m_item; } 0080 bool operator!=(const Pointer &p) const { return m_item != p.m_item; } 0081 PlaylistItem *operator->() const { return m_item; } 0082 PlaylistItem &operator*() const { return *m_item; } 0083 operator PlaylistItem*() const { return m_item; } 0084 static void clear(PlaylistItem *item); 0085 0086 private: 0087 PlaylistItem *m_item; 0088 static QHash<PlaylistItem *, QVector<Pointer *> > m_itemPointers; 0089 }; 0090 friend class Pointer; 0091 0092 static int lastColumn() { return FullPathColumn; } 0093 0094 void setFile(const FileHandle &file); 0095 void setFile(const QString &file); 0096 FileHandle file() const; 0097 0098 virtual QString text(int column) const; 0099 virtual void setText(int column, const QString &text); 0100 0101 bool isPlaying() const; 0102 void setPlaying(bool playing = true, bool master = true); 0103 0104 void guessTagInfo(TagGuesser::Type type); 0105 0106 Playlist *playlist() const; 0107 0108 virtual CollectionListItem *collectionItem() { return m_collectionItem; } 0109 0110 /** 0111 * This is an identifier for the playlist item which will remain unique 0112 * throughout the process lifetime. It stays constant once the PlaylistItem 0113 * is created. 0114 */ 0115 quint32 trackId() const { return m_trackId; } 0116 0117 /** 0118 * The widths of items are cached when they're updated for us in computations 0119 * in the "weighted" listview column width mode. 0120 */ 0121 QVector<int> cachedWidths() const; 0122 0123 /** 0124 * This just refreshes from the in memory data. This may seem pointless at 0125 * first, but this data is shared between all of the list view items that are 0126 * based on the same file, so if another one of those items changes its data 0127 * it is important to refresh the others. 0128 */ 0129 virtual void refresh(); 0130 0131 /** 0132 * This rereads the tag from disk. This affects all PlaylistItems based on 0133 * the same file. 0134 */ 0135 virtual void refreshFromDisk(); 0136 0137 /** 0138 * Asks the item's playlist to remove the item (which uses deleteLater()). 0139 */ 0140 virtual void clear(); 0141 0142 /** 0143 * Returns properly casted item below this one. 0144 */ 0145 PlaylistItem *itemBelow() { return static_cast<PlaylistItem *>(treeWidget()->itemBelow(this)); } 0146 0147 /** 0148 * Returns properly casted item above this one. 0149 */ 0150 PlaylistItem *itemAbove() { return static_cast<PlaylistItem *>(treeWidget()->itemAbove(this)); } 0151 0152 /** 0153 * Returns a reference to the list of the currently playing items, with the 0154 * first being the "master" item (i.e. the item from which the next track is 0155 * chosen). 0156 */ 0157 static const PlaylistItemList &playingItems() { return m_playingItems; } 0158 0159 protected: 0160 /** 0161 * Items should always be created using Playlist::createItem() or through a 0162 * subclass or friend class. 0163 */ 0164 PlaylistItem(CollectionListItem *item, Playlist *parent); 0165 PlaylistItem(CollectionListItem *item, Playlist *parent, QTreeWidgetItem *after); 0166 0167 /** 0168 * See the class documentation for an explanation of construction and deletion 0169 * of PlaylistItems. 0170 */ 0171 virtual ~PlaylistItem(); 0172 0173 virtual int compare(const QTreeWidgetItem *item, int column, bool ascending) const; 0174 int compare(const PlaylistItem *firstItem, const PlaylistItem *secondItem, int column, bool ascending) const; 0175 0176 bool operator<(const QTreeWidgetItem &other) const override; 0177 0178 bool isValid() const; 0179 0180 void setTrackId(quint32 id); 0181 0182 /** 0183 * Shared data between all PlaylistItems from the same track (incl. the CollectionItem 0184 * representing said track. 0185 */ 0186 struct Data : public QSharedData 0187 { 0188 FileHandle fileHandle; // Set within CollectionList 0189 QVector<QString> metadata; ///< Artist, album, or genre tags. Other columns unfilled 0190 QVector<int> cachedWidths; 0191 }; 0192 0193 using DataPtr = QExplicitlySharedDataPointer<Data>; 0194 DataPtr sharedData() const { return d; } 0195 0196 private: 0197 DataPtr d; 0198 0199 /** 0200 * This is the constructor that should be used by CollectionList. 0201 */ 0202 PlaylistItem(CollectionList *parent); 0203 friend class CollectionList; 0204 0205 void setup(CollectionListItem *item); 0206 0207 CollectionListItem *m_collectionItem; 0208 quint32 m_trackId; 0209 bool m_watched; 0210 static PlaylistItemList m_playingItems; 0211 }; 0212 0213 inline QDebug operator<<(QDebug s, const PlaylistItem &item) 0214 { 0215 s << item.text(PlaylistItem::TrackColumn); 0216 return s; 0217 } 0218 0219 #endif 0220 0221 // vim: set et sw=4 tw=0 sta: