Double-click on radio items to play

This commit is contained in:
David Sansome 2009-12-29 23:17:54 +00:00
parent 939e4b5264
commit 92db175819
12 changed files with 70 additions and 59 deletions

1
TODO
View File

@ -10,7 +10,6 @@
Last.fm:
- Artist/tag/etc. radio
- Double click from radio list
- More types of radio
Long-term:

View File

@ -145,34 +145,33 @@ void LastFMService::AuthenticateReplyFinished() {
emit AuthenticationComplete(true);
}
QList<RadioItem::PlaylistData> LastFMService::DataForItem(RadioItem* item) {
QList<RadioItem::PlaylistData> 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) {

View File

@ -33,13 +33,19 @@ class LastFMService : public RadioService {
// RadioService
RadioItem* CreateRootItem(RadioItem* parent);
void LazyPopulate(RadioItem *item);
QList<RadioItem::PlaylistData> 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);

View File

@ -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<RadioItem*>() << radio_model_->IndexToItem(index));
if (first_song.isValid() && player_->GetState() != Engine::Playing)
player_->PlayAt(first_song.row());
}

View File

@ -49,6 +49,7 @@ class MainWindow : public QMainWindow {
void UpdateTrackPosition();
void RadioDoubleClick(const QModelIndex& index);
void ScrobblingEnabledChanged(bool value);
void Love();

View File

@ -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<const RadioMimeData*>(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<RadioService*>& services,
const QList<QUrl>& urls,
const QStringList& titles, int after) {
Q_ASSERT(services.count() == urls.count());
Q_ASSERT(services.count() == titles.count());
QModelIndex Playlist::InsertRadioStations(const QList<RadioItem*>& items, int after) {
QList<PlaylistItem*> playlist_items;
foreach (RadioItem* item, items) {
if (!item->playable)
continue;
QList<PlaylistItem*> items;
for (int i=0 ; i<services.count() ; ++i) {
items << new RadioPlaylistItem(services[i], urls[i], titles[i]);
playlist_items << new RadioPlaylistItem(item->service, item->Url(), item->Title());
}
return InsertItems(items, after);
return InsertItems(playlist_items, after);
}
QMimeData* Playlist::mimeData(const QModelIndexList& indexes) const {

View File

@ -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<PlaylistItem*>& items, int after = -1);
QModelIndex InsertSongs(const SongList& items, int after = -1);
QModelIndex InsertRadioStations(const QList<RadioService*>& services,
const QList<QUrl>& urls,
const QStringList& titles, int after = -1);
QModelIndex InsertRadioStations(const QList<RadioItem*>& items, int after = -1);
QModelIndex InsertPaths(QList<QUrl> urls, int after = -1);
void StopAfter(int row);

View File

@ -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);
}

View File

@ -15,16 +15,12 @@ class RadioItem : public SimpleTreeItem<RadioItem> {
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;

View File

@ -3,14 +3,13 @@
#include <QMimeData>
class RadioService;
class RadioItem;
class RadioMimeData : public QMimeData {
Q_OBJECT
public:
QList<RadioService*> services;
QList<QString> titles;
QList<RadioItem*> items;
};
#endif // RADIOMIMEDATA_H

View File

@ -85,20 +85,15 @@ QStringList RadioModel::mimeTypes() const {
QMimeData* RadioModel::mimeData(const QModelIndexList& indexes) const {
QList<QUrl> urls;
QList<RadioService*> services;
QStringList titles;
QList<RadioItem*> items;
foreach (const QModelIndex& index, indexes) {
RadioItem* item = IndexToItem(index);
if (!item || !item->service || !item->playable)
continue;
QList<RadioItem::PlaylistData> 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;
}

View File

@ -21,7 +21,9 @@ class RadioService : public QObject {
virtual RadioItem* CreateRootItem(RadioItem* parent) = 0;
virtual void LazyPopulate(RadioItem* item) = 0;
virtual QList<RadioItem::PlaylistData> 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); }