diff --git a/TODO b/TODO index 699b624af..0af72a4fa 100644 --- a/TODO +++ b/TODO @@ -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 diff --git a/src/lastfmconfig.cpp b/src/lastfmconfig.cpp index a05f080a2..47bf4cbc1 100644 --- a/src/lastfmconfig.cpp +++ b/src/lastfmconfig.cpp @@ -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) { diff --git a/src/lastfmconfig.h b/src/lastfmconfig.h index e0659bdff..04e9c74c7 100644 --- a/src/lastfmconfig.h +++ b/src/lastfmconfig.h @@ -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_; }; diff --git a/src/lastfmconfig.ui b/src/lastfmconfig.ui index 015f88ae3..7d62b1096 100644 --- a/src/lastfmconfig.ui +++ b/src/lastfmconfig.ui @@ -52,6 +52,9 @@ Scrobble tracks that I listen to + + true + diff --git a/src/lastfmservice.cpp b/src/lastfmservice.cpp index 9277a07fc..e571201cb 100644 --- a/src/lastfmservice.cpp +++ b/src/lastfmservice.cpp @@ -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_); } diff --git a/src/lastfmservice.h b/src/lastfmservice.h index b0fc95e35..d369131a8 100644 --- a/src/lastfmservice.h +++ b/src/lastfmservice.h @@ -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 diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index d4279f426..836b1737b 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -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); +} diff --git a/src/mainwindow.h b/src/mainwindow.h index c46ce812b..83ebff34b 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -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(); diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 84031e9df..2726301fc 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -535,6 +535,9 @@ + + false + :/last.fm/love.png:/last.fm/love.png @@ -542,11 +545,11 @@ Love - - false - + + false + :/last.fm/ban.png:/last.fm/ban.png @@ -554,9 +557,6 @@ Ban - - false - diff --git a/src/player.cpp b/src/player.cpp index 69bd9c01f..2230d91ae 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -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()); } diff --git a/src/playlistheader.cpp b/src/playlistheader.cpp index 918874ccb..9a3b43015 100644 --- a/src/playlistheader.cpp +++ b/src/playlistheader.cpp @@ -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