Browse Source

Allow styling with QSS stylesheets

adaptive-webui-19844
Prince Gupta 5 years ago
parent
commit
a24925c858
  1. 4
      src/app/application.cpp
  2. 21
      src/base/preferences.cpp
  3. 4
      src/base/preferences.h
  4. 2
      src/gui/CMakeLists.txt
  5. 2
      src/gui/gui.pri
  6. 44
      src/gui/optionsdialog.cpp
  7. 2
      src/gui/optionsdialog.h
  8. 45
      src/gui/optionsdialog.ui
  9. 84
      src/gui/uithememanager.cpp
  10. 52
      src/gui/uithememanager.h

4
src/app/application.cpp

@ -56,6 +56,7 @@
#endif // Q_OS_MAC #endif // Q_OS_MAC
#include "addnewtorrentdialog.h" #include "addnewtorrentdialog.h"
#include "gui/guiiconprovider.h" #include "gui/guiiconprovider.h"
#include "gui/uithememanager.h"
#include "gui/utils.h" #include "gui/utils.h"
#include "mainwindow.h" #include "mainwindow.h"
#include "shutdownconfirmdialog.h" #include "shutdownconfirmdialog.h"
@ -558,7 +559,9 @@ int Application::exec(const QStringList &params)
} }
#endif // DISABLE_WEBUI #endif // DISABLE_WEBUI
#else #else
UIThemeManager::initInstance();
m_window = new MainWindow; m_window = new MainWindow;
UIThemeManager::instance()->applyStyleSheet();
#endif // DISABLE_GUI #endif // DISABLE_GUI
m_running = true; m_running = true;
@ -727,6 +730,7 @@ void Application::cleanup()
shutdownBRDestroy(reinterpret_cast<HWND>(m_window->effectiveWinId())); shutdownBRDestroy(reinterpret_cast<HWND>(m_window->effectiveWinId()));
#endif // Q_OS_WIN #endif // Q_OS_WIN
delete m_window; delete m_window;
UIThemeManager::freeInstance();
} }
#endif // DISABLE_GUI #endif // DISABLE_GUI

21
src/base/preferences.cpp

@ -105,6 +105,27 @@ void Preferences::setLocale(const QString &locale)
setValue("Preferences/General/Locale", locale); setValue("Preferences/General/Locale", locale);
} }
bool Preferences::useCustomUITheme() const
{
return value("Preferences/General/UseCustomUITheme", false).toBool()
&& !customUIThemePath().isEmpty();
}
void Preferences::setUseCustomUITheme(const bool use)
{
setValue("Preferences/General/UseCustomUITheme", use);
}
QString Preferences::customUIThemePath() const
{
return value("Preferences/General/CustomUIThemePath").toString();
}
void Preferences::setCustomUIThemePath(const QString &path)
{
setValue("Preferences/General/CustomUIThemePath", path);
}
bool Preferences::deleteTorrentFilesAsDefault() const bool Preferences::deleteTorrentFilesAsDefault() const
{ {
return value("Preferences/General/DeleteTorrentsFilesAsDefault", false).toBool(); return value("Preferences/General/DeleteTorrentsFilesAsDefault", false).toBool();

4
src/base/preferences.h

@ -98,6 +98,10 @@ public:
// General options // General options
QString getLocale() const; QString getLocale() const;
void setLocale(const QString &locale); void setLocale(const QString &locale);
bool useCustomUITheme() const;
void setUseCustomUITheme(bool use);
QString customUIThemePath() const;
void setCustomUIThemePath(const QString &path);
bool deleteTorrentFilesAsDefault() const; bool deleteTorrentFilesAsDefault() const;
void setDeleteTorrentFilesAsDefault(bool del); void setDeleteTorrentFilesAsDefault(bool del);
bool confirmOnExit() const; bool confirmOnExit() const;

2
src/gui/CMakeLists.txt

@ -57,6 +57,7 @@ transferlistfilterswidget.h
transferlistmodel.h transferlistmodel.h
transferlistsortmodel.h transferlistsortmodel.h
transferlistwidget.h transferlistwidget.h
uithememanager.h
updownratiodialog.h updownratiodialog.h
utils.h utils.h
@ -102,6 +103,7 @@ transferlistfilterswidget.cpp
transferlistmodel.cpp transferlistmodel.cpp
transferlistsortmodel.cpp transferlistsortmodel.cpp
transferlistwidget.cpp transferlistwidget.cpp
uithememanager.cpp
updownratiodialog.cpp updownratiodialog.cpp
utils.cpp utils.cpp

2
src/gui/gui.pri

@ -62,6 +62,7 @@ HEADERS += \
$$PWD/transferlistmodel.h \ $$PWD/transferlistmodel.h \
$$PWD/transferlistsortmodel.h \ $$PWD/transferlistsortmodel.h \
$$PWD/transferlistwidget.h \ $$PWD/transferlistwidget.h \
$$PWD/uithememanager.h \
$$PWD/updownratiodialog.h \ $$PWD/updownratiodialog.h \
$$PWD/utils.h $$PWD/utils.h
@ -118,6 +119,7 @@ SOURCES += \
$$PWD/transferlistmodel.cpp \ $$PWD/transferlistmodel.cpp \
$$PWD/transferlistsortmodel.cpp \ $$PWD/transferlistsortmodel.cpp \
$$PWD/transferlistwidget.cpp \ $$PWD/transferlistwidget.cpp \
$$PWD/uithememanager.cpp \
$$PWD/updownratiodialog.cpp \ $$PWD/updownratiodialog.cpp \
$$PWD/utils.cpp $$PWD/utils.cpp

44
src/gui/optionsdialog.cpp

@ -175,6 +175,8 @@ OptionsDialog::OptionsDialog(QWidget *parent)
// Languages supported // Languages supported
initializeLanguageCombo(); initializeLanguageCombo();
initializeThemeCombo();
// Load week days (scheduler) // Load week days (scheduler)
m_ui->comboBoxScheduleDays->addItems(translatedWeekdayNames()); m_ui->comboBoxScheduleDays->addItems(translatedWeekdayNames());
@ -216,6 +218,7 @@ OptionsDialog::OptionsDialog(QWidget *parent)
// Apply button is activated when a value is changed // Apply button is activated when a value is changed
// General tab // General tab
connect(m_ui->comboI18n, qComboBoxCurrentIndexChanged, this, &ThisType::enableApplyButton); connect(m_ui->comboI18n, qComboBoxCurrentIndexChanged, this, &ThisType::enableApplyButton);
connect(m_ui->comboTheme, qComboBoxCurrentIndexChanged, this, &ThisType::enableApplyButton);
connect(m_ui->confirmDeletion, &QAbstractButton::toggled, this, &ThisType::enableApplyButton); connect(m_ui->confirmDeletion, &QAbstractButton::toggled, this, &ThisType::enableApplyButton);
connect(m_ui->checkAltRowColors, &QAbstractButton::toggled, this, &ThisType::enableApplyButton); connect(m_ui->checkAltRowColors, &QAbstractButton::toggled, this, &ThisType::enableApplyButton);
connect(m_ui->checkHideZero, &QAbstractButton::toggled, this, &ThisType::enableApplyButton); connect(m_ui->checkHideZero, &QAbstractButton::toggled, this, &ThisType::enableApplyButton);
@ -493,6 +496,38 @@ void OptionsDialog::initializeLanguageCombo()
} }
} }
void OptionsDialog::initializeThemeCombo()
{
m_ui->comboTheme->addItem(tr("Default"));
const QString customUIThemePath = Preferences::instance()->customUIThemePath();
if (!customUIThemePath.isEmpty())
m_ui->comboTheme->addItem(Utils::Fs::toNativePath(customUIThemePath));
m_ui->comboTheme->insertSeparator(m_ui->comboTheme->count());
m_ui->comboTheme->addItem(tr("Select..."));
m_ui->comboTheme->setCurrentIndex(Preferences::instance()->useCustomUITheme() ? 1 : 0);
connect(m_ui->comboTheme, qOverload<int>(&QComboBox::currentIndexChanged), this, [this](const int index)
{
if (index != (m_ui->comboTheme->count() - 1))
return;
m_uiThemeFilePath = QFileDialog::getOpenFileName(this, tr("Select qBittorrent theme file"), {}, tr("qBittorrent Theme File (*.qbtheme)"));
m_ui->comboTheme->blockSignals(true);
if (!m_uiThemeFilePath.isEmpty()) {
if (m_ui->comboTheme->count() == 3)
m_ui->comboTheme->insertItem(1, Utils::Fs::toNativePath(m_uiThemeFilePath));
else
m_ui->comboTheme->setItemText(1, Utils::Fs::toNativePath(m_uiThemeFilePath));
m_ui->comboTheme->setCurrentIndex(1);
}
else {
// don't leave "Select..." as current text
m_ui->comboTheme->setCurrentIndex(Preferences::instance()->useCustomUITheme() ? 1 : 0);
}
m_ui->comboTheme->blockSignals(false);
});
}
// Main destructor // Main destructor
OptionsDialog::~OptionsDialog() OptionsDialog::~OptionsDialog()
{ {
@ -563,6 +598,15 @@ void OptionsDialog::saveOptions()
// General preferences // General preferences
pref->setLocale(locale); pref->setLocale(locale);
if (!m_uiThemeFilePath.isEmpty()
&& (m_ui->comboTheme->currentIndex() == 1)) {
// only change if current selection is still new m_uiThemeFilePath
pref->setCustomUIThemePath(m_uiThemeFilePath);
m_uiThemeFilePath.clear();
}
pref->setUseCustomUITheme(m_ui->comboTheme->currentIndex() == 1);
pref->setConfirmTorrentDeletion(m_ui->confirmDeletion->isChecked()); pref->setConfirmTorrentDeletion(m_ui->confirmDeletion->isChecked());
pref->setAlternatingRowColors(m_ui->checkAltRowColors->isChecked()); pref->setAlternatingRowColors(m_ui->checkAltRowColors->isChecked());
pref->setHideZeroValues(m_ui->checkHideZero->isChecked()); pref->setHideZeroValues(m_ui->checkHideZero->isChecked());

2
src/gui/optionsdialog.h

@ -117,6 +117,7 @@ private:
void saveOptions(); void saveOptions();
void loadOptions(); void loadOptions();
void initializeLanguageCombo(); void initializeLanguageCombo();
void initializeThemeCombo();
static QString languageToLocalizedString(const QLocale &locale); static QString languageToLocalizedString(const QLocale &locale);
// General options // General options
QString getLocale() const; QString getLocale() const;
@ -183,6 +184,7 @@ private:
AdvancedSettings *m_advancedSettings; AdvancedSettings *m_advancedSettings;
QList<QString> m_addedScanDirs; QList<QString> m_addedScanDirs;
QList<QString> m_removedScanDirs; QList<QString> m_removedScanDirs;
QString m_uiThemeFilePath;
}; };
#endif // OPTIONSDIALOG_H #endif // OPTIONSDIALOG_H

45
src/gui/optionsdialog.ui

@ -130,19 +130,17 @@
<item> <item>
<widget class="QGroupBox" name="UISettingsBox"> <widget class="QGroupBox" name="UISettingsBox">
<property name="title"> <property name="title">
<string>Language</string> <string>Interface</string>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_8"> <layout class="QGridLayout" name="gridLayout_81">
<item> <item row="0" column="0">
<layout class="QHBoxLayout">
<item>
<widget class="QLabel" name="label_9"> <widget class="QLabel" name="label_9">
<property name="text"> <property name="text">
<string>User Interface Language:</string> <string>Language:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item row="0" column="1">
<widget class="QComboBox" name="comboI18n"> <widget class="QComboBox" name="comboI18n">
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
@ -158,7 +156,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item> <item row="0" column="2">
<widget class="QLabel" name="lbl_i18n_info_2"> <widget class="QLabel" name="lbl_i18n_info_2">
<property name="font"> <property name="font">
<font> <font>
@ -173,20 +171,43 @@
</property> </property>
</widget> </widget>
</item> </item>
<item> <item row="0" column="3">
<spacer> <spacer name="horizontalSpacer_111">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="sizeHint" stdset="0"> <property name="sizeHint" stdset="0">
<size> <size>
<width>40</width> <width>200</width>
<height>20</height> <height>20</height>
</size> </size>
</property> </property>
</spacer> </spacer>
</item> </item>
</layout> <item row="1" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Theme:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="comboTheme"/>
</item>
<item row="1" column="2">
<widget class="QLabel" name="lbl_i18n_info_3">
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="text">
<string>(Requires restart)</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>

84
src/gui/uithememanager.cpp

@ -0,0 +1,84 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2019 Prince Gupta <jagannatharjun11@gmail.com>
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If
* you modify file(s), you may extend this exception to your version of the
* file(s), but you are not obligated to do so. If you do not wish to do so,
* delete this exception statement from your version.
*/
#include "uithememanager.h"
#include <QApplication>
#include <QFile>
#include <QResource>
#include "base/logger.h"
#include "base/preferences.h"
UIThemeManager *UIThemeManager::m_instance = nullptr;
void UIThemeManager::freeInstance()
{
if (m_instance) {
delete m_instance;
m_instance = nullptr;
}
}
void UIThemeManager::initInstance()
{
if (!m_instance)
m_instance = new UIThemeManager;
}
UIThemeManager::UIThemeManager()
{
const Preferences *const pref = Preferences::instance();
if (pref->useCustomUITheme()
&& !QResource::registerResource(pref->customUIThemePath(), "/uitheme"))
LogMsg(tr("Failed to load UI theme from file: \"%1\"").arg(pref->customUIThemePath()), Log::WARNING);
}
UIThemeManager *UIThemeManager::instance()
{
return m_instance;
}
void UIThemeManager::applyStyleSheet() const
{
if (!Preferences::instance()->useCustomUITheme()) {
qApp->setStyleSheet({});
return;
}
QFile qssFile(":uitheme/stylesheet.qss");
if (!qssFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
qApp->setStyleSheet({});
LogMsg(tr("Couldn't apply theme stylesheet. stylesheet.qss couldn't be opened. Reason: %1").arg(qssFile.errorString())
, Log::WARNING);
return;
}
qApp->setStyleSheet(qssFile.readAll());
}

52
src/gui/uithememanager.h

@ -0,0 +1,52 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2019 Prince Gupta <jagannatharjun11@gmail.com>
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* In addition, as a special exception, the copyright holders give permission to
* link this program with the OpenSSL project's "OpenSSL" library (or with
* modified versions of it that use the same license as the "OpenSSL" library),
* and distribute the linked executables. You must obey the GNU General Public
* License in all respects for all of the code used other than "OpenSSL". If
* you modify file(s), you may extend this exception to your version of the
* file(s), but you are not obligated to do so. If you do not wish to do so,
* delete this exception statement from your version.
*/
#pragma once
#include <QObject>
class QString;
class UIThemeManager : public QObject
{
Q_OBJECT
Q_DISABLE_COPY(UIThemeManager)
public:
static void initInstance();
static void freeInstance();
static UIThemeManager *instance();
void applyStyleSheet() const;
private:
UIThemeManager(); // singleton class
static UIThemeManager *m_instance;
};
Loading…
Cancel
Save