|
|
|
// Author: Max Howell (C) Copyright 2003-4
|
|
|
|
// Author: Mark Kretschmann (C) Copyright 2004
|
|
|
|
// Copyright: See COPYING file that comes with this distribution
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef UrlLoader_H
|
|
|
|
#define UrlLoader_H
|
|
|
|
|
|
|
|
#include "amarok.h"
|
|
|
|
#include "debug.h" //stack allocated
|
|
|
|
#include <tqptrlist.h>
|
|
|
|
#include <tqxml.h> //baseclass
|
|
|
|
#include <kurl.h> //KURL::List
|
|
|
|
#include "metabundle.h" //stack allocated
|
|
|
|
#include "threadmanager.h" //baseclass
|
|
|
|
#include "xmlloader.h" //baseclass
|
|
|
|
|
|
|
|
class TQListViewItem;
|
|
|
|
class TQTextStream;
|
|
|
|
class PlaylistItem;
|
|
|
|
class PLItemList;
|
|
|
|
class XMLData;
|
|
|
|
|
|
|
|
namespace TDEIO { class Job; }
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @class PlaylistFile
|
|
|
|
* @author Max Howell
|
|
|
|
* @short Allocate on the stack, the contents are immediately available from bundles()
|
|
|
|
*
|
|
|
|
* Note, it won't do anything with XML playlists
|
|
|
|
*
|
|
|
|
* TODO be able to load directories too, it's in the spec
|
|
|
|
* TODO and playlists within playlists, remote and local
|
|
|
|
*/
|
|
|
|
class PlaylistFile
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
PlaylistFile( const TQString &path );
|
|
|
|
|
|
|
|
enum Format { M3U, PLS, XML, RAM, SMIL, ASX, XSPF, Unknown, NotPlaylist = Unknown };
|
|
|
|
|
|
|
|
/// the bundles from this playlist, they only contain
|
|
|
|
/// the information that can be extracted from the playlists
|
|
|
|
BundleList &bundles() { return m_bundles; }
|
|
|
|
|
|
|
|
/// the name of the playlist. often stored in the document (eg xspf) or derived from the filename
|
|
|
|
TQString &title() { return m_title; }
|
|
|
|
|
|
|
|
///@return true if couldn't load the playlist's contents
|
|
|
|
bool isError() const { return !m_error.isEmpty(); }
|
|
|
|
|
|
|
|
/// if start returns false this has a translated error description
|
|
|
|
TQString error() const { return m_error; }
|
|
|
|
|
|
|
|
|
|
|
|
static inline bool isPlaylistFile( const KURL &url ) { return isPlaylistFile( url.fileName() ); }
|
|
|
|
static inline bool isPlaylistFile( const TQString &fileName ) { return format( fileName ) != Unknown; }
|
|
|
|
static inline Format format( const TQString &fileName );
|
|
|
|
static TQTime stringToTime(const TQString&);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
/// make these virtual if you need to
|
|
|
|
bool loadM3u( TQTextStream& );
|
|
|
|
bool loadPls( TQTextStream& );
|
|
|
|
unsigned int loadPls_extractIndex( const TQString &str ) const;
|
|
|
|
bool loadRealAudioRam( TQTextStream& );
|
|
|
|
bool loadASX( TQTextStream& );
|
|
|
|
bool loadSMIL( TQTextStream& );
|
|
|
|
bool loadXSPF( TQTextStream& );
|
|
|
|
TQString m_path;
|
|
|
|
TQString m_error;
|
|
|
|
BundleList m_bundles;
|
|
|
|
TQString m_title;
|
|
|
|
};
|
|
|
|
|
|
|
|
inline PlaylistFile::Format
|
|
|
|
PlaylistFile::format( const TQString &fileName )
|
|
|
|
{
|
|
|
|
const TQString ext = Amarok::extension( fileName );
|
|
|
|
|
|
|
|
if( ext == "m3u" ) return M3U;
|
|
|
|
if( ext == "pls" ) return PLS;
|
|
|
|
if( ext == "ram" ) return RAM;
|
|
|
|
if( ext == "smil") return SMIL;
|
|
|
|
if( ext == "asx" || ext == "wax" ) return ASX;
|
|
|
|
if( ext == "xml" ) return XML;
|
|
|
|
if( ext == "xspf" ) return XSPF;
|
|
|
|
|
|
|
|
return Unknown;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @author Max Howell
|
|
|
|
* @author Mark Kretschmann
|
|
|
|
* @short Populates the Playlist-view with URLs
|
|
|
|
*
|
|
|
|
* + Load playlists, remote and local
|
|
|
|
* + List directories, remote and local
|
|
|
|
* + Read tags, from file:/// and from DB
|
|
|
|
*/
|
|
|
|
#ifdef Q_MOC_RUN
|
|
|
|
// MOC_SKIP_BEGIN
|
|
|
|
class UrlLoader : public JobBase
|
|
|
|
// MOC_SKIP_END
|
|
|
|
#else // Q_MOC_RUN
|
|
|
|
class UrlLoader : public ThreadManager::DependentJob
|
|
|
|
#endif // Q_MOC_RUN
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
UrlLoader( const KURL::List&, TQListViewItem*, int options = 0 );
|
|
|
|
~UrlLoader();
|
|
|
|
|
|
|
|
static const uint OPTIMUM_BUNDLE_COUNT = 200;
|
|
|
|
|
|
|
|
signals:
|
|
|
|
void queueChanged( const PLItemList &, const PLItemList & );
|
|
|
|
|
|
|
|
protected:
|
|
|
|
/// reimplemented from ThreadManager::Job
|
|
|
|
virtual bool doJob();
|
|
|
|
virtual void completeJob();
|
|
|
|
virtual void customEvent( TQCustomEvent* );
|
|
|
|
|
|
|
|
void loadXml( const KURL& );
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
void slotNewBundle( const MetaBundle &bundle, const XmlAttributeList &attributes );
|
|
|
|
void slotPlaylistInfo( const TQString &product, const TQString &version, const TQString &dynamicMode );
|
|
|
|
|
|
|
|
private:
|
|
|
|
KURL::List recurse( const KURL& );
|
|
|
|
|
|
|
|
private:
|
|
|
|
KURL::List m_badURLs;
|
|
|
|
KURL::List m_URLs;
|
|
|
|
PlaylistItem *m_markerListViewItem;
|
|
|
|
bool m_playFirstUrl;
|
|
|
|
bool m_coloring;
|
|
|
|
int m_options;
|
|
|
|
Debug::Block m_block;
|
|
|
|
TQPtrList<PlaylistItem> m_oldQueue;
|
|
|
|
TQXmlInputSource *m_xmlSource;
|
|
|
|
TQValueList<XMLData> m_xml;
|
|
|
|
KURL m_currentURL;
|
|
|
|
TQString m_dynamicMode;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
UrlLoader( const UrlLoader& ); //undefined
|
|
|
|
UrlLoader &operator=( const UrlLoader& ); //undefined
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @author Max Howell
|
|
|
|
* @short Populates the Playlist-view using the result of a single SQL query
|
|
|
|
*
|
|
|
|
* The format of the query must be in a set order, see doJob()
|
|
|
|
*/
|
|
|
|
class SqlLoader : public UrlLoader
|
|
|
|
{
|
|
|
|
const TQString m_sql;
|
|
|
|
|
|
|
|
public:
|
|
|
|
SqlLoader( const TQString &sql, TQListViewItem *after, int options = 0 );
|
|
|
|
|
|
|
|
virtual bool doJob();
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @author Max Howell
|
|
|
|
* @short Fetches a playlist-file from any location, and then loads it into the Playlist-view
|
|
|
|
*/
|
|
|
|
class RemotePlaylistFetcher : public TQObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
|
|
const KURL m_source;
|
|
|
|
KURL m_destination;
|
|
|
|
TQListViewItem *m_after;
|
|
|
|
bool m_playFirstUrl;
|
|
|
|
int m_options;
|
|
|
|
class KTempFile *m_temp;
|
|
|
|
|
|
|
|
public:
|
|
|
|
RemotePlaylistFetcher( const KURL &source, TQListViewItem *after, int options = 0 );
|
|
|
|
~RemotePlaylistFetcher();
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
void result( TDEIO::Job* );
|
|
|
|
void abort() { delete this; }
|
|
|
|
};
|
|
|
|
|
|
|
|
// PRIVATE -- should be in the .cpp, but moc.
|
|
|
|
|
|
|
|
class MyXmlLoader: public MetaBundle::XmlLoader
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
|
|
|
MyXmlLoader() { }
|
|
|
|
virtual bool startElement( const TQString&, const TQString&, const TQString &, const TQXmlAttributes& );
|
|
|
|
signals:
|
|
|
|
void playlistInfo( const TQString &product, const TQString &version, const TQString &dynamicMode );
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#endif
|