Add some spotify branding, display spotify login errors, add a button to the config dialog to download the blob, only make the config dialog try to login when it needs to, fix a bug where the Starred and Inbox items would sometimes not get created.
This commit is contained in:
parent
1c0a0f17dd
commit
70e6018b1e
@ -318,5 +318,6 @@
|
||||
<file>icons/32x32/edit-find.png</file>
|
||||
<file>icons/48x48/edit-find.png</file>
|
||||
<file>schema/schema-33.sql</file>
|
||||
<file>spotify-core-logo-128x128.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
BIN
data/spotify-core-logo-128x128.png
Normal file
BIN
data/spotify-core-logo-128x128.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.9 KiB |
@ -44,6 +44,14 @@ SpotifyBlobDownloader::~SpotifyBlobDownloader() {
|
||||
delete progress_;
|
||||
}
|
||||
|
||||
bool SpotifyBlobDownloader::Prompt() {
|
||||
QMessageBox::StandardButton ret = QMessageBox::question(NULL,
|
||||
tr("Spotify plugin not installed"),
|
||||
tr("An additional plugin is required to use Spotify in Clementine. Would you like to download and install it now?"),
|
||||
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
|
||||
return ret == QMessageBox::Yes;
|
||||
}
|
||||
|
||||
void SpotifyBlobDownloader::Start() {
|
||||
qDeleteAll(replies_);
|
||||
replies_.clear();
|
||||
|
@ -32,6 +32,8 @@ public:
|
||||
QObject* parent = 0);
|
||||
~SpotifyBlobDownloader();
|
||||
|
||||
static bool Prompt();
|
||||
|
||||
void Start();
|
||||
|
||||
signals:
|
||||
|
@ -33,20 +33,55 @@ SpotifyConfig::SpotifyConfig(QWidget *parent)
|
||||
network_(new NetworkAccessManager(this)),
|
||||
ui_(new Ui_SpotifyConfig),
|
||||
service_(RadioModel::Service<SpotifyService>()),
|
||||
needs_validation_(true)
|
||||
validated_(false)
|
||||
{
|
||||
ui_->setupUi(this);
|
||||
ui_->busy->hide();
|
||||
|
||||
QFont bold_font(font());
|
||||
bold_font.setBold(true);
|
||||
ui_->blob_status->setFont(bold_font);
|
||||
|
||||
connect(ui_->download_blob, SIGNAL(clicked()), SLOT(DownloadBlob()));
|
||||
|
||||
connect(service_, SIGNAL(LoginFinished(bool)), SLOT(LoginFinished(bool)));
|
||||
connect(service_, SIGNAL(BlobStateChanged()), SLOT(BlobStateChanged()));
|
||||
|
||||
BlobStateChanged();
|
||||
}
|
||||
|
||||
SpotifyConfig::~SpotifyConfig() {
|
||||
delete ui_;
|
||||
}
|
||||
|
||||
void SpotifyConfig::BlobStateChanged() {
|
||||
const bool installed = service_->IsBlobInstalled();
|
||||
|
||||
ui_->account_group->setEnabled(installed);
|
||||
ui_->blob_status->setText(installed ? tr("Installed") : tr("Not installed"));
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
ui_->download_blob->setEnabled(!installed);
|
||||
#else
|
||||
ui_->download_blob->setEnabled(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SpotifyConfig::DownloadBlob() {
|
||||
service_->InstallBlob();
|
||||
}
|
||||
|
||||
bool SpotifyConfig::NeedsValidation() const {
|
||||
// FIXME
|
||||
return needs_validation_;
|
||||
if (!service_->IsBlobInstalled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ui_->username->text() == original_username_ &&
|
||||
ui_->password->text() == original_password_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !validated_;
|
||||
}
|
||||
|
||||
void SpotifyConfig::Validate() {
|
||||
@ -58,8 +93,12 @@ void SpotifyConfig::Load() {
|
||||
QSettings s;
|
||||
s.beginGroup(SpotifyService::kSettingsGroup);
|
||||
|
||||
ui_->username->setText(s.value("username").toString());
|
||||
ui_->password->setText(s.value("password").toString());
|
||||
original_username_ = s.value("username").toString();
|
||||
original_password_ = s.value("password").toString();
|
||||
|
||||
ui_->username->setText(original_username_);
|
||||
ui_->password->setText(original_password_);
|
||||
validated_ = false;
|
||||
}
|
||||
|
||||
void SpotifyConfig::Save() {
|
||||
@ -73,8 +112,7 @@ void SpotifyConfig::Save() {
|
||||
}
|
||||
|
||||
void SpotifyConfig::LoginFinished(bool success) {
|
||||
qDebug() << Q_FUNC_INFO << success;
|
||||
needs_validation_ = !success;
|
||||
validated_ = success;
|
||||
ui_->busy->hide();
|
||||
emit ValidationComplete(success);
|
||||
}
|
||||
|
@ -44,6 +44,9 @@ public slots:
|
||||
void Load();
|
||||
void Save();
|
||||
|
||||
void BlobStateChanged();
|
||||
void DownloadBlob();
|
||||
|
||||
private slots:
|
||||
void LoginFinished(bool success);
|
||||
|
||||
@ -52,7 +55,9 @@ private:
|
||||
Ui_SpotifyConfig* ui_;
|
||||
SpotifyService* service_;
|
||||
|
||||
bool needs_validation_;
|
||||
bool validated_;
|
||||
QString original_username_;
|
||||
QString original_password_;
|
||||
};
|
||||
|
||||
#endif // SPOTIFYCONFIG_H
|
||||
|
@ -6,16 +6,16 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>448</width>
|
||||
<height>310</height>
|
||||
<width>484</width>
|
||||
<height>384</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<widget class="QGroupBox" name="account_group">
|
||||
<property name="title">
|
||||
<string>Account details</string>
|
||||
</property>
|
||||
@ -69,6 +69,56 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Spotify plugin</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>For licensing reasons Spotify support is in a separate plugin.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Plugin status:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="blob_status"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="download_blob">
|
||||
<property name="text">
|
||||
<string>Download...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
@ -82,6 +132,45 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>64</width>
|
||||
<height>64</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>64</width>
|
||||
<height>64</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../../data/data.qrc">:/spotify-core-logo-128x128.png</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="busy" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
@ -120,6 +209,8 @@
|
||||
<header>widgets/busyindicator.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<resources>
|
||||
<include location="../../data/data.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
@ -90,9 +90,7 @@ void SpotifyServer::HandleMessage(const protobuf::SpotifyMessage& message) {
|
||||
const protobuf::LoginResponse& response = message.login_response();
|
||||
logged_in_ = response.success();
|
||||
|
||||
if (!response.success()) {
|
||||
qLog(Info) << QStringFromStdString(response.error());
|
||||
} else {
|
||||
if (response.success()) {
|
||||
// Send any messages that were queued before the client logged in
|
||||
foreach (const protobuf::SpotifyMessage& message, queued_messages_) {
|
||||
SendMessage(message);
|
||||
@ -100,7 +98,7 @@ void SpotifyServer::HandleMessage(const protobuf::SpotifyMessage& message) {
|
||||
queued_messages_.clear();
|
||||
}
|
||||
|
||||
emit LoginCompleted(response.success());
|
||||
emit LoginCompleted(response.success(), QStringFromStdString(response.error()));
|
||||
} else if (message.has_playlists_updated()) {
|
||||
emit PlaylistsUpdated(message.playlists_updated());
|
||||
} else if (message.has_load_playlist_response()) {
|
||||
|
@ -47,7 +47,7 @@ public:
|
||||
int server_port() const;
|
||||
|
||||
signals:
|
||||
void LoginCompleted(bool success);
|
||||
void LoginCompleted(bool success, const QString& error);
|
||||
void PlaylistsUpdated(const protobuf::Playlists& playlists);
|
||||
|
||||
void StarredLoaded(const protobuf::LoadPlaylistResponse& response);
|
||||
|
@ -37,6 +37,7 @@ SpotifyService::SpotifyService(RadioModel* parent)
|
||||
url_handler_(new SpotifyUrlHandler(this, this)),
|
||||
blob_process_(NULL),
|
||||
root_(NULL),
|
||||
search_(NULL),
|
||||
starred_(NULL),
|
||||
inbox_(NULL),
|
||||
login_task_id_(0),
|
||||
@ -46,14 +47,19 @@ SpotifyService::SpotifyService(RadioModel* parent)
|
||||
// Build the search path for the binary blob.
|
||||
// Look for one distributed alongside clementine first, then check in the
|
||||
// user's home directory for any that have been downloaded.
|
||||
blob_path_ << QCoreApplication::applicationFilePath() + "-spotifyblob" CMAKE_EXECUTABLE_SUFFIX
|
||||
<< QCoreApplication::applicationDirPath() + "/../PlugIns/clementine-spotifyblob" CMAKE_EXECUTABLE_SUFFIX;
|
||||
#ifdef Q_OS_MAC
|
||||
system_blob_path_ = QCoreApplication::applicationDirPath() +
|
||||
"/../PlugIns/clementine-spotifyblob";
|
||||
#else
|
||||
system_blob_path_ = QCoreApplication::applicationFilePath() +
|
||||
"-spotifyblob" CMAKE_EXECUTABLE_SUFFIX;
|
||||
#endif
|
||||
|
||||
local_blob_version_ = QString("version%1-%2bit").arg(SPOTIFY_BLOB_VERSION).arg(sizeof(void*) * 8);
|
||||
local_blob_path_ = Utilities::GetConfigPath(Utilities::Path_LocalSpotifyBlob) +
|
||||
"/" + local_blob_version_ + "/blob";
|
||||
|
||||
qLog(Debug) << "Spotify blob search path:" << blob_path_;
|
||||
qLog(Debug) << "Spotify system blob path:" << system_blob_path_;
|
||||
qLog(Debug) << "Spotify local blob path:" << local_blob_path_;
|
||||
|
||||
model()->player()->RegisterUrlHandler(url_handler_);
|
||||
@ -66,6 +72,11 @@ SpotifyService::SpotifyService(RadioModel* parent)
|
||||
}
|
||||
|
||||
SpotifyService::~SpotifyService() {
|
||||
if (blob_process_ && blob_process_->state() == QProcess::Running) {
|
||||
qLog(Info) << "Terminating blob process...";
|
||||
blob_process_->terminate();
|
||||
blob_process_->waitForFinished(1000);
|
||||
}
|
||||
}
|
||||
|
||||
QStandardItem* SpotifyService::CreateRootItem() {
|
||||
@ -118,12 +129,16 @@ void SpotifyService::Login(const QString& username, const QString& password) {
|
||||
EnsureServerCreated(username, password);
|
||||
}
|
||||
|
||||
void SpotifyService::LoginCompleted(bool success) {
|
||||
void SpotifyService::LoginCompleted(bool success, const QString& error) {
|
||||
if (login_task_id_) {
|
||||
model()->task_manager()->SetTaskFinished(login_task_id_);
|
||||
login_task_id_ = 0;
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
QMessageBox::warning(NULL, tr("Spotify login error"), error, QMessageBox::Close);
|
||||
}
|
||||
|
||||
emit LoginFinished(success);
|
||||
}
|
||||
|
||||
@ -132,8 +147,6 @@ void SpotifyService::BlobProcessError(QProcess::ProcessError error) {
|
||||
blob_process_->deleteLater();
|
||||
blob_process_ = NULL;
|
||||
|
||||
emit StreamError("The Spotify process failed");
|
||||
|
||||
if (login_task_id_) {
|
||||
model()->task_manager()->SetTaskFinished(login_task_id_);
|
||||
}
|
||||
@ -148,7 +161,7 @@ void SpotifyService::EnsureServerCreated(const QString& username,
|
||||
delete server_;
|
||||
server_ = new SpotifyServer(this);
|
||||
|
||||
connect(server_, SIGNAL(LoginCompleted(bool)), SLOT(LoginCompleted(bool)));
|
||||
connect(server_, SIGNAL(LoginCompleted(bool,QString)), SLOT(LoginCompleted(bool,QString)));
|
||||
connect(server_, SIGNAL(PlaylistsUpdated(protobuf::Playlists)),
|
||||
SLOT(PlaylistsUpdated(protobuf::Playlists)));
|
||||
connect(server_, SIGNAL(InboxLoaded(protobuf::LoadPlaylistResponse)),
|
||||
@ -186,19 +199,15 @@ void SpotifyService::StartBlobProcess() {
|
||||
QProcessEnvironment env(QProcessEnvironment::systemEnvironment());
|
||||
|
||||
// Look in the system search path first
|
||||
foreach (const QString& path, blob_path_) {
|
||||
if (QFile::exists(path)) {
|
||||
blob_path = path;
|
||||
break;
|
||||
}
|
||||
if (QFile::exists(system_blob_path_)) {
|
||||
blob_path = system_blob_path_;
|
||||
}
|
||||
|
||||
// Next look in the local path
|
||||
const QString local_blob_dir = QFileInfo(local_blob_path_).path();
|
||||
if (blob_path.isEmpty()) {
|
||||
if (QFile::exists(local_blob_path_)) {
|
||||
blob_path = local_blob_path_;
|
||||
env.insert("LD_LIBRARY_PATH", local_blob_dir);
|
||||
env.insert("LD_LIBRARY_PATH", QFileInfo(local_blob_path_).path());
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,17 +218,8 @@ void SpotifyService::StartBlobProcess() {
|
||||
}
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
QMessageBox::StandardButton ret = QMessageBox::question(NULL,
|
||||
tr("Spotify plugin not installed"),
|
||||
tr("An additional plugin is required to use Spotify in Clementine. Would you like to download and install it now?"),
|
||||
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
|
||||
|
||||
if (ret == QMessageBox::Yes) {
|
||||
// The downloader deletes itself when it finishes
|
||||
SpotifyBlobDownloader* downloader = new SpotifyBlobDownloader(
|
||||
local_blob_version_, local_blob_dir, this);
|
||||
connect(downloader, SIGNAL(Finished()), SLOT(BlobDownloadFinished()));
|
||||
downloader->Start();
|
||||
if (SpotifyBlobDownloader::Prompt()) {
|
||||
InstallBlob();
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -240,6 +240,20 @@ void SpotifyService::StartBlobProcess() {
|
||||
blob_path, QStringList() << QString::number(server_->server_port()));
|
||||
}
|
||||
|
||||
bool SpotifyService::IsBlobInstalled() const {
|
||||
return QFile::exists(system_blob_path_) ||
|
||||
QFile::exists(local_blob_path_);
|
||||
}
|
||||
|
||||
void SpotifyService::InstallBlob() {
|
||||
// The downloader deletes itself when it finishes
|
||||
SpotifyBlobDownloader* downloader = new SpotifyBlobDownloader(
|
||||
local_blob_version_, QFileInfo(local_blob_path_).path(), this);
|
||||
connect(downloader, SIGNAL(Finished()), SLOT(BlobDownloadFinished()));
|
||||
connect(downloader, SIGNAL(Finished()), SIGNAL(BlobStateChanged()));
|
||||
downloader->Start();
|
||||
}
|
||||
|
||||
void SpotifyService::BlobDownloadFinished() {
|
||||
EnsureServerCreated();
|
||||
}
|
||||
|
@ -52,7 +52,11 @@ public:
|
||||
|
||||
SpotifyServer* server() const;
|
||||
|
||||
bool IsBlobInstalled() const;
|
||||
void InstallBlob();
|
||||
|
||||
signals:
|
||||
void BlobStateChanged();
|
||||
void LoginFinished(bool success);
|
||||
void ImageLoaded(const QUrl& url, const QImage& image);
|
||||
|
||||
@ -72,7 +76,7 @@ private:
|
||||
|
||||
private slots:
|
||||
void BlobProcessError(QProcess::ProcessError error);
|
||||
void LoginCompleted(bool success);
|
||||
void LoginCompleted(bool success, const QString& error);
|
||||
void PlaylistsUpdated(const protobuf::Playlists& response);
|
||||
void InboxLoaded(const protobuf::LoadPlaylistResponse& response);
|
||||
void StarredLoaded(const protobuf::LoadPlaylistResponse& response);
|
||||
@ -90,9 +94,9 @@ private:
|
||||
SpotifyServer* server_;
|
||||
SpotifyUrlHandler* url_handler_;
|
||||
|
||||
QString system_blob_path_;
|
||||
QString local_blob_version_;
|
||||
QString local_blob_path_;
|
||||
QStringList blob_path_;
|
||||
QProcess* blob_process_;
|
||||
|
||||
QStandardItem* root_;
|
||||
|
@ -16,6 +16,7 @@
|
||||
*/
|
||||
|
||||
#include "about.h"
|
||||
#include "config.h"
|
||||
#include "ui_about.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
@ -77,6 +78,12 @@ QString About::MakeHtml() const {
|
||||
ret += QString("<br /><a href=\"http://rainymood.com\">Rainy Mood</a>");
|
||||
ret += QString("<br /><a href=\"http://www.smitelli.com/?page=blog&p=54\">Scott Smitelli</a></p>");
|
||||
|
||||
#ifdef HAVE_SPOTIFY
|
||||
ret += "<p>This product uses SPOTIFY(R) CORE but is not endorsed, certified "
|
||||
"or otherwise approved in any way by Spotify. Spotify is the "
|
||||
"registered trade mark of the Spotify Group.</p>";
|
||||
#endif // HAVE_SPOTIFY
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user