Love, ban, skip last.fm tracks

This commit is contained in:
David Sansome 2009-12-29 20:48:50 +00:00
parent 5e514c42b6
commit b5be7d6cb9
12 changed files with 84 additions and 70 deletions

2
TODO
View File

@ -10,8 +10,6 @@
Last.fm:
- Artist/tag/etc. radio
- Skip, love
- Disable the pause button
- Double click from radio list
- Right click on radio list to configure Last.fm
- More types of radio

View File

@ -10,8 +10,6 @@ LastFMConfig::LastFMConfig(LastFMService* service, QWidget *parent)
service_(service)
{
ui_.setupUi(this);
ui_.username->setText(lastfm::ws::Username);
ui_.busy->hide();
connect(service_, SIGNAL(AuthenticationComplete(bool)), SLOT(AuthenticationComplete(bool)));
@ -27,6 +25,8 @@ void LastFMConfig::accept() {
ui_.button_box->setEnabled(false);
service_->Authenticate(ui_.username->text(), ui_.password->text());
emit ScrobblingEnabledChanged(ui_.scrobble->isChecked());
}
void LastFMConfig::AuthenticationComplete(bool success) {

View File

@ -15,11 +15,15 @@ class LastFMConfig : public QDialog {
void accept();
Ui::LastFMConfig ui_;
signals:
void ScrobblingEnabledChanged(bool value);
private slots:
void AuthenticationComplete(bool success);
private:
Ui::LastFMConfig ui_;
LastFMService* service_;
};

View File

@ -52,6 +52,9 @@
<property name="text">
<string>Scrobble tracks that I listen to</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
</layout>

View File

@ -20,7 +20,8 @@ LastFMService::LastFMService(QObject* parent)
: RadioService(kServiceName, parent),
tuner_(NULL),
scrobbler_(NULL),
initial_tune_(false)
initial_tune_(false),
scrobbling_enabled_(false)
{
lastfm::ws::ApiKey = kApiKey;
lastfm::ws::SharedSecret = kSecret;
@ -29,8 +30,13 @@ LastFMService::LastFMService(QObject* parent)
settings.beginGroup(kSettingsGroup);
lastfm::ws::Username = settings.value("username").toString();
lastfm::ws::SessionKey = settings.value("session").toString();
scrobbling_enabled_ = settings.value("scrobbling_enabled", true).toBool();
config_ = new LastFMConfig(this);
connect(config_, SIGNAL(ScrobblingEnabledChanged(bool)), SLOT(ScrobblingEnabledChangedSlot(bool)));
config_->ui_.username->setText(lastfm::ws::Username);
config_->ui_.scrobble->setEnabled(scrobbling_enabled_);
}
LastFMService::~LastFMService() {
@ -41,6 +47,16 @@ bool LastFMService::IsAuthenticated() const {
return !lastfm::ws::SessionKey.isEmpty();
}
void LastFMService::ScrobblingEnabledChangedSlot(bool value) {
scrobbling_enabled_ = value;
QSettings settings;
settings.beginGroup(kSettingsGroup);
settings.setValue("scrobbling_enabled", scrobbling_enabled_);
emit ScrobblingEnabledChanged(value);
}
RadioItem* LastFMService::CreateRootItem(RadioItem* parent) {
RadioItem* item = new RadioItem(this, RadioItem::Type_Service, "Last.fm", parent);
item->icon = QIcon(":last.fm/as.png");
@ -240,7 +256,7 @@ void LastFMService::TunerTrackAvailable() {
}
bool LastFMService::InitScrobbler() {
if (!IsAuthenticated())
if (!IsAuthenticated() || !IsScrobblingEnabled())
return false;
if (!scrobbler_)
@ -282,6 +298,9 @@ void LastFMService::Scrobble() {
}
void LastFMService::Love() {
if (!IsAuthenticated())
config_->show();
lastfm::MutableTrack mtrack(last_track_);
mtrack.love();
}
@ -289,4 +308,7 @@ void LastFMService::Love() {
void LastFMService::Ban() {
lastfm::MutableTrack mtrack(last_track_);
mtrack.ban();
Scrobble();
LoadNext(last_url_);
}

View File

@ -38,18 +38,23 @@ class LastFMService : public RadioService {
bool ShowLastFmControls() const { return true; }
bool IsAuthenticated() const;
bool IsScrobblingEnabled() const { return scrobbling_enabled_; }
void Authenticate(const QString& username, const QString& password);
void NowPlaying(const Song& song);
public slots:
void Scrobble();
void Love();
void Ban();
signals:
void AuthenticationComplete(bool success);
void ScrobblingEnabledChanged(bool value);
private slots:
void AuthenticateReplyFinished();
void ScrobblingEnabledChangedSlot(bool value);
void TunerTrackAvailable();
void TunerError(lastfm::ws::Error error);
@ -69,6 +74,8 @@ class LastFMService : public RadioService {
LastFMConfig* config_;
QUrl last_url_;
bool initial_tune_;
bool scrobbling_enabled_;
};
#endif // LASTFMSERVICE_H

View File

@ -41,7 +41,6 @@ MainWindow::MainWindow(QWidget *parent)
tray_icon_->show();
ui_.volume->setValue(player_->GetVolume());
ui_.last_fm_controls->hide();
track_position_timer_->setInterval(1000);
connect(track_position_timer_, SIGNAL(timeout()), SLOT(UpdateTrackPosition()));
@ -75,6 +74,8 @@ MainWindow::MainWindow(QWidget *parent)
connect(ui_.action_quit, SIGNAL(triggered()), qApp, SLOT(quit()));
connect(ui_.action_stop_after_this_track, SIGNAL(triggered()), SLOT(StopAfterCurrent()));
connect(ui_.library_filter, SIGNAL(textChanged(QString)), library_, SLOT(SetFilterText(QString)));
connect(ui_.action_ban, SIGNAL(triggered()), radio_model_->GetLastFMService(), SLOT(Ban()));
connect(ui_.action_love, SIGNAL(triggered()), SLOT(Love()));
// Give actions to buttons
ui_.forward_button->setDefaultAction(ui_.action_next_track);
@ -155,6 +156,7 @@ MainWindow::MainWindow(QWidget *parent)
connect(radio_model_, SIGNAL(StreamFinished()), player_, SLOT(Next()));
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)));
// Tray icon
QMenu* tray_menu = new QMenu(this);
@ -223,9 +225,8 @@ void MainWindow::MediaStopped() {
ui_.action_play_pause->setEnabled(true);
ui_.action_ban->setVisible(false);
ui_.action_love->setVisible(false);
ui_.last_fm_controls->hide();
ui_.action_ban->setEnabled(false);
ui_.action_love->setEnabled(false);
track_position_timer_->stop();
}
@ -250,15 +251,21 @@ void MainWindow::MediaPlaying() {
ui_.action_play_pause->setEnabled(
! playlist_->current_item_options() & PlaylistItem::PauseDisabled);
bool lastfm = playlist_->current_item_options() & PlaylistItem::LastFMControls;
ui_.action_ban->setVisible(lastfm);
ui_.action_love->setVisible(lastfm);
ui_.last_fm_controls->setVisible(lastfm);
bool is_lastfm = playlist_->current_item_options() & PlaylistItem::LastFMControls;
LastFMService* lastfm = radio_model_->GetLastFMService();
ui_.action_ban->setEnabled(lastfm->IsScrobblingEnabled() && is_lastfm);
ui_.action_love->setEnabled(lastfm->IsScrobblingEnabled());
track_position_timer_->start();
UpdateTrackPosition();
}
void MainWindow::ScrobblingEnabledChanged(bool value) {
ui_.action_ban->setEnabled(value);
ui_.action_love->setEnabled(value);
}
void MainWindow::resizeEvent(QResizeEvent*) {
SaveGeometry();
}
@ -340,9 +347,16 @@ void MainWindow::FilePathChanged(const QString& path) {
void MainWindow::UpdateTrackPosition() {
int position = std::floor(float(player_->GetEngine()->position()) / 1000.0 + 0.5);
LastFMService* lastfm = radio_model_->GetLastFMService();
if (!playlist_->has_scrobbled() &&
position >= playlist_->scrobble_point()) {
radio_model_->GetLastFMService()->Scrobble();
lastfm->Scrobble();
playlist_->set_scrobbled(true);
}
}
void MainWindow::Love() {
radio_model_->GetLastFMService()->Love();
ui_.action_love->setEnabled(false);
}

View File

@ -11,6 +11,7 @@ class Player;
class Library;
class LibraryConfig;
class RadioModel;
class Song;
class QSortFilterProxyModel;
class SystemTrayIcon;
@ -48,6 +49,9 @@ class MainWindow : public QMainWindow {
void UpdateTrackPosition();
void ScrobblingEnabledChanged(bool value);
void Love();
private:
void SaveGeometry();

View File

@ -535,6 +535,9 @@
</property>
</action>
<action name="action_love">
<property name="enabled">
<bool>false</bool>
</property>
<property name="icon">
<iconset resource="../data/data.qrc">
<normaloff>:/last.fm/love.png</normaloff>:/last.fm/love.png</iconset>
@ -542,11 +545,11 @@
<property name="text">
<string>Love</string>
</property>
<property name="visible">
<bool>false</bool>
</property>
</action>
<action name="action_ban">
<property name="enabled">
<bool>false</bool>
</property>
<property name="icon">
<iconset resource="../data/data.qrc">
<normaloff>:/last.fm/ban.png</normaloff>:/last.fm/ban.png</iconset>
@ -554,9 +557,6 @@
<property name="text">
<string>Ban</string>
</property>
<property name="visible">
<bool>false</bool>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>

View File

@ -23,6 +23,11 @@ Player::Player(Playlist* playlist, LastFMService* lastfm, QObject* parent)
}
void Player::Next() {
if (playlist_->current_item_options() & PlaylistItem::ContainsMultipleTracks) {
playlist_->current_item()->LoadNext();
return;
}
int i = playlist_->next_index();
playlist_->set_current_index(i);
if (i == -1) {
@ -30,7 +35,6 @@ void Player::Next() {
return;
}
qDebug() << "Playing item" << i;
PlayAt(i);
}
@ -41,12 +45,7 @@ void Player::TrackEnded() {
return;
}
// Is this track a radio station (like Last.fm) that can have another track?
PlaylistItem* item = playlist_->item_at(i);
if (item->options() & PlaylistItem::ContainsMultipleTracks)
item->LoadNext();
else
Next();
Next();
}
void Player::PlayPause() {
@ -123,7 +122,9 @@ void Player::PlayAt(int index) {
item->StartLoading();
else {
engine_->play(item->Url());
lastfm_->NowPlaying(item->Metadata());
if (lastfm_->IsScrobblingEnabled())
lastfm_->NowPlaying(item->Metadata());
}
}
@ -137,5 +138,6 @@ void Player::StreamReady(const QUrl& original_url, const QUrl& media_url) {
return;
engine_->play(media_url);
lastfm_->NowPlaying(item->Metadata());
}

View File

@ -16,7 +16,6 @@ PlaylistHeader::PlaylistHeader(Qt::Orientation orientation, QWidget* parent)
show_action->setMenu(show_menu_);
connect(show_mapper_, SIGNAL(mapped(int)), SLOT(ToggleVisible(int)));
connect(this, SIGNAL(sectionMoved(int,int,int)), SLOT(SectionMoved()));
}
void PlaylistHeader::contextMenuEvent(QContextMenuEvent* e) {
@ -60,38 +59,3 @@ void PlaylistHeader::HideCurrent() {
void PlaylistHeader::ToggleVisible(int section) {
setSectionHidden(section, !isSectionHidden(section));
}
void PlaylistHeader::resizeEvent(QResizeEvent *event) {
if (!event->oldSize().isValid())
return;
const float scale = float(event->size().width()) / event->oldSize().width();
for (int i=0 ; i<count() ; ++i) {
resizeSection(i, sectionSize(i) * scale);
}
}
void PlaylistHeader::SectionMoved() {
for (int i=0 ; i<count() ; ++i) {
setResizeMode(i, Interactive);
if (sectionSize(i) < 20)
resizeSection(i, 50);
}
setResizeMode(logicalIndex(LastVisualIndex()), Stretch);
}
int PlaylistHeader::LastVisualIndex() const {
int ret = -1;
for (int i=0 ; i<count() ; ++i) {
if (isSectionHidden(i))
continue;
ret = qMax(visualIndex(i), ret);
}
return ret;
}

View File

@ -14,17 +14,13 @@ class PlaylistHeader : public QHeaderView {
// QWidget
void contextMenuEvent(QContextMenuEvent* e);
void resizeEvent(QResizeEvent *event);
private slots:
void HideCurrent();
void ToggleVisible(int section);
void SectionMoved();
private:
void AddColumnAction(int index);
int LastVisualIndex() const;
private:
int menu_section_;