00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef ITUNESDBSMARTPLAYLISTRULES_H
00025 #define ITUNESDBSMARTPLAYLISTRULES_H
00026
00027 #include <qstring.h>
00028 #include <vector>
00029
00030 #define ACTION_NOT_BIT 0x02000000
00031 #define ACTION_STRING_BIT 0x01000000
00032
00033 #define SPL_VALUE_NOW 0x2dae2dae2dae2daeLL
00034
00035 #define IN_THE_LAST_SECONDS 1
00036 #define IN_THE_LAST_DAYS 86400
00037 #define IN_THE_LAST_WEEKS 604800
00038
00039 namespace itunesdb {
00040
00048 enum SPLStringField {
00049 FIELD_NAME = 0x02,
00050 FIELD_ALBUM = 0x03,
00051 FIELD_ARTIST = 0x04,
00052 FIELD_GENRE = 0x08,
00053 FIELD_KIND = 0x09,
00054 FIELD_COMMENT = 0x0e,
00055 FIELD_COMPOSER = 0x12,
00056 FIELD_GROUPING = 0x27,
00057 FIELD_DESCRIPTION = 0x36,
00058 FIELD_CATEGORY = 0x37
00059 };
00060
00061
00062 enum SPLUIntField {
00063 FIELD_BITRATE = 0x05,
00064 FIELD_SAMPLERATE = 0x06,
00065 FIELD_YEAR = 0x07,
00066 FIELD_DATEMODIFIED = 0x0a,
00067 FIELD_TRACKNUMBER = 0x0b,
00068 FIELD_SIZE = 0x0c,
00069 FIELD_TIME = 0x0d,
00070 FIELD_DATEADDED = 0x10,
00071 FIELD_PLAYCOUNT = 0x16,
00072 FIELD_LASTPLAYED = 0x17,
00073 FIELD_DISCNUMBER = 0x18,
00074 FIELD_RATING = 0x19,
00075 FIELD_COMPILATION = 0x1f,
00076 FIELD_BPM = 0x23,
00077 FIELD_PLAYLISTID = 0x28,
00078 FIELD_PODCAST = 0x29
00079 };
00080
00081
00082 enum SPLStringAction {
00083 ACTION_IS_STRING = 0x01000001,
00084 ACTION_CONTAINS = 0x01000002,
00085 ACTION_STARTSWITH = 0x01000004,
00086 ACTION_ENDSWITH = 0x01000008,
00087 ACTION_IS_NOT_STRING = ACTION_IS_STRING ^ ACTION_NOT_BIT,
00088 ACTION_DOESNT_CONTAIN = ACTION_CONTAINS ^ ACTION_NOT_BIT,
00089 ACTION_DOESNT_STARTWITH = ACTION_STARTSWITH ^ ACTION_NOT_BIT,
00090 ACTION_DOESNT_ENDWITH = ACTION_ENDSWITH ^ ACTION_NOT_BIT
00091 };
00092
00093
00094 enum SPLUIntAction {
00095 ACTION_IS_UINT = 0x00000001,
00096 ACTION_GREATER_THAN = 0x00000010,
00097 ACTION_GREATER_OR_EQUAL = 0x00000020,
00098 ACTION_LESS_THAN = 0x00000040,
00099 ACTION_LESS_OR_EQUAL = 0x00000080,
00100 ACTION_IN_RANGE = 0x00000100,
00101 ACTION_IN_THE_LAST = 0x00000200,
00102 ACTION_IS_NOT_UINT = ACTION_IS_UINT ^ ACTION_NOT_BIT,
00103 ACTION_NOT_GREATER = ACTION_GREATER_THAN ^ ACTION_NOT_BIT,
00104 ACTION_NOT_GREATER_OR_EQUAL = ACTION_GREATER_OR_EQUAL ^ ACTION_NOT_BIT,
00105 ACTION_NOT_LESS = ACTION_LESS_THAN ^ ACTION_NOT_BIT,
00106 ACTION_NOT_LESS_OR_EQUAL = ACTION_LESS_OR_EQUAL ^ ACTION_NOT_BIT,
00107 ACTION_NOT_IN_RANGE = ACTION_IN_RANGE ^ ACTION_NOT_BIT,
00108 ACTION_NOT_IN_THE_LAST = ACTION_IN_THE_LAST ^ ACTION_NOT_BIT
00109 };
00110
00111
00112 enum SPLLimitSort {
00113 LIMIT_SORT_RANDOM = 0x02,
00114 LIMIT_SORT_SONG_NAME = 0x03,
00115 LIMIT_SORT_ALBUM = 0x04,
00116 LIMIT_SORT_ARTIST = 0x05,
00117 LIMIT_SORT_GENRE = 0x07,
00118 LIMIT_SORT_RECENTLYADDED = 0x10,
00119 LIMIT_SORT_PLAYCOUNT = 0x14,
00120 LIMIT_SORT_LASTPLAYED = 0x15,
00121 LIMIT_SORT_RATING = 0x17
00122 };
00123
00124
00125 enum SPLLimitType {
00126 LIMIT_TYPE_MINUTES = 1,
00127 LIMIT_TYPE_MEGABYTES = 2,
00128 LIMIT_TYPE_SONGS = 3,
00129 LIMIT_TYPE_HOURS = 4,
00130 LIMIT_TYPE_GIGABYTES = 5
00131 };
00132
00133
00137 class SmartPlaylistRule {
00138
00139 friend class SmartPlaylistRuleSet;
00140
00141 Q_UINT32 mField;
00142 Q_UINT32 mAction;
00143
00144 const QString mString;
00145
00146 const Q_UINT64 mFromValue;
00147 const Q_UINT64 mToValue;
00148
00149 const Q_INT64 mFromDate;
00150 const Q_INT64 mToDate;
00151
00152 const Q_UINT64 mFromUnits;
00153 const Q_UINT64 mToUnits;
00154
00155 Q_UINT64 mCalculatedFrom;
00156 Q_UINT64 mCalculatedTo;
00157
00158 public:
00159
00160 virtual ~SmartPlaylistRule();
00161
00165 Q_UINT32 getAction() const {
00166 return mAction;
00167 }
00168
00172 Q_UINT32 getField() const {
00173 return mField;
00174 }
00175
00179 const QString& getString() const {
00180 return mString;
00181 }
00182
00188 Q_UINT64 getFromValue() const {
00189 return mFromValue;
00190 }
00191
00197 Q_UINT64 getToValue() const {
00198 return mToValue;
00199 }
00200
00206 Q_INT64 getFromDate() const {
00207 return mFromDate;
00208 }
00209
00215 Q_INT64 getToDate() const {
00216 return mToDate;
00217 }
00218
00223 Q_UINT64 getFromUnits() const {
00224 return mFromUnits;
00225 }
00226
00231 Q_UINT64 getToUnits() const {
00232 return mToUnits;
00233 }
00234
00239 Q_UINT64 calculatedFrom() const;
00240
00245 Q_UINT64 calculatedTo() const;
00246
00251 uint writeToStream( QDataStream& outStream ) const;
00252
00256 bool isStringBasedRule() const {
00257 return getAction() & ACTION_STRING_BIT;
00258 }
00259
00263 virtual const QString toString() const;
00264
00265 protected:
00266
00270 SmartPlaylistRule( SPLStringField field, SPLStringAction action, const QString& testString );
00271
00275 SmartPlaylistRule( SPLUIntField field, SPLUIntAction action,
00276 Q_UINT64 fromValue, Q_UINT64 toValue,
00277 Q_INT64 fromDate, Q_INT64 toDate,
00278 Q_UINT64 fromUnits, Q_UINT64 toUnits );
00279
00280 static QString getActionString( uint action );
00281
00282 static QString getFieldString( uint field );
00283
00284 static Q_UINT64 calculateTestValue( Q_UINT64 value, Q_INT64 date, Q_UINT64 units );
00285
00286 };
00287
00288
00289 typedef std::vector<SmartPlaylistRule*> RuleList;
00290
00311 class SmartPlaylistRuleSet {
00312
00313 friend class Playlist;
00314
00315 public:
00316
00317 SmartPlaylistRuleSet();
00318 virtual ~SmartPlaylistRuleSet();
00319
00327 virtual bool addStringRule( SPLStringField field,
00328 SPLStringAction action, const QString& testString, int position = -1 );
00329
00357 virtual bool addUIntRule( SPLUIntField field, SPLUIntAction action,
00358 Q_UINT64 fromValue, Q_UINT64 toValue,
00359 Q_INT64 fromDate, Q_INT64 toDate,
00360 Q_UINT64 fromUnits, Q_UINT64 toUnits, int position = -1 );
00361
00371 bool addUIntRule( SPLUIntField field, SPLUIntAction action,
00372 Q_UINT64 fromValue, Q_UINT64 toValue, int position = -1 ) {
00373 return addUIntRule( field, action, fromValue, toValue, 0, 0, 1, 1, position );
00374 }
00375
00376
00385 bool addInTheLastRule( SPLUIntField field, bool negateRule, Q_INT64 value, Q_UINT64 units, int position = -1 ) {
00386 return addUIntRule( field,
00387 negateRule ? ACTION_NOT_IN_THE_LAST : ACTION_IN_THE_LAST,
00388 SPL_VALUE_NOW, SPL_VALUE_NOW, value, 0, units, 1, position );
00389 }
00390
00391
00397 const SmartPlaylistRule * getRuleAt( uint position ) {
00398 return mRules.at( position );
00399 }
00400
00408 bool removeRuleAt( uint position );
00409
00413 void clear();
00414
00415
00419 bool isLiveUpdate() const {
00420 return mLiveUpdate;
00421 }
00422
00423
00427 void setLiveUpdateFlag( bool liveupdate );
00428
00432 bool isCheckRules() const {
00433 return mCheckRules;
00434 }
00435
00439 void setCheckRulesFlag( bool checkRules );
00440
00444 bool isCheckLimits() const {
00445 return mCheckLimits;
00446 }
00447
00451 virtual void setLimits( SPLLimitSort limitSort, SPLLimitType limitType, Q_UINT32 limitValue );
00452
00456 void enableLimits( bool enable );
00457
00461 SPLLimitSort getLimitSort() const {
00462 return mLimitSort;
00463 }
00464
00468 SPLLimitType getLimitType() const {
00469 return mLimitType;
00470 }
00471
00475 bool isMatchAny() const {
00476 return mMatchAny;
00477 }
00478
00482 void setMatchAnyFlag( bool matchAny );
00483
00487 bool checkedTracksOnly() const {
00488 return mCheckedOnly;
00489 }
00490
00495 void setCheckedTracksOnlyFlag( bool checkedOnly );
00496
00500 const RuleList& getRules() const;
00501
00505 uint getNumRules() const;
00506
00510 QString toString() const;
00511
00512 protected:
00513
00514
00515 SmartPlaylistRuleSet( const SmartPlaylistRuleSet & src );
00516
00523 uint readRules( QDataStream & instream, uint length );
00524
00531 bool readHeader( QDataStream & instream, uint length );
00532
00538 uint writeRules( QDataStream & outstream ) const;
00539
00545 uint writeHeader( QDataStream & outstream ) const;
00546
00547
00548
00549
00550
00551
00552
00553 bool mMatchAny;
00554
00555 Q_UINT32 unk5;
00556
00557 Q_UINT8 mLiveUpdate;
00558 Q_UINT8 mCheckLimits;
00559 Q_UINT8 mCheckRules;
00560 Q_UINT8 mCheckedOnly;
00561 Q_UINT8 mReverseLimitSort;
00562 SPLLimitSort mLimitSort;
00563 SPLLimitType mLimitType;
00564 Q_UINT32 mLimitValue;
00565
00566
00567
00568 RuleList mRules;
00569
00570 virtual SmartPlaylistRule * createStringRule( SPLStringField field,
00571 SPLStringAction action, const QString& testString );
00572
00573 virtual SmartPlaylistRule * createUIntRule( SPLUIntField field, SPLUIntAction action,
00574 Q_UINT64 fromValue, Q_UINT64 toValue,
00575 Q_INT64 fromDate, Q_INT64 toDate,
00576 Q_UINT64 fromUnits, Q_UINT64 toUnits );
00577
00578 private:
00579
00580 SmartPlaylistRule * readSingleRule( QDataStream & instream, uint * bytesRead = NULL );
00581
00582 };
00583
00584
00585 }
00586
00587 #endif