/*************************************************************************** * copyright : (c) 2004 Pierpaolo Di Panfilo * * (c) 2004 Mark Kretschmann * * (c) 2005-2006 Seb Ruiz * * (c) 2005 Gábor Lehel * * (c) 2006 Adam Pigg * * See COPYING file for licensing information * ***************************************************************************/ #ifndef PLAYLISTBROWSER_H #define PLAYLISTBROWSER_H #include "amarokconfig.h" #include "playlistbrowseritem.h" #include "podcastsettings.h" #include #include #include #include #include #include #include class KTextBrowser; class KToolBar; class TQCustomEvent; class TQColorGroup; class TQDragObject; class TQPainter; class TQPixmap; class TQPoint; class TQSplitter; class TQTimer; class HTMLView; class InfoPane; class PlaylistBrowserView; class PlaylistTrackItem; class PlaylistBrowser : public TQVBox { Q_OBJECT TQ_OBJECT friend class DynamicMode; friend class PlaylistBrowserView; friend class PlaylistBrowserEntry; friend class PlaylistCategory; friend class PlaylistEntry; friend class PlaylistTrackItem; friend class PodcastChannel; //for changing podcast timer list friend class PodcastEpisode; friend class DynamicEntry; friend class StreamEntry; friend class SmartPlaylist; public: enum AddMode { PLAYLIST, PLAYLIST_IMPORT, STREAM, SMARTPLAYLIST, PODCAST, ADDDYNAMIC }; ~PlaylistBrowser(); void setInfo( const TQString &title, const TQString &info ); void addStream( TQListViewItem *parent = 0 ); void addSmartPlaylist( TQListViewItem *parent = 0 ); void addDynamic( TQListViewItem *parent = 0 ); void addPlaylist( const TQString &path, TQListViewItem *parent = 0, bool force=false, bool imported=false ); PlaylistEntry *findPlaylistEntry( const TQString &url, TQListViewItem *parent=0 ) const; int loadPlaylist( const TQString &playlist, bool force=false ); void addPodcast( TQListViewItem *parent = 0 ); void addPodcast( const KURL &url, TQListViewItem *parent = 0 ); void loadPodcastsFromDatabase( PlaylistCategory *p = 0 ); void registerPodcastSettings( const TQString &title, const PodcastSettings *settings ); static bool savePlaylist( const TQString &path, const TQValueList &urls, const TQValueList &titles = TQValueList(), const TQValueList &lengths = TQValueList(), bool relative = AmarokConfig::relativePlaylist() ); TQString dynamicBrowserCache() const; TQString playlistBrowserCache() const; TQString podcastBrowserCache() const; TQString streamBrowserCache() const; TQString smartplaylistBrowserCache() const; PlaylistBrowserEntry *findItem( TQString &t, int c ) const; TQListViewItem *findItemInTree( const TQString &searchstring, int c ) const; PodcastEpisode *findPodcastEpisode( const KURL &episode, const KURL &feed ) const; TQPtrList dynamicEntries() const { return m_dynamicEntries; } DynamicMode *findDynamicModeByTitle( const TQString &title ); TQListViewItem *podcastCategory() const { return m_podcastCategory; } static PlaylistBrowser *instance() { if(!s_instance) s_instance = new PlaylistBrowser("PlaylistBrowser"); return s_instance; } //following used by PlaylistSelection.cpp PlaylistBrowserView* getListView() const { return m_listview; } PlaylistCategory* getDynamicCategory() const { return m_dynamicCategory; } void saveDynamics(); protected: virtual void resizeEvent( TQResizeEvent * ); signals: void selectionChanged(); public slots: void openPlaylist( TQListViewItem *parent = 0 ); void scanPodcasts(); private slots: void abortPodcastQueue(); void addSelectedToPlaylist( int options = -1 ); void collectionScanDone(); void currentItemChanged( TQListViewItem * ); void downloadPodcastQueue(); void editStreamURL( StreamEntry *item, const bool readOnly=false ); void removeSelectedItems(); void renamePlaylist( TQListViewItem*, const TQString&, int ); void renameSelectedItem(); void invokeItem( TQListViewItem*, const TQPoint &, int column ); void slotDoubleClicked( TQListViewItem *item ); void slotAddMenu( int id ); void slotAddPlaylistMenu( int id ); void showContextMenu( TQListViewItem*, const TQPoint&, int ); void loadDynamicItems(); private: PlaylistBrowser( const char* name=0 ); void polish(); bool m_polished; PlaylistCategory* loadStreams(); void loadCoolStreams(); void saveStreams(); void loadLastfmStreams( const bool subscriber = false ); void addLastFmRadio( TQListViewItem *parent ); void addLastFmCustomRadio( TQListViewItem *parent ); void saveLastFm(); PlaylistCategory* loadSmartPlaylists(); void loadDefaultSmartPlaylists(); void editSmartPlaylist( SmartPlaylist* ); void saveSmartPlaylists( PlaylistCategory *smartCategory = NULL ); void updateSmartPlaylists( TQListViewItem *root ); void updateSmartPlaylistElement( TQDomElement& query ); PlaylistCategory* loadDynamics(); void fixDynamicPlaylistPath( TQListViewItem *item ); TQString guessPathFromPlaylistName( TQString name ); PlaylistCategory* loadPodcasts(); TQMap loadPodcastFolders( PlaylistCategory *p ); void changePodcastInterval(); void configurePodcasts( TQListViewItem *parent ); void configurePodcasts( TQPtrList &podcastChannelList, const TQString &caption ); void configureSelectedPodcasts(); bool deleteSelectedPodcastItems( const bool removeItem=false, const bool silent=false ); bool deletePodcasts( TQPtrList items ); void downloadSelectedPodcasts(); void refreshPodcasts( TQListViewItem *category ); void removePodcastFolder( PlaylistCategory *item ); void savePodcastFolderStates( PlaylistCategory *folder ); PodcastChannel *findPodcastChannel( const KURL &feed, TQListViewItem *parent=0 ) const; void markDynamicEntries(); PlaylistBrowserEntry* findByName( TQString name ); PlaylistCategory* loadPlaylists(); void savePlaylists(); void savePlaylist( PlaylistEntry * ); bool createPlaylist( TQListViewItem *parent = 0, bool current = true, TQString title = 0 ); bool deletePlaylists( TQPtrList items ); bool deletePlaylists( KURL::List items ); void customEvent( TQCustomEvent* e ); void saveM3U( PlaylistEntry *, bool append ); void savePLS( PlaylistEntry *, bool append ); void saveXSPF( PlaylistEntry *, bool append ); static KURL::List recurse( const KURL &url ); static PlaylistBrowser *s_instance; PlaylistCategory *m_playlistCategory; PlaylistCategory *m_streamsCategory; PlaylistCategory *m_smartCategory; PlaylistCategory *m_dynamicCategory; PlaylistCategory *m_podcastCategory; PlaylistCategory *m_coolStreams; PlaylistCategory *m_smartDefaults; PlaylistCategory *m_lastfmCategory; ShoutcastBrowser *m_shoutcastCategory; PlaylistEntry *m_lastPlaylist; DynamicEntry *m_randomDynamic; DynamicEntry *m_suggestedDynamic; bool m_coolStreamsOpen; bool m_smartDefaultsOpen; bool m_lastfmOpen; PlaylistBrowserView *m_listview; KActionCollection *m_ac; KAction *removeButton; KAction *renameButton; KActionMenu *viewMenuButton; KActionMenu *addMenuButton; KToolBar *m_toolbar; TQValueList m_dynamicSizeSave; TQDict m_podcastSettings; TQPtrList m_dynamicEntries; TQTimer *m_podcastTimer; int m_podcastTimerInterval; //in ms TQPtrList m_podcastItemsToScan; TQPtrList m_podcastDownloadQueue; InfoPane *m_infoPane; bool m_removeDirt; TQSplitter *m_splitter; }; class PlaylistBrowserView : public KListView { Q_OBJECT TQ_OBJECT friend class PlaylistEntry; public: PlaylistBrowserView( TQWidget *parent, const char *name=0 ); ~PlaylistBrowserView(); void rename( TQListViewItem *item, int c ); protected: virtual void keyPressEvent( TQKeyEvent * ); private slots: void mousePressed( int, TQListViewItem *, const TQPoint &, int ); void moveSelectedItems( TQListViewItem* newParent ); private: void startDrag(); void contentsDropEvent( TQDropEvent* ); void contentsDragEnterEvent( TQDragEnterEvent* ); void contentsDragMoveEvent( TQDragMoveEvent* ); void contentsDragLeaveEvent( TQDragLeaveEvent* ); void viewportPaintEvent( TQPaintEvent* ); void eraseMarker(); TQListViewItem *m_marker; //track that has the drag/drop marker under it }; class PlaylistDialog: public KDialogBase { Q_OBJECT TQ_OBJECT public: static TQString getSaveFileName( const TQString &suggestion = TQString(), bool proposeOverwriting = false ); private: KLineEdit *edit; bool customChosen; TQString result; PlaylistDialog(); private slots: void slotOk(); void slotTextChanged( const TQString &s ); void slotCustomPath(); }; // Returns true if item is Playlist, Stream, Smart Playlist or DynamicMode. inline bool isElement( TQListViewItem *item ) { if( !item ) return false; return item->rtti() == ( PlaylistEntry::RTTI || StreamEntry::RTTI || SmartPlaylist::RTTI /*|| DynamicEntry::RTTI */) ? true : false; } inline bool isCategory( TQListViewItem *item ) { if( !item ) return false; return item->rtti() == PlaylistCategory::RTTI ? true : false; } inline bool isDynamic( TQListViewItem *item ) { if( !item ) return false; return item->rtti() == DynamicEntry::RTTI ? true : false; } inline bool isPlaylist( TQListViewItem *item ) { if( !item ) return false; return item->rtti() == PlaylistEntry::RTTI ? true : false; } inline bool isSmartPlaylist( TQListViewItem *item ) { if( !item ) return false; return item->rtti() == SmartPlaylist::RTTI ? true : false; } inline bool isPlaylistTrackItem( TQListViewItem *item ) { if( !item ) return false; return item->rtti() == PlaylistTrackItem::RTTI ? true : false; } inline bool isPodcastChannel( TQListViewItem *item ) { if( !item ) return false; return item->rtti() == PodcastChannel::RTTI ? true : false; } inline bool isPodcastEpisode( TQListViewItem *item ) { if( !item ) return false; return item->rtti() == PodcastEpisode::RTTI ? true : false; } inline bool isStream( TQListViewItem *item ) { if( !item ) return false; return item->rtti() == StreamEntry::RTTI ? true : false; } inline bool isLastFm( TQListViewItem *item ) { if( !item ) return false; return item->rtti() == LastFmEntry::RTTI ? true : false; } inline TQString fileBaseName( const TQString &filePath ) { // this function returns the file name without extension // (e.g. if the file path is "/home/user/playlist.m3u", "playlist" is returned TQString fileName = filePath.right( filePath.length() - filePath.findRev( '/' ) - 1 ); return fileName.mid( 0, fileName.findRev( '.' ) ); } inline TQString fileDirPath( const TQString &filePath ) { return filePath.left( filePath.findRev( '/' )+1 ); } class InfoPane : public TQVBox { Q_OBJECT TQ_OBJECT public: InfoPane( TQWidget *parent ); ~InfoPane(); int getHeight(); void setStoredHeight( const int newHeight ); public slots: void setInfo( const TQString &title, const TQString &info ); private slots: void toggle( bool ); private: HTMLView *m_infoBrowser; KPushButton *m_pushButton; bool m_enable; int m_storedHeight; }; #endif