|
|
|
// (c) 2004 Christian Muehlhaeuser <chris@chris.de>
|
|
|
|
// (c) 2005 Martin Aumueller <aumuell@reserv.at>
|
|
|
|
// (c) 2005 Seb Ruiz <me@sebruiz.net>
|
|
|
|
// (c) 2006 T.R.Shashwath <trshash84@gmail.com>
|
|
|
|
// See COPYING file for licensing information
|
|
|
|
|
|
|
|
#ifndef AMAROK_MEDIABROWSER_H
|
|
|
|
#define AMAROK_MEDIABROWSER_H
|
|
|
|
|
|
|
|
#include "amarok.h"
|
|
|
|
#include "amarok_export.h"
|
|
|
|
#include "browserToolBar.h"
|
|
|
|
#include "medium.h"
|
|
|
|
#include "multitabbar.h" //baseclass
|
|
|
|
#include "plugin/plugin.h" //baseclass
|
|
|
|
#include "pluginmanager.h"
|
|
|
|
|
|
|
|
#include <tqmutex.h>
|
|
|
|
#include <tqvbox.h> //baseclass
|
|
|
|
#include <tqdatetime.h>
|
|
|
|
|
|
|
|
#include <tdelistview.h> //baseclass
|
|
|
|
#include <kurl.h> //stack allocated
|
|
|
|
#include <tdeio/global.h> //filesize_t
|
|
|
|
#include "scrobbler.h" //SubmitItem
|
|
|
|
#include "metabundle.h"
|
|
|
|
|
|
|
|
class MediaBrowser;
|
|
|
|
class MediaDevice;
|
|
|
|
class MediaItemTip;
|
|
|
|
class MediaView;
|
|
|
|
class SpaceLabel;
|
|
|
|
class TransferDialog;
|
|
|
|
|
|
|
|
class TDEAction;
|
|
|
|
class KComboBox;
|
|
|
|
class KDialogBase;
|
|
|
|
class KProgress;
|
|
|
|
class KPushButton;
|
|
|
|
class KShellProcess;
|
|
|
|
|
|
|
|
class TQDragObject;
|
|
|
|
class TQLabel;
|
|
|
|
class TQPalette;
|
|
|
|
|
|
|
|
class LIBAMAROK_EXPORT MediaItem : public TDEListViewItem
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
MediaItem( TQListView* parent );
|
|
|
|
MediaItem( TQListViewItem* parent );
|
|
|
|
MediaItem( TQListView* parent, TQListViewItem* after );
|
|
|
|
MediaItem( TQListViewItem* parent, TQListViewItem* after );
|
|
|
|
void init();
|
|
|
|
virtual ~MediaItem();
|
|
|
|
|
|
|
|
MediaItem *lastChild() const;
|
|
|
|
|
|
|
|
virtual KURL url() const;
|
|
|
|
const MetaBundle *bundle() const;
|
|
|
|
void setBundle( MetaBundle *bundle );
|
|
|
|
|
|
|
|
enum Type { UNKNOWN, ARTIST, ALBUM, TRACK, PODCASTSROOT, PODCASTCHANNEL,
|
|
|
|
PODCASTITEM, PLAYLISTSROOT, PLAYLIST, PLAYLISTITEM, INVISIBLEROOT,
|
|
|
|
INVISIBLE, STALEROOT, STALE, ORPHANEDROOT, ORPHANED, DIRECTORY };
|
|
|
|
|
|
|
|
enum Flags { Failed=1, BeginTransfer=2, StopTransfer=4, Transferring=8, SmartPlaylist=16 };
|
|
|
|
|
|
|
|
void setType( Type type );
|
|
|
|
void setFailed( bool failed=true );
|
|
|
|
Type type() const { return m_type; }
|
|
|
|
MediaItem *findItem(const TQString &key, const MediaItem *after=0) const;
|
|
|
|
const TQString &data() const { return m_data; }
|
|
|
|
void setData( const TQString &data ) { m_data = data; }
|
|
|
|
|
|
|
|
virtual bool isLeafItem() const; // A leaf node of the tree
|
|
|
|
virtual bool isFileBacked() const; // Should the file be deleted of the device when removed
|
|
|
|
virtual TQDateTime playTime() const { return TQDateTime(); }
|
|
|
|
virtual int played() const { return 0; }
|
|
|
|
virtual int recentlyPlayed() const { return 0; } // no of times played on device since last sync
|
|
|
|
virtual void setPlayCount( int ) {}
|
|
|
|
virtual int rating() const { return 0; } // rating on device, normalized to 100
|
|
|
|
virtual void setRating( int /*rating*/ ) {}
|
|
|
|
virtual bool ratingChanged() const { return false; }
|
|
|
|
virtual void setLastPlayed( uint ) {}
|
|
|
|
virtual void syncStatsFromPath( const TQString &path );
|
|
|
|
virtual long size() const;
|
|
|
|
virtual MediaDevice *device() const { return m_device; }
|
|
|
|
virtual bool listened() const { return m_listened; }
|
|
|
|
virtual void setListened( bool listened=true ) { m_listened = listened; }
|
|
|
|
|
|
|
|
int compare( TQListViewItem *i, int col, bool ascending ) const;
|
|
|
|
int flags() const { return m_flags; }
|
|
|
|
|
|
|
|
void paintCell( TQPainter *p, const TQColorGroup &cg, int column, int width, int align );
|
|
|
|
|
|
|
|
//attributes:
|
|
|
|
int m_order;
|
|
|
|
Type m_type;
|
|
|
|
TQString m_playlistName;
|
|
|
|
TQString m_data;
|
|
|
|
MediaDevice *m_device;
|
|
|
|
int m_flags;
|
|
|
|
bool m_listened;
|
|
|
|
|
|
|
|
static TQPixmap *s_pixUnknown;
|
|
|
|
static TQPixmap *s_pixRootItem;
|
|
|
|
static TQPixmap *s_pixFile;
|
|
|
|
static TQPixmap *s_pixArtist;
|
|
|
|
static TQPixmap *s_pixAlbum;
|
|
|
|
static TQPixmap *s_pixPlaylist;
|
|
|
|
static TQPixmap *s_pixPodcast;
|
|
|
|
static TQPixmap *s_pixTrack;
|
|
|
|
static TQPixmap *s_pixInvisible;
|
|
|
|
static TQPixmap *s_pixStale;
|
|
|
|
static TQPixmap *s_pixOrphaned;
|
|
|
|
static TQPixmap *s_pixDirectory;
|
|
|
|
static TQPixmap *s_pixTransferFailed;
|
|
|
|
static TQPixmap *s_pixTransferBegin;
|
|
|
|
static TQPixmap *s_pixTransferEnd;
|
|
|
|
|
|
|
|
private:
|
|
|
|
mutable MetaBundle *m_bundle;
|
|
|
|
};
|
|
|
|
|
|
|
|
class MediaQueue : public TDEListView, public DropProxyTarget
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
MediaQueue(MediaBrowser *parent);
|
|
|
|
MediaItem *findPath( TQString path );
|
|
|
|
|
|
|
|
TDEIO::filesize_t totalSize() const; // total size of items to transfer in KB
|
|
|
|
void computeSize() const; // compute total size of items to transfer in KB
|
|
|
|
void addItemToSize( const MediaItem *item ) const;
|
|
|
|
void subtractItemFromSize( const MediaItem *item, bool unconditonally=false ) const;
|
|
|
|
|
|
|
|
void removeSelected();
|
|
|
|
void clearItems();
|
|
|
|
|
|
|
|
void load( const TQString &path );
|
|
|
|
void save( const TQString &path );
|
|
|
|
void syncPlaylist( const TQString &playlistName, const TQString &sql, bool loading=false );
|
|
|
|
void syncPlaylist( const TQString &playlistName, const KURL &url, bool loading=false );
|
|
|
|
void addURL( const KURL& url, MetaBundle *bundle=NULL, const TQString &playlistName=TQString() );
|
|
|
|
LIBAMAROK_EXPORT void addURL( const KURL& url, MediaItem *item );
|
|
|
|
void addURLs( const KURL::List urls, const TQString &playlistName=TQString() );
|
|
|
|
|
|
|
|
void URLsAdded(); // call after finishing adding single urls
|
|
|
|
|
|
|
|
void dropProxyEvent( TQDropEvent *e );
|
|
|
|
// Reimplemented from TDEListView
|
|
|
|
bool acceptDrag( TQDropEvent *e ) const;
|
|
|
|
TQDragObject *dragObject();
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
void itemCountChanged();
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
void selectAll() {TQListView::selectAll(true); }
|
|
|
|
void slotShowContextMenu( TQListViewItem* item, const TQPoint& point, int );
|
|
|
|
void slotDropped (TQDropEvent* e, TQListViewItem* parent, TQListViewItem* after);
|
|
|
|
|
|
|
|
private:
|
|
|
|
void keyPressEvent( TQKeyEvent *e );
|
|
|
|
MediaBrowser *m_parent;
|
|
|
|
mutable TDEIO::filesize_t m_totalSize;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class LIBAMAROK_EXPORT MediaBrowser : public TQVBox
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
friend class DeviceConfigureDialog;
|
|
|
|
friend class MediaDevice;
|
|
|
|
friend class MediaView;
|
|
|
|
friend class MediaQueue;
|
|
|
|
friend class MediumPluginChooser;
|
|
|
|
friend class MediaItem;
|
|
|
|
|
|
|
|
public:
|
|
|
|
enum { CONNECT, DISCONNECT, TRANSFER, CONFIGURE, CUSTOM };
|
|
|
|
|
|
|
|
static bool isAvailable();
|
|
|
|
static MediaBrowser *instance() { return s_instance; }
|
|
|
|
static MediaQueue *queue() { return s_instance ? s_instance->m_queue : 0; }
|
|
|
|
|
|
|
|
MediaBrowser( const char *name );
|
|
|
|
virtual ~MediaBrowser();
|
|
|
|
bool blockQuit() const;
|
|
|
|
MediaDevice *currentDevice() const;
|
|
|
|
MediaDevice *deviceFromId( const TQString &id ) const;
|
|
|
|
TQStringList deviceNames() const;
|
|
|
|
bool deviceSwitch( const TQString &name );
|
|
|
|
|
|
|
|
TQString getInternalPluginName ( const TQString string ) { return m_pluginName[string]; }
|
|
|
|
TQString getDisplayPluginName ( const TQString string ) { return m_pluginAmarokName[string]; }
|
|
|
|
const TDETrader::OfferList &getPlugins() { return m_plugins; }
|
|
|
|
void transcodingFinished( const TQString &src, const TQString &dst );
|
|
|
|
bool isTranscoding() const { return m_waitForTranscode; }
|
|
|
|
void updateStats();
|
|
|
|
void updateButtons();
|
|
|
|
void updateDevices();
|
|
|
|
// return bundle for url if it is known to MediaBrowser
|
|
|
|
bool getBundle( const KURL &url, MetaBundle *bundle ) const;
|
|
|
|
bool isQuitting() const { return m_quitting; }
|
|
|
|
|
|
|
|
KURL getProxyUrl( const KURL& daapUrl ) const;
|
|
|
|
TDEToolBar* getToolBar() const { return m_toolbar; }
|
|
|
|
|
|
|
|
signals:
|
|
|
|
void availabilityChanged( bool isAvailable );
|
|
|
|
|
|
|
|
protected slots:
|
|
|
|
void transferClicked();
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
void slotSetFilterTimeout();
|
|
|
|
void slotSetFilter();
|
|
|
|
void slotSetFilter( const TQString &filter );
|
|
|
|
void slotEditFilter();
|
|
|
|
void mediumAdded( const Medium *, TQString , bool constructing = false);
|
|
|
|
void mediumChanged( const Medium *, TQString );
|
|
|
|
void mediumRemoved( const Medium *, TQString );
|
|
|
|
void activateDevice( const MediaDevice *device );
|
|
|
|
void activateDevice( int index, bool skipDummy = true );
|
|
|
|
void pluginSelected( const Medium *, const TQString );
|
|
|
|
void showPluginManager();
|
|
|
|
void cancelClicked();
|
|
|
|
void connectClicked();
|
|
|
|
void disconnectClicked();
|
|
|
|
void customClicked();
|
|
|
|
void configSelectPlugin( int index );
|
|
|
|
bool config(); // false if canceled by user
|
|
|
|
KURL transcode( const KURL &src, const TQString &filetype );
|
|
|
|
void tagsChanged( const MetaBundle &bundle );
|
|
|
|
void prepareToQuit();
|
|
|
|
|
|
|
|
private:
|
|
|
|
MediaDevice *loadDevicePlugin( const TQString &deviceName );
|
|
|
|
void unloadDevicePlugin( MediaDevice *device );
|
|
|
|
|
|
|
|
KLineEdit* m_searchEdit;
|
|
|
|
TQTimer *m_timer;
|
|
|
|
static MediaBrowser *s_instance;
|
|
|
|
|
|
|
|
TQValueList<MediaDevice *> m_devices;
|
|
|
|
TQValueList<MediaDevice *>::iterator m_currentDevice;
|
|
|
|
|
|
|
|
TQMap<TQString, TQString> m_pluginName;
|
|
|
|
TQMap<TQString, TQString> m_pluginAmarokName;
|
|
|
|
void addDevice( MediaDevice *device );
|
|
|
|
void removeDevice( MediaDevice *device );
|
|
|
|
|
|
|
|
MediaQueue* m_queue;
|
|
|
|
bool m_waitForTranscode;
|
|
|
|
KURL m_transcodedUrl;
|
|
|
|
TQString m_transcodeSrc;
|
|
|
|
|
|
|
|
SpaceLabel* m_stats;
|
|
|
|
TQHBox* m_progressBox;
|
|
|
|
KProgress* m_progress;
|
|
|
|
TQVBox* m_views;
|
|
|
|
KPushButton* m_cancelButton;
|
|
|
|
//KPushButton* m_playlistButton;
|
|
|
|
TQVBox* m_configBox;
|
|
|
|
KComboBox* m_configPluginCombo;
|
|
|
|
KComboBox* m_deviceCombo;
|
|
|
|
Browser::ToolBar*m_toolbar;
|
|
|
|
typedef TQMap<TQString, MediaItem*> ItemMap;
|
|
|
|
mutable TQMutex m_itemMapMutex;
|
|
|
|
ItemMap m_itemMap;
|
|
|
|
TDETrader::OfferList m_plugins;
|
|
|
|
bool m_haveDevices;
|
|
|
|
bool m_quitting;
|
|
|
|
};
|
|
|
|
|
|
|
|
class MediaView : public TDEListView
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
friend class MediaBrowser;
|
|
|
|
friend class MediaDevice;
|
|
|
|
|
|
|
|
public:
|
|
|
|
enum Flags
|
|
|
|
{
|
|
|
|
None = 0,
|
|
|
|
OnlySelected = 1,
|
|
|
|
OnlyPlayed = 2
|
|
|
|
};
|
|
|
|
|
|
|
|
MediaView( TQWidget *parent, MediaDevice *device );
|
|
|
|
virtual ~MediaView();
|
|
|
|
LIBAMAROK_EXPORT KURL::List nodeBuildDragList( MediaItem* item, int flags=OnlySelected );
|
|
|
|
LIBAMAROK_EXPORT int getSelectedLeaves(MediaItem *parent, TQPtrList<MediaItem> *list, int flags=OnlySelected );
|
|
|
|
LIBAMAROK_EXPORT MediaItem *newDirectory( MediaItem* parent );
|
|
|
|
bool setFilter( const TQString &filter, MediaItem *parent=NULL );
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
void rmbPressed( TQListViewItem*, const TQPoint&, int );
|
|
|
|
void renameItem( TQListViewItem *item );
|
|
|
|
void slotExpand( TQListViewItem* );
|
|
|
|
void selectAll() { TQListView::selectAll(true); }
|
|
|
|
void invokeItem( TQListViewItem*, const TQPoint &, int column );
|
|
|
|
void invokeItem( TQListViewItem* );
|
|
|
|
|
|
|
|
private:
|
|
|
|
void keyPressEvent( TQKeyEvent *e );
|
|
|
|
// Reimplemented from TDEListView
|
|
|
|
void contentsDropEvent( TQDropEvent *e );
|
|
|
|
void viewportPaintEvent( TQPaintEvent* );
|
|
|
|
bool acceptDrag( TQDropEvent *e ) const;
|
|
|
|
TQDragObject *dragObject();
|
|
|
|
|
|
|
|
TQWidget *m_parent;
|
|
|
|
MediaDevice *m_device;
|
|
|
|
MediaItemTip *m_toolTip;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* at least the pure virtual functions have to be implemented by a media device,
|
|
|
|
all items are stored in a hierarchy of MediaItems,
|
|
|
|
when items are manipulated the MediaItems have to be updated accordingly */
|
|
|
|
|
|
|
|
class LIBAMAROK_EXPORT MediaDevice : public TQObject, public Amarok::Plugin
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
friend class DeviceConfigureDialog;
|
|
|
|
friend class TransferDialog;
|
|
|
|
friend class MediaBrowser;
|
|
|
|
friend class MediaView;
|
|
|
|
friend class MediaQueue;
|
|
|
|
|
|
|
|
public:
|
|
|
|
enum Flags
|
|
|
|
{
|
|
|
|
None = 0,
|
|
|
|
OnlyPlayed = 1,
|
|
|
|
DeleteTrack = 2,
|
|
|
|
Recursing = 4
|
|
|
|
};
|
|
|
|
|
|
|
|
MediaDevice();
|
|
|
|
virtual void init( MediaBrowser* parent );
|
|
|
|
virtual ~MediaDevice();
|
|
|
|
|
|
|
|
MediaView *view();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @retrun a TDEAction that will be plugged into the media device browser toolbar
|
|
|
|
*/
|
|
|
|
virtual TDEAction *customAction() { return 0; }
|
|
|
|
|
|
|
|
virtual void rmbPressed( TQListViewItem *item, const TQPoint &point, int ) { (void)item; (void) point; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return list of filetypes playable on this device
|
|
|
|
* (empty list is interpreted as all types are good)
|
|
|
|
*/
|
|
|
|
virtual TQStringList supportedFiletypes() { return TQStringList(); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param bundle describes track that should be checked
|
|
|
|
* @return true if the device is capable of playing the track referred to by bundle
|
|
|
|
*/
|
|
|
|
virtual bool isPlayable( const MetaBundle &bundle );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param bundle describes track that should be checked
|
|
|
|
* @return true if the track is in the preferred (first in list) format of the device
|
|
|
|
*/
|
|
|
|
virtual bool isPreferredFormat( const MetaBundle &bundle );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return true if the device is connected
|
|
|
|
*/
|
|
|
|
virtual bool isConnected() = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Adds particular tracks to a playlist
|
|
|
|
* @param playlist parent playlist for tracks to be added to
|
|
|
|
* @param after insert following this item
|
|
|
|
* @param items tracks to add to playlist
|
|
|
|
*/
|
|
|
|
virtual void addToPlaylist(MediaItem *playlist, MediaItem *after, TQPtrList<MediaItem> items) { Q_UNUSED(playlist); Q_UNUSED(after); Q_UNUSED(items); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a new playlist
|
|
|
|
* @param name playlist title
|
|
|
|
* @param parent parent MediaItem of the new playlist
|
|
|
|
* @param items tracks to add to the new playlist
|
|
|
|
* @return the newly created playlist
|
|
|
|
*/
|
|
|
|
virtual MediaItem *newPlaylist(const TQString &name, MediaItem *parent, TQPtrList<MediaItem> items) { Q_UNUSED(name); Q_UNUSED(parent); Q_UNUSED(items); return 0; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Move items to a directory
|
|
|
|
* @param directory new parent of dropped items
|
|
|
|
* @param items tracks to add to the directory
|
|
|
|
*/
|
|
|
|
virtual void addToDirectory( MediaItem *directory, TQPtrList<MediaItem> items ) { Q_UNUSED(directory); Q_UNUSED(items); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a new directory
|
|
|
|
* @param name directory title
|
|
|
|
* @param parent parent MediaItem of the new directory
|
|
|
|
* @param items tracks to add to the new directory
|
|
|
|
* @return the newly created directory
|
|
|
|
*/
|
|
|
|
virtual MediaItem *newDirectory( const TQString &name, MediaItem *parent ) { Q_UNUSED(name); Q_UNUSED(parent); return 0; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Notify device of changed tags
|
|
|
|
* @param item item to be updated
|
|
|
|
* @param changed bundle containing new tags
|
|
|
|
* @return the changed MediaItem
|
|
|
|
*/
|
|
|
|
virtual MediaItem *tagsChanged( MediaItem *item, const MetaBundle &changed ) { Q_UNUSED(item); Q_UNUSED(changed); return 0; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Indicate whether the device has a custom transfer dialog
|
|
|
|
* @return whether there is a custom dialog
|
|
|
|
*/
|
|
|
|
virtual bool hasTransferDialog() { return false; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Run the transfer dialog to be used when Transfer is clicked
|
|
|
|
*/
|
|
|
|
virtual void runTransferDialog() {}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the transfer dialog, if any
|
|
|
|
* @return the transfer dialog, if any, else NULL;
|
|
|
|
*/
|
|
|
|
virtual TransferDialog *getTransferDialog() { return NULL; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Can be used to explicitly indicate whether a device needs manual configuration
|
|
|
|
* @return whether manual configuration is needed
|
|
|
|
*/
|
|
|
|
virtual bool needsManualConfig() { return true; }
|
|
|
|
|
|
|
|
virtual void addConfigElements( TQWidget * /*parent*/ ) {}
|
|
|
|
virtual void removeConfigElements( TQWidget * /*parent*/ ) {}
|
|
|
|
virtual void applyConfig() {}
|
|
|
|
virtual void loadConfig();
|
|
|
|
|
|
|
|
TQString configString( const TQString &name, const TQString &defValue = TQString() );
|
|
|
|
void setConfigString( const TQString &name, const TQString &value );
|
|
|
|
bool configBool( const TQString &name, bool defValue=false );
|
|
|
|
void setConfigBool( const TQString &name, bool value );
|
|
|
|
|
|
|
|
void setRequireMount( const bool b ) { m_requireMount = b; }
|
|
|
|
bool hasMountPoint() { return m_hasMountPoint; }
|
|
|
|
void setDeviceType( const TQString &type ) { m_type = type; }
|
|
|
|
TQString deviceType() { return m_type; }
|
|
|
|
virtual bool autoConnect() { return false; }
|
|
|
|
virtual bool asynchronousTransfer() { return false; }
|
|
|
|
bool isTransferring() { return m_transferring; }
|
|
|
|
bool isDeleting() { return m_deleting; }
|
|
|
|
bool isCanceled() { return m_canceled; }
|
|
|
|
void setCanceled( const bool b ) { m_canceled = b; }
|
|
|
|
|
|
|
|
int progress() const;
|
|
|
|
void setProgress( const int progress, const int total = -1 /* leave total unchanged by default */ );
|
|
|
|
void hideProgress();
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return a unique identifier that is constant across sessions
|
|
|
|
*/
|
|
|
|
TQString uniqueId() const { return m_medium.id(); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return the name for the device that should be presented to the user
|
|
|
|
*/
|
|
|
|
TQString name() const { return m_name; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return the device node
|
|
|
|
*/
|
|
|
|
TQString deviceNode() const { return m_medium.deviceNode(); }
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @return the device mount point (or empty if non-applicable or unknown)
|
|
|
|
*/
|
|
|
|
TQString mountPoint() const { return m_medium.mountPoint(); }
|
|
|
|
|
|
|
|
TQString getTransferDir() { return m_transferDir; }
|
|
|
|
Medium &getMedium() { return m_medium; }
|
|
|
|
|
|
|
|
void setSpacesToUnderscores( bool yesno ) { m_spacesToUnderscores = yesno;
|
|
|
|
setConfigBool( "spacesToUnderscores", yesno); }
|
|
|
|
bool getSpacesToUnderscores() { return m_spacesToUnderscores; }
|
|
|
|
|
|
|
|
void setFirstSort( TQString text ) { m_firstSort = text;
|
|
|
|
setConfigString( "firstGrouping", text ); }
|
|
|
|
void setSecondSort( TQString text ) { m_secondSort = text;
|
|
|
|
setConfigString( "secondGrouping", text ); }
|
|
|
|
void setThirdSort( TQString text ) { m_thirdSort = text;
|
|
|
|
setConfigString( "thirdGrouping", text ); }
|
|
|
|
|
|
|
|
virtual KURL getProxyUrl( const KURL& /*url*/) { return KURL(); }
|
|
|
|
virtual void customClicked() { return; }
|
|
|
|
|
|
|
|
BundleList bundlesToSync( const TQString &playlistName, const TQString &sql );
|
|
|
|
BundleList bundlesToSync( const TQString &playlistName, const KURL &url );
|
|
|
|
void preparePlaylistForSync( const TQString &playlistName, const BundleList &bundles );
|
|
|
|
bool isOnOtherPlaylist( const TQString &playlistToAvoid, const MetaBundle &bundle );
|
|
|
|
bool isOnPlaylist( const MediaItem &playlist, const MetaBundle &bundle );
|
|
|
|
bool isInBundleList( const BundleList &bundles, const MetaBundle &bundle );
|
|
|
|
bool bundleMatch( const MetaBundle &b1, const MetaBundle &b2 );
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
void abortTransfer();
|
|
|
|
void transferFiles();
|
|
|
|
virtual void renameItem( TQListViewItem *item ) {(void)item; }
|
|
|
|
virtual void expandItem( TQListViewItem *item ) {(void)item; }
|
|
|
|
bool connectDevice( bool silent=false );
|
|
|
|
bool disconnectDevice( bool postdisconnecthook=true );
|
|
|
|
void scheduleDisconnect() { m_scheduledDisconnect = true; }
|
|
|
|
|
|
|
|
protected slots:
|
|
|
|
void fileTransferred( TDEIO::Job *job );
|
|
|
|
void fileTransferFinished();
|
|
|
|
|
|
|
|
private:
|
|
|
|
int sysCall(const TQString & command);
|
|
|
|
int runPreConnectCommand();
|
|
|
|
int runPostDisconnectCommand();
|
|
|
|
TQString replaceVariables( const TQString &cmd ); // replace %m with mount point and %d with device node
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Find a particular track
|
|
|
|
* @param bundle The metabundle of the requested media item
|
|
|
|
* @return The MediaItem of the item if found, otherwise NULL
|
|
|
|
* @note This may not be worth implementing for non database driven devices, as it could be slow
|
|
|
|
*/
|
|
|
|
virtual MediaItem *trackExists( const MetaBundle& bundle ) = 0;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
/**
|
|
|
|
* Get the capacity and freespace available on the device, in bytes
|
|
|
|
* @return true if successful
|
|
|
|
*/
|
|
|
|
virtual bool getCapacity( TDEIO::filesize_t *total, TDEIO::filesize_t *available ) { Q_UNUSED(total); Q_UNUSED(available); return false; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Lock device for exclusive access if possible
|
|
|
|
*/
|
|
|
|
virtual bool lockDevice( bool tryOnly = false ) = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Unlock device
|
|
|
|
*/
|
|
|
|
virtual void unlockDevice() = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Connect to device, and populate m_view with MediaItems
|
|
|
|
* @return true if successful
|
|
|
|
*/
|
|
|
|
virtual bool openDevice( bool silent=false ) = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Wrap up any loose ends and close the device
|
|
|
|
* @return true if successful
|
|
|
|
*/
|
|
|
|
virtual bool closeDevice() = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Write any pending changes to the device, such as database changes
|
|
|
|
*/
|
|
|
|
virtual void synchronizeDevice() = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Copy a track to the device
|
|
|
|
* @param bundle The MetaBundle of the item to transfer. Will move the item specified by bundle().url().path()
|
|
|
|
* @return If successful, the created MediaItem in the media device view, else 0
|
|
|
|
*/
|
|
|
|
virtual MediaItem *copyTrackToDevice(const MetaBundle& bundle) = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Copy track from device to computer
|
|
|
|
* @param item The MediaItem of the track to transfer.
|
|
|
|
* @param url The URL to transfer the track to.
|
|
|
|
* @return The MediaItem transfered.
|
|
|
|
*/
|
|
|
|
virtual void copyTrackFromDevice(MediaItem *item);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Recursively remove MediaItem from the tracklist and the device
|
|
|
|
* @param item MediaItem to remove
|
|
|
|
* @param onlyPlayed True if item should be deleted only if it has been played
|
|
|
|
* @return -1 on failure, number of files deleted otherwise
|
|
|
|
*/
|
|
|
|
virtual int deleteItemFromDevice( MediaItem *item, int flags=DeleteTrack ) = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Abort the currently active track transfer
|
|
|
|
*/
|
|
|
|
virtual void cancelTransfer() { /* often checking m_cancel is enough */ }
|
|
|
|
|
|
|
|
virtual void updateRootItems();
|
|
|
|
|
|
|
|
virtual bool isSpecialItem( MediaItem *item );
|
|
|
|
|
|
|
|
int deleteFromDevice( MediaItem *item=0, int flags=DeleteTrack );
|
|
|
|
|
|
|
|
void purgeEmptyItems( MediaItem *root=0 );
|
|
|
|
void syncStatsFromDevice( MediaItem *root=0 );
|
|
|
|
void syncStatsToDevice( MediaItem *root=0 );
|
|
|
|
|
|
|
|
bool kioCopyTrack( const KURL &src, const KURL &dst );
|
|
|
|
|
|
|
|
TQString m_name;
|
|
|
|
|
|
|
|
bool m_hasMountPoint;
|
|
|
|
|
|
|
|
TQString m_preconnectcmd;
|
|
|
|
TQString m_postdisconnectcmd;
|
|
|
|
bool m_autoDeletePodcasts;
|
|
|
|
bool m_syncStats;
|
|
|
|
|
|
|
|
bool m_transcode;
|
|
|
|
bool m_transcodeAlways;
|
|
|
|
bool m_transcodeRemove;
|
|
|
|
|
|
|
|
KShellProcess *sysProc;
|
|
|
|
MediaBrowser *m_parent;
|
|
|
|
MediaView *m_view;
|
|
|
|
Medium m_medium;
|
|
|
|
TQString m_transferDir;
|
|
|
|
TQString m_firstSort;
|
|
|
|
TQString m_secondSort;
|
|
|
|
TQString m_thirdSort;
|
|
|
|
bool m_wait;
|
|
|
|
bool m_waitForDeletion;
|
|
|
|
bool m_copyFailed;
|
|
|
|
bool m_requireMount;
|
|
|
|
bool m_canceled;
|
|
|
|
bool m_transferring;
|
|
|
|
bool m_deleting;
|
|
|
|
bool m_deferredDisconnect;
|
|
|
|
bool m_scheduledDisconnect;
|
|
|
|
bool m_runDisconnectHook;
|
|
|
|
bool m_spacesToUnderscores;
|
|
|
|
bool m_transfer;
|
|
|
|
bool m_configure;
|
|
|
|
bool m_customButton;
|
|
|
|
|
|
|
|
TQString m_type;
|
|
|
|
|
|
|
|
// root listview items
|
|
|
|
MediaItem *m_playlistItem;
|
|
|
|
MediaItem *m_podcastItem;
|
|
|
|
// items not on the master playlist and not on the podcast playlist are not visible on the ipod
|
|
|
|
MediaItem *m_invisibleItem;
|
|
|
|
// items in the database for which the file is missing
|
|
|
|
MediaItem *m_staleItem;
|
|
|
|
// files without database entry
|
|
|
|
MediaItem *m_orphanedItem;
|
|
|
|
|
|
|
|
// stow away all items below m_rootItems when device is not current
|
|
|
|
TQPtrList<TQListViewItem> m_rootItems;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#endif /* AMAROK_MEDIABROWSER_H */
|