summaryrefslogtreecommitdiffstats
path: root/amarok/src/mediabrowser.h
blob: 2b8a9c389e5662aecd2b24afcf79ee9e4bad751d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
// (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 */