Commit 13c4eee2 authored by Mikhail Zolotukhin's avatar Mikhail Zolotukhin
Browse files

Refactor GTK KCM code

Summary:
This diff introduces purely cosmetic changes.

1. KCM now compiled with no signals/slot keywords to avoid clash with
   gtk
2. Remove linking of XCursors library, because it is no longer needed
3. Replace some for-cycles with range-based ones
4. Wrap some string literals with QStringLiteral
5. Rearrange include headers
5. Some other changes to better match code style

Test Plan: Check, if there is no regressions

Reviewers: apol

Reviewed By: apol

Subscribers: plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D25872
parent 338ce246
......@@ -50,9 +50,29 @@ ki18n_wrap_ui(kcm_SRCS
src/ui/dialog_installer.ui
src/ui/dialog_uninstaller.ui
)
add_library(kcm_kdegtkconfig MODULE ${kcm_SRCS})
target_compile_definitions(kcm_kdegtkconfig PRIVATE -DPROJECT_VERSION="${PROJECT_VERSION}")
target_link_libraries(kcm_kdegtkconfig ${X11_Xcursor_LIB} ${GIO2_LIBRARY} ${GLIB2_LIBRARY} ${GTK3_LIBRARY} ${GOBJECT2_LIBRARY} Qt5::Svg KF5::ConfigCore KF5::I18n KF5::KIOWidgets KF5::NewStuff KF5::Archive KF5::NewStuff KF5::ConfigWidgets KF5::IconThemes)
target_compile_definitions(kcm_kdegtkconfig
PRIVATE
-DPROJECT_VERSION="${PROJECT_VERSION}"
-DQT_NO_SIGNALS_SLOTS_KEYWORDS
)
target_link_libraries(kcm_kdegtkconfig
${GIO2_LIBRARY}
${GLIB2_LIBRARY}
${GTK3_LIBRARY}
${GOBJECT2_LIBRARY}
Qt5::Svg
KF5::ConfigCore
KF5::I18n
KF5::KIOWidgets
KF5::NewStuff
KF5::Archive
KF5::ConfigWidgets
KF5::IconThemes
)
kcoreaddons_desktop_to_json(kcm_kdegtkconfig kde-gtk-config.desktop)
......
......@@ -19,48 +19,52 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "abstractappearance.h"
#include <qregexp.h>
#include <QDir>
#include <QDebug>
#include <QRegExp>
#include "abstractappearance.h"
static bool isTrue(const QString& value)
void AbstractAppearance::setTheme(const QString& name)
{
return value == "1" || value == "true";
m_settings["theme"] = name;
}
//SETTERS
void AbstractAppearance::setTheme(const QString& name) { m_settings["theme"] = name;}
QString AbstractAppearance::getTheme() const
{
return m_settings["theme"];
}
// GETTERS
QString AbstractAppearance::getTheme() const { return m_settings["theme"];}
QString AbstractAppearance::getThemeGtk3() const { return m_settings["themegtk3"]; }
QString AbstractAppearance::getThemeGtk3() const
{
return m_settings["themegtk3"];
}
QRegExp valueRx(" *([a-zA-Z\\-_]+) *= *\"?([^\"\\n]+)\"?", Qt::CaseSensitive, QRegExp::RegExp2);
QMap<QString,QString> AbstractAppearance::readSettingsTuples(QIODevice* device)
{
static const QRegExp valueRx(" *([a-zA-Z\\-_]+) *= *\"?([^\"\\n]+)\"?", Qt::CaseSensitive, QRegExp::RegExp2);
QMap<QString, QString> ret;
QTextStream flow(device);
for(; !flow.atEnd() ;) {
while (!flow.atEnd()) {
QString line = flow.readLine();
int idxComment = line.indexOf('#');
if(idxComment>=0)
if (idxComment >= 0) {
line = line.left(idxComment).simplified();
}
if(valueRx.exactMatch(line))
if (valueRx.exactMatch(line)) {
ret[valueRx.cap(1)] = valueRx.cap(2);
else if(line.startsWith("include \"")) {
} else if (line.startsWith("include \"")) {
QString filename = line.mid(9);
filename.chop(1);
// qDebug() << "including: " << filename;
QFile f(filename);
if(f.open(QFile::Text|QFile::ReadOnly)) {
if (f.open(QFile::Text | QFile::ReadOnly)) {
ret.unite(readSettingsTuples(&f));
} else
} else {
qWarning() << "couldn't include " << filename;
}
}
// else if(!line.isEmpty())
// qWarning() << "misinterpreted line" << line;
}
return ret;
}
......@@ -70,8 +74,9 @@ QStringList AbstractAppearance::installedThemesNames() const
QStringList themes = installedThemes();
QStringList ret;
foreach(const QString& theme, themes)
for(const QString &theme : themes) {
ret += QDir(theme).dirName();
}
return ret;
}
......
......@@ -32,21 +32,21 @@ class AbstractAppearance
virtual ~AbstractAppearance() {}
virtual bool loadSettings() = 0;
virtual bool saveSettings() const = 0;
virtual bool loadSettings(const QString& path) = 0;
virtual bool saveSettings(const QString& path) const = 0;
virtual bool loadSettings(const QString &path) = 0;
virtual bool saveSettings(const QString &path) const = 0;
/** @returns the installed themes' paths*/
virtual QStringList installedThemes() const = 0;
void setTheme(const QString& name);
void setTheme(const QString &name);
QString getTheme() const;
QString getThemeGtk3() const;
QStringList installedThemesNames() const;
bool hasProperty(const QString& key) const;
bool hasProperty(const QString &key) const;
static QMap<QString,QString> readSettingsTuples(QIODevice* device);
static QMap<QString, QString> readSettingsTuples(QIODevice *device);
protected:
QMap<QString, QString> m_settings;
......
......@@ -20,7 +20,6 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "appearancegtk2.h"
#include <QFile>
#include <QStringList>
#include <QDir>
......@@ -28,35 +27,38 @@
#include <QDebug>
#include <QProcess>
#include <QStandardPaths>
#include <config.h>
#include <QRegularExpression>
bool AppearanceGTK2::loadSettingsPrivate(const QString& path)
#include "config.h"
#include "appearancegtk2.h"
bool AppearanceGTK2::loadSettingsPrivate(const QString &path)
{
QFile configFile(path);
if (!configFile.open(QIODevice::ReadOnly | QIODevice::Text))
if (!configFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
return false;
}
const QMap<QString, QString> foundSettings = readSettingsTuples(&configFile);
for(auto it = foundSettings.constBegin(), itEnd = foundSettings.constEnd(); it!=itEnd; ++it) {
if (it.key() == "gtk-theme-name")
m_settings["theme"] = *it;
if (it.key() == QStringLiteral("gtk-theme-name")) {
m_settings[QStringLiteral("theme")] = *it;
}
}
return true;
}
QString AppearanceGTK2::themesGtkrcFile(const QString& themeName) const
QString AppearanceGTK2::themesGtkrcFile(const QString &themeName) const
{
QStringList themes=installedThemes();
themes=themes.filter(QRegExp("/"+themeName+"/?$"));
if(themes.size()==1) {
QStringList themes = installedThemes();
themes = themes.filter(QRegExp("/" + themeName + "/?$"));
if (themes.size() == 1) {
QDirIterator it(themes.first(), QDirIterator::Subdirectories);
while(it.hasNext()) {
it.next();
if(it.fileName()=="gtkrc") {
// qDebug() << "\tgtkrc file found at : " << it.filePath();
if(it.fileName() == "gtkrc") {
return it.filePath();
}
}
......@@ -65,12 +67,12 @@ QString AppearanceGTK2::themesGtkrcFile(const QString& themeName) const
return QString();
}
bool AppearanceGTK2::saveSettingsPrivate(const QString& gtkrcFile) const
bool AppearanceGTK2::saveSettingsPrivate(const QString &gtkrcFile) const
{
QFile gtkrc{gtkrcFile};
QFile gtkrc(gtkrcFile);
if (gtkrc.open(QIODevice::ReadWrite | QIODevice::Text)) {
QString fileContents{gtkrc.readAll()};
QString fileContents = gtkrc.readAll();
modifyGtkrcContents(fileContents);
......@@ -84,18 +86,18 @@ bool AppearanceGTK2::saveSettingsPrivate(const QString& gtkrcFile) const
return true;
} else {
qWarning() << "There was unable to write the .gtkrc-2.0 file";
qWarning() << "Unable to write the .gtkrc-2.0 file";
return false;
}
}
void AppearanceGTK2::modifyGtkrcContents(QString& fileContents) const
void AppearanceGTK2::modifyGtkrcContents(QString &fileContents) const
{
modifyGtkrcProperty("gtk-theme-name", m_settings["theme"], fileContents);
removeGtkrcLegacyContents(fileContents);
}
void AppearanceGTK2::modifyGtkrcProperty(const QString& propertyName, const QString& newValue, QString& fileContents) const
void AppearanceGTK2::modifyGtkrcProperty(const QString &propertyName, const QString &newValue, QString &fileContents) const
{
const QRegularExpression regExp{propertyName + "=[^\n]*($|\n)"};
......@@ -143,34 +145,35 @@ void AppearanceGTK2::removeGtkrcLegacyContents(QString &fileContents) const
void AppearanceGTK2::reset()
{
m_settings = QMap<QString, QString> {};
m_settings.clear();
}
QString AppearanceGTK2::defaultConfigFile() const
{
return QDir::homePath()+"/.gtkrc-2.0";
return QDir::homePath() + QStringLiteral("/.gtkrc-2.0");
}
QStringList AppearanceGTK2::installedThemes() const
{
QFileInfoList availableThemes;
foreach(const QString& themesDir, QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, "themes", QStandardPaths::LocateDirectory)) {
for (const QString& themesDir : QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, "themes", QStandardPaths::LocateDirectory)) {
QDir root(themesDir);
availableThemes += root.entryInfoList(QDir::NoDotAndDotDot|QDir::AllDirs);
availableThemes += root.entryInfoList(QDir::NoDotAndDotDot | QDir::AllDirs);
}
//Check if there are themes installed by the user
QDir user(QDir::homePath()+"/.themes");
availableThemes += user.entryInfoList(QDir::NoDotAndDotDot|QDir::AllDirs);
// Check if there are themes installed by the user
QDir user(QDir::homePath() + "/.themes");
availableThemes += user.entryInfoList(QDir::NoDotAndDotDot | QDir::AllDirs);
//we just want actual themes
// We just want actual themes
QStringList paths;
for(QFileInfoList::const_iterator it=availableThemes.constBegin(); it!=availableThemes.constEnd(); ++it) {
bool hasGtkrc = QDir(it->filePath()).exists("gtk-2.0");
for (const QFileInfo &it : availableThemes) {
bool hasGtkrc = QDir(it.filePath()).exists("gtk-2.0");
//If it doesn't exist, we don't want it on the list
if(hasGtkrc)
paths += it->filePath();
// If it doesn't exist, we don't want it on the list
if (hasGtkrc) {
paths += it.filePath();
}
}
return paths;
......@@ -180,7 +183,7 @@ bool AppearanceGTK2::loadSettings()
{
reset();
bool b = loadSettingsPrivate("/etc/gtk-2.0/gtkrc");
bool b = loadSettingsPrivate(QStringLiteral("/etc/gtk-2.0/gtkrc"));
b |= loadSettingsPrivate(defaultConfigFile());
return b;
}
......@@ -190,13 +193,13 @@ bool AppearanceGTK2::saveSettings() const
return saveSettings(defaultConfigFile());
}
bool AppearanceGTK2::loadSettings(const QString& gtkrcFile)
bool AppearanceGTK2::loadSettings(const QString &gtkrcFile)
{
reset();
return loadSettingsPrivate(gtkrcFile);
}
bool AppearanceGTK2::saveSettings(const QString& gtkrcFile) const
bool AppearanceGTK2::saveSettings(const QString &gtkrcFile) const
{
return saveSettingsPrivate(gtkrcFile);
}
......@@ -27,22 +27,22 @@
class AppearanceGTK2 : public AbstractAppearance
{
bool loadSettings(const QString& path) override;
bool saveSettings(const QString& path) const override;
bool loadSettings(const QString &path) override;
bool saveSettings(const QString &path) const override;
bool loadSettings() override;
bool saveSettings() const override;
QStringList installedThemes() const override;
QString themesGtkrcFile(const QString& themeName) const;
QString themesGtkrcFile(const QString &themeName) const;
private:
void reset();
QString defaultConfigFile() const;
bool loadSettingsPrivate(const QString& path);
bool saveSettingsPrivate(const QString& path) const;
void modifyGtkrcContents(QString& fileContents) const;
void modifyGtkrcProperty(const QString& propertyName, const QString& newValue, QString& fileContents) const;
void removeGtkrcLegacyContents(QString& fileContents) const;
bool loadSettingsPrivate(const QString &path);
bool saveSettingsPrivate(const QString &path) const;
void modifyGtkrcContents(QString &fileContents) const;
void modifyGtkrcProperty(const QString &propertyName, const QString &newValue, QString &fileContents) const;
void removeGtkrcLegacyContents(QString &fileContents) const;
};
#endif // APPEARANCEGTK2_H
......@@ -20,40 +20,40 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "appearancegtk3.h"
#include <QFile>
#include <QDir>
#include <QDebug>
#include <QStandardPaths>
#include <KSharedConfig>
#include <KConfigGroup>
#undef signals
#include <gio/gio.h>
#include <gtk/gtk.h>
#define signals Q_SIGNALS
#include "appearancegtk3.h"
QStringList AppearanceGTK3::installedThemes() const
{
QFileInfoList availableThemes;
foreach(const QString& themesDir, QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, "themes", QStandardPaths::LocateDirectory)) {
for (const QString& themesDir : QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("themes"), QStandardPaths::LocateDirectory)) {
QDir root(themesDir);
availableThemes += root.entryInfoList(QDir::NoDotAndDotDot|QDir::AllDirs);
availableThemes += root.entryInfoList(QDir::NoDotAndDotDot | QDir::AllDirs);
}
//Also show the user-installed themes
QDir user(QDir::homePath()+"/.themes");
availableThemes += user.entryInfoList(QDir::NoDotAndDotDot|QDir::AllDirs);
// Also show the user-installed themes
QDir user(QDir::homePath() + QStringLiteral("/.themes"));
availableThemes += user.entryInfoList(QDir::NoDotAndDotDot | QDir::AllDirs);
//we just want actual themes
// We just want actual themes
QStringList themes;
// Check that the theme contains a gtk-3.* subdirectory
QStringList gtk3SubdirPattern{QStringLiteral("gtk-3.*")};
for(QFileInfoList::const_iterator it=availableThemes.constBegin(); it!=availableThemes.constEnd(); ++it) {
QDir themeDir(it->filePath());
QStringList gtk3SubdirPattern(QStringLiteral("gtk-3.*"));
for (const QFileInfo &it : availableThemes) {
QDir themeDir(it.filePath());
if(!themeDir.entryList(gtk3SubdirPattern, QDir::Dirs).isEmpty())
themes += it->filePath();
themes += it.filePath();
}
return themes;
......@@ -61,10 +61,10 @@ QStringList AppearanceGTK3::installedThemes() const
bool AppearanceGTK3::saveSettings(const KSharedConfig::Ptr& file) const
{
KConfigGroup group(file, "Settings");
KConfigGroup group(file, QStringLiteral("Settings"));
group.writeEntry("gtk-theme-name", m_settings["theme"]);
group.writeEntry("gtk-application-prefer-dark-theme", m_settings["application_prefer_dark_theme"]);
group.writeEntry(QStringLiteral("gtk-theme-name"), m_settings["theme"]);
group.writeEntry(QStringLiteral("gtk-application-prefer-dark-theme"), m_settings[QStringLiteral("application_prefer_dark_theme")]);
const bool sync = group.sync();
Q_ASSERT(sync);
......@@ -73,24 +73,25 @@ bool AppearanceGTK3::saveSettings(const KSharedConfig::Ptr& file) const
bool AppearanceGTK3::loadSettings(const KSharedConfig::Ptr& file)
{
KConfigGroup group(file, "Settings");
KConfigGroup group(file, QStringLiteral("Settings"));
if (!file || !group.isValid()) {
qWarning() << "Cannot open the GTK3 config file" << file;
qWarning() << QStringLiteral("Cannot open the GTK3 config file") << file;
return false;
}
m_settings = QMap<QString, QString> {
{"application_prefer_dark_theme", "false"}
{QStringLiteral("application_prefer_dark_theme"), QStringLiteral("false")}
};
m_settings["theme"] = group.readEntry("gtk-theme-name");
m_settings["application_prefer_dark_theme"] = group.readEntry("gtk-application-prefer-dark-theme");
m_settings[QStringLiteral("theme")] = group.readEntry(QStringLiteral("gtk-theme-name"));
m_settings[QStringLiteral("application_prefer_dark_theme")] = group.readEntry(QStringLiteral("gtk-application-prefer-dark-theme"));
for(auto it = m_settings.begin(); it != m_settings.end(); ) {
if (it.value().isEmpty())
if (it.value().isEmpty()) {
it = m_settings.erase(it);
else
} else {
++it;
}
}
return true;
}
......@@ -103,20 +104,21 @@ QString AppearanceGTK3::configFileName() const
QString AppearanceGTK3::defaultConfigFile() const
{
QString root = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
if(root.isEmpty())
root = QFileInfo(QDir::home(), ".config").absoluteFilePath();
if(root.isEmpty()) {
root = QFileInfo(QDir::home(), QStringLiteral(".config")).absoluteFilePath();
}
return root + '/' + configFileName();
}
bool AppearanceGTK3::getApplicationPreferDarkTheme() const
{
return m_settings["application_prefer_dark_theme"] == "1" || m_settings["application_prefer_dark_theme"] == "true";
return m_settings[QStringLiteral("application_prefer_dark_theme")] == QStringLiteral("1") || m_settings[QStringLiteral("application_prefer_dark_theme")] == QStringLiteral("true");
}
void AppearanceGTK3::setApplicationPreferDarkTheme(const bool& enable)
void AppearanceGTK3::setApplicationPreferDarkTheme(bool enable)
{
m_settings["application_prefer_dark_theme"] = enable ? "true" : "false";
m_settings[QStringLiteral("application_prefer_dark_theme")] = enable ? QStringLiteral("true") : QStringLiteral("false");
}
bool AppearanceGTK3::saveSettings(const QString& file) const
......@@ -143,8 +145,6 @@ bool AppearanceGTK3::saveSettings() const
// We should maybe use GSettings everywhere in future, but at this moment we
// need this to have this configuration available in sandboxed applications which
// is only possible through dconf
gtk_init(nullptr, nullptr);
g_autoptr(GSettings) gsettings = g_settings_new("org.gnome.desktop.interface");
g_settings_set_string(gsettings, "gtk-theme", m_settings["theme"].toUtf8().constData());
......
......@@ -24,6 +24,7 @@
#define APPEARANCEGTK3_H
#include <KSharedConfig>
#include "abstractappearance.h"
class AppearanceGTK3 : public AbstractAppearance
......@@ -33,16 +34,16 @@ public:
QStringList installedThemes() const override;
bool saveSettings() const override;
bool loadSettings() override;
bool saveSettings(const QString& file) const override;
bool loadSettings(const QString& path) override;
bool saveSettings(const QString &file) const override;
bool loadSettings(const QString &path) override;
bool getApplicationPreferDarkTheme() const;
void setApplicationPreferDarkTheme(const bool& enable);
void setApplicationPreferDarkTheme(bool enable);
private:
QString defaultConfigFile() const;
QString configFileName() const;
bool saveSettings(const KSharedConfig::Ptr& file) const;
bool loadSettings(const KSharedConfig::Ptr& file);
bool saveSettings(const KSharedConfig::Ptr &file) const;
bool loadSettings(const KSharedConfig::Ptr &file);
};
#endif // APPEARANCEGTK3_H
......@@ -20,9 +20,10 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "appearencegtk.h"
#include <QDirIterator>
#include "abstractappearance.h"
#include "appearencegtk.h"
#include "appearancegtk2.h"
#include "appearancegtk3.h"
......@@ -37,34 +38,52 @@ AppearenceGTK::~AppearenceGTK()
qDeleteAll(m_app);
}
QString AppearenceGTK::getTheme() const { return gtk2Appearance()->getTheme(); }
void AppearenceGTK::setTheme(const QString& name) { return gtk2Appearance()->setTheme(name); }
QString AppearenceGTK::getThemeGtk3() const { return gtk3Appearance()->getTheme(); }
void AppearenceGTK::setThemeGtk3(const QString& name) { return gtk3Appearance()->setTheme(name); }
bool AppearenceGTK::getApplicationPreferDarkTheme() const { return ((AppearanceGTK3*)gtk3Appearance())->getApplicationPreferDarkTheme(); }
void AppearenceGTK::setApplicationPreferDarkTheme(const bool& enable) { return ((AppearanceGTK3*)gtk3Appearance())->setApplicationPreferDarkTheme(enable); }
QString AppearenceGTK::getTheme() const
{
return gtk2Appearance()->getTheme();
}
void AppearenceGTK::setTheme(const QString& name)
{
return gtk2Appearance()->setTheme(name);
}
////////////////////////////////////
// Methods responsible of file creation
QString AppearenceGTK::getThemeGtk3() const
{
return gtk3Appearance()->getTheme();
}
void AppearenceGTK::setThemeGtk3(const QString& name)
{
return gtk3Appearance()->setTheme(name);
}
bool AppearenceGTK::getApplicationPreferDarkTheme() const
{
return ((AppearanceGTK3*)gtk3Appearance())->getApplicationPreferDarkTheme();
}
void AppearenceGTK::setApplicationPreferDarkTheme(bool enable)
{
return ((AppearanceGTK3*)gtk3Appearance())->setApplicationPreferDarkTheme(enable);
}
bool AppearenceGTK::loadFileConfig()
{
bool correct = false;
foreach(AbstractAppearance* app, m_app) {
for(AbstractAppearance *app : m_app) {
bool c = app->loadSettings();
correct = correct || c;
}
// qDebug() << "loading..." << correct;
return correct;
}
bool AppearenceGTK::saveFileConfig()
{
bool correct = true;
foreach(AbstractAppearance* app, m_app) {
for(AbstractAppearance *app : m_app) {
bool c = app->saveSettings();
correct = correct && c;
}
// qDebug() << "saving..." << correct;
return correct;
}
......@@ -25,9 +25,10 @@
#include <QString>
#include <QMap>
#include <qvector.h>
#include <QVector>
class AbstractAppearance;
/**
* This class is responsible of administrating the GTK themes. It loads the
* configurations from the .gtkrc-2.0 file.
......@@ -38,32 +39,14 @@ public:
AppearenceGTK();
~AppearenceGTK();
void setTheme(const QString&);
void setTheme(const QString &);
void setThemeGtk3(const QString &theme);
void setApplicationPreferDarkTheme(const bool& enable);