From 70e6018b1e3581265aa7e576c8dc96ecc0b2bfa8 Mon Sep 17 00:00:00 2001 From: David Sansome Date: Sat, 30 Apr 2011 12:31:20 +0000 Subject: [PATCH] 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. --- data/data.qrc | 1 + data/spotify-core-logo-128x128.png | Bin 0 -> 7082 bytes src/radio/spotifyblobdownloader.cpp | 8 +++ src/radio/spotifyblobdownloader.h | 2 + src/radio/spotifyconfig.cpp | 52 ++++++++++++-- src/radio/spotifyconfig.h | 7 +- src/radio/spotifyconfig.ui | 101 ++++++++++++++++++++++++++-- src/radio/spotifyserver.cpp | 6 +- src/radio/spotifyserver.h | 2 +- src/radio/spotifyservice.cpp | 64 +++++++++++------- src/radio/spotifyservice.h | 8 ++- src/ui/about.cpp | 7 ++ 12 files changed, 213 insertions(+), 45 deletions(-) create mode 100644 data/spotify-core-logo-128x128.png diff --git a/data/data.qrc b/data/data.qrc index 757b80473..5656264ac 100644 --- a/data/data.qrc +++ b/data/data.qrc @@ -318,5 +318,6 @@ icons/32x32/edit-find.png icons/48x48/edit-find.png schema/schema-33.sql + spotify-core-logo-128x128.png diff --git a/data/spotify-core-logo-128x128.png b/data/spotify-core-logo-128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..e52ecc4b9d6d539313ee5d555e798c1389ee6bce GIT binary patch literal 7082 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 a1eo94_E-c7wZSh#05v6T#aemmu>S$3cQsQ0 literal 0 HcmV?d00001 diff --git a/src/radio/spotifyblobdownloader.cpp b/src/radio/spotifyblobdownloader.cpp index 3c1e27a9a..7f5eca980 100644 --- a/src/radio/spotifyblobdownloader.cpp +++ b/src/radio/spotifyblobdownloader.cpp @@ -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(); diff --git a/src/radio/spotifyblobdownloader.h b/src/radio/spotifyblobdownloader.h index f69c58778..f0300b3ff 100644 --- a/src/radio/spotifyblobdownloader.h +++ b/src/radio/spotifyblobdownloader.h @@ -32,6 +32,8 @@ public: QObject* parent = 0); ~SpotifyBlobDownloader(); + static bool Prompt(); + void Start(); signals: diff --git a/src/radio/spotifyconfig.cpp b/src/radio/spotifyconfig.cpp index c0225f687..5400c31a4 100644 --- a/src/radio/spotifyconfig.cpp +++ b/src/radio/spotifyconfig.cpp @@ -33,20 +33,55 @@ SpotifyConfig::SpotifyConfig(QWidget *parent) network_(new NetworkAccessManager(this)), ui_(new Ui_SpotifyConfig), service_(RadioModel::Service()), - 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); } diff --git a/src/radio/spotifyconfig.h b/src/radio/spotifyconfig.h index 95f0e0ace..f4d756250 100644 --- a/src/radio/spotifyconfig.h +++ b/src/radio/spotifyconfig.h @@ -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 diff --git a/src/radio/spotifyconfig.ui b/src/radio/spotifyconfig.ui index 3631f903a..f3f49161c 100644 --- a/src/radio/spotifyconfig.ui +++ b/src/radio/spotifyconfig.ui @@ -6,16 +6,16 @@ 0 0 - 448 - 310 + 484 + 384 Form - + - + Account details @@ -69,6 +69,56 @@ + + + + Spotify plugin + + + + + + For licensing reasons Spotify support is in a separate plugin. + + + + + + + + + Plugin status: + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Download... + + + + + + + + @@ -82,6 +132,45 @@ + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 64 + 64 + + + + + 64 + 64 + + + + :/spotify-core-logo-128x128.png + + + true + + + + + @@ -120,6 +209,8 @@
widgets/busyindicator.h
- + + + diff --git a/src/radio/spotifyserver.cpp b/src/radio/spotifyserver.cpp index 7d34f1764..2003e8888 100644 --- a/src/radio/spotifyserver.cpp +++ b/src/radio/spotifyserver.cpp @@ -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()) { diff --git a/src/radio/spotifyserver.h b/src/radio/spotifyserver.h index a97e888f8..f5f87f391 100644 --- a/src/radio/spotifyserver.h +++ b/src/radio/spotifyserver.h @@ -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); diff --git a/src/radio/spotifyservice.cpp b/src/radio/spotifyservice.cpp index efae7d773..b7ac91adb 100644 --- a/src/radio/spotifyservice.cpp +++ b/src/radio/spotifyservice.cpp @@ -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(); } diff --git a/src/radio/spotifyservice.h b/src/radio/spotifyservice.h index f59355673..82204b2a3 100644 --- a/src/radio/spotifyservice.h +++ b/src/radio/spotifyservice.h @@ -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_; diff --git a/src/ui/about.cpp b/src/ui/about.cpp index 6f78dd7a5..23bff7734 100644 --- a/src/ui/about.cpp +++ b/src/ui/about.cpp @@ -16,6 +16,7 @@ */ #include "about.h" +#include "config.h" #include "ui_about.h" #include @@ -77,6 +78,12 @@ QString About::MakeHtml() const { ret += QString("
Rainy Mood"); ret += QString("
Scott Smitelli

"); +#ifdef HAVE_SPOTIFY + ret += "

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.

"; +#endif // HAVE_SPOTIFY + return ret; }