diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3473eb270..45cf481d1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -39,7 +39,6 @@ SET( tomahawkSources ${tomahawkSources} musicscanner.cpp shortcuthandler.cpp - globalactionmanager.cpp scanmanager.cpp tomahawkapp.cpp main.cpp @@ -84,7 +83,6 @@ SET( tomahawkHeaders ${tomahawkHeaders} musicscanner.h scanmanager.h shortcuthandler.h - globalactionmanager.h ) IF(LIBLASTFM_FOUND) diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index 7db52f153..aab9a3e60 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -29,6 +29,7 @@ set( libSources source.cpp viewpage.cpp viewmanager.cpp + globalactionmanager.cpp sip/SipPlugin.cpp sip/SipHandler.cpp @@ -159,6 +160,7 @@ set( libSources widgets/newplaylistwidget.cpp widgets/welcomewidget.cpp + widgets/welcomeplaylistmodel.cpp widgets/overlaywidget.cpp widgets/infowidgets/sourceinfowidget.cpp @@ -183,6 +185,7 @@ set( libHeaders source.h viewpage.h viewmanager.h + globalactionmanager.h artist.h album.h @@ -318,6 +321,7 @@ set( libHeaders widgets/newplaylistwidget.h widgets/welcomewidget.h + widgets/welcomeplaylistmodel.h widgets/overlaywidget.h widgets/infowidgets/sourceinfowidget.h diff --git a/src/libtomahawk/collection.cpp b/src/libtomahawk/collection.cpp index b22e1b105..3aac8bda1 100644 --- a/src/libtomahawk/collection.cpp +++ b/src/libtomahawk/collection.cpp @@ -153,7 +153,6 @@ Collection::deleteStation( const dynplaylist_ptr& s ) playlist_ptr Collection::playlist( const QString& guid ) { - qDebug() << "Returning playlist for guid:" << guid << "found?" << m_playlists.contains( guid ); return m_playlists.value( guid, playlist_ptr() ); } @@ -161,7 +160,6 @@ Collection::playlist( const QString& guid ) dynplaylist_ptr Collection::autoPlaylist( const QString& guid ) { - qDebug() << "Returning auto playlist for guid:" << guid << "found?" << m_autoplaylists.contains( guid ); return m_autoplaylists.value( guid, dynplaylist_ptr() ); } @@ -169,7 +167,6 @@ dynplaylist_ptr Collection::station( const QString& guid ) { - qDebug() << "Returning station for guid:" << guid << "found?" << m_stations.contains( guid ); return m_stations.value( guid, dynplaylist_ptr() ); } diff --git a/src/globalactionmanager.cpp b/src/libtomahawk/globalactionmanager.cpp similarity index 73% rename from src/globalactionmanager.cpp rename to src/libtomahawk/globalactionmanager.cpp index 2f9d64279..1526b96b3 100644 --- a/src/globalactionmanager.cpp +++ b/src/libtomahawk/globalactionmanager.cpp @@ -31,6 +31,8 @@ #include #include +#include +#include GlobalActionManager* GlobalActionManager::s_instance = 0; @@ -53,6 +55,28 @@ GlobalActionManager::GlobalActionManager( QObject* parent ) GlobalActionManager::~GlobalActionManager() {} +QUrl +GlobalActionManager::openLinkFromQuery( const Tomahawk::query_ptr& query ) const +{ + QUrl link( "tomahawk://open/track/" ); + if( !query->track().isEmpty() ) + link.addQueryItem( "title", query->track() ); + if( !query->artist().isEmpty() ) + link.addQueryItem( "artist", query->artist() ); + if( !query->album().isEmpty() ) + link.addQueryItem( "album", query->album() ); + + return link; +} + +void +GlobalActionManager::copyToClipboard( const Tomahawk::query_ptr& query ) const +{ + QClipboard* cb = QApplication::clipboard(); + cb->setText( openLinkFromQuery( query ).toEncoded() ); +} + + bool GlobalActionManager::parseTomahawkLink( const QString& url ) { @@ -88,6 +112,10 @@ GlobalActionManager::parseTomahawkLink( const QString& url ) return handleSearchCommand( u ); } else if( cmdType == "play" ) { return handlePlayCommand( u ); + } else if( cmdType == "bookmark" ) { + return handlePlayCommand( u ); + } else if( cmdType == "open" ) { + return handleOpenCommand( u ); } else { qDebug() << "Tomahawk link not supported, command not known!" << cmdType << u.path(); return false; @@ -128,7 +156,7 @@ GlobalActionManager::handlePlaylistCommand( const QUrl& url ) pl->createNewRevision( uuid(), pl->currentrevision(), QList< Tomahawk::plentry_ptr >() ); ViewManager::instance()->show( pl ); } else if( parts[ 0 ] == "add" ) { - if( !url.hasQueryItem( "playlistid" ) || !url.hasQueryItem( "track" ) || !url.hasQueryItem( "artist" ) ) { + if( !url.hasQueryItem( "playlistid" ) || !url.hasQueryItem( "title" ) || !url.hasQueryItem( "artist" ) ) { qDebug() << "Add to playlist command needs playlistid, track, and artist..." << url.toString(); return false; } @@ -155,6 +183,19 @@ GlobalActionManager::handleCollectionCommand( const QUrl& url ) return false; } +bool +GlobalActionManager::handleOpenCommand(const QUrl& url) +{ + QStringList parts = url.path().split( "/" ).mid( 1 ); + if( parts.isEmpty() ) { + qDebug() << "No specific type to open:" << url.toString(); + return false; + } + // TODO user configurable in the UI + return doQueueAdd( parts, url.queryItems() ); +} + + bool GlobalActionManager::handleQueueCommand( const QUrl& url ) { @@ -165,9 +206,50 @@ GlobalActionManager::handleQueueCommand( const QUrl& url ) } if( parts[ 0 ] == "add" ) { - if( parts.size() > 1 && parts[ 1 ] == "track" ) { - QPair< QString, QString > pair; - foreach( pair, url.queryItems() ) { + doQueueAdd( parts.mid( 1 ), url.queryItems() ); + } else { + qDebug() << "Only queue/add/track is support at the moment, got:" << parts; + return false; + } + + return false; +} + +bool +GlobalActionManager::doQueueAdd( const QStringList& parts, const QList< QPair< QString, QString > >& queryItems ) +{ + if( parts.size() && parts[ 0 ] == "track" ) { + QPair< QString, QString > pair; + + QString title, artist, album, urlStr; + foreach( pair, queryItems ) { + if( pair.first == "title" ) + title = pair.second; + else if( pair.first == "artist" ) + artist = pair.second; + else if( pair.first == "album" ) + album = pair.second; + else if( pair.first == "url" ) + urlStr = pair.second; + } + + if( !title.isEmpty() || !artist.isEmpty() || !album.isEmpty() ) { // an individual; query to add to queue + Tomahawk::query_ptr q = Tomahawk::Query::get( artist, title, album ); + if( !urlStr.isEmpty() ) + q->setResultHint( urlStr ); + Tomahawk::Pipeline::instance()->resolve( q, true ); + + ViewManager::instance()->queue()->model()->append( q ); + ViewManager::instance()->showQueue(); + + if( !AudioEngine::instance()->isPlaying() ) { + connect( q.data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( waitingForResolved( bool ) ) ); + m_waitingToPlay = q; + } + return true; + + } else { // a list of urls to add to the queue + foreach( pair, queryItems ) { if( pair.first != "url" ) continue; QUrl track = QUrl::fromUserInput( pair.second ); @@ -175,7 +257,6 @@ GlobalActionManager::handleQueueCommand( const QUrl& url ) if( track.toString().startsWith( "file://" ) ) { // it's local, so we see if it's in the DB and load it if so // TODO } else { // give it a web result hint - // TODO actually read the tags QFileInfo info( track.path() ); Tomahawk::query_ptr q = Tomahawk::Query::get( QString(), info.baseName(), QString() ); q->setResultHint( track.toString() ); @@ -186,12 +267,8 @@ GlobalActionManager::handleQueueCommand( const QUrl& url ) } return true; } - } else { - qDebug() << "Only queue/add/track is support at the moment, got:" << parts; - return false; } } - return false; } @@ -204,8 +281,8 @@ GlobalActionManager::handleSearchCommand( const QUrl& url ) query << url.queryItemValue( "artist" ); if( url.hasQueryItem( "album" ) ) query << url.queryItemValue( "album" ); - if( url.hasQueryItem( "track" ) ) - query << url.queryItemValue( "track" ); + if( url.hasQueryItem( "title" ) ) + query << url.queryItemValue( "title" ); QString queryStr = query.join( " " ); if( queryStr.isEmpty() ) @@ -268,7 +345,42 @@ GlobalActionManager::handlePlayCommand( const QUrl& url ) QPair< QString, QString > pair; QString title, artist, album, urlStr; foreach( pair, url.queryItems() ) { - if( pair.first == "track" ) + if( pair.first == "title" ) + title = pair.second; + else if( pair.first == "artist" ) + artist = pair.second; + else if( pair.first == "album" ) + album = pair.second; + else if( pair.first == "url" ) + urlStr = pair.second; + } + Tomahawk::query_ptr q = Tomahawk::Query::get( artist, title, album ); + if( !urlStr.isEmpty() ) + q->setResultHint( urlStr ); + Tomahawk::Pipeline::instance()->resolve( q, true ); + + m_waitingToPlay = q; + connect( q.data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( waitingForResolved( bool ) ) ); + + return true; + } + + return false; +} + +bool GlobalActionManager::handleBookmarkCommand(const QUrl& url) +{ + QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command + if( parts.isEmpty() ) { + qDebug() << "No specific bookmark command:" << url.toString(); + return false; + } + + if( parts[ 0 ] == "track" ) { + QPair< QString, QString > pair; + QString title, artist, album, urlStr; + foreach( pair, url.queryItems() ) { + if( pair.first == "title" ) title = pair.second; else if( pair.first == "artist" ) artist = pair.second; @@ -299,6 +411,8 @@ GlobalActionManager::handlePlayCommand( const QUrl& url ) return false; } + + void GlobalActionManager::bookmarkPlaylistCreated( const Tomahawk::playlist_ptr& pl ) { @@ -326,13 +440,6 @@ GlobalActionManager::doBookmark( const Tomahawk::playlist_ptr& pl, const Tomahaw m_toShow = pl; - // if nothing is playing, lets start this - // TODO - if( !AudioEngine::instance()->isPlaying() ) { - connect( q.data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( waitingForResolved( bool ) ) ); - m_waitingToPlay = q; - } - m_waitingToBookmark.clear(); } @@ -351,7 +458,8 @@ void GlobalActionManager::waitingForResolved( bool success ) { if( success && !m_waitingToPlay.isNull() && !m_waitingToPlay->results().isEmpty() ) { // play it! - AudioEngine::instance()->playItem( AudioEngine::instance()->playlist(), m_waitingToPlay->results().first() ); +// AudioEngine::instance()->playItem( AudioEngine::instance()->playlist(), m_waitingToPlay->results().first() ); + AudioEngine::instance()->play(); } m_waitingToPlay.clear(); diff --git a/src/globalactionmanager.h b/src/libtomahawk/globalactionmanager.h similarity index 81% rename from src/globalactionmanager.h rename to src/libtomahawk/globalactionmanager.h index d4b94af37..55c645d3d 100644 --- a/src/globalactionmanager.h +++ b/src/libtomahawk/globalactionmanager.h @@ -21,17 +21,21 @@ #define GLOBALACTIONMANAGER_H #include "playlist.h" +#include "dllmacro.h" #include #include -class GlobalActionManager : public QObject +class DLLEXPORT GlobalActionManager : public QObject { Q_OBJECT public: static GlobalActionManager* instance(); virtual ~GlobalActionManager(); + QUrl openLinkFromQuery( const Tomahawk::query_ptr& query ) const; + void copyToClipboard( const Tomahawk::query_ptr& query ) const; + public slots: bool parseTomahawkLink( const QString& link ); void waitingForResolved( bool ); @@ -50,6 +54,10 @@ private: bool handleStationCommand(const QUrl& url ); bool handleSearchCommand(const QUrl& url ); bool handlePlayCommand(const QUrl& url ); + bool handleBookmarkCommand(const QUrl& url ); + bool handleOpenCommand(const QUrl& url ); + + bool doQueueAdd( const QStringList& parts, const QList< QPair< QString, QString > >& queryItems ); Tomahawk::playlist_ptr m_toShow; Tomahawk::query_ptr m_waitingToBookmark; diff --git a/src/libtomahawk/infosystem/infoplugins/lastfmplugin.cpp b/src/libtomahawk/infosystem/infoplugins/lastfmplugin.cpp index a9c29c5fe..7dbbcf0f8 100644 --- a/src/libtomahawk/infosystem/infoplugins/lastfmplugin.cpp +++ b/src/libtomahawk/infosystem/infoplugins/lastfmplugin.cpp @@ -68,11 +68,6 @@ LastFmPlugin::LastFmPlugin( InfoSystemWorker* parent ) m_pw = TomahawkSettings::instance()->lastFmPassword(); - if( TomahawkSettings::instance()->scrobblingEnabled() && !lastfm::ws::Username.isEmpty() ) - { - createScrobbler(); - } - //HACK work around a bug in liblastfm---it doesn't create its config dir, so when it // tries to write the track cache, it fails silently. until we have a fixed version, do this // code taken from Amarok (src/services/lastfm/ScrobblerAdapter.cpp) @@ -94,7 +89,9 @@ LastFmPlugin::LastFmPlugin( InfoSystemWorker* parent ) LastFmPlugin::~LastFmPlugin() { + qDebug() << Q_FUNC_INFO << " beginning"; delete m_scrobbler; + qDebug() << Q_FUNC_INFO << " exiting"; } @@ -103,6 +100,7 @@ LastFmPlugin::namChangedSlot() { qDebug() << Q_FUNC_INFO; lastfm::setNetworkAccessManager( m_infoSystemWorker->nam() ); + settingsChanged(); // to get the scrobbler set up } @@ -158,13 +156,20 @@ LastFmPlugin::pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoTy void LastFmPlugin::nowPlaying( const QString &caller, const InfoType type, const QVariant &input ) { + qDebug() << Q_FUNC_INFO; if ( !input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() || !m_scrobbler ) + { + qDebug() << "LastFmPlugin::nowPlaying no m_scrobbler, or cannot convert input!"; + if ( ! m_scrobbler ) + qDebug() << "no scrobbler!"; return; + } InfoCriteriaHash hash = input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); if ( !hash.contains( "title" ) || !hash.contains( "artist" ) || !hash.contains( "album" ) || !hash.contains( "duration" ) ) return; + qDebug() << "LastFmPlugin::nowPlaying valid criteria hash"; m_track = lastfm::MutableTrack(); m_track.stamp(); @@ -182,7 +187,8 @@ LastFmPlugin::nowPlaying( const QString &caller, const InfoType type, const QVar void LastFmPlugin::scrobble( const QString &caller, const InfoType type, const QVariant &input ) { - Q_ASSERT( QThread::currentThread() == thread() ); + qDebug() << Q_FUNC_INFO; + //Q_ASSERT( QThread::currentThread() == thread() ); if ( !m_scrobbler || m_track.isNull() ) return; @@ -418,6 +424,7 @@ LastFmPlugin::settingsChanged() void LastFmPlugin::onAuthenticated() { + qDebug() << Q_FUNC_INFO; if( !m_authJob ) { qDebug() << Q_FUNC_INFO << "Help! No longer got a last.fm auth job!"; @@ -440,6 +447,7 @@ LastFmPlugin::onAuthenticated() TomahawkSettings::instance()->setLastFmSessionKey( lastfm::ws::SessionKey.toLatin1() ); + qDebug() << "Got session key from last.fm"; if( TomahawkSettings::instance()->scrobblingEnabled() ) m_scrobbler = new lastfm::Audioscrobbler( "thk" ); } @@ -456,8 +464,10 @@ LastFmPlugin::onAuthenticated() void LastFmPlugin::createScrobbler() { + qDebug() << Q_FUNC_INFO; if( TomahawkSettings::instance()->lastFmSessionKey().isEmpty() ) // no session key, so get one { + qDebug() << "LastFmPlugin::createScrobbler Session key is empty"; QString authToken = md5( ( lastfm::ws::Username.toLower() + md5( m_pw.toUtf8() ) ).toUtf8() ); QMap query; @@ -470,9 +480,9 @@ LastFmPlugin::createScrobbler() } else { + qDebug() << "LastFmPlugin::createScrobbler Already have session key"; lastfm::ws::SessionKey = TomahawkSettings::instance()->lastFmSessionKey(); m_scrobbler = new lastfm::Audioscrobbler( "thk" ); - m_scrobbler->moveToThread( thread() ); } } diff --git a/src/libtomahawk/infosystem/infosystem.cpp b/src/libtomahawk/infosystem/infosystem.cpp index e42edda5b..84a15bd67 100644 --- a/src/libtomahawk/infosystem/infosystem.cpp +++ b/src/libtomahawk/infosystem/infosystem.cpp @@ -78,17 +78,44 @@ InfoSystem::InfoSystem(QObject *parent) InfoSystem::~InfoSystem() { - qDebug() << Q_FUNC_INFO; + qDebug() << Q_FUNC_INFO << " beginning"; + + if ( m_infoSystemWorkerThreadController ) + m_infoSystemWorkerThreadController->quit(); + + qDebug() << Q_FUNC_INFO << " sent quit signals"; + + if( m_infoSystemWorkerThreadController ) + { + while( !m_infoSystemWorkerThreadController->isFinished() ) + { + qDebug() << Q_FUNC_INFO << " worker thread controller not finished, processing events"; + QCoreApplication::processEvents( QEventLoop::AllEvents, 200 ); + TomahawkUtils::Sleep::msleep( 100 ); + } + + qDebug() << Q_FUNC_INFO << " worker is finished, deleting worker"; + if( m_worker ) + { + delete m_worker; + m_worker = 0; + } + + qDebug() << Q_FUNC_INFO << " worker finished being deleted"; + delete m_infoSystemWorkerThreadController; + m_infoSystemWorkerThreadController = 0; + } + + qDebug() << Q_FUNC_INFO << " done deleting worker"; if ( m_infoSystemCacheThreadController ) m_infoSystemCacheThreadController->quit(); - if ( m_infoSystemWorkerThreadController ) - m_infoSystemWorkerThreadController->quit(); if( m_infoSystemCacheThreadController ) { while( !m_infoSystemCacheThreadController->isFinished() ) { + qDebug() << Q_FUNC_INFO << " cache thread controller not finished, processing events"; QCoreApplication::processEvents( QEventLoop::AllEvents, 200 ); TomahawkUtils::Sleep::msleep( 100 ); } @@ -102,24 +129,7 @@ InfoSystem::~InfoSystem() delete m_infoSystemCacheThreadController; m_infoSystemCacheThreadController = 0; } - - if( m_infoSystemWorkerThreadController ) - { - while( !m_infoSystemWorkerThreadController->isFinished() ) - { - QCoreApplication::processEvents( QEventLoop::AllEvents, 200 ); - TomahawkUtils::Sleep::msleep( 100 ); - } - - if( m_worker ) - { - delete m_worker; - m_worker = 0; - } - - delete m_infoSystemWorkerThreadController; - m_infoSystemWorkerThreadController = 0; - } + qDebug() << Q_FUNC_INFO << " done deleting cache"; } diff --git a/src/libtomahawk/infosystem/infosystem.h b/src/libtomahawk/infosystem/infosystem.h index f4fe24871..6dcb2a912 100644 --- a/src/libtomahawk/infosystem/infosystem.h +++ b/src/libtomahawk/infosystem/infosystem.h @@ -107,7 +107,10 @@ class DLLEXPORT InfoPlugin : public QObject public: InfoPlugin( InfoSystemWorker *parent ); - virtual ~InfoPlugin() {} + virtual ~InfoPlugin() + { + qDebug() << Q_FUNC_INFO; + } signals: void getCachedInfo( Tomahawk::InfoSystem::InfoCriteriaHash criteria, qint64 newMaxAge, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData ); diff --git a/src/libtomahawk/infosystem/infosystemworker.cpp b/src/libtomahawk/infosystem/infosystemworker.cpp index c70cbe019..763e34a65 100644 --- a/src/libtomahawk/infosystem/infosystemworker.cpp +++ b/src/libtomahawk/infosystem/infosystemworker.cpp @@ -27,6 +27,8 @@ #include "infoplugins/musixmatchplugin.h" #include "infoplugins/lastfmplugin.h" +#include "lastfm/NetworkAccessManager" + namespace Tomahawk { @@ -42,12 +44,13 @@ InfoSystemWorker::InfoSystemWorker() InfoSystemWorker::~InfoSystemWorker() { - qDebug() << Q_FUNC_INFO; + qDebug() << Q_FUNC_INFO << " beginning"; Q_FOREACH( InfoPluginPtr plugin, m_plugins ) { if( plugin ) delete plugin.data(); } + qDebug() << Q_FUNC_INFO << " is done deleting plugins"; } @@ -165,7 +168,13 @@ void InfoSystemWorker::newNam() { qDebug() << Q_FUNC_INFO; - QNetworkAccessManager *newNam = new QNetworkAccessManager(); + + QNetworkAccessManager* newNam; +#ifdef LIBLASTFM_FOUND + newNam = new lastfm::NetworkAccessManager( this ); +#else + newNam = new QNetworkAccessManager( this ); +#endif if ( m_nam ) { delete m_nam; diff --git a/src/libtomahawk/playlist.cpp b/src/libtomahawk/playlist.cpp index 3ff822634..17a1622a4 100644 --- a/src/libtomahawk/playlist.cpp +++ b/src/libtomahawk/playlist.cpp @@ -184,7 +184,6 @@ playlist_ptr Playlist::load( const QString& guid ) { playlist_ptr p; - qDebug() << "asked to load playlist:" << guid; foreach( const Tomahawk::source_ptr& source, SourceList::instance()->sources() ) { diff --git a/src/libtomahawk/playlist.h b/src/libtomahawk/playlist.h index e905517b2..6c23fe808 100644 --- a/src/libtomahawk/playlist.h +++ b/src/libtomahawk/playlist.h @@ -262,4 +262,6 @@ private: }; +Q_DECLARE_METATYPE( QSharedPointer< Tomahawk::Playlist > ) + #endif // PLAYLIST_H diff --git a/src/libtomahawk/playlist/collectionview.cpp b/src/libtomahawk/playlist/collectionview.cpp index 6d93742f6..1b4d02c0f 100644 --- a/src/libtomahawk/playlist/collectionview.cpp +++ b/src/libtomahawk/playlist/collectionview.cpp @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -83,7 +83,10 @@ CollectionView::setupMenus() m_playItemAction = m_itemMenu.addAction( tr( "&Play" ) ); m_addItemsToQueueAction = m_itemMenu.addAction( tr( "Add to &Queue" ) ); -// m_itemMenu.addSeparator(); + m_itemMenu.addSeparator(); + + foreach( QAction* a, actions() ) + m_itemMenu.addAction( a ); // m_addItemsToPlaylistAction = m_itemMenu.addAction( tr( "&Add to Playlist" ) ); connect( m_playItemAction, SIGNAL( triggered() ), SLOT( playItem() ) ); diff --git a/src/libtomahawk/playlist/playlistview.cpp b/src/libtomahawk/playlist/playlistview.cpp index 175d0705a..ddd19ecc0 100644 --- a/src/libtomahawk/playlist/playlistview.cpp +++ b/src/libtomahawk/playlist/playlistview.cpp @@ -30,6 +30,12 @@ using namespace Tomahawk; PlaylistView::PlaylistView( QWidget* parent ) : TrackView( parent ) + , m_model( 0 ) + , m_itemMenu( 0 ) + , m_playItemAction( 0 ) + , m_addItemsToQueueAction( 0 ) + , m_addItemsToPlaylistAction( 0 ) + , m_deleteItemsAction( 0 ) { setProxyModel( new PlaylistProxyModel( this ) ); @@ -84,6 +90,9 @@ PlaylistView::setupMenus() m_playItemAction = m_itemMenu.addAction( tr( "&Play" ) ); m_addItemsToQueueAction = m_itemMenu.addAction( tr( "Add to &Queue" ) ); m_itemMenu.addSeparator(); + + foreach( QAction* a, actions() ) + m_itemMenu.addAction( a ); // m_addItemsToPlaylistAction = m_itemMenu.addAction( tr( "&Add to Playlist" ) ); // m_itemMenu.addSeparator(); m_deleteItemsAction = m_itemMenu.addAction( i > 1 ? tr( "&Delete Items" ) : tr( "&Delete Item" ) ); @@ -144,7 +153,6 @@ PlaylistView::deleteItems() proxyModel()->removeIndexes( selectedIndexes() ); } - void PlaylistView::onTrackCountChanged( unsigned int tracks ) { diff --git a/src/libtomahawk/playlist/playlistview.h b/src/libtomahawk/playlist/playlistview.h index 84df64805..589c5f815 100644 --- a/src/libtomahawk/playlist/playlistview.h +++ b/src/libtomahawk/playlist/playlistview.h @@ -65,7 +65,6 @@ private slots: void deleteItems(); void onDeleted(); - private: void setupMenus(); diff --git a/src/libtomahawk/playlist/trackview.cpp b/src/libtomahawk/playlist/trackview.cpp index c7ab24d61..db7a619f4 100644 --- a/src/libtomahawk/playlist/trackview.cpp +++ b/src/libtomahawk/playlist/trackview.cpp @@ -33,7 +33,8 @@ #include "queueview.h" #include "trackmodel.h" #include "trackproxymodel.h" -#include +#include "track.h" +#include "globalactionmanager.h" using namespace Tomahawk; @@ -77,6 +78,10 @@ TrackView::TrackView( QWidget* parent ) setFont( f ); #endif + QAction* createLinkAction = new QAction( tr( "Copy track link" ), this ); + connect( createLinkAction, SIGNAL( triggered( bool ) ), this, SLOT( copyLink() ) ); + addAction( createLinkAction ); + connect( this, SIGNAL( doubleClicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) ); } @@ -173,7 +178,6 @@ TrackView::onItemResized( const QModelIndex& index ) m_delegate->updateRowSize( index ); } - void TrackView::playItem() { @@ -341,6 +345,16 @@ TrackView::onFilterChanged( const QString& ) m_overlay->hide(); } +void +TrackView::copyLink() +{ + TrackModelItem* item = model()->itemFromIndex( proxyModel()->mapToSource( contextMenuIndex() ) ); + if ( item && !item->query().isNull() ) + { + GlobalActionManager::instance()->copyToClipboard( item->query() ); + } +} + void TrackView::startDrag( Qt::DropActions supportedActions ) diff --git a/src/libtomahawk/playlist/trackview.h b/src/libtomahawk/playlist/trackview.h index aac8b2a11..c14b42692 100644 --- a/src/libtomahawk/playlist/trackview.h +++ b/src/libtomahawk/playlist/trackview.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -26,6 +26,7 @@ #include "dllmacro.h" +class QAction; class LoadingSpinner; class PlaylistInterface; class TrackHeader; @@ -80,6 +81,7 @@ private slots: void onFilterChanged( const QString& filter ); + void copyLink(); private: QString m_guid; TrackModel* m_model; diff --git a/src/libtomahawk/sip/SipPlugin.cpp b/src/libtomahawk/sip/SipPlugin.cpp index f10cd0710..1bde2db64 100644 --- a/src/libtomahawk/sip/SipPlugin.cpp +++ b/src/libtomahawk/sip/SipPlugin.cpp @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * 2011, Dominik Schmidt * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -64,3 +65,9 @@ SipPlugin::icon() const { return QIcon(); } + +void +SipPlugin::setProxy( const QNetworkProxy& proxy ) +{ + qDebug() << Q_FUNC_INFO << "Not implemented"; +} diff --git a/src/libtomahawk/sip/SipPlugin.h b/src/libtomahawk/sip/SipPlugin.h index e42fb9fb7..92be5b217 100644 --- a/src/libtomahawk/sip/SipPlugin.h +++ b/src/libtomahawk/sip/SipPlugin.h @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * 2011, Dominik Schmidt * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,6 +23,8 @@ #include #include #include +#include + #include "dllmacro.h" @@ -80,6 +83,8 @@ public slots: virtual void addContact( const QString &jid, const QString& msg = QString() ) = 0; virtual void sendMsg( const QString& to, const QString& msg ) = 0; + void setProxy( const QNetworkProxy &proxy ); + signals: void error( int, const QString& ); void stateChanged( SipPlugin::ConnectionState state ); diff --git a/src/libtomahawk/tomahawksettings.cpp b/src/libtomahawk/tomahawksettings.cpp index 19af83fe2..1f9c96fc7 100644 --- a/src/libtomahawk/tomahawksettings.cpp +++ b/src/libtomahawk/tomahawksettings.cpp @@ -365,6 +365,12 @@ TomahawkSettings::recentlyPlayedPlaylists() const return playlists; } +QStringList +TomahawkSettings::recentlyPlayedPlaylistGuids() const +{ + return value( "playlists/recentlyPlayed" ).toStringList(); +} + void TomahawkSettings::appendRecentlyPlayedPlaylist( const Tomahawk::playlist_ptr& playlist ) @@ -375,6 +381,8 @@ TomahawkSettings::appendRecentlyPlayedPlaylist( const Tomahawk::playlist_ptr& pl playlist_guids.append( playlist->guid() ); setValue( "playlists/recentlyPlayed", playlist_guids ); + + emit recentlyPlayedPlaylistAdded( playlist ); } QString diff --git a/src/libtomahawk/tomahawksettings.h b/src/libtomahawk/tomahawksettings.h index 50cacb7ac..0c1468596 100644 --- a/src/libtomahawk/tomahawksettings.h +++ b/src/libtomahawk/tomahawksettings.h @@ -66,6 +66,7 @@ public: void setPlaylistColumnSizes( const QString& playlistid, const QByteArray& state ); QList recentlyPlayedPlaylists() const; + QStringList recentlyPlayedPlaylistGuids() const; void appendRecentlyPlayedPlaylist( const Tomahawk::playlist_ptr& playlist ); /// SIP plugins @@ -158,6 +159,7 @@ public: signals: void changed(); + void recentlyPlayedPlaylistAdded( const Tomahawk::playlist_ptr& playlist ); private: void doUpgrade( int oldVersion, int newVersion ); diff --git a/src/libtomahawk/viewmanager.cpp b/src/libtomahawk/viewmanager.cpp index fa55d13d8..e6abf3250 100644 --- a/src/libtomahawk/viewmanager.cpp +++ b/src/libtomahawk/viewmanager.cpp @@ -121,6 +121,8 @@ ViewManager::ViewManager( QObject* parent ) m_widget->layout()->setMargin( 0 ); m_widget->layout()->setSpacing( 0 ); + connect( AudioEngine::instance(), SIGNAL( playlistChanged( PlaylistInterface* ) ), this, SLOT( playlistInterfaceChanged( PlaylistInterface* ) ) ); + connect( &m_filterTimer, SIGNAL( timeout() ), SLOT( applyFilter() ) ); connect( m_topbar, SIGNAL( filterTextChanged( QString ) ), @@ -180,7 +182,7 @@ ViewManager::show( const Tomahawk::playlist_ptr& playlist ) } setPage( view ); - TomahawkSettings::instance()->appendRecentlyPlayedPlaylist( playlist ); + emit numSourcesChanged( SourceList::instance()->count() ); return view; @@ -206,7 +208,6 @@ ViewManager::show( const Tomahawk::dynplaylist_ptr& playlist ) else m_queueView->show(); - TomahawkSettings::instance()->appendRecentlyPlayedPlaylist( playlist ); emit numSourcesChanged( SourceList::instance()->count() ); return m_dynamicWidgets.value( playlist ); @@ -421,6 +422,22 @@ ViewManager::showSuperCollection() return shown; } +void +ViewManager::playlistInterfaceChanged( PlaylistInterface* interface ) +{ + playlist_ptr pl = playlistForInterface( interface ); + if ( !pl.isNull() ) + { + TomahawkSettings::instance()->appendRecentlyPlayedPlaylist( pl ); + } else + { + pl = dynamicPlaylistForInterface( interface ); + if ( !pl.isNull() ) + TomahawkSettings::instance()->appendRecentlyPlayedPlaylist( pl ); + } +} + + Tomahawk::ViewPage* ViewManager::showWelcomePage() { @@ -599,7 +616,7 @@ ViewManager::setPage( ViewPage* page, bool trackHistory ) qDebug() << "View page shown:" << page->title(); emit viewPageActivated( page ); - if ( !AudioEngine::instance()->isPlaying() ) + if ( !AudioEngine::instance()->playlist() ) AudioEngine::instance()->setPlaylist( currentPlaylistInterface() ); // UGH! diff --git a/src/libtomahawk/viewmanager.h b/src/libtomahawk/viewmanager.h index 65b4f6fa3..9ac8bc63d 100644 --- a/src/libtomahawk/viewmanager.h +++ b/src/libtomahawk/viewmanager.h @@ -145,6 +145,8 @@ public slots: void setRepeatMode( PlaylistInterface::RepeatMode mode ); void setShuffled( bool enabled ); + void playlistInterfaceChanged( PlaylistInterface* ); + // called by the playlist creation dbcmds void createPlaylist( const Tomahawk::source_ptr& src, const QVariant& contents ); void createDynamicPlaylist( const Tomahawk::source_ptr& src, const QVariant& contents ); diff --git a/src/libtomahawk/widgets/welcomeplaylistmodel.cpp b/src/libtomahawk/widgets/welcomeplaylistmodel.cpp new file mode 100644 index 000000000..d15760601 --- /dev/null +++ b/src/libtomahawk/widgets/welcomeplaylistmodel.cpp @@ -0,0 +1,177 @@ +/* + + Copyright (C) 2011 Leo Franchi + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + + +#include "welcomeplaylistmodel.h" +#include +#include