00001 /***************************************************************************** 00002 * Copyright (C) 2004 by Michael Schulze * 00003 * mike.s@genion.de * 00004 * * 00005 * The code contained in this file is free software; you can redistribute * 00006 * it and/or modify it under the terms of the GNU Lesser General Public * 00007 * License as published by the Free Software Foundation; either version * 00008 * 2.1 of the License, or (at your option) any later version. * 00009 * * 00010 * This file is distributed in the hope that it will be useful, * 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00013 * Lesser General Public License for more details. * 00014 * * 00015 * You should have received a copy of the GNU Lesser General Public * 00016 * License along with this code; if not, write to the Free Software * 00017 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 00018 * * 00019 * iTunes and iPod are trademarks of Apple * 00020 * * 00021 * This product is not supported/written/published by Apple! * 00022 *****************************************************************************/ 00023 #ifndef ITUNESDBPLAYLIST_H 00024 #define ITUNESDBPLAYLIST_H 00025 00026 #include "utils.h" 00027 #include "listitem.h" 00028 #include "playlistitem.h" 00029 #include "smartplaylistrules.h" 00030 00031 namespace itunesdb { 00032 00033 /** 00034 * This class represents a playlist in the database.<br> 00035 * It allows to read, create, manipulate and write back all kinds of playlists. It's part of 00036 * the itunesdb namespace which is intended to be used for plain reading/writing the database. 00037 * More enhanced features like sorting or updating smart playlists is implemented in the 00038 * @c ITunesDB related implementation @c ITunesDBPlaylist <br> 00039 * For normal playlists the @c addPlaylistItem( Q_UINT32, int ) method can be used to 00040 * add tracks to the playlist, @c removeAll( Q_UINT32 ) and @c removeTrackAt( uint ) 00041 * will remove them. 00042 * For editing the rules of smart playlists use the @c getSmartPlaylistRules() method to retrieve 00043 * the @c SmartPlaylistRuleSet and use its methods for manipulating the rules. 00044 * To create a new smart playlist create a new playlist and use @c enableSmartPlaylist() method to 00045 * enable smart playlist behaviour. This method also returns the still empty 00046 * @c SmartPlaylistRuleSet ready for adding new rules. 00047 * 00048 * @see ITunesDBPlaylist 00049 * @see SmartPlaylistRuleSet 00050 * @author Michael Schulze 00051 */ 00052 class Playlist : public ListItem 00053 { 00054 friend class ItunesDBParser; 00055 friend class ItunesDBWriter; 00056 00057 public: 00058 enum Sortorder { 00059 SORTORDER_MANUAL = 1, 00060 SORTORDER_RANDOM = 2, 00061 SORTORDER_TITLE = 3, 00062 SORTORDER_ALBUM = 4, 00063 SORTORDER_ARTIST = 5, 00064 SORTORDER_BITRATE = 6, 00065 SORTORDER_GENRE = 7, 00066 SORTORDER_FILETYPE = 8, 00067 SORTORDER_TIME_MODIFIED = 9, 00068 SORTORDER_TRACK_NR = 10, 00069 SORTORDER_SIZE = 11, 00070 SORTORDER_TIME = 12, 00071 SORTORDER_YEAR = 13, 00072 SORTORDER_SAMPLERATE = 14, 00073 SORTORDER_COMMENT = 15, 00074 SORTORDER_TIME_ADDED = 16, // FIXME TIME_PLAYED??? 00075 SORTORDER_EQUALIZER = 17, 00076 SORTORDER_COMPOSER = 18, 00077 SORTORDER_PLAYCOUNT = 20, 00078 SORTORDER_TIME_PLAYED = 21, 00079 SORTORDER_CD_NR = 22, 00080 SORTORDER_RATING = 23, 00081 SORTORDER_RELEASE_DATE = 24, 00082 SORTORDER_BPM = 25, 00083 SORTORDER_GROUPING = 26, 00084 SORTORDER_CATEGORY = 27, 00085 SORTORDER_DESCRIPTION = 28, 00086 SORTORDER_SHOW = 29, 00087 SORTORDER_SEASON = 30, 00088 SORTORDER_EPISODE_NUMBER = 31 00089 } ItdbPlaylistSortOrder; 00090 00091 // FIXME containerversion should correlate with dirty flag 00092 typedef itunesdb::utils::SortablePtrVector<PlaylistItem> TrackList_T; 00093 typedef TrackList_T::ConstIterator ConstIterator; 00094 typedef TrackList_T::Iterator Iterator; 00095 00096 Playlist(); 00097 virtual ~Playlist(); 00098 00099 /** 00100 * Returns the title of the playlist 00101 * @return the title of the playlist 00102 */ 00103 const QString& getTitle() const; 00104 00105 /** 00106 * Sets the title of the playlist 00107 * @param newtitle the new title 00108 */ 00109 void setTitle( const QString& newtitle); 00110 00111 /** 00112 * Returns the sort order field of the playlist 00113 * @return the sort order field of the playlist 00114 */ 00115 Sortorder getSortOrder() const; 00116 00117 00118 /** 00119 * Returns true if the playlist contains the specified trackid. 00120 */ 00121 bool contains( Q_UINT32 trackID ) const; 00122 00123 /** 00124 * Adds a new PlaylistItem at the specified position to the list and sets 00125 * the dirty flag to true. The position field only works if the playlists 00126 * sort order is set to "manual" which is the only sort order implemented 00127 * by this class, but may be ignored if you use the @c ITunesDBPlaylist 00128 * implementation and set the sort order to something other than manual. 00129 * @param trackid the id of the track to add. Doesn't check if the track actually exists 00130 * @param position the position field as found in the itunesdb mhip playlist item, or -1 if the item should just be appended to the list 00131 * @return the index of the item in the list or -1 if the item could not be added or the item was NULL 00132 * @see @c ITunesDBPlaylist for a full implementation of itunesDBs playlists 00133 */ 00134 int addPlaylistItem( Q_UINT32 trackid, int position = -1 ); 00135 00136 /** 00137 * Removes the track at the position the given Iterator points to and returns the 00138 * former trackid at that position. If the Iterator doesn't point to an element in this 00139 * list PLAYLISTITEM_INVALID (as defined in playlistitem.h) is returned. 00140 * The iterators position will be invalidated so the next() method has to be called 00141 * before the next removal operation. 00142 */ 00143 Q_UINT32 removeTrackAt( Iterator& pos ); 00144 00145 /** 00146 * Removes the track at the given position and returns the 00147 * former trackid at that position. If the given position is out of range 00148 * PLAYLISTITEM_INVALID (as defined in playlistitem.h) is returned. 00149 */ 00150 Q_UINT32 removeTrackAt( uint pos ); 00151 00152 /** 00153 * Removes all occurences of the track with the given ID. Returns true if an element 00154 * with the given trackid existed and was removed, false otherwise. 00155 */ 00156 bool removeAll( Q_UINT32 trackid ); 00157 00158 /** 00159 * Returns the trackID at the given position or PLAYLISTITEM_INVALID 00160 * (as defined in playlistitem.h) if the given position is either negative 00161 * or above the last element in the list. 00162 */ 00163 virtual Q_UINT32 getTrackIDAt( uint pos ); 00164 00165 /** 00166 * Returns an iterator over all tracks in this playlist. The iterator 00167 * works like a java iterator - you can check if there are any elements 00168 * left with the @c Iterator::hasNext() method and get the next element with the 00169 * @c Iterator::next() method. 00170 * @return an iterator over the elements in the playlist 00171 */ 00172 virtual Iterator getElements(); 00173 00174 /** 00175 * @deprecated as the Iterator iterates over elements of type @c PlaylistItem the name is somewhat misleading. Use the new Method getElements() instead. 00176 */ 00177 Iterator getTrackIDs() __attribute__((deprecated)) { 00178 return getElements(); 00179 } 00180 00181 /** 00182 * The const version of the above method. 00183 * Returns an iterator over all tracks in this playlist. 00184 * @return an iterator over the playlists elements 00185 */ 00186 virtual ConstIterator getElements() const; 00187 00188 /** 00189 * @deprecated as the Iterator iterates over elements of type @c PlaylistItem the name is somewhat misleading. Use the new Method getElements() instead. 00190 */ 00191 ConstIterator getTrackIDs() const __attribute__((deprecated)) { 00192 return getElements(); 00193 } 00194 00195 /** 00196 * Returns the number of tracks in this playlist 00197 * @return the number of tracks in this playlist 00198 */ 00199 virtual uint getNumTracks() const; 00200 00201 /** 00202 * Returns the unique DB id for this playlist 00203 * @return the unique DB id for this playlist 00204 */ 00205 Q_UINT64 getID() const { return m_id; } 00206 00207 /** 00208 * Sets the unique DB id for this playlist 00209 * @param id the unique DB id for this playlist 00210 */ 00211 void setID( Q_UINT64 id ); 00212 00213 /** 00214 * Sorts the playlistItems by position. 00215 */ 00216 void sort(); 00217 00218 /** 00219 * Empties the playlist. 00220 * After a call to this method the @c getNumTracks() method returns 0. 00221 */ 00222 void clear(); 00223 00224 /** 00225 * Returns true if this playlist is the master playlist. 00226 */ 00227 inline bool isMasterPL() const { return m_isMaster; } 00228 00229 /* 00230 * FIXME check how to implement isHidden() 00231 */ 00232 00233 /** 00234 * Enables Smart Playlist Behaviour by creating a SmartPlaylistRuleSet. 00235 */ 00236 SmartPlaylistRuleSet& enableSmartPlaylist(); 00237 00238 /** 00239 * Returns true if this playlist is a smart playlist. 00240 */ 00241 bool isSmartPlaylist() const; 00242 00243 /** 00244 * Discards smart playlist data thus making it a normal playlist. 00245 * The items in this playlist will be kept. 00246 */ 00247 void discardSmartPlaylistData(); 00248 00249 /** 00250 * Returns the SmartPlaylistRuleSet making up this smart playlist, or NULL 00251 * IF this playlist isn't a SmartPlaylist. All smart playlist behaviour can 00252 * be / is controlled by the returned object. 00253 */ 00254 SmartPlaylistRuleSet * getSmartPlaylistRules() const; 00255 00256 /** 00257 * Returns true if this playlist is a podcast list 00258 */ 00259 bool isPodcastList() const { return mIsPodcast; } 00260 00261 /** 00262 * Adds all tracks delivered by the given Iterator. 00263 */ 00264 template <class JavaLikeTrackIterator> 00265 void addAll( JavaLikeTrackIterator trackIter ) { 00266 if ( trackIter.hasNext() ) { 00267 setDirty(); 00268 do { 00269 addPlaylistItem( trackIter.next()->getID() ); 00270 } while( trackIter.hasNext() ); 00271 } 00272 } 00273 00274 /** 00275 * Adds all tracks delivered by the given Iterator. 00276 */ 00277 template <class CPPStyleTrackIterator> 00278 void addAll( CPPStyleTrackIterator trackIter, CPPStyleTrackIterator end ) { 00279 bool changed = false; 00280 for ( ; trackIter != end; trackIter++ ) { 00281 addPlaylistItem( (*trackIter)->getID() ); 00282 changed = true; 00283 } 00284 if ( changed ) { 00285 setDirty(); 00286 } 00287 } 00288 00289 protected: 00290 00291 Playlist( const Playlist& ); 00292 00293 void updatePositions(); 00294 00295 /** 00296 * Creates a new PlaylistItem. Override this method if you need your own PlaylistItem implementation. 00297 */ 00298 virtual PlaylistItem * createNewItem( Q_UINT32 trackid ); 00299 00300 virtual QDataStream & readFromStream( QDataStream & instream, bool * ok = NULL ); 00301 00302 virtual QDataStream & writeToStream ( QDataStream & outstream, bool isMainlist ); 00303 00304 /** 00305 * override from ListItem::doneAddingData() 00306 */ 00307 virtual void doneAddingData(); 00308 00309 /** 00310 * Adds a new playlist item to the internal list. 00311 */ 00312 virtual int addPlaylistItem( PlaylistItem * item ); 00313 00314 virtual SmartPlaylistRuleSet * createNewSplRuleSet(); 00315 00316 void fillSplHeaderBuffer( QByteArray& buffer ) const; 00317 00318 void fillSplRulesBuffer( QByteArray& buffer ) const; 00319 00320 virtual void readNonStringMHOD( QDataStream& stream, Q_UINT32 type, Q_UINT32 blocklen ); 00321 virtual uint writeNonStringMHODs( QDataStream& outstream ) const; 00322 00323 void writeData( QByteArray& data, bool isMainlist) const; 00324 void writeTitle( QDataStream& stream ) const; 00325 void writeLongPlaylist( QDataStream& stream ) const; 00326 void writeTracks( QDataStream& stream ) const; 00327 00328 TrackList_T m_tracklist; 00329 Q_UINT8 m_isMaster; 00330 Q_UINT8 m_flag2; 00331 Q_UINT8 m_flag3; 00332 Q_UINT8 m_flag4; 00333 Q_UINT32 timeStamp; // some timestamp 00334 Q_UINT64 m_id; // playlist ID 00335 Q_UINT32 unk3; 00336 Q_UINT16 mIsPodcast; // podcast flag 00337 Sortorder m_order; 00338 00339 SmartPlaylistRuleSet * mSplRuleSet; 00340 00341 }; 00342 00343 } 00344 00345 #endif