From 844a455824fed9ca78e670dd6e8cbfbb3fde3ad3 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sun, 27 Feb 2011 03:04:58 +0100 Subject: [PATCH] * Added ViewPage, ViewPage-history and more consistent sidebar behaviour. --- data/images/back.png | Bin 0 -> 9960 bytes data/images/forward.png | Bin 0 -> 9668 bytes resources.qrc | 2 + src/libtomahawk/CMakeLists.txt | 3 +- src/libtomahawk/playlist/albummodel.cpp | 4 + src/libtomahawk/playlist/albummodel.h | 11 +- src/libtomahawk/playlist/albumproxymodel.h | 3 +- src/libtomahawk/playlist/albumview.cpp | 2 - src/libtomahawk/playlist/albumview.h | 23 +- .../playlist/collectionflatmodel.cpp | 5 + .../playlist/collectionproxymodel.h | 2 + src/libtomahawk/playlist/collectionview.cpp | 8 +- src/libtomahawk/playlist/collectionview.h | 15 +- .../playlist/dynamic/DynamicView.h | 2 +- .../dynamic/widgets/DynamicWidget.cpp | 6 + .../playlist/dynamic/widgets/DynamicWidget.h | 21 +- src/libtomahawk/playlist/playlistmanager.cpp | 536 ++++++++++-------- src/libtomahawk/playlist/playlistmanager.h | 47 +- src/libtomahawk/playlist/playlistmodel.cpp | 4 +- src/libtomahawk/playlist/playlistview.cpp | 8 +- src/libtomahawk/playlist/playlistview.h | 13 +- src/libtomahawk/playlist/topbar/topbar.cpp | 68 ++- src/libtomahawk/playlist/topbar/topbar.h | 7 + src/libtomahawk/playlist/trackmodel.h | 8 + src/libtomahawk/playlist/trackview.cpp | 1 - src/libtomahawk/playlistinterface.h | 10 +- src/libtomahawk/viewpage.cpp | 6 + src/libtomahawk/viewpage.h | 38 ++ .../widgets/infowidgets/sourceinfowidget.cpp | 2 + .../widgets/infowidgets/sourceinfowidget.h | 16 +- src/libtomahawk/widgets/newplaylistwidget.h | 13 +- src/libtomahawk/widgets/newplaylistwidget.ui | 23 +- src/libtomahawk/widgets/welcomewidget.h | 13 +- src/sip/jabber/jabber_p.cpp | 2 +- src/sourcetree/sourcesmodel.cpp | 72 ++- src/sourcetree/sourcesmodel.h | 4 + src/sourcetree/sourcetreeitem.cpp | 4 +- src/sourcetree/sourcetreeview.cpp | 68 ++- src/sourcetree/sourcetreeview.h | 6 + src/tomahawkwindow.cpp | 20 +- src/tomahawkwindow.h | 7 +- 41 files changed, 786 insertions(+), 317 deletions(-) create mode 100644 data/images/back.png create mode 100644 data/images/forward.png create mode 100644 src/libtomahawk/viewpage.cpp create mode 100644 src/libtomahawk/viewpage.h diff --git a/data/images/back.png b/data/images/back.png new file mode 100644 index 0000000000000000000000000000000000000000..88db1dc23691f750f221ed8ef117214a42a1a0a6 GIT binary patch literal 9960 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 P|6|Zl(NV5ZL`VD|&wewg literal 0 HcmV?d00001 diff --git a/data/images/forward.png b/data/images/forward.png new file mode 100644 index 0000000000000000000000000000000000000000..3e0c424763c163dbc633d437d87e99bd8136f205 GIT binary patch literal 9668 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 literal 0 HcmV?d00001 diff --git a/resources.qrc b/resources.qrc index fe25dfcaa..fc3705795 100644 --- a/resources.qrc +++ b/resources.qrc @@ -71,6 +71,8 @@ ./data/images/echonest_logo.png ./data/images/loading-animation.gif ./data/images/home.png +./data/images/back.png +./data/images/forward.png ./data/topbar-radiobuttons.css ./data/icons/tomahawk-icon-16x16.png ./data/icons/tomahawk-icon-32x32.png diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 6465a3ec6..d92d048ff 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -24,10 +24,10 @@ set( libSources query.cpp result.cpp source.cpp + viewpage.cpp sip/SipPlugin.cpp - audio/madtranscode.cpp audio/vorbistranscode.cpp audio/flactranscode.cpp @@ -161,6 +161,7 @@ set( libHeaders resolver.h result.h source.h + viewpage.h artist.h album.h diff --git a/src/libtomahawk/playlist/albummodel.cpp b/src/libtomahawk/playlist/albummodel.cpp index f22d389d8..c7efad856 100644 --- a/src/libtomahawk/playlist/albummodel.cpp +++ b/src/libtomahawk/playlist/albummodel.cpp @@ -225,6 +225,8 @@ AlbumModel::addCollection( const collection_ptr& collection ) SLOT( onAlbumsAdded( QList, Tomahawk::collection_ptr ) ) ); Database::instance()->enqueue( QSharedPointer( cmd ) ); + + m_title = tr( "All albums from %1" ).arg( collection->source()->friendlyName() ); } @@ -245,6 +247,8 @@ AlbumModel::addFilteredCollection( const collection_ptr& collection, unsigned in SLOT( onAlbumsAdded( QList, Tomahawk::collection_ptr ) ) ); Database::instance()->enqueue( QSharedPointer( cmd ) ); + + m_title = tr( "All albums by %1" ).arg( collection->source()->friendlyName() ); } diff --git a/src/libtomahawk/playlist/albummodel.h b/src/libtomahawk/playlist/albummodel.h index 445538b86..f25724ad4 100644 --- a/src/libtomahawk/playlist/albummodel.h +++ b/src/libtomahawk/playlist/albummodel.h @@ -40,9 +40,6 @@ public: virtual void removeIndex( const QModelIndex& index ); virtual void removeIndexes( const QList& indexes ); - virtual PlaylistInterface::RepeatMode repeatMode() const { return PlaylistInterface::NoRepeat; } - virtual bool shuffled() const { return false; } - virtual QMimeData* mimeData( const QModelIndexList& indexes ) const; virtual QStringList mimeTypes() const; virtual Qt::ItemFlags flags( const QModelIndex& index ) const; @@ -50,6 +47,11 @@ public: void addCollection( const Tomahawk::collection_ptr& collection ); void addFilteredCollection( const Tomahawk::collection_ptr& collection, unsigned int amount, DatabaseCommand_AllAlbums::SortOrder order ); + virtual QString title() const { return m_title; } + virtual QString description() const { return m_description; } + virtual void setTitle( const QString& title ) { m_title = title; } + virtual void setDescription( const QString& description ) { m_description = description; } + AlbumItem* itemFromIndex( const QModelIndex& index ) const { if ( index.isValid() ) @@ -81,6 +83,9 @@ private: QPersistentModelIndex m_currentIndex; AlbumItem* m_rootItem; QPixmap m_defaultCover; + + QString m_title; + QString m_description; }; #endif // ALBUMMODEL_H diff --git a/src/libtomahawk/playlist/albumproxymodel.h b/src/libtomahawk/playlist/albumproxymodel.h index d87c855db..3e694e2a6 100644 --- a/src/libtomahawk/playlist/albumproxymodel.h +++ b/src/libtomahawk/playlist/albumproxymodel.h @@ -33,7 +33,8 @@ public: virtual PlaylistInterface::RepeatMode repeatMode() const { return m_repeatMode; } virtual bool shuffled() const { return m_shuffled; } - + virtual PlaylistInterface::ViewMode viewMode() const { return PlaylistInterface::Album; } + signals: void repeatModeChanged( PlaylistInterface::RepeatMode mode ); void shuffleModeChanged( bool enabled ); diff --git a/src/libtomahawk/playlist/albumview.cpp b/src/libtomahawk/playlist/albumview.cpp index 9e954cc7f..83ecb28b9 100644 --- a/src/libtomahawk/playlist/albumview.cpp +++ b/src/libtomahawk/playlist/albumview.cpp @@ -10,8 +10,6 @@ #include "tomahawksettings.h" #include "albumitemdelegate.h" -#include "albummodel.h" -#include "albumproxymodel.h" #include "playlistmanager.h" using namespace Tomahawk; diff --git a/src/libtomahawk/playlist/albumview.h b/src/libtomahawk/playlist/albumview.h index a2445971f..d4616cd3c 100644 --- a/src/libtomahawk/playlist/albumview.h +++ b/src/libtomahawk/playlist/albumview.h @@ -4,12 +4,13 @@ #include #include +#include "albummodel.h" +#include "albumproxymodel.h" +#include "viewpage.h" + #include "dllmacro.h" -class AlbumModel; -class AlbumProxyModel; - -class DLLEXPORT AlbumView : public QListView +class DLLEXPORT AlbumView : public QListView, public Tomahawk::ViewPage { Q_OBJECT @@ -19,12 +20,22 @@ public: void setProxyModel( AlbumProxyModel* model ); - AlbumModel* model() { return m_model; } - AlbumProxyModel* proxyModel() { return m_proxyModel; } + AlbumModel* model() const { return m_model; } + AlbumProxyModel* proxyModel() const { return m_proxyModel; } // PlaylistItemDelegate* delegate() { return m_delegate; } void setModel( AlbumModel* model ); + virtual QWidget* widget() { return this; } + virtual PlaylistInterface* playlistInterface() const { return proxyModel(); } + + virtual QString title() const { return m_model->title(); } + virtual QString description() const { return m_model->description(); } + + virtual bool showModes() const { return true; } + + virtual bool jumpToCurrentTrack() { return false; } + public slots: void onItemActivated( const QModelIndex& index ); diff --git a/src/libtomahawk/playlist/collectionflatmodel.cpp b/src/libtomahawk/playlist/collectionflatmodel.cpp index 54c4bdc04..6e63feeba 100644 --- a/src/libtomahawk/playlist/collectionflatmodel.cpp +++ b/src/libtomahawk/playlist/collectionflatmodel.cpp @@ -60,6 +60,11 @@ CollectionFlatModel::addCollection( const collection_ptr& collection ) SLOT( onTracksAdded( QList, Tomahawk::collection_ptr ) ) ); connect( collection.data(), SIGNAL( tracksFinished( Tomahawk::collection_ptr ) ), SLOT( onTracksAddingFinished( Tomahawk::collection_ptr ) ) ); + + if ( collection->source()->isLocal() ) + setTitle( tr( "Your Collection" ) ); + else + setTitle( tr( "Collection of %1" ).arg( collection->source()->friendlyName() ) ); } diff --git a/src/libtomahawk/playlist/collectionproxymodel.h b/src/libtomahawk/playlist/collectionproxymodel.h index e6ea9311d..af46be8c4 100644 --- a/src/libtomahawk/playlist/collectionproxymodel.h +++ b/src/libtomahawk/playlist/collectionproxymodel.h @@ -12,6 +12,8 @@ Q_OBJECT public: explicit CollectionProxyModel( QObject* parent = 0 ); + virtual PlaylistInterface::ViewMode viewMode() const { return PlaylistInterface::Flat; } + protected: bool lessThan( const QModelIndex& left, const QModelIndex& right ) const; }; diff --git a/src/libtomahawk/playlist/collectionview.cpp b/src/libtomahawk/playlist/collectionview.cpp index dc1490595..09b557611 100644 --- a/src/libtomahawk/playlist/collectionview.cpp +++ b/src/libtomahawk/playlist/collectionview.cpp @@ -45,7 +45,6 @@ CollectionView::setModel( TrackModel* model ) void CollectionView::dragEnterEvent( QDragEnterEvent* event ) { - qDebug() << Q_FUNC_INFO; event->ignore(); } @@ -94,3 +93,10 @@ CollectionView::onTrackCountChanged( unsigned int tracks ) else overlay()->hide(); } + + +bool +CollectionView::jumpToCurrentTrack() +{ + scrollTo( proxyModel()->currentItem(), QAbstractItemView::PositionAtCenter ); +} diff --git a/src/libtomahawk/playlist/collectionview.h b/src/libtomahawk/playlist/collectionview.h index 9fd3f3483..cddd1e98c 100644 --- a/src/libtomahawk/playlist/collectionview.h +++ b/src/libtomahawk/playlist/collectionview.h @@ -3,11 +3,14 @@ #include +#include "trackproxymodel.h" +#include "trackmodel.h" #include "trackview.h" +#include "viewpage.h" #include "dllmacro.h" -class DLLEXPORT CollectionView : public TrackView +class DLLEXPORT CollectionView : public TrackView, public Tomahawk::ViewPage { Q_OBJECT @@ -17,6 +20,16 @@ public: virtual void setModel( TrackModel* model ); + virtual QWidget* widget() { return this; } + virtual PlaylistInterface* playlistInterface() const { return proxyModel(); } + + virtual QString title() const { return model()->title(); } + virtual QString description() const { return model()->description(); } + + virtual bool showModes() const { return true; } + + virtual bool jumpToCurrentTrack(); + private slots: void onCustomContextMenu( const QPoint& pos ); void onTrackCountChanged( unsigned int tracks ); diff --git a/src/libtomahawk/playlist/dynamic/DynamicView.h b/src/libtomahawk/playlist/dynamic/DynamicView.h index d7ad8103e..26a63e4f1 100644 --- a/src/libtomahawk/playlist/dynamic/DynamicView.h +++ b/src/libtomahawk/playlist/dynamic/DynamicView.h @@ -45,7 +45,7 @@ public: void setDynamicWorking( bool working ); - virtual void paintEvent(QPaintEvent* event); + virtual void paintEvent( QPaintEvent* event ); public slots: void showMessageTimeout( const QString& title, const QString& body ); diff --git a/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp b/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp index 8bea35d94..20ec27727 100644 --- a/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp +++ b/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.cpp @@ -386,3 +386,9 @@ DynamicWidget::paintRoundedFilledRect( QPainter& p, QPalette& pal, QRect& r, qre p.setPen( pen ); p.drawRoundedRect( r, 10, 10 ); } + +bool +DynamicWidget::jumpToCurrentTrack() +{ + m_view->scrollTo( m_view->proxyModel()->currentItem(), QAbstractItemView::PositionAtCenter ); +} diff --git a/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.h b/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.h index 17d31d882..e8653b2b7 100644 --- a/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.h +++ b/src/libtomahawk/playlist/dynamic/widgets/DynamicWidget.h @@ -20,8 +20,11 @@ #include #include "typedefs.h" +#include "viewpage.h" + #include "dynamic/DynamicPlaylist.h" #include "dynamic/DynamicControl.h" +#include "dynamic/DynamicModel.h" class LoadingSpinner; class QShowEvent; @@ -43,20 +46,15 @@ namespace Tomahawk class DynamicSetupWidget; - -class DynamicModel; - - class DynamicView; - class CollapsibleControls; /** * This class contains the dynamic playlist config and the playlist view itself */ -class DynamicWidget : public QWidget +class DynamicWidget : public QWidget, public Tomahawk::ViewPage { Q_OBJECT public: @@ -65,7 +63,7 @@ public: void loadDynamicPlaylist( const dynplaylist_ptr& playlist ); - PlaylistInterface* playlistInterface() const; + virtual PlaylistInterface* playlistInterface() const; virtual QSize sizeHint() const; virtual void resizeEvent( QResizeEvent* ); @@ -73,6 +71,14 @@ public: virtual void showEvent(QShowEvent* ); static void paintRoundedFilledRect( QPainter& p, QPalette& pal, QRect& r, qreal opacity = .95 ); + + virtual QWidget* widget() { return this; } + + virtual QString title() const { return m_model->title(); } + virtual QString description() const { return m_model->description(); } + + virtual bool jumpToCurrentTrack(); + public slots: void onRevisionLoaded( const Tomahawk::DynamicPlaylistRevision& rev ); void playlistTypeChanged(QString); @@ -94,6 +100,7 @@ private slots: void controlChanged( const Tomahawk::dyncontrol_ptr& control ); void layoutFloatingWidgets(); + private: dynplaylist_ptr m_playlist; QVBoxLayout* m_layout; diff --git a/src/libtomahawk/playlist/playlistmanager.cpp b/src/libtomahawk/playlist/playlistmanager.cpp index 40ee565d3..c2425aa78 100644 --- a/src/libtomahawk/playlist/playlistmanager.cpp +++ b/src/libtomahawk/playlist/playlistmanager.cpp @@ -30,6 +30,8 @@ #define FILTER_TIMEOUT 280 +using namespace Tomahawk; + PlaylistManager* PlaylistManager::s_instance = 0; @@ -44,14 +46,12 @@ PlaylistManager::PlaylistManager( QObject* parent ) : QObject( parent ) , m_widget( new QWidget() ) , m_welcomeWidget( new WelcomeWidget() ) - , m_currentInterface( 0 ) , m_currentMode( 0 ) , m_superCollectionVisible( true ) - , m_statsAvailable( false ) - , m_modesAvailable( false ) { s_instance = this; + setHistoryPosition( -1 ); m_widget->setLayout( new QVBoxLayout() ); m_topbar = new TopBar(); @@ -91,11 +91,8 @@ PlaylistManager::PlaylistManager( QObject* parent ) m_superAlbumView = new AlbumView(); m_superAlbumModel = new AlbumModel( m_superAlbumView ); m_superAlbumView->setModel( m_superAlbumModel ); - - m_stack->addWidget( m_superCollectionView ); - m_stack->addWidget( m_superAlbumView ); - - m_currentInterface = m_superCollectionView->proxyModel(); + m_superAlbumView->setFrameShape( QFrame::NoFrame ); + m_superAlbumView->setAttribute( Qt::WA_MacShowFocusRect, 0 ); m_stack->setContentsMargins( 0, 0, 0, 0 ); m_widget->setContentsMargins( 0, 0, 0, 0 ); @@ -106,34 +103,16 @@ PlaylistManager::PlaylistManager( QObject* parent ) connect( &m_filterTimer, SIGNAL( timeout() ), SLOT( applyFilter() ) ); connect( m_topbar, SIGNAL( filterTextChanged( QString ) ), - this, SLOT( setFilter( QString ) ) ); - - connect( this, SIGNAL( numSourcesChanged( unsigned int ) ), - m_topbar, SLOT( setNumSources( unsigned int ) ) ); - - connect( this, SIGNAL( numTracksChanged( unsigned int ) ), - m_topbar, SLOT( setNumTracks( unsigned int ) ) ); - - connect( this, SIGNAL( numArtistsChanged( unsigned int ) ), - m_topbar, SLOT( setNumArtists( unsigned int ) ) ); - - connect( this, SIGNAL( numShownChanged( unsigned int ) ), - m_topbar, SLOT( setNumShown( unsigned int ) ) ); + SLOT( setFilter( QString ) ) ); connect( m_topbar, SIGNAL( flatMode() ), - this, SLOT( setTableMode() ) ); - + SLOT( setTableMode() ) ); + connect( m_topbar, SIGNAL( artistMode() ), - this, SLOT( setTreeMode() ) ); - + SLOT( setTreeMode() ) ); + connect( m_topbar, SIGNAL( albumMode() ), - this, SLOT( setAlbumMode() ) ); - - connect( this, SIGNAL( statsAvailable( bool ) ), - m_topbar, SLOT( setStatsVisible( bool ) ) ); - - connect( this, SIGNAL( modesAvailable( bool ) ), - m_topbar, SLOT( setModesVisible( bool ) ) ); + SLOT( setAlbumMode() ) ); } @@ -153,11 +132,10 @@ PlaylistManager::queue() const bool PlaylistManager::show( const Tomahawk::playlist_ptr& playlist ) { - unlinkPlaylist(); - + PlaylistView* view; if ( !m_playlistViews.contains( playlist ) ) { - PlaylistView* view = new PlaylistView(); + view = new PlaylistView(); PlaylistModel* model = new PlaylistModel(); view->setModel( model ); view->setFrameShape( QFrame::NoFrame ); @@ -165,27 +143,15 @@ PlaylistManager::show( const Tomahawk::playlist_ptr& playlist ) model->loadPlaylist( playlist ); playlist->resolve(); - m_currentInterface = view->proxyModel(); m_playlistViews.insert( playlist, view ); - - m_stack->addWidget( view ); - m_stack->setCurrentWidget( view ); } else { - PlaylistView* view = m_playlistViews.value( playlist ); - m_stack->setCurrentWidget( view ); - m_currentInterface = view->proxyModel(); + view = m_playlistViews.value( playlist ); } - m_queueView->show(); - m_infobar->setCaption( playlist->title() ); - m_infobar->setDescription( tr( "A playlist by %1" ).arg( playlist->author()->isLocal() ? tr( "you" ) : playlist->author()->friendlyName() ) ); - + setPage( view ); m_superCollectionVisible = false; - m_statsAvailable = true; - m_modesAvailable = false; - linkPlaylist(); TomahawkSettings::instance()->appendRecentlyPlayedPlaylist( playlist ); @@ -197,34 +163,25 @@ PlaylistManager::show( const Tomahawk::playlist_ptr& playlist ) bool PlaylistManager::show( const Tomahawk::dynplaylist_ptr& playlist ) { - unlinkPlaylist(); - - if( !m_dynamicWidgets.contains( playlist ) ) + if ( !m_dynamicWidgets.contains( playlist ) ) { m_dynamicWidgets[ playlist ] = new Tomahawk::DynamicWidget( playlist, m_stack ); - m_stack->addWidget( m_dynamicWidgets[ playlist ] ); + playlist->resolve(); } - m_stack->setCurrentWidget( m_dynamicWidgets.value( playlist ) ); - m_currentInterface = m_dynamicWidgets.value( playlist )->playlistInterface(); + setPage( m_dynamicWidgets.value( playlist ) ); - m_infobar->setCaption( playlist->title() ); - m_infobar->setDescription( tr( "A playlist by %1" ).arg( playlist->author()->isLocal() ? tr( "you" ) : playlist->author()->friendlyName() ) ); - - if( playlist->mode() == Tomahawk::OnDemand ) + if ( playlist->mode() == Tomahawk::OnDemand ) m_queueView->hide(); - + else + m_queueView->show(); m_superCollectionVisible = false; - m_statsAvailable = true; - m_modesAvailable = false; - linkPlaylist(); TomahawkSettings::instance()->appendRecentlyPlayedPlaylist( playlist ); emit numSourcesChanged( SourceList::instance()->count() ); - return true; } @@ -232,39 +189,26 @@ PlaylistManager::show( const Tomahawk::dynplaylist_ptr& playlist ) bool PlaylistManager::show( const Tomahawk::artist_ptr& artist ) { - qDebug() << Q_FUNC_INFO << &artist << artist.data(); - unlinkPlaylist(); + PlaylistView* view; if ( !m_artistViews.contains( artist ) ) { - PlaylistView* view = new PlaylistView(); + view = new PlaylistView(); PlaylistModel* model = new PlaylistModel(); view->setModel( model ); view->setFrameShape( QFrame::NoFrame ); view->setAttribute( Qt::WA_MacShowFocusRect, 0 ); model->append( artist ); - m_currentInterface = view->proxyModel(); m_artistViews.insert( artist, view ); - - m_stack->addWidget( view ); - m_stack->setCurrentWidget( view ); } else { - PlaylistView* view = m_artistViews.value( artist ); - m_stack->setCurrentWidget( view ); - m_currentInterface = view->proxyModel(); + view = m_artistViews.value( artist ); } - m_queueView->show(); - m_infobar->setCaption( tr( "All tracks by %1" ).arg( artist->name() ) ); - m_infobar->setDescription( "" ); - + setPage( view ); m_superCollectionVisible = false; - m_statsAvailable = false; - m_modesAvailable = false; - linkPlaylist(); emit numSourcesChanged( 1 ); return true; @@ -274,39 +218,25 @@ PlaylistManager::show( const Tomahawk::artist_ptr& artist ) bool PlaylistManager::show( const Tomahawk::album_ptr& album ) { - qDebug() << Q_FUNC_INFO << &album << album.data(); - unlinkPlaylist(); - + PlaylistView* view; if ( !m_albumViews.contains( album ) ) { - PlaylistView* view = new PlaylistView(); + view = new PlaylistView(); PlaylistModel* model = new PlaylistModel(); view->setModel( model ); view->setFrameShape( QFrame::NoFrame ); view->setAttribute( Qt::WA_MacShowFocusRect, 0 ); model->append( album ); - m_currentInterface = view->proxyModel(); m_albumViews.insert( album, view ); - - m_stack->addWidget( view ); - m_stack->setCurrentWidget( view ); } else { - PlaylistView* view = m_albumViews.value( album ); - m_stack->setCurrentWidget( view ); - m_currentInterface = view->proxyModel(); + view = m_albumViews.value( album ); } - m_queueView->show(); - m_infobar->setCaption( tr( "All tracks on %1 by %2" ).arg( album->name() ).arg( album->artist()->name() ) ); - m_infobar->setDescription( "" ); - + setPage( view ); m_superCollectionVisible = false; - m_statsAvailable = false; - m_modesAvailable = false; - linkPlaylist(); emit numSourcesChanged( 1 ); return true; @@ -316,70 +246,52 @@ PlaylistManager::show( const Tomahawk::album_ptr& album ) bool PlaylistManager::show( const Tomahawk::collection_ptr& collection ) { - unlinkPlaylist(); - m_currentCollection = collection; if ( m_currentMode == 0 ) { + CollectionView* view; if ( !m_collectionViews.contains( collection ) ) { - CollectionView* view = new CollectionView(); + view = new CollectionView(); CollectionFlatModel* model = new CollectionFlatModel(); view->setModel( model ); view->setFrameShape( QFrame::NoFrame ); view->setAttribute( Qt::WA_MacShowFocusRect, 0 ); model->addCollection( collection ); - m_currentInterface = view->proxyModel(); m_collectionViews.insert( collection, view ); - - m_stack->addWidget( view ); - m_stack->setCurrentWidget( view ); } else { - CollectionView* view = m_collectionViews.value( collection ); - m_stack->setCurrentWidget( view ); - m_currentInterface = view->proxyModel(); + view = m_collectionViews.value( collection ); } + + setPage( view ); } if ( m_currentMode == 2 ) { + AlbumView* aview; if ( !m_collectionAlbumViews.contains( collection ) ) { - AlbumView* aview = new AlbumView(); + aview = new AlbumView(); AlbumModel* amodel = new AlbumModel( aview ); aview->setModel( amodel ); aview->setFrameShape( QFrame::NoFrame ); aview->setAttribute( Qt::WA_MacShowFocusRect, 0 ); amodel->addCollection( collection ); - m_currentInterface = aview->proxyModel(); m_collectionAlbumViews.insert( collection, aview ); - - m_stack->addWidget( aview ); - m_stack->setCurrentWidget( aview ); } else { - AlbumView* view = m_collectionAlbumViews.value( collection ); - m_stack->setCurrentWidget( view ); - m_currentInterface = view->proxyModel(); + aview = m_collectionAlbumViews.value( collection ); } + + setPage( aview ); } - m_infobar->setDescription( "" ); - if ( collection->source()->isLocal() ) - m_infobar->setCaption( tr( "Your Collection" ) ); - else - m_infobar->setCaption( tr( "Collection of %1" ).arg( collection->source()->friendlyName() ) ); - - m_queueView->show(); m_superCollectionVisible = false; - m_statsAvailable = ( m_currentMode == 0 ); - m_modesAvailable = true; - linkPlaylist(); emit numSourcesChanged( 1 ); return true; @@ -389,32 +301,19 @@ PlaylistManager::show( const Tomahawk::collection_ptr& collection ) bool PlaylistManager::show( const Tomahawk::source_ptr& source ) { - unlinkPlaylist(); - - m_currentInterface = 0; - + SourceInfoWidget* swidget; if ( !m_sourceViews.contains( source ) ) { - SourceInfoWidget* swidget = new SourceInfoWidget( source ); - m_currentInfoWidget = swidget; - m_stack->addWidget( m_currentInfoWidget ); + swidget = new SourceInfoWidget( source ); m_sourceViews.insert( source, swidget ); } else { - m_currentInfoWidget = m_sourceViews.value( source ); + swidget = m_sourceViews.value( source ); } - m_infobar->setCaption( tr( "Info about %1" ).arg( source->isLocal() ? tr( "Your Collection" ) : source->friendlyName() ) ); - m_infobar->setDescription( "" ); - - m_queueView->show(); - m_stack->setCurrentWidget( m_currentInfoWidget ); + setPage( swidget ); m_superCollectionVisible = false; - m_statsAvailable = false; - m_modesAvailable = false; - - linkPlaylist(); emit numSourcesChanged( 1 ); return true; @@ -422,28 +321,15 @@ PlaylistManager::show( const Tomahawk::source_ptr& source ) bool -PlaylistManager::show( QWidget* widget, const QString& title, const QString& desc, const QPixmap& pixmap ) +PlaylistManager::show( ViewPage* page ) { - unlinkPlaylist(); - - if ( m_stack->indexOf( widget ) < 0 ) + if ( m_stack->indexOf( page->widget() ) < 0 ) { - connect( widget, SIGNAL( destroyed( QWidget* ) ), SLOT( onWidgetDestroyed( QWidget* ) ) ); - m_stack->addWidget( widget ); + connect( page->widget(), SIGNAL( destroyed( QWidget* ) ), SLOT( onWidgetDestroyed( QWidget* ) ) ); } - m_stack->setCurrentWidget( widget ); - m_infobar->setCaption( title ); - m_infobar->setDescription( desc ); - m_infobar->setPixmap( pixmap.isNull() ? QPixmap( RESPATH "icons/tomahawk-icon-128x128.png" ) : pixmap ); - - m_queueView->show(); + setPage( page ); m_superCollectionVisible = false; - m_statsAvailable = false; - m_modesAvailable = false; - m_currentInterface = 0; - - linkPlaylist(); return true; } @@ -460,27 +346,21 @@ PlaylistManager::showSuperCollection() m_superCollectionFlatModel->addCollection( source->collection() ); m_superAlbumModel->addCollection( source->collection() ); } + + m_superCollectionFlatModel->setTitle( tr( "All available tracks" ) ); + m_superAlbumModel->setTitle( tr( "All available albums" ) ); } if ( m_currentMode == 0 ) { - m_stack->setCurrentWidget( m_superCollectionView ); - m_currentInterface = m_superCollectionView->proxyModel(); + setPage( m_superCollectionView ); } else if ( m_currentMode == 2 ) { - m_stack->setCurrentWidget( m_superAlbumView ); - m_currentInterface = m_superAlbumView->proxyModel(); + setPage( m_superAlbumView ); } - m_infobar->setCaption( tr( "Super Collection" ) ); - m_infobar->setDescription( tr( "All available tracks" ) ); - - m_queueView->show(); m_superCollectionVisible = true; - m_statsAvailable = ( m_currentMode == 0 ); - m_modesAvailable = true; - linkPlaylist(); emit numSourcesChanged( m_superCollections.count() ); return true; @@ -490,8 +370,7 @@ PlaylistManager::showSuperCollection() void PlaylistManager::showWelcomePage() { - qDebug() << Q_FUNC_INFO; - show( m_welcomeWidget, tr( "Welcome to Tomahawk!" ) ); + show( m_welcomeWidget ); } @@ -545,8 +424,7 @@ PlaylistManager::showQueue() if ( QThread::currentThread() != thread() ) { qDebug() << "Reinvoking in correct thread:" << Q_FUNC_INFO; - QMetaObject::invokeMethod( this, "showQueue", - Qt::QueuedConnection ); + QMetaObject::invokeMethod( this, "showQueue", Qt::QueuedConnection ); return; } @@ -560,8 +438,7 @@ PlaylistManager::hideQueue() if ( QThread::currentThread() != thread() ) { qDebug() << "Reinvoking in correct thread:" << Q_FUNC_INFO; - QMetaObject::invokeMethod( this, "hideQueue", - Qt::QueuedConnection ); + QMetaObject::invokeMethod( this, "hideQueue", Qt::QueuedConnection ); return; } @@ -569,6 +446,42 @@ PlaylistManager::hideQueue() } +void +PlaylistManager::historyBack() +{ + if ( m_historyPosition < 1 ) + return; + + showHistory( m_historyPosition - 1 ); +} + + +void +PlaylistManager::historyForward() +{ + if ( m_historyPosition >= m_pageHistory.count() - 1 ) + return; + + showHistory( m_historyPosition + 1 ); +} + + +void +PlaylistManager::showHistory( int historyPosition ) +{ + if ( historyPosition < 0 || historyPosition >= m_pageHistory.count() ) + { + qDebug() << "History position out of bounds!" << historyPosition << m_pageHistory.count(); + Q_ASSERT( false ); + return; + } + + setHistoryPosition( historyPosition ); + ViewPage* page = m_pageHistory.at( historyPosition ); + setPage( page, false ); +} + + void PlaylistManager::setFilter( const QString& filter ) { @@ -586,67 +499,111 @@ PlaylistManager::applyFilter() { qDebug() << Q_FUNC_INFO; - if ( m_currentInterface && m_currentInterface->filter() != m_filter ) - m_currentInterface->setFilter( m_filter ); + if ( currentPlaylistInterface() && currentPlaylistInterface()->filter() != m_filter ) + currentPlaylistInterface()->setFilter( m_filter ); +} + + +void +PlaylistManager::setPage( ViewPage* page, bool trackHistory ) +{ + unlinkPlaylist(); + + if ( !m_pageHistory.contains( page ) ) + { + m_stack->addWidget( page->widget() ); + } + else + { + if ( trackHistory ) + m_pageHistory.removeAll( page ); + } + + if ( trackHistory ) + { + m_pageHistory << page; + setHistoryPosition( m_pageHistory.count() - 1 ); + } + + if ( playlistForInterface( currentPlaylistInterface() ) ) + emit playlistActivated( playlistForInterface( currentPlaylistInterface() ) ); + if ( dynamicPlaylistForInterface( currentPlaylistInterface() ) ) + emit dynamicPlaylistActivated( dynamicPlaylistForInterface( currentPlaylistInterface() ) ); + if ( collectionForInterface( currentPlaylistInterface() ) ) + emit collectionActivated( collectionForInterface( currentPlaylistInterface() ) ); + if ( !currentPlaylistInterface() ) + emit tempPageActivated(); + + m_stack->setCurrentWidget( page->widget() ); + updateView(); } void PlaylistManager::unlinkPlaylist() { - if ( m_currentInterface ) + if ( currentPlaylistInterface() ) { - disconnect( m_currentInterface->object(), SIGNAL( sourceTrackCountChanged( unsigned int ) ), - this, SIGNAL( numTracksChanged( unsigned int ) ) ); + disconnect( currentPlaylistInterface()->object(), SIGNAL( sourceTrackCountChanged( unsigned int ) ), + this, SIGNAL( numTracksChanged( unsigned int ) ) ); - disconnect( m_currentInterface->object(), SIGNAL( trackCountChanged( unsigned int ) ), - this, SIGNAL( numShownChanged( unsigned int ) ) ); + disconnect( currentPlaylistInterface()->object(), SIGNAL( trackCountChanged( unsigned int ) ), + this, SIGNAL( numShownChanged( unsigned int ) ) ); - disconnect( m_currentInterface->object(), SIGNAL( repeatModeChanged( PlaylistInterface::RepeatMode ) ), - this, SIGNAL( repeatModeChanged( PlaylistInterface::RepeatMode ) ) ); + disconnect( currentPlaylistInterface()->object(), SIGNAL( repeatModeChanged( PlaylistInterface::RepeatMode ) ), + this, SIGNAL( repeatModeChanged( PlaylistInterface::RepeatMode ) ) ); - disconnect( m_currentInterface->object(), SIGNAL( shuffleModeChanged( bool ) ), - this, SIGNAL( shuffleModeChanged( bool ) ) ); + disconnect( currentPlaylistInterface()->object(), SIGNAL( shuffleModeChanged( bool ) ), + this, SIGNAL( shuffleModeChanged( bool ) ) ); } } void -PlaylistManager::linkPlaylist() +PlaylistManager::updateView() { - if ( m_currentInterface ) + if ( currentPlaylistInterface() ) { - connect( m_currentInterface->object(), SIGNAL( sourceTrackCountChanged( unsigned int ) ), - this, SIGNAL( numTracksChanged( unsigned int ) ) ); + connect( currentPlaylistInterface()->object(), SIGNAL( sourceTrackCountChanged( unsigned int ) ), + SIGNAL( numTracksChanged( unsigned int ) ) ); - connect( m_currentInterface->object(), SIGNAL( trackCountChanged( unsigned int ) ), - this, SIGNAL( numShownChanged( unsigned int ) ) ); + connect( currentPlaylistInterface()->object(), SIGNAL( trackCountChanged( unsigned int ) ), + SIGNAL( numShownChanged( unsigned int ) ) ); - connect( m_currentInterface->object(), SIGNAL( repeatModeChanged( PlaylistInterface::RepeatMode ) ), - this, SIGNAL( repeatModeChanged( PlaylistInterface::RepeatMode ) ) ); + connect( currentPlaylistInterface()->object(), SIGNAL( repeatModeChanged( PlaylistInterface::RepeatMode ) ), + SIGNAL( repeatModeChanged( PlaylistInterface::RepeatMode ) ) ); - connect( m_currentInterface->object(), SIGNAL( shuffleModeChanged( bool ) ), - this, SIGNAL( shuffleModeChanged( bool ) ) ); + connect( currentPlaylistInterface()->object(), SIGNAL( shuffleModeChanged( bool ) ), + SIGNAL( shuffleModeChanged( bool ) ) ); - m_interfaceHistory.removeAll( m_currentInterface ); - m_interfaceHistory << m_currentInterface; + m_topbar->setFilter( currentPlaylistInterface()->filter() ); } - AudioEngine::instance()->setPlaylist( m_currentInterface ); - - if ( m_currentInterface && m_statsAvailable ) + if ( currentPage()->showStatsBar() && currentPlaylistInterface() ) { - m_topbar->setFilter( m_currentInterface->filter() ); - - emit numTracksChanged( m_currentInterface->unfilteredTrackCount() ); - emit numShownChanged( m_currentInterface->trackCount() ); - emit repeatModeChanged( m_currentInterface->repeatMode() ); - emit shuffleModeChanged( m_currentInterface->shuffled() ); - + emit numTracksChanged( currentPlaylistInterface()->unfilteredTrackCount() ); + emit numShownChanged( currentPlaylistInterface()->trackCount() ); + emit repeatModeChanged( currentPlaylistInterface()->repeatMode() ); + emit shuffleModeChanged( currentPlaylistInterface()->shuffled() ); + emit modeChanged( currentPlaylistInterface()->viewMode() ); } - emit statsAvailable( m_statsAvailable ); - emit modesAvailable( m_modesAvailable ); + if ( currentPage()->queueVisible() ) + m_queueView->show(); + else + m_queueView->hide(); + + emit statsAvailable( currentPage()->showStatsBar() ); + emit modesAvailable( currentPage()->showModes() ); + + if ( !currentPage()->showStatsBar() && !currentPage()->showModes() ) + m_topbar->setVisible( false ); + else + m_topbar->setVisible( true ); + + m_infobar->setCaption( currentPage()->title() ); + m_infobar->setDescription( currentPage()->description() ); + m_infobar->setPixmap( currentPage()->pixmap() ); } @@ -658,17 +615,20 @@ PlaylistManager::onWidgetDestroyed( QWidget* widget ) bool resetWidget = ( m_stack->currentWidget() == widget ); m_stack->removeWidget( widget ); - if ( resetWidget && m_interfaceHistory.count() ) + for ( int i = 0; i < m_pageHistory.count(); i++ ) { - unlinkPlaylist(); + ViewPage* page = m_pageHistory.at( i ); + if ( page->widget() == widget ) + { + m_pageHistory.removeAt( i ); + break; + } + } - m_currentInterface = m_interfaceHistory.last(); - qDebug() << "Last interface:" << m_currentInterface << m_currentInterface->widget(); - - if ( m_currentInterface->widget() ) - m_stack->setCurrentWidget( m_currentInterface->widget() ); - - linkPlaylist(); + if ( resetWidget ) + { + if ( m_pageHistory.count() ) + showHistory( m_pageHistory.count() - 1 ); } } @@ -676,16 +636,16 @@ PlaylistManager::onWidgetDestroyed( QWidget* widget ) void PlaylistManager::setRepeatMode( PlaylistInterface::RepeatMode mode ) { - if ( m_currentInterface ) - m_currentInterface->setRepeatMode( mode ); + if ( currentPlaylistInterface() ) + currentPlaylistInterface()->setRepeatMode( mode ); } void PlaylistManager::setShuffled( bool enabled ) { - if ( m_currentInterface ) - m_currentInterface->setShuffled( enabled ); + if ( currentPlaylistInterface() ) + currentPlaylistInterface()->setShuffled( enabled ); } @@ -709,20 +669,120 @@ PlaylistManager::createDynamicPlaylist( const Tomahawk::source_ptr& src, } +ViewPage* +PlaylistManager::pageForInterface( PlaylistInterface* interface ) const +{ + for ( int i = 0; i < m_pageHistory.count(); i++ ) + { + ViewPage* page = m_pageHistory.at( i ); + if ( page->playlistInterface() == interface ) + return page; + } + + return 0; +} + + +int +PlaylistManager::positionInHistory( ViewPage* page ) const +{ + for ( int i = 0; i < m_pageHistory.count(); i++ ) + { + if ( page == m_pageHistory.at( i ) ) + return i; + } + + return -1; +} + + +PlaylistInterface* +PlaylistManager::currentPlaylistInterface() const +{ + if ( currentPage() ) + return currentPage()->playlistInterface(); + else + return 0; +} + + +Tomahawk::ViewPage* +PlaylistManager::currentPage() const +{ + if ( m_historyPosition >= 0 ) + return m_pageHistory.at( m_historyPosition ); + else + return 0; +} + + +void +PlaylistManager::setHistoryPosition( int position ) +{ + m_historyPosition = position; + + emit historyBackAvailable( m_historyPosition > 0 ); + emit historyForwardAvailable( m_historyPosition < m_pageHistory.count() - 1 ); +} + + +Tomahawk::playlist_ptr +PlaylistManager::playlistForInterface( PlaylistInterface* interface ) const +{ + foreach ( PlaylistView* view, m_playlistViews.values() ) + { + if ( view->playlistInterface() == interface ) + { + return m_playlistViews.key( view ); + } + } + + return playlist_ptr(); +} + + +Tomahawk::dynplaylist_ptr +PlaylistManager::dynamicPlaylistForInterface( PlaylistInterface* interface ) const +{ + foreach ( DynamicWidget* view, m_dynamicWidgets.values() ) + { + if ( view->playlistInterface() == interface ) + { + return m_dynamicWidgets.key( view ); + } + } + + return dynplaylist_ptr(); +} + + +Tomahawk::collection_ptr +PlaylistManager::collectionForInterface( PlaylistInterface* interface ) const +{ + foreach ( CollectionView* view, m_collectionViews.values() ) + { + if ( view->playlistInterface() == interface ) + { + return m_collectionViews.key( view ); + } + } + foreach ( AlbumView* view, m_collectionAlbumViews.values() ) + { + if ( view->playlistInterface() == interface ) + { + return m_collectionAlbumViews.key( view ); + } + } + + return collection_ptr(); +} + + void PlaylistManager::showCurrentTrack() { - unlinkPlaylist(); - - m_currentInterface = AudioEngine::instance()->currentTrackPlaylist(); - - if ( m_currentInterface->widget() ) - m_stack->setCurrentWidget( m_currentInterface->widget() ); - - linkPlaylist(); - -/* if ( m_currentView && m_currentProxyModel ) - m_currentView->scrollTo( m_currentProxyModel->currentItem(), QAbstractItemView::PositionAtCenter );*/ + ViewPage* page = pageForInterface( AudioEngine::instance()->currentTrackPlaylist() ); + setPage( page ); } @@ -737,4 +797,4 @@ void PlaylistManager::onPauseClicked() { emit pauseClicked(); -} \ No newline at end of file +} diff --git a/src/libtomahawk/playlist/playlistmanager.h b/src/libtomahawk/playlist/playlistmanager.h index 3923b6f4c..722f7286e 100644 --- a/src/libtomahawk/playlist/playlistmanager.h +++ b/src/libtomahawk/playlist/playlistmanager.h @@ -7,6 +7,7 @@ #include "collection.h" #include "playlistinterface.h" +#include "viewpage.h" #include "dllmacro.h" @@ -27,7 +28,8 @@ class InfoBar; class TopBar; class WelcomeWidget; -namespace Tomahawk { +namespace Tomahawk +{ class DynamicWidget; } @@ -46,7 +48,10 @@ public: bool isSuperCollectionVisible() const { return true; } - PlaylistInterface* currentPlaylistInterface() const { return m_currentInterface; } + PlaylistInterface* currentPlaylistInterface() const; + Tomahawk::ViewPage* currentPage() const; + Tomahawk::ViewPage* pageForInterface( PlaylistInterface* interface ) const; + int positionInHistory( Tomahawk::ViewPage* page ) const; bool show( const Tomahawk::playlist_ptr& playlist ); bool show( const Tomahawk::dynplaylist_ptr& playlist ); @@ -55,7 +60,7 @@ public: bool show( const Tomahawk::collection_ptr& collection ); bool show( const Tomahawk::source_ptr& source ); - bool show( QWidget* widget, const QString& title = QString(), const QString& desc = QString(), const QPixmap& pixmap = QPixmap() ); + bool show( Tomahawk::ViewPage* page ); signals: void numSourcesChanged( unsigned int sources ); @@ -68,15 +73,29 @@ signals: void statsAvailable( bool b ); void modesAvailable( bool b ); + void modeChanged( PlaylistInterface::ViewMode mode ); void playClicked(); void pauseClicked(); + void historyBackAvailable( bool avail ); + void historyForwardAvailable( bool avail ); + + void tempPageActivated(); + void superCollectionActivated(); + void collectionActivated( const Tomahawk::collection_ptr& collection ); + void playlistActivated( const Tomahawk::playlist_ptr& playlist ); + void dynamicPlaylistActivated( const Tomahawk::dynplaylist_ptr& playlist ); + public slots: bool showSuperCollection(); void showWelcomePage(); void showCurrentTrack(); - + + void historyBack(); + void historyForward(); + void showHistory( int historyPosition ); + void setTreeMode(); void setTableMode(); void setAlbumMode(); @@ -103,9 +122,15 @@ private slots: void onWidgetDestroyed( QWidget* widget ); private: + void setHistoryPosition( int position ); + void setPage( Tomahawk::ViewPage* page, bool trackHistory = true ); + void updateView(); void unlinkPlaylist(); - void linkPlaylist(); + Tomahawk::playlist_ptr playlistForInterface( PlaylistInterface* interface ) const; + Tomahawk::dynplaylist_ptr dynamicPlaylistForInterface( PlaylistInterface* interface ) const; + Tomahawk::collection_ptr collectionForInterface( PlaylistInterface* interface ) const; + QWidget* m_widget; InfoBar* m_infobar; TopBar* m_topbar; @@ -130,19 +155,15 @@ private: QHash< Tomahawk::album_ptr, PlaylistView* > m_albumViews; QHash< Tomahawk::playlist_ptr, PlaylistView* > m_playlistViews; QHash< Tomahawk::source_ptr, SourceInfoWidget* > m_sourceViews; - - PlaylistInterface* m_currentInterface; - QList m_interfaceHistory; - - QWidget* m_currentInfoWidget; + + QList m_pageHistory; + int m_historyPosition; Tomahawk::collection_ptr m_currentCollection; int m_currentMode; bool m_superCollectionVisible; - bool m_statsAvailable; - bool m_modesAvailable; - + QTimer m_filterTimer; QString m_filter; diff --git a/src/libtomahawk/playlist/playlistmodel.cpp b/src/libtomahawk/playlist/playlistmodel.cpp index 620cc240b..660e9a1a7 100644 --- a/src/libtomahawk/playlist/playlistmodel.cpp +++ b/src/libtomahawk/playlist/playlistmodel.cpp @@ -67,8 +67,10 @@ PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEn connect( playlist.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), SLOT( onRevisionLoaded( Tomahawk::PlaylistRevision ) ) ); setReadOnly( !m_playlist->author()->isLocal() ); + setTitle( playlist->title() ); + setDescription( tr( "A playlist by %1" ).arg( playlist->author()->isLocal() ? tr( "you" ) : playlist->author()->friendlyName() ) ); - if( !loadEntries ) + if ( !loadEntries ) return; PlItem* plitem; diff --git a/src/libtomahawk/playlist/playlistview.cpp b/src/libtomahawk/playlist/playlistview.cpp index b2a367dfc..18abb0d01 100644 --- a/src/libtomahawk/playlist/playlistview.cpp +++ b/src/libtomahawk/playlist/playlistview.cpp @@ -4,7 +4,6 @@ #include #include -#include "playlist/playlistmodel.h" #include "playlist/playlistproxymodel.h" #include "widgets/overlaywidget.h" @@ -129,3 +128,10 @@ PlaylistView::onTrackCountChanged( unsigned int tracks ) else overlay()->hide(); } + + +bool +PlaylistView::jumpToCurrentTrack() +{ + scrollTo( proxyModel()->currentItem(), QAbstractItemView::PositionAtCenter ); +} diff --git a/src/libtomahawk/playlist/playlistview.h b/src/libtomahawk/playlist/playlistview.h index 1e7c80c70..26a543316 100644 --- a/src/libtomahawk/playlist/playlistview.h +++ b/src/libtomahawk/playlist/playlistview.h @@ -3,13 +3,16 @@ #include +#include "playlist/trackproxymodel.h" +#include "playlist/playlistmodel.h" #include "trackview.h" +#include "viewpage.h" #include "dllmacro.h" class PlaylistModel; -class DLLEXPORT PlaylistView : public TrackView +class DLLEXPORT PlaylistView : public TrackView, public Tomahawk::ViewPage { Q_OBJECT @@ -20,6 +23,14 @@ public: PlaylistModel* playlistModel() const { return m_model; } virtual void setModel( PlaylistModel* model ); + virtual QWidget* widget() { return this; } + virtual PlaylistInterface* playlistInterface() const { return proxyModel(); } + + virtual QString title() const { return playlistModel()->title(); } + virtual QString description() const { return m_model->description(); } + + virtual bool jumpToCurrentTrack(); + protected: void keyPressEvent( QKeyEvent* event ); diff --git a/src/libtomahawk/playlist/topbar/topbar.cpp b/src/libtomahawk/playlist/topbar/topbar.cpp index dd6705bfd..3aa584bf5 100644 --- a/src/libtomahawk/playlist/topbar/topbar.cpp +++ b/src/libtomahawk/playlist/topbar/topbar.cpp @@ -65,7 +65,28 @@ TopBar::TopBar( QWidget* parent ) setNumArtists( 0 ); setNumShown( 0 ); - ui->radioNormal->setChecked( true ); + onFlatMode(); + + connect( PlaylistManager::instance(), SIGNAL( numSourcesChanged( unsigned int ) ), + SLOT( setNumSources( unsigned int ) ) ); + + connect( PlaylistManager::instance(), SIGNAL( numTracksChanged( unsigned int ) ), + SLOT( setNumTracks( unsigned int ) ) ); + + connect( PlaylistManager::instance(), SIGNAL( numArtistsChanged( unsigned int ) ), + SLOT( setNumArtists( unsigned int ) ) ); + + connect( PlaylistManager::instance(), SIGNAL( numShownChanged( unsigned int ) ), + SLOT( setNumShown( unsigned int ) ) ); + + connect( PlaylistManager::instance(), SIGNAL( statsAvailable( bool ) ), + SLOT( setStatsVisible( bool ) ) ); + + connect( PlaylistManager::instance(), SIGNAL( modesAvailable( bool ) ), + SLOT( setModesVisible( bool ) ) ); + + connect( PlaylistManager::instance(), SIGNAL( modeChanged( PlaylistInterface::ViewMode ) ), + SLOT( onModeChanged( PlaylistInterface::ViewMode ) ) ); } @@ -238,3 +259,48 @@ TopBar::setFilter( const QString& filter ) { ui->filterEdit->setText( filter ); } + + +void +TopBar::onModeChanged( PlaylistInterface::ViewMode mode ) +{ + qDebug() << Q_FUNC_INFO << mode; + switch ( mode ) + { + case PlaylistInterface::Flat: + onFlatMode(); + break; + + case PlaylistInterface::Tree: + onArtistMode(); + break; + + case PlaylistInterface::Album: + onAlbumMode(); + break; + + default: + break; + } +} + + +void +TopBar::onFlatMode() +{ + ui->radioNormal->setChecked( true ); +} + + +void +TopBar::onArtistMode() +{ + ui->radioDetailed->setChecked( true ); +} + + +void +TopBar::onAlbumMode() +{ + ui->radioCloud->setChecked( true ); +} diff --git a/src/libtomahawk/playlist/topbar/topbar.h b/src/libtomahawk/playlist/topbar/topbar.h index f51b27e30..439768029 100644 --- a/src/libtomahawk/playlist/topbar/topbar.h +++ b/src/libtomahawk/playlist/topbar/topbar.h @@ -5,6 +5,7 @@ #include #include +#include "playlist/playlistmanager.h" #include "sourcelist.h" #include "dllmacro.h" @@ -42,6 +43,12 @@ public slots: void setFilter( const QString& filter ); +private slots: + void onModeChanged( PlaylistInterface::ViewMode mode ); + void onFlatMode(); + void onArtistMode(); + void onAlbumMode(); + protected: void changeEvent( QEvent* e ); void resizeEvent( QResizeEvent* e ); diff --git a/src/libtomahawk/playlist/trackmodel.h b/src/libtomahawk/playlist/trackmodel.h index ad43006be..f67b6631a 100644 --- a/src/libtomahawk/playlist/trackmodel.h +++ b/src/libtomahawk/playlist/trackmodel.h @@ -35,6 +35,11 @@ public: virtual bool isReadOnly() const { return m_readOnly; } + virtual QString title() const { return m_title; } + virtual void setTitle( const QString& title ) { m_title = title; } + virtual QString description() const { return m_description; } + virtual void setDescription( const QString& description ) { m_description = description; } + virtual int trackCount() const { return rowCount( QModelIndex() ); } virtual int rowCount( const QModelIndex& parent ) const; @@ -84,6 +89,9 @@ private slots: private: QPersistentModelIndex m_currentIndex; bool m_readOnly; + + QString m_title; + QString m_description; }; #endif // TRACKMODEL_H diff --git a/src/libtomahawk/playlist/trackview.cpp b/src/libtomahawk/playlist/trackview.cpp index c2a972ed1..bdc139773 100644 --- a/src/libtomahawk/playlist/trackview.cpp +++ b/src/libtomahawk/playlist/trackview.cpp @@ -73,7 +73,6 @@ void TrackView::setProxyModel( TrackProxyModel* model ) { m_proxyModel = model; - m_proxyModel->setWidget( this ); m_delegate = new PlaylistItemDelegate( this, m_proxyModel ); setItemDelegate( m_delegate ); diff --git a/src/libtomahawk/playlistinterface.h b/src/libtomahawk/playlistinterface.h index 7ef4fefd1..f8a56fa32 100644 --- a/src/libtomahawk/playlistinterface.h +++ b/src/libtomahawk/playlistinterface.h @@ -13,8 +13,9 @@ class DLLEXPORT PlaylistInterface { public: enum RepeatMode { NoRepeat, RepeatOne, RepeatAll }; - - PlaylistInterface( QObject* parent = 0 ) : m_widget( 0 ), m_object( parent ) {} + enum ViewMode { Unknown, Flat, Tree, Album }; + + PlaylistInterface( QObject* parent = 0 ) : m_object( parent ) {} virtual ~PlaylistInterface() {} virtual QList< Tomahawk::query_ptr > tracks() = 0; @@ -28,13 +29,11 @@ public: virtual PlaylistInterface::RepeatMode repeatMode() const = 0; virtual bool shuffled() const = 0; + virtual PlaylistInterface::ViewMode viewMode() const { return Unknown; } virtual QString filter() const { return m_filter; } virtual void setFilter( const QString& pattern ) { m_filter = pattern; } - QWidget* widget() const { return m_widget; } - void setWidget( QWidget* widget ) { m_widget = widget; } - QObject* object() const { return m_object; } public slots: @@ -48,7 +47,6 @@ signals: virtual void sourceTrackCountChanged( unsigned int tracks ) = 0; private: - QWidget* m_widget; QObject* m_object; QString m_filter; diff --git a/src/libtomahawk/viewpage.cpp b/src/libtomahawk/viewpage.cpp new file mode 100644 index 000000000..321bbbdf8 --- /dev/null +++ b/src/libtomahawk/viewpage.cpp @@ -0,0 +1,6 @@ +#include "viewpage.h" + +#include + +using namespace Tomahawk; + diff --git a/src/libtomahawk/viewpage.h b/src/libtomahawk/viewpage.h new file mode 100644 index 000000000..af087c669 --- /dev/null +++ b/src/libtomahawk/viewpage.h @@ -0,0 +1,38 @@ +#ifndef VIEWPAGE_H +#define VIEWPAGE_H + +#include + +#include "typedefs.h" +#include "playlistinterface.h" +#include "utils/tomahawkutils.h" + +#include "dllmacro.h" + +namespace Tomahawk +{ + +class DLLEXPORT ViewPage +{ +public: + ViewPage() {} + + virtual QWidget* widget() = 0; + virtual PlaylistInterface* playlistInterface() const = 0; + + virtual QString title() const = 0; + virtual QString description() const = 0; + virtual QPixmap pixmap() const { return QPixmap( RESPATH "icons/tomahawk-icon-128x128.png" ); } + + virtual bool showStatsBar() const { return true; } + virtual bool showModes() const { return false; } + virtual bool queueVisible() const { return true; } + + virtual bool jumpToCurrentTrack() = 0; + +private: +}; + +}; // ns + +#endif //VIEWPAGE_H diff --git a/src/libtomahawk/widgets/infowidgets/sourceinfowidget.cpp b/src/libtomahawk/widgets/infowidgets/sourceinfowidget.cpp index ad57103d2..80469499e 100644 --- a/src/libtomahawk/widgets/infowidgets/sourceinfowidget.cpp +++ b/src/libtomahawk/widgets/infowidgets/sourceinfowidget.cpp @@ -43,6 +43,8 @@ SourceInfoWidget::SourceInfoWidget( const Tomahawk::source_ptr& source, QWidget* m_recentAlbumModel = new AlbumModel( ui->recentAlbumView ); ui->recentAlbumView->setModel( m_recentAlbumModel ); m_recentAlbumModel->addFilteredCollection( source->collection(), 20, DatabaseCommand_AllAlbums::ModificationTime ); + + m_title = tr( "Info about %1" ).arg( source->isLocal() ? tr( "Your Collection" ) : source->friendlyName() ); } diff --git a/src/libtomahawk/widgets/infowidgets/sourceinfowidget.h b/src/libtomahawk/widgets/infowidgets/sourceinfowidget.h index 8d369a97e..f12fd942d 100644 --- a/src/libtomahawk/widgets/infowidgets/sourceinfowidget.h +++ b/src/libtomahawk/widgets/infowidgets/sourceinfowidget.h @@ -6,6 +6,7 @@ #include "album.h" #include "result.h" #include "playlistinterface.h" +#include "viewpage.h" #include "dllmacro.h" @@ -18,7 +19,7 @@ namespace Ui class SourceInfoWidget; } -class DLLEXPORT SourceInfoWidget : public QWidget +class DLLEXPORT SourceInfoWidget : public QWidget, public Tomahawk::ViewPage { Q_OBJECT @@ -26,6 +27,16 @@ public: SourceInfoWidget( const Tomahawk::source_ptr& source, QWidget* parent = 0 ); ~SourceInfoWidget(); + virtual QWidget* widget() { return this; } + virtual PlaylistInterface* playlistInterface() const { return 0; } + + virtual QString title() const { return m_title; } + virtual QString description() const { return m_description; } + + virtual bool showStatsBar() const { return false; } + + virtual bool jumpToCurrentTrack() { return false; } + protected: void changeEvent( QEvent* e ); @@ -38,6 +49,9 @@ private: CollectionFlatModel* m_recentCollectionModel; PlaylistModel* m_historyModel; AlbumModel* m_recentAlbumModel; + + QString m_title; + QString m_description; }; #endif // SOURCEINFOWIDGET_H diff --git a/src/libtomahawk/widgets/newplaylistwidget.h b/src/libtomahawk/widgets/newplaylistwidget.h index f19590aa7..dfe54a988 100644 --- a/src/libtomahawk/widgets/newplaylistwidget.h +++ b/src/libtomahawk/widgets/newplaylistwidget.h @@ -7,6 +7,7 @@ #include "album.h" #include "result.h" #include "playlistinterface.h" +#include "viewpage.h" #include "dllmacro.h" @@ -18,7 +19,7 @@ namespace Ui class NewPlaylistWidget; } -class DLLEXPORT NewPlaylistWidget : public QWidget +class DLLEXPORT NewPlaylistWidget : public QWidget, public Tomahawk::ViewPage { Q_OBJECT @@ -26,6 +27,16 @@ public: NewPlaylistWidget( QWidget* parent = 0 ); ~NewPlaylistWidget(); + virtual QWidget* widget() { return this; } + virtual PlaylistInterface* playlistInterface() const { return 0; } + + virtual QString title() const { return tr( "Create a new playlist" ); } + virtual QString description() const { return QString(); } + + virtual bool showStatsBar() const { return false; } + + virtual bool jumpToCurrentTrack() { return false; } + protected: void changeEvent( QEvent* e ); diff --git a/src/libtomahawk/widgets/newplaylistwidget.ui b/src/libtomahawk/widgets/newplaylistwidget.ui index 8b30f4780..6a2701ee8 100644 --- a/src/libtomahawk/widgets/newplaylistwidget.ui +++ b/src/libtomahawk/widgets/newplaylistwidget.ui @@ -11,28 +11,11 @@ - - - - - 20 - 75 - true - - - - Create A New Playlist - - - false - - - - 14 + 13 @@ -54,7 +37,7 @@ - 14 + 13 @@ -69,7 +52,7 @@ - 14 + 13 diff --git a/src/libtomahawk/widgets/welcomewidget.h b/src/libtomahawk/widgets/welcomewidget.h index 79f700448..9d14859e8 100644 --- a/src/libtomahawk/widgets/welcomewidget.h +++ b/src/libtomahawk/widgets/welcomewidget.h @@ -9,6 +9,7 @@ #include "playlist.h" #include "result.h" +#include "viewpage.h" #include "utils/tomahawkutils.h" @@ -73,7 +74,7 @@ private: }; -class DLLEXPORT WelcomeWidget : public QWidget +class DLLEXPORT WelcomeWidget : public QWidget, public Tomahawk::ViewPage { Q_OBJECT @@ -81,6 +82,16 @@ public: WelcomeWidget( QWidget* parent = 0 ); ~WelcomeWidget(); + virtual QWidget* widget() { return this; } + virtual PlaylistInterface* playlistInterface() const { return 0; } + + virtual QString title() const { return tr( "Welcome to Tomahawk" ); } + virtual QString description() const { return QString(); } + + virtual bool showStatsBar() const { return false; } + + virtual bool jumpToCurrentTrack() { return false; } + protected: void changeEvent( QEvent* e ); diff --git a/src/sip/jabber/jabber_p.cpp b/src/sip/jabber/jabber_p.cpp index a891973a9..cf090c107 100644 --- a/src/sip/jabber/jabber_p.cpp +++ b/src/sip/jabber/jabber_p.cpp @@ -526,7 +526,7 @@ Jabber_p::handleRosterPresence( const RosterItem& item, const std::string& resou // convert to QString to get proper regex support QString res( jid.resource().c_str() ); QRegExp regex( "tomahawk\\d+" ); - if( res != "tomahawk-tomahawk" && !res.contains( regex ) ) + if( res != "tomahawk-tomahawk" && !res.startsWith( "tomahawk" ) ) { //qDebug() << "not considering resource of" << res; // Disco them to check if they are tomahawk-capable diff --git a/src/sourcetree/sourcesmodel.cpp b/src/sourcetree/sourcesmodel.cpp index a84c7da7a..e2a95de0c 100644 --- a/src/sourcetree/sourcesmodel.cpp +++ b/src/sourcetree/sourcesmodel.cpp @@ -58,7 +58,8 @@ SourcesModel::flags( const QModelIndex& index ) const playlist_ptr playlist = indexToPlaylist( index ); if ( !playlist.isNull() && playlist->author()->isLocal() ) defaultFlags |= Qt::ItemIsEditable; - } else if ( indexType( index ) == DynamicPlaylistSource ) + } + else if ( indexType( index ) == DynamicPlaylistSource ) { dynplaylist_ptr playlist = indexToDynamicPlaylist( index ); if ( !playlist.isNull() && playlist->author()->isLocal() ) @@ -261,6 +262,75 @@ SourcesModel::indexToTreeItem( const QModelIndex& index ) } +QModelIndex +SourcesModel::playlistToIndex( const Tomahawk::playlist_ptr& playlist ) +{ + for ( int i = 0; i < rowCount(); i++ ) + { + QModelIndex pidx = index( i, 0 ); + + for ( int j = 0; j < rowCount( pidx ); j++ ) + { + QModelIndex idx = index( j, 0, pidx ); + SourcesModel::SourceType type = SourcesModel::indexType( idx ); + + if ( type == SourcesModel::PlaylistSource ) + { + playlist_ptr p = SourcesModel::indexToPlaylist( idx ); + if ( playlist.data() == p.data() ) + return idx; + } + } + } + + return QModelIndex(); +} + + +QModelIndex +SourcesModel::dynamicPlaylistToIndex( const Tomahawk::dynplaylist_ptr& playlist ) +{ + for ( int i = 0; i < rowCount(); i++ ) + { + QModelIndex pidx = index( i, 0 ); + + for ( int j = 0; j < rowCount( pidx ); j++ ) + { + QModelIndex idx = index( j, 0, pidx ); + SourcesModel::SourceType type = SourcesModel::indexType( idx ); + + if ( type == SourcesModel::DynamicPlaylistSource ) + { + playlist_ptr p = SourcesModel::indexToDynamicPlaylist( idx ); + if ( playlist.data() == p.data() ) + return idx; + } + } + } + + return QModelIndex(); +} + + +QModelIndex +SourcesModel::collectionToIndex( const Tomahawk::collection_ptr& collection ) +{ + for ( int i = 0; i < rowCount(); i++ ) + { + QModelIndex idx = index( i, 0 ); + SourcesModel::SourceType type = SourcesModel::indexType( idx ); + if ( type == SourcesModel::CollectionSource ) + { + SourceTreeItem* sti = SourcesModel::indexToTreeItem( idx ); + if ( sti && !sti->source().isNull() && sti->source()->collection().data() == collection.data() ) + return idx; + } + } + + return QModelIndex(); +} + + bool SourcesModel::setData( const QModelIndex& index, const QVariant& value, int role ) { diff --git a/src/sourcetree/sourcesmodel.h b/src/sourcetree/sourcesmodel.h index 2b761637b..e258e73ff 100644 --- a/src/sourcetree/sourcesmodel.h +++ b/src/sourcetree/sourcesmodel.h @@ -37,6 +37,10 @@ public: static Tomahawk::dynplaylist_ptr indexToDynamicPlaylist( const QModelIndex& index ); static SourceTreeItem* indexToTreeItem( const QModelIndex& index ); + QModelIndex playlistToIndex( const Tomahawk::playlist_ptr& playlist ); + QModelIndex dynamicPlaylistToIndex( const Tomahawk::dynplaylist_ptr& playlist ); + QModelIndex collectionToIndex( const Tomahawk::collection_ptr& collection ); + signals: void clicked( const QModelIndex& ); diff --git a/src/sourcetree/sourcetreeitem.cpp b/src/sourcetree/sourcetreeitem.cpp index 0e4ec8748..96fa06a8d 100644 --- a/src/sourcetree/sourcetreeitem.cpp +++ b/src/sourcetree/sourcetreeitem.cpp @@ -237,8 +237,8 @@ void SourceTreeItem::playlistAddedInternal( qlonglong ptr, const Tomahawk::playl subitem->setData( (qlonglong)this, SourceItemPointer ); m_columns.at( 0 )->appendRow( subitem ); - Q_ASSERT( qobject_cast((parent()->parent()) ) ); - qobject_cast((parent()->parent()))->expandAll(); +// Q_ASSERT( qobject_cast((parent()->parent()) ) ); +// qobject_cast((parent()->parent()))->expandAll(); p->loadRevision(); } diff --git a/src/sourcetree/sourcetreeview.cpp b/src/sourcetree/sourcetreeview.cpp index 916d725a0..177482a61 100644 --- a/src/sourcetree/sourcetreeview.cpp +++ b/src/sourcetree/sourcetreeview.cpp @@ -67,7 +67,7 @@ SourceTreeView::SourceTreeView( QWidget* parent ) setItemDelegate( new SourceDelegate( this ) ); setContextMenuPolicy( Qt::CustomContextMenu ); - connect( this, SIGNAL( customContextMenuRequested( const QPoint& ) ), SLOT( onCustomContextMenu( const QPoint& ) ) ); + connect( this, SIGNAL( customContextMenuRequested( QPoint ) ), SLOT( onCustomContextMenu( QPoint ) ) ); m_model = new SourcesModel( this ); m_proxyModel = new SourcesProxyModel( m_model, this ); @@ -77,14 +77,25 @@ SourceTreeView::SourceTreeView( QWidget* parent ) header()->setResizeMode( 0, QHeaderView::Stretch ); connect( m_model, SIGNAL( clicked( QModelIndex ) ), SIGNAL( clicked( QModelIndex ) ) ); - connect( this, SIGNAL( clicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) ); + connect( this, SIGNAL( clicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) ); - connect( selectionModel(), SIGNAL( selectionChanged( const QItemSelection&, const QItemSelection& ) ), SLOT( onSelectionChanged() ) ); + connect( selectionModel(), SIGNAL( selectionChanged( QItemSelection, QItemSelection ) ), SLOT( onSelectionChanged() ) ); connect( SourceList::instance(), SIGNAL( sourceRemoved( Tomahawk::source_ptr ) ), SLOT( onSourceOffline( Tomahawk::source_ptr ) ) ); m_model->appendItem( source_ptr() ); hideOfflineSources(); + + connect( PlaylistManager::instance(), SIGNAL( playlistActivated( Tomahawk::playlist_ptr ) ), + SLOT( onPlaylistActivated( Tomahawk::playlist_ptr ) ) ); + connect( PlaylistManager::instance(), SIGNAL( dynamicPlaylistActivated( Tomahawk::dynplaylist_ptr ) ), + SLOT( onDynamicPlaylistActivated( Tomahawk::dynplaylist_ptr ) ) ); + connect( PlaylistManager::instance(), SIGNAL( collectionActivated( Tomahawk::collection_ptr ) ), + SLOT( onCollectionActivated( Tomahawk::collection_ptr ) ) ); + connect( PlaylistManager::instance(), SIGNAL( superCollectionActivated() ), + SLOT( onSuperCollectionActivated() ) ); + connect( PlaylistManager::instance(), SIGNAL( tempPageActivated() ), + SLOT( onTempPageActivated() ) ); } @@ -143,6 +154,57 @@ SourceTreeView::onSourceOffline( Tomahawk::source_ptr src ) } +void +SourceTreeView::onPlaylistActivated( const Tomahawk::playlist_ptr& playlist ) +{ + QModelIndex idx = m_proxyModel->mapFromSource( m_model->playlistToIndex( playlist ) ); + if ( idx.isValid() ) + { + setCurrentIndex( idx ); + } +} + + +void +SourceTreeView::onDynamicPlaylistActivated( const Tomahawk::dynplaylist_ptr& playlist ) +{ + QModelIndex idx = m_proxyModel->mapFromSource( m_model->dynamicPlaylistToIndex( playlist ) ); + if ( idx.isValid() ) + { + setCurrentIndex( idx ); + } +} + + +void +SourceTreeView::onCollectionActivated( const Tomahawk::collection_ptr& collection ) +{ + QModelIndex idx = m_proxyModel->mapFromSource( m_model->collectionToIndex( collection ) ); + if ( idx.isValid() ) + { + setCurrentIndex( idx ); + } +} + + +void +SourceTreeView::onSuperCollectionActivated() +{ + QModelIndex idx = m_proxyModel->index( 0, 0 ); + if ( idx.isValid() ) + { + setCurrentIndex( idx ); + } +} + + +void +SourceTreeView::onTempPageActivated() +{ + clearSelection(); +} + + void SourceTreeView::onItemActivated( const QModelIndex& index ) { diff --git a/src/sourcetree/sourcetreeview.h b/src/sourcetree/sourcetreeview.h index 10df5d54d..077fb2937 100644 --- a/src/sourcetree/sourcetreeview.h +++ b/src/sourcetree/sourcetreeview.h @@ -27,6 +27,12 @@ signals: void onOffline( const QModelIndex& index ); private slots: + void onPlaylistActivated( const Tomahawk::playlist_ptr& playlist ); + void onDynamicPlaylistActivated( const Tomahawk::dynplaylist_ptr& playlist ); + void onCollectionActivated( const Tomahawk::collection_ptr& collection ); + void onSuperCollectionActivated(); + void onTempPageActivated(); + void onItemActivated( const QModelIndex& index ); void onSelectionChanged(); diff --git a/src/tomahawkwindow.cpp b/src/tomahawkwindow.cpp index b873accac..0fb8fd67d 100644 --- a/src/tomahawkwindow.cpp +++ b/src/tomahawkwindow.cpp @@ -56,6 +56,8 @@ TomahawkWindow::TomahawkWindow( QWidget* parent ) #endif PlaylistManager* pm = new PlaylistManager( this ); + connect( pm, SIGNAL( historyBackAvailable( bool ) ), SLOT( onHistoryBackAvailable( bool ) ) ); + connect( pm, SIGNAL( historyForwardAvailable( bool ) ), SLOT( onHistoryForwardAvailable( bool ) ) ); connect( m_audioControls, SIGNAL( playPressed() ), pm, SLOT( onPlayClicked() ) ); connect( m_audioControls, SIGNAL( pausePressed() ), pm, SLOT( onPauseClicked() ) ); @@ -119,9 +121,11 @@ TomahawkWindow::TomahawkWindow( QWidget* parent ) toolbar->setMovable( false ); toolbar->setFloatable( false ); toolbar->setIconSize( QSize( 32, 32 ) ); - toolbar->setToolButtonStyle( Qt::ToolButtonTextUnderIcon ); + toolbar->setToolButtonStyle( Qt::ToolButtonFollowStyle ); toolbar->installEventFilter( new WidgetDragFilter( toolbar ) ); + m_backAvailable = toolbar->addAction( QIcon( RESPATH "images/back.png" ), tr( "Back" ), PlaylistManager::instance(), SLOT( historyBack() ) ); + m_forwardAvailable = toolbar->addAction( QIcon( RESPATH "images/forward.png" ), tr( "Forward" ), PlaylistManager::instance(), SLOT( historyForward() ) ); toolbar->addAction( QIcon( RESPATH "images/home.png" ), tr( "Home" ), PlaylistManager::instance(), SLOT( showWelcomePage() ) ); statusBar()->addPermanentWidget( m_audioControls, 1 ); @@ -355,6 +359,20 @@ TomahawkWindow::onPlaybackLoading( const Tomahawk::result_ptr& result ) } +void +TomahawkWindow::onHistoryBackAvailable( bool avail ) +{ + m_backAvailable->setEnabled( avail ); +} + + +void +TomahawkWindow::onHistoryForwardAvailable( bool avail ) +{ + m_forwardAvailable->setEnabled( avail ); +} + + void TomahawkWindow::onSipConnected() { diff --git a/src/tomahawkwindow.h b/src/tomahawkwindow.h index 5e6a24472..766066cd8 100644 --- a/src/tomahawkwindow.h +++ b/src/tomahawkwindow.h @@ -54,7 +54,9 @@ private slots: void addPeerManually(); void onPlaybackLoading( const Tomahawk::result_ptr& result ); - + void onHistoryBackAvailable( bool avail ); + void onHistoryForwardAvailable( bool avail ); + void showAboutTomahawk(); private: @@ -68,6 +70,9 @@ private: QNetworkAccessManager m_nam; QPushButton* m_statusButton; + QAction* m_backAvailable; + QAction* m_forwardAvailable; + Tomahawk::result_ptr m_currentTrack; QString m_windowTitle; };