From 92db1758193a9566e8801fa2f364c693ab09e428 Mon Sep 17 00:00:00 2001 From: David Sansome Date: Tue, 29 Dec 2009 23:17:54 +0000 Subject: [PATCH] Double-click on radio items to play --- TODO | 1 - src/lastfmservice.cpp | 45 +++++++++++++++++++++---------------------- src/lastfmservice.h | 8 +++++++- src/mainwindow.cpp | 9 +++++++++ src/mainwindow.h | 1 + src/playlist.cpp | 18 ++++++++--------- src/playlist.h | 5 ++--- src/radioitem.cpp | 9 +++++++++ src/radioitem.h | 10 +++------- src/radiomimedata.h | 5 ++--- src/radiomodel.cpp | 14 ++++---------- src/radioservice.h | 4 +++- 12 files changed, 70 insertions(+), 59 deletions(-) diff --git a/TODO b/TODO index 6035caf43..7c6b2ae01 100644 --- a/TODO +++ b/TODO @@ -10,7 +10,6 @@ Last.fm: - Artist/tag/etc. radio -- Double click from radio list - More types of radio Long-term: diff --git a/src/lastfmservice.cpp b/src/lastfmservice.cpp index a974b2305..c535dff61 100644 --- a/src/lastfmservice.cpp +++ b/src/lastfmservice.cpp @@ -145,34 +145,33 @@ void LastFMService::AuthenticateReplyFinished() { emit AuthenticationComplete(true); } -QList LastFMService::DataForItem(RadioItem* item) { - QList ret; +QUrl LastFMService::UrlForItem(const RadioItem* item) const { + switch (item->type) { + case Type_MyRecommendations: + return "lastfm://user/" + lastfm::ws::Username + "/recommended"; + case Type_MyLoved: + return "lastfm://user/" + lastfm::ws::Username + "/loved"; + + case Type_MyNeighbourhood: + return "lastfm://user/" + lastfm::ws::Username + "/neighbours"; + + case Type_MyRadio: + return "lastfm://user/" + lastfm::ws::Username + "/library"; + } + return QUrl(); +} + +QString LastFMService::TitleForItem(const RadioItem* item) const { const QString user(lastfm::ws::Username); switch (item->type) { - case Type_MyRecommendations: - ret << RadioItem::PlaylistData(user + "'s Recommended Radio", - "lastfm://user/" + lastfm::ws::Username + "/recommended"); - break; - - case Type_MyLoved: - ret << RadioItem::PlaylistData(user + "'s Loved Tracks", - "lastfm://user/" + lastfm::ws::Username + "/loved"); - break; - - case Type_MyNeighbourhood: - ret << RadioItem::PlaylistData(user + "'s Neighbour Radio", - "lastfm://user/" + lastfm::ws::Username + "/neighbours"); - break; - - case Type_MyRadio: - ret << RadioItem::PlaylistData(user + "'s Library", - "lastfm://user/" + lastfm::ws::Username + "/library"); - break; + case Type_MyRecommendations: return user + "'s Recommended Radio"; + case Type_MyLoved: return user + "'s Loved Tracks"; + case Type_MyNeighbourhood: return user + "'s Neighbour Radio"; + case Type_MyRadio: return user + "'s Library"; } - - return ret; + return QString(); } void LastFMService::StartLoading(const QUrl& url) { diff --git a/src/lastfmservice.h b/src/lastfmservice.h index 79e6d514c..4b27d6edd 100644 --- a/src/lastfmservice.h +++ b/src/lastfmservice.h @@ -33,13 +33,19 @@ class LastFMService : public RadioService { // RadioService RadioItem* CreateRootItem(RadioItem* parent); void LazyPopulate(RadioItem *item); - QList DataForItem(RadioItem* item); + + QUrl UrlForItem(const RadioItem* item) const; + QString TitleForItem(const RadioItem* item) const; + void ShowContextMenu(RadioItem *item, const QPoint &global_pos); + void StartLoading(const QUrl& url); void LoadNext(const QUrl& url); + bool IsPauseAllowed() const { return false; } bool ShowLastFmControls() const { return true; } + // Last.fm specific stuff bool IsAuthenticated() const; bool IsScrobblingEnabled() const { return scrobbling_enabled_; } void Authenticate(const QString& username, const QString& password); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 836b1737b..f2aabe2bd 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -157,6 +157,7 @@ MainWindow::MainWindow(QWidget *parent) connect(radio_model_, SIGNAL(StreamReady(QUrl,QUrl)), player_, SLOT(StreamReady(QUrl,QUrl))); connect(radio_model_, SIGNAL(StreamMetadataFound(QUrl,Song)), playlist_, SLOT(SetStreamMetadata(QUrl,Song))); connect(radio_model_->GetLastFMService(), SIGNAL(ScrobblingEnabledChanged(bool)), SLOT(ScrobblingEnabledChanged(bool))); + connect(ui_.radio_view, SIGNAL(doubleClicked(QModelIndex)), SLOT(RadioDoubleClick(QModelIndex))); // Tray icon QMenu* tray_menu = new QMenu(this); @@ -360,3 +361,11 @@ void MainWindow::Love() { radio_model_->GetLastFMService()->Love(); ui_.action_love->setEnabled(false); } + +void MainWindow::RadioDoubleClick(const QModelIndex& index) { + QModelIndex first_song = playlist_->InsertRadioStations( + QList() << radio_model_->IndexToItem(index)); + + if (first_song.isValid() && player_->GetState() != Engine::Playing) + player_->PlayAt(first_song.row()); +} diff --git a/src/mainwindow.h b/src/mainwindow.h index 83ebff34b..76af1102e 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -49,6 +49,7 @@ class MainWindow : public QMainWindow { void UpdateTrackPosition(); + void RadioDoubleClick(const QModelIndex& index); void ScrobblingEnabledChanged(bool value); void Love(); diff --git a/src/playlist.cpp b/src/playlist.cpp index 8588d0c0b..2f015c1bb 100644 --- a/src/playlist.cpp +++ b/src/playlist.cpp @@ -133,7 +133,7 @@ bool Playlist::dropMimeData(const QMimeData* data, Qt::DropAction action, int ro InsertSongs(song_data->songs, row); } else if (const RadioMimeData* radio_data = qobject_cast(data)) { // Dragged from the Radio pane - InsertRadioStations(radio_data->services, radio_data->urls(), radio_data->titles, row); + InsertRadioStations(radio_data->items, row); } else if (data->hasFormat(kRowsMimetype)) { // Dragged from the playlist // Rearranging it is tricky... @@ -245,17 +245,15 @@ QModelIndex Playlist::InsertSongs(const SongList& songs, int after) { return InsertItems(items, after); } -QModelIndex Playlist::InsertRadioStations(const QList& services, - const QList& urls, - const QStringList& titles, int after) { - Q_ASSERT(services.count() == urls.count()); - Q_ASSERT(services.count() == titles.count()); +QModelIndex Playlist::InsertRadioStations(const QList& items, int after) { + QList playlist_items; + foreach (RadioItem* item, items) { + if (!item->playable) + continue; - QList items; - for (int i=0 ; iservice, item->Url(), item->Title()); } - return InsertItems(items, after); + return InsertItems(playlist_items, after); } QMimeData* Playlist::mimeData(const QModelIndexList& indexes) const { diff --git a/src/playlist.h b/src/playlist.h index ccac4bd90..f6e219fe1 100644 --- a/src/playlist.h +++ b/src/playlist.h @@ -6,6 +6,7 @@ #include "playlistitem.h" #include "song.h" +#include "radioitem.h" class RadioService; @@ -62,9 +63,7 @@ class Playlist : public QAbstractListModel { // Changing the playlist QModelIndex InsertItems(const QList& items, int after = -1); QModelIndex InsertSongs(const SongList& items, int after = -1); - QModelIndex InsertRadioStations(const QList& services, - const QList& urls, - const QStringList& titles, int after = -1); + QModelIndex InsertRadioStations(const QList& items, int after = -1); QModelIndex InsertPaths(QList urls, int after = -1); void StopAfter(int row); diff --git a/src/radioitem.cpp b/src/radioitem.cpp index 9ace16c9c..a7b9fc21f 100644 --- a/src/radioitem.cpp +++ b/src/radioitem.cpp @@ -1,4 +1,5 @@ #include "radioitem.h" +#include "radioservice.h" RadioItem::RadioItem(RadioService* _service, int type, const QString& key, RadioItem* parent) @@ -7,3 +8,11 @@ RadioItem::RadioItem(RadioService* _service, int type, const QString& key, playable(false) { } + +QUrl RadioItem::Url() const { + return service->UrlForItem(this); +} + +QString RadioItem::Title() const { + return service->TitleForItem(this); +} diff --git a/src/radioitem.h b/src/radioitem.h index 44b5d7b8d..51010e7b6 100644 --- a/src/radioitem.h +++ b/src/radioitem.h @@ -15,16 +15,12 @@ class RadioItem : public SimpleTreeItem { Type_Service, }; - struct PlaylistData { - PlaylistData(const QString& _title, const QUrl& _url) : title(_title), url(_url) {} - - QString title; - QUrl url; - }; - RadioItem(RadioService* _service, int type, const QString& key = QString::null, RadioItem* parent = NULL); + QUrl Url() const; + QString Title() const; + QIcon icon; RadioService* service; bool playable; diff --git a/src/radiomimedata.h b/src/radiomimedata.h index 75f2ec5ff..53dd8df97 100644 --- a/src/radiomimedata.h +++ b/src/radiomimedata.h @@ -3,14 +3,13 @@ #include -class RadioService; +class RadioItem; class RadioMimeData : public QMimeData { Q_OBJECT public: - QList services; - QList titles; + QList items; }; #endif // RADIOMIMEDATA_H diff --git a/src/radiomodel.cpp b/src/radiomodel.cpp index 7cf2c92bd..94c80349f 100644 --- a/src/radiomodel.cpp +++ b/src/radiomodel.cpp @@ -85,20 +85,15 @@ QStringList RadioModel::mimeTypes() const { QMimeData* RadioModel::mimeData(const QModelIndexList& indexes) const { QList urls; - QList services; - QStringList titles; + QList items; foreach (const QModelIndex& index, indexes) { RadioItem* item = IndexToItem(index); if (!item || !item->service || !item->playable) continue; - QList item_data(item->service->DataForItem(item)); - foreach (const RadioItem::PlaylistData& data, item_data) { - urls << data.url; - services << item->service; - titles << data.title; - } + items << item; + urls << item->service->UrlForItem(item); } if (urls.isEmpty()) @@ -106,8 +101,7 @@ QMimeData* RadioModel::mimeData(const QModelIndexList& indexes) const { RadioMimeData* data = new RadioMimeData; data->setUrls(urls); - data->services = services; - data->titles = titles; + data->items = items; return data; } diff --git a/src/radioservice.h b/src/radioservice.h index e29f6fdf9..130bb963c 100644 --- a/src/radioservice.h +++ b/src/radioservice.h @@ -21,7 +21,9 @@ class RadioService : public QObject { virtual RadioItem* CreateRootItem(RadioItem* parent) = 0; virtual void LazyPopulate(RadioItem* item) = 0; - virtual QList DataForItem(RadioItem* item) = 0; + virtual QUrl UrlForItem(const RadioItem* item) const = 0; + virtual QString TitleForItem(const RadioItem* item) const = 0; + virtual void ShowContextMenu(RadioItem* item, const QPoint& global_pos) { Q_UNUSED(item); Q_UNUSED(global_pos); }