From 07cb94b1bcbdadae35427a06469125ea481467ad Mon Sep 17 00:00:00 2001 From: Leo Franchi Date: Sun, 29 May 2011 16:56:25 -0400 Subject: [PATCH] Add a new source item for temporary pages. This fixes TWK-182. Also, ensure that what is selected on the left is always in sync with what is on the right. In addition, expand the parent nodes when selecting an item automatically in the tree. --- .../playlist/dynamic/DynamicModel.cpp | 5 ++- src/libtomahawk/playlist/playlistmodel.cpp | 20 +++++++++ src/libtomahawk/playlist/playlistmodel.h | 3 +- src/libtomahawk/playlist/playlistview.cpp | 14 +++++++ src/libtomahawk/playlist/playlistview.h | 3 ++ src/libtomahawk/viewmanager.cpp | 18 ++------ src/libtomahawk/viewmanager.h | 8 +--- src/libtomahawk/viewpage.h | 3 ++ src/sourcetree/items/collectionitem.cpp | 42 +++++++++++++++++++ src/sourcetree/items/collectionitem.h | 12 ++++++ src/sourcetree/items/genericpageitems.cpp | 7 ++++ src/sourcetree/items/genericpageitems.h | 1 + src/sourcetree/items/sourcetreeitem.cpp | 2 +- src/sourcetree/items/sourcetreeitem.h | 1 + src/sourcetree/sourcesmodel.cpp | 6 +++ src/sourcetree/sourcesmodel.h | 1 + src/sourcetree/sourcetreeview.cpp | 6 ++- 17 files changed, 125 insertions(+), 27 deletions(-) diff --git a/src/libtomahawk/playlist/dynamic/DynamicModel.cpp b/src/libtomahawk/playlist/dynamic/DynamicModel.cpp index 6e7a16de8..74d1fb2cc 100644 --- a/src/libtomahawk/playlist/dynamic/DynamicModel.cpp +++ b/src/libtomahawk/playlist/dynamic/DynamicModel.cpp @@ -64,7 +64,10 @@ DynamicModel::loadPlaylist( const Tomahawk::dynplaylist_ptr& playlist, bool load QString DynamicModel::description() const { - return m_playlist->generator()->sentenceSummary(); + if( !m_playlist.isNull() && !m_playlist->generator().isNull() ) + return m_playlist->generator()->sentenceSummary(); + else + return QString(); } diff --git a/src/libtomahawk/playlist/playlistmodel.cpp b/src/libtomahawk/playlist/playlistmodel.cpp index 1e1ee0889..65c157d9c 100644 --- a/src/libtomahawk/playlist/playlistmodel.cpp +++ b/src/libtomahawk/playlist/playlistmodel.cpp @@ -34,6 +34,7 @@ using namespace Tomahawk; PlaylistModel::PlaylistModel( QObject* parent ) : TrackModel( parent ) , m_waitForUpdate( false ) + , m_isTemporary( false ) { qDebug() << Q_FUNC_INFO; @@ -91,6 +92,7 @@ PlaylistModel::loadPlaylist( const Tomahawk::playlist_ptr& playlist, bool loadEn setTitle( playlist->title() ); setDescription( tr( "A playlist by %1" ).arg( playlist->author()->isLocal() ? tr( "you" ) : playlist->author()->friendlyName() ) ); + m_isTemporary = false; if ( !loadEntries ) return; @@ -192,6 +194,12 @@ PlaylistModel::append( const Tomahawk::album_ptr& album ) connect( album.data(), SIGNAL( tracksAdded( QList ) ), SLOT( onTracksAdded( QList ) ) ); + if( rowCount( QModelIndex() ) == 0 ) { + setTitle( album->name() ); + setDescription( tr( "All tracks by %1 on album %2" ).arg( album->artist()->name() ).arg( album->name() ) ); + m_isTemporary = true; + } + onTracksAdded( album->tracks() ); } @@ -205,6 +213,12 @@ PlaylistModel::append( const Tomahawk::artist_ptr& artist ) connect( artist.data(), SIGNAL( tracksAdded( QList ) ), SLOT( onTracksAdded( QList ) ) ); + if( rowCount( QModelIndex() ) == 0 ) { + setTitle( artist->name() ); + setDescription( tr( "All tracks by %1" ).arg( artist->name() ) ); + m_isTemporary = true; + } + onTracksAdded( artist->tracks() ); } @@ -494,3 +508,9 @@ PlaylistModel::removeIndex( const QModelIndex& index, bool moreToCome ) onPlaylistChanged(); } } + +bool +PlaylistModel::isTemporary() const +{ + return m_isTemporary; +} diff --git a/src/libtomahawk/playlist/playlistmodel.h b/src/libtomahawk/playlist/playlistmodel.h index 96cfb72ce..30af9f4ea 100644 --- a/src/libtomahawk/playlist/playlistmodel.h +++ b/src/libtomahawk/playlist/playlistmodel.h @@ -67,6 +67,7 @@ public: void remove( unsigned int row, bool moreToCome = false ); virtual void removeIndex( const QModelIndex& index, bool moreToCome = false ); + bool isTemporary() const; signals: void repeatModeChanged( PlaylistInterface::RepeatMode mode ); void shuffleModeChanged( bool enabled ); @@ -90,7 +91,7 @@ private: QList playlistEntries() const; Tomahawk::playlist_ptr m_playlist; - bool m_waitForUpdate; + bool m_waitForUpdate, m_isTemporary; QList< Tomahawk::Query* > m_waitingForResolved; }; diff --git a/src/libtomahawk/playlist/playlistview.cpp b/src/libtomahawk/playlist/playlistview.cpp index be01df8ec..5000bd80c 100644 --- a/src/libtomahawk/playlist/playlistview.cpp +++ b/src/libtomahawk/playlist/playlistview.cpp @@ -71,8 +71,12 @@ PlaylistView::setPlaylistModel( PlaylistModel* model ) if ( !m_model->playlist().isNull() ) setGuid( QString( "playlistview/%1" ).arg( m_model->playlist()->guid() ) ); else + { setGuid( "playlistview" ); + m_model->title(); + m_model->description(); + } connect( m_model, SIGNAL( trackCountChanged( unsigned int ) ), SLOT( onTrackCountChanged( unsigned int ) ) ); connect( m_model, SIGNAL( playlistDeleted() ), SLOT( onDeleted() ) ); connect( m_model, SIGNAL( playlistChanged() ), SLOT( onChanged() ) ); @@ -191,3 +195,13 @@ PlaylistView::onChanged() ViewManager::instance()->currentPage() == this ) emit nameChanged( m_model->playlist()->title() ); } + +bool +PlaylistView::isTemporaryPage() const +{ + if ( m_model ) { + return m_model->isTemporary(); + } else { + return false; + } +} diff --git a/src/libtomahawk/playlist/playlistview.h b/src/libtomahawk/playlist/playlistview.h index fe845d5b8..c42ff1248 100644 --- a/src/libtomahawk/playlist/playlistview.h +++ b/src/libtomahawk/playlist/playlistview.h @@ -52,6 +52,7 @@ public: virtual QPixmap pixmap() const { return QPixmap( RESPATH "images/playlist-icon.png" ); } virtual bool jumpToCurrentTrack(); + virtual bool isTemporaryPage() const; signals: void nameChanged( const QString& title ); @@ -75,6 +76,8 @@ private: PlaylistModel* m_model; QMenu m_itemMenu; + QString m_customTitle; + QString m_customDescripton; QAction* m_playItemAction; QAction* m_addItemsToQueueAction; diff --git a/src/libtomahawk/viewmanager.cpp b/src/libtomahawk/viewmanager.cpp index efb2ca5ad..6b9380aef 100644 --- a/src/libtomahawk/viewmanager.cpp +++ b/src/libtomahawk/viewmanager.cpp @@ -599,24 +599,12 @@ ViewManager::setPage( ViewPage* page, bool trackHistory ) setHistoryPosition( m_pageHistory.count() - 1 ); } - if ( !playlistForInterface( currentPlaylistInterface() ).isNull() ) - emit playlistActivated( playlistForInterface( currentPlaylistInterface() ) ); - - else if ( dynamicPlaylistForInterface( currentPlaylistInterface() ) ) - emit dynamicPlaylistActivated( dynamicPlaylistForInterface( currentPlaylistInterface() ) ); - else if ( collectionForInterface( currentPlaylistInterface() ) ) - emit collectionActivated( collectionForInterface( currentPlaylistInterface() ) ); - else if ( isSuperCollectionVisible() ) - emit superCollectionActivated(); - else if( isNewPlaylistPageVisible() ) - emit newPlaylistActivated(); - /* TODO refactor. now we have rows in the sourcetreeview that are connected to pages, e.g. Stations, Recently Updated, etc - else if ( !currentPlaylistInterface() ) - emit tempPageActivated();*/ - qDebug() << "View page shown:" << page->title(); emit viewPageActivated( page ); + if( page->isTemporaryPage() ) + emit tempPageActivated( page ); + if ( !AudioEngine::instance()->playlist() ) AudioEngine::instance()->setPlaylist( currentPlaylistInterface() ); diff --git a/src/libtomahawk/viewmanager.h b/src/libtomahawk/viewmanager.h index 0070f95e8..234e9c846 100644 --- a/src/libtomahawk/viewmanager.h +++ b/src/libtomahawk/viewmanager.h @@ -111,13 +111,7 @@ signals: 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 ); - - void newPlaylistActivated(); + void tempPageActivated( Tomahawk::ViewPage* ); void viewPageActivated( Tomahawk::ViewPage* ); public slots: diff --git a/src/libtomahawk/viewpage.h b/src/libtomahawk/viewpage.h index 0921998b2..31e18ba3e 100644 --- a/src/libtomahawk/viewpage.h +++ b/src/libtomahawk/viewpage.h @@ -51,7 +51,10 @@ public: virtual bool jumpToCurrentTrack() = 0; + virtual bool isTemporaryPage() const { return false; } + /** subclasses implementing ViewPage can emit the following signals: + * nameChanged( const QString& ) * descriptionChanged( const QString& ) * destroyed( QWidget* widget ); * diff --git a/src/sourcetree/items/collectionitem.cpp b/src/sourcetree/items/collectionitem.cpp index a559fbc83..4aa76867b 100644 --- a/src/sourcetree/items/collectionitem.cpp +++ b/src/sourcetree/items/collectionitem.cpp @@ -21,6 +21,7 @@ #include "playlistitems.h" #include "viewmanager.h" #include "playlist.h" +#include "genericpageitems.h" /// CollectionItem @@ -31,8 +32,12 @@ CollectionItem::CollectionItem( SourcesModel* mdl, SourceTreeItem* parent, cons , m_source( source ) , m_playlists( 0 ) , m_stations( 0 ) + , m_tempItem( 0 ) + , m_curTempPage( 0 ) { if( m_source.isNull() ) { // super collection + connect( ViewManager::instance(), SIGNAL( tempPageActivated( Tomahawk::ViewPage*) ), this, SLOT( tempPageActivated( Tomahawk::ViewPage* ) ) ); + return; } // create category items if there are playlists to show, or stations to show @@ -264,3 +269,40 @@ CollectionItem::onStationsDeleted( const QList< dynplaylist_ptr >& stations ) { playlistsDeletedInternal( m_stations, stations ); } + +void +CollectionItem::tempPageActivated( Tomahawk::ViewPage* v ) +{ + QString name = v->title(); + m_curTempPage = v; + if( !m_tempItem ) { + emit beginRowsAdded( children().count(), children().count() ); + m_tempItem = new GenericPageItem( model(), this, name, QIcon( RESPATH "images/playlist-icon.png" ), + boost::bind( &CollectionItem::tempItemClicked, this ), + boost::bind( &CollectionItem::getTempPage, this ) + ); + emit endRowsAdded(); + } else { + m_tempItem->setText( name ); + } + + model()->linkSourceItemToPage( m_tempItem, v ); + emit selectRequest( m_tempItem ); +} + +ViewPage* +CollectionItem::tempItemClicked() +{ + if( m_curTempPage ) { + // show the last temporary page the user displayed + return ViewManager::instance()->show( m_curTempPage ); + } + + return 0; +} + +ViewPage* +CollectionItem::getTempPage() const +{ + return m_curTempPage; +} diff --git a/src/sourcetree/items/collectionitem.h b/src/sourcetree/items/collectionitem.h index 1cb99e0cb..8bb23bee7 100644 --- a/src/sourcetree/items/collectionitem.h +++ b/src/sourcetree/items/collectionitem.h @@ -19,7 +19,11 @@ #include "sourcetreeitem.h" +class GenericPageItem; class CategoryItem; +namespace Tomahawk { + class ViewPage; +} class CollectionItem : public SourceTreeItem { @@ -38,6 +42,7 @@ public: CategoryItem* playlistsCategory() const { return m_playlists; } void setStationsCategory( CategoryItem* item ) { m_stations = item; } void setPlaylistsCategory( CategoryItem* item ) { m_playlists = item; } + private slots: void onPlaylistsAdded( const QList& playlists ); void onPlaylistsDeleted( const QList& playlists ); @@ -46,6 +51,10 @@ private slots: void onStationsAdded( const QList& stations ); void onStationsDeleted( const QList& stations ); + void tempPageActivated( Tomahawk::ViewPage* ); + Tomahawk::ViewPage* tempItemClicked(); + Tomahawk::ViewPage* getTempPage() const; + private: void playlistsAddedInternal( SourceTreeItem* parent, const QList< Tomahawk::dynplaylist_ptr >& playlists ); template< typename T > @@ -54,6 +63,9 @@ private: Tomahawk::source_ptr m_source; CategoryItem* m_playlists; CategoryItem* m_stations; + + GenericPageItem* m_tempItem; + Tomahawk::ViewPage* m_curTempPage; }; diff --git a/src/sourcetree/items/genericpageitems.cpp b/src/sourcetree/items/genericpageitems.cpp index 47f05605d..3739fa7cb 100644 --- a/src/sourcetree/items/genericpageitems.cpp +++ b/src/sourcetree/items/genericpageitems.cpp @@ -63,3 +63,10 @@ GenericPageItem::willAcceptDrag(const QMimeData* data) const { return false; } + +void +GenericPageItem::setText( const QString &text ) +{ + m_text = text; + emit updated(); +} diff --git a/src/sourcetree/items/genericpageitems.h b/src/sourcetree/items/genericpageitems.h index 1c0e954e4..5a980f7c3 100644 --- a/src/sourcetree/items/genericpageitems.h +++ b/src/sourcetree/items/genericpageitems.h @@ -36,6 +36,7 @@ public: virtual bool willAcceptDrag( const QMimeData* data ) const; virtual QIcon icon() const; + void setText( const QString& text ); signals: void activated(); diff --git a/src/sourcetree/items/sourcetreeitem.cpp b/src/sourcetree/items/sourcetreeitem.cpp index f1169cc28..ffe039ee6 100644 --- a/src/sourcetree/items/sourcetreeitem.cpp +++ b/src/sourcetree/items/sourcetreeitem.cpp @@ -30,7 +30,7 @@ SourceTreeItem::SourceTreeItem( SourcesModel* model, SourceTreeItem* parent, Sou connect( this, SIGNAL( childRowsAdded() ), m_model, SLOT( onItemRowsAddedDone() ) ); connect( this, SIGNAL( childRowsRemoved() ), m_model, SLOT( onItemRowsRemovedDone() ) ); connect( this, SIGNAL( updated() ), m_model, SLOT( itemUpdated() ) ); - + connect( this, SIGNAL( selectRequest( SourceTreeItem* ) ), m_model, SLOT( itemSelectRequest( SourceTreeItem* ) ) ); if( !m_parent ) return; diff --git a/src/sourcetree/items/sourcetreeitem.h b/src/sourcetree/items/sourcetreeitem.h index 290e72f15..57553988e 100644 --- a/src/sourcetree/items/sourcetreeitem.h +++ b/src/sourcetree/items/sourcetreeitem.h @@ -62,6 +62,7 @@ public: signals: void updated(); + void selectRequest( SourceTreeItem* ); void beginChildRowsAdded( int fromRow, int toRow ); void childRowsAdded(); diff --git a/src/sourcetree/sourcesmodel.cpp b/src/sourcetree/sourcesmodel.cpp index 8fc2971e7..04384ae9c 100644 --- a/src/sourcetree/sourcesmodel.cpp +++ b/src/sourcetree/sourcesmodel.cpp @@ -448,3 +448,9 @@ SourcesModel::rowForItem( SourceTreeItem* item ) const { return item->parent()->children().indexOf( item ); } + +void +SourcesModel::itemSelectRequest( SourceTreeItem* item ) +{ + emit selectRequest( indexFromItem( item ) ); +} diff --git a/src/sourcetree/sourcesmodel.h b/src/sourcetree/sourcesmodel.h index 5455da673..c702b4b4b 100644 --- a/src/sourcetree/sourcesmodel.h +++ b/src/sourcetree/sourcesmodel.h @@ -101,6 +101,7 @@ public slots: void viewPageActivated( Tomahawk::ViewPage* ); + void itemSelectRequest( SourceTreeItem* item ); signals: void selectRequest( const QModelIndex& idx ); diff --git a/src/sourcetree/sourcetreeview.cpp b/src/sourcetree/sourcetreeview.cpp index cf73e7fb4..fe94ff5e9 100644 --- a/src/sourcetree/sourcetreeview.cpp +++ b/src/sourcetree/sourcetreeview.cpp @@ -198,9 +198,11 @@ SourceTreeView::onItemExpanded( const QModelIndex& idx ) void SourceTreeView::selectRequest( const QModelIndex& idx ) { - if( !selectionModel()->selectedIndexes().contains( idx ) ) + if ( !selectionModel()->selectedIndexes().contains( idx ) ) + { + scrollTo( idx, QTreeView::EnsureVisible ); selectionModel()->select( idx, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Current ); - + } }