Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

playlist.h

Go to the documentation of this file.
00001 #ifndef NOATUNPLAYLIST_H
00002 #define NOATUNPLAYLIST_H
00003 
00004 #include <qobject.h>
00005 #include <kurl.h>
00006 #include <qdict.h>
00007 #include <qstringlist.h>
00008 #include <cassert>
00009 
00010 class PlaylistItem;
00011 
00012 /**
00013  * If you're not coding a playlist, ignore this class.
00014  * 
00015  * The backend.  Since PlaylistItemData is refcounted,
00016  * this contains the data, the PlaylistItem is the "reference"
00017  *
00018  * PlaylistItem m=new PlaylistItemData;
00019  *
00020  * Of course, you're supposed to inheret from PlaylistItemData
00021  * in your Playlist, since there's pure virtuals.
00022  *
00023  * You can create these objects on demand.
00024  **/
00025 class PlaylistItemData
00026 {
00027 public:
00028     PlaylistItemData();
00029     virtual ~PlaylistItemData();
00030 
00031     /**
00032      * Noatun asks your playlist for properties.  It is your
00033      * responsiblity to store the information.  But usually a QMap<QString,QString>
00034      * is enough.
00035      *
00036      * If you return the default value, the default should not
00037      * be written.
00038      *
00039      * This returns the property, or def if such a property doesn't exist
00040      **/
00041     virtual QString property(const QString &key, const QString &def=0) const=0;
00042 
00043     /**
00044      * This sets the property with the given key and value.
00045      *
00046      * Important: If you use a QMap, you'll have to remove the current
00047      * item before adding a new one
00048      **/
00049     virtual void setProperty(const QString &key, const QString &property)=0;
00050 
00051     /**
00052      * remove the item with given key
00053      **/
00054     virtual void clearProperty(const QString &key)=0;
00055 
00056     /**
00057      * return a list of property keys
00058      **/
00059     virtual QStringList properties() const=0;
00060 
00061     /**
00062      * return whether if the given key exists
00063      **/
00064     virtual bool isProperty(const QString &key) const=0;
00065 
00066     /**
00067      * return the title of the song. By default, this will
00068      * use the following by default, in order of priority
00069      *
00070      * property("realtitle")
00071      * property("title")
00072      * url().filename()
00073      *
00074      * you shouldn't need to override this.
00075      **/
00076     virtual QString title() const;
00077 
00078     /**
00079      * the true filename of the song, remote or local
00080      **/
00081     virtual KURL url() const { return KURL(property("url")); }
00082     /**
00083      * set the true filename of the song, remote or local
00084      **/
00085     virtual void setUrl(const KURL &url) { setProperty("url", url.url()); }
00086 
00087     /**
00088      * first, this checks for the property "mimetype", else
00089      * it'l ask KMimeType based on file()
00090      **/
00091     virtual QCString mimetype() const;
00092 
00093     /**
00094      * first, checks for the property "playObject", else,
00095      * it'l ask aRts
00096      **/
00097     virtual QCString playObject() const;
00098     
00099     /**
00100      * return the filename to send to the playobject
00101      **/
00102     virtual QString file() const { return url().path(); }
00103 
00104     /**
00105      * what's the length of the song, in milliseconds?
00106      **/
00107     virtual int length() const;
00108 
00109     /**
00110      * sets the length of the song, in milliseconds
00111      **/
00112     virtual void setLength(int ms);
00113 
00114     /**
00115      * returns a friendly representation of the length
00116      * of this file
00117      **/
00118     QString lengthString() const;
00119     
00120     /**
00121      * compare yourself with the given PlaylistItemData
00122      * This is implemented in the slow fashion of
00123      * comparing all the properties.  You may 
00124      * have a much faster way of implementing this
00125      * if this==&d, this will not be called, normally
00126      **/
00127     virtual bool operator == (const PlaylistItemData &d) const;
00128 
00129     /**
00130      * this is implemented as !(*this==d), you may have a 
00131      * faster way to implement this
00132      **/
00133     virtual bool operator != (const PlaylistItemData &d) const;
00134     
00135     /**
00136      * remove this item from the list
00137      **/
00138     virtual void remove() = 0;
00139     
00140 
00141     /**
00142      * Playlists should not download files if this is true
00143      **/
00144     bool streamable() const  { return isProperty("stream_"); }
00145     
00146 public:
00147     /**
00148      * Call this when you want to signal
00149      * the given item has been added to the list
00150      **/
00151     void added();
00152 
00153     /**
00154      * Your playlist must call this when the file
00155      * is removed from the playlist
00156      **/
00157     void removed();
00158 
00159     /**
00160      * Your playlist must call this when the file
00161      * is modified
00162      **/
00163     void modified();
00164 
00165 
00166 public: // reference counting
00167     /**
00168      * Have the reference counter never delete this
00169      * 
00170      * This is useful for when you want to keep all
00171      * your items hanging around
00172      **/
00173     void addRef() { mRefs++; }
00174     void removeRef() { mRefs--; if (!mRefs) delete this; }
00175 
00176 private:
00177     mutable int mRefs;
00178 };
00179 
00180 
00181 /**
00182  * a reference to a PlaylistItem(Data)
00183  *
00184  * All methods here should have the same behavior
00185  * as they do for PlaylistItemData
00186  *
00187  * If you're a playlist, you should inherit
00188  * from PlaylistItemData
00189  *
00190  * It's client code's responsibility to ensure that
00191  * PlaylistItem is not null by using either the boolean
00192  * conversion or isNull()
00193  **/
00194 class PlaylistItem
00195 {
00196 public:
00197     PlaylistItem(const PlaylistItem &source);
00198     PlaylistItem(PlaylistItemData *source);
00199     PlaylistItem() : mData(0) {}
00200     ~PlaylistItem();
00201 
00202     PlaylistItem &operator =(const PlaylistItem &source);
00203     PlaylistItem &operator =(PlaylistItemData *source);
00204 
00205     PlaylistItemData *data() { return mData; }
00206     const PlaylistItemData *data() const { return mData; }
00207     
00208     const PlaylistItem &operator =(const PlaylistItem &source) const;
00209     const PlaylistItem &operator =(const PlaylistItemData *source) const;
00210 
00211     operator bool() const { return (bool)mData; }
00212     bool isNull() const { return !(bool)mData; }
00213 
00214     bool operator ==(const PlaylistItem &i) const
00215     {
00216         if (data()==i.data()) return true;
00217         if (!data() || !i.data()) return false;
00218         return *i.data()==*data();
00219     }
00220     bool operator ==(const PlaylistItemData *i) const
00221     {
00222         if (data()==i) return true;
00223         if (!data() || !i) return false;
00224         return *i==*data();
00225     }
00226 
00227     bool operator !=(const PlaylistItem &i) const
00228         { return ! (*this==i); }
00229     bool operator !=(const PlaylistItemData *i) const
00230         { return ! (*this->data()==*i); }
00231     
00232     QString property(const QString &key, const QString &def=0) const
00233     {
00234         assert(mData);
00235         return mData->property(key, def);
00236     }
00237     
00238     void setProperty(const QString &key, const QString &property)
00239     {
00240         assert(mData);
00241         const_cast<PlaylistItemData*>(mData)->setProperty(key, property);
00242     }
00243     
00244     void clearProperty(const QString &key)
00245     {
00246         assert(mData);
00247         const_cast<PlaylistItemData*>(mData)->clearProperty(key);
00248     }
00249     
00250     QStringList properties() const
00251     {
00252         assert(mData);
00253         return mData->properties();
00254     }
00255 
00256     bool isProperty(const QString &key) const
00257     {
00258         assert(mData);
00259         return mData->isProperty(key);
00260     }
00261 
00262     KURL url() const { assert(mData); return mData->url(); }
00263     void setUrl(const KURL &url)
00264     {
00265         assert(mData);
00266         const_cast<PlaylistItemData*>(mData)->setUrl(url);
00267     }
00268 
00269     QCString mimetype() const { assert(mData); return mData->mimetype(); }
00270     QCString playObject() const { assert(mData); return mData->playObject(); }
00271     QString file() const { assert(mData); return mData->file(); }
00272 
00273     QString title() const
00274     {
00275         assert(mData);
00276         return mData->title();
00277     }
00278 
00279     int length() const
00280     {
00281         assert(mData);
00282         return mData->length();
00283     }
00284 
00285     void setLength(int ms) const
00286     {
00287         assert(mData);
00288         mData->setLength(ms);
00289     }
00290 
00291     QString lengthString() const { assert(mData); return mData->lengthString(); }
00292     
00293     void remove() { assert(mData); mData->remove(); }
00294 
00295     bool streamable() const  { assert(mData); return mData->streamable(); }
00296 
00297 private:
00298     // reference counting
00299     void removeRef() const;
00300     void addRef() const; // requires mData already has item
00301 
00302 private:
00303     mutable PlaylistItemData *mData;
00304     void *_bc1, *_bc2;
00305 };
00306 
00307 /**
00308  * The playlist, which you derive from when creating
00309  * your own playlist.
00310  *
00311  * Do not, under any circumstances, call a Playlist method
00312  * when you can call a Player method, unless, of course, you
00313  * ARE the playlist.
00314  **/
00315 class Playlist : public QObject
00316 {
00317 Q_OBJECT
00318     friend class PlaylistItemData;
00319 public:
00320     Playlist(QObject *parent, const char *name);
00321     /**
00322      * on playlist unload, your playlist must
00323      * have current()==0 and emit playCurrent
00324      **/
00325     virtual ~Playlist();
00326     
00327     /**
00328      * go to the front
00329      **/
00330     virtual void reset()=0;
00331     
00332     /**
00333      * empty the list
00334      **/
00335     virtual void clear()=0;
00336 
00337     /**
00338      * add a file
00339      */
00340     virtual void addFile(const KURL&, bool play=false)=0;
00341 
00342     /**
00343      * cycle forward, return that
00344      **/    
00345     virtual PlaylistItem next()=0;
00346 
00347     /**
00348      * cycle to next section, return that
00349      * defaults to return next()
00350      */
00351     virtual PlaylistItem nextSection();
00352 
00353     /**
00354      * cycle back, return that
00355      **/
00356     virtual PlaylistItem previous()=0;
00357 
00358     /**
00359      * cycle to previous section, return that
00360      * defaults to return previous()
00361      */
00362     virtual PlaylistItem previousSection();
00363 
00364     /**
00365      * current item
00366      **/
00367     virtual PlaylistItem current()=0;
00368     /**
00369      * set the current item
00370      **/
00371     virtual void setCurrent(const PlaylistItem &)=0;
00372 
00373     /**
00374      * get the first item
00375      **/
00376     virtual PlaylistItem getFirst() const =0;
00377 
00378     /**
00379      * get the item after item
00380      **/
00381     virtual PlaylistItem getAfter(const PlaylistItem &item) const =0;
00382      
00383     /**
00384      * is the view visible?
00385      **/
00386     
00387     virtual bool listVisible() const =0;
00388     
00389     /**
00390      * do the KCmdLineArgs stuff
00391      **/
00392     int handleArguments();
00393 
00394     /**
00395      * return a list of songs in which at least one
00396      * of the keys matches at least one of the values
00397      *
00398      * the default implementation will call getFirst()
00399      * and getAfter() which could be potentially slow,
00400      * depending how your playlist is designed.  So
00401      * you're free to reimplement this if you could
00402      * do better
00403      *
00404      * A value of "" is equal to an unset value
00405      * 
00406      * limit is the maximum amount of items to return,
00407      * or -1 if you want as many as possible
00408      *
00409      * if exact is true, a match is only made if
00410      * the string is identical to a value.  if false
00411      * a match is made if the string contains a value
00412      *
00413      * caseSensitive, if false, means that the given
00414      * values are compared case insensitively to
00415      * to the items in the playlist.  The keys
00416      * are always compared with case sensitivity
00417      **/
00418     virtual QValueList<PlaylistItem> select(
00419             const QStringList &keys, const QStringList &values,
00420             int limit=-1, bool exact=false, bool caseSensitive=false
00421         );
00422     
00423     /**
00424      * The default implementation will just call
00425      * the above select.  Of course, you're free to implement
00426      * both of these (with different mechanisms if need be)
00427      * for speed
00428      **/
00429     virtual QValueList<PlaylistItem> select(
00430             const QString &key, const QString &value,
00431             int limit=-1, bool exact=false, bool caseSensitive=false
00432         );
00433     /**
00434      * exactly the same as the above, except converts 
00435      * the const char* to QString (utf8)
00436      **/
00437     inline QValueList<PlaylistItem> select(
00438             const char *key, const char *value,
00439             int limit=-1, bool exact=false, bool caseSensitive=false
00440         )
00441     {
00442         return select(
00443                 QString(key), QString(value),
00444                 limit, exact, caseSensitive
00445             );
00446     }
00447 
00448 public slots:
00449     /**
00450      * show the list!
00451      **/
00452     virtual void showList()=0;
00453     /**
00454      * hide it
00455      **/
00456     virtual void hideList()=0;
00457     /**
00458      * toggle visibility
00459      **/
00460     virtual void toggleList();
00461 
00462 signals:
00463     /**
00464      * when you want the engine to reload current()
00465      * This is how your playlist forces noatun to
00466      * play a new song
00467      **/
00468     void playCurrent();
00469 
00470     /**
00471      * when the list is hidden
00472      **/
00473     void listHidden();
00474     
00475     /**
00476      * when the list is shown
00477      **/
00478     void listShown();
00479 };
00480 
00481 /**
00482  * this class's methods will be called whenever
00483  * something happens to the playlist or its
00484  * items.
00485  *
00486  * If the playlist plugin changes, you don't have to do
00487  * anything.
00488  **/
00489 class PlaylistNotifier
00490 {
00491 public:
00492     PlaylistNotifier();
00493     virtual ~PlaylistNotifier();
00494 
00495     /**
00496      * a new item is added to the list
00497      **/
00498     virtual void added(PlaylistItem &) {}
00499 
00500     /**
00501      * an item is removed from the list
00502      **/
00503     virtual void removed(PlaylistItem &) {}
00504 
00505     /**
00506      * this item was modified (via a changed
00507      * or added property
00508      **/
00509     virtual void modified(PlaylistItem &) {}
00510 };
00511 
00512 
00513 #endif
00514 

Generated at Mon Apr 1 11:45:00 2002 for noatun by doxygen1.2.9.1 written by Dimitri van Heesch, © 1997-2001