track.h

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 ITUNESDBTRACK_H
00024 #define ITUNESDBTRACK_H
00025 
00026 #include <qdatetime.h>
00027 
00028 #include "utils.h"
00029 #include "listitem.h"
00030 
00031 namespace itunesdb {
00032 
00033 
00034 /**
00035  * @brief Represents a track in the database.
00036  *
00037  * This class mainly acts as a data access object for reading and writing track entries to/from the database file.
00038  * @author Michael Schulze
00039 */
00040 class Track : public ListItem {
00041 
00042     friend class ItunesDBParser;
00043     friend class ItunesDBWriter;
00044 
00045 public:
00046 
00047     enum MediaType {
00048         Audio_Video     = 0x00,
00049         Audio           = 0x01,
00050         Video           = 0x02,
00051         Podcast         = 0x04,
00052         Video_Podcast   = 0x06,
00053         Audiobook       = 0x08,
00054         Music_Video     = 0x20,
00055         TV_Show         = 0x40,
00056         TV_Show_w_Audio = 0x60
00057     };
00058 
00059     Track( Q_UINT32 trackID = 0 );
00060 
00061     virtual ~Track();
00062 
00063     /**
00064      * Returns the key for the track in the ITunesDB database
00065      * @return the key for the track in the ITunesDB database
00066      */
00067     Q_UINT32 getID() const;
00068 
00069     /**
00070      * Returns the album the track is released for
00071      * @return the albumname
00072      */
00073     const QString & getAlbum() const;
00074 
00075     /**
00076      * Returns the album the track is released for
00077      * @return the albumname for sorting
00078      */
00079     const QString & getAlbumForSort() const;
00080 
00081     /**
00082      * Returns the artist
00083      * @return the artists name
00084      */
00085     const QString & getArtist() const;
00086 
00087     /**
00088      * @deprecated use Track::getArtistNameForSort() instead
00089      * @see Track::getArtistNameForSort()
00090      */
00091     QString getPlainArtistName() const __attribute__((deprecated));
00092 
00093     /**
00094      * Returns the category
00095      * @return the category
00096      */
00097     const QString& getCategory() const;
00098 
00099     /**
00100      * Returns the comment set for the track
00101      * @return the comment
00102      */
00103     const QString & getComment() const;
00104 
00105     /**
00106      * Returns the name of the (TV) show
00107      */
00108     const QString & getTvShow() const;
00109 
00110     /**
00111      * Sets the name of the (TV) show
00112      */
00113     void setTvShow( const QString& show );
00114 
00115     /**
00116      * Returns the title of the track
00117      * @return the title
00118      */
00119     const QString & getTitle() const;
00120 
00121     /**
00122      * Returns the title of the track
00123      * @return the title of the track used for sorting
00124      */
00125     const QString & getTitleForSort() const;
00126 
00127     /**
00128      * Returns the genre of the track
00129      * @return the genre
00130      */
00131     const QString & getGenre() const;
00132 
00133     /**
00134      * Returns the pathname of the track as stored in the itunesdb.
00135      * Be aware that the path is relative to the ipod base directory
00136      * and the path separator is ":".
00137      * @return pathname of the track
00138      */
00139     const QString & getPathInfo() const;
00140 
00141     /**
00142      * Returns the composer
00143      * @return the composer
00144      */
00145     const QString & getComposer() const;
00146 
00147     /**
00148      * Retunrs the EQ Setting
00149      */
00150     const QString & getEqualizerSetting() const;
00151 
00152     /**
00153      * Returns some descriptional text for this piece of audio data.
00154      */
00155     const QString& getDescription() const;
00156 
00157     /**
00158      * Returns the grouping info for this song.
00159      */
00160     const QString& getGrouping() const;
00161 
00162     /**
00163      * Returns the name of the artist for the whole album. This may be different if it's a soundtrack for example.
00164      */
00165     const QString& getAlbumArtist() const;
00166 
00167     /**
00168      * In case the band/artist name starts with a "The" this returns the name with the The
00169      * at the end (like "Prodigy, The" for "The Prodigy"). Otherwise the normal artist name
00170      * is returned.
00171      */
00172     const QString& getAlbumArtistForSort() const;
00173 
00174     /**
00175      * In case the band/artist name starts with a "The" this returns the name with the The
00176      * at the end (like "Prodigy, The" for "The Prodigy"). Otherwise the normal artist name
00177      * is returned.
00178      */
00179     const QString& getArtistNameForSort() const;
00180 
00181     /**
00182      * Returns the list of keywords pertaining the track
00183      */
00184     const QString& getKeywords() const;
00185 
00186     const QString& getFileFormatDesc() const;
00187 
00188     /**
00189      * Returns the DBID which refers to additional media associated to this track (like cover art)
00190      * @return the DBID
00191      */
00192     Q_UINT64 getDBID() const;
00193 
00194     /**
00195      * Returns the rating for this track as read from the itunesdb.
00196      * @return the rating for this track as read from the itunesdb.
00197      */
00198     unsigned char getRating() const;
00199 
00200     /**
00201      * Returns the last modified date for this track.
00202      * @return the last modified date for this track.
00203      */
00204     Q_UINT32 getLastModified() const;
00205 
00206     /**
00207      * Returns the size of the file associated with this track
00208      * @return the filesize
00209      */
00210     Q_UINT32 getFileSize() const;
00211 
00212     /**
00213      * Returns the length of the track in milliseconds
00214      * @return the length of the track in milliseconds
00215      */
00216     Q_UINT32 getTrackLength() const;
00217 
00218     /**
00219      * Returns the number of the track
00220      * @return the number of the track
00221      */
00222     Q_UINT32 getTrackNumber() const;
00223 
00224     /**
00225      * Returns the number of tracks in the album
00226      * @return the number of tracks in the album
00227      */
00228     Q_UINT32 getTrackCount() const;
00229 
00230     /**
00231      * Returns the year the song was created
00232      * @return the year the song was created
00233      */
00234     Q_UINT32 getYear() const;
00235 
00236     /**
00237      * Returns the bitrate
00238      * @return the bitrate
00239      */
00240     Q_UINT32 getBitrate() const;
00241 
00242     /**
00243      * Returns the sample rate
00244      * @return the sample rate
00245      */
00246     Q_UINT32 getSamplerate() const;
00247 
00248     /**
00249      * Returns the volume adjust for the track
00250      * @return the volume adjust
00251      */
00252     Q_UINT32 getVolumeAdjust() const;
00253 
00254     /**
00255      * Returns the number of times the track was played so far
00256      * @return the play count
00257      */
00258     Q_UINT32 getPlayCount() const;
00259 
00260     /**
00261      * Returns the date the track was last played.
00262      */
00263     Q_UINT32 getLastPlayed() const;
00264 
00265     /**
00266      * Returns the cd number the track is on for albums with more than one CD.
00267      * @return the cd number the track is on for albums with more than one CD.
00268      */
00269     Q_UINT32 getCdNumber() const;
00270 
00271     /**
00272      * Returns the number of CDs for the album of the track.
00273      * @return the number of CDs for the album of the track.
00274      */
00275     Q_UINT32 getCdCount() const;
00276 
00277     /**
00278      * Returns the date the track was added to the database/device.
00279      * @return the date the track was added to the database/device.
00280      */
00281     Q_UINT32 getDateAdded() const { return date_added; }
00282 
00283     Q_UINT32 getStartTime() const { return mStartTime; }
00284     Q_UINT32 getStopTime() const { return mStopTime; }
00285     Q_UINT32 getSoundCheck() const { return mSoundCheck; }
00286 
00287     unsigned char getVbrFlag() const;
00288 
00289     Q_UINT32 getFileFormatCode() const { return file_format_code; }
00290     Q_UINT32 getReleaseDate() const { return date_released; }
00291     unsigned char getCompilationFlag() const { return compilation; }
00292 
00293     unsigned char isChecked() const { return checked; }
00294 
00295     bool isVideo() const;
00296 
00297     Q_UINT16 getBPM() const;
00298 
00299     virtual void setDBID( Q_UINT64 id );
00300 
00301     /**
00302      * Sets the album for this track.
00303      * @param album the album to set.
00304      */
00305     virtual void setAlbum( const QString& album );
00306 
00307     /**
00308      * Sets the album for this track.
00309      * @param album the album to set for sort.
00310      */
00311     virtual void setAlbumForSort( const QString& album );
00312 
00313     /**
00314      * Sets the artist for this track.
00315      * @param artist the artist name to set.
00316      */
00317     virtual void setArtist( const QString& artist );
00318 
00319     /**
00320      * Sets the artist for this track used for sorting.
00321      * @param artist the artist name to set for sort.
00322      */
00323     virtual void setArtistNameForSort( const QString& artist );
00324 
00325     /**
00326      * Sets the category for this track.
00327      * @param category the category to set.
00328      */
00329     virtual void setCategory( const QString& category );
00330 
00331     /**
00332      * Sets the path information for this track. The path is relative to the ipod's base directory.
00333      * The path separator is ":"
00334      * @param encodedpath the path information to set.
00335      */
00336     virtual void setPathInfo( const QString& encodedpath );
00337 
00338     /**
00339      * Sets the comment for this track.
00340      * @param comment the comment to set.
00341      */
00342     virtual void setComment( const QString& comment );
00343 
00344     virtual void setCompilationFlag( unsigned char isCompilation );
00345 
00346     /**
00347      * Sets the description for this track.
00348      * @param description_txt the description to set.
00349      */
00350     virtual void setDescription( const QString& description_txt );
00351 
00352     /**
00353      * Sets the grouping for this track.
00354      * @param grouping the grouping to set.
00355      */
00356     virtual void setGrouping( const QString& grouping );
00357 
00358     /**
00359      * Sets the genre for this track.
00360      * @param genre the genre to set.
00361      */
00362     virtual void setGenre( const QString& genre );
00363 
00364     /**
00365      * Sets the title for this track.
00366      * @param title the title to set.
00367      */
00368     virtual void setTitle( const QString& title );
00369 
00370     /**
00371      * Sets the title for this track used for sorting.
00372      * @param title the title to set.
00373      */
00374     virtual void setTitleForSort( const QString& title );
00375 
00376     /**
00377      * Sets the file format description for this track.
00378      * @param fdesc the file format description to set.
00379      */
00380     virtual void setFileFormatDesc( const QString& fdesc );
00381 
00382     /**
00383      * Sets the composer for this track.
00384      * @param composer the composer to set.
00385      */
00386     virtual void setComposer( const QString& composer );
00387 
00388     /**
00389      * Sets the equalizer setting for this track.
00390      * @param eqSetting the equalizer preset to set. See the itunesb wiki for details
00391      */
00392     virtual void setEqualizerSetting( const QString& eqSetting );
00393 
00394     /**
00395      * Sets the name of the artist for the whole album. This may be different if it's a soundtrack for example.
00396      * @param albumartist the name of the artist for the whole album
00397      */
00398     virtual void setAlbumArtist( const QString& albumartist );
00399 
00400     /**
00401      * Sets the name of the artist for the whole album. This may be different if it's a soundtrack for example.
00402      * @param albumartist the name of the artist for the whole album used for sorting
00403      */
00404     virtual void setAlbumArtistForSort( const QString& albumartist );
00405 
00406     /**
00407      * Sets the list of keywords pertaining the track
00408      * @param keywords a number of keywords
00409      */
00410     virtual void setKeywords( const QString& keywords );
00411 
00412     /**
00413      * Sets the track number for this track.
00414      * @param tracknumber the track number to set.
00415      */
00416     virtual void setTrackNumber( Q_UINT32 tracknumber );
00417 
00418     /**
00419      * Sets the the number of tracks in the album for this track.
00420      * @param numtracks the number of tracks to set.
00421      */
00422     virtual void setTrackCount( Q_UINT32 numtracks );
00423 
00424     /**
00425      * Sets the volume adjust for this track.
00426      * @param newVolumeAdjust the volume adjust to set.
00427      */
00428     virtual void setVolumeAdjust( Q_UINT32 newVolumeAdjust );
00429 
00430     /**
00431      * Sets the year of release for this track.
00432      * @param newYear the year to set.
00433      */
00434     virtual void setYear( Q_UINT32 newYear );
00435 
00436     /**
00437      * Sets the start time for this track.
00438      * @param startTime the start time to set.
00439      */
00440     virtual void setStartTime( Q_UINT32 startTime );
00441 
00442     /**
00443      * Sets the stop time for this track.
00444      * @param stopTime the stop time to set.
00445      */
00446     virtual void setStopTime( Q_UINT32 stopTime );
00447 
00448     /**
00449      * Sets the soundcheck for this track.
00450      * @param soundCheck the soundcheck to set.
00451      */
00452     virtual void setSoundCheck( Q_UINT32 soundCheck );
00453 
00454     /**
00455      * Sets the rating for this track.
00456      * @param rating the rating to set.
00457      */
00458     void setRating(unsigned char rating);
00459 
00460     /**
00461      * Sets the date the track was last played.
00462      * @param lastplayed the last played date to set.
00463      */
00464     void setLastPlayed(Q_UINT32 lastplayed);
00465 
00466     /**
00467      * Sets the playcount for this track.
00468      * @param newPlaycount the playcount to set.
00469      */
00470     void setPlayCount(Q_UINT32 newPlaycount);
00471 
00472     /**
00473      * Sets the beats per minute info for this track.
00474      * @param bpm the beats per minute information to set.
00475      */
00476     void setBPM( Q_UINT32 bpm ) { beatsPerMinute = bpm; }
00477 
00478     /**
00479      * Returns the file extension for this track.
00480      * @return the file extension for this track.
00481      */
00482     QString getFileExtension() const;
00483 
00484     /**
00485      * Sets the file extension for this track.
00486      * @param fileextension the file extension to set.
00487      */
00488     virtual void setFileExtension( const QString& fileextension );
00489 
00490     /**
00491      * Sets the number of skips for this track
00492      */
00493     void setSkipCount( Q_UINT32 numberOfSkips );
00494 
00495     /**
00496      * Returns the number of times this track was skipped
00497      * @return the number of times this track was skipped
00498      */
00499     Q_UINT32 getSkipCount() const;
00500 
00501     /**
00502      * Sets the time the track was skipped
00503      */
00504     void setLastSkippedTime( Q_UINT32 lastSkippedDateTime );
00505 
00506     /**
00507      * Returns the time the track was skipped
00508      * @return the time the track was skipped
00509      */
00510     Q_UINT32 getLastSkippedTime() const;
00511 
00512     void skipWhenShuffle( bool enable );
00513 
00514     bool skippedWhenShuffle() const;
00515 
00516     void setHasLyrics( bool hasLyrics );
00517 
00518     bool hasLyrics() const;
00519 
00520     void setMediaType( Track::MediaType type );
00521 
00522     Track::MediaType getMediaType() const;
00523 
00524     /**
00525      * Sets the nessessary information for gapless playback. Set all the parameters to zero
00526      * if gapless playback should be disabled for this song.
00527      * @param pregapSamples Number of samples of silence before the songs starts
00528      * @param songSamples Number of samples in the song
00529      * @param postgapSamples Number of samples of silence at the end of the song
00530      * @param gaplessData The size in bytes from first Synch Frame (which is usually the XING frame that includes the LAME tag) until the 8th before the last frame. The gapless playback does not work for MP3 files if this is set to zero. Maybe the iPod prepares the next track when rest 8 frames in the actual track. For AAC tracks, this may be zero.
00531      */
00532     void setGaplessPBackData( Q_UINT32 pregapSamples, Q_UINT64 songSamples, Q_UINT32 postgapSamples, Q_UINT32 gaplessData );
00533 
00534     Q_UINT32 getNumPregapSamples() const;
00535 
00536     Q_UINT64 getNumSongSamples() const;
00537 
00538     Q_UINT32 getNumPostgapSamples() const;
00539 
00540     /**
00541      * Returns the size in bytes from first Synch Frame (which is usually the XING frame that includes the LAME tag) until the 8th before the last frame.
00542      */
00543     Q_UINT32 getGaplessDataSize() const;
00544 
00545     void setSeasonNumber( Q_UINT32 season );
00546 
00547     Q_UINT32 getSeasonNumber() const;
00548 
00549     void setEpisodeNumber( Q_UINT32 episode );
00550 
00551     Q_UINT32 getEpisodeNumber() const;
00552 
00553     /**
00554      * Copies the metadata from the given source to this Track.
00555      * The Track class itself is a possible TrackMetaSource, so you
00556      * can copy metadata from a track to another.
00557      */
00558     template <class TrackMetaSource>
00559     void readFrom( TrackMetaSource& provider ) {
00560         // Album specific stuff
00561         setAlbum( provider.getAlbum() );
00562         setAlbumForSort( provider.getAlbumForSort() );
00563         setArtist( provider.getArtist() );
00564         setArtistNameForSort( provider.getArtistNameForSort() );
00565         setBPM( provider.getBPM() );
00566         setCategory( provider.getCategory() );
00567         setComment( provider.getComment() );
00568         setCompilationFlag( provider.getCompilationFlag() );
00569         setComposer( provider.getComposer() );
00570         setDescription( provider.getDescription() );
00571         setGrouping( provider.getGrouping() );
00572         setEqualizerSetting( provider.getEqualizerSetting() );
00573         setAlbumArtist( provider.getAlbumArtist() );
00574         setAlbumArtistForSort( provider.getAlbumArtistForSort() );
00575         setKeywords( provider.getKeywords() );
00576         setFileFormatDesc(  provider.getFileFormatDesc() );
00577         setGenre( provider.getGenre() );
00578         setTitle( provider.getTitle() );
00579         setTitleForSort( provider.getTitleForSort() );
00580         setTrackCount( provider.getTrackCount() );
00581         setTrackNumber( provider.getTrackNumber() );
00582         setVolumeAdjust( provider.getVolumeAdjust() );
00583         setYear( provider.getYear() );
00584         setTvShow( provider.getTvShow() );
00585         setSeasonNumber( provider.getSeasonNumber() );
00586         setEpisodeNumber( provider.getEpisodeNumber() );
00587 
00588         // Track related technical stuff
00589         setLastPlayed( provider.getLastPlayed() );
00590         setPlayCount( provider.getPlayCount() );
00591         setLastSkippedTime( provider.getLastSkippedTime() );
00592         setSkipCount( provider.getSkipCount() );
00593         setRating( provider.getRating() );
00594         numcds = provider.getCdCount();
00595         cdnum = provider.getCdNumber();
00596         file_format_code = provider.getFileFormatCode();
00597         type = provider.getMediaType();
00598         tracklen = provider.getTrackLength();
00599         vbr = provider.getVbrFlag();
00600         bitrate = provider.getBitrate();
00601         samplerate = provider.getSamplerate();
00602         setStartTime( provider.getStartTime() );
00603         setStopTime( provider.getStopTime() );
00604         setSoundCheck( provider.getSoundCheck() );
00605         setHasLyrics( provider.hasLyrics() );
00606         setMediaType( provider.getMediaType() );
00607         setGaplessPBackData( provider.getNumPregapSamples(), provider.getNumSongSamples(), provider.getNumPostgapSamples(), provider.getGaplessDataSize() );
00608         // Resource related technical stuff
00609         file_size = provider.getFileSize();
00610         lastmodified = provider.getLastModified();
00611 
00612         doneAddingData();
00613     }
00614 
00615     void setRecentlyPlayed( bool playedRecently = true ) { m_recentlyPlayed = playedRecently; }
00616     bool recentlyPlayed() const { return m_recentlyPlayed; }
00617 
00618     QString toQString() const {
00619         return getArtist() + " - " + getAlbum() + " - " + QString::number( getTrackNumber() ) + QString( "-" ) + getTitle();
00620     }
00621 
00622 protected:
00623 
00624     /**
00625      * Writes track information (mhit) to the given stream.
00626      * @param outstream the stream to write the mhit to
00627      * @return the given stream
00628      */
00629     virtual QDataStream & writeToStream( QDataStream & outstream );
00630 
00631     /**
00632      * Reads track information (mhit) from the given stream.
00633      * @param instream the stream to read the mhit from
00634      * @param ok a pointer to a bool to be set to true if the read succeeds
00635      * @return the given stream
00636      */
00637     virtual QDataStream & readFromStream( QDataStream & instream, bool * ok = NULL );
00638 
00639     void writeData( QByteArray& data ) const;
00640 
00641     /**
00642      * override from ListItem::doneAddingData()
00643      */
00644     virtual void doneAddingData();
00645 
00646     Q_UINT32 id;
00647 
00648     // attributes
00649     Q_UINT32 lastmodified;    // last modified date
00650     Q_UINT32 file_size;
00651     Q_UINT32 tracklen;
00652     Q_UINT32 tracknum;
00653     Q_UINT32 numtracks;
00654     Q_UINT32 year;
00655     Q_UINT32 bitrate;
00656     Q_UINT32 samplerate;
00657     Q_UINT32 volumeadjust;
00658     Q_UINT32 playcount;
00659     Q_UINT32 last_played_at;
00660     Q_UINT32 cdnum;
00661     Q_UINT32 numcds;
00662     Q_UINT32 file_format_code;
00663     Q_UINT32 date_added;
00664     Q_UINT32 date_released;
00665 
00666     Q_UINT32 mStartTime;
00667     Q_UINT32 mStopTime;
00668     Q_UINT32 mSoundCheck;
00669 
00670     unsigned char rating;       // rating 0 lowest 100 highest
00671     unsigned char vbr;          // vbr=1, cbr=0
00672     unsigned char type;         // mp3=1, aac+audible=0
00673     unsigned char compilation;  // iscompiltaion=1, 0 otherwise
00674 
00675     Q_UINT64 dbid;
00676     Q_UINT8  checked;
00677     Q_UINT8  app_rating;
00678     Q_UINT16 beatsPerMinute;
00679     Q_UINT16 mArtworkCount;
00680     Q_UINT16 unk9;
00681     Q_UINT32 mArtworkSize;
00682     Q_UINT32 unk11;
00683     Q_UINT32 mAppleDRM;
00684     Q_UINT32 mSkipCount;
00685     Q_UINT32 mLastSkippedDate;
00686     Q_UINT8  mHasArtwork;
00687     Q_UINT8  mSkipWhenShuffe;
00688     Q_UINT8  mRememberPbackPos;
00689     Q_UINT8  flag4;
00690     Q_UINT8  mHasLyricsFlag;
00691     Q_UINT8  mIsMovie;
00692     Q_UINT8  mPodcastPlayedFlag;
00693     Q_UINT8  unk37_2;
00694     Q_UINT32 unk21;
00695     Q_UINT32 mPregapSamples;
00696     Q_UINT64 mNumSamples;
00697     Q_UINT32 unk25;
00698     Q_UINT32 mPostgapSamples;
00699     Q_UINT32 unk27;
00700     Q_UINT32 mMediaType;
00701     Q_UINT32 mSeasonNumber;
00702     Q_UINT32 mEpisodeNumber;
00703     Q_UINT32 unk31; // seems to be always 0 for unprotected files
00704     Q_UINT32 unk32;
00705     Q_UINT32 unk33;
00706     Q_UINT32 unk34;
00707     Q_UINT32 unk35;
00708     Q_UINT32 unk36;
00709     Q_UINT32 unk37;
00710     Q_UINT32 mGaplessData;
00711     Q_UINT32 unk38;
00712     Q_UINT16 mGapLessFlag;
00713     Q_UINT16 mGaplessAlbum; // no crossfading in iTunes
00714 
00715     // TODO implement podcast flag (together with the whole rest)
00716 
00717 private:
00718 
00719     bool m_recentlyPlayed;
00720 
00721 };
00722 
00723 /**
00724  * This interface defines a comparator comparing 2 Tracks and returning a negative int, zero, or
00725  * a positive int if the first track is smaller, equal or greater than the second.
00726  *
00727  * Example: you need to sort a TrackPtrList by Year
00728  *
00729  * First create an implementor for TrackComparator like this:
00730  * <pre><code>
00731  * class TracksByYearComparator : public TrackComparator {
00732  * public:
00733  *     virtual int compare( const itunesdb::Track& track1, const itunesdb::Track& track2 ) {
00734  *         return track1.getYear() - track2.getYear();
00735  *     }
00736  * };
00737  * </code></pre>
00738  * then you call the @c TrackPtrList::setComparator() method of your @c TrackPtrList instance and
00739  * sort() it.
00740  * @see itunesdb::TrackComparators for a list of predefined comparators and further examples
00741  */
00742 typedef itunesdb::utils::Comparator<itunesdb::Track> TrackComparator;
00743 typedef QTPOD_SHARED_PTR_IMPL_DEF<TrackComparator> TrackComparatorPtr;
00744 typedef QTPOD_SHARED_PTR_IMPL_DEF<const TrackComparator> ConstTrackComparatorPtr;
00745 
00746 /**
00747  * This class provides a set of predefined TrackComparator implementations
00748  */
00749 class TrackComparators {
00750     class KeepOrder;
00751     class ByTitle;
00752     class ByArtist;
00753     class ByAlbum;
00754     class ByGenre;
00755     class ByCategory;
00756     class ByComment;
00757     class ByComposer;
00758     class ByEqualizerSetting;
00759     class ByDescriptionTxt;
00760     class ByGrouping;
00761     class ByBitrate;
00762     class ByFiletype;
00763     class ByTimeModified;
00764     class ByTrackNumber;
00765     class BySize;
00766     class ByTrackLength;
00767     class ByYear;
00768     class BySampleRate;
00769     class ByDateAdded;
00770     class ByPlaycount;
00771     class ByLastPlayed;
00772     class ByRating;
00773     class ByCdNumber;
00774     class ByReleaseDate;
00775     class ByBPM;
00776     class BySkipCountOnly;
00777     class ByLastSkipped;
00778     class ByTvShow;
00779     class BySeason;
00780     class ByEpisodeNumber;
00781 
00782 public:
00783 
00784     /**
00785      * Comparator to keep the order when calling sort()
00786      */
00787     static TrackComparatorPtr KEEP_ORDER;
00788 
00789     /**
00790      * Comparator to sort a list of tracks by title
00791      */
00792     static TrackComparatorPtr BY_TITLE;
00793 
00794     /**
00795      * Comparator to sort a list of tracks by the artist property
00796      */
00797     static TrackComparatorPtr BY_ARTISTONLY;
00798 
00799     /**
00800      * Comparator to sort a list of tracks by the album property
00801      */
00802     static TrackComparatorPtr BY_ALBUMONLY;
00803 
00804     /**
00805      * Comparator to sort a list of tracks by TV show, season, spisode and title
00806      */
00807     static TrackComparatorPtr BY_TVSHOWONLY;
00808 
00809     /**
00810      * Comparator to sort a list of tracks by season, episode and title
00811      */
00812     static TrackComparatorPtr BY_SEASONONLY;
00813 
00814     /**
00815      * Comparator to sort a list of tracks by episode number and title
00816      */
00817     static TrackComparatorPtr BY_EPISODEONLY;
00818 
00819     /**
00820      * Comparator to sort a list of tracks by the genre property
00821      */
00822     static TrackComparatorPtr BY_GENREONLY;
00823 
00824     /**
00825      * Comparator to sort a list of tracks by category
00826      */
00827     static TrackComparatorPtr BY_CATEGORY;
00828 
00829     /**
00830      * Comparator to sort a list of tracks by the comment property
00831      */
00832     static TrackComparatorPtr BY_COMMENT;
00833 
00834     /**
00835      * Comparator to sort a list of tracks by the composer property
00836      */
00837     static TrackComparatorPtr BY_COMPOSERONLY;
00838 
00839     /**
00840      * Comparator to sort a list of tracks by the eq setting property
00841      */
00842     static TrackComparatorPtr BY_EQSETTING;
00843 
00844     /**
00845      * Comparator to sort a list of tracks by the description property
00846      */
00847     static TrackComparatorPtr BY_DESCRIPTIONTXT;
00848 
00849     /**
00850      * Comparator to sort a list of tracks by the grouping property
00851      */
00852     static TrackComparatorPtr BY_GROUPING;
00853 
00854     /**
00855      * Comparator to sort a list of tracks by bitrate
00856      */
00857     static TrackComparatorPtr BY_BITRATE;
00858 
00859     /**
00860      * Comparator to sort a list of tracks by filetype
00861      */
00862     static TrackComparatorPtr BY_FILETYPE;
00863 
00864     /**
00865      * Comparator to sort a list of tracks by modification time
00866      */
00867     static TrackComparatorPtr BY_TIMEMODIFIED;
00868 
00869     /**
00870      * Comparator to sort a list of tracks by track number
00871      */
00872     static TrackComparatorPtr BY_TRACKNUMBER;
00873 
00874     /**
00875      * Comparator to sort a list of tracks by size
00876      */
00877     static TrackComparatorPtr BY_SIZE;
00878 
00879     /**
00880      * Comparator to sort a list of tracks by the tracks length (timewise)
00881      */
00882     static TrackComparatorPtr BY_TRACKLENGTH;
00883 
00884     /**
00885      * Comparator to sort a list of tracks by the year property
00886      */
00887     static TrackComparatorPtr BY_YEAR;
00888 
00889     /**
00890      * Comparator to sort a list of tracks by the sample rate
00891      */
00892     static TrackComparatorPtr BY_SAMPLERATE;
00893 
00894     /**
00895      * Comparator to sort a list of tracks by the date the tracks were added to the database
00896      * (oldest first).
00897      */
00898     static TrackComparatorPtr BY_DATEADDED;
00899 
00900     /**
00901      * Comparator to sort a list of tracks by the date the tracks were added to the database
00902      * (most recently first).
00903      */
00904     static TrackComparatorPtr BY_RECENTLYADDED;
00905 
00906     /**
00907      * Comparator to sort a list of tracks by the play count property
00908      */
00909     static TrackComparatorPtr BY_PLAYCOUNTONLY;
00910 
00911     /**
00912      * Comparator to sort a list of tracks by the last played property (most recently last).
00913      */
00914     static TrackComparatorPtr BY_LASTPLAYED;
00915 
00916     /**
00917      * Comparator to sort a list of tracks by the last played property (most recently first).
00918      */
00919     static TrackComparatorPtr BY_LASTPLAYED_REVERSE;
00920 
00921     /**
00922      * Comparator to sort a list of tracks by the rating property.
00923      */
00924     static TrackComparatorPtr BY_RATING;
00925 
00926     /**
00927      * Comparator to sort a list of tracks by the cd number property.
00928      */
00929     static TrackComparatorPtr BY_CDNUMBER;
00930 
00931     /**
00932      * Comparator to sort a list of tracks by release date.
00933      */
00934     static TrackComparatorPtr BY_RELEASEDATE;
00935 
00936     /**
00937      * Comparator to sort a list of tracks by beats per minute.
00938      */
00939     static TrackComparatorPtr BY_BPM;
00940 
00941     /**
00942      * Comparator to sort a list of tracks by the skip count property
00943      */
00944     static TrackComparatorPtr BY_SKIPCOUNTONLY;
00945 
00946     /**
00947      * Comparator to sort a list of tracks by the last played property (most recently last).
00948      */
00949     static TrackComparatorPtr BY_LASTSKIPPED;
00950 
00951     /**
00952      * Comparator to sort a list of tracks by the last played property (most recently first).
00953      */
00954     static TrackComparatorPtr BY_LASTSKIPPED_REVERSE;
00955 
00956     /**
00957      * Comparator to sort a list of tracks by album, tracknumber and title
00958      */
00959     static TrackComparatorPtr BY_ALBUM;
00960 
00961     /**
00962      * Comparator to sort a list of tracks by artist, album, tracknumber and title
00963      */
00964     static TrackComparatorPtr BY_ARTIST;
00965 
00966     /**
00967      * Comparator to sort a list of tracks by genre and all the properties BY_ARTIST uses.
00968      */
00969     static TrackComparatorPtr BY_GENRE;
00970 
00971     /**
00972      * Comparator to sort a list of tracks by composer and title
00973      */
00974     static TrackComparatorPtr BY_COMPOSER;
00975 
00976     /**
00977      * Comparator to sort a list of tracks by playcount and all the properties BY_ARTIST uses.
00978      */
00979     static TrackComparatorPtr BY_PLAYCOUNT;
00980 
00981     /**
00982      * Comparator to sort a list of tracks by skip count and all the properties BY_ARTIST uses.
00983      */
00984     static TrackComparatorPtr BY_SKIPCOUNT;
00985 
00986     /**
00987      * Comparator to sort a list of tracks by TV show, season, spisode and title
00988      */
00989     static TrackComparatorPtr BY_TVSHOW;
00990 
00991     /**
00992      * Comparator to sort a list of tracks by season, episode and title
00993      */
00994     static TrackComparatorPtr BY_SEASON;
00995 
00996     /**
00997      * Comparator to sort a list of tracks by episode number and title
00998      */
00999     static TrackComparatorPtr BY_EPISODE;
01000 
01001     /**
01002      * Reverses the sort order of the given comparator.
01003      */
01004     class ReverseComparator : public TrackComparator {
01005         TrackComparatorPtr m_delegate;
01006     public:
01007         /**
01008          * Constructs a comparator reversing the sort order of the given comparator.
01009          */
01010         ReverseComparator( const TrackComparatorPtr& comparator ) : m_delegate( comparator ) {}
01011         virtual ~ReverseComparator() {}
01012         /**
01013          * Compares the two given tracks in reverse to the delegating comparator
01014          * @param track1 the first track to be compared to the second
01015          * @param track2 the second track to be compared
01016          * @return the reverse of the result of the delegate
01017          */
01018         virtual int compare( const itunesdb::Track& track1, const itunesdb::Track& track2 ) const {
01019             return m_delegate->compare( track2, track1 );
01020         }
01021     };
01022 
01023 
01024     /**
01025      * @brief Composition of many comparators.
01026      * 
01027      * The first Comparator added is the one with the highest priority.
01028      */
01029     class ComposingComparator : public TrackComparator {
01030         typedef std::vector<TrackComparatorPtr> ComparatorPtrVector;
01031         ComparatorPtrVector m_comparators;
01032     public:
01033 
01034         /**
01035          * @brief Creates a new empty comparator composition
01036          */
01037         ComposingComparator() {}
01038 
01039         /**
01040          * @brief Constructs a composing comparator with the given comparator added to the top.
01041          * 
01042          * The comparator given is owned by this instance so the lifecycle is managed by it.
01043          */
01044         ComposingComparator( TrackComparator * first ) {
01045             if ( first ) {
01046                 m_comparators.push_back( TrackComparatorPtr( first ) );
01047             }
01048         }
01049 
01050         /**
01051          * @brief Constructs a composing comparator with the given comparator added to the top.
01052          */
01053         ComposingComparator( TrackComparatorPtr first ) {
01054             if ( first ) {
01055                 m_comparators.push_back( first );
01056             }
01057         }
01058         virtual ~ComposingComparator() {}
01059 
01060         /**
01061          * @brief Appends the given comparator.
01062          * @param next the TrackComparator to add
01063          * @return a pointer to this ComposingComparator
01064          */
01065         ComposingComparator * add( TrackComparatorPtr next ) {
01066             if ( next ) {
01067                 m_comparators.push_back( next );
01068             }
01069             return this;
01070         }
01071 
01072         /**
01073          * @brief Appends the given comparator.
01074          * 
01075          * The comparator given is owned by this instance so the lifecycle is managed by it.
01076          * @param next the TrackComparator to add
01077          * @return a pointer to this ComposingComparator
01078          */
01079         ComposingComparator * add( TrackComparator * next ) {
01080             if ( next ) {
01081                 m_comparators.push_back( TrackComparatorPtr( next ) );
01082             }
01083             return this;
01084         }
01085 
01086         /**
01087          * @brief Returns the result of the first comparator returning a value != 0
01088          * @param track1 the first track to compare
01089          * @param track2 the second track to compare
01090          * @return the result of the first comparator returning a value != 0
01091          */
01092         virtual int compare( const itunesdb::Track& track1, const itunesdb::Track& track2 ) const;
01093     };
01094 
01095     /**
01096      * @brief Creates a shared ptr to the given comparator.
01097      */
01098     static TrackComparatorPtr createPtr( TrackComparator * comparator );
01099 };  // TrackComparators
01100 
01101 
01102 /**
01103  * This interface will be used by ITunesDB::findFirstTrackBy and ITunesDB::getTracksBy.
01104  * Callers to these functions provide a reference to an implementation of this interface
01105  * and thus provide code to decide if a given track is a valid result.
01106  *
01107  * Example: you need to get all the tracks performed at a given year (e.g. 2004) from the database
01108  *
01109  * First create an implementor for TrackPredicate like this:
01110  * <pre><code>
01111  * class TracksByYearPredicate : public TrackPredicate {
01112  *     Q_UINT32 m_givenYear;
01113  * public:
01114  *     TracksByYearPredicate( Q_UINT32 givenYear ) : m_givenYear( givenYear ) {}
01115  *     ~TracksByYearPredicate() {}
01116  *     bool operator() ( const itunesdb::Track& track ) {
01117  *         return track.getYear() == m_givenYear;
01118  *     }
01119  * };
01120  * </code></pre>
01121  * then you call the ITunesDB::getTracksBy() method of your ITunesDB instance (here itunesdb) with a reference to your predicate
01122  * <pre><code>
01123  * TracksByYearPredicate yearPredicate( 2004 );
01124  * TrackPtrList result;
01125  * itunesdb.getTracksBy( yearPredicate, result );
01126  * </code></pre>
01127  * Now you have all tracks performed at 2004 in your result list.
01128  * Alternatively you can call the getTracksBy() method returning a RangeIterator and add the tracks to your own container.
01129  * <pre><code>
01130     ITunesDB::FilteredTrackConstIterator<TracksByYearPredicate> iter = itunesdb.getTracksBy( yearPredicate );
01131     std::vector<itunesdb::Track*> vector;
01132     while( iter.hasNext() ) {
01133         vector.push_back( iter.next() );
01134     }
01135  * </code></pre>
01136  * @see ITunesDB::findFirstTrackBy()
01137  * @see ITunesDB::getTracksBy()
01138  * }
01139  */
01140 class TrackPredicate {
01141 public:
01142     virtual ~TrackPredicate() {}
01143 
01144     /**
01145      * Implement this method accordingly to the documentation above and (!) the documentation
01146      * of the function this predicate will be given to.
01147      */
01148     virtual bool operator () ( const Track * ) const = 0;
01149 };
01150 
01151 
01152 typedef QTPOD_SHARED_PTR_IMPL_DEF<TrackPredicate> TrackPredicatePtr;
01153 typedef QTPOD_SHARED_PTR_IMPL_DEF<const TrackPredicate> ConstTrackPredicatePtr;
01154 
01155 
01156 /**
01157  * This class provides a few TrackPredicate implementations.
01158  */
01159 class TrackPredicates {
01160 public:
01161 
01162     /**
01163      * A predicate to find tracks by a given artist. This predicate will return true for
01164      * every track that fits to the artist given at construction time.
01165      * @see ByArtist::ByArtist( const QString& )
01166      */
01167     class ByArtist : public TrackPredicate {
01168     public:
01169         /**
01170          * Constructor to create a new predicate for the given artist.
01171          */
01172         ByArtist( const QString& artist ) : _artist_( artist ) {}
01173         virtual ~ByArtist() {}
01174 
01175         /**
01176          * Returns true if the given track matches the parameters given to the constructor.
01177          */
01178         bool operator () ( const Track * track ) const {
01179             return  track && _artist_.compare( track->getArtist() ) == 0;
01180         }
01181     private:
01182         const QString _artist_;
01183     };  // ByArtist
01184 
01185 
01186     /**
01187      * A predicate to find tracks by a given album. This predicate will return true for
01188      * every track that fits to the artist/album combination given at construction time.
01189      * @see ByAlbum::ByAlbum( const QString&, const QString& )
01190      */
01191     class ByAlbum : public TrackPredicate {
01192     public:
01193         /**
01194          * Constructor to create a new predicate for the given artist/album combination.
01195          */
01196         ByAlbum(const QString& artist, const QString & album)
01197             : _artist_( artist ), _album_( album ) {}
01198         virtual ~ByAlbum() {}
01199 
01200         /**
01201          * Returns true if the given track matches the parameters given to the constructor.
01202          */
01203         bool operator () ( const Track * track ) const {
01204             bool result = track;
01205             if ( result && !_artist_.isEmpty() ) {
01206                 result = _artist_.compare( track->getArtist() ) == 0;
01207             }
01208             return  result && _album_.compare( track->getAlbum() ) == 0;
01209         }
01210     private:
01211         const QString _artist_;
01212         const QString _album_;
01213     };
01214 
01215 
01216     /**
01217      * A predicate to find the track by a given artist/album/title. This predicate will return
01218      * true for every track that fits to the artist/album/title combination given at construction
01219      * time.
01220      * @see ByFullInfo::ByFullInfo( const QString&, const QString&, const QString&, Q_UINT32 )
01221      */
01222     class ByFullInfo : public TrackPredicate {
01223     public:
01224         /**
01225          * Constructor to create a new predicate for the given artist/album/title combination.
01226          */
01227         ByFullInfo( const QString& artist, const QString& album, const QString& title, Q_UINT32 trackNum = 0 )
01228             : m_artist( artist ), m_album( album ), m_title( title ), m_trackNum( trackNum ) {}
01229         virtual ~ByFullInfo() {}
01230 
01231         bool operator () ( const Track * track ) const {
01232             return  track &&
01233                     m_artist.compare( track->getArtist() ) == 0 &&
01234                     m_album.compare( track->getAlbum() ) == 0 &&
01235                     m_title.compare( track->getTitle() ) == 0 &&
01236                     ( m_trackNum == 0 || m_trackNum == track->getTrackNumber() );
01237         }
01238     private:
01239         const QString& m_artist;
01240         const QString& m_album;
01241         const QString& m_title;
01242         Q_UINT32 m_trackNum;
01243     };  // ByFullInfo
01244 
01245 
01246     /**
01247      * A predicate to find a track for the given filename. This predicate will return
01248      * true for every track that fits to the file name given at construction time.
01249      */
01250     class ByPathInfo : public TrackPredicate {
01251     public:
01252 
01253         /**
01254          * Constructor to create a new predicate for the given file path.
01255          */
01256         ByPathInfo( const QString& pathInfo )
01257             : mPathInfo( pathInfo ) {}
01258 
01259         virtual ~ByPathInfo() {}
01260 
01261         /**
01262          * Returns true if the given track matches the parameters given to the constructor.
01263          */
01264         bool operator () ( const Track * track ) const {
01265             if ( !track ) return false;
01266             const QString & trackPathInfo = track->getPathInfo();
01267             return mPathInfo.startsWith( trackPathInfo, false ) &&
01268                    mPathInfo.length() == trackPathInfo.length();
01269         }
01270 
01271     private:
01272         const QString mPathInfo;
01273     };
01274 
01275 
01276     /**
01277      * Predicate to find tracks by a given free text search. This predicate will return true
01278      * for every track that somehow contains the string given at construction time.
01279      * @see Contains::Contains( const QString&, bool )
01280      */
01281     class Contains : public TrackPredicate {
01282     public:
01283         /**
01284          * Constructor to create a new predicate for the given free text string.
01285          */
01286         Contains( const QString& someString, bool caseSensitive )
01287             : m_someString( someString ), m_caseSensitive( caseSensitive ) {}
01288         virtual ~Contains() {}
01289 
01290         /**
01291          * Returns true if the given track somehow contains the string given at construction time.
01292          */
01293         bool operator () ( const Track * track ) const {
01294             if ( !track ) return false;
01295             QString sBuffer( track->getArtist() + track->getAlbum() + track->getTitle() + track->getComposer() );
01296             return sBuffer.contains( m_someString, m_caseSensitive );
01297         }
01298     private:
01299         const QString m_someString;
01300         bool m_caseSensitive;
01301     };  // Contains
01302 
01303 
01304     static class AllTracks : public TrackPredicate {
01305     public:
01306         bool operator() ( const Track * track ) const {
01307             return track;
01308         }
01309     } ALLTRACKS;
01310 
01311 
01312     struct PredicatePtrDelegator {
01313         const itunesdb::TrackPredicate * m_predicate;
01314         PredicatePtrDelegator( const itunesdb::TrackPredicate * predicate = NULL )
01315             : m_predicate( predicate ) {}
01316         bool operator()( const Track * track ) const {
01317             return track && ( !m_predicate || (*m_predicate)( track ) );
01318         }
01319     };
01320 
01321 };  // TrackPredicates
01322 
01323 
01324 /**
01325  * @brief A SortablePtrVector implementation for Track pointers.
01326  * 
01327  * The default sort order is set to Artist - Album - tracknumber
01328  * @see itunesdb::utils::SortablePtrVector for details about the base class
01329  * @see itunesdb::TrackComparators for a collection of predefined comparators
01330  */
01331 class TrackPtrList : public itunesdb::utils::SortablePtrVector<itunesdb::Track>
01332 {
01333     typedef itunesdb::utils::SortablePtrVector<itunesdb::Track> BaseClass;
01334 public:
01335 
01336     /**
01337      * @brief Creates an empty TrackPtrList
01338      * 
01339      * The default sort order ist set accordingly to setDefaultSortOrder()
01340      */
01341     TrackPtrList();
01342 
01343     /**
01344      * @brief Creates a TrackPtrList and fills in the itunesdb::Track pointers returned by the given utils::RangeIterator.
01345      * 
01346      * The default sort order ist set accordingly to setDefaultSortOrder()
01347      * @param elements the Tracks to be filled in to the list
01348      */
01349     template <typename IterT>
01350     TrackPtrList( IterT elements )
01351         : itunesdb::utils::SortablePtrVector<itunesdb::Track> ( elements, false )
01352     {
01353         setDefaultSortOrder();
01354     }
01355 
01356 
01357     virtual ~TrackPtrList();
01358 
01359     /**
01360      * @brief Returns true if this list contains tracks not in sync with the database.
01361      */
01362     bool hasDirtyTracks() const;
01363 
01364     /**
01365      * @brief Returns true if this list contains tracks being played after the last sync.
01366      */
01367     bool hasRecentlyPlayedTracks() const;
01368 
01369     /**
01370      * @brief Returns all the Tracks where the given predicate returned true
01371      */
01372     TrackPtrList * getTracksBy( TrackPredicate& predicate, itunesdb::TrackPtrList& buffer ) const;
01373 
01374     /**
01375      * @brief Returns the first Track where the given predicate returned true
01376      * 
01377      * The given trackpredicate needs to contain a method that gets a track, and returns a bool
01378      * if it's the desired track
01379      * @return the first Track where the given predicate returned true
01380      * @see class TrackPredicate
01381      */
01382     Track * findFirstTrackBy( TrackPredicate& predicate ) const;
01383 
01384     /**
01385      * @brief Removes the elements the given predicate returns true.
01386      * 
01387      * @return true if at least one of the elements got removed.
01388      */
01389     bool removeIfTrue( TrackPredicate& predicate );
01390 
01391     /**
01392      * @brief Removes all references to the given track.
01393      * 
01394      * @return true if at least one element got removed. false otherwise
01395      */
01396     bool removeAllRefs( itunesdb::Track * track );
01397 
01398     /**
01399      * @brief Sets the sort order to default ( Artist/Album/Tracknumber )
01400      */
01401     void setDefaultSortOrder();
01402 
01403 };
01404 
01405 }   // namespace itunesdb
01406 
01407 #endif

Generated on Wed Nov 28 03:04:38 2007 for libqtpod by  doxygen 1.5.0