Tag and artist radio
This commit is contained in:
parent
bfc81e4d5c
commit
efefc35d6e
4
TODO
4
TODO
@ -8,10 +8,6 @@
|
||||
- Make QSortFilterProxyModel on the library obey hasChildren()
|
||||
- More columns in playlist
|
||||
|
||||
Last.fm:
|
||||
- Artist/tag/etc. radio
|
||||
- More types of radio
|
||||
|
||||
Long-term:
|
||||
- iPod
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "lastfmconfig.h"
|
||||
#include "radioitem.h"
|
||||
#include "song.h"
|
||||
#include "lastfmstationdialog.h"
|
||||
|
||||
#include <lastfm/ws.h>
|
||||
#include <lastfm/misc.h>
|
||||
@ -21,9 +22,12 @@ LastFMService::LastFMService(QObject* parent)
|
||||
: RadioService(kServiceName, parent),
|
||||
tuner_(NULL),
|
||||
scrobbler_(NULL),
|
||||
station_dialog_(new LastFMStationDialog),
|
||||
context_menu_(new QMenu),
|
||||
initial_tune_(false),
|
||||
scrobbling_enabled_(false),
|
||||
artist_list_(NULL),
|
||||
tag_list_(NULL),
|
||||
friends_list_(NULL),
|
||||
neighbours_list_(NULL)
|
||||
{
|
||||
@ -44,13 +48,18 @@ LastFMService::LastFMService(QObject* parent)
|
||||
|
||||
play_action_ = context_menu_->addAction(QIcon(":media-playback-start.png"), "Add to playlist", this, SLOT(AddToPlaylist()));
|
||||
context_menu_->addSeparator();
|
||||
add_artist_action_ = context_menu_->addAction(QIcon(":last.fm/icon_radio.png"), "Play artist radio...", this, SLOT(AddArtistRadio()));
|
||||
add_tag_action_ = context_menu_->addAction(QIcon(":last.fm/icon_tag.png"), "Play tag radio...", this, SLOT(AddTagRadio()));
|
||||
context_menu_->addAction(QIcon(":configure.png"), "Configure Last.fm...",
|
||||
config_, SLOT(show()));
|
||||
|
||||
add_artist_action_->setEnabled(false);
|
||||
add_tag_action_->setEnabled(false);
|
||||
}
|
||||
|
||||
LastFMService::~LastFMService() {
|
||||
delete config_;
|
||||
delete station_dialog_;
|
||||
delete context_menu_;
|
||||
}
|
||||
|
||||
@ -75,8 +84,6 @@ RadioItem* LastFMService::CreateRootItem(RadioItem* parent) {
|
||||
}
|
||||
|
||||
void LastFMService::LazyPopulate(RadioItem *item) {
|
||||
RadioItem* c = NULL;
|
||||
|
||||
switch (item->type) {
|
||||
case RadioItem::Type_Service:
|
||||
// Normal radio types
|
||||
@ -85,16 +92,18 @@ void LastFMService::LazyPopulate(RadioItem *item) {
|
||||
CreateStationItem(Type_MyLoved, "My Loved Tracks", ":last.fm/loved_radio.png", item);
|
||||
CreateStationItem(Type_MyNeighbourhood, "My Neighbourhood", ":last.fm/neighbour_radio.png", item);
|
||||
|
||||
// Types that spawn a popup dialog
|
||||
c = CreateStationItem(Type_ArtistRadio, "Artist radio...",
|
||||
":last.fm/icon_radio.png", item);
|
||||
c->playable = false;
|
||||
|
||||
c = CreateStationItem(Type_TagRadio, "Tag radio...",
|
||||
":last.fm/icon_tag.png", item);
|
||||
c->playable = false;
|
||||
|
||||
// Types that have children
|
||||
artist_list_ = new RadioItem(this, Type_ArtistRadio, "Artist radio", item);
|
||||
artist_list_->icon = QIcon(":last.fm/icon_radio.png");
|
||||
artist_list_->lazy_loaded = true;
|
||||
|
||||
tag_list_ = new RadioItem(this, Type_TagRadio, "Tag radio", item);
|
||||
tag_list_->icon = QIcon(":last.fm/icon_tag.png");
|
||||
tag_list_->lazy_loaded = true;
|
||||
|
||||
RestoreList("artists", Type_Artist, QIcon(":last.fm/icon_radio.png"), artist_list_);
|
||||
RestoreList("tags", Type_Tag, QIcon(":last.fm/icon_tag.png"), tag_list_);
|
||||
|
||||
friends_list_ = new RadioItem(this, Type_MyFriends, "Friends", item);
|
||||
friends_list_->icon = QIcon(":last.fm/my_friends.png");
|
||||
|
||||
@ -103,6 +112,9 @@ void LastFMService::LazyPopulate(RadioItem *item) {
|
||||
|
||||
if (!IsAuthenticated())
|
||||
config_->show();
|
||||
|
||||
add_artist_action_->setEnabled(true);
|
||||
add_tag_action_->setEnabled(true);
|
||||
break;
|
||||
|
||||
case Type_MyFriends:
|
||||
@ -204,6 +216,12 @@ QUrl LastFMService::UrlForItem(const RadioItem* item) const {
|
||||
|
||||
case Type_OtherUserNeighbourhood:
|
||||
return "lastfm://user/" + item->key + "/neighbours";
|
||||
|
||||
case Type_Artist:
|
||||
return "lastfm://artist/" + item->key + "/similarartists";
|
||||
|
||||
case Type_Tag:
|
||||
return "lastfm://globaltags/" + item->key;
|
||||
}
|
||||
return QUrl();
|
||||
}
|
||||
@ -220,6 +238,8 @@ QString LastFMService::TitleForItem(const RadioItem* item) const {
|
||||
case Type_OtherUserRadio: return item->key + "'s Library";
|
||||
case Type_OtherUserLoved: return item->key + "'s Loved Tracks";
|
||||
case Type_OtherUserNeighbourhood: return item->key + "'s Neighbour Radio";
|
||||
case Type_Artist: return "Similar artists to " + item->key;
|
||||
case Type_Tag: return "Tag radio: " + item->key;
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
@ -444,3 +464,62 @@ void LastFMService::RefreshNeighboursFinished() {
|
||||
void LastFMService::AddToPlaylist() {
|
||||
emit AddItemToPlaylist(context_item_);
|
||||
}
|
||||
|
||||
void LastFMService::AddArtistRadio() {
|
||||
AddArtistOrTag("artists", LastFMStationDialog::Artist, Type_Artist, QIcon(":last.fm/icon_radio.png"), artist_list_);
|
||||
}
|
||||
|
||||
void LastFMService::AddTagRadio() {
|
||||
AddArtistOrTag("tags", LastFMStationDialog::Tag, Type_Tag, QIcon(":last.fm/icon_tag.png"), tag_list_);
|
||||
}
|
||||
|
||||
void LastFMService::AddArtistOrTag(const QString& name,
|
||||
LastFMStationDialog::Type dialog_type, ItemType item_type,
|
||||
const QIcon& icon, RadioItem* list) {
|
||||
station_dialog_->SetType(dialog_type);
|
||||
if (station_dialog_->exec() == QDialog::Rejected)
|
||||
return;
|
||||
|
||||
if (station_dialog_->content().isEmpty())
|
||||
return;
|
||||
|
||||
RadioItem* item = new RadioItem(this, item_type, station_dialog_->content());
|
||||
item->icon = icon;
|
||||
item->playable = true;
|
||||
item->lazy_loaded = true;
|
||||
item->InsertNotify(list);
|
||||
emit AddItemToPlaylist(item);
|
||||
|
||||
SaveList(name, list);
|
||||
}
|
||||
|
||||
void LastFMService::SaveList(const QString& name, RadioItem* list) const {
|
||||
QSettings settings;
|
||||
settings.beginGroup(kSettingsGroup);
|
||||
|
||||
settings.beginWriteArray(name, list->children.count());
|
||||
for (int i=0 ; i<list->children.count() ; ++i) {
|
||||
settings.setArrayIndex(i);
|
||||
settings.setValue("key", list->children[i]->key);
|
||||
}
|
||||
settings.endArray();
|
||||
}
|
||||
|
||||
void LastFMService::RestoreList(const QString &name, ItemType item_type,
|
||||
const QIcon& icon, RadioItem *list) {
|
||||
QSettings settings;
|
||||
settings.beginGroup(kSettingsGroup);
|
||||
|
||||
list->ClearNotify();
|
||||
|
||||
int count = settings.beginReadArray(name);
|
||||
for (int i=0 ; i<count ; ++i) {
|
||||
settings.setArrayIndex(i);
|
||||
RadioItem* item = new RadioItem(this, item_type,
|
||||
settings.value("key").toString(), list);
|
||||
item->icon = icon;
|
||||
item->playable = true;
|
||||
item->lazy_loaded = true;
|
||||
}
|
||||
settings.endArray();
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "radioservice.h"
|
||||
#include "song.h"
|
||||
#include "lastfmstationdialog.h"
|
||||
|
||||
#include <lastfm/RadioTuner>
|
||||
|
||||
@ -37,6 +38,8 @@ class LastFMService : public RadioService {
|
||||
Type_OtherUserRadio,
|
||||
Type_OtherUserLoved,
|
||||
Type_OtherUserNeighbourhood,
|
||||
Type_Artist,
|
||||
Type_Tag,
|
||||
};
|
||||
|
||||
// RadioService
|
||||
@ -80,6 +83,8 @@ class LastFMService : public RadioService {
|
||||
void TunerError(lastfm::ws::Error error);
|
||||
|
||||
void AddToPlaylist();
|
||||
void AddArtistRadio();
|
||||
void AddTagRadio();
|
||||
|
||||
private:
|
||||
RadioItem* CreateStationItem(ItemType type, const QString& name,
|
||||
@ -89,6 +94,12 @@ class LastFMService : public RadioService {
|
||||
lastfm::Track TrackFromSong(const Song& song) const;
|
||||
void RefreshFriends();
|
||||
void RefreshNeighbours();
|
||||
void AddArtistOrTag(const QString& name,
|
||||
LastFMStationDialog::Type dialog_type, ItemType item_type,
|
||||
const QIcon& icon, RadioItem* list);
|
||||
void SaveList(const QString& name, RadioItem* list) const;
|
||||
void RestoreList(const QString &name, ItemType item_type,
|
||||
const QIcon& icon, RadioItem *list);
|
||||
|
||||
private:
|
||||
lastfm::RadioTuner* tuner_;
|
||||
@ -96,9 +107,13 @@ class LastFMService : public RadioService {
|
||||
lastfm::Track last_track_;
|
||||
|
||||
LastFMConfig* config_;
|
||||
LastFMStationDialog* station_dialog_;
|
||||
|
||||
QMenu* context_menu_;
|
||||
QAction* play_action_;
|
||||
QAction* remove_action_;
|
||||
QAction* add_artist_action_;
|
||||
QAction* add_tag_action_;
|
||||
RadioItem* context_item_;
|
||||
|
||||
QUrl last_url_;
|
||||
@ -106,6 +121,8 @@ class LastFMService : public RadioService {
|
||||
|
||||
bool scrobbling_enabled_;
|
||||
|
||||
RadioItem* artist_list_;
|
||||
RadioItem* tag_list_;
|
||||
RadioItem* friends_list_;
|
||||
RadioItem* neighbours_list_;
|
||||
};
|
||||
|
18
src/lastfmstationdialog.cpp
Normal file
18
src/lastfmstationdialog.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
#include "lastfmstationdialog.h"
|
||||
#include "ui_lastfmstationdialog.h"
|
||||
|
||||
LastFMStationDialog::LastFMStationDialog(QWidget* parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
ui_.setupUi(this);
|
||||
}
|
||||
|
||||
void LastFMStationDialog::SetType(Type type) {
|
||||
ui_.type->setCurrentIndex(type);
|
||||
ui_.content->clear();
|
||||
ui_.content->setFocus(Qt::OtherFocusReason);
|
||||
}
|
||||
|
||||
QString LastFMStationDialog::content() const {
|
||||
return ui_.content->text();
|
||||
}
|
26
src/lastfmstationdialog.h
Normal file
26
src/lastfmstationdialog.h
Normal file
@ -0,0 +1,26 @@
|
||||
#ifndef LASTFMSTATIONDIALOG_H
|
||||
#define LASTFMSTATIONDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include "ui_lastfmstationdialog.h"
|
||||
|
||||
class LastFMStationDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
LastFMStationDialog(QWidget* parent = 0);
|
||||
|
||||
enum Type {
|
||||
Artist,
|
||||
Tag,
|
||||
};
|
||||
|
||||
void SetType(Type type);
|
||||
QString content() const;
|
||||
|
||||
private:
|
||||
Ui::LastFMStationDialog ui_;
|
||||
};
|
||||
|
||||
#endif // LASTFMSTATIONDIALOG_H
|
108
src/lastfmstationdialog.ui
Normal file
108
src/lastfmstationdialog.ui
Normal file
@ -0,0 +1,108 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>LastFMStationDialog</class>
|
||||
<widget class="QDialog" name="LastFMStationDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>407</width>
|
||||
<height>120</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Play Artist or Tag</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Enter an <b>artist</b> or <b>tag</b> to start listening to Last.fm radio.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QComboBox" name="type">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Artist</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Tag</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="content"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>7</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>LastFMStationDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>LastFMStationDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -42,7 +42,8 @@ SOURCES += main.cpp \
|
||||
busyindicator.cpp \
|
||||
radioplaylistitem.cpp \
|
||||
radioloadingindicator.cpp \
|
||||
radioview.cpp
|
||||
radioview.cpp \
|
||||
lastfmstationdialog.cpp
|
||||
HEADERS += mainwindow.h \
|
||||
player.h \
|
||||
library.h \
|
||||
@ -84,12 +85,14 @@ HEADERS += mainwindow.h \
|
||||
radiomimedata.h \
|
||||
radioplaylistitem.h \
|
||||
radioloadingindicator.h \
|
||||
radioview.h
|
||||
radioview.h \
|
||||
lastfmstationdialog.h
|
||||
FORMS += mainwindow.ui \
|
||||
libraryconfig.ui \
|
||||
fileview.ui \
|
||||
lastfmconfig.ui \
|
||||
radioloadingindicator.ui
|
||||
radioloadingindicator.ui \
|
||||
lastfmstationdialog.ui
|
||||
RESOURCES += ../data/data.qrc
|
||||
OTHER_FILES += ../data/schema.sql \
|
||||
../data/mainwindow.css
|
||||
|
Loading…
x
Reference in New Issue
Block a user