mirror of
https://github.com/clementine-player/Clementine
synced 2025-01-31 03:27:40 +01:00
parent
1b7f99127d
commit
4ab4bbc23f
@ -245,18 +245,11 @@
|
|||||||
<file>last.fm/as_disabled.png</file>
|
<file>last.fm/as_disabled.png</file>
|
||||||
<file>last.fm/as_light.png</file>
|
<file>last.fm/as_light.png</file>
|
||||||
<file>last.fm/as.png</file>
|
<file>last.fm/as.png</file>
|
||||||
<file>last.fm/ban.png</file>
|
|
||||||
<file>last.fm/icon_radio.png</file>
|
<file>last.fm/icon_radio.png</file>
|
||||||
<file>last.fm/icon_tag.png</file>
|
<file>last.fm/icon_tag.png</file>
|
||||||
<file>last.fm/icon_user.png</file>
|
<file>last.fm/icon_user.png</file>
|
||||||
<file>last.fm/lastfm.png</file>
|
<file>last.fm/lastfm.png</file>
|
||||||
<file>last.fm/loved_radio.png</file>
|
|
||||||
<file>last.fm/love.png</file>
|
<file>last.fm/love.png</file>
|
||||||
<file>last.fm/my_friends.png</file>
|
|
||||||
<file>last.fm/my_neighbours.png</file>
|
|
||||||
<file>last.fm/neighbour_radio.png</file>
|
|
||||||
<file>last.fm/personal_radio.png</file>
|
|
||||||
<file>last.fm/recommended_radio.png</file>
|
|
||||||
<file>last.fm/user_purple.png</file>
|
<file>last.fm/user_purple.png</file>
|
||||||
<file>logo.png</file>
|
<file>logo.png</file>
|
||||||
<file>lumberjacksong.txt</file>
|
<file>lumberjacksong.txt</file>
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 637 B |
Binary file not shown.
Before Width: | Height: | Size: 580 B |
Binary file not shown.
Before Width: | Height: | Size: 1.0 KiB |
@ -494,6 +494,7 @@ set(HEADERS
|
|||||||
internet/magnatunesettingspage.h
|
internet/magnatunesettingspage.h
|
||||||
internet/oauthenticator.h
|
internet/oauthenticator.h
|
||||||
internet/savedradio.h
|
internet/savedradio.h
|
||||||
|
internet/scrobbler.h
|
||||||
internet/searchboxwidget.h
|
internet/searchboxwidget.h
|
||||||
internet/somafmservice.h
|
internet/somafmservice.h
|
||||||
internet/somafmurlhandler.h
|
internet/somafmurlhandler.h
|
||||||
@ -817,13 +818,10 @@ optional_source(ENABLE_VISUALISATIONS
|
|||||||
optional_source(HAVE_LIBLASTFM
|
optional_source(HAVE_LIBLASTFM
|
||||||
SOURCES
|
SOURCES
|
||||||
covers/lastfmcoverprovider.cpp
|
covers/lastfmcoverprovider.cpp
|
||||||
globalsearch/lastfmsearchprovider.cpp
|
|
||||||
internet/fixlastfm.cpp
|
internet/fixlastfm.cpp
|
||||||
internet/lastfmcompat.cpp
|
internet/lastfmcompat.cpp
|
||||||
internet/lastfmservice.cpp
|
internet/lastfmservice.cpp
|
||||||
internet/lastfmsettingspage.cpp
|
internet/lastfmsettingspage.cpp
|
||||||
internet/lastfmstationdialog.cpp
|
|
||||||
internet/lastfmurlhandler.cpp
|
|
||||||
songinfo/echonestsimilarartists.cpp
|
songinfo/echonestsimilarartists.cpp
|
||||||
songinfo/echonesttags.cpp
|
songinfo/echonesttags.cpp
|
||||||
songinfo/lastfmtrackinfoprovider.cpp
|
songinfo/lastfmtrackinfoprovider.cpp
|
||||||
@ -832,14 +830,12 @@ optional_source(HAVE_LIBLASTFM
|
|||||||
covers/lastfmcoverprovider.h
|
covers/lastfmcoverprovider.h
|
||||||
internet/lastfmservice.h
|
internet/lastfmservice.h
|
||||||
internet/lastfmsettingspage.h
|
internet/lastfmsettingspage.h
|
||||||
internet/lastfmstationdialog.h
|
|
||||||
songinfo/echonestsimilarartists.h
|
songinfo/echonestsimilarartists.h
|
||||||
songinfo/echonesttags.h
|
songinfo/echonesttags.h
|
||||||
songinfo/lastfmtrackinfoprovider.h
|
songinfo/lastfmtrackinfoprovider.h
|
||||||
songinfo/tagwidget.h
|
songinfo/tagwidget.h
|
||||||
UI
|
UI
|
||||||
internet/lastfmsettingspage.ui
|
internet/lastfmsettingspage.ui
|
||||||
internet/lastfmstationdialog.ui
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -39,6 +39,10 @@
|
|||||||
#include "podcasts/podcastdownloader.h"
|
#include "podcasts/podcastdownloader.h"
|
||||||
#include "podcasts/podcastupdater.h"
|
#include "podcasts/podcastupdater.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBLASTFM
|
||||||
|
#include "internet/lastfmservice.h"
|
||||||
|
#endif // HAVE_LIBLASTFM
|
||||||
|
|
||||||
#ifdef HAVE_MOODBAR
|
#ifdef HAVE_MOODBAR
|
||||||
#include "moodbar/moodbarcontroller.h"
|
#include "moodbar/moodbarcontroller.h"
|
||||||
#include "moodbar/moodbarloader.h"
|
#include "moodbar/moodbarloader.h"
|
||||||
@ -69,7 +73,8 @@ Application::Application(QObject* parent)
|
|||||||
moodbar_loader_(nullptr),
|
moodbar_loader_(nullptr),
|
||||||
moodbar_controller_(nullptr),
|
moodbar_controller_(nullptr),
|
||||||
network_remote_(nullptr),
|
network_remote_(nullptr),
|
||||||
network_remote_helper_(nullptr) {
|
network_remote_helper_(nullptr),
|
||||||
|
scrobbler_(nullptr) {
|
||||||
tag_reader_client_ = new TagReaderClient(this);
|
tag_reader_client_ = new TagReaderClient(this);
|
||||||
MoveToNewThread(tag_reader_client_);
|
MoveToNewThread(tag_reader_client_);
|
||||||
tag_reader_client_->Start();
|
tag_reader_client_->Start();
|
||||||
@ -116,6 +121,10 @@ Application::Application(QObject* parent)
|
|||||||
// crash when a client connects before the manager is initialized!
|
// crash when a client connects before the manager is initialized!
|
||||||
network_remote_helper_ = new NetworkRemoteHelper(this);
|
network_remote_helper_ = new NetworkRemoteHelper(this);
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBLASTFM
|
||||||
|
scrobbler_ = new LastFMService(this, this);
|
||||||
|
#endif // HAVE_LIBLASTFM
|
||||||
|
|
||||||
library_->Init();
|
library_->Init();
|
||||||
|
|
||||||
DoInAMinuteOrSo(database_, SLOT(DoBackup()));
|
DoInAMinuteOrSo(database_, SLOT(DoBackup()));
|
||||||
|
@ -44,6 +44,7 @@ class PodcastDownloader;
|
|||||||
class PlaylistManager;
|
class PlaylistManager;
|
||||||
class PodcastBackend;
|
class PodcastBackend;
|
||||||
class PodcastUpdater;
|
class PodcastUpdater;
|
||||||
|
class Scrobbler;
|
||||||
class TagReaderClient;
|
class TagReaderClient;
|
||||||
class TaskManager;
|
class TaskManager;
|
||||||
|
|
||||||
@ -86,6 +87,7 @@ class Application : public QObject {
|
|||||||
NetworkRemoteHelper* network_remote_helper() const {
|
NetworkRemoteHelper* network_remote_helper() const {
|
||||||
return network_remote_helper_;
|
return network_remote_helper_;
|
||||||
}
|
}
|
||||||
|
Scrobbler* scrobbler() const { return scrobbler_; }
|
||||||
|
|
||||||
LibraryBackend* library_backend() const;
|
LibraryBackend* library_backend() const;
|
||||||
LibraryModel* library_model() const;
|
LibraryModel* library_model() const;
|
||||||
@ -128,6 +130,7 @@ signals:
|
|||||||
MoodbarController* moodbar_controller_;
|
MoodbarController* moodbar_controller_;
|
||||||
NetworkRemote* network_remote_;
|
NetworkRemote* network_remote_;
|
||||||
NetworkRemoteHelper* network_remote_helper_;
|
NetworkRemoteHelper* network_remote_helper_;
|
||||||
|
Scrobbler* scrobbler_;
|
||||||
|
|
||||||
QList<QObject*> objects_in_threads_;
|
QList<QObject*> objects_in_threads_;
|
||||||
QList<QThread*> threads_;
|
QList<QThread*> threads_;
|
||||||
|
@ -76,7 +76,7 @@ void Player::Init() {
|
|||||||
engine_->SetVolume(settings_.value("volume", 50).toInt());
|
engine_->SetVolume(settings_.value("volume", 50).toInt());
|
||||||
|
|
||||||
#ifdef HAVE_LIBLASTFM
|
#ifdef HAVE_LIBLASTFM
|
||||||
lastfm_ = InternetModel::Service<LastFMService>();
|
lastfm_ = app_->scrobbler();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
#include "playlist/playlistitem.h"
|
#include "playlist/playlistitem.h"
|
||||||
|
|
||||||
class Application;
|
class Application;
|
||||||
class LastFMService;
|
class Scrobbler;
|
||||||
|
|
||||||
class PlayerInterface : public QObject {
|
class PlayerInterface : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -173,7 +173,7 @@ class Player : public PlayerInterface {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Application* app_;
|
Application* app_;
|
||||||
LastFMService* lastfm_;
|
Scrobbler* lastfm_;
|
||||||
QSettings settings_;
|
QSettings settings_;
|
||||||
|
|
||||||
PlaylistItemPtr current_item_;
|
PlaylistItemPtr current_item_;
|
||||||
|
@ -1,86 +0,0 @@
|
|||||||
/* This file is part of Clementine.
|
|
||||||
Copyright 2010, David Sansome <me@davidsansome.com>
|
|
||||||
|
|
||||||
Clementine is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Clementine is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "lastfmsearchprovider.h"
|
|
||||||
#include "core/logging.h"
|
|
||||||
#include "internet/lastfmservice.h"
|
|
||||||
|
|
||||||
LastFMSearchProvider::LastFMSearchProvider(LastFMService* service,
|
|
||||||
Application* app, QObject* parent)
|
|
||||||
: SimpleSearchProvider(app, parent), service_(service) {
|
|
||||||
Init("Last.fm", "lastfm", QIcon(":last.fm/as.png"),
|
|
||||||
CanShowConfig | CanGiveSuggestions);
|
|
||||||
icon_ = ScaleAndPad(QImage(":last.fm/as.png"));
|
|
||||||
|
|
||||||
set_safe_words(QStringList() << "lastfm"
|
|
||||||
<< "last.fm");
|
|
||||||
set_max_suggestion_count(3);
|
|
||||||
|
|
||||||
connect(service, SIGNAL(SavedItemsChanged()), SLOT(MaybeRecreateItems()));
|
|
||||||
|
|
||||||
// Load the friends list on startup only if it doesn't involve going to update
|
|
||||||
// info from the server.
|
|
||||||
if (!service_->IsFriendsListStale()) RecreateItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMSearchProvider::LoadArtAsync(int id, const Result& result) {
|
|
||||||
// TODO: Maybe we should try to get user pictures for friends?
|
|
||||||
|
|
||||||
emit ArtLoaded(id, icon_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMSearchProvider::RecreateItems() {
|
|
||||||
QList<Item> items;
|
|
||||||
|
|
||||||
items << Item(tr("My Last.fm Recommended Radio"),
|
|
||||||
QUrl("lastfm://user/USERNAME/recommended"), "recommended");
|
|
||||||
items << Item(tr("My Last.fm Library"),
|
|
||||||
QUrl("lastfm://user/USERNAME/library"), "radio");
|
|
||||||
items << Item(tr("My Last.fm Mix Radio"), QUrl("lastfm://user/USERNAME/mix"),
|
|
||||||
"mix");
|
|
||||||
items << Item(tr("My Last.fm Neighborhood"),
|
|
||||||
QUrl("lastfm://user/USERNAME/neighbours"), "neighborhood");
|
|
||||||
|
|
||||||
const QStringList artists = service_->SavedArtistRadioNames();
|
|
||||||
const QStringList tags = service_->SavedTagRadioNames();
|
|
||||||
const QStringList friends = service_->FriendNames();
|
|
||||||
|
|
||||||
for (const QString& name : artists) {
|
|
||||||
items << Item(tr(LastFMService::kTitleArtist).arg(name),
|
|
||||||
QUrl(QString(LastFMService::kUrlArtist).arg(name)), name);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const QString& name : tags) {
|
|
||||||
items << Item(tr(LastFMService::kTitleTag).arg(name),
|
|
||||||
QUrl(QString(LastFMService::kUrlTag).arg(name)), name);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const QString& name : friends) {
|
|
||||||
items << Item(tr("Last.fm Radio Station - %1").arg(name),
|
|
||||||
QUrl("lastfm://user/" + name + "/library"), name);
|
|
||||||
items << Item(tr("Last.fm Mix Radio - %1").arg(name),
|
|
||||||
QUrl("lastfm://user/" + name + "/mix"), name);
|
|
||||||
items << Item(tr("Last.fm Neighbor Radio - %1").arg(name),
|
|
||||||
QUrl("lastfm://user/" + name + "/neighbours"), name);
|
|
||||||
}
|
|
||||||
|
|
||||||
SetItems(items);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LastFMSearchProvider::IsLoggedIn() { return service_->IsAuthenticated(); }
|
|
||||||
|
|
||||||
void LastFMSearchProvider::ShowConfig() { service_->ShowConfig(); }
|
|
@ -1,43 +0,0 @@
|
|||||||
/* This file is part of Clementine.
|
|
||||||
Copyright 2010, David Sansome <me@davidsansome.com>
|
|
||||||
|
|
||||||
Clementine is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Clementine is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LASTFMSEARCHPROVIDER_H
|
|
||||||
#define LASTFMSEARCHPROVIDER_H
|
|
||||||
|
|
||||||
#include "simplesearchprovider.h"
|
|
||||||
|
|
||||||
class LastFMService;
|
|
||||||
|
|
||||||
class LastFMSearchProvider : public SimpleSearchProvider {
|
|
||||||
public:
|
|
||||||
LastFMSearchProvider(LastFMService* service, Application* app,
|
|
||||||
QObject* parent);
|
|
||||||
|
|
||||||
void LoadArtAsync(int id, const Result& result);
|
|
||||||
|
|
||||||
bool IsLoggedIn();
|
|
||||||
void ShowConfig();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void RecreateItems();
|
|
||||||
|
|
||||||
private:
|
|
||||||
LastFMService* service_;
|
|
||||||
QImage icon_;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // LASTFMSEARCHPROVIDER_H
|
|
@ -38,9 +38,6 @@
|
|||||||
#include "podcasts/podcastservice.h"
|
#include "podcasts/podcastservice.h"
|
||||||
#include "smartplaylists/generatormimedata.h"
|
#include "smartplaylists/generatormimedata.h"
|
||||||
|
|
||||||
#ifdef HAVE_LIBLASTFM
|
|
||||||
#include "lastfmservice.h"
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_GOOGLE_DRIVE
|
#ifdef HAVE_GOOGLE_DRIVE
|
||||||
#include "googledriveservice.h"
|
#include "googledriveservice.h"
|
||||||
#endif
|
#endif
|
||||||
@ -57,7 +54,7 @@
|
|||||||
#include "boxservice.h"
|
#include "boxservice.h"
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_VK
|
#ifdef HAVE_VK
|
||||||
#include "vkservice.h"
|
#include "vkservice.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using smart_playlists::Generator;
|
using smart_playlists::Generator;
|
||||||
@ -80,9 +77,6 @@ InternetModel::InternetModel(Application* app, QObject* parent)
|
|||||||
AddService(new DigitallyImportedService(app, this));
|
AddService(new DigitallyImportedService(app, this));
|
||||||
AddService(new IcecastService(app, this));
|
AddService(new IcecastService(app, this));
|
||||||
AddService(new JamendoService(app, this));
|
AddService(new JamendoService(app, this));
|
||||||
#ifdef HAVE_LIBLASTFM
|
|
||||||
AddService(new LastFMService(app, this));
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_GOOGLE_DRIVE
|
#ifdef HAVE_GOOGLE_DRIVE
|
||||||
AddService(new GoogleDriveService(app, this));
|
AddService(new GoogleDriveService(app, this));
|
||||||
#endif
|
#endif
|
||||||
@ -172,13 +166,13 @@ InternetService* InternetModel::ServiceByName(const QString& name) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
InternetService* InternetModel::ServiceForItem(const QStandardItem* item)
|
InternetService* InternetModel::ServiceForItem(
|
||||||
const {
|
const QStandardItem* item) const {
|
||||||
return ServiceForIndex(indexFromItem(item));
|
return ServiceForIndex(indexFromItem(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
InternetService* InternetModel::ServiceForIndex(const QModelIndex& index)
|
InternetService* InternetModel::ServiceForIndex(
|
||||||
const {
|
const QModelIndex& index) const {
|
||||||
QModelIndex current_index = index;
|
QModelIndex current_index = index;
|
||||||
while (current_index.isValid()) {
|
while (current_index.isValid()) {
|
||||||
InternetService* service =
|
InternetService* service =
|
||||||
|
@ -43,8 +43,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "lastfmcompat.h"
|
#include "lastfmcompat.h"
|
||||||
#include "lastfmstationdialog.h"
|
|
||||||
#include "lastfmurlhandler.h"
|
|
||||||
#include "internetmodel.h"
|
#include "internetmodel.h"
|
||||||
#include "internetplaylistitem.h"
|
#include "internetplaylistitem.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
@ -55,8 +53,6 @@
|
|||||||
#include "core/taskmanager.h"
|
#include "core/taskmanager.h"
|
||||||
#include "covers/coverproviders.h"
|
#include "covers/coverproviders.h"
|
||||||
#include "covers/lastfmcoverprovider.h"
|
#include "covers/lastfmcoverprovider.h"
|
||||||
#include "globalsearch/globalsearch.h"
|
|
||||||
#include "globalsearch/lastfmsearchprovider.h"
|
|
||||||
#include "ui/iconloader.h"
|
#include "ui/iconloader.h"
|
||||||
#include "ui/settingsdialog.h"
|
#include "ui/settingsdialog.h"
|
||||||
|
|
||||||
@ -73,72 +69,20 @@ const char* LastFMService::kAudioscrobblerClientId = "tng";
|
|||||||
const char* LastFMService::kApiKey = "75d20fb472be99275392aefa2760ea09";
|
const char* LastFMService::kApiKey = "75d20fb472be99275392aefa2760ea09";
|
||||||
const char* LastFMService::kSecret = "d3072b60ae626be12be69448f5c46e70";
|
const char* LastFMService::kSecret = "d3072b60ae626be12be69448f5c46e70";
|
||||||
|
|
||||||
const char* LastFMService::kUrlArtist = "lastfm://artist/%1/similarartists";
|
LastFMService::LastFMService(Application* app, QObject* parent)
|
||||||
const char* LastFMService::kUrlTag = "lastfm://globaltags/%1";
|
: Scrobbler(parent),
|
||||||
const char* LastFMService::kUrlCustom = "lastfm://rql/%1";
|
|
||||||
|
|
||||||
const char* LastFMService::kTitleArtist =
|
|
||||||
QT_TR_NOOP("Last.fm Similar Artists to %1");
|
|
||||||
const char* LastFMService::kTitleTag = QT_TR_NOOP("Last.fm Tag Radio: %1");
|
|
||||||
const char* LastFMService::kTitleCustom =
|
|
||||||
QT_TR_NOOP("Last.fm Custom Radio: %1");
|
|
||||||
|
|
||||||
const int LastFMService::kFriendsCacheDurationSecs = 60 * 60 * 24; // 1 day
|
|
||||||
|
|
||||||
LastFMService::LastFMService(Application* app, InternetModel* parent)
|
|
||||||
: InternetService(kServiceName, app, parent, parent),
|
|
||||||
url_handler_(new LastFMUrlHandler(this, this)),
|
|
||||||
scrobbler_(nullptr),
|
scrobbler_(nullptr),
|
||||||
already_scrobbled_(false),
|
already_scrobbled_(false),
|
||||||
station_dialog_(new LastFMStationDialog),
|
|
||||||
context_menu_(new QMenu),
|
|
||||||
initial_tune_(false),
|
|
||||||
tune_task_id_(0),
|
|
||||||
scrobbling_enabled_(false),
|
scrobbling_enabled_(false),
|
||||||
root_item_(nullptr),
|
connection_problems_(false),
|
||||||
artist_list_(nullptr),
|
app_(app) {
|
||||||
tag_list_(nullptr),
|
|
||||||
custom_list_(nullptr),
|
|
||||||
friends_list_(nullptr),
|
|
||||||
neighbours_list_(nullptr),
|
|
||||||
friend_names_(kSettingsGroup, "friend_names", kFriendsCacheDurationSecs),
|
|
||||||
connection_problems_(false) {
|
|
||||||
ReloadSettings();
|
ReloadSettings();
|
||||||
|
|
||||||
// we emit the signal the first time to be sure the buttons are in the right
|
// we emit the signal the first time to be sure the buttons are in the right
|
||||||
// state
|
// state
|
||||||
emit ScrobblingEnabledChanged(scrobbling_enabled_);
|
emit ScrobblingEnabledChanged(scrobbling_enabled_);
|
||||||
|
|
||||||
context_menu_->addActions(GetPlaylistActions());
|
|
||||||
remove_action_ = context_menu_->addAction(IconLoader::Load("list-remove"),
|
|
||||||
tr("Remove"), this, SLOT(Remove()));
|
|
||||||
context_menu_->addSeparator();
|
|
||||||
add_artist_action_ = context_menu_->addAction(
|
|
||||||
QIcon(":last.fm/icon_radio.png"), tr("Play artist radio..."), this,
|
|
||||||
SLOT(AddArtistRadio()));
|
|
||||||
add_tag_action_ = context_menu_->addAction(QIcon(":last.fm/icon_tag.png"),
|
|
||||||
tr("Play tag radio..."), this,
|
|
||||||
SLOT(AddTagRadio()));
|
|
||||||
add_custom_action_ = context_menu_->addAction(
|
|
||||||
QIcon(":last.fm/icon_radio.png"), tr("Play custom radio..."), this,
|
|
||||||
SLOT(AddCustomRadio()));
|
|
||||||
refresh_friends_action_ = context_menu_->addAction(
|
|
||||||
IconLoader::Load("view-refresh"), tr("Refresh friends list"), this,
|
|
||||||
SLOT(ForceRefreshFriends()));
|
|
||||||
context_menu_->addAction(IconLoader::Load("configure"),
|
|
||||||
tr("Configure Last.fm..."), this,
|
|
||||||
SLOT(ShowConfig()));
|
|
||||||
|
|
||||||
remove_action_->setEnabled(false);
|
|
||||||
add_artist_action_->setEnabled(false);
|
|
||||||
add_tag_action_->setEnabled(false);
|
|
||||||
add_custom_action_->setEnabled(false);
|
|
||||||
|
|
||||||
app_->player()->RegisterUrlHandler(url_handler_);
|
|
||||||
app_->cover_providers()->AddProvider(new LastFmCoverProvider(this));
|
app_->cover_providers()->AddProvider(new LastFmCoverProvider(this));
|
||||||
|
|
||||||
app_->global_search()->AddProvider(
|
|
||||||
new LastFMSearchProvider(this, app_, this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LastFMService::~LastFMService() {}
|
LastFMService::~LastFMService() {}
|
||||||
@ -154,7 +98,6 @@ void LastFMService::ReloadSettings() {
|
|||||||
scrobble_button_visible_ =
|
scrobble_button_visible_ =
|
||||||
settings.value("ShowScrobbleButton", true).toBool();
|
settings.value("ShowScrobbleButton", true).toBool();
|
||||||
prefer_albumartist_ = settings.value("PreferAlbumArtist", false).toBool();
|
prefer_albumartist_ = settings.value("PreferAlbumArtist", false).toBool();
|
||||||
friend_names_.Load();
|
|
||||||
|
|
||||||
// avoid emitting signal if it's not changed
|
// avoid emitting signal if it's not changed
|
||||||
if (scrobbling_enabled_old != scrobbling_enabled_)
|
if (scrobbling_enabled_old != scrobbling_enabled_)
|
||||||
@ -178,121 +121,6 @@ bool LastFMService::IsSubscriber() const {
|
|||||||
return settings.value("Subscriber", false).toBool();
|
return settings.value("Subscriber", false).toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
QStandardItem* LastFMService::CreateRootItem() {
|
|
||||||
root_item_ = new QStandardItem(QIcon(":last.fm/as.png"), kServiceName);
|
|
||||||
root_item_->setData(true, InternetModel::Role_CanLazyLoad);
|
|
||||||
return root_item_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMService::LazyPopulate(QStandardItem* parent) {
|
|
||||||
switch (parent->data(InternetModel::Role_Type).toInt()) {
|
|
||||||
case InternetModel::Type_Service:
|
|
||||||
// Normal radio types
|
|
||||||
CreateStationItem(parent, tr("My Recommendations"),
|
|
||||||
":last.fm/recommended_radio.png",
|
|
||||||
QUrl("lastfm://user/USERNAME/recommended"),
|
|
||||||
tr("My Last.fm Recommended Radio"));
|
|
||||||
CreateStationItem(
|
|
||||||
parent, tr("My Radio Station"), ":last.fm/personal_radio.png",
|
|
||||||
QUrl("lastfm://user/USERNAME/library"), tr("My Last.fm Library"));
|
|
||||||
CreateStationItem(parent, tr("My Mix Radio"), ":last.fm/loved_radio.png",
|
|
||||||
QUrl("lastfm://user/USERNAME/mix"),
|
|
||||||
tr("My Last.fm Mix Radio"));
|
|
||||||
CreateStationItem(parent, tr("My Neighborhood"),
|
|
||||||
":last.fm/neighbour_radio.png",
|
|
||||||
QUrl("lastfm://user/USERNAME/neighbours"),
|
|
||||||
tr("My Last.fm Neighborhood"));
|
|
||||||
|
|
||||||
// Types that have children
|
|
||||||
artist_list_ = new QStandardItem(QIcon(":last.fm/icon_radio.png"),
|
|
||||||
tr("Artist radio"));
|
|
||||||
artist_list_->setData(Type_Artists, InternetModel::Role_Type);
|
|
||||||
parent->appendRow(artist_list_);
|
|
||||||
|
|
||||||
tag_list_ =
|
|
||||||
new QStandardItem(QIcon(":last.fm/icon_tag.png"), tr("Tag radio"));
|
|
||||||
tag_list_->setData(Type_Tags, InternetModel::Role_Type);
|
|
||||||
parent->appendRow(tag_list_);
|
|
||||||
|
|
||||||
custom_list_ = new QStandardItem(QIcon(":last.fm/icon_radio.png"),
|
|
||||||
tr("Custom radio"));
|
|
||||||
custom_list_->setData(Type_Custom, InternetModel::Role_Type);
|
|
||||||
parent->appendRow(custom_list_);
|
|
||||||
|
|
||||||
RestoreList("artists", kUrlArtist, tr(kTitleArtist),
|
|
||||||
QIcon(":last.fm/icon_radio.png"), artist_list_);
|
|
||||||
RestoreList("tags", kUrlTag, tr(kTitleTag),
|
|
||||||
QIcon(":last.fm/icon_tag.png"), tag_list_);
|
|
||||||
RestoreList("custom", kUrlCustom, tr(kTitleCustom),
|
|
||||||
QIcon(":last.fm/icon_radio.png"), custom_list_);
|
|
||||||
|
|
||||||
friends_list_ =
|
|
||||||
new QStandardItem(QIcon(":last.fm/my_friends.png"), tr("Friends"));
|
|
||||||
friends_list_->setData(Type_Friends, InternetModel::Role_Type);
|
|
||||||
friends_list_->setData(true, InternetModel::Role_CanLazyLoad);
|
|
||||||
parent->appendRow(friends_list_);
|
|
||||||
|
|
||||||
neighbours_list_ = new QStandardItem(QIcon(":last.fm/my_neighbours.png"),
|
|
||||||
tr("Neighbors"));
|
|
||||||
neighbours_list_->setData(Type_Neighbours, InternetModel::Role_Type);
|
|
||||||
neighbours_list_->setData(true, InternetModel::Role_CanLazyLoad);
|
|
||||||
parent->appendRow(neighbours_list_);
|
|
||||||
|
|
||||||
if (!IsAuthenticated()) ShowConfig();
|
|
||||||
|
|
||||||
add_artist_action_->setEnabled(true);
|
|
||||||
add_tag_action_->setEnabled(true);
|
|
||||||
add_custom_action_->setEnabled(true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Type_Friends:
|
|
||||||
RefreshFriends(false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Type_Neighbours:
|
|
||||||
RefreshNeighbours();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Type_OtherUser:
|
|
||||||
CreateStationItem(parent,
|
|
||||||
tr("Last.fm Radio Station - %1").arg(parent->text()),
|
|
||||||
":last.fm/personal_radio.png",
|
|
||||||
QUrl("lastfm://user/" + parent->text() + "/library"),
|
|
||||||
tr("Last.fm Library - %1").arg(parent->text()));
|
|
||||||
CreateStationItem(parent,
|
|
||||||
tr("Last.fm Mix Radio - %1").arg(parent->text()),
|
|
||||||
":last.fm/loved_radio.png",
|
|
||||||
QUrl("lastfm://user/" + parent->text() + "/mix"),
|
|
||||||
tr("Last.fm Mix Radio - %1").arg(parent->text()));
|
|
||||||
CreateStationItem(parent,
|
|
||||||
tr("Last.fm Neighbor Radio - %1").arg(parent->text()),
|
|
||||||
":last.fm/neighbour_radio.png",
|
|
||||||
QUrl("lastfm://user/" + parent->text() + "/neighbours"),
|
|
||||||
tr("Last.fm Neighbor Radio - %1").arg(parent->text()));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QStandardItem* LastFMService::CreateStationItem(QStandardItem* parent,
|
|
||||||
const QString& name,
|
|
||||||
const QString& icon,
|
|
||||||
const QUrl& url,
|
|
||||||
const QString& title) {
|
|
||||||
Song song;
|
|
||||||
song.set_url(url);
|
|
||||||
song.set_title(title);
|
|
||||||
|
|
||||||
QStandardItem* ret = new QStandardItem(QIcon(icon), name);
|
|
||||||
ret->setData(QVariant::fromValue(song), InternetModel::Role_SongMetadata);
|
|
||||||
ret->setData(InternetModel::PlayBehaviour_SingleItem,
|
|
||||||
InternetModel::Role_PlayBehaviour);
|
|
||||||
parent->appendRow(ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMService::Authenticate(const QString& username,
|
void LastFMService::Authenticate(const QString& username,
|
||||||
const QString& password) {
|
const QString& password) {
|
||||||
QMap<QString, QString> params;
|
QMap<QString, QString> params;
|
||||||
@ -311,8 +139,6 @@ void LastFMService::SignOut() {
|
|||||||
lastfm::ws::Username.clear();
|
lastfm::ws::Username.clear();
|
||||||
lastfm::ws::SessionKey.clear();
|
lastfm::ws::SessionKey.clear();
|
||||||
|
|
||||||
friend_names_.Update(QStringList());
|
|
||||||
|
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
settings.beginGroup(kSettingsGroup);
|
settings.beginGroup(kSettingsGroup);
|
||||||
|
|
||||||
@ -386,51 +212,6 @@ QUrl LastFMService::FixupUrl(const QUrl& url) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
QUrl LastFMService::DeququeNextMediaUrl() {
|
|
||||||
if (playlist_.empty()) {
|
|
||||||
return QUrl();
|
|
||||||
}
|
|
||||||
|
|
||||||
lastfm::MutableTrack track = playlist_.dequeue();
|
|
||||||
track.stamp();
|
|
||||||
|
|
||||||
already_scrobbled_ = false;
|
|
||||||
last_track_ = track;
|
|
||||||
if (playlist_.empty()) {
|
|
||||||
FetchMoreTracks();
|
|
||||||
}
|
|
||||||
|
|
||||||
next_metadata_ = track;
|
|
||||||
StreamMetadataReady();
|
|
||||||
|
|
||||||
return last_track_.url();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMService::StreamMetadataReady() {
|
|
||||||
Song metadata;
|
|
||||||
metadata.InitFromLastFM(next_metadata_);
|
|
||||||
|
|
||||||
if (art_urls_.contains(next_metadata_))
|
|
||||||
metadata.set_art_automatic(art_urls_[next_metadata_]);
|
|
||||||
|
|
||||||
emit StreamMetadataFound(last_url_, metadata);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMService::TunerError(lastfm::ws::Error error) {
|
|
||||||
qLog(Warning) << "Last.fm error" << error;
|
|
||||||
if (!initial_tune_) return;
|
|
||||||
|
|
||||||
app_->task_manager()->SetTaskFinished(tune_task_id_);
|
|
||||||
tune_task_id_ = 0;
|
|
||||||
|
|
||||||
if (error == lastfm::ws::NotEnoughContent) {
|
|
||||||
url_handler_->TunerError();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
emit StreamError(ErrorString(error));
|
|
||||||
}
|
|
||||||
|
|
||||||
QString LastFMService::ErrorString(lastfm::ws::Error error) const {
|
QString LastFMService::ErrorString(lastfm::ws::Error error) const {
|
||||||
switch (error) {
|
switch (error) {
|
||||||
case lastfm::ws::InvalidService:
|
case lastfm::ws::InvalidService:
|
||||||
@ -477,13 +258,6 @@ QString LastFMService::ErrorString(lastfm::ws::Error error) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LastFMService::TunerTrackAvailable() {
|
|
||||||
if (initial_tune_) {
|
|
||||||
url_handler_->TunerTrackAvailable();
|
|
||||||
initial_tune_ = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool LastFMService::InitScrobbler() {
|
bool LastFMService::InitScrobbler() {
|
||||||
if (!IsAuthenticated() || !IsScrobblingEnabled()) return false;
|
if (!IsAuthenticated() || !IsScrobblingEnabled()) return false;
|
||||||
|
|
||||||
@ -610,357 +384,6 @@ void LastFMService::Ban() {
|
|||||||
app_->player()->Next();
|
app_->player()->Next();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LastFMService::ShowContextMenu(const QPoint& global_pos) {
|
|
||||||
switch (model()
|
|
||||||
->current_index()
|
|
||||||
.parent()
|
|
||||||
.data(InternetModel::Role_Type)
|
|
||||||
.toInt()) {
|
|
||||||
case Type_Artists:
|
|
||||||
case Type_Tags:
|
|
||||||
case Type_Custom:
|
|
||||||
remove_action_->setEnabled(true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
remove_action_->setEnabled(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool playable = model()->IsPlayable(model()->current_index());
|
|
||||||
GetAppendToPlaylistAction()->setEnabled(playable);
|
|
||||||
GetReplacePlaylistAction()->setEnabled(playable);
|
|
||||||
GetOpenInNewPlaylistAction()->setEnabled(playable);
|
|
||||||
context_menu_->popup(global_pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList LastFMService::FriendNames() {
|
|
||||||
// Update the list for next time, in the main thread.
|
|
||||||
if (IsFriendsListStale())
|
|
||||||
metaObject()->invokeMethod(this, "RefreshFriends", Qt::QueuedConnection);
|
|
||||||
|
|
||||||
return friend_names_.Data();
|
|
||||||
}
|
|
||||||
|
|
||||||
static QStringList SavedArtistOrTagRadioNames(const QString& name) {
|
|
||||||
QStringList ret;
|
|
||||||
|
|
||||||
QSettings s;
|
|
||||||
s.beginGroup(LastFMService::kSettingsGroup);
|
|
||||||
int count = s.beginReadArray(name);
|
|
||||||
for (int i = 0; i < count; ++i) {
|
|
||||||
s.setArrayIndex(i);
|
|
||||||
ret << s.value("key").toString();
|
|
||||||
}
|
|
||||||
s.endArray();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList LastFMService::SavedArtistRadioNames() const {
|
|
||||||
return SavedArtistOrTagRadioNames("artists");
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList LastFMService::SavedTagRadioNames() const {
|
|
||||||
return SavedArtistOrTagRadioNames("tags");
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMService::RefreshFriends() { RefreshFriends(false); }
|
|
||||||
|
|
||||||
void LastFMService::ForceRefreshFriends() { RefreshFriends(true); }
|
|
||||||
|
|
||||||
void LastFMService::RefreshFriends(bool force) {
|
|
||||||
if (!IsAuthenticated()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!friends_list_) {
|
|
||||||
root_item_->setData(false, InternetModel::Role_CanLazyLoad);
|
|
||||||
LazyPopulate(root_item_);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!force && !IsFriendsListStale()) {
|
|
||||||
PopulateFriendsList();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
lastfm::compat::AuthenticatedUser user;
|
|
||||||
QNetworkReply* reply = user.getFriends();
|
|
||||||
NewClosure(reply, SIGNAL(finished()), this,
|
|
||||||
SLOT(RefreshFriendsFinished(QNetworkReply*)), reply);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMService::RefreshNeighbours() {
|
|
||||||
if (!neighbours_list_ || !IsAuthenticated()) return;
|
|
||||||
|
|
||||||
lastfm::compat::AuthenticatedUser user;
|
|
||||||
QNetworkReply* reply = user.getNeighbours();
|
|
||||||
NewClosure(reply, SIGNAL(finished()), this,
|
|
||||||
SLOT(RefreshNeighboursFinished(QNetworkReply*)), reply);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMService::RefreshFriendsFinished(QNetworkReply* reply) {
|
|
||||||
QList<lastfm::User> friends;
|
|
||||||
if (!lastfm::compat::ParseUserList(reply, &friends)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList names;
|
|
||||||
for (const lastfm::User& f : friends) {
|
|
||||||
names << f.name();
|
|
||||||
}
|
|
||||||
|
|
||||||
friend_names_.Update(names);
|
|
||||||
|
|
||||||
PopulateFriendsList();
|
|
||||||
emit SavedItemsChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMService::PopulateFriendsList() {
|
|
||||||
if (friends_list_->hasChildren())
|
|
||||||
friends_list_->removeRows(0, friends_list_->rowCount());
|
|
||||||
|
|
||||||
for (const QString& name : friend_names_) {
|
|
||||||
Song song;
|
|
||||||
song.set_url(QUrl("lastfm://user/" + name + "/library"));
|
|
||||||
song.set_title(tr("Last.fm Library - %1").arg(name));
|
|
||||||
|
|
||||||
QStandardItem* item =
|
|
||||||
new QStandardItem(QIcon(":last.fm/icon_user.png"), name);
|
|
||||||
item->setData(QVariant::fromValue(song), InternetModel::Role_SongMetadata);
|
|
||||||
item->setData(true, InternetModel::Role_CanLazyLoad);
|
|
||||||
item->setData(Type_OtherUser, InternetModel::Role_Type);
|
|
||||||
item->setData(InternetModel::PlayBehaviour_SingleItem,
|
|
||||||
InternetModel::Role_PlayBehaviour);
|
|
||||||
friends_list_->appendRow(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMService::RefreshNeighboursFinished(QNetworkReply* reply) {
|
|
||||||
QList<lastfm::User> neighbours;
|
|
||||||
if (!lastfm::compat::ParseUserList(reply, &neighbours)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (neighbours_list_->hasChildren())
|
|
||||||
neighbours_list_->removeRows(0, neighbours_list_->rowCount());
|
|
||||||
|
|
||||||
for (const lastfm::User& n : neighbours) {
|
|
||||||
Song song;
|
|
||||||
song.set_url(QUrl("lastfm://user/" + n.name() + "/library"));
|
|
||||||
song.set_title(tr("Last.fm Library - %1").arg(n.name()));
|
|
||||||
|
|
||||||
QStandardItem* item =
|
|
||||||
new QStandardItem(QIcon(":last.fm/user_purple.png"), n.name());
|
|
||||||
item->setData(QVariant::fromValue(song), InternetModel::Role_SongMetadata);
|
|
||||||
item->setData(true, InternetModel::Role_CanLazyLoad);
|
|
||||||
item->setData(Type_OtherUser, InternetModel::Role_Type);
|
|
||||||
item->setData(InternetModel::PlayBehaviour_SingleItem,
|
|
||||||
InternetModel::Role_PlayBehaviour);
|
|
||||||
neighbours_list_->appendRow(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMService::AddArtistRadio() {
|
|
||||||
AddArtistOrTag("artists", LastFMStationDialog::Artist, kUrlArtist,
|
|
||||||
tr(kTitleArtist), ":last.fm/icon_radio.png", artist_list_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMService::AddTagRadio() {
|
|
||||||
AddArtistOrTag("tags", LastFMStationDialog::Tag, kUrlTag, tr(kTitleTag),
|
|
||||||
":last.fm/icon_tag.png", tag_list_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMService::AddCustomRadio() {
|
|
||||||
AddArtistOrTag("custom", LastFMStationDialog::Custom, kUrlCustom,
|
|
||||||
tr(kTitleCustom), ":last.fm/icon_radio.png", custom_list_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMService::AddArtistOrTag(const QString& name,
|
|
||||||
LastFMStationDialog::Type dialog_type,
|
|
||||||
const QString& url_pattern,
|
|
||||||
const QString& title_pattern,
|
|
||||||
const QString& icon, QStandardItem* list) {
|
|
||||||
station_dialog_->SetType(dialog_type);
|
|
||||||
if (station_dialog_->exec() == QDialog::Rejected) return;
|
|
||||||
|
|
||||||
if (station_dialog_->content().isEmpty()) return;
|
|
||||||
|
|
||||||
QString content = station_dialog_->content();
|
|
||||||
QString url;
|
|
||||||
if (name == "custom" && content.startsWith("lastfm://")) {
|
|
||||||
url = content;
|
|
||||||
} else if (name == "custom") {
|
|
||||||
url = url_pattern.arg(QString(content.toUtf8().toBase64()));
|
|
||||||
} else {
|
|
||||||
url = url_pattern.arg(content);
|
|
||||||
}
|
|
||||||
|
|
||||||
Song song;
|
|
||||||
song.set_url(QUrl((url)));
|
|
||||||
song.set_title(title_pattern.arg(content));
|
|
||||||
|
|
||||||
QStandardItem* item = new QStandardItem(QIcon(icon), content);
|
|
||||||
item->setData(QVariant::fromValue(song), InternetModel::Role_SongMetadata);
|
|
||||||
item->setData(InternetModel::PlayBehaviour_SingleItem,
|
|
||||||
InternetModel::Role_PlayBehaviour);
|
|
||||||
list->appendRow(item);
|
|
||||||
emit AddItemToPlaylist(item->index(), AddMode_Append);
|
|
||||||
|
|
||||||
SaveList(name, list);
|
|
||||||
|
|
||||||
emit SavedItemsChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMService::SaveList(const QString& name, QStandardItem* list) const {
|
|
||||||
QSettings settings;
|
|
||||||
settings.beginGroup(kSettingsGroup);
|
|
||||||
|
|
||||||
settings.beginWriteArray(name, list->rowCount());
|
|
||||||
for (int i = 0; i < list->rowCount(); ++i) {
|
|
||||||
settings.setArrayIndex(i);
|
|
||||||
settings.setValue("key", list->child(i)->text());
|
|
||||||
}
|
|
||||||
settings.endArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMService::RestoreList(const QString& name, const QString& url_pattern,
|
|
||||||
const QString& title_pattern, const QIcon& icon,
|
|
||||||
QStandardItem* parent) {
|
|
||||||
if (parent->hasChildren()) parent->removeRows(0, parent->rowCount());
|
|
||||||
|
|
||||||
const QStringList keys = SavedArtistOrTagRadioNames(name);
|
|
||||||
|
|
||||||
for (const QString& key : keys) {
|
|
||||||
QString url;
|
|
||||||
if (name == "custom" && key.startsWith("lastfm://")) {
|
|
||||||
url = key;
|
|
||||||
} else if (name == "custom") {
|
|
||||||
url = url_pattern.arg(QString(key.toUtf8().toBase64()));
|
|
||||||
} else {
|
|
||||||
url = url_pattern.arg(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
Song song;
|
|
||||||
song.set_url(QUrl(url));
|
|
||||||
song.set_title(title_pattern.arg(key));
|
|
||||||
|
|
||||||
QStandardItem* item = new QStandardItem(icon, key);
|
|
||||||
item->setData(QVariant::fromValue(song), InternetModel::Role_SongMetadata);
|
|
||||||
item->setData(InternetModel::PlayBehaviour_SingleItem,
|
|
||||||
InternetModel::Role_PlayBehaviour);
|
|
||||||
parent->appendRow(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMService::Remove() {
|
|
||||||
QStandardItem* context_item =
|
|
||||||
model()->itemFromIndex(model()->current_index());
|
|
||||||
int type = context_item->parent()->data(InternetModel::Role_Type).toInt();
|
|
||||||
|
|
||||||
context_item->parent()->removeRow(context_item->row());
|
|
||||||
|
|
||||||
if (type == Type_Artists)
|
|
||||||
SaveList("artists", artist_list_);
|
|
||||||
else if (type == Type_Tags)
|
|
||||||
SaveList("tags", tag_list_);
|
|
||||||
else if (type == Type_Custom)
|
|
||||||
SaveList("custom", custom_list_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMService::FetchMoreTracks() {
|
|
||||||
QMap<QString, QString> params;
|
|
||||||
params["method"] = "radio.getPlaylist";
|
|
||||||
params["rtp"] = "1";
|
|
||||||
QNetworkReply* reply = lastfm::ws::post(params);
|
|
||||||
NewClosure(reply, SIGNAL(finished()), this,
|
|
||||||
SLOT(FetchMoreTracksFinished(QNetworkReply*)), reply);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMService::FetchMoreTracksFinished(QNetworkReply* reply) {
|
|
||||||
reply->deleteLater();
|
|
||||||
app_->task_manager()->SetTaskFinished(tune_task_id_);
|
|
||||||
tune_task_id_ = 0;
|
|
||||||
|
|
||||||
lastfm::XmlQuery query(lastfm::compat::EmptyXmlQuery());
|
|
||||||
if (lastfm::compat::ParseQuery(reply->readAll(), &query)) {
|
|
||||||
const XmlQuery& playlist = query["playlist"];
|
|
||||||
for (const XmlQuery& q : playlist["trackList"].children("track")) {
|
|
||||||
lastfm::MutableTrack t;
|
|
||||||
t.setUrl(QUrl(q["location"].text()));
|
|
||||||
t.setExtra("trackauth", q["extension"]["trackauth"].text());
|
|
||||||
t.setTitle(q["title"].text());
|
|
||||||
t.setArtist(q["creator"].text());
|
|
||||||
t.setAlbum(q["album"].text());
|
|
||||||
t.setDuration(q["duration"].text().toInt() / 1000);
|
|
||||||
t.setSource(lastfm::Track::LastFmRadio);
|
|
||||||
|
|
||||||
art_urls_[t] = q["image"].text();
|
|
||||||
playlist_ << t;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
emit StreamError(tr("Couldn't load the last.fm radio station"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TunerTrackAvailable();
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMService::Tune(const QUrl& url) {
|
|
||||||
if (!tune_task_id_)
|
|
||||||
tune_task_id_ =
|
|
||||||
app_->task_manager()->StartTask(tr("Loading Last.fm radio"));
|
|
||||||
|
|
||||||
last_url_ = url;
|
|
||||||
initial_tune_ = true;
|
|
||||||
const lastfm::RadioStation station(FixupUrl(url).toString());
|
|
||||||
|
|
||||||
playlist_.clear();
|
|
||||||
|
|
||||||
// Remove all the old album art URLs
|
|
||||||
art_urls_.clear();
|
|
||||||
|
|
||||||
QMap<QString, QString> params;
|
|
||||||
params["method"] = "radio.tune";
|
|
||||||
params["station"] = station.url();
|
|
||||||
QNetworkReply* reply = lastfm::ws::post(params);
|
|
||||||
NewClosure(reply, SIGNAL(finished()), this,
|
|
||||||
SLOT(TuneFinished(QNetworkReply*)), reply);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMService::TuneFinished(QNetworkReply* reply) {
|
|
||||||
reply->deleteLater();
|
|
||||||
FetchMoreTracks();
|
|
||||||
}
|
|
||||||
|
|
||||||
PlaylistItem::Options LastFMService::playlistitem_options() const {
|
|
||||||
return PlaylistItem::LastFMControls | PlaylistItem::PauseDisabled |
|
|
||||||
PlaylistItem::SeekDisabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
PlaylistItemPtr LastFMService::PlaylistItemForUrl(const QUrl& url) {
|
|
||||||
// This is a bit of a hack, it's only used by the artist/song info tag
|
|
||||||
// widgets for tag radio and similar artists radio.
|
|
||||||
|
|
||||||
if (url.scheme() != "lastfm") return PlaylistItemPtr();
|
|
||||||
|
|
||||||
QStringList sections(url.path().split("/", QString::SkipEmptyParts));
|
|
||||||
|
|
||||||
Song song;
|
|
||||||
song.set_url(url);
|
|
||||||
|
|
||||||
if (sections.count() == 2 && url.host() == "artist" &&
|
|
||||||
sections[1] == "similarartists") {
|
|
||||||
song.set_title(tr(kTitleArtist).arg(sections[0]));
|
|
||||||
} else if (sections.count() == 1 && url.host() == "globaltags") {
|
|
||||||
song.set_title(tr(kTitleTag).arg(sections[0]));
|
|
||||||
} else {
|
|
||||||
return PlaylistItemPtr();
|
|
||||||
}
|
|
||||||
|
|
||||||
return PlaylistItemPtr(new InternetPlaylistItem(this, song));
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMService::ToggleScrobbling() {
|
void LastFMService::ToggleScrobbling() {
|
||||||
// toggle status
|
// toggle status
|
||||||
scrobbling_enabled_ = !scrobbling_enabled_;
|
scrobbling_enabled_ = !scrobbling_enabled_;
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace lastfm {
|
namespace lastfm {
|
||||||
class RadioStation;
|
|
||||||
class Track;
|
class Track;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,29 +29,19 @@ uint qHash(const lastfm::Track& track);
|
|||||||
|
|
||||||
#include "lastfmcompat.h"
|
#include "lastfmcompat.h"
|
||||||
|
|
||||||
#include "internetmodel.h"
|
#include "internet/scrobbler.h"
|
||||||
#include "internetservice.h"
|
|
||||||
#include "lastfmstationdialog.h"
|
|
||||||
#include "core/cachedlist.h"
|
|
||||||
#include "core/song.h"
|
|
||||||
#include "playlist/playlistitem.h"
|
|
||||||
|
|
||||||
#include <QDateTime>
|
|
||||||
#include <QMap>
|
|
||||||
#include <QMenu>
|
|
||||||
#include <QQueue>
|
|
||||||
|
|
||||||
|
class Application;
|
||||||
class LastFMUrlHandler;
|
class LastFMUrlHandler;
|
||||||
|
|
||||||
class QAction;
|
class QAction;
|
||||||
class QNetworkAccessManager;
|
class QNetworkAccessManager;
|
||||||
|
class Song;
|
||||||
|
|
||||||
class LastFMService : public InternetService {
|
class LastFMService : public Scrobbler {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
friend class LastFMUrlHandler;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LastFMService(Application* app, InternetModel* parent);
|
LastFMService(Application* app, QObject* parent = nullptr);
|
||||||
~LastFMService();
|
~LastFMService();
|
||||||
|
|
||||||
static const char* kServiceName;
|
static const char* kServiceName;
|
||||||
@ -61,34 +50,6 @@ class LastFMService : public InternetService {
|
|||||||
static const char* kApiKey;
|
static const char* kApiKey;
|
||||||
static const char* kSecret;
|
static const char* kSecret;
|
||||||
|
|
||||||
static const char* kUrlArtist;
|
|
||||||
static const char* kUrlTag;
|
|
||||||
static const char* kUrlCustom;
|
|
||||||
|
|
||||||
static const char* kTitleArtist;
|
|
||||||
static const char* kTitleTag;
|
|
||||||
static const char* kTitleCustom;
|
|
||||||
|
|
||||||
static const int kFriendsCacheDurationSecs;
|
|
||||||
|
|
||||||
enum ItemType {
|
|
||||||
Type_Root = InternetModel::TypeCount,
|
|
||||||
Type_Artists,
|
|
||||||
Type_Tags,
|
|
||||||
Type_Custom,
|
|
||||||
Type_Friends,
|
|
||||||
Type_Neighbours,
|
|
||||||
Type_OtherUser,
|
|
||||||
};
|
|
||||||
|
|
||||||
// InternetService
|
|
||||||
QStandardItem* CreateRootItem();
|
|
||||||
void LazyPopulate(QStandardItem* parent);
|
|
||||||
|
|
||||||
void ShowContextMenu(const QPoint& global_pos);
|
|
||||||
|
|
||||||
PlaylistItem::Options playlistitem_options() const;
|
|
||||||
|
|
||||||
void ReloadSettings();
|
void ReloadSettings();
|
||||||
|
|
||||||
virtual QString Icon() { return ":last.fm/lastfm.png"; }
|
virtual QString Icon() { return ":last.fm/lastfm.png"; }
|
||||||
@ -106,18 +67,6 @@ class LastFMService : public InternetService {
|
|||||||
void SignOut();
|
void SignOut();
|
||||||
void UpdateSubscriberStatus();
|
void UpdateSubscriberStatus();
|
||||||
|
|
||||||
void FetchMoreTracks();
|
|
||||||
QUrl DeququeNextMediaUrl();
|
|
||||||
|
|
||||||
PlaylistItemPtr PlaylistItemForUrl(const QUrl& url);
|
|
||||||
|
|
||||||
bool IsFriendsListStale() const { return friend_names_.IsStale(); }
|
|
||||||
|
|
||||||
// Thread safe
|
|
||||||
QStringList FriendNames();
|
|
||||||
QStringList SavedArtistRadioNames() const;
|
|
||||||
QStringList SavedTagRadioNames() const;
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void NowPlaying(const Song& song);
|
void NowPlaying(const Song& song);
|
||||||
void Scrobble();
|
void Scrobble();
|
||||||
@ -142,91 +91,35 @@ signals:
|
|||||||
private slots:
|
private slots:
|
||||||
void AuthenticateReplyFinished(QNetworkReply* reply);
|
void AuthenticateReplyFinished(QNetworkReply* reply);
|
||||||
void UpdateSubscriberStatusFinished(QNetworkReply* reply);
|
void UpdateSubscriberStatusFinished(QNetworkReply* reply);
|
||||||
void RefreshFriendsFinished(QNetworkReply* reply);
|
|
||||||
void RefreshNeighboursFinished(QNetworkReply* reply);
|
|
||||||
|
|
||||||
void TunerTrackAvailable();
|
|
||||||
void TunerError(lastfm::ws::Error error);
|
|
||||||
void ScrobblerStatus(int value);
|
void ScrobblerStatus(int value);
|
||||||
|
|
||||||
void AddArtistRadio();
|
|
||||||
void AddTagRadio();
|
|
||||||
void AddCustomRadio();
|
|
||||||
void ForceRefreshFriends();
|
|
||||||
void RefreshFriends();
|
|
||||||
void Remove();
|
|
||||||
|
|
||||||
// Radio tuner.
|
|
||||||
void FetchMoreTracksFinished(QNetworkReply* reply);
|
|
||||||
void TuneFinished(QNetworkReply* reply);
|
|
||||||
|
|
||||||
void StreamMetadataReady();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QStandardItem* CreateStationItem(QStandardItem* parent, const QString& name,
|
|
||||||
const QString& icon, const QUrl& url,
|
|
||||||
const QString& title);
|
|
||||||
QString ErrorString(lastfm::ws::Error error) const;
|
QString ErrorString(lastfm::ws::Error error) const;
|
||||||
bool InitScrobbler();
|
bool InitScrobbler();
|
||||||
lastfm::Track TrackFromSong(const Song& song) const;
|
lastfm::Track TrackFromSong(const Song& song) const;
|
||||||
void RefreshFriends(bool force);
|
|
||||||
void RefreshNeighbours();
|
|
||||||
void AddArtistOrTag(const QString& name,
|
|
||||||
LastFMStationDialog::Type dialog_type,
|
|
||||||
const QString& url_pattern, const QString& title_pattern,
|
|
||||||
const QString& icon, QStandardItem* list);
|
|
||||||
void SaveList(const QString& name, QStandardItem* list) const;
|
|
||||||
void RestoreList(const QString& name, const QString& url_pattern,
|
|
||||||
const QString& title_pattern, const QIcon& icon,
|
|
||||||
QStandardItem* parent);
|
|
||||||
|
|
||||||
static QUrl FixupUrl(const QUrl& url);
|
static QUrl FixupUrl(const QUrl& url);
|
||||||
void Tune(const QUrl& station);
|
|
||||||
|
|
||||||
void PopulateFriendsList();
|
|
||||||
|
|
||||||
void AddSelectedToPlaylist(bool clear_first);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LastFMUrlHandler* url_handler_;
|
|
||||||
|
|
||||||
lastfm::Audioscrobbler* scrobbler_;
|
lastfm::Audioscrobbler* scrobbler_;
|
||||||
lastfm::Track last_track_;
|
lastfm::Track last_track_;
|
||||||
lastfm::Track next_metadata_;
|
lastfm::Track next_metadata_;
|
||||||
QQueue<lastfm::Track> playlist_;
|
|
||||||
bool already_scrobbled_;
|
bool already_scrobbled_;
|
||||||
|
|
||||||
std::unique_ptr<LastFMStationDialog> station_dialog_;
|
|
||||||
|
|
||||||
std::unique_ptr<QMenu> context_menu_;
|
|
||||||
QAction* remove_action_;
|
|
||||||
QAction* add_artist_action_;
|
|
||||||
QAction* add_tag_action_;
|
|
||||||
QAction* add_custom_action_;
|
|
||||||
QAction* refresh_friends_action_;
|
|
||||||
|
|
||||||
QUrl last_url_;
|
QUrl last_url_;
|
||||||
bool initial_tune_;
|
|
||||||
int tune_task_id_;
|
|
||||||
|
|
||||||
bool scrobbling_enabled_;
|
bool scrobbling_enabled_;
|
||||||
bool buttons_visible_;
|
bool buttons_visible_;
|
||||||
bool scrobble_button_visible_;
|
bool scrobble_button_visible_;
|
||||||
bool prefer_albumartist_;
|
bool prefer_albumartist_;
|
||||||
|
|
||||||
QStandardItem* root_item_;
|
|
||||||
QStandardItem* artist_list_;
|
|
||||||
QStandardItem* tag_list_;
|
|
||||||
QStandardItem* custom_list_;
|
|
||||||
QStandardItem* friends_list_;
|
|
||||||
QStandardItem* neighbours_list_;
|
|
||||||
|
|
||||||
QHash<lastfm::Track, QString> art_urls_;
|
QHash<lastfm::Track, QString> art_urls_;
|
||||||
|
|
||||||
CachedList<QString> friend_names_;
|
|
||||||
|
|
||||||
// Useful to inform the user that we can't scrobble right now
|
// Useful to inform the user that we can't scrobble right now
|
||||||
bool connection_problems_;
|
bool connection_problems_;
|
||||||
|
|
||||||
|
Application* app_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LASTFMSERVICE_H
|
#endif // LASTFMSERVICE_H
|
||||||
|
@ -16,21 +16,21 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "lastfmsettingspage.h"
|
#include "lastfmsettingspage.h"
|
||||||
#include "lastfmservice.h"
|
|
||||||
#include "internetmodel.h"
|
|
||||||
#include "ui_lastfmsettingspage.h"
|
#include "ui_lastfmsettingspage.h"
|
||||||
#include "ui/iconloader.h"
|
|
||||||
|
|
||||||
#include <lastfm/ws.h>
|
#include <lastfm/ws.h>
|
||||||
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QMovie>
|
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
|
||||||
|
#include "lastfmservice.h"
|
||||||
|
#include "internetmodel.h"
|
||||||
|
#include "core/application.h"
|
||||||
|
#include "ui/iconloader.h"
|
||||||
|
|
||||||
LastFMSettingsPage::LastFMSettingsPage(SettingsDialog* dialog)
|
LastFMSettingsPage::LastFMSettingsPage(SettingsDialog* dialog)
|
||||||
: SettingsPage(dialog),
|
: SettingsPage(dialog),
|
||||||
service_(
|
service_(static_cast<LastFMService*>(dialog->app()->scrobbler())),
|
||||||
static_cast<LastFMService*>(InternetModel::ServiceByName("Last.fm"))),
|
|
||||||
ui_(new Ui_LastFMSettingsPage),
|
ui_(new Ui_LastFMSettingsPage),
|
||||||
waiting_for_auth_(false) {
|
waiting_for_auth_(false) {
|
||||||
ui_->setupUi(this);
|
ui_->setupUi(this);
|
||||||
@ -40,8 +40,6 @@ LastFMSettingsPage::LastFMSettingsPage(SettingsDialog* dialog)
|
|||||||
|
|
||||||
connect(service_, SIGNAL(AuthenticationComplete(bool, QString)),
|
connect(service_, SIGNAL(AuthenticationComplete(bool, QString)),
|
||||||
SLOT(AuthenticationComplete(bool, QString)));
|
SLOT(AuthenticationComplete(bool, QString)));
|
||||||
connect(service_, SIGNAL(UpdatedSubscriberStatus(bool)),
|
|
||||||
SLOT(UpdatedSubscriberStatus(bool)));
|
|
||||||
connect(ui_->login_state, SIGNAL(LogoutClicked()), SLOT(Logout()));
|
connect(ui_->login_state, SIGNAL(LogoutClicked()), SLOT(Logout()));
|
||||||
connect(ui_->login_state, SIGNAL(LoginClicked()), SLOT(Login()));
|
connect(ui_->login_state, SIGNAL(LoginClicked()), SLOT(Login()));
|
||||||
connect(ui_->login, SIGNAL(clicked()), SLOT(Login()));
|
connect(ui_->login, SIGNAL(clicked()), SLOT(Login()));
|
||||||
@ -83,7 +81,6 @@ void LastFMSettingsPage::AuthenticationComplete(bool success,
|
|||||||
}
|
}
|
||||||
|
|
||||||
RefreshControls(success);
|
RefreshControls(success);
|
||||||
service_->UpdateSubscriberStatus();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LastFMSettingsPage::Load() {
|
void LastFMSettingsPage::Load() {
|
||||||
@ -92,31 +89,9 @@ void LastFMSettingsPage::Load() {
|
|||||||
ui_->scrobble_button->setChecked(service_->IsScrobbleButtonVisible());
|
ui_->scrobble_button->setChecked(service_->IsScrobbleButtonVisible());
|
||||||
ui_->prefer_albumartist->setChecked(service_->PreferAlbumArtist());
|
ui_->prefer_albumartist->setChecked(service_->PreferAlbumArtist());
|
||||||
|
|
||||||
if (service_->IsAuthenticated()) {
|
|
||||||
service_->UpdateSubscriberStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
RefreshControls(service_->IsAuthenticated());
|
RefreshControls(service_->IsAuthenticated());
|
||||||
}
|
}
|
||||||
|
|
||||||
void LastFMSettingsPage::UpdatedSubscriberStatus(bool is_subscriber) {
|
|
||||||
ui_->login_state->SetAccountTypeVisible(!is_subscriber);
|
|
||||||
|
|
||||||
if (!is_subscriber) {
|
|
||||||
if (service_->HasConnectionProblems()) {
|
|
||||||
ui_->login_state->SetAccountTypeText(
|
|
||||||
tr("Clementine couldn't fetch your subscription status since there "
|
|
||||||
"are problems "
|
|
||||||
"with your connection. Played tracks will be cached and sent "
|
|
||||||
"later to Last.fm."));
|
|
||||||
} else {
|
|
||||||
ui_->login_state->SetAccountTypeText(
|
|
||||||
tr("You will not be able to play Last.fm radio stations "
|
|
||||||
"as you are not a Last.fm subscriber."));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMSettingsPage::Save() {
|
void LastFMSettingsPage::Save() {
|
||||||
QSettings s;
|
QSettings s;
|
||||||
s.beginGroup(LastFMService::kSettingsGroup);
|
s.beginGroup(LastFMService::kSettingsGroup);
|
||||||
@ -141,12 +116,4 @@ void LastFMSettingsPage::RefreshControls(bool authenticated) {
|
|||||||
ui_->login_state->SetLoggedIn(
|
ui_->login_state->SetLoggedIn(
|
||||||
authenticated ? LoginStateWidget::LoggedIn : LoginStateWidget::LoggedOut,
|
authenticated ? LoginStateWidget::LoggedIn : LoginStateWidget::LoggedOut,
|
||||||
lastfm::ws::Username);
|
lastfm::ws::Username);
|
||||||
ui_->login_state->SetAccountTypeVisible(!authenticated);
|
|
||||||
|
|
||||||
if (!authenticated) {
|
|
||||||
ui_->login_state->SetAccountTypeText(
|
|
||||||
tr("You can scrobble tracks for free, but only "
|
|
||||||
"<span style=\" font-weight:600;\">paid subscribers</span> "
|
|
||||||
"can stream Last.fm radio from Clementine."));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -37,12 +37,10 @@ class LastFMSettingsPage : public SettingsPage {
|
|||||||
void Login();
|
void Login();
|
||||||
void AuthenticationComplete(bool success, const QString& error_message);
|
void AuthenticationComplete(bool success, const QString& error_message);
|
||||||
void Logout();
|
void Logout();
|
||||||
void UpdatedSubscriberStatus(bool is_subscriber);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LastFMService* service_;
|
LastFMService* service_;
|
||||||
Ui_LastFMSettingsPage* ui_;
|
Ui_LastFMSettingsPage* ui_;
|
||||||
QMovie* loading_icon_;
|
|
||||||
|
|
||||||
bool waiting_for_auth_;
|
bool waiting_for_auth_;
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="love_ban_">
|
<widget class="QCheckBox" name="love_ban_">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Show the "love" and "ban" buttons</string>
|
<string>Show the "love" button</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="checked">
|
<property name="checked">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
/* This file is part of Clementine.
|
|
||||||
Copyright 2010, David Sansome <me@davidsansome.com>
|
|
||||||
|
|
||||||
Clementine is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Clementine is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "lastfmstationdialog.h"
|
|
||||||
#include "ui_lastfmstationdialog.h"
|
|
||||||
|
|
||||||
LastFMStationDialog::LastFMStationDialog(QWidget* parent)
|
|
||||||
: QDialog(parent), ui_(new Ui_LastFMStationDialog) {
|
|
||||||
ui_->setupUi(this);
|
|
||||||
|
|
||||||
resize(sizeHint());
|
|
||||||
}
|
|
||||||
|
|
||||||
LastFMStationDialog::~LastFMStationDialog() { delete ui_; }
|
|
||||||
|
|
||||||
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(); }
|
|
@ -1,41 +0,0 @@
|
|||||||
/* This file is part of Clementine.
|
|
||||||
Copyright 2010, David Sansome <me@davidsansome.com>
|
|
||||||
|
|
||||||
Clementine is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Clementine is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LASTFMSTATIONDIALOG_H
|
|
||||||
#define LASTFMSTATIONDIALOG_H
|
|
||||||
|
|
||||||
#include <QDialog>
|
|
||||||
|
|
||||||
class Ui_LastFMStationDialog;
|
|
||||||
|
|
||||||
class LastFMStationDialog : public QDialog {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
LastFMStationDialog(QWidget* parent = nullptr);
|
|
||||||
~LastFMStationDialog();
|
|
||||||
|
|
||||||
enum Type { Artist, Tag, Custom, };
|
|
||||||
|
|
||||||
void SetType(Type type);
|
|
||||||
QString content() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ui_LastFMStationDialog* ui_;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // LASTFMSTATIONDIALOG_H
|
|
@ -1,119 +0,0 @@
|
|||||||
<?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>126</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Play Artist or Tag</string>
|
|
||||||
</property>
|
|
||||||
<property name="windowIcon">
|
|
||||||
<iconset resource="../../data/data.qrc">
|
|
||||||
<normaloff>:/last.fm/as.png</normaloff>:/last.fm/as.png</iconset>
|
|
||||||
</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>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Custom</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>
|
|
||||||
<include location="../../data/data.qrc"/>
|
|
||||||
</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>
|
|
@ -1,46 +0,0 @@
|
|||||||
/* This file is part of Clementine.
|
|
||||||
Copyright 2010, David Sansome <me@davidsansome.com>
|
|
||||||
|
|
||||||
Clementine is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
Clementine is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "lastfmservice.h"
|
|
||||||
#include "lastfmurlhandler.h"
|
|
||||||
|
|
||||||
LastFMUrlHandler::LastFMUrlHandler(LastFMService* service, QObject* parent)
|
|
||||||
: UrlHandler(parent), service_(service) {}
|
|
||||||
|
|
||||||
UrlHandler::LoadResult LastFMUrlHandler::StartLoading(const QUrl& url) {
|
|
||||||
if (!service_->IsAuthenticated()) return LoadResult();
|
|
||||||
|
|
||||||
service_->Tune(url);
|
|
||||||
return LoadResult(url, LoadResult::WillLoadAsynchronously);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMUrlHandler::TunerTrackAvailable() {
|
|
||||||
emit AsyncLoadComplete(LoadNext(service_->last_url_));
|
|
||||||
}
|
|
||||||
|
|
||||||
void LastFMUrlHandler::TunerError() {
|
|
||||||
emit AsyncLoadComplete(
|
|
||||||
LoadResult(service_->last_url_, LoadResult::NoMoreTracks));
|
|
||||||
}
|
|
||||||
|
|
||||||
UrlHandler::LoadResult LastFMUrlHandler::LoadNext(const QUrl& url) {
|
|
||||||
const QUrl media_url = service_->DeququeNextMediaUrl();
|
|
||||||
if (media_url.isEmpty()) {
|
|
||||||
return LoadResult();
|
|
||||||
}
|
|
||||||
return LoadResult(url, LoadResult::TrackAvailable, media_url);
|
|
||||||
}
|
|
36
src/internet/scrobbler.h
Normal file
36
src/internet/scrobbler.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#ifndef SCROBBLER_H
|
||||||
|
#define SCROBBLER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class Song;
|
||||||
|
|
||||||
|
class Scrobbler : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
Scrobbler(QObject* parent = nullptr) {}
|
||||||
|
|
||||||
|
virtual bool IsAuthenticated() const = 0;
|
||||||
|
virtual bool IsScrobblingEnabled() const = 0;
|
||||||
|
virtual bool AreButtonsVisible() const = 0;
|
||||||
|
virtual bool IsScrobbleButtonVisible() const = 0;
|
||||||
|
virtual bool PreferAlbumArtist() const = 0;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void NowPlaying(const Song& song) = 0;
|
||||||
|
virtual void Scrobble() = 0;
|
||||||
|
virtual void Love() = 0;
|
||||||
|
virtual void ToggleScrobbling() = 0;
|
||||||
|
virtual void ShowConfig() = 0;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void AuthenticationComplete(bool success, const QString& error_message);
|
||||||
|
void ScrobblingEnabledChanged(bool value);
|
||||||
|
void ButtonVisibilityChanged(bool value);
|
||||||
|
void ScrobbleButtonVisibilityChanged(bool value);
|
||||||
|
void ScrobbleSubmitted();
|
||||||
|
void ScrobbleError(int value);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SCROBBLER_H
|
@ -70,10 +70,7 @@ IncomingDataParser::IncomingDataParser(Application* app) : app_(app) {
|
|||||||
SLOT(RateCurrentSong(double)));
|
SLOT(RateCurrentSong(double)));
|
||||||
|
|
||||||
#ifdef HAVE_LIBLASTFM
|
#ifdef HAVE_LIBLASTFM
|
||||||
connect(this, SIGNAL(Love()), InternetModel::Service<LastFMService>(),
|
connect(this, SIGNAL(Love()), app_->scrobbler(), SLOT(Love()));
|
||||||
SLOT(Love()));
|
|
||||||
connect(this, SIGNAL(Ban()), InternetModel::Service<LastFMService>(),
|
|
||||||
SLOT(Ban()));
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,7 +258,6 @@ void IncomingDataParser::RemoveSongs(const pb::remote::Message& msg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void IncomingDataParser::ClientConnect(const pb::remote::Message& msg) {
|
void IncomingDataParser::ClientConnect(const pb::remote::Message& msg) {
|
||||||
|
|
||||||
// Always sned the Clementine infos
|
// Always sned the Clementine infos
|
||||||
emit SendClementineInfo();
|
emit SendClementineInfo();
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ class MacSystemTrayIcon : public SystemTrayIcon {
|
|||||||
|
|
||||||
void SetupMenu(QAction* previous, QAction* play, QAction* stop,
|
void SetupMenu(QAction* previous, QAction* play, QAction* stop,
|
||||||
QAction* stop_after, QAction* next, QAction* mute,
|
QAction* stop_after, QAction* next, QAction* mute,
|
||||||
QAction* love, QAction* ban, QAction* quit);
|
QAction* love, QAction* quit);
|
||||||
|
|
||||||
void SetNowPlaying(const Song& song, const QString& image_path);
|
void SetNowPlaying(const Song& song, const QString& image_path);
|
||||||
void ClearNowPlaying();
|
void ClearNowPlaying();
|
||||||
|
@ -177,7 +177,7 @@ MacSystemTrayIcon::~MacSystemTrayIcon() {}
|
|||||||
void MacSystemTrayIcon::SetupMenu(QAction* previous, QAction* play,
|
void MacSystemTrayIcon::SetupMenu(QAction* previous, QAction* play,
|
||||||
QAction* stop, QAction* stop_after,
|
QAction* stop, QAction* stop_after,
|
||||||
QAction* next, QAction* mute, QAction* love,
|
QAction* next, QAction* mute, QAction* love,
|
||||||
QAction* ban, QAction* quit) {
|
QAction* quit) {
|
||||||
p_.reset(new MacSystemTrayIconPrivate());
|
p_.reset(new MacSystemTrayIconPrivate());
|
||||||
SetupMenuItem(previous);
|
SetupMenuItem(previous);
|
||||||
SetupMenuItem(play);
|
SetupMenuItem(play);
|
||||||
@ -188,7 +188,6 @@ void MacSystemTrayIcon::SetupMenu(QAction* previous, QAction* play,
|
|||||||
SetupMenuItem(mute);
|
SetupMenuItem(mute);
|
||||||
p_->AddSeparator();
|
p_->AddSeparator();
|
||||||
SetupMenuItem(love);
|
SetupMenuItem(love);
|
||||||
SetupMenuItem(ban);
|
|
||||||
Q_UNUSED(quit); // Mac already has a Quit item.
|
Q_UNUSED(quit); // Mac already has a Quit item.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_VK
|
#ifdef HAVE_VK
|
||||||
# include "internet/vkservice.h"
|
#include "internet/vkservice.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef Q_OS_DARWIN
|
#ifdef Q_OS_DARWIN
|
||||||
@ -342,15 +342,13 @@ MainWindow::MainWindow(Application* app, SystemTrayIcon* tray_icon, OSD* osd,
|
|||||||
SLOT(StopAfterCurrent()));
|
SLOT(StopAfterCurrent()));
|
||||||
connect(ui_->action_mute, SIGNAL(triggered()), app_->player(), SLOT(Mute()));
|
connect(ui_->action_mute, SIGNAL(triggered()), app_->player(), SLOT(Mute()));
|
||||||
#ifdef HAVE_LIBLASTFM
|
#ifdef HAVE_LIBLASTFM
|
||||||
connect(ui_->action_ban, SIGNAL(triggered()),
|
|
||||||
InternetModel::Service<LastFMService>(), SLOT(Ban()));
|
|
||||||
connect(ui_->action_love, SIGNAL(triggered()), SLOT(Love()));
|
connect(ui_->action_love, SIGNAL(triggered()), SLOT(Love()));
|
||||||
connect(ui_->action_toggle_scrobbling, SIGNAL(triggered()),
|
connect(ui_->action_toggle_scrobbling, SIGNAL(triggered()), app_->scrobbler(),
|
||||||
InternetModel::Service<LastFMService>(), SLOT(ToggleScrobbling()));
|
SLOT(ToggleScrobbling()));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_VK
|
#ifdef HAVE_VK
|
||||||
connect(ui_->action_love, SIGNAL(triggered()),
|
connect(ui_->action_love, SIGNAL(triggered()),
|
||||||
InternetModel::Service<VkService>(), SLOT(AddToMyMusicCurrent()));
|
InternetModel::Service<VkService>(), SLOT(AddToMyMusicCurrent()));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -424,7 +422,6 @@ MainWindow::MainWindow(Application* app, SystemTrayIcon* tray_icon, OSD* osd,
|
|||||||
ui_->pause_play_button->setDefaultAction(ui_->action_play_pause);
|
ui_->pause_play_button->setDefaultAction(ui_->action_play_pause);
|
||||||
ui_->stop_button->setDefaultAction(ui_->action_stop);
|
ui_->stop_button->setDefaultAction(ui_->action_stop);
|
||||||
ui_->love_button->setDefaultAction(ui_->action_love);
|
ui_->love_button->setDefaultAction(ui_->action_love);
|
||||||
ui_->ban_button->setDefaultAction(ui_->action_ban);
|
|
||||||
ui_->scrobbling_button->setDefaultAction(ui_->action_toggle_scrobbling);
|
ui_->scrobbling_button->setDefaultAction(ui_->action_toggle_scrobbling);
|
||||||
ui_->clear_playlist_button->setDefaultAction(ui_->action_clear_playlist);
|
ui_->clear_playlist_button->setDefaultAction(ui_->action_clear_playlist);
|
||||||
ui_->playlist->SetActions(
|
ui_->playlist->SetActions(
|
||||||
@ -654,14 +651,13 @@ MainWindow::MainWindow(Application* app, SystemTrayIcon* tray_icon, OSD* osd,
|
|||||||
connect(app_->internet_model(), SIGNAL(ScrollToIndex(QModelIndex)),
|
connect(app_->internet_model(), SIGNAL(ScrollToIndex(QModelIndex)),
|
||||||
SLOT(ScrollToInternetIndex(QModelIndex)));
|
SLOT(ScrollToInternetIndex(QModelIndex)));
|
||||||
#ifdef HAVE_LIBLASTFM
|
#ifdef HAVE_LIBLASTFM
|
||||||
LastFMService* lastfm_service = InternetModel::Service<LastFMService>();
|
connect(app_->scrobbler(), SIGNAL(ButtonVisibilityChanged(bool)),
|
||||||
connect(lastfm_service, SIGNAL(ButtonVisibilityChanged(bool)),
|
|
||||||
SLOT(LastFMButtonVisibilityChanged(bool)));
|
SLOT(LastFMButtonVisibilityChanged(bool)));
|
||||||
connect(lastfm_service, SIGNAL(ScrobbleButtonVisibilityChanged(bool)),
|
connect(app_->scrobbler(), SIGNAL(ScrobbleButtonVisibilityChanged(bool)),
|
||||||
SLOT(ScrobbleButtonVisibilityChanged(bool)));
|
SLOT(ScrobbleButtonVisibilityChanged(bool)));
|
||||||
connect(lastfm_service, SIGNAL(ScrobblingEnabledChanged(bool)),
|
connect(app_->scrobbler(), SIGNAL(ScrobblingEnabledChanged(bool)),
|
||||||
SLOT(ScrobblingEnabledChanged(bool)));
|
SLOT(ScrobblingEnabledChanged(bool)));
|
||||||
connect(lastfm_service, SIGNAL(ScrobbledRadioStream()),
|
connect(app_->scrobbler(), SIGNAL(ScrobbledRadioStream()),
|
||||||
SLOT(ScrobbledRadioStream()));
|
SLOT(ScrobbledRadioStream()));
|
||||||
#endif
|
#endif
|
||||||
connect(app_->internet_model()->Service<MagnatuneService>(),
|
connect(app_->internet_model()->Service<MagnatuneService>(),
|
||||||
@ -681,7 +677,7 @@ MainWindow::MainWindow(Application* app, SystemTrayIcon* tray_icon, OSD* osd,
|
|||||||
tray_icon_->SetupMenu(ui_->action_previous_track, ui_->action_play_pause,
|
tray_icon_->SetupMenu(ui_->action_previous_track, ui_->action_play_pause,
|
||||||
ui_->action_stop, ui_->action_stop_after_this_track,
|
ui_->action_stop, ui_->action_stop_after_this_track,
|
||||||
ui_->action_next_track, ui_->action_mute,
|
ui_->action_next_track, ui_->action_mute,
|
||||||
ui_->action_love, ui_->action_ban, ui_->action_quit);
|
ui_->action_love, ui_->action_quit);
|
||||||
connect(tray_icon_, SIGNAL(PlayPause()), app_->player(), SLOT(PlayPause()));
|
connect(tray_icon_, SIGNAL(PlayPause()), app_->player(), SLOT(PlayPause()));
|
||||||
connect(tray_icon_, SIGNAL(SeekForward()), app_->player(),
|
connect(tray_icon_, SIGNAL(SeekForward()), app_->player(),
|
||||||
SLOT(SeekForward()));
|
SLOT(SeekForward()));
|
||||||
@ -698,7 +694,7 @@ MainWindow::MainWindow(Application* app, SystemTrayIcon* tray_icon, OSD* osd,
|
|||||||
<< ui_->action_previous_track << ui_->action_play_pause
|
<< ui_->action_previous_track << ui_->action_play_pause
|
||||||
<< ui_->action_stop << ui_->action_next_track
|
<< ui_->action_stop << ui_->action_next_track
|
||||||
<< nullptr // spacer
|
<< nullptr // spacer
|
||||||
<< ui_->action_love << ui_->action_ban);
|
<< ui_->action_love);
|
||||||
|
|
||||||
#if (defined(Q_OS_DARWIN) && defined(HAVE_SPARKLE)) || defined(Q_OS_WIN32)
|
#if (defined(Q_OS_DARWIN) && defined(HAVE_SPARKLE)) || defined(Q_OS_WIN32)
|
||||||
// Add check for updates item to application menu.
|
// Add check for updates item to application menu.
|
||||||
@ -744,8 +740,7 @@ MainWindow::MainWindow(Application* app, SystemTrayIcon* tray_icon, OSD* osd,
|
|||||||
connect(global_shortcuts_, SIGNAL(TogglePrettyOSD()), app_->player(),
|
connect(global_shortcuts_, SIGNAL(TogglePrettyOSD()), app_->player(),
|
||||||
SLOT(TogglePrettyOSD()));
|
SLOT(TogglePrettyOSD()));
|
||||||
#ifdef HAVE_LIBLASTFM
|
#ifdef HAVE_LIBLASTFM
|
||||||
connect(global_shortcuts_, SIGNAL(ToggleScrobbling()),
|
connect(global_shortcuts_, SIGNAL(ToggleScrobbling()), app_->scrobbler(),
|
||||||
app_->internet_model()->InternetModel::Service<LastFMService>(),
|
|
||||||
SLOT(ToggleScrobbling()));
|
SLOT(ToggleScrobbling()));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -844,20 +839,14 @@ MainWindow::MainWindow(Application* app, SystemTrayIcon* tray_icon, OSD* osd,
|
|||||||
SLOT(ShuffleModeChanged(PlaylistSequence::ShuffleMode)));
|
SLOT(ShuffleModeChanged(PlaylistSequence::ShuffleMode)));
|
||||||
|
|
||||||
#ifdef HAVE_LIBLASTFM
|
#ifdef HAVE_LIBLASTFM
|
||||||
connect(InternetModel::Service<LastFMService>(), SIGNAL(ScrobbleSubmitted()),
|
connect(app_->scrobbler(), SIGNAL(ScrobbleSubmitted()),
|
||||||
SLOT(ScrobbleSubmitted()));
|
SLOT(ScrobbleSubmitted()));
|
||||||
connect(InternetModel::Service<LastFMService>(), SIGNAL(ScrobbleError(int)),
|
connect(app_->scrobbler(), SIGNAL(ScrobbleError(int)),
|
||||||
SLOT(ScrobbleError(int)));
|
SLOT(ScrobbleError(int)));
|
||||||
|
|
||||||
LastFMButtonVisibilityChanged(app_->internet_model()
|
LastFMButtonVisibilityChanged(app_->scrobbler()->AreButtonsVisible());
|
||||||
->InternetModel::Service<LastFMService>()
|
ScrobbleButtonVisibilityChanged(app_->scrobbler()->IsScrobbleButtonVisible());
|
||||||
->AreButtonsVisible());
|
ScrobblingEnabledChanged(app_->scrobbler()->IsScrobblingEnabled());
|
||||||
ScrobbleButtonVisibilityChanged(app_->internet_model()
|
|
||||||
->InternetModel::Service<LastFMService>()
|
|
||||||
->IsScrobbleButtonVisible());
|
|
||||||
ScrobblingEnabledChanged(app_->internet_model()
|
|
||||||
->InternetModel::Service<LastFMService>()
|
|
||||||
->IsScrobblingEnabled());
|
|
||||||
#else
|
#else
|
||||||
LastFMButtonVisibilityChanged(false);
|
LastFMButtonVisibilityChanged(false);
|
||||||
ScrobbleButtonVisibilityChanged(false);
|
ScrobbleButtonVisibilityChanged(false);
|
||||||
@ -869,7 +858,7 @@ MainWindow::MainWindow(Application* app, SystemTrayIcon* tray_icon, OSD* osd,
|
|||||||
|
|
||||||
restoreGeometry(settings_.value("geometry").toByteArray());
|
restoreGeometry(settings_.value("geometry").toByteArray());
|
||||||
if (!ui_->splitter->restoreState(
|
if (!ui_->splitter->restoreState(
|
||||||
settings_.value("splitter_state").toByteArray())) {
|
settings_.value("splitter_state").toByteArray())) {
|
||||||
ui_->splitter->setSizes(QList<int>() << 300 << width() - 300);
|
ui_->splitter->setSizes(QList<int>() << 300 << width() - 300);
|
||||||
}
|
}
|
||||||
ui_->tabs->SetCurrentIndex(
|
ui_->tabs->SetCurrentIndex(
|
||||||
@ -989,10 +978,8 @@ void MainWindow::MediaStopped() {
|
|||||||
|
|
||||||
ui_->action_play_pause->setEnabled(true);
|
ui_->action_play_pause->setEnabled(true);
|
||||||
|
|
||||||
ui_->action_ban->setEnabled(false);
|
|
||||||
ui_->action_love->setEnabled(false);
|
ui_->action_love->setEnabled(false);
|
||||||
tray_icon_->LastFMButtonLoveStateChanged(false);
|
tray_icon_->LastFMButtonLoveStateChanged(false);
|
||||||
tray_icon_->LastFMButtonBanStateChanged(false);
|
|
||||||
|
|
||||||
track_position_timer_->stop();
|
track_position_timer_->stop();
|
||||||
ui_->track_slider->SetStopped();
|
ui_->track_slider->SetStopped();
|
||||||
@ -1028,18 +1015,10 @@ void MainWindow::MediaPlaying() {
|
|||||||
ui_->track_slider->SetCanSeek(can_seek);
|
ui_->track_slider->SetCanSeek(can_seek);
|
||||||
|
|
||||||
#ifdef HAVE_LIBLASTFM
|
#ifdef HAVE_LIBLASTFM
|
||||||
bool is_lastfm = (app_->player()->GetCurrentItem()->options() &
|
bool enable_love = app_->scrobbler()->IsScrobblingEnabled();
|
||||||
PlaylistItem::LastFMControls);
|
|
||||||
LastFMService* lastfm = InternetModel::Service<LastFMService>();
|
|
||||||
bool enable_ban = lastfm->IsScrobblingEnabled() && is_lastfm;
|
|
||||||
bool enable_love = lastfm->IsScrobblingEnabled();
|
|
||||||
|
|
||||||
ui_->action_ban->setEnabled(enable_ban);
|
|
||||||
ui_->action_love->setEnabled(enable_love);
|
ui_->action_love->setEnabled(enable_love);
|
||||||
tray_icon_->LastFMButtonBanStateChanged(enable_ban);
|
|
||||||
tray_icon_->LastFMButtonLoveStateChanged(enable_love);
|
tray_icon_->LastFMButtonLoveStateChanged(enable_love);
|
||||||
|
tray_icon_->SetPlaying(enable_play_pause, enable_love);
|
||||||
tray_icon_->SetPlaying(enable_play_pause, enable_ban, enable_love);
|
|
||||||
#else
|
#else
|
||||||
tray_icon_->SetPlaying(enable_play_pause);
|
tray_icon_->SetPlaying(enable_play_pause);
|
||||||
#endif
|
#endif
|
||||||
@ -1059,8 +1038,7 @@ void MainWindow::SongChanged(const Song& song) {
|
|||||||
|
|
||||||
#ifdef HAVE_LIBLASTFM
|
#ifdef HAVE_LIBLASTFM
|
||||||
if (ui_->action_toggle_scrobbling->isVisible())
|
if (ui_->action_toggle_scrobbling->isVisible())
|
||||||
SetToggleScrobblingIcon(
|
SetToggleScrobblingIcon(app_->scrobbler()->IsScrobblingEnabled());
|
||||||
InternetModel::Service<LastFMService>()->IsScrobblingEnabled());
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1104,17 +1082,12 @@ void MainWindow::ScrobblingEnabledChanged(bool value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_lastfm = (app_->player()->GetCurrentItem()->options() &
|
|
||||||
PlaylistItem::LastFMControls);
|
|
||||||
ui_->action_ban->setEnabled(value && is_lastfm);
|
|
||||||
tray_icon_->LastFMButtonBanStateChanged(value && is_lastfm);
|
|
||||||
ui_->action_love->setEnabled(value);
|
ui_->action_love->setEnabled(value);
|
||||||
tray_icon_->LastFMButtonLoveStateChanged(value);
|
tray_icon_->LastFMButtonLoveStateChanged(value);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void MainWindow::LastFMButtonVisibilityChanged(bool value) {
|
void MainWindow::LastFMButtonVisibilityChanged(bool value) {
|
||||||
ui_->action_ban->setVisible(value);
|
|
||||||
ui_->action_love->setVisible(value);
|
ui_->action_love->setVisible(value);
|
||||||
ui_->last_fm_controls->setVisible(value);
|
ui_->last_fm_controls->setVisible(value);
|
||||||
tray_icon_->LastFMButtonVisibilityChanged(value);
|
tray_icon_->LastFMButtonVisibilityChanged(value);
|
||||||
@ -1132,9 +1105,7 @@ void MainWindow::ScrobbleButtonVisibilityChanged(bool value) {
|
|||||||
ui_->action_toggle_scrobbling->setIcon(QIcon(":/last.fm/as.png"));
|
ui_->action_toggle_scrobbling->setIcon(QIcon(":/last.fm/as.png"));
|
||||||
} else {
|
} else {
|
||||||
#ifdef HAVE_LIBLASTFM
|
#ifdef HAVE_LIBLASTFM
|
||||||
SetToggleScrobblingIcon(app_->internet_model()
|
SetToggleScrobblingIcon(app_->scrobbler()->IsScrobblingEnabled());
|
||||||
->InternetModel::Service<LastFMService>()
|
|
||||||
->IsScrobblingEnabled());
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1300,20 +1271,19 @@ void MainWindow::UpdateTrackPosition() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_LIBLASTFM
|
#ifdef HAVE_LIBLASTFM
|
||||||
LastFMService* lastfm_service = InternetModel::Service<LastFMService>();
|
|
||||||
const bool last_fm_enabled = ui_->action_toggle_scrobbling->isVisible() &&
|
const bool last_fm_enabled = ui_->action_toggle_scrobbling->isVisible() &&
|
||||||
lastfm_service->IsScrobblingEnabled() &&
|
app_->scrobbler()->IsScrobblingEnabled() &&
|
||||||
lastfm_service->IsAuthenticated();
|
app_->scrobbler()->IsAuthenticated();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Time to scrobble?
|
// Time to scrobble?
|
||||||
if (position >= scrobble_point) {
|
if (position >= scrobble_point) {
|
||||||
if (playlist->get_lastfm_status() == Playlist::LastFM_New) {
|
if (playlist->get_lastfm_status() == Playlist::LastFM_New) {
|
||||||
#ifdef HAVE_LIBLASTFM
|
#ifdef HAVE_LIBLASTFM
|
||||||
if (lastfm_service->IsScrobblingEnabled() &&
|
if (app_->scrobbler()->IsScrobblingEnabled() &&
|
||||||
lastfm_service->IsAuthenticated()) {
|
app_->scrobbler()->IsAuthenticated()) {
|
||||||
qLog(Info) << "Scrobbling at" << scrobble_point;
|
qLog(Info) << "Scrobbling at" << scrobble_point;
|
||||||
lastfm_service->Scrobble();
|
app_->scrobbler()->Scrobble();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -1355,7 +1325,7 @@ void MainWindow::ScrobbledRadioStream() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::Love() {
|
void MainWindow::Love() {
|
||||||
InternetModel::Service<LastFMService>()->Love();
|
app_->scrobbler()->Love();
|
||||||
ui_->action_love->setEnabled(false);
|
ui_->action_love->setEnabled(false);
|
||||||
tray_icon_->LastFMButtonLoveStateChanged(false);
|
tray_icon_->LastFMButtonLoveStateChanged(false);
|
||||||
}
|
}
|
||||||
@ -1432,10 +1402,8 @@ void MainWindow::AddToPlaylist(QAction* action) {
|
|||||||
PlaylistItemList items;
|
PlaylistItemList items;
|
||||||
|
|
||||||
// get the selected playlist items
|
// get the selected playlist items
|
||||||
for (const QModelIndex& index : ui_->playlist->view()
|
for (const QModelIndex& index :
|
||||||
->selectionModel()
|
ui_->playlist->view()->selectionModel()->selection().indexes()) {
|
||||||
->selection()
|
|
||||||
.indexes()) {
|
|
||||||
if (index.column() != 0) continue;
|
if (index.column() != 0) continue;
|
||||||
int row =
|
int row =
|
||||||
app_->playlist_manager()->current()->proxy()->mapToSource(index).row();
|
app_->playlist_manager()->current()->proxy()->mapToSource(index).row();
|
||||||
@ -1693,10 +1661,8 @@ void MainWindow::EditTracks() {
|
|||||||
SongList songs;
|
SongList songs;
|
||||||
PlaylistItemList items;
|
PlaylistItemList items;
|
||||||
|
|
||||||
for (const QModelIndex& index : ui_->playlist->view()
|
for (const QModelIndex& index :
|
||||||
->selectionModel()
|
ui_->playlist->view()->selectionModel()->selection().indexes()) {
|
||||||
->selection()
|
|
||||||
.indexes()) {
|
|
||||||
if (index.column() != 0) continue;
|
if (index.column() != 0) continue;
|
||||||
int row =
|
int row =
|
||||||
app_->playlist_manager()->current()->proxy()->mapToSource(index).row();
|
app_->playlist_manager()->current()->proxy()->mapToSource(index).row();
|
||||||
@ -2078,10 +2044,8 @@ void MainWindow::AddFilesToTranscoder() {
|
|||||||
|
|
||||||
QStringList filenames;
|
QStringList filenames;
|
||||||
|
|
||||||
for (const QModelIndex& index : ui_->playlist->view()
|
for (const QModelIndex& index :
|
||||||
->selectionModel()
|
ui_->playlist->view()->selectionModel()->selection().indexes()) {
|
||||||
->selection()
|
|
||||||
.indexes()) {
|
|
||||||
if (index.column() != 0) continue;
|
if (index.column() != 0) continue;
|
||||||
int row =
|
int row =
|
||||||
app_->playlist_manager()->current()->proxy()->mapToSource(index).row();
|
app_->playlist_manager()->current()->proxy()->mapToSource(index).row();
|
||||||
@ -2249,9 +2213,8 @@ void MainWindow::DeleteFinished(const SongList& songs_with_errors) {
|
|||||||
|
|
||||||
void MainWindow::PlaylistQueue() {
|
void MainWindow::PlaylistQueue() {
|
||||||
QModelIndexList indexes;
|
QModelIndexList indexes;
|
||||||
for (const QModelIndex& proxy_index : ui_->playlist->view()
|
for (const QModelIndex& proxy_index :
|
||||||
->selectionModel()
|
ui_->playlist->view()->selectionModel()->selectedRows()) {
|
||||||
->selectedRows()) {
|
|
||||||
indexes << app_->playlist_manager()->current()->proxy()->mapToSource(
|
indexes << app_->playlist_manager()->current()->proxy()->mapToSource(
|
||||||
proxy_index);
|
proxy_index);
|
||||||
}
|
}
|
||||||
@ -2261,9 +2224,8 @@ void MainWindow::PlaylistQueue() {
|
|||||||
|
|
||||||
void MainWindow::PlaylistSkip() {
|
void MainWindow::PlaylistSkip() {
|
||||||
QModelIndexList indexes;
|
QModelIndexList indexes;
|
||||||
for (const QModelIndex& proxy_index : ui_->playlist->view()
|
for (const QModelIndex& proxy_index :
|
||||||
->selectionModel()
|
ui_->playlist->view()->selectionModel()->selectedRows()) {
|
||||||
->selectedRows()) {
|
|
||||||
indexes << app_->playlist_manager()->current()->proxy()->mapToSource(
|
indexes << app_->playlist_manager()->current()->proxy()->mapToSource(
|
||||||
proxy_index);
|
proxy_index);
|
||||||
}
|
}
|
||||||
@ -2545,10 +2507,8 @@ void MainWindow::AutoCompleteTags() {
|
|||||||
// Get the selected songs and start fetching tags for them
|
// Get the selected songs and start fetching tags for them
|
||||||
SongList songs;
|
SongList songs;
|
||||||
autocomplete_tag_items_.clear();
|
autocomplete_tag_items_.clear();
|
||||||
for (const QModelIndex& index : ui_->playlist->view()
|
for (const QModelIndex& index :
|
||||||
->selectionModel()
|
ui_->playlist->view()->selectionModel()->selection().indexes()) {
|
||||||
->selection()
|
|
||||||
.indexes()) {
|
|
||||||
if (index.column() != 0) continue;
|
if (index.column() != 0) continue;
|
||||||
int row =
|
int row =
|
||||||
app_->playlist_manager()->current()->proxy()->mapToSource(index).row();
|
app_->playlist_manager()->current()->proxy()->mapToSource(index).row();
|
||||||
@ -2613,10 +2573,9 @@ void MainWindow::SetToggleScrobblingIcon(bool value) {
|
|||||||
|
|
||||||
#ifdef HAVE_LIBLASTFM
|
#ifdef HAVE_LIBLASTFM
|
||||||
void MainWindow::ScrobbleSubmitted() {
|
void MainWindow::ScrobbleSubmitted() {
|
||||||
const LastFMService* lastfm_service = InternetModel::Service<LastFMService>();
|
|
||||||
const bool last_fm_enabled = ui_->action_toggle_scrobbling->isVisible() &&
|
const bool last_fm_enabled = ui_->action_toggle_scrobbling->isVisible() &&
|
||||||
lastfm_service->IsScrobblingEnabled() &&
|
app_->scrobbler()->IsScrobblingEnabled() &&
|
||||||
lastfm_service->IsAuthenticated();
|
app_->scrobbler()->IsAuthenticated();
|
||||||
|
|
||||||
app_->playlist_manager()->active()->set_lastfm_status(
|
app_->playlist_manager()->active()->set_lastfm_status(
|
||||||
Playlist::LastFM_Scrobbled);
|
Playlist::LastFM_Scrobbled);
|
||||||
|
@ -200,19 +200,6 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QToolButton" name="ban_button">
|
|
||||||
<property name="iconSize">
|
|
||||||
<size>
|
|
||||||
<width>22</width>
|
|
||||||
<height>22</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="autoRaise">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -435,7 +422,6 @@
|
|||||||
<addaction name="action_mute"/>
|
<addaction name="action_mute"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="action_love"/>
|
<addaction name="action_love"/>
|
||||||
<addaction name="action_ban"/>
|
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="action_quit"/>
|
<addaction name="action_quit"/>
|
||||||
</widget>
|
</widget>
|
||||||
@ -567,21 +553,6 @@
|
|||||||
<string>Ctrl+L</string>
|
<string>Ctrl+L</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</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>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Ban</string>
|
|
||||||
</property>
|
|
||||||
<property name="shortcut">
|
|
||||||
<string>Ctrl+B</string>
|
|
||||||
</property>
|
|
||||||
</action>
|
|
||||||
<action name="action_clear_playlist">
|
<action name="action_clear_playlist">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Clear playlist</string>
|
<string>Clear playlist</string>
|
||||||
|
@ -36,8 +36,7 @@ QtSystemTrayIcon::QtSystemTrayIcon(QObject* parent)
|
|||||||
action_stop_(nullptr),
|
action_stop_(nullptr),
|
||||||
action_stop_after_this_track_(nullptr),
|
action_stop_after_this_track_(nullptr),
|
||||||
action_mute_(nullptr),
|
action_mute_(nullptr),
|
||||||
action_love_(nullptr),
|
action_love_(nullptr) {
|
||||||
action_ban_(nullptr) {
|
|
||||||
QIcon theme_icon = IconLoader::Load("clementine-panel");
|
QIcon theme_icon = IconLoader::Load("clementine-panel");
|
||||||
QIcon theme_icon_grey = IconLoader::Load("clementine-panel-grey");
|
QIcon theme_icon_grey = IconLoader::Load("clementine-panel-grey");
|
||||||
|
|
||||||
@ -97,7 +96,7 @@ bool QtSystemTrayIcon::eventFilter(QObject* object, QEvent* event) {
|
|||||||
void QtSystemTrayIcon::SetupMenu(QAction* previous, QAction* play,
|
void QtSystemTrayIcon::SetupMenu(QAction* previous, QAction* play,
|
||||||
QAction* stop, QAction* stop_after,
|
QAction* stop, QAction* stop_after,
|
||||||
QAction* next, QAction* mute, QAction* love,
|
QAction* next, QAction* mute, QAction* love,
|
||||||
QAction* ban, QAction* quit) {
|
QAction* quit) {
|
||||||
// Creating new actions and connecting them to old ones. This allows us to
|
// Creating new actions and connecting them to old ones. This allows us to
|
||||||
// use old actions without displaying shortcuts that can not be used when
|
// use old actions without displaying shortcuts that can not be used when
|
||||||
// Clementine's window is hidden
|
// Clementine's window is hidden
|
||||||
@ -123,10 +122,6 @@ void QtSystemTrayIcon::SetupMenu(QAction* previous, QAction* play,
|
|||||||
menu_->addAction(love->icon(), love->text(), love, SLOT(trigger()));
|
menu_->addAction(love->icon(), love->text(), love, SLOT(trigger()));
|
||||||
action_love_->setVisible(love->isVisible());
|
action_love_->setVisible(love->isVisible());
|
||||||
action_love_->setEnabled(love->isEnabled());
|
action_love_->setEnabled(love->isEnabled());
|
||||||
action_ban_ =
|
|
||||||
menu_->addAction(ban->icon(), ban->text(), ban, SLOT(trigger()));
|
|
||||||
action_ban_->setVisible(ban->isVisible());
|
|
||||||
action_ban_->setEnabled(ban->isEnabled());
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
menu_->addSeparator();
|
menu_->addSeparator();
|
||||||
@ -171,8 +166,7 @@ void QtSystemTrayIcon::SetPaused() {
|
|||||||
action_play_pause_->setEnabled(true);
|
action_play_pause_->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtSystemTrayIcon::SetPlaying(bool enable_play_pause, bool enable_ban,
|
void QtSystemTrayIcon::SetPlaying(bool enable_play_pause, bool enable_love) {
|
||||||
bool enable_love) {
|
|
||||||
SystemTrayIcon::SetPlaying();
|
SystemTrayIcon::SetPlaying();
|
||||||
|
|
||||||
action_stop_->setEnabled(true);
|
action_stop_->setEnabled(true);
|
||||||
@ -181,7 +175,6 @@ void QtSystemTrayIcon::SetPlaying(bool enable_play_pause, bool enable_ban,
|
|||||||
action_play_pause_->setText(tr("Pause"));
|
action_play_pause_->setText(tr("Pause"));
|
||||||
action_play_pause_->setEnabled(enable_play_pause);
|
action_play_pause_->setEnabled(enable_play_pause);
|
||||||
#ifdef HAVE_LIBLASTFM
|
#ifdef HAVE_LIBLASTFM
|
||||||
action_ban_->setEnabled(enable_ban);
|
|
||||||
action_love_->setEnabled(enable_love);
|
action_love_->setEnabled(enable_love);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -197,14 +190,12 @@ void QtSystemTrayIcon::SetStopped() {
|
|||||||
action_play_pause_->setEnabled(true);
|
action_play_pause_->setEnabled(true);
|
||||||
|
|
||||||
#ifdef HAVE_LIBLASTFM
|
#ifdef HAVE_LIBLASTFM
|
||||||
action_ban_->setEnabled(false);
|
|
||||||
action_love_->setEnabled(false);
|
action_love_->setEnabled(false);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtSystemTrayIcon::LastFMButtonVisibilityChanged(bool value) {
|
void QtSystemTrayIcon::LastFMButtonVisibilityChanged(bool value) {
|
||||||
#ifdef HAVE_LIBLASTFM
|
#ifdef HAVE_LIBLASTFM
|
||||||
action_ban_->setVisible(value);
|
|
||||||
action_love_->setVisible(value);
|
action_love_->setVisible(value);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -215,12 +206,6 @@ void QtSystemTrayIcon::LastFMButtonLoveStateChanged(bool value) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtSystemTrayIcon::LastFMButtonBanStateChanged(bool value) {
|
|
||||||
#ifdef HAVE_LIBLASTFM
|
|
||||||
action_ban_->setEnabled(value);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void QtSystemTrayIcon::MuteButtonStateChanged(bool value) {
|
void QtSystemTrayIcon::MuteButtonStateChanged(bool value) {
|
||||||
if (action_mute_) action_mute_->setChecked(value);
|
if (action_mute_) action_mute_->setChecked(value);
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ class QtSystemTrayIcon : public SystemTrayIcon {
|
|||||||
|
|
||||||
void SetupMenu(QAction* previous, QAction* play, QAction* stop,
|
void SetupMenu(QAction* previous, QAction* play, QAction* stop,
|
||||||
QAction* stop_after, QAction* next, QAction* mute,
|
QAction* stop_after, QAction* next, QAction* mute,
|
||||||
QAction* love, QAction* ban, QAction* quit);
|
QAction* love, QAction* quit);
|
||||||
bool IsVisible() const;
|
bool IsVisible() const;
|
||||||
void SetVisible(bool visible);
|
void SetVisible(bool visible);
|
||||||
|
|
||||||
@ -44,12 +44,10 @@ class QtSystemTrayIcon : public SystemTrayIcon {
|
|||||||
// SystemTrayIcon
|
// SystemTrayIcon
|
||||||
void UpdateIcon();
|
void UpdateIcon();
|
||||||
void SetPaused();
|
void SetPaused();
|
||||||
void SetPlaying(bool enable_play_pause = false, bool enable_ban = false,
|
void SetPlaying(bool enable_play_pause = false, bool enable_love = false);
|
||||||
bool enable_love = false);
|
|
||||||
void SetStopped();
|
void SetStopped();
|
||||||
void LastFMButtonVisibilityChanged(bool value);
|
void LastFMButtonVisibilityChanged(bool value);
|
||||||
void LastFMButtonLoveStateChanged(bool value);
|
void LastFMButtonLoveStateChanged(bool value);
|
||||||
void LastFMButtonBanStateChanged(bool value);
|
|
||||||
void MuteButtonStateChanged(bool value);
|
void MuteButtonStateChanged(bool value);
|
||||||
|
|
||||||
// QObject
|
// QObject
|
||||||
@ -66,7 +64,6 @@ class QtSystemTrayIcon : public SystemTrayIcon {
|
|||||||
QAction* action_stop_after_this_track_;
|
QAction* action_stop_after_this_track_;
|
||||||
QAction* action_mute_;
|
QAction* action_mute_;
|
||||||
QAction* action_love_;
|
QAction* action_love_;
|
||||||
QAction* action_ban_;
|
|
||||||
|
|
||||||
QString pattern_;
|
QString pattern_;
|
||||||
|
|
||||||
|
@ -86,8 +86,7 @@ void SystemTrayIcon::SetPaused() {
|
|||||||
UpdateIcon();
|
UpdateIcon();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemTrayIcon::SetPlaying(bool enable_play_pause, bool enable_ban,
|
void SystemTrayIcon::SetPlaying(bool enable_play_pause, bool enable_love) {
|
||||||
bool enable_love) {
|
|
||||||
current_state_icon_ = playing_icon_;
|
current_state_icon_ = playing_icon_;
|
||||||
UpdateIcon();
|
UpdateIcon();
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ class SystemTrayIcon : public QObject {
|
|||||||
// Called once to create the icon's context menu
|
// Called once to create the icon's context menu
|
||||||
virtual void SetupMenu(QAction* previous, QAction* play, QAction* stop,
|
virtual void SetupMenu(QAction* previous, QAction* play, QAction* stop,
|
||||||
QAction* stop_after, QAction* next, QAction* mute,
|
QAction* stop_after, QAction* next, QAction* mute,
|
||||||
QAction* love, QAction* ban, QAction* quit) = 0;
|
QAction* love, QAction* quit) = 0;
|
||||||
|
|
||||||
virtual bool IsVisible() const { return true; }
|
virtual bool IsVisible() const { return true; }
|
||||||
virtual void SetVisible(bool visible) {}
|
virtual void SetVisible(bool visible) {}
|
||||||
@ -54,11 +54,10 @@ class SystemTrayIcon : public QObject {
|
|||||||
void SetProgress(int percentage);
|
void SetProgress(int percentage);
|
||||||
virtual void SetPaused();
|
virtual void SetPaused();
|
||||||
virtual void SetPlaying(bool enable_play_pause = false,
|
virtual void SetPlaying(bool enable_play_pause = false,
|
||||||
bool enable_ban = false, bool enable_love = false);
|
bool enable_love = false);
|
||||||
virtual void SetStopped();
|
virtual void SetStopped();
|
||||||
virtual void LastFMButtonVisibilityChanged(bool value) {}
|
virtual void LastFMButtonVisibilityChanged(bool value) {}
|
||||||
virtual void LastFMButtonLoveStateChanged(bool value) {}
|
virtual void LastFMButtonLoveStateChanged(bool value) {}
|
||||||
virtual void LastFMButtonBanStateChanged(bool value) {}
|
|
||||||
virtual void MuteButtonStateChanged(bool value) {}
|
virtual void MuteButtonStateChanged(bool value) {}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user