diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,11 +1,11 @@ project(kde-gtk-config) set(PROJECT_VERSION "5.17.80") -cmake_minimum_required(VERSION 2.8.12) +cmake_minimum_required(VERSION 3.10) find_package(ECM 0.0.9 REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" ${ECM_MODULE_PATH}) -find_package(Qt5 REQUIRED NO_MODULE COMPONENTS Widgets Svg Test) +find_package(Qt5 REQUIRED NO_MODULE COMPONENTS Widgets DBus) find_package(KF5 REQUIRED COMPONENTS I18n KIO ConfigWidgets NewStuff Archive KCMUtils IconThemes DBusAddons) find_package(GTK3 REQUIRED) find_package(GSettingSchemas REQUIRED) @@ -28,26 +28,17 @@ include(KDEClangFormat) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake kded/config.h) # Set KI18n translation domain add_definitions(-DTRANSLATION_DOMAIN=\"kde-gtk-config\") set(kcm_SRCS - src/appearancegtk3.cpp - src/appearancegtk2.cpp - src/appearencegtk.cpp - src/abstractappearance.cpp - src/thread.cpp - src/installer.cpp src/gtkconfigkcmodule.cpp - src/dialog_installer.cpp - src/dialog_uninstaller.cpp ) ki18n_wrap_ui(kcm_SRCS src/ui/gui.ui - src/ui/dialog_installer.ui - src/ui/dialog_uninstaller.ui ) add_library(kcm_kdegtkconfig MODULE ${kcm_SRCS}) @@ -63,14 +54,14 @@ ${GLIB2_LIBRARY} ${GTK3_LIBRARY} ${GOBJECT2_LIBRARY} - Qt5::Svg + Qt5::DBus KF5::ConfigCore KF5::I18n KF5::KIOWidgets KF5::NewStuff KF5::Archive KF5::ConfigWidgets - KF5::IconThemes + KF5::DBusAddons ) kcoreaddons_desktop_to_json(kcm_kdegtkconfig kde-gtk-config.desktop) @@ -82,7 +73,6 @@ add_subdirectory(gtkproxies) add_subdirectory(gtk3proxies) add_subdirectory(icons) -add_subdirectory(tests) add_subdirectory(kded) # add clang-format target for all our real source files diff --git a/kded/CMakeLists.txt b/kded/CMakeLists.txt --- a/kded/CMakeLists.txt +++ b/kded/CMakeLists.txt @@ -2,6 +2,7 @@ gtkconfig.cpp configeditor.cpp configvalueprovider.cpp + themepreviewer.cpp ) add_library(gtkconfig MODULE ${kscreen_daemon_SRCS}) diff --git a/kded/configeditor.h b/kded/configeditor.h --- a/kded/configeditor.h +++ b/kded/configeditor.h @@ -23,11 +23,28 @@ #include class QFile; +class QString; namespace ConfigEditor { void setGtk2ConfigValue(const QString ¶mName, const QString ¶mValue); void setGtk3ConfigValueDconf(const QString ¶mName, const QString ¶mValue, const QString &category = QStringLiteral("org.gnome.desktop.interface")); void setGtk3ConfigValueSettingsIni(const QString ¶mName, const QString ¶mValue); void setGtk3ConfigValueXSettingsd(const QString ¶mName, const QString ¶mValue); + + QString gtk2ConfigValue(const QString& paramName); + QString gtk3ConfigValueSettingsIni(const QString& paramName); + + void removeLegacyGtk2Strings(); + + + void replaceValueInGtkrcContents(QString >krcContents, const QString ¶mName, const QString ¶mValue); + void replaceValueInXSettingsdContents(QString &xSettingsdContents, const QString ¶mName, const QString ¶mValue); + + QString readFileContents(QFile >krc); + + void reloadGtk2Apps(); + void reloadXSettingsd(); + + pid_t pidOfXSettingsd(); }; diff --git a/kded/configeditor.cpp b/kded/configeditor.cpp --- a/kded/configeditor.cpp +++ b/kded/configeditor.cpp @@ -35,16 +35,6 @@ #include "configeditor.h" -static void replaceValueInGtkrcContents(QString >krcContents, const QString ¶mName, const QString ¶mValue); -static void replaceValueInXSettingsdContents(QString &xSettingsdContents, const QString ¶mName, const QString ¶mValue); - -static void reloadGtk2Apps(); -static void reloadXSettingsd(); - -static QString readFileContents(QFile >krc); -static pid_t pidOfXSettingsd(); - - void ConfigEditor::setGtk3ConfigValueDconf(const QString ¶mName, const QString ¶mValue, const QString &category) { g_autoptr(GSettings) gsettings = g_settings_new(category.toUtf8().constData()); @@ -99,16 +89,73 @@ reloadGtk2Apps(); } -static QString readFileContents(QFile &file) +QString ConfigEditor::gtk2ConfigValue(const QString& paramName) +{ + QString gtkrcPath = QDir::homePath() + QStringLiteral("/.gtkrc-2.0"); + QFile gtkrc(gtkrcPath); + if (gtkrc.open(QIODevice::ReadWrite | QIODevice::Text)) { + const QRegularExpression regExp(paramName + QStringLiteral("=[^\n]*($|\n)")); + while (!gtkrc.atEnd()) { + QString line = gtkrc.readLine(); + if (line.contains(regExp)) { + return line.split('"')[1]; + } + } + } + + return QStringLiteral("Breeze"); +} + +QString ConfigEditor::gtk3ConfigValueSettingsIni(const QString& paramName) +{ + QString configLocation = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation); + QString gtk3ConfigPath = configLocation + QStringLiteral("/gtk-3.0/settings.ini"); + + KSharedConfig::Ptr gtk3Config = KSharedConfig::openConfig(gtk3ConfigPath, KConfig::NoGlobals); + KConfigGroup group = gtk3Config->group(QStringLiteral("Settings")); + + return group.readEntry(paramName, QStringLiteral("Breeze")); +} + + +void ConfigEditor::removeLegacyGtk2Strings() +{ + QString gtkrcPath = QDir::homePath() + QStringLiteral("/.gtkrc-2.0"); + QFile gtkrc(gtkrcPath); + QString gtkrcContents = readFileContents(gtkrc); + + // Remove "include" lines + // Example: + // include "/usr/share/themes/Adwaita-dark/gtk-2.0/gtkrc" + static const QRegularExpression includeRegExp(QStringLiteral("include .*\n")); + gtkrcContents.remove(includeRegExp); + + // Remove redundant font config lines + // Example: + // style "user-font" + // { + // font_name="Noto Sans Regular" + // } + // widget_class "*" style "user-font" + static const QRegularExpression userFontStyleRegexp(QStringLiteral("style(.|\n)*{(.|\n)*}\nwidget_class.*\"user-font\"")); + gtkrcContents.remove(userFontStyleRegexp); + + gtkrc.remove(); + gtkrc.open(QIODevice::WriteOnly | QIODevice::Text); + gtkrc.write(gtkrcContents.toUtf8()); + reloadGtk2Apps(); +} + +QString ConfigEditor::readFileContents(QFile &file) { if (file.open(QIODevice::ReadWrite | QIODevice::Text)) { return file.readAll(); } else { return QString(); } } -static void replaceValueInGtkrcContents(QString >krcContents, const QString ¶mName, const QString ¶mValue) +void ConfigEditor::replaceValueInGtkrcContents(QString >krcContents, const QString ¶mName, const QString ¶mValue) { const QRegularExpression regExp(paramName + QStringLiteral("=[^\n]*($|\n)")); @@ -133,7 +180,7 @@ } } -static void replaceValueInXSettingsdContents(QString &xSettingsdContents, const QString ¶mName, const QString ¶mValue) +void ConfigEditor::replaceValueInXSettingsdContents(QString &xSettingsdContents, const QString ¶mName, const QString ¶mValue) { const QRegularExpression regExp(paramName + QStringLiteral(" [^\n]*($|\n)")); @@ -158,26 +205,26 @@ } } -static void reloadGtk2Apps() +void ConfigEditor::reloadGtk2Apps() { QProcess::startDetached(QStandardPaths::findExecutable(QStringLiteral("reload_gtk_apps"))); } -static void reloadXSettingsd() +pid_t ConfigEditor::pidOfXSettingsd() +{ + QProcess pidof; + pidof.start(QStringLiteral("pidof"), QStringList() << QStringLiteral("-s") << QStringLiteral("xsettingsd")); + pidof.waitForFinished(); + QString xsettingsdPid = QString(pidof.readAllStandardOutput()).remove('\n'); + return xsettingsdPid.toInt(); +} + +void ConfigEditor::reloadXSettingsd() { pid_t xSettingsdPid = pidOfXSettingsd(); if (xSettingsdPid == 0) { QProcess::startDetached(QStandardPaths::findExecutable(QStringLiteral("xsettingsd"))); } else { kill(xSettingsdPid, SIGHUP); } } - -static pid_t pidOfXSettingsd() -{ - QProcess pidof; - pidof.start(QStringLiteral("pidof"), QStringList() << QStringLiteral("-s") << QStringLiteral("xsettingsd")); - pidof.waitForFinished(); - QString xsettingsdPid = QString(pidof.readAllStandardOutput()).remove('\n'); - return xsettingsdPid.toInt(); -} diff --git a/kded/gtkconfig.h b/kded/gtkconfig.h --- a/kded/gtkconfig.h +++ b/kded/gtkconfig.h @@ -26,10 +26,12 @@ #include "configeditor.h" #include "configvalueprovider.h" +#include "themepreviewer.h" class Q_DECL_EXPORT GtkConfig : public KDEDModule { Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.kde.GtkConfig") enum class SettingsChangeType { Palette = 0, @@ -56,6 +58,7 @@ public: GtkConfig(QObject *parent, const QVariantList& args); + ~GtkConfig(); void setFont() const; void setIconTheme(int iconGroup) const; @@ -70,10 +73,20 @@ void applyAllSettings() const; public Q_SLOTS: + Q_SCRIPTABLE void setGtk2Theme(const QString &themeName) const; + Q_SCRIPTABLE void setGtk3Theme(const QString &themeName) const; + + Q_SCRIPTABLE QString gtk2Theme() const; + Q_SCRIPTABLE QString gtk3Theme() const; + + Q_SCRIPTABLE void showGtk2ThemePreview(const QString &themeName) const; + Q_SCRIPTABLE void showGtk3ThemePreview(const QString &themeName) const; + void onGlobalSettingsChange(int settingsChangeType, int arg) const; void onKWinSettingsChange(const KConfigGroup &group, const QByteArrayList &names) const; private: QScopedPointer configValueProvider; + QScopedPointer themePreviewer; KConfigWatcher::Ptr kwinConfigWatcher; }; diff --git a/kded/gtkconfig.cpp b/kded/gtkconfig.cpp --- a/kded/gtkconfig.cpp +++ b/kded/gtkconfig.cpp @@ -19,37 +19,86 @@ * along with this program. If not, see . */ -#include #include #include +#include #include #include #include #include #include "gtkconfig.h" #include "configvalueprovider.h" +#include "themepreviewer.h" K_PLUGIN_CLASS_WITH_JSON(GtkConfig, "gtkconfig.json") GtkConfig::GtkConfig(QObject *parent, const QVariantList&) : KDEDModule(parent), configValueProvider(new ConfigValueProvider()), + themePreviewer(new ThemePreviewer(this)), kwinConfigWatcher(KConfigWatcher::create(KSharedConfig::openConfig(QStringLiteral("kwinrc")))) { + QDBusConnection dbus = QDBusConnection::sessionBus(); + dbus.registerService(QStringLiteral("org.kde.GtkConfig")); + dbus.registerObject(QStringLiteral("/GtkConfig"), this, QDBusConnection::ExportScriptableSlots); + connect(qGuiApp, &QGuiApplication::fontChanged, this, &GtkConfig::setFont); connect(KIconLoader::global(), &KIconLoader::iconChanged, this, &GtkConfig::setIconTheme); connect(kwinConfigWatcher.data(), &KConfigWatcher::configChanged, this, &GtkConfig::onKWinSettingsChange); - QDBusConnection::sessionBus().connect(QString(), - QStringLiteral("/KGlobalSettings"), - QStringLiteral("org.kde.KGlobalSettings"), - QStringLiteral("notifyChange"), - this, - SLOT(onGlobalSettingsChange(int,int))); + dbus.connect( + QString(), + QStringLiteral("/KGlobalSettings"), + QStringLiteral("org.kde.KGlobalSettings"), + QStringLiteral("notifyChange"), + this, + SLOT(onGlobalSettingsChange(int,int)) + ); + + ConfigEditor::removeLegacyGtk2Strings(); applyAllSettings(); } +GtkConfig::~GtkConfig() +{ + QDBusConnection dbus = QDBusConnection::sessionBus(); + dbus.unregisterService(QStringLiteral("org.kde.GtkConfig")); + dbus.unregisterObject(QStringLiteral("/GtkConfig")); +} + +void GtkConfig::setGtk2Theme(const QString &themeName) const +{ + ConfigEditor::setGtk2ConfigValue(QStringLiteral("gtk-theme-name"), themeName); +} + +void GtkConfig::setGtk3Theme(const QString &themeName) const +{ + ConfigEditor::setGtk3ConfigValueDconf(QStringLiteral("gtk-theme"), themeName); + ConfigEditor::setGtk3ConfigValueSettingsIni(QStringLiteral("gtk-theme-name"), themeName); + ConfigEditor::setGtk3ConfigValueXSettingsd(QStringLiteral("Net/ThemeName"), themeName); +} + +QString GtkConfig::gtk2Theme() const +{ + return ConfigEditor::gtk2ConfigValue(QStringLiteral("gtk-theme-name")); +} + +QString GtkConfig::gtk3Theme() const +{ + return ConfigEditor::gtk3ConfigValueSettingsIni(QStringLiteral("gtk-theme-name")); +} + +void GtkConfig::showGtk2ThemePreview(const QString& themeName) const +{ + themePreviewer->showGtk2App(themeName); +} + +void GtkConfig::showGtk3ThemePreview(const QString& themeName) const +{ + themePreviewer->showGtk3App(themeName); +} + void GtkConfig::setFont() const { const QString configFontName = configValueProvider->fontName(); diff --git a/kded/configeditor.h b/kded/themepreviewer.h copy from kded/configeditor.h copy to kded/themepreviewer.h --- a/kded/configeditor.h +++ b/kded/themepreviewer.h @@ -17,17 +17,31 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + #pragma once -#include +#include #include -class QFile; +class ThemePreviewer : QObject { + Q_OBJECT +public: + ThemePreviewer(QObject *parent); + + void showGtk2App(const QString &themeName); + void showGtk3App(const QString &themeName); + +private Q_SLOTS: + void startXsettingsd(); + void stopXsettingsd(); + +private: + static const QString previewGtk2ConfigPath; + static const QString currentGtk2ConfigPath; + static const QString gtk2PreviewerExecutablePath; + + static const QString gtk3PreviewerExecutablePath; -namespace ConfigEditor -{ - void setGtk2ConfigValue(const QString ¶mName, const QString ¶mValue); - void setGtk3ConfigValueDconf(const QString ¶mName, const QString ¶mValue, const QString &category = QStringLiteral("org.gnome.desktop.interface")); - void setGtk3ConfigValueSettingsIni(const QString ¶mName, const QString ¶mValue); - void setGtk3ConfigValueXSettingsd(const QString ¶mName, const QString ¶mValue); + QProcess gtk2PreviewerProccess; + QProcess gtk3PreviewerProccess; }; diff --git a/kded/themepreviewer.cpp b/kded/themepreviewer.cpp new file mode 100644 --- /dev/null +++ b/kded/themepreviewer.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2019 Mikhail Zolotukhin + * + * 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) version 3 or any later version + * accepted by the membership of KDE e.V. (or its successor approved + * by the membership of KDE e.V.), which shall act as a proxy + * defined in Section 14 of version 3 of the license. + * + * 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, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "themepreviewer.h" +#include "configeditor.h" +#include "config.h" + +const QString ThemePreviewer::previewGtk2ConfigPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + QStringLiteral("/gtkrc-2.0"); +const QString ThemePreviewer::currentGtk2ConfigPath = QDir::homePath() + QStringLiteral("/.gtkrc-2.0"); +const QString ThemePreviewer::gtk2PreviewerExecutablePath = QStandardPaths::findExecutable(QStringLiteral("gtk_preview"), {CMAKE_INSTALL_FULL_LIBEXECDIR}); + +const QString ThemePreviewer::gtk3PreviewerExecutablePath = QStandardPaths::findExecutable(QStringLiteral("gtk3_preview"), {CMAKE_INSTALL_FULL_LIBEXECDIR}); + +ThemePreviewer::ThemePreviewer(QObject *parent) : QObject(parent), +gtk2PreviewerProccess(), +gtk3PreviewerProccess() +{ + QProcessEnvironment gtk2PreviewEnvironment = QProcessEnvironment::systemEnvironment(); + gtk2PreviewEnvironment.insert(QStringLiteral("GTK2_RC_FILES"), previewGtk2ConfigPath); + + gtk2PreviewerProccess.setProcessEnvironment(gtk2PreviewEnvironment); + connect(>k2PreviewerProccess, SIGNAL(finished(int)), this, SLOT(startXsettingsd())); +} + +void ThemePreviewer::showGtk2App(const QString& themeName) +{ + if (gtk2PreviewerProccess.state() == QProcess::ProcessState::NotRunning) { + if (QFile::exists(previewGtk2ConfigPath)) { + QFile::remove(previewGtk2ConfigPath); + } + + QFile::copy(currentGtk2ConfigPath, previewGtk2ConfigPath); + + QFile previewConfig(previewGtk2ConfigPath); + QString previewConfigContents = ConfigEditor::readFileContents(previewConfig); + ConfigEditor::replaceValueInGtkrcContents(previewConfigContents, QStringLiteral("gtk-theme-name"), themeName); + previewConfig.remove(); + previewConfig.open(QIODevice::WriteOnly | QIODevice::Text); + previewConfig.write(previewConfigContents.toUtf8()); + + stopXsettingsd(); + gtk2PreviewerProccess.start(gtk2PreviewerExecutablePath); + } else { + gtk2PreviewerProccess.close(); + } +} + +void ThemePreviewer::showGtk3App(const QString& themeName) +{ + if (gtk3PreviewerProccess.state() == QProcess::ProcessState::NotRunning) { + QProcessEnvironment gtk3PreviewEnvironment = QProcessEnvironment::systemEnvironment(); + gtk3PreviewEnvironment.insert(QStringLiteral("GTK_THEME"), themeName); + gtk3PreviewerProccess.setProcessEnvironment(gtk3PreviewEnvironment); + + gtk3PreviewerProccess.start(gtk3PreviewerExecutablePath); + } else { + gtk3PreviewerProccess.close(); + } +} + +void ThemePreviewer::startXsettingsd() +{ + if (gtk2PreviewerProccess.state() == QProcess::ProcessState::NotRunning && + gtk3PreviewerProccess.state() == QProcess::ProcessState::NotRunning) { + QProcess::startDetached(QStandardPaths::findExecutable(QStringLiteral("xsettingsd"))); + } +} + +void ThemePreviewer::stopXsettingsd() +{ + pid_t pidOfXSettingsd = ConfigEditor::pidOfXSettingsd(); + if (pidOfXSettingsd > 0) { + kill(pidOfXSettingsd, SIGTERM); + } +} diff --git a/src/abstractappearance.h b/src/abstractappearance.h deleted file mode 100644 --- a/src/abstractappearance.h +++ /dev/null @@ -1,55 +0,0 @@ -/* KDE GTK Configuration Module - * - * Copyright 2011 Aleix Pol Gonzalez - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) version 3, or any - * later version accepted by the membership of KDE e.V. (or its - * successor approved by the membership of KDE e.V.), which shall - * act as a proxy defined in Section 6 of version 3 of the license. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#ifndef ABSTACTAPPEARANCE_H -#define ABSTACTAPPEARANCE_H - -#include -#include -#include - -class AbstractAppearance -{ - public: - 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; - - /** @returns the installed themes' paths*/ - virtual QStringList installedThemes() const = 0; - - void setTheme(const QString &name); - - QString getTheme() const; - QString getThemeGtk3() const; - - QStringList installedThemesNames() const; - bool hasProperty(const QString &key) const; - - static QMap readSettingsTuples(QIODevice *device); - - protected: - QMap m_settings; -}; - -#endif diff --git a/src/abstractappearance.cpp b/src/abstractappearance.cpp deleted file mode 100644 --- a/src/abstractappearance.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* KDE GTK Configuration Module - * - * Copyright 2011 Aleix Pol Gonzalez - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) version 3, or any - * later version accepted by the membership of KDE e.V. (or its - * successor approved by the membership of KDE e.V.), which shall - * act as a proxy defined in Section 6 of version 3 of the license. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#include -#include -#include - -#include "abstractappearance.h" - -void AbstractAppearance::setTheme(const QString& name) -{ - m_settings["theme"] = name; -} - -QString AbstractAppearance::getTheme() const -{ - return m_settings["theme"]; -} - -QString AbstractAppearance::getThemeGtk3() const -{ - return m_settings["themegtk3"]; -} - -QMap AbstractAppearance::readSettingsTuples(QIODevice* device) -{ - static const QRegExp valueRx(" *([a-zA-Z\\-_]+) *= *\"?([^\"\\n]+)\"?", Qt::CaseSensitive, QRegExp::RegExp2); - - QMap ret; - QTextStream flow(device); - while (!flow.atEnd()) { - QString line = flow.readLine(); - int idxComment = line.indexOf('#'); - if (idxComment >= 0) { - line = line.left(idxComment).simplified(); - } - - if (valueRx.exactMatch(line)) { - ret[valueRx.cap(1)] = valueRx.cap(2); - } else if (line.startsWith("include \"")) { - QString filename = line.mid(9); - filename.chop(1); - QFile f(filename); - if (f.open(QFile::Text | QFile::ReadOnly)) { - ret.unite(readSettingsTuples(&f)); - } else { - qWarning() << "couldn't include " << filename; - } - } - } - return ret; -} - -QStringList AbstractAppearance::installedThemesNames() const -{ - QStringList themes = installedThemes(); - QStringList ret; - - for(const QString &theme : themes) { - ret += QDir(theme).dirName(); - } - - return ret; -} - -bool AbstractAppearance::hasProperty(const QString& key) const -{ - return !m_settings.value(key).isEmpty(); -} diff --git a/src/appearancegtk2.h b/src/appearancegtk2.h deleted file mode 100644 --- a/src/appearancegtk2.h +++ /dev/null @@ -1,48 +0,0 @@ -/* KDE GTK Configuration Module - * - * Copyright 2011 José Antonio Sanchez Reynaga - * Copyright 2011 Aleix Pol Gonzalez - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) version 3, or any - * later version accepted by the membership of KDE e.V. (or its - * successor approved by the membership of KDE e.V.), which shall - * act as a proxy defined in Section 6 of version 3 of the license. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#ifndef APPEARANCEGTK2_H -#define APPEARANCEGTK2_H - -#include "abstractappearance.h" - -class AppearanceGTK2 : public AbstractAppearance -{ - 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; - -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; -}; - -#endif // APPEARANCEGTK2_H diff --git a/src/appearancegtk2.cpp b/src/appearancegtk2.cpp deleted file mode 100644 --- a/src/appearancegtk2.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* KDE GTK Configuration Module - * - * Copyright 2011 José Antonio Sanchez Reynaga - * Copyright 2011 Aleix Pol Gonzalez - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) version 3, or any - * later version accepted by the membership of KDE e.V. (or its - * successor approved by the membership of KDE e.V.), which shall - * act as a proxy defined in Section 6 of version 3 of the license. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "config.h" -#include "appearancegtk2.h" - -bool AppearanceGTK2::loadSettingsPrivate(const QString &path) -{ - QFile configFile(path); - - if (!configFile.open(QIODevice::ReadOnly | QIODevice::Text)) { - return false; - } - - const QMap foundSettings = readSettingsTuples(&configFile); - - for(auto it = foundSettings.constBegin(), itEnd = foundSettings.constEnd(); it!=itEnd; ++it) { - if (it.key() == QStringLiteral("gtk-theme-name")) { - m_settings[QStringLiteral("theme")] = *it; - } - } - return true; -} - -QString AppearanceGTK2::themesGtkrcFile(const QString &themeName) const -{ - 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") { - return it.filePath(); - } - } - } - - return QString(); -} - -bool AppearanceGTK2::saveSettingsPrivate(const QString >krcFile) const -{ - QFile gtkrc(gtkrcFile); - - if (gtkrc.open(QIODevice::ReadWrite | QIODevice::Text)) { - QString fileContents = gtkrc.readAll(); - - modifyGtkrcContents(fileContents); - - gtkrc.remove(); - gtkrc.open(QIODevice::WriteOnly | QIODevice::Text); - gtkrc.write(fileContents.toUtf8()); - - if (QFileInfo(gtkrc).filePath() == defaultConfigFile()) { - QProcess::startDetached(QStandardPaths::findExecutable("reload_gtk_apps", {CMAKE_INSTALL_FULL_LIBEXECDIR})); - } - - return true; - } else { - qWarning() << "Unable to write the .gtkrc-2.0 file"; - return false; - } -} - -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 -{ - const QRegularExpression regExp{propertyName + "=[^\n]*($|\n)"}; - - static const QStringList nonStringProperties{ - "gtk-toolbar-style", - "gtk-menu-images", - "gtk-button-images", - "gtk-primary-button-warps-slider", - }; - - QString newConfigString; - if (nonStringProperties.contains(propertyName)) { - newConfigString = propertyName + "=" + newValue + "\n"; - } else { - newConfigString = propertyName + "=\"" + newValue + "\"\n"; - } - - if (fileContents.contains(regExp)) { - fileContents.replace(regExp, newConfigString); - } else { - fileContents = newConfigString + "\n" + fileContents; - } -} - -void AppearanceGTK2::removeGtkrcLegacyContents(QString &fileContents) const -{ - // Remove "include" lines - // Example: - // include "/usr/share/themes/Adwaita-dark/gtk-2.0/gtkrc" - - static const QRegularExpression includeRegExp(QStringLiteral("include .*\n")); - fileContents.remove(includeRegExp); - - // Remove redundant font config lines - // Example: - // style "user-font" - // { - // font_name="Noto Sans Regular" - // } - // widget_class "*" style "user-font" - - static const QRegularExpression userFontStyleRegexp(QStringLiteral("style(.|\n)*{(.|\n)*}\nwidget_class.*\"user-font\"")); - fileContents.remove(userFontStyleRegexp); -} - -void AppearanceGTK2::reset() -{ - m_settings.clear(); -} - -QString AppearanceGTK2::defaultConfigFile() const -{ - return QDir::homePath() + QStringLiteral("/.gtkrc-2.0"); -} - -QStringList AppearanceGTK2::installedThemes() const -{ - QFileInfoList availableThemes; - for (const QString& themesDir : QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, "themes", QStandardPaths::LocateDirectory)) { - QDir root(themesDir); - 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); - - // We just want actual themes - QStringList paths; - 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(); - } - } - - return paths; -} - -bool AppearanceGTK2::loadSettings() -{ - reset(); - - bool b = loadSettingsPrivate(QStringLiteral("/etc/gtk-2.0/gtkrc")); - b |= loadSettingsPrivate(defaultConfigFile()); - return b; -} - -bool AppearanceGTK2::saveSettings() const -{ - return saveSettings(defaultConfigFile()); -} - -bool AppearanceGTK2::loadSettings(const QString >krcFile) -{ - reset(); - return loadSettingsPrivate(gtkrcFile); -} - -bool AppearanceGTK2::saveSettings(const QString >krcFile) const -{ - return saveSettingsPrivate(gtkrcFile); -} diff --git a/src/appearancegtk3.h b/src/appearancegtk3.h deleted file mode 100644 --- a/src/appearancegtk3.h +++ /dev/null @@ -1,47 +0,0 @@ -/* KDE GTK Configuration Module - * - * Copyright 2011 José Antonio Sanchez Reynaga - * Copyright 2011 Aleix Pol Gonzalez - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) version 3, or any - * later version accepted by the membership of KDE e.V. (or its - * successor approved by the membership of KDE e.V.), which shall - * act as a proxy defined in Section 6 of version 3 of the license. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#ifndef APPEARANCEGTK3_H -#define APPEARANCEGTK3_H - -#include - -#include "abstractappearance.h" - -class AppearanceGTK3 : public AbstractAppearance -{ - -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; - -private: - QString defaultConfigFile() const; - QString configFileName() const; - bool saveSettings(const KSharedConfig::Ptr &file) const; - bool loadSettings(const KSharedConfig::Ptr &file); -}; - -#endif // APPEARANCEGTK3_H diff --git a/src/appearancegtk3.cpp b/src/appearancegtk3.cpp deleted file mode 100644 --- a/src/appearancegtk3.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/* KDE GTK Configuration Module - * - * Copyright 2011 José Antonio Sanchez Reynaga - * Copyright 2011 Aleix Pol Gonzalez - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) version 3, or any - * later version accepted by the membership of KDE e.V. (or its - * successor approved by the membership of KDE e.V.), which shall - * act as a proxy defined in Section 6 of version 3 of the license. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#include -#include -#include -#include - -#include -#include - -#include - -#include "appearancegtk3.h" - -QStringList AppearanceGTK3::installedThemes() const -{ - QFileInfoList availableThemes; - for (const QString& themesDir : QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("themes"), QStandardPaths::LocateDirectory)) { - QDir root(themesDir); - availableThemes += root.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 - QStringList themes; - - // Check that the theme contains a gtk-3.* subdirectory - QStringList gtk3SubdirPattern(QStringLiteral("gtk-3.*")); - for (const QFileInfo &it : availableThemes) { - QDir themeDir(it.filePath()); - if(!themeDir.entryList(gtk3SubdirPattern, QDir::Dirs).isEmpty()) - themes += it.filePath(); - } - - return themes; -} - -bool AppearanceGTK3::saveSettings(const KSharedConfig::Ptr& file) const -{ - KConfigGroup group(file, QStringLiteral("Settings")); - - group.writeEntry(QStringLiteral("gtk-theme-name"), m_settings["theme"]); - - const bool sync = group.sync(); - Q_ASSERT(sync); - return true; -} - -bool AppearanceGTK3::loadSettings(const KSharedConfig::Ptr& file) -{ - KConfigGroup group(file, QStringLiteral("Settings")); - - if (!file || !group.isValid()) { - qWarning() << QStringLiteral("Cannot open the GTK3 config file") << file; - return false; - } - - m_settings.clear(); - - m_settings[QStringLiteral("theme")] = group.readEntry(QStringLiteral("gtk-theme-name")); - for(auto it = m_settings.begin(); it != m_settings.end(); ) { - if (it.value().isEmpty()) { - it = m_settings.erase(it); - } else { - ++it; - } - } - return true; -} - -QString AppearanceGTK3::configFileName() const -{ - return QStringLiteral("gtk-3.0/settings.ini"); -} - -QString AppearanceGTK3::defaultConfigFile() const -{ - QString root = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation); - if(root.isEmpty()) { - root = QFileInfo(QDir::home(), QStringLiteral(".config")).absoluteFilePath(); - } - - return root + '/' + configFileName(); -} - -bool AppearanceGTK3::saveSettings(const QString& file) const -{ - auto cfg = KSharedConfig::openConfig(file, KConfig::NoGlobals); - return saveSettings(cfg); -} - -bool AppearanceGTK3::loadSettings(const QString& path) -{ - auto cfg = KSharedConfig::openConfig(path, KConfig::NoGlobals); - return loadSettings(cfg); -} - -bool AppearanceGTK3::loadSettings() -{ - auto cfg = KSharedConfig::openConfig(configFileName(), KConfig::NoGlobals); - return loadSettings(cfg); -} - -bool AppearanceGTK3::saveSettings() const -{ - // FIXME kdebz#387417 - // 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 - g_autoptr(GSettings) gsettings = g_settings_new("org.gnome.desktop.interface"); - g_settings_set_string(gsettings, "gtk-theme", m_settings["theme"].toUtf8().constData()); - - auto cfg = KSharedConfig::openConfig(configFileName(), KConfig::NoGlobals); - return saveSettings(cfg); -} diff --git a/src/appearencegtk.h b/src/appearencegtk.h deleted file mode 100644 --- a/src/appearencegtk.h +++ /dev/null @@ -1,57 +0,0 @@ -/* KDE GTK Configuration Module - * - * Copyright 2011 José Antonio Sanchez Reynaga - * Copyright 2011 Aleix Pol Gonzalez - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) version 3, or any - * later version accepted by the membership of KDE e.V. (or its - * successor approved by the membership of KDE e.V.), which shall - * act as a proxy defined in Section 6 of version 3 of the license. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#ifndef APARIENCIAGTK_H -#define APARIENCIAGTK_H - -#include -#include -#include - -class AbstractAppearance; - -/** - * This class is responsible of administrating the GTK themes. It loads the - * configurations from the .gtkrc-2.0 file. - */ -class AppearenceGTK -{ -public: - AppearenceGTK(); - ~AppearenceGTK(); - - void setTheme(const QString &); - void setThemeGtk3(const QString &theme); - - QString getTheme() const; - QString getThemeGtk3() const; - - bool loadFileConfig(); - bool saveFileConfig(); - - AbstractAppearance* gtk2Appearance() const { return m_app.first(); } - AbstractAppearance* gtk3Appearance() const { return m_app.last(); } -private: - QVector m_app; -}; - -#endif // APARIENCIAGTK_H diff --git a/src/appearencegtk.cpp b/src/appearencegtk.cpp deleted file mode 100644 --- a/src/appearencegtk.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* KDE GTK Configuration Module - * - * Copyright 2011 José Antonio Sanchez Reynaga - * Copyright 2011 Aleix Pol Gonzalez - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) version 3, or any - * later version accepted by the membership of KDE e.V. (or its - * successor approved by the membership of KDE e.V.), which shall - * act as a proxy defined in Section 6 of version 3 of the license. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#include - -#include "abstractappearance.h" -#include "appearencegtk.h" -#include "appearancegtk2.h" -#include "appearancegtk3.h" - -AppearenceGTK::AppearenceGTK() -{ - m_app << new AppearanceGTK2; - m_app << new AppearanceGTK3; -} - -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::loadFileConfig() -{ - bool correct = false; - for(AbstractAppearance *app : m_app) { - bool c = app->loadSettings(); - correct = correct || c; - } - return correct; -} - -bool AppearenceGTK::saveFileConfig() -{ - bool correct = true; - for(AbstractAppearance *app : m_app) { - bool c = app->saveSettings(); - correct = correct && c; - } - return correct; -} diff --git a/src/dialog_installer.h b/src/dialog_installer.h deleted file mode 100644 --- a/src/dialog_installer.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2011 José Antonio Sanchez Reynaga - * Copyright 2011 Aleix Pol Gonzalez - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) version 3, or any - * later version accepted by the membership of KDE e.V. (or its - * successor approved by the membership of KDE e.V.), which shall - * act as a proxy defined in Section 6 of version 3 of the license. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#ifndef DIALOGINSTALLER_H -#define DIALOGINSTALLER_H - -#include - -class ThreadAnalisysThemeIcon; -class ThreadAnalisysTheme; -class Thread; - -namespace Ui { - class dialog_installer; -} - -/** - * GUI to install icons and gtk themes - */ -class DialogInstaller : public QDialog -{ -Q_OBJECT -public: - DialogInstaller(QWidget *parent=0); - ~DialogInstaller(); - -Q_SIGNALS: - /** - * Whenever a theme is installed, this signal is emitted - */ - void themeInstalled(); - -private Q_SLOTS: - /** - Instala el tema de icono a traves del objeto Installer - Para ello lanza un hilo para que no se bloqué la GUI - */ - void installTheme(); - - void enableGUIThemeInstaller(); - void disableGUIThemeInstaller(); - void refreshGUITheme(); - void themeAnalisys(); - - // Executed after analyzing theme - void checkThemeAnalisys(); - -private: - Ui::dialog_installer *ui; - - //PROPIEDADES PARA EL AREA DE INSTALADOR - Thread *threadForTheme; //Hilo que instala el tema gtk - ThreadAnalisysTheme *threadAnalisysTheme; //hilo para analizar los temas a instalar - -}; - -#endif //dialog_installer.h diff --git a/src/dialog_installer.cpp b/src/dialog_installer.cpp deleted file mode 100644 --- a/src/dialog_installer.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2011 José Antonio Sanchez Reynaga - * Copyright 2011 Aleix Pol Gonzalez - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) version 3, or any - * later version accepted by the membership of KDE e.V. (or its - * successor approved by the membership of KDE e.V.), which shall - * act as a proxy defined in Section 6 of version 3 of the license. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#include -#include - -#include -#include - -#include "dialog_installer.h" -#include "ui_dialog_installer.h" -#include "installer.h" -#include "thread.h" - -static bool fileIsTar(const QString& path) -{ - QFileInfo file(path); - if(file.isDir() || !file.exists()) { - return false; - } - - QMimeDatabase db; - QMimeType type = db.mimeTypeForUrl(QUrl::fromLocalFile(path)); - return type.isValid() && (type.inherits("application/x-tar") || type.inherits("application/x-bzip-compressed-tar") || type.inherits("application/x-compressed-tar")); -} - -DialogInstaller::DialogInstaller(QWidget *parent) - : QDialog(parent), ui(new Ui::dialog_installer) -{ - ui->setupUi(this); - - // TODO: make sure it's a good idea to have the threads always instanciated - threadForTheme = new Thread("theme"); - threadAnalisysTheme = new ThreadAnalisysTheme; - - // Installation ui - connect(ui->theme_file, &KUrlRequester::textChanged, this, &DialogInstaller::themeAnalisys); - - connect(ui->but_theme_install, &QAbstractButton::clicked, this, &DialogInstaller::installTheme); - - connect(threadAnalisysTheme, &KJob::finished, this, &DialogInstaller::checkThemeAnalisys); - - connect(threadForTheme, &Thread::started, this, &DialogInstaller::disableGUIThemeInstaller); - connect(threadForTheme, &KJob::finished, this, &DialogInstaller::enableGUIThemeInstaller); - - // Ui refresh - connect(threadForTheme, &KJob::finished, this, &DialogInstaller::refreshGUITheme); -} - -DialogInstaller::~DialogInstaller() -{ - - disconnect(threadAnalisysTheme, nullptr, this, nullptr); - disconnect(threadForTheme, nullptr, this, nullptr); - disconnect(threadForTheme, nullptr, this, nullptr); - - delete threadAnalisysTheme; - delete threadForTheme; - delete ui; -} - -void DialogInstaller::installTheme() -{ - QString file = ui->theme_file->text(); - - if(!fileIsTar(file)) { - KMessageBox::error(this, i18n("Could not install the %1 theme.", file), i18n("Cannot install theme")); - return; - } - - threadForTheme->setUrlPackage(file); - threadForTheme->start(); -} - -void DialogInstaller::themeAnalisys() -{ - ui->lb_theme_notice->setText(i18n("Parsing theme...")); - - ui->theme_file->setEnabled(false); - - QString archivo = ui->theme_file->text(); - threadAnalisysTheme->setPackageTheme(archivo); - threadAnalisysTheme->start(); -} - -void DialogInstaller::checkThemeAnalisys() -{ - ui->theme_file->setEnabled(true); - - if(threadAnalisysTheme->isSuccess()) { - ui->lb_theme_notice->setText(i18n("This GTK theme can be installed")); - ui->but_theme_install->setEnabled(true); - } else { - ui->lb_theme_notice->setText(i18n("This GTK theme cannot be installed")); - ui->but_theme_install->setEnabled(false); - } -} - -void DialogInstaller::enableGUIThemeInstaller() -{ - ui->but_theme_install->setEnabled(true); - ui->theme_file->setEnabled(true); -} - -void DialogInstaller::disableGUIThemeInstaller() -{ - ui->lb_theme_notice->setText(i18n("Installing GTK theme...")); - ui->but_theme_install->setEnabled(false); - ui->theme_file->setEnabled(false); -} - - -// Esto se ejecuta cuando un tema es tratado a instalar -void DialogInstaller::refreshGUITheme() -{ - if(threadForTheme->isSuccess()) { - ui->lb_theme_notice->setText(i18n("GTK Theme Successfully Installed")); - emit themeInstalled(); - } else { - ui->lb_theme_notice->setText(i18n("The GTK theme cannot be installed")); - } - ui->theme_file->clear(); -} diff --git a/src/dialog_uninstaller.h b/src/dialog_uninstaller.h deleted file mode 100644 --- a/src/dialog_uninstaller.h +++ /dev/null @@ -1,57 +0,0 @@ -/* KDE GTK Configuration Module - * - * Copyright 2011 José Antonio Sanchez Reynaga - * Copyright 2011 Aleix Pol Gonzalez - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) version 3, or any - * later version accepted by the membership of KDE e.V. (or its - * successor approved by the membership of KDE e.V.), which shall - * act as a proxy defined in Section 6 of version 3 of the license. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#ifndef DIALOGUNINSTALLER_H -#define DIALOGUNINSTALLER_H - -#include - -class KJob; -class AppearenceGTK; -namespace Ui{ - class dialog_uninstaller; -} - -/** - * GUI to uninstall GTK themes and icon themes - */ -class DialogUninstaller: public QDialog -{ - Q_OBJECT -public: - DialogUninstaller(QWidget *parent = 0, AppearenceGTK *app=0); - ~DialogUninstaller(); - -Q_SIGNALS: - void themeUninstalled(); - -public Q_SLOTS: - void refreshListsForUninstall(); - void uninstallTheme(); - void threadUninstalledThemeFinished(KJob* job); - -private: - Ui::dialog_uninstaller *ui; - AppearenceGTK *appareance; -}; - -#endif //dialog_installer.h diff --git a/src/dialog_uninstaller.cpp b/src/dialog_uninstaller.cpp deleted file mode 100644 --- a/src/dialog_uninstaller.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* KDE GTK Configuration Module - * - * Copyright 2011 José Antonio Sanchez Reynaga - * Copyright 2011 Aleix Pol Gonzalez - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) version 3, or any - * later version accepted by the membership of KDE e.V. (or its - * successor approved by the membership of KDE e.V.), which shall - * act as a proxy defined in Section 6 of version 3 of the license. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#include -#include - -#include - -#include "dialog_uninstaller.h" -#include "abstractappearance.h" -#include "ui_dialog_uninstaller.h" -#include "thread.h" -#include "appearencegtk.h" - -DialogUninstaller::DialogUninstaller(QWidget *parent, AppearenceGTK *app) - : QDialog(parent) - , ui(new Ui::dialog_uninstaller) - , appareance(app) -{ - ui->setupUi(this); - - refreshListsForUninstall(); - - connect(ui->but_uninstall_theme, &QAbstractButton::clicked, this, &DialogUninstaller::uninstallTheme); -} - -DialogUninstaller::~DialogUninstaller() -{ - delete ui; -} - -void DialogUninstaller::refreshListsForUninstall() -{ - ui->lb_notice_uninstall_theme->clear(); - - QStringList themes = appareance->gtk2Appearance()->installedThemes(); - themes = themes.filter(QDir::homePath()); // We only one the locally installed themes - - // Just leave the theme name - for(QStringList::iterator it=themes.begin(); it!=themes.end(); ++it) - *it = QDir(*it).dirName(); - - ui->cb_uninstall_theme->clear(); - ui->cb_uninstall_theme->addItems(themes); -} - -void DialogUninstaller::uninstallTheme() -{ - if(ui->cb_uninstall_theme->currentIndex() < 0) - return; - - QString tema = ui->cb_uninstall_theme->currentText(); - - QStringList themes = appareance->gtk2Appearance()->installedThemes(); - themes = themes.filter(QRegExp('/' + tema + '$')); - - Q_ASSERT(themes.size() == 1); - - ui->cb_uninstall_theme->setEnabled(false); - ui->but_uninstall_theme->setEnabled(false); - - ui->lb_notice_uninstall_theme->setText(i18n("Uninstalling GTK theme...")); - - ThreadErase* threadEraseTheme = new ThreadErase; - threadEraseTheme->setThemeForErase(themes.first()); - connect(threadEraseTheme, &KJob::finished, this, &DialogUninstaller::threadUninstalledThemeFinished); - threadEraseTheme->start(); -} - -void DialogUninstaller::threadUninstalledThemeFinished(KJob* job) -{ - if (job->error()==0) { - ui->lb_notice_uninstall_theme->setText(i18n("GTK theme successfully uninstalled.")); - emit(themeUninstalled()); - } else { - ui->lb_notice_uninstall_theme->setText(i18n("Could not uninstall the GTK theme.")); - } - - ui->cb_uninstall_theme->setEnabled(true); - ui->but_uninstall_theme->setEnabled(true); - - refreshListsForUninstall(); -} diff --git a/src/gtkconfigkcmodule.h b/src/gtkconfigkcmodule.h --- a/src/gtkconfigkcmodule.h +++ b/src/gtkconfigkcmodule.h @@ -20,64 +20,80 @@ * License along with this library. If not, see . */ - #ifndef GTKCONFIGKCMODULE_H #define GTKCONFIGKCMODULE_H #include -#include -#include "appearencegtk.h" -#include "dialog_installer.h" -#include "dialog_uninstaller.h" +#include +#include +#include + +class GtkThemesListModel : public QAbstractTableModel { + Q_OBJECT +public: + GtkThemesListModel(QObject *parent = nullptr); + + void setThemesList(const QMap &themes); + bool containsTheme(const QString &themeName); + int rowCount(const QModelIndex &parent) const override; + int columnCount(const QModelIndex &parent) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; -class KProcess; -namespace Ui { class Modulo; class GUI; } +private: + QMap themesList; +}; + +class QStringList; +namespace Ui { class GUI; } class GTKConfigKCModule : public KCModule { - Q_OBJECT + Q_OBJECT public: - explicit GTKConfigKCModule(QWidget *parent = 0 ,const QVariantList &args = QVariantList() ); - ~GTKConfigKCModule(); - - void refreshThemesUi(bool useConfig = false); + explicit GTKConfigKCModule(QWidget *parent = nullptr, const QVariantList &args = QVariantList()); + ~GTKConfigKCModule() override; void save() override; void defaults() override; void load() override; -public Q_SLOTS: - void refreshLists(); - - // It is called whenever something in the UI has changed - void appChanged(); - void savePreviewConfig(); - - void showThemeGHNS(); - void installThemeGTK3GHNS(); - - void showDialogForInstall(); - void showDialogForUninstall(); - - void runGtk2IfNecessary(bool); - void runGtk3IfNecessary(bool); - void untogglePreview(); +private Q_SLOTS: + void updateThemesListsWithoutLoosingSelection(); + + void installGtk2ThemeFromGHNS(); + void installGtk3ThemeFromGHNS(); + void installGtkThemeFromFile(); + void removeGtk2Theme(); + void removeGtk3Theme(); + + void showGtk2Preview(); + void showGtk3Preview(); + + void themesSelectionsChanged(); private: - void syncUI(); - bool m_loading = false; - + void saveGtk2Theme(); + void saveGtk3Theme(); + + void loadGtkThemes(); + void loadGtk2Themes(const QStringList &possibleThemesPaths); + void loadGtk3Themes(const QStringList &possibleThemesPaths); + + static QStringList possiblePathsToGtkThemes(); + + void selectCurrentGtk2ThemeInCheckbox(); + void selectCurrentGtk3ThemeInCheckbox(); + + void updateDeletionPossibilityForSelectedGtk2Theme(); + void updateDeletionPossibilityForSelectedGtk3Theme(); + + QString currentGtk2Theme; + QString currentGtk3Theme; + GtkThemesListModel gtk2ThemesModel; + GtkThemesListModel gtk3ThemesModel; + QDBusInterface gtkConfigInterface; Ui::GUI *ui; - AppearenceGTK *appareance; - - DialogInstaller *installer; - DialogUninstaller *uninstaller; - KProcess *m_p2; - KProcess *m_p3; - QString m_tempGtk2Preview; - QString m_tempGtk3Preview; - bool m_saveEnabled; }; -#endif // MODULO_H +#endif // GTKCONFIGKCMODULE_H diff --git a/src/gtkconfigkcmodule.cpp b/src/gtkconfigkcmodule.cpp --- a/src/gtkconfigkcmodule.cpp +++ b/src/gtkconfigkcmodule.cpp @@ -20,367 +20,373 @@ * License along with this library. If not, see . */ -#include -#include #include -#include #include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include -#include -#include -#include +#include #include +#include +#include #include "config.h" #include "ui_gui.h" -#include "abstractappearance.h" #include "gtkconfigkcmodule.h" K_PLUGIN_FACTORY_WITH_JSON(GTKConfigKCModuleFactory, "kde-gtk-config.json", registerPlugin();) GTKConfigKCModule::GTKConfigKCModule(QWidget* parent, const QVariantList& args ) : KCModule(parent) + , currentGtk2Theme() + , currentGtk3Theme() + , gtk2ThemesModel() + , gtk3ThemesModel() + , gtkConfigInterface( + QStringLiteral("org.kde.GtkConfig"), + QStringLiteral("/GtkConfig"), + QStringLiteral("org.kde.GtkConfig") + ) , ui(new Ui::GUI) - , installer(0) - , uninstaller(0) - , m_saveEnabled(true) { - Q_UNUSED(args); - KAboutData *acercade = new KAboutData("cgc", i18n("GTK Application Style"), PROJECT_VERSION, + Q_UNUSED(args) + auto *about = new KAboutData("cgc", i18n("GTK Application Style"), PROJECT_VERSION, QString(), KAboutLicense::LGPL_V3, i18n("Copyright 2011 José Antonio Sánchez Reynaga")); - acercade->addAuthor(i18n("José Antonio Sánchez Reynaga (antonioJASR)"),i18n("Main Developer"), "joanzare@gmail.com"); - acercade->addAuthor(i18n("Aleix Pol i Gonzalez"), i18n("Feature development. Previews, code refactoring."), "aleixpol@blue-systems.com"); - acercade->addCredit(i18n("Manuel Tortosa (manutortosa)"), i18n("Ideas, tester, internationalization")); - acercade->addCredit(i18n("Adrián Chaves Fernández (Gallaecio)"), i18n("Internationalization")); - setAboutData(acercade); + about->addAuthor(i18n("José Antonio Sánchez Reynaga (antonioJASR)"),i18n("Main Developer"), "joanzare@gmail.com"); + about->addAuthor(i18n("Aleix Pol i Gonzalez"), i18n("Feature development. Previews, code refactoring."), "aleixpol@blue-systems.com"); + about->addCredit(i18n("Manuel Tortosa (manutortosa)"), i18n("Ideas, tester, internationalization")); + about->addCredit(i18n("Adrián Chaves Fernández (Gallaecio)"), i18n("Internationalization")); + setAboutData(about); setButtons(KCModule::Default | KCModule::Apply); ui->setupUi(this); - appareance = new AppearenceGTK; - m_tempGtk2Preview = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/gtkrc-2.0"; - m_tempGtk3Preview = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/.config/gtk-3.0/settings.ini"; - - const QIcon previewIcon = QIcon::fromTheme("document-preview"); - ui->gtk2Preview->setIcon(previewIcon); - ui->gtk3Preview->setIcon(previewIcon); - - QString gtk2Preview = QStandardPaths::findExecutable("gtk_preview", {CMAKE_INSTALL_FULL_LIBEXECDIR}); - QString gtk3Preview = QStandardPaths::findExecutable("gtk3_preview", {CMAKE_INSTALL_FULL_LIBEXECDIR}); - - m_p2 = new KProcess(this); - m_p2->setEnv("GTK2_RC_FILES", m_tempGtk2Preview, true); - if(!gtk2Preview.isEmpty()) { - *m_p2 << gtk2Preview; - connect(m_p2, SIGNAL(finished(int)), this, SLOT(untogglePreview())); - } - - m_p3 = new KProcess(this); - m_p3->setEnv("XDG_CONFIG_HOME", QStandardPaths::writableLocation(QStandardPaths::TempLocation)+"/.config"); - if(!gtk3Preview.isEmpty()) { - *m_p3 << gtk3Preview; - connect(m_p3, SIGNAL(finished(int)), this, SLOT(untogglePreview())); - } + ui->cb_theme->setModel(>k2ThemesModel); + ui->cb_theme_gtk3->setModel(>k3ThemesModel); + + connect(ui->cb_theme, SIGNAL(currentTextChanged(const QString &)), this, SLOT(themesSelectionsChanged())); + connect(ui->cb_theme_gtk3, SIGNAL(currentTextChanged(const QString &)), this, SLOT(themesSelectionsChanged())); + + connect(ui->removeGtk2Theme, &QAbstractButton::clicked, this, >KConfigKCModule::removeGtk2Theme); + connect(ui->removeGtk3Theme, &QAbstractButton::clicked, this, >KConfigKCModule::removeGtk3Theme); - ui->gtk2Preview->setVisible(!gtk2Preview.isEmpty()); - ui->gtk3Preview->setVisible(!gtk3Preview.isEmpty()); + connect(ui->gtk2Preview, &QAbstractButton::clicked, this, >KConfigKCModule::showGtk2Preview); + connect(ui->gtk3Preview, &QAbstractButton::clicked, this, >KConfigKCModule::showGtk3Preview); - // UI changes - connect(ui->cb_theme, SIGNAL(currentIndexChanged(int)), this, SLOT(appChanged())); - connect(ui->cb_theme_gtk3, SIGNAL(currentIndexChanged(int)), this, SLOT(appChanged())); + connect(ui->installFromFile, &QAbstractButton::clicked, this, >KConfigKCModule::installGtkThemeFromFile); - // Preview updates - connect(ui->gtk2Preview, &QAbstractButton::clicked, this, >KConfigKCModule::runGtk2IfNecessary); - connect(ui->gtk3Preview, &QAbstractButton::clicked, this, >KConfigKCModule::runGtk3IfNecessary); - - QMenu *m = new QMenu(this); - m->addAction(QIcon::fromTheme("get-hot-new-stuff"), i18n("Download GTK2 themes..."), this, >KConfigKCModule::showThemeGHNS); - m->addAction(QIcon::fromTheme("get-hot-new-stuff"), i18n("Download GTK3 themes..."), this, >KConfigKCModule::installThemeGTK3GHNS); - m->addAction(QIcon::fromTheme("archive-insert"), i18n("Install a local theme..."), this, >KConfigKCModule::showDialogForInstall); - m->addAction(QIcon::fromTheme("archive-remove"), i18n("Uninstall a local theme..."), this, >KConfigKCModule::showDialogForUninstall); - ui->newThemes->setMenu(m); + auto *ghnsMenu = new QMenu(this); + ghnsMenu->addAction(QIcon::fromTheme("get-hot-new-stuff"), i18n("Get New GNOME/GTK2 Application Styles..."), this, >KConfigKCModule::installGtk2ThemeFromGHNS); + ghnsMenu->addAction(QIcon::fromTheme("get-hot-new-stuff"), i18n("Get New GNOME/GTK3 Application Styles..."), this, >KConfigKCModule::installGtk3ThemeFromGHNS); + ui->newThemes->setMenu(ghnsMenu); ui->newThemes->setIcon(QIcon::fromTheme("get-hot-new-stuff")); } GTKConfigKCModule::~GTKConfigKCModule() { - m_p2->kill(); - m_p3->kill(); - - QFile::remove(m_tempGtk2Preview); - QFile::remove(m_tempGtk3Preview); - delete appareance; - - m_p2->waitForFinished(); - m_p3->waitForFinished(); delete ui; } -void GTKConfigKCModule::syncUI() +void GTKConfigKCModule::installGtk2ThemeFromGHNS() { - appareance->setThemeGtk3(ui->cb_theme_gtk3->currentText()); - appareance->setTheme(ui->cb_theme->currentText()); + KNS3::DownloadDialog downloadDialog("cgctheme.knsrc", this); + if (downloadDialog.exec()) { + updateThemesListsWithoutLoosingSelection(); + } } -void GTKConfigKCModule::showThemeGHNS() +void GTKConfigKCModule::installGtk3ThemeFromGHNS() { - KNS3::DownloadDialog d("cgctheme.knsrc", this); - if(d.exec()) { - refreshLists(); - } + KNS3::DownloadDialog downloadDialog("cgcgtk3.knsrc", this); + if (downloadDialog.exec()) { + updateThemesListsWithoutLoosingSelection(); + } } -void GTKConfigKCModule::installThemeGTK3GHNS() +void GTKConfigKCModule::installGtkThemeFromFile() { - KNS3::DownloadDialog d("cgcgtk3.knsrc", this); - if(d.exec()) { - refreshLists(); - } -} + QString themeArchivePath = QFileDialog::getOpenFileName( + this, + i18n("Select GTK Theme Archive"), + QDir::home().path(), + i18n("GTK Theme Archive (*.tar.xz *.tar.gz *.tar.bz2)") + ); + + if (themeArchivePath.isEmpty()) { + return; + } -void GTKConfigKCModule::refreshLists() -{ - refreshThemesUi(true); -} + QString themesInstallDirectoryPath(QDir::homePath() + QStringLiteral("/.themes")); + QDir::home().mkpath(themesInstallDirectoryPath); + KTar themeArchive(themeArchivePath); + themeArchive.open(QIODevice::ReadOnly); -void GTKConfigKCModule::appChanged() -{ - if (m_loading) { + QStringList archiveSubitems = themeArchive.directory()->entries(); + if (!archiveSubitems.contains(QStringLiteral("gtk-2.0")) && archiveSubitems.indexOf(QRegExp("gtk-3.*")) == -1) { + QMessageBox::warning(this, i18n("Invalid GTK Theme archive"), i18n("%1 is not a valid GTK Theme archive.", QDir(themeArchivePath).dirName())); return; } - savePreviewConfig(); - emit changed(true); -} + themeArchive.directory()->copyTo(themesInstallDirectoryPath); + updateThemesListsWithoutLoosingSelection(); +} -void GTKConfigKCModule::savePreviewConfig() +void GTKConfigKCModule::removeGtk2Theme() { - if(!m_saveEnabled || !(ui->gtk2Preview->isChecked() || ui->gtk3Preview->isChecked())) { - return; - } - - syncUI(); - - if(ui->gtk3Preview->isChecked()) { - // We don't want to recursively loop between savePreviewConfig and runIfNecessary - m_saveEnabled = false; - m_p3->kill(); - appareance->gtk3Appearance()->saveSettings(m_tempGtk3Preview); - - // Need to make sure runIfNecessary() to know that it's not running - m_p3->waitForFinished(); - - m_p3->start(); - ui->gtk3Preview->setChecked(true); - m_saveEnabled = true; - } else if(ui->gtk2Preview->isChecked()) { - appareance->gtk2Appearance()->saveSettings(m_tempGtk2Preview); - } + const QModelIndex index = gtk2ThemesModel.index(ui->cb_theme->currentIndex(), 1); + const QString themePath = gtk2ThemesModel.data(index).value(); + KIO::DeleteJob* deleteJob = KIO::del(QUrl::fromLocalFile(themePath), KIO::HideProgressInfo); + connect(deleteJob, &KJob::finished, this, >KConfigKCModule::updateThemesListsWithoutLoosingSelection); } -void GTKConfigKCModule::runGtk2IfNecessary(bool checked) +void GTKConfigKCModule::removeGtk3Theme() { - KProcess* p = m_p2; - KProcess* np = m_p3; - - if (checked) { - np->kill(); - np->waitForFinished(); - savePreviewConfig(); - if(p->state() == QProcess::NotRunning) { - p->start(); - } - } else { - p->kill(); - p->waitForFinished(); - } + const QModelIndex index = gtk3ThemesModel.index(ui->cb_theme_gtk3->currentIndex(), 1); + const QString themePath = gtk3ThemesModel.data(index).value(); + KIO::del(QUrl::fromLocalFile(themePath), KIO::HideProgressInfo); + KIO::DeleteJob* deleteJob = KIO::del(QUrl::fromLocalFile(themePath), KIO::HideProgressInfo); + connect(deleteJob, &KJob::finished, this, >KConfigKCModule::updateThemesListsWithoutLoosingSelection); } -void GTKConfigKCModule::runGtk3IfNecessary(bool checked) +void GTKConfigKCModule::showGtk2Preview() { - KProcess* p = m_p3; - KProcess* np = m_p2; - - if (checked) { - np->kill(); - np->waitForFinished(); - savePreviewConfig(); - if(p->state() == QProcess::NotRunning) { - p->start(); - } - } else { - p->kill(); - p->waitForFinished(); - } + gtkConfigInterface.call(QStringLiteral("showGtk2ThemePreview"), ui->cb_theme->currentText()); } -void GTKConfigKCModule::save() +void GTKConfigKCModule::showGtk3Preview() { - syncUI(); - if(!appareance->saveFileConfig()) { - KMessageBox::error(this, i18n("Failed to save configuration.")); - } + gtkConfigInterface.call(QStringLiteral("showGtk3ThemePreview"), ui->cb_theme_gtk3->currentText()); } -void setComboItem(QComboBox* combo, const QStringList& texts) +void GTKConfigKCModule::save() { - for (const QString &text : texts) { - int pos = combo->findText(text); - if(pos >= 0) { - combo->setCurrentIndex(pos); - return; - } - } + saveGtk2Theme(); + saveGtk3Theme(); } void GTKConfigKCModule::defaults() { - refreshThemesUi(false); + int gtk2DefaultThemeIndex = ui->cb_theme->findText(QStringLiteral("Breeze")); + ui->cb_theme->setCurrentIndex(gtk2DefaultThemeIndex); - m_saveEnabled = false; - - setComboItem(ui->cb_theme, QStringList("oxygen-gtk") << "Clearlooks"); - setComboItem(ui->cb_theme_gtk3, QStringList("oxygen-gtk") << "Adwaita"); - - m_saveEnabled = true; - - appChanged(); + int gtk3DefaultThemeIndex = ui->cb_theme_gtk3->findText(QStringLiteral("Breeze")); + ui->cb_theme_gtk3->setCurrentIndex(gtk3DefaultThemeIndex); } void GTKConfigKCModule::load() { - m_saveEnabled = false; - bool someCorrect = appareance->loadFileConfig(); - m_loading = true; - if(someCorrect) { - refreshLists(); - } else { - defaults(); - } - m_loading = false; - - m_saveEnabled = true; + loadGtkThemes(); + + selectCurrentGtk2ThemeInCheckbox(); + selectCurrentGtk3ThemeInCheckbox(); } -class MyStringListModel : public QAbstractListModel +void GTKConfigKCModule::updateThemesListsWithoutLoosingSelection() { -public: - MyStringListModel(const QStringList &texts, QObject* parent) : QAbstractListModel(parent), m_texts(texts) - { + QString currentGtk2ThemeChoice = ui->cb_theme->currentText(); + QString currentGtk3ThemeChoice = ui->cb_theme_gtk3->currentText(); + + loadGtkThemes(); + + // Restore correct gtk configuration, if the theme that was being used is deleted + if (!gtk2ThemesModel.containsTheme(currentGtk2Theme)) { + ui->cb_theme->setCurrentText(QStringLiteral("Breeze")); + saveGtk2Theme(); } - QVariant data(const QModelIndex & index, int role) const override - { - if (role != Qt::DisplayRole || !index.isValid() || index.row()>=m_texts.count()) { - return {}; - } + if (!gtk3ThemesModel.containsTheme(currentGtk3Theme)) { + ui->cb_theme_gtk3->setCurrentText(QStringLiteral("Breeze")); + saveGtk3Theme(); + } + + // Restore choices, that was before possible themes deletion + if (gtk2ThemesModel.containsTheme(currentGtk2ThemeChoice)) { + ui->cb_theme->setCurrentText(currentGtk2ThemeChoice); + } else { + ui->cb_theme->setCurrentText(QStringLiteral("Breeze")); + } - return m_texts[index.row()]; + if (gtk3ThemesModel.containsTheme(currentGtk3ThemeChoice)) { + ui->cb_theme_gtk3->setCurrentText(currentGtk3ThemeChoice); + } else { + ui->cb_theme_gtk3->setCurrentText(QStringLiteral("Breeze")); } +} - int rowCount(const QModelIndex &parent) const override { - return parent.isValid() ? 0 : m_texts.count(); +void GTKConfigKCModule::themesSelectionsChanged() +{ + if (ui->cb_theme->currentText() == currentGtk2Theme && + ui->cb_theme_gtk3->currentText() == currentGtk3Theme) { + emit changed(false); + } else { + markAsChanged(); } + updateDeletionPossibilityForSelectedGtk2Theme(); + updateDeletionPossibilityForSelectedGtk3Theme(); +} + +void GTKConfigKCModule::saveGtk2Theme() +{ + currentGtk2Theme = ui->cb_theme->currentText(); + gtkConfigInterface.call(QStringLiteral("setGtk2Theme"), currentGtk2Theme); +} - void setStrings(const QSet &list) { - const auto current = m_texts.toSet(); +void GTKConfigKCModule::saveGtk3Theme() +{ + currentGtk3Theme = ui->cb_theme_gtk3->currentText(); + gtkConfigInterface.call(QStringLiteral("setGtk3Theme"), currentGtk3Theme); +} - const auto oldRows = QSet(current).subtract(list); - const auto newRows = QSet(list).subtract(current); - if (!newRows.isEmpty()) { - beginInsertRows({}, m_texts.count(), m_texts.count() + newRows.count()); - m_texts += newRows.values(); - endInsertRows(); - } +void GTKConfigKCModule::loadGtkThemes() +{ + QStringList possibleThemesPaths = possiblePathsToGtkThemes(); + loadGtk2Themes(possibleThemesPaths); + loadGtk3Themes(possibleThemesPaths); +} - int from = -1; - for (const auto &row: oldRows) { - for(; from < m_texts.count();) { - const auto idx = m_texts.indexOf(row, from); - if (idx < 0) { - break; - } - beginRemoveRows({}, idx, idx); - m_texts.removeAt(idx); - endRemoveRows(); - from = idx + 1; - } +void GTKConfigKCModule::loadGtk2Themes(const QStringList &possibleThemesPaths) +{ + QMap gtk2ThemesNames; + + for (const QString &possibleThemePath : possibleThemesPaths) { + // If the directory has a gtk-2.0 directory inside, it is the GTK2 theme for sure + QDir possibleThemeDirectory(possibleThemePath); + bool hasGtk2DirectoryInside = possibleThemeDirectory.exists(QStringLiteral("gtk-2.0")); + if (hasGtk2DirectoryInside) { + gtk2ThemesNames.insert(possibleThemeDirectory.dirName(), possibleThemeDirectory.path()); } } -private: - QStringList m_texts; -}; + gtk2ThemesModel.setThemesList(gtk2ThemesNames); +} -void refreshComboSameCurrentValue(QComboBox* combo, const QString& temp, const QStringList& texts) +void GTKConfigKCModule::loadGtk3Themes(const QStringList &possibleThemesPaths) { - const auto model = dynamic_cast(combo->model()); - if (!model) { - combo->setModel(new MyStringListModel(texts, combo)); - } else { - model->setStrings(texts.toSet()); + QMap gtk3ThemesNames; + + static const QStringList gtk3SubdirPattern(QStringLiteral("gtk-3.*")); + for (const QString &possibleThemePath : possibleThemesPaths) { + // If the directory contains any of gtk-3.X folders, it is the GTK3 theme for sure + QDir possibleThemeDirectory(possibleThemePath); + if (!possibleThemeDirectory.entryList(gtk3SubdirPattern, QDir::Dirs).isEmpty()) { + gtk3ThemesNames.insert(possibleThemeDirectory.dirName(), possibleThemeDirectory.path()); + } } - const int idx = combo->findText(temp); - combo->setCurrentIndex(qMax(0, idx)); + gtk3ThemesModel.setThemesList(gtk3ThemesNames); } -void GTKConfigKCModule::refreshThemesUi(bool useConfig) +QStringList GTKConfigKCModule::possiblePathsToGtkThemes() { + QStringList possibleThemesPaths; + + QStringList themesLocationsPaths = QStandardPaths::locateAll( + QStandardPaths::GenericDataLocation, + QStringLiteral("themes"), + QStandardPaths::LocateDirectory); + themesLocationsPaths << QDir::homePath() + QStringLiteral("/.themes"); + + for (const QString& themesLocationPath : themesLocationsPaths) { + QStringList possibleThemesDirectoriesNames = QDir(themesLocationPath).entryList(QDir::NoDotAndDotDot | QDir::AllDirs); + for (const QString &possibleThemeDirectoryName : possibleThemesDirectoriesNames) { + possibleThemesPaths += themesLocationPath + '/' + possibleThemeDirectoryName; + } + } + + return possibleThemesPaths; +} + +void GTKConfigKCModule::selectCurrentGtk2ThemeInCheckbox() { - // Theme gtk2 - bool wasenabled = m_saveEnabled; - m_saveEnabled = false; - - refreshComboSameCurrentValue(ui->cb_theme, - useConfig ? appareance->getTheme() : ui->cb_theme->currentText(), - appareance->gtk2Appearance()->installedThemesNames()); - - // Theme gtk3 - refreshComboSameCurrentValue(ui->cb_theme_gtk3, - useConfig ? appareance->getThemeGtk3() : ui->cb_theme_gtk3->currentText(), - appareance->gtk3Appearance()->installedThemesNames()); + QDBusReply dbusReply = gtkConfigInterface.call(QStringLiteral("gtk2Theme")); + currentGtk2Theme = dbusReply.value(); + ui->cb_theme->setCurrentText(currentGtk2Theme); +} - m_saveEnabled = wasenabled; - emit changed(true); +void GTKConfigKCModule::selectCurrentGtk3ThemeInCheckbox() +{ + QDBusReply dbusReply = gtkConfigInterface.call(QStringLiteral("gtk3Theme")); + currentGtk3Theme = dbusReply.value(); + ui->cb_theme_gtk3->setCurrentText(currentGtk3Theme); } -void GTKConfigKCModule::showDialogForInstall() +void GTKConfigKCModule::updateDeletionPossibilityForSelectedGtk2Theme() { - if(!installer) { - installer = new DialogInstaller(this); - connect(installer, &DialogInstaller::themeInstalled, this, >KConfigKCModule::refreshLists); + const QModelIndex index = gtk2ThemesModel.index(ui->cb_theme->currentIndex(), 1); + const QString themePath = gtk2ThemesModel.data(index).value(); + if (themePath.contains(QDir::homePath())) { + ui->removeGtk2Theme->setDisabled(false); + } else { + ui->removeGtk2Theme->setDisabled(true); } - - installer->exec(); - refreshThemesUi(); } -void GTKConfigKCModule::showDialogForUninstall() +void GTKConfigKCModule::updateDeletionPossibilityForSelectedGtk3Theme() { - if(!uninstaller) { - uninstaller = new DialogUninstaller(this, appareance); - connect(uninstaller, &DialogUninstaller::themeUninstalled, this, >KConfigKCModule::refreshLists); + const QModelIndex index = gtk3ThemesModel.index(ui->cb_theme_gtk3->currentIndex(), 1); + const QString themePath = gtk3ThemesModel.data(index).value(); + if (themePath.contains(QDir::homePath())) { + ui->removeGtk3Theme->setDisabled(false); + } else { + ui->removeGtk3Theme->setDisabled(true); } - - uninstaller->refreshListsForUninstall(); - uninstaller->exec(); - - refreshThemesUi(); } -void GTKConfigKCModule::untogglePreview() + +GtkThemesListModel::GtkThemesListModel(QObject* parent) +: QAbstractTableModel(parent), +themesList() { - if(sender() == m_p2) { - ui->gtk2Preview->setChecked(false); + +} + +QVariant GtkThemesListModel::data(const QModelIndex& index, int role) const +{ + if (role == Qt::DisplayRole) { + if (index.row() < 0 || index.row() > themesList.count()) { + return QVariant(); + } + + if (index.column() == 0) { + return themesList.keys().at(index.row()); + } else { + return themesList.values().at(index.row()); + } } else { - ui->gtk3Preview->setChecked(false); + return QVariant(); } } +int GtkThemesListModel::rowCount(const QModelIndex& parent) const +{ + Q_UNUSED(parent) + return themesList.count(); +} + +int GtkThemesListModel::columnCount(const QModelIndex& parent) const +{ + Q_UNUSED(parent) + return 2; +} + +void GtkThemesListModel::setThemesList(const QMap& themes) +{ + beginResetModel(); + themesList = themes; + endResetModel(); +} + +bool GtkThemesListModel::containsTheme(const QString &themeName) +{ + return themesList.contains(themeName); +} + #include "gtkconfigkcmodule.moc" diff --git a/src/installer.h b/src/installer.h deleted file mode 100644 --- a/src/installer.h +++ /dev/null @@ -1,38 +0,0 @@ -/* KDE GTK Configuration Module - * - * Copyright 2011 José Antonio Sanchez Reynaga - * Copyright 2011 Aleix Pol Gonzalez - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) version 3, or any - * later version accepted by the membership of KDE e.V. (or its - * successor approved by the membership of KDE e.V.), which shall - * act as a proxy defined in Section 6 of version 3 of the license. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#ifndef INSTALLER_H -#define INSTALLER_H - -#include - -class Installer -{ -public: - /** - This function will unpack the @p urlPackage GTK theme packages wherever - it has to be installed - */ - static bool installTheme(const QString& urlPackage); -}; - -#endif // INSTALLER_H diff --git a/src/installer.cpp b/src/installer.cpp deleted file mode 100644 --- a/src/installer.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/* KDE GTK Configuration Module - * - * Copyright 2011 José Antonio Sanchez Reynaga - * Copyright 2011 Aleix Pol Gonzalez - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) version 3, or any - * later version accepted by the membership of KDE e.V. (or its - * successor approved by the membership of KDE e.V.), which shall - * act as a proxy defined in Section 6 of version 3 of the license. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#include -#include - -#include - -#include "installer.h" - -bool Installer::installTheme(const QString &urlPackage) -{ - QString dest(QDir::homePath() + QStringLiteral("/.themes")); - QDir::home().mkpath(dest); - - KTar package(urlPackage); - if(!package.open(QIODevice::ReadOnly)) { - return false; - } - package.directory()->copyTo(dest); - return true; -} diff --git a/src/thread.h b/src/thread.h deleted file mode 100644 --- a/src/thread.h +++ /dev/null @@ -1,101 +0,0 @@ -/* KDE GTK Configuration Module - * - * Copyright 2011 José Antonio Sanchez Reynaga - * Copyright 2011 Aleix Pol Gonzalez - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) version 3, or any - * later version accepted by the membership of KDE e.V. (or its - * successor approved by the membership of KDE e.V.), which shall - * act as a proxy defined in Section 6 of version 3 of the license. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#ifndef THREAD_H -#define THREAD_H - -#include -#include - -/** - Used so that we don't block the GUI when we install the themes - */ -class Thread: public KJob -{ -Q_OBJECT -public: - Thread(const QString& ); - void start() override; - - ///sets the icon path - void setUrlPackage(const QString& ); - - ///@returns whether it was successful - bool isSuccess() const; - -Q_SIGNALS: - void started(); - -private: - QString action; - QString urlPackage; -}; - -class ThreadAnalisysTheme: public KJob -{ -public: - void start() override; - - ///@returns whether the theme is correct - bool isSuccess() const; - - ///sets the theme to analyze - void setPackageTheme(const QString& ); -private: - QString packageTheme; -}; - -class ThreadAnalisysThemeIcon: public KJob -{ -public: - void start() override; - - ///@returns whether the theme is correct - bool isSuccess(); - - ///sets what theme to use - void setPackageTheme(const QString& ); -private: - QString packageTheme; -}; - -/** - Thread to erase the icons - */ -class ThreadErase: public KJob -{ -Q_OBJECT -public: - void start() override; - - bool isSuccess(); - void setThemeForErase(const QString& theme ); -private: - QString themeForErase; - -public Q_SLOTS: - void deleted(KJob*); -}; - -#endif // THREAD_H - - diff --git a/src/thread.cpp b/src/thread.cpp deleted file mode 100644 --- a/src/thread.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/* KDE GTK Configuration Module - * - * Copyright 2011 José Antonio Sanchez Reynaga - * Copyright 2011 Aleix Pol Gonzalez - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) version 3, or any - * later version accepted by the membership of KDE e.V. (or its - * successor approved by the membership of KDE e.V.), which shall - * act as a proxy defined in Section 6 of version 3 of the license. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "thread.h" - -Thread::Thread(const QString& accion) - : action(accion) -{} - -void Thread::start() -{ - emit started(); - - bool success = false; - if (urlPackage.isEmpty()) { - qWarning() << "*** ERROR: There's nothing to do"; - } else if(action == "theme") { - success = Installer::installTheme(urlPackage); - } - setError(success); - emitResult(); -} - -void Thread::setUrlPackage(const QString& package) -{ - urlPackage = package; -} - -bool Thread::isSuccess() const -{ - return error() == 0; -} - -void ThreadAnalisysTheme::start() -{ - bool success = false; - - KTar package(packageTheme); - if(!package.open(QIODevice::ReadOnly)) { - setError(1); - emitResult(); - return; - } - - // We proceed unpacking the package in a temporal directory - QDir temporal(QDir::tempPath()+"/CGC/theme"); - - // Make sure it's already created - temporal.mkpath(temporal.path()); - - package.directory()->copyTo(temporal.path()); - - // Package extracted in the temp dir. Now we want to know the name - const auto entries = temporal.entryList(QDir::AllDirs|QDir::NoDotAndDotDot); - if (entries.isEmpty()) { - qDebug() << "no files in" << temporal.path(); - setError(3); - emitResult(); - return; - } - QString folder=entries.first(); - - // We know the path of the folder to analyze - QDirIterator it(temporal.path() + '/' + folder); - - while(it.hasNext()) { - QString file = it.next(); - - if(it.fileName() == QStringLiteral("gtkrc")) { - success = true; - break; - } - } - - QUrl tempUrl = QUrl::fromLocalFile(temporal.path()); - if(!KIO::del(tempUrl, KIO::HideProgressInfo)->exec()) { - qWarning() << "There was not cleanning"; - } - - if(!success) { - setError(2); - } - emitResult(); -} - -void ThreadAnalisysTheme::setPackageTheme(const QString& theme) -{ - packageTheme = theme; -} - -bool ThreadAnalisysTheme::isSuccess() const -{ - return error() == 0; -} - -void ThreadAnalisysThemeIcon::start() -{ - bool success = false; - - KTar package(packageTheme); - if(!package.open(QIODevice::ReadOnly)) { - qWarning() << "ERROR extracting the package theme" << packageTheme; - return; - } - - QDir temporal(QDir::tempPath() + "/CGC/icon"); - temporal.mkpath(temporal.path()); - - package.directory()->copyTo(temporal.path()); - - // Archive extracted in the temp directory - QString folder= temporal.entryList(QDir::AllDirs|QDir::NoDotAndDotDot).first(); - - QDirIterator it(temporal.path()+'/'+folder); - - while(it.hasNext()) { - QString file = it.next(); - - if(it.fileName() == QStringLiteral("index.theme")) { - success = true; - break; - } - } - - QUrl tempUrl = QUrl::fromLocalFile(temporal.path()); - if(KIO::del(tempUrl, KIO::HideProgressInfo)->exec()) { - qWarning() << "Cleaning was not successful"; - } - - if(!success) - setError(2); - emitResult(); -} - -void ThreadAnalisysThemeIcon::setPackageTheme(const QString& theme) -{ - packageTheme = theme; -} - -bool ThreadAnalisysThemeIcon::isSuccess() -{ - return error() == 0; -} - -bool ThreadErase::isSuccess() -{ - return error() == 0; -} - -void ThreadErase::setThemeForErase(const QString& theme) -{ - Q_ASSERT(!theme.isEmpty()); - themeForErase = theme; -} - -void ThreadErase::start() -{ - KIO::DeleteJob* job = KIO::del(QUrl::fromLocalFile(themeForErase), KIO::HideProgressInfo); - connect(job, &KJob::finished, this, &ThreadErase::deleted); -} - -void ThreadErase::deleted(KJob* job) -{ - setError(job->error()); - setErrorText(job->errorText()); - emitResult(); -} diff --git a/src/ui/dialog_installer.ui b/src/ui/dialog_installer.ui deleted file mode 100644 --- a/src/ui/dialog_installer.ui +++ /dev/null @@ -1,190 +0,0 @@ - - - dialog_installer - - - - 0 - 0 - 518 - 332 - - - - - 0 - 0 - - - - Installer - - - - - - - - - - 0 - 0 - - - - <b>Step 2</b> - - - - - - - - 0 - 0 - - - - Select the theme file you want to install: - - - - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - true - - - - - - - - 0 - 0 - - - - Click the next button in order to install the theme in your system. - - - - - - - - 0 - 0 - - - - <b>Step 1</b> - - - - - - - false - - - Install GTK Theme - - - false - - - - - - - *.tar.gz *.tar|Compressed file - - - - - - - - - - QDialogButtonBox::Close - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - KUrlRequester - QWidget -
kurlrequester.h
-
-
- - - - buttonBox - accepted() - dialog_installer - accept() - - - 387 - 312 - - - 362 - 300 - - - - - buttonBox - rejected() - dialog_installer - reject() - - - 484 - 318 - - - 518 - 296 - - - - -
diff --git a/src/ui/dialog_uninstaller.ui b/src/ui/dialog_uninstaller.ui deleted file mode 100644 --- a/src/ui/dialog_uninstaller.ui +++ /dev/null @@ -1,145 +0,0 @@ - - - dialog_uninstaller - - - - 0 - 0 - 608 - 335 - - - - Remove Themes - - - - - - - 460 - 0 - - - - - 16777 - 16777215 - - - - - - - - - - Select a GTK theme to uninstall - - - - - - - - 150 - 0 - - - - - - - - Uninstall - - - - - - - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 75 - true - - - - Remove GTK Theme - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - QDialogButtonBox::Close - - - - - - - - - buttonBox - accepted() - dialog_uninstaller - accept() - - - 539 - 320 - - - 528 - 290 - - - - - buttonBox - rejected() - dialog_uninstaller - reject() - - - 431 - 325 - - - 426 - 281 - - - - - diff --git a/src/ui/gui.ui b/src/ui/gui.ui --- a/src/ui/gui.ui +++ b/src/ui/gui.ui @@ -48,12 +48,27 @@ - - - Preview Theme + + + + + + + .. + + + + + + + Preview... + + + + .. - true + false @@ -79,12 +94,27 @@ - - - Preview Theme + + + + + + + .. + + + + + + + Preview... + + + + .. - true + false @@ -135,6 +165,17 @@ + + + + Install from File... + + + + .. + + + diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt deleted file mode 100644 --- a/tests/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -macro(add_kgc_test name) - add_executable(${name} ${name}.cpp ${ARGV}) - add_test(${name} ${name}) - ecm_mark_as_test(${name}) - target_link_libraries(${name} ${GIO2_LIBRARY} ${GLIB2_LIBRARY} ${GTK3_LIBRARY} ${GOBJECT2_LIBRARY} Qt5::Core Qt5::Gui Qt5::Test KF5::ConfigCore) - target_compile_definitions(${name} PUBLIC -DQT_NO_SIGNALS_SLOTS_KEYWORDS) - target_include_directories(${name} PRIVATE ${CMAKE_BINARY_DIR}) -endmacro(add_kgc_test) - -add_kgc_test(configsavetest ../src/abstractappearance.cpp ../src/appearancegtk2.cpp ../src/appearancegtk3.cpp) diff --git a/tests/configsavetest.h b/tests/configsavetest.h deleted file mode 100644 --- a/tests/configsavetest.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * - */ - -#ifndef CONFIGSAVETEST_H -#define CONFIGSAVETEST_H - -#include - -class ConfigSaveTest : public QObject -{ - Q_OBJECT -public: - ConfigSaveTest(); -private Q_SLOTS: - void testGtk2(); - void testGtk3(); -}; - -#endif // CONFIGSAVETEST_H diff --git a/tests/configsavetest.cpp b/tests/configsavetest.cpp deleted file mode 100644 --- a/tests/configsavetest.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - * - */ -#include "configsavetest.h" -#include -#include - -#include - -QTEST_GUILESS_MAIN(ConfigSaveTest); - -ConfigSaveTest::ConfigSaveTest() -{ - QStandardPaths::setTestModeEnabled(true); -} - -static void fillValues(QScopedPointer& a) -{ - a->setTheme("a"); -} - -void compareAppearances(QScopedPointer& reloaded, QScopedPointer& instance) -{ - QCOMPARE(reloaded->getTheme(), instance->getTheme()); -} - -QByteArray readFile(const QString& path) -{ - QFile f(path); - if(!f.open(QFile::ReadOnly | QFile::Text)) - return QByteArray(); - return f.readAll(); -} - -void ConfigSaveTest::testGtk2() -{ - const QString pathA = QDir::current().absoluteFilePath("test-gtk2") - , pathB = QDir::current().absoluteFilePath("testB-gtk2"); - - QScopedPointer instance(new AppearanceGTK2); - fillValues(instance); - QVERIFY(instance->saveSettings(pathA)); - - QScopedPointer reloaded(new AppearanceGTK2); - QVERIFY(reloaded->loadSettings(pathA)); - compareAppearances(reloaded, instance); - QVERIFY(reloaded->saveSettings(pathB)); - QCOMPARE(readFile(pathA), readFile(pathB)); -} - -void ConfigSaveTest::testGtk3() -{ - QScopedPointer instance(new AppearanceGTK3); - fillValues(instance); - const QString pathA = QDir::current().absoluteFilePath("test-gtk3") - , pathB = QDir::current().absoluteFilePath("testB-gtk3"); - QVERIFY(instance->saveSettings(pathA)); - - QScopedPointer reloaded(new AppearanceGTK3); - QVERIFY(QFile::exists(pathA)); - QVERIFY(reloaded->loadSettings(pathA)); - compareAppearances(reloaded, instance); - QVERIFY(reloaded->saveSettings(pathB)); - - QCOMPARE(readFile(pathA), readFile(pathB)); -}