diff --git a/data/data.qrc b/data/data.qrc
index 334f7a62e..973c81c58 100644
--- a/data/data.qrc
+++ b/data/data.qrc
@@ -333,6 +333,7 @@
schema/schema-39.sql
schema/schema-3.sql
schema/schema-40.sql
+ schema/schema-41.sql
schema/schema-4.sql
schema/schema-5.sql
schema/schema-6.sql
diff --git a/data/schema/schema-41.sql b/data/schema/schema-41.sql
new file mode 100644
index 000000000..8e0d20752
--- /dev/null
+++ b/data/schema/schema-41.sql
@@ -0,0 +1,48 @@
+CREATE TABLE dropbox_songs(
+ title TEXT,
+ album TEXT,
+ artist TEXT,
+ albumartist TEXT,
+ composer TEXT,
+ track INTEGER,
+ disc INTEGER,
+ bpm REAL,
+ year INTEGER,
+ genre TEXT,
+ comment TEXT,
+ compilation INTEGER,
+
+ length INTEGER,
+ bitrate INTEGER,
+ samplerate INTEGER,
+
+ directory INTEGER NOT NULL,
+ filename TEXT NOT NULL,
+ mtime INTEGER NOT NULL,
+ ctime INTEGER NOT NULL,
+ filesize INTEGER NOT NULL,
+ sampler INTEGER NOT NULL DEFAULT 0,
+ art_automatic TEXT,
+ art_manual TEXT,
+ filetype INTEGER NOT NULL DEFAULT 0,
+ playcount INTEGER NOT NULL DEFAULT 0,
+ lastplayed INTEGER,
+ rating INTEGER,
+ forced_compilation_on INTEGER NOT NULL DEFAULT 0,
+ forced_compilation_off INTEGER NOT NULL DEFAULT 0,
+ effective_compilation NOT NULL DEFAULT 0,
+ skipcount INTEGER NOT NULL DEFAULT 0,
+ score INTEGER NOT NULL DEFAULT 0,
+ beginning INTEGER NOT NULL DEFAULT 0,
+ cue_path TEXT,
+ unavailable INTEGER DEFAULT 0,
+ effective_albumartist TEXT,
+ etag TEXT
+);
+
+CREATE VIRTUAL TABLE dropbox_songs_fts USING fts3 (
+ ftstitle, ftsalbum, ftsartist, ftsalbumartist, ftscomposer, ftsgenre, ftscomment,
+ tokenize=unicode
+);
+
+UPDATE schema_version SET version=41;
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 611952420..824b561c5 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1058,8 +1058,14 @@ optional_source(HAVE_UBUNTU_ONE
optional_source(HAVE_DROPBOX
SOURCES
internet/dropboxauthenticator.cpp
+ internet/dropboxservice.cpp
+ internet/dropboxsettingspage.cpp
HEADERS
internet/dropboxauthenticator.h
+ internet/dropboxservice.h
+ internet/dropboxsettingspage.h
+ UI
+ internet/dropboxsettingspage.ui
)
# Hack to add Clementine to the Unity system tray whitelist
diff --git a/src/core/database.cpp b/src/core/database.cpp
index a8862d3b4..58d410fe9 100644
--- a/src/core/database.cpp
+++ b/src/core/database.cpp
@@ -37,7 +37,7 @@
#include
const char* Database::kDatabaseFilename = "clementine.db";
-const int Database::kSchemaVersion = 40;
+const int Database::kSchemaVersion = 41;
const char* Database::kMagicAllSongsTables = "%allsongstables";
int Database::sNextConnectionId = 1;
diff --git a/src/internet/cloudfileservice.h b/src/internet/cloudfileservice.h
index 060f84829..b0ca7af7a 100644
--- a/src/internet/cloudfileservice.h
+++ b/src/internet/cloudfileservice.h
@@ -34,7 +34,7 @@ class CloudFileService : public InternetService {
virtual bool has_credentials() const = 0;
virtual void Connect() = 0;
- private slots:
+ protected slots:
void ShowCoverManager();
void AddToPlaylist(QMimeData* mime);
void ShowSettingsDialog();
diff --git a/src/internet/dropboxauthenticator.cpp b/src/internet/dropboxauthenticator.cpp
index e31277a6a..fdd9730c3 100644
--- a/src/internet/dropboxauthenticator.cpp
+++ b/src/internet/dropboxauthenticator.cpp
@@ -35,7 +35,7 @@ DropboxAuthenticator::DropboxAuthenticator(QObject* parent)
network_(new NetworkAccessManager(this)) {
}
-void DropboxAuthenticator::StartAuthorisation(const QString& email) {
+void DropboxAuthenticator::StartAuthorisation() {
QUrl url(kRequestTokenEndpoint);
typedef QPair Param;
@@ -194,4 +194,5 @@ void DropboxAuthenticator::RequestAccountInformationFinished(QNetworkReply* repl
QJson::Parser parser;
QVariantMap response = parser.parse(reply).toMap();
name_ = response["display_name"].toString();
+ emit Finished();
}
diff --git a/src/internet/dropboxauthenticator.h b/src/internet/dropboxauthenticator.h
index ca1ddc96f..add3a45ef 100644
--- a/src/internet/dropboxauthenticator.h
+++ b/src/internet/dropboxauthenticator.h
@@ -11,7 +11,15 @@ class DropboxAuthenticator : public QObject {
Q_OBJECT
public:
explicit DropboxAuthenticator(QObject* parent = 0);
- void StartAuthorisation(const QString& email);
+ void StartAuthorisation();
+
+ const QString& access_token() const { return access_token_; }
+ const QString& access_token_secret() const { return access_token_secret_; }
+ const QString& uid() const { return uid_; }
+ const QString& name() const { return name_; }
+
+ signals:
+ void Finished();
private slots:
void RequestTokenFinished(QNetworkReply* reply);
diff --git a/src/internet/dropboxservice.cpp b/src/internet/dropboxservice.cpp
new file mode 100644
index 000000000..1e853f8ab
--- /dev/null
+++ b/src/internet/dropboxservice.cpp
@@ -0,0 +1,49 @@
+#include "dropboxservice.h"
+
+#include "internet/dropboxauthenticator.h"
+
+const char* DropboxService::kServiceName = "Dropbox";
+const char* DropboxService::kSettingsGroup = "Dropbox";
+
+namespace {
+
+static const char* kServiceId = "dropbox";
+
+} // namespace
+
+DropboxService::DropboxService(Application* app, InternetModel* parent)
+ : CloudFileService(
+ app, parent,
+ kServiceName, kServiceId,
+ QIcon(":/providers/dropbox.png"),
+ SettingsDialog::Page_Dropbox) {
+}
+
+bool DropboxService::has_credentials() const {
+ return !access_token_.isEmpty();
+}
+
+void DropboxService::Connect() {
+ if (!has_credentials()) {
+ DropboxAuthenticator* authenticator = new DropboxAuthenticator;
+ authenticator->StartAuthorisation();
+ NewClosure(authenticator, SIGNAL(Finished()),
+ this, SLOT(AuthenticationFinished(DropboxAuthenticator*)),
+ authenticator);
+ } else {
+ ShowSettingsDialog();
+ }
+}
+
+void DropboxService::AuthenticationFinished(DropboxAuthenticator* authenticator) {
+ authenticator->deleteLater();
+
+ QSettings settings;
+ settings.beginGroup(kSettingsGroup);
+
+ settings.setValue("access_token", authenticator->access_token());
+ settings.setValue("access_token_secret", authenticator->access_token_secret());
+ settings.setValue("name", authenticator->name());
+
+ emit Connected();
+}
diff --git a/src/internet/dropboxservice.h b/src/internet/dropboxservice.h
new file mode 100644
index 000000000..66947693e
--- /dev/null
+++ b/src/internet/dropboxservice.h
@@ -0,0 +1,34 @@
+#ifndef DROPBOXSERVICE_H
+#define DROPBOXSERVICE_H
+
+#include "internet/cloudfileservice.h"
+
+#include "core/tagreaderclient.h"
+
+class DropboxAuthenticator;
+
+class DropboxService : public CloudFileService {
+ Q_OBJECT
+ public:
+ DropboxService(Application* app, InternetModel* parent);
+
+ static const char* kServiceName;
+ static const char* kSettingsGroup;
+
+ virtual bool has_credentials() const;
+
+ signals:
+ void Connected();
+
+ public slots:
+ void Connect();
+
+ private slots:
+ void AuthenticationFinished(DropboxAuthenticator* authenticator);
+
+ private:
+ QString access_token_;
+ QString access_token_secret_;
+};
+
+#endif // DROPBOXSERVICE_H
diff --git a/src/internet/dropboxsettingspage.cpp b/src/internet/dropboxsettingspage.cpp
new file mode 100644
index 000000000..9b99d0857
--- /dev/null
+++ b/src/internet/dropboxsettingspage.cpp
@@ -0,0 +1,86 @@
+/* This file is part of Clementine.
+ Copyright 2012, David Sansome
+
+ 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 .
+*/
+
+#include "dropboxsettingspage.h"
+#include "ui_dropboxsettingspage.h"
+
+#include "core/application.h"
+#include "internet/dropboxservice.h"
+#include "internet/internetmodel.h"
+#include "ui/settingsdialog.h"
+
+DropboxSettingsPage::DropboxSettingsPage(SettingsDialog* parent)
+ : SettingsPage(parent),
+ ui_(new Ui::DropboxSettingsPage),
+ service_(dialog()->app()->internet_model()->Service())
+{
+ ui_->setupUi(this);
+ ui_->login_state->AddCredentialGroup(ui_->login_container);
+
+ connect(ui_->login_button, SIGNAL(clicked()), SLOT(LoginClicked()));
+ connect(ui_->login_state, SIGNAL(LogoutClicked()), SLOT(LogoutClicked()));
+ connect(service_, SIGNAL(Connected()), SLOT(Connected()));
+
+ dialog()->installEventFilter(this);
+}
+
+DropboxSettingsPage::~DropboxSettingsPage() {
+ delete ui_;
+}
+
+void DropboxSettingsPage::Load() {
+ QSettings s;
+ s.beginGroup(DropboxService::kSettingsGroup);
+
+ const QString user_email = s.value("user_email").toString();
+
+ if (!user_email.isEmpty()) {
+ ui_->login_state->SetLoggedIn(LoginStateWidget::LoggedIn, user_email);
+ }
+}
+
+void DropboxSettingsPage::Save() {
+ QSettings s;
+ s.beginGroup(DropboxService::kSettingsGroup);
+}
+
+void DropboxSettingsPage::LoginClicked() {
+ service_->Connect();
+ ui_->login_button->setEnabled(false);
+}
+
+bool DropboxSettingsPage::eventFilter(QObject* object, QEvent* event) {
+ if (object == dialog() && event->type() == QEvent::Enter) {
+ ui_->login_button->setEnabled(true);
+ return false;
+ }
+
+ return SettingsPage::eventFilter(object, event);
+}
+
+void DropboxSettingsPage::LogoutClicked() {
+ ui_->login_state->SetLoggedIn(LoginStateWidget::LoggedOut);
+}
+
+void DropboxSettingsPage::Connected() {
+ QSettings s;
+ s.beginGroup(DropboxService::kSettingsGroup);
+
+ const QString user_email = s.value("user_email").toString();
+
+ ui_->login_state->SetLoggedIn(LoginStateWidget::LoggedIn, user_email);
+}
diff --git a/src/internet/dropboxsettingspage.h b/src/internet/dropboxsettingspage.h
new file mode 100644
index 000000000..d4285fed3
--- /dev/null
+++ b/src/internet/dropboxsettingspage.h
@@ -0,0 +1,53 @@
+/* This file is part of Clementine.
+ Copyright 2012, David Sansome
+
+ 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 .
+*/
+
+#ifndef DROPBOXSETTINGSPAGE_H
+#define DROPBOXSETTINGSPAGE_H
+
+#include "ui/settingspage.h"
+
+#include
+#include
+
+class DropboxService;
+class Ui_DropboxSettingsPage;
+
+class DropboxSettingsPage : public SettingsPage {
+ Q_OBJECT
+
+public:
+ DropboxSettingsPage(SettingsDialog* parent = 0);
+ ~DropboxSettingsPage();
+
+ void Load();
+ void Save();
+
+ // QObject
+ bool eventFilter(QObject* object, QEvent* event);
+
+private slots:
+ void LoginClicked();
+ void LogoutClicked();
+ void Connected();
+
+private:
+ Ui_DropboxSettingsPage* ui_;
+
+ DropboxService* service_;
+};
+
+#endif // DROPBOXSETTINGSPAGE_H
diff --git a/src/internet/dropboxsettingspage.ui b/src/internet/dropboxsettingspage.ui
new file mode 100644
index 000000000..dbb7bf05a
--- /dev/null
+++ b/src/internet/dropboxsettingspage.ui
@@ -0,0 +1,110 @@
+
+
+ DropboxSettingsPage
+
+
+
+ 0
+ 0
+ 569
+ 491
+
+
+
+ Google Drive
+
+
+
+ :/providers/dropbox.png:/providers/dropbox.png
+
+
+ -
+
+
+ Clementine can play music that you have uploaded to Dropbox
+
+
+ true
+
+
+
+ -
+
+
+ -
+
+
+
+ 28
+
+
+ 0
+
+
+ 0
+
+
-
+
+
-
+
+
+ Login
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+ Clicking the Login button will open a web browser. You should return to Clementine after you have logged in.
+
+
+ true
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 357
+
+
+
+
+
+
+
+
+ LoginStateWidget
+ QWidget
+ widgets/loginstatewidget.h
+ 1
+
+
+
+
+
+
+
diff --git a/src/internet/internetmodel.cpp b/src/internet/internetmodel.cpp
index 771e97ff8..17f382a3e 100644
--- a/src/internet/internetmodel.cpp
+++ b/src/internet/internetmodel.cpp
@@ -48,6 +48,9 @@
#ifdef HAVE_UBUNTU_ONE
#include "ubuntuoneservice.h"
#endif
+#ifdef HAVE_DROPBOX
+ #include "dropboxservice.h"
+#endif
using smart_playlists::Generator;
using smart_playlists::GeneratorMimeData;
@@ -91,6 +94,9 @@ InternetModel::InternetModel(Application* app, QObject* parent)
#ifdef HAVE_UBUNTU_ONE
AddService(new UbuntuOneService(app, this));
#endif
+#ifdef HAVE_DROPBOX
+ AddService(new DropboxService(app, this));
+#endif
}
void InternetModel::AddService(InternetService *service) {
diff --git a/src/internet/ubuntuoneservice.cpp b/src/internet/ubuntuoneservice.cpp
index 544fc57af..dac0dd303 100644
--- a/src/internet/ubuntuoneservice.cpp
+++ b/src/internet/ubuntuoneservice.cpp
@@ -233,10 +233,6 @@ QUrl UbuntuOneService::GetStreamingUrlFromSongId(const QString& song_id) {
return url;
}
-void UbuntuOneService::ShowSettingsDialog() {
- app_->OpenSettingsDialogAtPage(SettingsDialog::Page_UbuntuOne);
-}
-
void UbuntuOneService::ShowCoverManager() {
if (!cover_manager_) {
cover_manager_.reset(new AlbumCoverManager(app_, library_backend_));
diff --git a/src/internet/ubuntuoneservice.h b/src/internet/ubuntuoneservice.h
index 6519a04d5..d3dab1451 100644
--- a/src/internet/ubuntuoneservice.h
+++ b/src/internet/ubuntuoneservice.h
@@ -23,7 +23,6 @@ class UbuntuOneService : public CloudFileService {
void FileListRequestFinished(QNetworkReply* reply);
void ReadTagsFinished(
TagReaderClient::ReplyType* reply, const QVariantMap& file, const QUrl& url);
- void ShowSettingsDialog();
void ShowCoverManager();
void AddToPlaylist(QMimeData* mime);
void VolumeListRequestFinished(QNetworkReply* reply);
diff --git a/src/main.cpp b/src/main.cpp
index 1061c3f30..61397080c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -110,8 +110,6 @@ using boost::scoped_ptr;
Q_IMPORT_PLUGIN(qsqlite)
#endif
-#include "internet/dropboxauthenticator.h"
-
void LoadTranslation(const QString& prefix, const QString& path,
const QString& override_language = QString()) {
#if QT_VERSION < 0x040700
@@ -449,9 +447,6 @@ int main(int argc, char *argv[]) {
}
#endif
- DropboxAuthenticator authenticator;
- authenticator.StartAuthorisation("foo");
-
// Window
MainWindow w(&app, tray_icon.get(), &osd);
#ifdef Q_OS_DARWIN
diff --git a/src/ui/settingsdialog.cpp b/src/ui/settingsdialog.cpp
index 97a74147b..9f51feb68 100644
--- a/src/ui/settingsdialog.cpp
+++ b/src/ui/settingsdialog.cpp
@@ -68,6 +68,10 @@
# include "internet/ubuntuonesettingspage.h"
#endif
+#ifdef HAVE_DROPBOX
+# include "internet/dropboxsettingspage.h"
+#endif
+
#include
#include
#include
@@ -156,6 +160,10 @@ SettingsDialog::SettingsDialog(Application* app, BackgroundStreams* streams, QWi
AddPage(Page_UbuntuOne, new UbuntuOneSettingsPage(this), providers);
#endif
+#ifdef HAVE_DROPBOX
+ AddPage(Page_Dropbox, new DropboxSettingsPage(this), providers);
+#endif
+
#ifdef HAVE_SPOTIFY
AddPage(Page_Spotify, new SpotifySettingsPage(this), providers);
#endif
diff --git a/src/ui/settingsdialog.h b/src/ui/settingsdialog.h
index 0e8d19498..643a225eb 100644
--- a/src/ui/settingsdialog.h
+++ b/src/ui/settingsdialog.h
@@ -78,6 +78,7 @@ public:
Page_Podcasts,
Page_GoogleDrive,
Page_UbuntuOne,
+ Page_Dropbox,
};
enum Role {