|
|
|
/***************************************************************************
|
|
|
|
* copyright : (c) 2004 Pierpaolo Di Panfilo *
|
|
|
|
* (c) 2005-2006 Seb Ruiz <me@sebruiz.net> *
|
|
|
|
* (c) 2006 Bart Cerneels <bart.cerneels@gmail.com> *
|
|
|
|
* (c) 2006 Adam Pigg <adam@piggz.co.uk> *
|
|
|
|
* (c) 2006 Bonne Eggleston <b.eggleston@gmail.com> *
|
|
|
|
* See COPYING file for licensing information *
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#ifndef PLAYLISTBROWSERITEM_H
|
|
|
|
#define PLAYLISTBROWSERITEM_H
|
|
|
|
|
|
|
|
#include "dynamicmode.h"
|
|
|
|
#include "podcastbundle.h"
|
|
|
|
#include "podcastsettings.h"
|
|
|
|
|
|
|
|
#include <kdialogbase.h> // StreamEditor baseclass
|
|
|
|
#include <tdeio/job.h>
|
|
|
|
#include <klineedit.h>
|
|
|
|
#include <tdelistview.h>
|
|
|
|
#include <kurl.h>
|
|
|
|
|
|
|
|
#include <tqdom.h>
|
|
|
|
#include <tqfile.h>
|
|
|
|
#include <tqhttp.h>
|
|
|
|
#include <tqptrlist.h>
|
|
|
|
#include <tqtimer.h> // Podcast loading animation
|
|
|
|
#include <tqurl.h>
|
|
|
|
|
|
|
|
class MetaBundle;
|
|
|
|
class PlaylistTrackItem;
|
|
|
|
class TrackItemInfo;
|
|
|
|
|
|
|
|
namespace TDEIO { class Job; class TransferJob; class CopyJob; } //podcast downloads
|
|
|
|
|
|
|
|
/**
|
|
|
|
* RTTI VALUES
|
|
|
|
* 1000 - PlaylistCategory
|
|
|
|
* 1001 - PlaylistEntry
|
|
|
|
* 1002 - PlaylistTrackItem
|
|
|
|
* 1003 - StreamEntry
|
|
|
|
* 1004 - SmartPlaylist
|
|
|
|
* 1005 - DynamicEntry (Dynamic)
|
|
|
|
* 1006 - PodcastChannel
|
|
|
|
* 1007 - PodcastEpisode
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/* A base class to be able to use polymorphism and avoid tons of casts */
|
|
|
|
class PlaylistBrowserEntry : public TQObject, public TDEListViewItem
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
|
|
|
PlaylistBrowserEntry( TQListViewItem *parent, TQListViewItem *after )
|
|
|
|
: TDEListViewItem( parent, after) { m_kept = true; }
|
|
|
|
PlaylistBrowserEntry( TQListView *parent, TQListViewItem *after )
|
|
|
|
: TDEListViewItem( parent, after) { m_kept = true; }
|
|
|
|
PlaylistBrowserEntry( TQListViewItem *parent, TQListViewItem *after, const TQString &name )
|
|
|
|
: TDEListViewItem( parent, after, name) { m_kept = true; }
|
|
|
|
|
|
|
|
virtual TQDomElement xml() const { return TQDomElement(); }
|
|
|
|
TQListViewItem* parent() const { return TDEListViewItem::parent(); }
|
|
|
|
|
|
|
|
bool isKept() const { return m_kept; } // if kept == true, then it will be saved
|
|
|
|
void setKept( bool k ); // to the cache files. If false, non-renameable
|
|
|
|
|
|
|
|
virtual void updateInfo();
|
|
|
|
virtual void setDynamic( bool ) {};
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
virtual void slotDoubleClicked();
|
|
|
|
virtual void slotRenameItem();
|
|
|
|
virtual void slotPostRenameItem( const TQString newName );
|
|
|
|
virtual void showContextMenu( const TQPoint & ) {};
|
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual int compare( TQListViewItem*, int, bool ) const; //reimplemented
|
|
|
|
|
|
|
|
/** Interval of the download pixmap animation, in milliseconds */
|
|
|
|
static const int ANIMATION_INTERVAL = 250;
|
|
|
|
|
|
|
|
private:
|
|
|
|
bool m_kept;
|
|
|
|
};
|
|
|
|
|
|
|
|
class DynamicEntry : public PlaylistBrowserEntry, public DynamicMode
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
|
|
|
DynamicEntry( TQListViewItem *parent, TQListViewItem *after, const TQString &title );
|
|
|
|
DynamicEntry( TQListViewItem *parent, TQListViewItem *after, const TQDomElement &xmlDefinition );
|
|
|
|
~DynamicEntry() { };
|
|
|
|
|
|
|
|
virtual TQString text( int column ) const;
|
|
|
|
|
|
|
|
virtual TQDomElement xml() const;
|
|
|
|
|
|
|
|
static const int RTTI = 1005;
|
|
|
|
int rtti() const { return RTTI; }
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
virtual void slotDoubleClicked();
|
|
|
|
virtual void showContextMenu( const TQPoint & );
|
|
|
|
};
|
|
|
|
|
|
|
|
class PlaylistCategory : public PlaylistBrowserEntry
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
|
|
|
PlaylistCategory( TQListView *parent, TQListViewItem *after, const TQString &, bool isFolder=false );
|
|
|
|
PlaylistCategory( PlaylistCategory *parent, TQListViewItem *after, const TQString &, bool isFolder=true );
|
|
|
|
PlaylistCategory( TQListView *parent, TQListViewItem *after, const TQDomElement &xmlDefinition, bool isFolder=false);
|
|
|
|
PlaylistCategory( PlaylistCategory *parent, TQListViewItem *after, const TQDomElement &xmlDefinition );
|
|
|
|
PlaylistCategory( PlaylistCategory *parent, TQListViewItem *after, const TQString &t, const int id );
|
|
|
|
|
|
|
|
~PlaylistCategory() { };
|
|
|
|
|
|
|
|
const TQString &title() const { return m_title; }
|
|
|
|
bool isFolder() { return m_folder; }
|
|
|
|
|
|
|
|
void paintCell( TQPainter*, const TQColorGroup&, int, int, int );
|
|
|
|
|
|
|
|
void setId( const int id ) { m_id = id; }
|
|
|
|
const int id() const { return m_id; }
|
|
|
|
|
|
|
|
virtual TQDomElement xml() const;
|
|
|
|
|
|
|
|
int rtti() const { return RTTI; }
|
|
|
|
static const int RTTI = 1000; //category item
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
virtual void slotDoubleClicked();
|
|
|
|
virtual void slotRenameItem();
|
|
|
|
virtual void showContextMenu( const TQPoint & );
|
|
|
|
|
|
|
|
protected:
|
|
|
|
void okRename( int col );
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
void setXml( const TQDomElement &xml );
|
|
|
|
|
|
|
|
TQString m_title;
|
|
|
|
int m_id;
|
|
|
|
bool m_folder;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class PlaylistEntry : public PlaylistBrowserEntry
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
|
|
friend class PlaylistTrackItem;
|
|
|
|
friend class TrackItemInfo;
|
|
|
|
friend class PlaylistCategory;
|
|
|
|
|
|
|
|
public:
|
|
|
|
PlaylistEntry( TQListViewItem *parent, TQListViewItem *after, const KURL &, int tracks=0, int length=0 );
|
|
|
|
PlaylistEntry( TQListViewItem *parent, TQListViewItem *after, const TQDomElement &xmlDefinition );
|
|
|
|
~PlaylistEntry();
|
|
|
|
|
|
|
|
void sortChildItems ( int /*column*/, bool /*ascending*/ ) { /* Don't sort its children */ }; //reimplemented
|
|
|
|
|
|
|
|
void load();
|
|
|
|
|
|
|
|
const KURL &url() const { return m_url; }
|
|
|
|
void setUrl( const TQString &u ) { m_url.setPath( u ); }
|
|
|
|
int trackCount() const { return m_trackCount; }
|
|
|
|
int length() const { return m_length; }
|
|
|
|
bool isDynamic() const { return m_dynamic; }
|
|
|
|
bool isLoaded() const { return m_loaded; }
|
|
|
|
|
|
|
|
void setDynamic( bool );
|
|
|
|
|
|
|
|
int compare( TQListViewItem* i, int col ) const; //reimpl.
|
|
|
|
KURL::List tracksURL(); //returns the list of tracks url
|
|
|
|
void insertTracks( TQListViewItem *after, KURL::List list );
|
|
|
|
void insertTracks( TQListViewItem *after, TQValueList<MetaBundle> bundles );
|
|
|
|
// isLast is used to avoid saving the playlist to disk every time a track is removed
|
|
|
|
// when removing a list of tracks from the playlist
|
|
|
|
void removeTrack( TQListViewItem *item, bool isLast = true );
|
|
|
|
|
|
|
|
//returns a list of track information
|
|
|
|
TQPtrList<TrackItemInfo> trackList() const { return m_trackList; }
|
|
|
|
TQPtrList<TrackItemInfo> droppedTracks() const { return tmp_droppedTracks; }
|
|
|
|
|
|
|
|
void setOpen( bool );
|
|
|
|
void setup();
|
|
|
|
void paintCell( TQPainter*, const TQColorGroup&, int, int, int );
|
|
|
|
|
|
|
|
virtual TQDomElement xml() const;
|
|
|
|
|
|
|
|
virtual void updateInfo();
|
|
|
|
|
|
|
|
//rtti is used to distinguish different kinds of list view items
|
|
|
|
int rtti() const { return RTTI; }
|
|
|
|
static const int RTTI = 1001; //playlist item
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
virtual void slotDoubleClicked();
|
|
|
|
virtual void slotPostRenameItem( const TQString newName );
|
|
|
|
virtual void showContextMenu( const TQPoint & );
|
|
|
|
|
|
|
|
signals:
|
|
|
|
void startingLoading();
|
|
|
|
void loaded();
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
void slotAnimation();
|
|
|
|
|
|
|
|
private:
|
|
|
|
void customEvent( TQCustomEvent* e );
|
|
|
|
void startAnimation();
|
|
|
|
void stopAnimation();
|
|
|
|
|
|
|
|
KURL m_url; //playlist url
|
|
|
|
int m_length; //total length in seconds
|
|
|
|
int m_trackCount; //track counter
|
|
|
|
TQPtrList<TrackItemInfo> m_trackList; //tracks in playlist
|
|
|
|
TQPtrList<TrackItemInfo> tmp_droppedTracks; //tracks dropped to the playlist while it wasn't been loaded
|
|
|
|
bool m_loading;
|
|
|
|
bool m_loaded; //playlist loaded
|
|
|
|
bool m_dynamic; //the playlist is scheduled for dynamic mode rotation
|
|
|
|
TQPixmap *m_loading1, *m_loading2; //icons for loading animation
|
|
|
|
TQTimer m_animationTimer;
|
|
|
|
uint m_iconCounter;
|
|
|
|
PlaylistTrackItem *m_lastTrack;
|
|
|
|
};
|
|
|
|
|
|
|
|
class PlaylistTrackItem : public PlaylistBrowserEntry
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
friend class TrackItemInfo;
|
|
|
|
|
|
|
|
public:
|
|
|
|
PlaylistTrackItem( TQListViewItem *parent, TQListViewItem *after, TrackItemInfo *info );
|
|
|
|
|
|
|
|
const KURL &url();
|
|
|
|
TrackItemInfo *trackInfo() const { return m_trackInfo; }
|
|
|
|
|
|
|
|
int rtti() const { return RTTI; }
|
|
|
|
static const int RTTI = 1002; //track item
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
virtual void slotDoubleClicked();
|
|
|
|
virtual void slotRenameItem() { /* Do nothing */ };
|
|
|
|
virtual void showContextMenu( const TQPoint & );
|
|
|
|
|
|
|
|
private:
|
|
|
|
TrackItemInfo *m_trackInfo;
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Stored in the database
|
|
|
|
class PodcastEpisode : public PlaylistBrowserEntry
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
PodcastEpisode( TQListViewItem *parent, TQListViewItem *after, const TQDomElement &xml,
|
|
|
|
const int feedType, const bool &isNew=false );
|
|
|
|
PodcastEpisode( TQListViewItem *parent, TQListViewItem *after, PodcastEpisodeBundle &bundle );
|
|
|
|
|
|
|
|
void downloadMedia();
|
|
|
|
void setOnDisk( bool d = true );
|
|
|
|
TQListViewItem *itemChannel() { return m_parent; }
|
|
|
|
|
|
|
|
|
|
|
|
const bool isNew() const { return m_bundle.isNew(); }
|
|
|
|
|
|
|
|
void setNew( const bool &n = true );
|
|
|
|
void setListened( const bool &n = true ) { setNew( !n ); }
|
|
|
|
|
|
|
|
// for convenience
|
|
|
|
const int dBId() const { return m_bundle.dBId(); }
|
|
|
|
const KURL url() const { return m_bundle.url(); }
|
|
|
|
const TQString title() const { return m_bundle.title(); }
|
|
|
|
const TQString author() const { return m_bundle.author(); }
|
|
|
|
const TQString date() const { return m_bundle.date(); }
|
|
|
|
const TQString type() const { return m_bundle.type(); }
|
|
|
|
const TQString description() const { return m_bundle.description(); }
|
|
|
|
const TQString guid() const { return m_bundle.guid(); }
|
|
|
|
const int duration() const { return m_bundle.duration(); }
|
|
|
|
const KURL &localUrl() const { return m_bundle.localUrl(); }
|
|
|
|
void setLocalUrlBase( const TQString &s );
|
|
|
|
void setLocalUrl( const KURL &localUrl );
|
|
|
|
|
|
|
|
void setup();
|
|
|
|
void paintCell( TQPainter*, const TQColorGroup&, int, int, int );
|
|
|
|
|
|
|
|
virtual void updateInfo();
|
|
|
|
|
|
|
|
void addToMediaDevice();
|
|
|
|
|
|
|
|
int rtti() const { return RTTI; }
|
|
|
|
static const int RTTI = 1007; //PodcastEpisode
|
|
|
|
static void createLocalDir( const KURL &localDir );
|
|
|
|
|
|
|
|
signals:
|
|
|
|
void downloadFinished();
|
|
|
|
void downloadAborted();
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
const bool isOnDisk();
|
|
|
|
virtual void slotDoubleClicked();
|
|
|
|
virtual void slotRenameItem() { /* Do nothing */ };
|
|
|
|
virtual void showContextMenu( const TQPoint & );
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
void abortDownload();
|
|
|
|
void downloadResult( TDEIO::Job * transferJob );
|
|
|
|
void slotAnimation();
|
|
|
|
void redirected( TDEIO::Job * job,const KURL & redirectedUrl );
|
|
|
|
|
|
|
|
private:
|
|
|
|
enum FeedType{ RSS=0, ATOM=1 };
|
|
|
|
|
|
|
|
virtual int compare( TQListViewItem*, int, bool ) const; //reimplemented
|
|
|
|
|
|
|
|
void associateWithLocalFile();
|
|
|
|
|
|
|
|
void startAnimation();
|
|
|
|
void stopAnimation();
|
|
|
|
void updatePixmap();
|
|
|
|
|
|
|
|
TQListViewItem *m_parent; //podcast channel it belongs to
|
|
|
|
PodcastEpisodeBundle m_bundle;
|
|
|
|
KURL m_localUrl;
|
|
|
|
|
|
|
|
bool m_fetching;
|
|
|
|
TQTimer m_animationTimer;
|
|
|
|
uint m_iconCounter;
|
|
|
|
|
|
|
|
TDEIO::StoredTransferJob* m_podcastEpisodeJob;
|
|
|
|
TQString m_filename;
|
|
|
|
|
|
|
|
bool m_downloaded; //marked as downloaded in cached xml
|
|
|
|
bool m_onDisk;
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Stored in the database
|
|
|
|
class PodcastChannel : public PlaylistBrowserEntry
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
PodcastChannel( TQListViewItem *parent, TQListViewItem *after, const KURL &url,
|
|
|
|
const TQDomNode &channelSettings );
|
|
|
|
PodcastChannel( TQListViewItem *parent, TQListViewItem *after, const KURL &url );
|
|
|
|
PodcastChannel( TQListViewItem *parent, TQListViewItem *after, const KURL &url,
|
|
|
|
const TQDomNode &channelSettings, const TQDomDocument &xml );
|
|
|
|
PodcastChannel( TQListViewItem *parent, TQListViewItem *after, const PodcastChannelBundle &pcb );
|
|
|
|
|
|
|
|
enum MediaFetch{ STREAM=0, AUTOMATIC=1 };
|
|
|
|
|
|
|
|
void setNew( const bool n = true );
|
|
|
|
bool hasNew() const { return m_new; }
|
|
|
|
// iterate over all children and explicitly check if there are any episodes which have not been listened
|
|
|
|
// to. Mark the channel as new/listened after doing this.
|
|
|
|
void checkAndSetNew();
|
|
|
|
|
|
|
|
void setListened( const bool n = true ); // over rides each child so it has been listened
|
|
|
|
|
|
|
|
void setOpen( bool open ); // if !m_polished, load the children. Lazy loading to improve start times
|
|
|
|
void load();
|
|
|
|
const bool isPolished() const { return m_polished; }
|
|
|
|
|
|
|
|
void configure();
|
|
|
|
void fetch();
|
|
|
|
void rescan();
|
|
|
|
|
|
|
|
const KURL &url() const { return m_url; }
|
|
|
|
const KURL link() const { return m_bundle.link(); }
|
|
|
|
const TQString title() const { return m_bundle.title(); }
|
|
|
|
const TQString description() const { return m_bundle.description(); }
|
|
|
|
const TQString copyright() const { return m_bundle.copyright(); }
|
|
|
|
|
|
|
|
const bool autoscan() const { return m_bundle.autoscan(); }
|
|
|
|
const bool autotransfer() const { return m_bundle.autotransfer(); }
|
|
|
|
const int fetchType() const { return m_bundle.fetchType(); }
|
|
|
|
const bool hasPurge() const { return m_bundle.hasPurge(); }
|
|
|
|
const int purgeCount() const { return m_bundle.purgeCount(); }
|
|
|
|
const TQString &saveLocation() const { return m_bundle.saveLocation(); }
|
|
|
|
PodcastSettings *getSettings() const
|
|
|
|
{
|
|
|
|
return new PodcastSettings( title(), saveLocation(),
|
|
|
|
autoscan(), fetchType(), autotransfer(),
|
|
|
|
hasPurge(), purgeCount() );
|
|
|
|
}
|
|
|
|
|
|
|
|
void setParent( PlaylistCategory *newParent );
|
|
|
|
void setSettings( PodcastSettings *settings );
|
|
|
|
void setXml( const TQDomNode &xml, const int feedType );
|
|
|
|
|
|
|
|
virtual void updateInfo();
|
|
|
|
|
|
|
|
int rtti() const { return RTTI; }
|
|
|
|
static const int RTTI = 1006; //podcastchannel
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
virtual void slotDoubleClicked();
|
|
|
|
virtual void slotRenameItem() { /* Do nothing */ };
|
|
|
|
virtual void showContextMenu( const TQPoint & );
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
void abortFetch();
|
|
|
|
void downloadChildQueue();
|
|
|
|
void fetchResult( TDEIO::Job* job );
|
|
|
|
void slotAnimation();
|
|
|
|
|
|
|
|
private:
|
|
|
|
enum FeedType{ RSS=0, ATOM=1 };
|
|
|
|
static const int EPISODE_LIMIT = 10; //Maximum number of episodes initially shown
|
|
|
|
|
|
|
|
bool containsItem( TQDomElement xml );
|
|
|
|
void downloadChildren();
|
|
|
|
const bool episodeExists( const TQDomNode &xml, const int feedType );
|
|
|
|
void purge();
|
|
|
|
void restorePurged();
|
|
|
|
void removeChildren();
|
|
|
|
void setDOMSettings( const TQDomNode &channelSettings );
|
|
|
|
void startAnimation();
|
|
|
|
void stopAnimation();
|
|
|
|
|
|
|
|
PodcastChannelBundle m_bundle;
|
|
|
|
|
|
|
|
/// loading all of the podcast episodes during startup can be very inefficient.
|
|
|
|
/// When the user expands the podcast for the first time, we load up the episodes.
|
|
|
|
bool m_polished;
|
|
|
|
|
|
|
|
KURL m_url; //remote xml url
|
|
|
|
bool m_fetching;
|
|
|
|
bool m_updating;
|
|
|
|
TQTimer m_animationTimer;
|
|
|
|
uint m_iconCounter;
|
|
|
|
bool m_new;
|
|
|
|
bool m_hasProblem;
|
|
|
|
|
|
|
|
TDEIO::TransferJob *m_podcastJob;
|
|
|
|
PlaylistCategory *m_parent; // category it belongs to
|
|
|
|
TQString m_podcastCurrentUrl;
|
|
|
|
TQPtrList<PodcastEpisode> m_podcastDownloadQueue;
|
|
|
|
bool m_settingsValid;
|
|
|
|
};
|
|
|
|
|
|
|
|
class StreamEntry : public PlaylistBrowserEntry
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
|
|
|
StreamEntry( TQListViewItem *parent, TQListViewItem *after, const KURL &, const TQString &t );
|
|
|
|
StreamEntry( TQListViewItem *parent, TQListViewItem *after, const TQDomElement &xmlDefinition );
|
|
|
|
~StreamEntry() { };
|
|
|
|
|
|
|
|
void setURL ( KURL u ) { m_url = u; }
|
|
|
|
void setTitle( TQString t ) { m_title = t; }
|
|
|
|
|
|
|
|
void setup();
|
|
|
|
void paintCell( TQPainter*, const TQColorGroup&, int, int, int );
|
|
|
|
|
|
|
|
const KURL &url() const { return m_url; }
|
|
|
|
const TQString &title() const { return m_title; }
|
|
|
|
|
|
|
|
virtual TQDomElement xml() const;
|
|
|
|
|
|
|
|
virtual void updateInfo();
|
|
|
|
|
|
|
|
int rtti() const { return RTTI; }
|
|
|
|
static const int RTTI = 1003; //stream item
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
virtual void slotDoubleClicked();
|
|
|
|
virtual void showContextMenu( const TQPoint & );
|
|
|
|
|
|
|
|
protected:
|
|
|
|
TQString m_title;
|
|
|
|
KURL m_url;
|
|
|
|
};
|
|
|
|
|
|
|
|
class LastFmEntry : public StreamEntry
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
|
|
|
LastFmEntry( TQListViewItem *parent, TQListViewItem *after, const KURL &u, const TQString &t )
|
|
|
|
: StreamEntry( parent, after, u, t ) { }
|
|
|
|
LastFmEntry( TQListViewItem *parent, TQListViewItem *after, const TQDomElement &xmlDefinition )
|
|
|
|
: StreamEntry( parent, after, xmlDefinition ) { }
|
|
|
|
virtual TQDomElement xml() const;
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
virtual void slotRenameItem() { /* Do nothing */ }
|
|
|
|
|
|
|
|
public:
|
|
|
|
int rtti() const { return RTTI; }
|
|
|
|
static const int RTTI = 1008; //lastfm item
|
|
|
|
};
|
|
|
|
|
|
|
|
class StreamEditor : public KDialogBase
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
StreamEditor( TQWidget *parent, const TQString &title, const TQString &url, bool readonly = false );
|
|
|
|
|
|
|
|
KURL url() const { return KURL( m_urlLineEdit->text() ); }
|
|
|
|
TQString name() const { return m_nameLineEdit->text().replace( "\n", " " ); }
|
|
|
|
|
|
|
|
private:
|
|
|
|
KLineEdit *m_urlLineEdit;
|
|
|
|
KLineEdit *m_nameLineEdit;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
class SmartPlaylist : public PlaylistBrowserEntry
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
|
|
|
SmartPlaylist( TQListViewItem *parent, TQListViewItem *after, const TQString &name, const TQString &query );
|
|
|
|
SmartPlaylist( TQListViewItem *parent, TQListViewItem *after, const TQString &name,
|
|
|
|
const TQString &urls, const TQString &tags );
|
|
|
|
SmartPlaylist( TQListViewItem *parent, TQListViewItem *after, const TQDomElement &xmlDefinition );
|
|
|
|
|
|
|
|
bool isDynamic() const { return m_dynamic; }
|
|
|
|
bool isEditable() const { return !m_xml.isNull(); }
|
|
|
|
bool isTimeOrdered(); //returns yes if the ordering is based on a time attribute
|
|
|
|
TQString query();
|
|
|
|
TQString title() const { return m_title; }
|
|
|
|
virtual TQDomElement xml() const { return m_xml; }
|
|
|
|
|
|
|
|
int length();
|
|
|
|
void setDynamic( bool );
|
|
|
|
void setXml( const TQDomElement &xml );
|
|
|
|
|
|
|
|
int rtti() const { return RTTI; }
|
|
|
|
static const int RTTI = 1004; //smart playlist item
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
virtual void slotDoubleClicked();
|
|
|
|
virtual void slotPostRenameItem( const TQString newName );
|
|
|
|
virtual void showContextMenu( const TQPoint & );
|
|
|
|
|
|
|
|
private:
|
|
|
|
// for xml playlists, this member is computed on demand
|
|
|
|
TQString m_sqlForTags;
|
|
|
|
|
|
|
|
TQString m_title;
|
|
|
|
TQDomElement m_xml;
|
|
|
|
TQListViewItem *m_after;
|
|
|
|
bool m_dynamic;
|
|
|
|
|
|
|
|
// Build the query for a given xml object. If \p for expand is true,
|
|
|
|
// insert (*ExpandString*) as placeholders for childrens' filters
|
|
|
|
static TQString xmlToQuery( const TQDomElement &xml, bool forExpand = false );
|
|
|
|
};
|
|
|
|
|
|
|
|
//this class is used to store information of a playlist track
|
|
|
|
class TrackItemInfo
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
TrackItemInfo( const MetaBundle &mb );
|
|
|
|
~TrackItemInfo() {}
|
|
|
|
const KURL &url() const { return m_url; }
|
|
|
|
const TQString &album() const { return m_album; }
|
|
|
|
const TQString &artist() const { return m_artist; }
|
|
|
|
const TQString &title() const { return m_title; }
|
|
|
|
const int length() const { return m_length; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
KURL m_url;
|
|
|
|
TQString m_artist;
|
|
|
|
TQString m_album;
|
|
|
|
TQString m_title;
|
|
|
|
int m_length;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*!
|
|
|
|
@brief Implement a shoutcast playlist category
|
|
|
|
|
|
|
|
On open, download the shoutcast genre XML file.
|
|
|
|
|
|
|
|
Process the file and add each genre as a ShoutcastGenre
|
|
|
|
style PlaylistCategory
|
|
|
|
*/
|
|
|
|
class ShoutcastBrowser : public PlaylistCategory
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
|
|
|
ShoutcastBrowser( PlaylistCategory* parent );
|
|
|
|
void setOpen( bool open );
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
virtual void slotDoubleClicked();
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
void doneGenreDownload( TDEIO::Job *job, const KURL &from, const KURL &to, bool directory, bool renamed );
|
|
|
|
void jobFinished( TDEIO::Job *job );
|
|
|
|
void slotAnimation();
|
|
|
|
|
|
|
|
private:
|
|
|
|
bool m_downloading;
|
|
|
|
TDEIO::CopyJob *m_cj;
|
|
|
|
TQPixmap *m_loading1, *m_loading2; //icons for loading animation
|
|
|
|
TQTimer m_animationTimer;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*!
|
|
|
|
@brief Implement a shoutcast genre category
|
|
|
|
|
|
|
|
On open, download the shoutcast station list XML file.
|
|
|
|
|
|
|
|
Process the file and add each station as a StreamEntry
|
|
|
|
*/
|
|
|
|
class ShoutcastGenre : public PlaylistCategory
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
|
|
|
ShoutcastGenre( ShoutcastBrowser *browser, TQListViewItem *after, TQString genre );
|
|
|
|
void setOpen( bool open );
|
|
|
|
void appendAlternateGenre( TQString alternateGenre ) { m_alternateGenres << alternateGenre; }
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
virtual void slotDoubleClicked();
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
void doneListDownload( TDEIO::Job *job, const KURL &from, const KURL &to, bool directory, bool renamed );
|
|
|
|
void jobFinished( TDEIO::Job *job );
|
|
|
|
void slotAnimation();
|
|
|
|
|
|
|
|
private:
|
|
|
|
void startGenreDownload( TQString genre, TQString tmppath );
|
|
|
|
bool m_downloading;
|
|
|
|
TQString m_genre;
|
|
|
|
TQPixmap *m_loading1, *m_loading2; //icons for loading animation
|
|
|
|
TQTimer m_animationTimer;
|
|
|
|
TQStringList m_alternateGenres;
|
|
|
|
TQStringList m_stations;
|
|
|
|
int m_totalJobs;
|
|
|
|
int m_completedJobs;
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|