diff --git a/src/libtomahawk/globalactionmanager.cpp b/src/libtomahawk/globalactionmanager.cpp index 664550688..1dd335571 100644 --- a/src/libtomahawk/globalactionmanager.cpp +++ b/src/libtomahawk/globalactionmanager.cpp @@ -85,14 +85,14 @@ GlobalActionManager::openLinkFromQuery( const Tomahawk::query_ptr& query ) const return link; } -void +QString GlobalActionManager::copyPlaylistToClipboard( const Tomahawk::dynplaylist_ptr& playlist ) { QUrl link( QString( "tomahawk://%1/create/" ).arg( playlist->mode() == Tomahawk::OnDemand ? "station" : "autoplaylist" ) ); if( playlist->generator()->type() != "echonest" ) { qDebug() << "Only echonest generators are supported"; - return; + return QString(); } link.addEncodedQueryItem( "type", "echonest" ); @@ -123,6 +123,8 @@ GlobalActionManager::copyPlaylistToClipboard( const Tomahawk::dynplaylist_ptr& p QClipboard* cb = QApplication::clipboard(); cb->setText( link.toEncoded() ); + + return link.toString(); } void @@ -380,22 +382,22 @@ GlobalActionManager::handleSearchCommand( const QUrl& url ) bool GlobalActionManager::handleAutoPlaylistCommand( const QUrl& url ) { - return loadDynamicPlaylist( url, false ); + return !loadDynamicPlaylist( url, false ).isNull(); } -bool +Tomahawk::dynplaylist_ptr GlobalActionManager::loadDynamicPlaylist( const QUrl& url, bool station ) { QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command if( parts.isEmpty() ) { qDebug() << "No specific station command:" << url.toString(); - return false; + return Tomahawk::dynplaylist_ptr(); } if( parts[ 0 ] == "create" ) { if( !url.hasQueryItem( "title" ) || !url.hasQueryItem( "type" ) ) { qDebug() << "Station create command needs title and type..." << url.toString(); - return false; + return Tomahawk::dynplaylist_ptr(); } QString title = url.queryItemValue( "title" ); QString type = url.queryItemValue( "type" ); @@ -520,17 +522,17 @@ GlobalActionManager::loadDynamicPlaylist( const QUrl& url, bool station ) else pl->createNewRevision( uuid(), pl->currentrevision(), type, controls, pl->entries() ); - return true; + return pl; } - return false; + return Tomahawk::dynplaylist_ptr(); } bool GlobalActionManager::handleStationCommand( const QUrl& url ) { - return loadDynamicPlaylist( url, true ); + return !loadDynamicPlaylist( url, true ).isNull(); } bool diff --git a/src/libtomahawk/globalactionmanager.h b/src/libtomahawk/globalactionmanager.h index 061d1609a..c7b9d71dc 100644 --- a/src/libtomahawk/globalactionmanager.h +++ b/src/libtomahawk/globalactionmanager.h @@ -38,13 +38,14 @@ public: QUrl openLinkFromQuery( const Tomahawk::query_ptr& query ) const; void copyToClipboard( const Tomahawk::query_ptr& query ) const; - void copyPlaylistToClipboard( const Tomahawk::dynplaylist_ptr& playlist ); + QString copyPlaylistToClipboard( const Tomahawk::dynplaylist_ptr& playlist ); void savePlaylistToFile( const Tomahawk::playlist_ptr& playlist, const QString& filename ); public slots: bool parseTomahawkLink( const QString& link ); void waitingForResolved( bool ); + Tomahawk::dynplaylist_ptr loadDynamicPlaylist( const QUrl& url, bool station ); private slots: void bookmarkPlaylistCreated( const Tomahawk::playlist_ptr& pl ); void showPlaylist(); @@ -65,7 +66,6 @@ private: bool handleBookmarkCommand(const QUrl& url ); bool handleOpenCommand(const QUrl& url ); - bool loadDynamicPlaylist( const QUrl& url, bool station ); bool doQueueAdd( const QStringList& parts, const QList< QPair< QString, QString > >& queryItems ); Tomahawk::playlist_ptr m_toShow; diff --git a/src/sourcetree/sourcetreeview.cpp b/src/sourcetree/sourcetreeview.cpp index fe94ff5e9..8b21bb176 100644 --- a/src/sourcetree/sourcetreeview.cpp +++ b/src/sourcetree/sourcetreeview.cpp @@ -143,10 +143,20 @@ SourceTreeView::setupMenus() m_copyPlaylistAction = m_playlistMenu.addAction( tr( "&Copy Link" ) ); m_deletePlaylistAction = m_playlistMenu.addAction( tr( "&Delete %1" ).arg( SourcesModel::rowTypeToString( type ) ) ); - m_roPlaylistMenu.addAction( m_copyPlaylistAction ); + QString addToText = QString( "Add to my %1" ); + if ( type == SourcesModel::StaticPlaylist ) + addToText = addToText.arg( "Playlists" ); + if ( type == SourcesModel::AutomaticPlaylist ) + addToText = addToText.arg( "Automatic Playlists" ); + else if ( type == SourcesModel::Station ) + addToText = addToText.arg( "Stations" ); + m_addToLocalAction = m_roPlaylistMenu.addAction( tr( addToText.toUtf8(), "Adds the given playlist, dynamic playlist, or station to the users's own list" ) ); + + m_roPlaylistMenu.addAction( m_copyPlaylistAction ); m_deletePlaylistAction->setEnabled( !readonly ); m_renamePlaylistAction->setEnabled( !readonly ); + m_addToLocalAction->setEnabled( readonly ); if ( type == SourcesModel::StaticPlaylist ) m_copyPlaylistAction->setText( tr( "&Export Playlist" ) ); @@ -155,6 +165,7 @@ SourceTreeView::setupMenus() connect( m_renamePlaylistAction, SIGNAL( triggered() ), SLOT( renamePlaylist() ) ); connect( m_deletePlaylistAction, SIGNAL( triggered() ), SLOT( deletePlaylist() ) ); connect( m_copyPlaylistAction, SIGNAL( triggered() ), SLOT( copyPlaylistLink() ) ); + connect( m_addToLocalAction, SIGNAL( triggered() ), SLOT( addToLocal() ) ); } @@ -259,6 +270,36 @@ SourceTreeView::copyPlaylistLink() } } +void SourceTreeView::addToLocal() +{ + QModelIndex idx = m_contextMenuIndex; + if ( !idx.isValid() ) + return; + + SourcesModel::RowType type = ( SourcesModel::RowType )model()->data( m_contextMenuIndex, SourcesModel::SourceTreeItemTypeRole ).toInt(); + if( type == SourcesModel::AutomaticPlaylist || type == SourcesModel::Station ) + { + DynamicPlaylistItem* item = itemFromIndex< DynamicPlaylistItem >( m_contextMenuIndex ); + dynplaylist_ptr playlist = item->dynPlaylist(); + + // copy to a link and then generate a new playlist from that + // this way we cheaply regenerate the needed controls + QString link = GlobalActionManager::instance()->copyPlaylistToClipboard( playlist ); + dynplaylist_ptr p = GlobalActionManager::instance()->loadDynamicPlaylist( link, type == SourcesModel::Station ); + } else if ( type == SourcesModel::StaticPlaylist ) + { + PlaylistItem* item = itemFromIndex< PlaylistItem >( m_contextMenuIndex ); + playlist_ptr playlist = item->playlist(); + + // just create the new playlist with the same values + QList< query_ptr > queries; + foreach( const plentry_ptr& e, playlist->entries() ) + queries << e->query(); + + playlist_ptr newpl = Playlist::create( SourceList::instance()->getLocal(), uuid(), playlist->title(), playlist->info(), playlist->creator(), playlist->shared(), queries ); + } +} + void SourceTreeView::renamePlaylist() diff --git a/src/sourcetree/sourcetreeview.h b/src/sourcetree/sourcetreeview.h index d3d6eb97e..7964122f0 100644 --- a/src/sourcetree/sourcetreeview.h +++ b/src/sourcetree/sourcetreeview.h @@ -54,6 +54,7 @@ private slots: void loadPlaylist(); void deletePlaylist( const QModelIndex& = QModelIndex() ); void copyPlaylistLink(); + void addToLocal(); void onCustomContextMenu( const QPoint& pos ); protected: @@ -84,6 +85,7 @@ private: QAction* m_renamePlaylistAction; QAction* m_deletePlaylistAction; QAction* m_copyPlaylistAction; + QAction* m_addToLocalAction; bool m_dragging; QRect m_dropRect;