Add a Podcasts settings page and the start of some gpodder.net syncing

This commit is contained in:
David Sansome 2012-03-09 15:25:49 +00:00
parent b9e08bbfe6
commit 1abf059d16
15 changed files with 622 additions and 114 deletions

View File

@ -233,6 +233,7 @@ set(SOURCES
podcasts/addpodcastpage.cpp
podcasts/fixedopmlpage.cpp
podcasts/gpoddersearchpage.cpp
podcasts/gpoddersync.cpp
podcasts/gpoddertoptagsmodel.cpp
podcasts/gpoddertoptagspage.cpp
podcasts/itunessearchpage.cpp
@ -242,6 +243,7 @@ set(SOURCES
podcasts/podcastepisode.cpp
podcasts/podcastinfowidget.cpp
podcasts/podcastservice.cpp
podcasts/podcastsettingspage.cpp
podcasts/podcastparser.cpp
podcasts/podcastupdater.cpp
podcasts/podcasturlloader.cpp
@ -341,7 +343,6 @@ set(SOURCES
widgets/ratingwidget.cpp
widgets/renametablineedit.cpp
widgets/sliderwidget.cpp
widgets/spinbox.cpp
widgets/stickyslider.cpp
widgets/stretchheaderview.cpp
widgets/stylehelper.cpp
@ -487,6 +488,7 @@ set(HEADERS
podcasts/addpodcastpage.h
podcasts/fixedopmlpage.h
podcasts/gpoddersearchpage.h
podcasts/gpoddersync.h
podcasts/gpoddertoptagsmodel.h
podcasts/gpoddertoptagspage.h
podcasts/itunessearchpage.h
@ -494,6 +496,7 @@ set(HEADERS
podcasts/podcastdiscoverymodel.h
podcasts/podcastinfowidget.h
podcasts/podcastservice.h
podcasts/podcastsettingspage.h
podcasts/podcastupdater.h
podcasts/podcasturlloader.h
@ -580,7 +583,6 @@ set(HEADERS
widgets/ratingwidget.h
widgets/renametablineedit.h
widgets/sliderwidget.h
widgets/spinbox.h
widgets/stickyslider.h
widgets/stretchheaderview.h
widgets/trackslider.h
@ -620,6 +622,7 @@ set(UI
podcasts/gpoddersearchpage.ui
podcasts/itunessearchpage.ui
podcasts/podcastinfowidget.ui
podcasts/podcastsettingspage.ui
remote/remotesettingspage.ui

View File

@ -31,6 +31,7 @@
#include "library/librarybackend.h"
#include "playlist/playlistbackend.h"
#include "playlist/playlistmanager.h"
#include "podcasts/gpoddersync.h"
#include "podcasts/podcastbackend.h"
#include "podcasts/podcastupdater.h"
@ -51,7 +52,8 @@ Application::Application(QObject* parent)
internet_model_(NULL),
library_(NULL),
device_manager_(NULL),
podcast_updater_(NULL)
podcast_updater_(NULL),
gpodder_sync_(NULL)
{
tag_reader_client_ = new TagReaderClient(this);
MoveToNewThread(tag_reader_client_);
@ -80,7 +82,7 @@ Application::Application(QObject* parent)
library_ = new Library(this, this);
device_manager_ = new DeviceManager(this, this);
podcast_updater_ = new PodcastUpdater(this, this);
gpodder_sync_ = new GPodderSync(this, this);
library_->Init();
library_->StartThreads();

View File

@ -27,6 +27,7 @@ class CurrentArtLoader;
class Database;
class DeviceManager;
class GlobalSearch;
class GPodderSync;
class InternetModel;
class Library;
class LibraryBackend;
@ -63,6 +64,7 @@ public:
Library* library() const { return library_; }
DeviceManager* device_manager() const { return device_manager_; }
PodcastUpdater* podcast_updater() const { return podcast_updater_; }
GPodderSync* gpodder_sync() const { return gpodder_sync_; }
LibraryBackend* library_backend() const;
LibraryModel* library_model() const;
@ -95,6 +97,7 @@ private:
Library* library_;
DeviceManager* device_manager_;
PodcastUpdater* podcast_updater_;
GPodderSync* gpodder_sync_;
QList<QObject*> objects_in_threads_;
QList<QThread*> threads_;

View File

@ -480,6 +480,26 @@ int GetThreadId() {
#endif
}
bool IsLaptop() {
#ifdef Q_OS_WIN
LPSYSTEM_POWER_STATUS status;
if (!GetSystemPowerStatus(&status)) {
return false;
}
return !(status.BatteryFlag & 128); // 128 = no system battery
#endif
#ifdef Q_OS_LINUX
return !QDir("/proc/acpi/battery").entryList(QDir::Dirs | QDir::NoDotAndDotDot).isEmpty();
#endif
#ifdef Q_OS_MAC
Q_ASSERT("Fixit John" == 0);
return false;
#endif
}
} // namespace Utilities

View File

@ -130,6 +130,9 @@ namespace Utilities {
int SetThreadIOPriority(IoPriority priority);
int GetThreadId();
// Returns true if this machine has a battery.
bool IsLaptop();
}
class ScopedWCharArray {

View File

@ -0,0 +1,109 @@
/* This file is part of Clementine.
Copyright 2012, 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 "gpoddersync.h"
#include "core/application.h"
#include "core/closure.h"
#include "core/network.h"
#include "core/utilities.h"
#include <ApiRequest.h>
#include <QCoreApplication>
#include <QHostInfo>
#include <QNetworkAccessManager>
#include <QSettings>
const char* GPodderSync::kSettingsGroup = "Podcasts";
GPodderSync::GPodderSync(Application* app, QObject* parent)
: QObject(parent),
app_(app),
network_(new NetworkAccessManager(this))
{
ReloadSettings();
connect(app_, SIGNAL(SettingsChanged()), SLOT(ReloadSettings()));
}
GPodderSync::~GPodderSync() {
}
QString GPodderSync::DeviceId() {
return QString("%1-%2").arg(qApp->applicationName(),
QHostInfo::localHostName()).toLower();
}
QString GPodderSync::DefaultDeviceName() {
return tr("%1 on %2").arg(qApp->applicationName(),
QHostInfo::localHostName());
}
bool GPodderSync::is_logged_in() const {
return !username_.isEmpty() && !password_.isEmpty() && api_;
}
void GPodderSync::ReloadSettings() {
QSettings s;
s.beginGroup(kSettingsGroup);
username_ = s.value("gpodder_username").toString();
password_ = s.value("gpodder_password").toString();
if (!username_.isEmpty() && !password_.isEmpty()) {
api_.reset(new mygpo::ApiRequest(username_, password_, network_));
}
}
QNetworkReply* GPodderSync::Login(const QString& username, const QString& password,
const QString& device_name) {
api_.reset(new mygpo::ApiRequest(username, password, network_));
QNetworkReply* reply = api_->renameDevice(
username, DeviceId(), device_name,
Utilities::IsLaptop() ? mygpo::Device::LAPTOP
: mygpo::Device::DESKTOP);
NewClosure(reply, SIGNAL(finished()),
this, SLOT(LoginFinished(QNetworkReply*,QString,QString)),
reply, username, password);
return reply;
}
void GPodderSync::LoginFinished(QNetworkReply* reply,
const QString& username, const QString& password) {
reply->deleteLater();
if (reply->error() == QNetworkReply::NoError) {
username_ = username;
password_ = password;
QSettings s;
s.beginGroup(kSettingsGroup);
s.setValue("gpodder_username", username);
s.setValue("gpodder_password", password);
} else {
api_.reset();
}
}
void GPodderSync::Logout() {
QSettings s;
s.beginGroup(kSettingsGroup);
s.remove("gpodder_username");
s.remove("gpodder_password");
api_.reset();
}

View File

@ -0,0 +1,71 @@
/* This file is part of Clementine.
Copyright 2012, 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 GPODDERSYNC_H
#define GPODDERSYNC_H
#include <QObject>
#include <QScopedPointer>
class Application;
class QNetworkAccessManager;
class QNetworkReply;
namespace mygpo {
class ApiRequest;
}
class GPodderSync : public QObject {
Q_OBJECT
public:
GPodderSync(Application* app, QObject* parent = 0);
~GPodderSync();
static const char* kSettingsGroup;
static QString DefaultDeviceName();
static QString DeviceId();
bool is_logged_in() const;
// Tries to login using the given username and password. Also sets the
// device name and type on gpodder.net. You do NOT need to deleteLater()
// the QNetworkReply returned from this function.
// If login succeeds the username and password will be saved in QSettings.
QNetworkReply* Login(const QString& username, const QString& password,
const QString& device_name);
// Clears any saved username and password from QSettings.
void Logout();
private slots:
void ReloadSettings();
void LoginFinished(QNetworkReply* reply,
const QString& username, const QString& password);
private:
Application* app_;
QNetworkAccessManager* network_;
QScopedPointer<mygpo::ApiRequest> api_;
QString username_;
QString password_;
};
#endif // GPODDERSYNC_H

View File

@ -0,0 +1,107 @@
/* This file is part of Clementine.
Copyright 2012, 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 "gpoddersync.h"
#include "podcastsettingspage.h"
#include "ui_podcastsettingspage.h"
#include "core/application.h"
#include "core/closure.h"
#include "ui/settingsdialog.h"
#include <QNetworkReply>
#include <QSettings>
const char* PodcastSettingsPage::kSettingsGroup = "Podcasts";
PodcastSettingsPage::PodcastSettingsPage(SettingsDialog* dialog)
: SettingsPage(dialog),
ui_(new Ui_PodcastSettingsPage)
{
ui_->setupUi(this);
connect(ui_->login, SIGNAL(clicked()), SLOT(LoginClicked()));
connect(ui_->login_state, SIGNAL(LoginClicked()), SLOT(LoginClicked()));
connect(ui_->login_state, SIGNAL(LogoutClicked()), SLOT(LogoutClicked()));
ui_->login_state->AddCredentialField(ui_->username);
ui_->login_state->AddCredentialField(ui_->password);
ui_->login_state->AddCredentialField(ui_->device_name);
ui_->login_state->AddCredentialGroup(ui_->login_group);
ui_->check_interval->setItemData(0, 0); // manually
ui_->check_interval->setItemData(1, 10*60); // 10 minutes
ui_->check_interval->setItemData(2, 20*60); // 20 minutes
ui_->check_interval->setItemData(3, 30*60); // 30 minutes
ui_->check_interval->setItemData(4, 60*60); // 1 hour
ui_->check_interval->setItemData(5, 2*60*60); // 2 hours
ui_->check_interval->setItemData(6, 6*60*60); // 6 hours
ui_->check_interval->setItemData(7, 12*60*60); // 12 hours
}
PodcastSettingsPage::~PodcastSettingsPage() {
delete ui_;
}
void PodcastSettingsPage::Load() {
QSettings s;
s.beginGroup(kSettingsGroup);
const int update_interval = s.value("update_interval_secs", 0).toInt();
ui_->check_interval->setCurrentIndex(ui_->check_interval->findData(update_interval));
ui_->auto_download->setChecked(s.value("auto_download", false).toBool());
ui_->delete_after->setValue(s.value("delete_after", 0).toInt() / (24*60*60));
ui_->delete_unplayed->setChecked(s.value("delete_unplayed", false).toBool());
ui_->username->setText(s.value("gpodder_username").toString());
ui_->device_name->setText(s.value("gpodder_device_name", GPodderSync::DefaultDeviceName()).toString());
}
void PodcastSettingsPage::Save() {
QSettings s;
s.beginGroup(kSettingsGroup);
s.setValue("update_interval_secs",
ui_->check_interval->itemData(ui_->check_interval->currentIndex()));
s.setValue("auto_download", ui_->auto_download->isChecked());
s.setValue("delete_after", ui_->delete_after->value());
s.setValue("delete_unplayed", ui_->delete_unplayed->isChecked());
s.setValue("gpodder_device_name", ui_->device_name->text());
}
void PodcastSettingsPage::LoginClicked() {
ui_->login_state->SetLoggedIn(LoginStateWidget::LoginInProgress);
QNetworkReply* reply = dialog()->app()->gpodder_sync()->Login(
ui_->username->text(), ui_->password->text(), ui_->device_name->text());
NewClosure(reply, SIGNAL(finished()),
this, SLOT(LoginFinished(QNetworkReply*)),
reply);
}
void PodcastSettingsPage::LoginFinished(QNetworkReply* reply) {
const bool success = reply->error() == QNetworkReply::NoError;
ui_->login_state->SetLoggedIn(success ? LoginStateWidget::LoggedIn
: LoginStateWidget::LoggedOut,
ui_->username->text());
}
void PodcastSettingsPage::LogoutClicked() {
ui_->login_state->SetLoggedIn(LoginStateWidget::LoggedOut);
ui_->password->clear();
dialog()->app()->gpodder_sync()->Logout();
}

View File

@ -0,0 +1,48 @@
/* This file is part of Clementine.
Copyright 2012, 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 PODCASTSETTINGSPAGE_H
#define PODCASTSETTINGSPAGE_H
#include "ui/settingspage.h"
class Ui_PodcastSettingsPage;
class QNetworkReply;
class PodcastSettingsPage : public SettingsPage {
Q_OBJECT
public:
PodcastSettingsPage(SettingsDialog* dialog);
~PodcastSettingsPage();
static const char* kSettingsGroup;
void Load();
void Save();
private slots:
void LoginClicked();
void LoginFinished(QNetworkReply* reply);
void LogoutClicked();
private:
Ui_PodcastSettingsPage* ui_;
};
#endif // PODCASTSETTINGSPAGE_H

View File

@ -0,0 +1,237 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PodcastSettingsPage</class>
<widget class="QWidget" name="PodcastSettingsPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>616</width>
<height>656</height>
</rect>
</property>
<property name="windowTitle">
<string>Podcasts</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Updating</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Check for new episodes</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="check_interval">
<item>
<property name="text">
<string>Manually</string>
</property>
</item>
<item>
<property name="text">
<string>Every 10 minutes</string>
</property>
</item>
<item>
<property name="text">
<string>Every 20 minutes</string>
</property>
</item>
<item>
<property name="text">
<string>Every 30 minutes</string>
</property>
</item>
<item>
<property name="text">
<string>Every hour</string>
</property>
</item>
<item>
<property name="text">
<string>Every 2 hours</string>
</property>
</item>
<item>
<property name="text">
<string>Every 6 hours</string>
</property>
</item>
<item>
<property name="text">
<string>Every 12 hours</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="auto_download">
<property name="text">
<string>Download new episodes automatically</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Cleaning up</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Delete played episodes</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="delete_after">
<property name="specialValueText">
<string>manually</string>
</property>
<property name="suffix">
<string> days</string>
</property>
<property name="prefix">
<string>after </string>
</property>
<property name="maximum">
<number>30</number>
</property>
<property name="empty_text" stdset="0">
<string/>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="delete_unplayed">
<property name="text">
<string>Also delete unplayed episodes</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>gpodder.net</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Clementine can synchronize your subscription list with your other computers and podcast applications. &lt;a href=&quot;https://gpodder.net/register/&quot;&gt;Create an account&lt;/a&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="LoginStateWidget" name="login_state" native="true"/>
</item>
<item>
<widget class="QWidget" name="login_group" native="true">
<layout class="QFormLayout" name="formLayout_3">
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Username</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="username"/>
</item>
<item>
<widget class="QPushButton" name="login">
<property name="text">
<string>Sign in</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Password</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="password">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Device name</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="device_name"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>217</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>LoginStateWidget</class>
<extends>QWidget</extends>
<header>widgets/loginstatewidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>check_interval</tabstop>
<tabstop>auto_download</tabstop>
<tabstop>delete_after</tabstop>
<tabstop>delete_unplayed</tabstop>
<tabstop>username</tabstop>
<tabstop>password</tabstop>
<tabstop>device_name</tabstop>
<tabstop>login</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@ -1901,13 +1901,9 @@ void MainWindow::EnsureSettingsDialogCreated() {
if (settings_dialog_)
return;
settings_dialog_.reset(new SettingsDialog(background_streams_));
settings_dialog_->SetLibraryDirectoryModel(app_->library_model()->directory_model());
settings_dialog_->SetGstEngine(qobject_cast<GstEngine*>(app_->player()->engine()));
settings_dialog_.reset(new SettingsDialog(app_, background_streams_));
settings_dialog_->SetGlobalShortcutManager(global_shortcuts_);
settings_dialog_->SetGlobalSearch(app_->global_search());
settings_dialog_->SetSongInfoView(song_info_view_);
settings_dialog_->SetAppearance(app_->appearance());
// Settings
connect(settings_dialog_.get(), SIGNAL(accepted()), SLOT(ReloadAllSettings()));

View File

@ -26,9 +26,11 @@
#include "notificationssettingspage.h"
#include "mainwindow.h"
#include "settingsdialog.h"
#include "core/application.h"
#include "core/backgroundstreams.h"
#include "core/logging.h"
#include "core/networkproxyfactory.h"
#include "core/player.h"
#include "engines/enginebase.h"
#include "engines/gstengine.h"
#include "globalsearch/globalsearchsettingspage.h"
@ -37,6 +39,7 @@
#include "internet/magnatunesettingspage.h"
#include "library/librarysettingspage.h"
#include "playlist/playlistview.h"
#include "podcasts/podcastsettingspage.h"
#include "songinfo/songinfosettingspage.h"
#include "transcoder/transcodersettingspage.h"
#include "widgets/groupediconview.h"
@ -96,13 +99,15 @@ void SettingsItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem&
}
SettingsDialog::SettingsDialog(BackgroundStreams* streams, QWidget* parent)
SettingsDialog::SettingsDialog(Application* app, BackgroundStreams* streams, QWidget* parent)
: QDialog(parent),
model_(NULL),
gst_engine_(NULL),
app_(app),
model_(app_->library_model()->directory_model()),
gst_engine_(qobject_cast<GstEngine*>(app_->player()->engine())),
song_info_view_(NULL),
streams_(streams),
global_search_(NULL),
global_search_(app_->global_search()),
appearance_(app_->appearance()),
ui_(new Ui_SettingsDialog),
loading_settings_(false)
{
@ -149,6 +154,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_Podcasts, new PodcastSettingsPage(this), providers);
// List box
connect(ui_->list, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),

View File

@ -53,7 +53,7 @@ class SettingsDialog : public QDialog {
Q_OBJECT
public:
SettingsDialog(BackgroundStreams* streams, QWidget* parent = 0);
SettingsDialog(Application* app, BackgroundStreams* streams, QWidget* parent = 0);
~SettingsDialog();
enum Page {
@ -75,21 +75,19 @@ public:
Page_Transcoding,
Page_Remote,
Page_Wiimotedev,
Page_Podcasts,
};
enum Role {
Role_IsSeparator = Qt::UserRole
};
void SetLibraryDirectoryModel(LibraryDirectoryModel* model) { model_ = model; }
void SetGlobalShortcutManager(GlobalShortcuts* manager) { manager_ = manager; }
void SetGstEngine(const GstEngine* engine) { gst_engine_ = engine; }
void SetSongInfoView(SongInfoView* view) { song_info_view_ = view; }
void SetGlobalSearch(GlobalSearch* global_search) { global_search_ = global_search; }
void SetAppearance(Appearance* appearance) { appearance_ = appearance; }
bool is_loading_settings() const { return loading_settings_; }
Application* app() const { return app_; }
LibraryDirectoryModel* library_directory_model() const { return model_; }
GlobalShortcuts* global_shortcuts_manager() const { return manager_; }
const GstEngine* gst_engine() const { return gst_engine_; }
@ -125,6 +123,7 @@ private:
void AddPage(Page id, SettingsPage* page, QTreeWidgetItem* parent = NULL);
private:
Application* app_;
LibraryDirectoryModel* model_;
GlobalShortcuts* manager_;
const GstEngine* gst_engine_;

View File

@ -1,50 +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 "spinbox.h"
#include <QtDebug>
SpinBox::SpinBox(QWidget *parent)
: QSpinBox(parent),
empty_value_(0)
{
}
int SpinBox::valueFromText(const QString &text) const {
if (text.isEmpty())
return empty_value_;
return QSpinBox::valueFromText(text);
}
QString SpinBox::textFromValue(int val) const {
if (val == empty_value_)
return "";
return QSpinBox::textFromValue(val);
}
void SpinBox::fixup(QString &str) const {
if (str.isEmpty())
return;
QSpinBox::fixup(str);
}
QValidator::State SpinBox::validate(QString &input, int &pos) const {
if (input.isEmpty())
return QValidator::Acceptable;
return QSpinBox::validate(input, pos);
}

View File

@ -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/>.
*/
#ifndef SPINBOX_H
#define SPINBOX_H
#include <QSpinBox>
// A spinbox that accepts the empty string as input
class SpinBox : public QSpinBox {
Q_OBJECT
Q_PROPERTY(int empty_value READ empty_value WRITE set_empty_value);
public:
SpinBox(QWidget *parent = 0);
// The empty_value must still be within the range of the spinbox.
// Defaults to 0
int empty_value() const { return empty_value_; }
void set_empty_value(int v) { empty_value_ = v; }
protected:
int valueFromText(const QString &text) const;
QString textFromValue(int val) const;
void fixup(QString &str) const;
QValidator::State validate(QString &input, int &pos) const;
private:
int empty_value_;
};
#endif // SPINBOX_H