diff --git a/data/data.qrc b/data/data.qrc
index 1fc89205b..f3a51c48b 100644
--- a/data/data.qrc
+++ b/data/data.qrc
@@ -337,5 +337,6 @@
schema/schema-35.sql
schema/schema-36.sql
grooveshark-valicert-ca.pem
+ providers/subsonic.png
diff --git a/data/providers/subsonic.png b/data/providers/subsonic.png
new file mode 100644
index 000000000..d2d864787
Binary files /dev/null and b/data/providers/subsonic.png differ
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 54a53f28e..a265e0bef 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -169,6 +169,8 @@ set(SOURCES
internet/savedradio.cpp
internet/somafmservice.cpp
internet/somafmurlhandler.cpp
+ internet/subsonicservice.cpp
+ internet/subsonicsettingspage.cpp
library/groupbydialog.cpp
library/library.cpp
@@ -411,6 +413,8 @@ set(HEADERS
internet/savedradio.h
internet/somafmservice.h
internet/somafmurlhandler.h
+ internet/subsonicservice.h
+ internet/subsonicsettingspage.h
library/groupbydialog.h
library/library.h
@@ -559,6 +563,7 @@ set(UI
internet/magnatunedownloaddialog.ui
internet/magnatunesettingspage.ui
internet/spotifysettingspage.ui
+ internet/subsonicsettingspage.ui
library/groupbydialog.ui
library/libraryfilterwidget.ui
diff --git a/src/internet/internetmodel.cpp b/src/internet/internetmodel.cpp
index f26ab7d97..8786d36f3 100644
--- a/src/internet/internetmodel.cpp
+++ b/src/internet/internetmodel.cpp
@@ -25,6 +25,7 @@
#include "savedradio.h"
#include "somafmservice.h"
#include "groovesharkservice.h"
+#include "subsonicservice.h"
#include "core/logging.h"
#include "core/mergedproxymodel.h"
#include "smartplaylists/generatormimedata.h"
@@ -78,6 +79,7 @@ InternetModel::InternetModel(BackgroundThread* db_thread,
#ifdef HAVE_SPOTIFY
AddService(new SpotifyService(this));
#endif
+ AddService(new SubsonicService(this));
}
void InternetModel::AddService(InternetService *service) {
diff --git a/src/internet/subsonicservice.cpp b/src/internet/subsonicservice.cpp
new file mode 100644
index 000000000..bf8a6e5fe
--- /dev/null
+++ b/src/internet/subsonicservice.cpp
@@ -0,0 +1,47 @@
+#include "subsonicservice.h"
+#include "internetmodel.h"
+
+const char* SubsonicService::kServiceName = "Subsonic";
+const char* SubsonicService::kSettingsGroup = "Subsonic";
+const char* SubsonicService::kApiVersion = "1.6.0";
+const char* SubsonicService::kApiClientName = "Clementine";
+
+SubsonicService::SubsonicService(InternetModel *parent)
+ : InternetService(kServiceName, parent, parent)
+{
+}
+
+SubsonicService::~SubsonicService()
+{
+}
+
+QStandardItem* SubsonicService::CreateRootItem()
+{
+ root_ = new QStandardItem(QIcon(":providers/subsonic.png"), kServiceName);
+ root_->setData(true, InternetModel::Role_CanLazyLoad);
+ return root_;
+}
+
+void SubsonicService::LazyPopulate(QStandardItem *item)
+{
+
+}
+
+QModelIndex SubsonicService::GetCurrentIndex()
+{
+ return context_item_;
+}
+
+QUrl SubsonicService::BuildRequestUrl(const QString &view, const RequestOptions &options)
+{
+ QUrl url(server_url_ + "rest/" + view + ".view");
+ url.addQueryItem("v", kApiVersion);
+ url.addQueryItem("c", kApiClientName);
+ url.addQueryItem("u", username_);
+ url.addQueryItem("p", password_);
+ for (RequestOptions::const_iterator i = options.begin(); i != options.end(); ++i)
+ {
+ url.addQueryItem(i.key(), i.value());
+ }
+ return url;
+}
diff --git a/src/internet/subsonicservice.h b/src/internet/subsonicservice.h
new file mode 100644
index 000000000..f574f7741
--- /dev/null
+++ b/src/internet/subsonicservice.h
@@ -0,0 +1,39 @@
+#ifndef SUBSONICSERVICE_H
+#define SUBSONICSERVICE_H
+
+#include "internetservice.h"
+
+class SubsonicService : public InternetService
+{
+ Q_OBJECT
+ public:
+ SubsonicService(InternetModel *parent);
+ ~SubsonicService();
+
+ typedef QMap RequestOptions;
+
+ QStandardItem* CreateRootItem();
+ void LazyPopulate(QStandardItem *item);
+
+ static const char* kServiceName;
+ static const char* kSettingsGroup;
+ static const char* kApiVersion;
+ static const char* kApiClientName;
+
+ protected:
+ QModelIndex GetCurrentIndex();
+
+ private:
+ QUrl BuildRequestUrl(const QString &view, const RequestOptions &options);
+
+ QModelIndex context_item_;
+ QStandardItem* root_;
+
+ // Configuration
+ QString server_url_;
+ QString username_;
+ QString password_;
+
+};
+
+#endif // SUBSONICSERVICE_H
diff --git a/src/internet/subsonicsettingspage.cpp b/src/internet/subsonicsettingspage.cpp
new file mode 100644
index 000000000..d669f0df2
--- /dev/null
+++ b/src/internet/subsonicsettingspage.cpp
@@ -0,0 +1,39 @@
+#include "subsonicsettingspage.h"
+#include "ui_subsonicsettingspage.h"
+#include "subsonicservice.h"
+
+#include
+
+SubsonicSettingsPage::SubsonicSettingsPage(SettingsDialog *dialog)
+ : SettingsPage(dialog),
+ ui_(new Ui_SubsonicSettingsPage)
+{
+ ui_->setupUi(this);
+
+ setWindowIcon(QIcon(":/providers/subsonic.png"));
+}
+
+SubsonicSettingsPage::~SubsonicSettingsPage()
+{
+ delete ui_;
+}
+
+void SubsonicSettingsPage::Load()
+{
+ QSettings s;
+ s.beginGroup(SubsonicService::kSettingsGroup);
+
+ ui_->server->setText(s.value("server").toString());
+ ui_->username->setText(s.value("username").toString());
+ ui_->password->setText(s.value("password").toString());
+}
+
+void SubsonicSettingsPage::Save()
+{
+ QSettings s;
+ s.beginGroup(SubsonicService::kSettingsGroup);
+
+ s.setValue("server", ui_->server->text());
+ s.setValue("username", ui_->username->text());
+ s.setValue("password", ui_->password->text());
+}
diff --git a/src/internet/subsonicsettingspage.h b/src/internet/subsonicsettingspage.h
new file mode 100644
index 000000000..acc4f021c
--- /dev/null
+++ b/src/internet/subsonicsettingspage.h
@@ -0,0 +1,25 @@
+#ifndef SUBSONICSETTINGSPAGE_H
+#define SUBSONICSETTINGSPAGE_H
+
+#include "ui/settingspage.h"
+
+class Ui_SubsonicSettingsPage;
+class SubsonicService;
+
+class SubsonicSettingsPage : public SettingsPage
+{
+ Q_OBJECT
+
+ public:
+ SubsonicSettingsPage(SettingsDialog *dialog);
+ ~SubsonicSettingsPage();
+
+ void Load();
+ void Save();
+
+ private:
+ Ui_SubsonicSettingsPage* ui_;
+ SubsonicService* service_;
+};
+
+#endif // SUBSONICSETTINGSPAGE_H
diff --git a/src/internet/subsonicsettingspage.ui b/src/internet/subsonicsettingspage.ui
new file mode 100644
index 000000000..da5706c73
--- /dev/null
+++ b/src/internet/subsonicsettingspage.ui
@@ -0,0 +1,101 @@
+
+
+ SubsonicSettingsPage
+
+
+
+ 0
+ 0
+ 505
+ 219
+
+
+
+ Subsonic
+
+
+ -
+
+
+ -
+
+
+ Server details
+
+
+
-
+
+
+ Server
+
+
+
+ -
+
+
+ Username
+
+
+
+ -
+
+
+ Password
+
+
+
+ -
+
+
+ QLineEdit::Password
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ Login
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+ LoginStateWidget
+ QWidget
+ widgets/loginstatewidget.h
+ 1
+
+
+
+ server
+ username
+ password
+ login
+
+
+
+
diff --git a/src/ui/settingsdialog.cpp b/src/ui/settingsdialog.cpp
index 0e01a16a5..e5026b1f3 100644
--- a/src/ui/settingsdialog.cpp
+++ b/src/ui/settingsdialog.cpp
@@ -35,6 +35,7 @@
#include "internet/digitallyimportedsettingspage.h"
#include "internet/groovesharksettingspage.h"
#include "internet/magnatunesettingspage.h"
+#include "internet/subsonicsettingspage.h"
#include "library/librarysettingspage.h"
#include "playlist/playlistview.h"
#include "songinfo/songinfosettingspage.h"
@@ -149,6 +150,7 @@ SettingsDialog::SettingsDialog(BackgroundStreams* streams, QWidget* parent)
AddPage(Page_Magnatune, new MagnatuneSettingsPage(this), providers);
AddPage(Page_DigitallyImported, new DigitallyImportedSettingsPage(this), providers);
AddPage(Page_BackgroundStreams, new BackgroundStreamsSettingsPage(this), providers);
+ AddPage(Page_Subsonic, new SubsonicSettingsPage(this), providers);
// List box
connect(ui_->list, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
diff --git a/src/ui/settingsdialog.h b/src/ui/settingsdialog.h
index 237c5cbb9..f2b1947d8 100644
--- a/src/ui/settingsdialog.h
+++ b/src/ui/settingsdialog.h
@@ -75,6 +75,7 @@ public:
Page_Transcoding,
Page_Remote,
Page_Wiimotedev,
+ Page_Subsonic,
};
enum Role {