From 0d0f812a1704c62c014bc87162b1280224b64f93 Mon Sep 17 00:00:00 2001 From: Fabian Vogt Date: Tue, 24 Oct 2017 13:25:32 +0200 Subject: Revert "Make the kde-gtk-config kcm better at checking global gtk settings" Summary: This reverts commit 34357f74ee2d98128ff423b0ec6ddcbf4232c475. Reverting this fixes loading of the actually used GTK settings. BUG: 382291 Test Plan: Opened kcmshell5 kde-gtk-config with and without this revert. Without, it shows Adwaita as theme, with it shows breeze. GTK uses breeze, so the behaviour with the revert is correct. Reviewers: #plasma, apol Subscribers: plasma-devel Tags: #plasma Differential Revision: https://phabricator.kde.org/D8443 --- CMakeLists.txt | 2 +- src/abstractappearance.h | 5 +- src/appearancegtk2.cpp | 103 +++++++++++++--------------------- src/appearancegtk2.h | 11 +--- src/appearancegtk3.cpp | 143 +++++++++++++++++++++-------------------------- src/appearancegtk3.h | 10 +--- src/appearencegtk.cpp | 4 +- tests/CMakeLists.txt | 2 +- tests/configsavetest.cpp | 75 ++++++++++--------------- tests/configsavetest.h | 8 +-- 10 files changed, 144 insertions(+), 219 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 181cfc9..bf1ba29 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,7 +51,7 @@ ki18n_wrap_ui(kcm_SRCS ) 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} KF5::ConfigCore KF5::I18n KF5::KIOWidgets KF5::NewStuff KF5::Archive KF5::NewStuff KF5::ConfigWidgets KF5::IconThemes) +target_link_libraries(kcm_kdegtkconfig ${X11_Xcursor_LIB} KF5::I18n KF5::KIOWidgets KF5::NewStuff KF5::Archive KF5::NewStuff KF5::ConfigWidgets KF5::IconThemes) kcoreaddons_desktop_to_json(kcm_kdegtkconfig kde-gtk-config.desktop) diff --git a/src/abstractappearance.h b/src/abstractappearance.h index 208342e..2961a09 100644 --- a/src/abstractappearance.h +++ b/src/abstractappearance.h @@ -30,11 +30,10 @@ class AbstractAppearance { public: virtual ~AbstractAppearance() {} - virtual bool loadSettings() = 0; - virtual bool saveSettings() const = 0; + virtual QString defaultConfigFile() 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; diff --git a/src/appearancegtk2.cpp b/src/appearancegtk2.cpp index 92cbee3..44a2239 100644 --- a/src/appearancegtk2.cpp +++ b/src/appearancegtk2.cpp @@ -30,38 +30,48 @@ #include #include -bool AppearanceGTK2::loadSettingsPrivate(const QString& path) +bool AppearanceGTK2::loadSettings(const QString& path) { QFile configFile(path); - if (!configFile.open(QIODevice::ReadOnly | QIODevice::Text)) - return false; + bool canRead = configFile.open(QIODevice::ReadOnly | QIODevice::Text); - const QMap foundSettings = readSettingsTuples(&configFile); - - for(auto it = foundSettings.constBegin(), itEnd = foundSettings.constEnd(); it!=itEnd; ++it) { - if (it.key() == "gtk-theme-name") - m_settings["theme"] = *it; - else if (it.key() == "gtk-icon-theme-name") - m_settings["icon"] = *it; - else if (it.key() == "gtk-fallback-icon-theme") - m_settings["icon_fallback"] = *it; - else if (it.key() == "gtk-cursor-theme-name") - m_settings["cursor"] = *it; - else if (it.key() == "gtk-font-name") - m_settings["font"] = *it; - else if (it.key() == "gtk-toolbar-style") - m_settings["toolbar_style"] = *it; - else if (it.key() == "gtk-button-images") - m_settings["show_icons_buttons"] = *it; - else if(it.key() == "gtk-menu-images") - m_settings["show_icons_menus"] = *it; - else if (it.key() == "gtk-primary-button-warps-slider") - m_settings["primary_button_warps_slider"] = *it; - else - qWarning() << "unknown field" << it.key(); + if(canRead) { +// qDebug() << "The gtk2 config file exists..."; + const QMap foundSettings = readSettingsTuples(&configFile); + m_settings = QMap { + {"toolbar_style", "GTK_TOOLBAR_ICONS"}, + {"show_icons_buttons", "0"}, + {"show_icons_menus", "0"}, + {"primary_button_warps_slider", "false"} + }; + + for(auto it = foundSettings.constBegin(), itEnd = foundSettings.constEnd(); it!=itEnd; ++it) { + if (it.key() == "gtk-theme-name") + m_settings["theme"] = *it; + else if (it.key() == "gtk-icon-theme-name") + m_settings["icon"] = *it; + else if (it.key() == "gtk-fallback-icon-theme") + m_settings["icon_fallback"] = *it; + else if (it.key() == "gtk-cursor-theme-name") + m_settings["cursor"] = *it; + else if (it.key() == "gtk-font-name") + m_settings["font"] = *it; + else if (it.key() == "gtk-toolbar-style") + m_settings["toolbar_style"] = *it; + else if (it.key() == "gtk-button-images") + m_settings["show_icons_buttons"] = *it; + else if(it.key() == "gtk-menu-images") + m_settings["show_icons_menus"] = *it; + else if (it.key() == "gtk-primary-button-warps-slider") + m_settings["primary_button_warps_slider"] = *it; + else + qWarning() << "unknown field" << it.key(); + } + } - return true; + + return canRead; } QString AppearanceGTK2::themesGtkrcFile(const QString& themeName) const @@ -82,7 +92,7 @@ QString AppearanceGTK2::themesGtkrcFile(const QString& themeName) const return QString(); } -bool AppearanceGTK2::saveSettingsPrivate(const QString& gtkrcFile) const +bool AppearanceGTK2::saveSettings(const QString& gtkrcFile) const { QFile gtkrc(gtkrcFile); gtkrc.remove(); @@ -107,14 +117,14 @@ bool AppearanceGTK2::saveSettingsPrivate(const QString& gtkrcFile) const flow << "include \"/etc/gtk-2.0/gtkrc\"\n"; //We include the /etc's config file int nameEnd = m_settings["font"].lastIndexOf(QRegExp(" ([0-9]+|bold|italic)")); - const auto fontFamily = m_settings["font"].leftRef(nameEnd); + QString fontFamily = m_settings["font"].left(nameEnd); //TODO: is this really needed? flow << "style \"user-font\" \n" << "{\n" << "\tfont_name=\""<< fontFamily << "\"\n" << "}\n"; - + flow << "widget_class \"*\" style \"user-font\"\n"; flow << "gtk-font-name=\"" << m_settings["font"] << "\"\n"; flow << "gtk-theme-name=\"" << m_settings["theme"] << "\"\n"; @@ -144,16 +154,6 @@ bool AppearanceGTK2::saveSettingsPrivate(const QString& gtkrcFile) const return true; } -void AppearanceGTK2::reset() -{ - m_settings = QMap { - {"toolbar_style", "GTK_TOOLBAR_ICONS"}, - {"show_icons_buttons", "0"}, - {"show_icons_menus", "0"}, - {"primary_button_warps_slider", "false"} - }; -} - QString AppearanceGTK2::defaultConfigFile() const { return QDir::homePath()+"/.gtkrc-2.0"; @@ -183,26 +183,3 @@ QStringList AppearanceGTK2::installedThemes() const return paths; } - -bool AppearanceGTK2::loadSettings() -{ - reset(); - - return loadSettingsPrivate("/etc/gtk-2.0/gtkrc") && loadSettingsPrivate(defaultConfigFile()); -} - -bool AppearanceGTK2::saveSettings() const -{ - return saveSettings(defaultConfigFile()); -} - -bool AppearanceGTK2::loadSettings(const QString& gtkrcFile) -{ - reset(); - return loadSettingsPrivate(gtkrcFile); -} - -bool AppearanceGTK2::saveSettings(const QString& gtkrcFile) const -{ - return saveSettingsPrivate(gtkrcFile); -} diff --git a/src/appearancegtk2.h b/src/appearancegtk2.h index 7df49bf..8bc28ee 100644 --- a/src/appearancegtk2.h +++ b/src/appearancegtk2.h @@ -29,17 +29,10 @@ class AppearanceGTK2 : public AbstractAppearance { bool loadSettings(const QString& path) override; bool saveSettings(const QString& path) const override; - bool loadSettings() override; - bool saveSettings() const override; + QString defaultConfigFile() 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; }; #endif // APPEARANCEGTK2_H diff --git a/src/appearancegtk3.cpp b/src/appearancegtk3.cpp index 7df48c3..fa1bde5 100644 --- a/src/appearancegtk3.cpp +++ b/src/appearancegtk3.cpp @@ -25,8 +25,6 @@ #include #include #include -#include -#include QStringList AppearanceGTK3::installedThemes() const { @@ -53,65 +51,76 @@ QStringList AppearanceGTK3::installedThemes() const return themes; } -bool AppearanceGTK3::saveSettings(const KSharedConfig::Ptr& file) const -{ - KConfigGroup group(file, "Settings"); - - group.writeEntry("gtk-font-name", m_settings["font"]); - group.writeEntry("gtk-theme-name", m_settings["theme"]); - group.writeEntry("gtk-icon-theme-name", m_settings["icon"]); - group.writeEntry("gtk-fallback-icon-theme", m_settings["icon_fallback"]); - group.writeEntry("gtk-cursor-theme-name", m_settings["cursor"]); - group.writeEntry("gtk-toolbar-style", m_settings["toolbar_style"]); - group.writeEntry("gtk-menu-images", m_settings["show_icons_menus"]); - group.writeEntry("gtk-button-images", m_settings["show_icons_buttons"]); - group.writeEntry("gtk-primary-button-warps-slider", m_settings["primary_button_warps_slider"]); - group.writeEntry("gtk-application-prefer-dark-theme", m_settings["application_prefer_dark_theme"]); - - const bool sync = group.sync(); - Q_ASSERT(sync); - return true; -} - -bool AppearanceGTK3::loadSettings(const KSharedConfig::Ptr& file) +bool AppearanceGTK3::saveSettings(const QString& file) const { - KConfigGroup group(file, "Settings"); - - if (!file || !group.isValid()) { - qWarning() << "Cannot open the GTK3 config file" << file; + //Opening GTK3 config file $ENV{XDG_CONFIG_HOME}/gtk-3.0/m_settings.ini + QDir::home().mkpath(file.left(file.lastIndexOf('/'))); //we make sure the path exists + QFile file_gtk3(file); + + if(!file_gtk3.open(QIODevice::WriteOnly | QIODevice::Text)) { + qWarning() << "Couldn't open GTK3 config file for writing at:" << file_gtk3.fileName(); return false; } + QTextStream flow3(&file_gtk3); + flow3 << "[Settings]\n"; + flow3 << "gtk-font-name=" << m_settings["font"] << "\n"; + flow3 << "gtk-theme-name=" << m_settings["theme"] << "\n"; + flow3 << "gtk-icon-theme-name="<< m_settings["icon"] << "\n"; + flow3 << "gtk-fallback-icon-theme=" << m_settings["icon_fallback"] << "\n"; + flow3 << "gtk-cursor-theme-name=" << m_settings["cursor"] << "\n"; + flow3 << "gtk-toolbar-style=" << m_settings["toolbar_style"] << "\n"; + flow3 << "gtk-menu-images=" << m_settings["show_icons_menus"] << "\n"; + flow3 << "gtk-button-images=" << m_settings["show_icons_buttons"] << "\n"; + flow3 << "gtk-primary-button-warps-slider=" << m_settings["primary_button_warps_slider"] << "\n"; + flow3 << "gtk-application-prefer-dark-theme=" << m_settings["application_prefer_dark_theme"] << "\n"; - m_settings = QMap { - {"toolbar_style", "GTK_TOOLBAR_ICONS"}, - {"show_icons_buttons", "0"}, - {"show_icons_menus", "0"}, - {"primary_button_warps_slider", "false"}, - {"application_prefer_dark_theme", "false"} - }; - - m_settings["theme"] = group.readEntry("gtk-theme-name"); - m_settings["icon"] = group.readEntry("gtk-icon-theme-name"); - m_settings["icon_fallback"] = group.readEntry("gtk-fallback-icon-theme"); - m_settings["cursor"] = group.readEntry("gtk-cursor-theme-name"); - m_settings["font"] = group.readEntry("gtk-font-name"); - m_settings["toolbar_style"] = group.readEntry("gtk-toolbar-style"); - m_settings["show_icons_buttons"] = group.readEntry("gtk-button-images"); - m_settings["show_icons_menus"] = group.readEntry("gtk-menu-images"); - m_settings["primary_button_warps_slider"] = group.readEntry("gtk-primary-button-warps-slider"); - m_settings["application_prefer_dark_theme"] = group.readEntry("gtk-application-prefer-dark-theme"); - 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 +bool AppearanceGTK3::loadSettings(const QString& path) { - return QStringLiteral("gtk-3.0/settings.ini"); + QFile fileGtk3(path); + bool canRead=fileGtk3.open(QIODevice::ReadOnly | QIODevice::Text); + + if(canRead) { + const QMap foundSettings = readSettingsTuples(&fileGtk3); + + m_settings = QMap { + {"toolbar_style", "GTK_TOOLBAR_ICONS"}, + {"show_icons_buttons", "0"}, + {"show_icons_menus", "0"}, + {"primary_button_warps_slider", "false"}, + {"application_prefer_dark_theme", "false"} + }; + + for(auto it = foundSettings.constBegin(), itEnd = foundSettings.constEnd(); it!=itEnd; ++it) { + if (it.key() == "gtk-theme-name") + m_settings["theme"] = *it; + else if (it.key() == "gtk-icon-theme-name") + m_settings["icon"] = *it; + else if (it.key() == "gtk-fallback-icon-theme") + m_settings["icon_fallback"] = *it; + else if (it.key() == "gtk-cursor-theme-name") + m_settings["cursor"] = *it; + else if (it.key() == "gtk-font-name") + m_settings["font"] = *it; + else if (it.key() == "gtk-toolbar-style") + m_settings["toolbar_style"] = *it; + else if (it.key() == "gtk-button-images") + m_settings["show_icons_buttons"] = *it; + else if (it.key() == "gtk-menu-images") + m_settings["show_icons_menus"] = *it; + else if (it.key() == "gtk-primary-button-warps-slider") + m_settings["primary_button_warps_slider"] = *it; + else if (it.key() == "gtk-application-prefer-dark-theme") + m_settings["application_prefer_dark_theme"] = *it; + else + qWarning() << "unknown field" << it.key(); + } + } else + qWarning() << "Cannot open the GTK3 config file" << path; + + return canRead; } QString AppearanceGTK3::defaultConfigFile() const @@ -120,7 +129,7 @@ QString AppearanceGTK3::defaultConfigFile() const if(root.isEmpty()) root = QFileInfo(QDir::home(), ".config").absoluteFilePath(); - return root + '/' + configFileName(); + return root+"/gtk-3.0/settings.ini"; } bool AppearanceGTK3::getApplicationPreferDarkTheme() const @@ -132,29 +141,3 @@ void AppearanceGTK3::setApplicationPreferDarkTheme(const bool& enable) { m_settings["application_prefer_dark_theme"] = enable ? "true" : "false"; } - -bool AppearanceGTK3::saveSettings(const QString& file) const -{ - auto cfg = KSharedConfig::openConfig(file); - return saveSettings(cfg); -} - -bool AppearanceGTK3::loadSettings(const QString& path) -{ - auto cfg = KSharedConfig::openConfig(path); - return loadSettings(cfg); -} - -bool AppearanceGTK3::loadSettings() -{ - auto cfg = KSharedConfig::openConfig(configFileName()); - cfg->setReadDefaults(true); - return loadSettings(cfg); -} - -bool AppearanceGTK3::saveSettings() const -{ - auto cfg = KSharedConfig::openConfig(configFileName()); - cfg->setReadDefaults(true); - return saveSettings(cfg); -} diff --git a/src/appearancegtk3.h b/src/appearancegtk3.h index 3ce5a05..d4562b1 100644 --- a/src/appearancegtk3.h +++ b/src/appearancegtk3.h @@ -23,7 +23,6 @@ #ifndef APPEARANCEGTK3_H #define APPEARANCEGTK3_H -#include #include "abstractappearance.h" class AppearanceGTK3 : public AbstractAppearance @@ -31,18 +30,11 @@ 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; + QString defaultConfigFile() const override; bool getApplicationPreferDarkTheme() const; void setApplicationPreferDarkTheme(const bool& enable); - -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/appearencegtk.cpp b/src/appearencegtk.cpp index 95a6604..2e26a5a 100644 --- a/src/appearencegtk.cpp +++ b/src/appearencegtk.cpp @@ -64,7 +64,7 @@ bool AppearenceGTK::loadFileConfig() { bool correct = false; foreach(AbstractAppearance* app, m_app) { - bool c = app->loadSettings(); + bool c = app->loadSettings(app->defaultConfigFile()); correct = correct || c; } // qDebug() << "loading..." << correct; @@ -75,7 +75,7 @@ bool AppearenceGTK::saveFileConfig() { bool correct = true; foreach(AbstractAppearance* app, m_app) { - bool c = app->saveSettings(); + bool c = app->saveSettings(app->defaultConfigFile()); correct = correct && c; } // qDebug() << "saving..." << correct; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 151725d..05bf8f1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -2,7 +2,7 @@ macro(add_kgc_test name) add_executable(${name} ${name}.cpp ${ARGV}) add_test(${name} ${name}) ecm_mark_as_test(${name}) - target_link_libraries(${name} Qt5::Core Qt5::Gui Qt5::Test KF5::ConfigCore) + target_link_libraries(${name} Qt5::Core Qt5::Gui Qt5::Test) target_include_directories(${name} PRIVATE ${CMAKE_BINARY_DIR}) endmacro(add_kgc_test) diff --git a/tests/configsavetest.cpp b/tests/configsavetest.cpp index 1fe8f4f..d5d8460 100644 --- a/tests/configsavetest.cpp +++ b/tests/configsavetest.cpp @@ -9,40 +9,33 @@ QTEST_GUILESS_MAIN(ConfigSaveTest); -ConfigSaveTest::ConfigSaveTest() -{ - QStandardPaths::setTestModeEnabled(true); -} - -static void fillValues(QScopedPointer& a) +void ConfigSaveTest::fillValues(AbstractAppearance* a) { a->setFont("a"); a->setIcon("a"); a->setTheme("a"); a->setToolbarStyle("a"); a->setIconFallback("a"); - a->setCursor("a"); a->setShowIconsInButtons(true); a->setShowIconsInMenus(true); a->setPrimaryButtonWarpsSlider(true); - auto a3 = dynamic_cast(a.data()); + auto a3 = dynamic_cast(a); if (a3) { a3->setApplicationPreferDarkTheme(false); } } -void compareAppearances(QScopedPointer& reloaded, QScopedPointer& instance) +bool compareAppearances(AbstractAppearance* a, AbstractAppearance* b) { - QCOMPARE(reloaded->getFont(), instance->getFont()); - QCOMPARE(reloaded->getIcon(), instance->getIcon()); - QCOMPARE(reloaded->getTheme(), instance->getTheme()); - QCOMPARE(reloaded->getCursor(), instance->getCursor()); - QCOMPARE(reloaded->getToolbarStyle(), instance->getToolbarStyle()); - QCOMPARE(reloaded->getIconFallback(), instance->getIconFallback()); - QCOMPARE(reloaded->getShowIconsInButtons(), instance->getShowIconsInButtons()); - QCOMPARE(reloaded->getShowIconsInMenus(), instance->getShowIconsInMenus()); - QCOMPARE(reloaded->getPrimaryButtonWarpsSlider(), instance->getPrimaryButtonWarpsSlider()); + return a->getFont() == b->getFont() + && a->getIcon() == b->getIcon() + && a->getTheme() == b->getTheme() + && a->getToolbarStyle() == b->getToolbarStyle() + && a->getIconFallback() == b->getIconFallback() + && a->getShowIconsInButtons() == b->getShowIconsInButtons() + && a->getShowIconsInMenus() == b->getShowIconsInMenus() + && a->getPrimaryButtonWarpsSlider() == b->getPrimaryButtonWarpsSlider(); } QByteArray readFile(const QString& path) @@ -53,35 +46,23 @@ QByteArray readFile(const QString& path) return f.readAll(); } -void ConfigSaveTest::testGtk2() +void ConfigSaveTest::testOpen() { - 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)); + QVector instances; + instances << new AppearanceGTK2 << new AppearanceGTK3; + fillValues(instances[0]); + fillValues(instances[1]); + QVERIFY(instances[0]->saveSettings("test-gtk2")); + QVERIFY(instances[1]->saveSettings("test-gtk3")); - QCOMPARE(readFile(pathA), readFile(pathB)); + QVector reloaded; + reloaded << new AppearanceGTK2 << new AppearanceGTK3; + QVERIFY(reloaded[0]->loadSettings("test-gtk2")); + QVERIFY(reloaded[1]->loadSettings("test-gtk3")); + QVERIFY(compareAppearances(reloaded[0], instances[0])); + QVERIFY(compareAppearances(reloaded[1], instances[1])); + QVERIFY(reloaded[0]->saveSettings("testB-gtk2")); + QVERIFY(reloaded[1]->saveSettings("testB-gtk3")); + QCOMPARE(readFile("test-gtk2"), readFile("testB-gtk2")); + QCOMPARE(readFile("test-gtk3"), readFile("testB-gtk3")); } diff --git a/tests/configsavetest.h b/tests/configsavetest.h index 342b408..39fb4c2 100644 --- a/tests/configsavetest.h +++ b/tests/configsavetest.h @@ -11,11 +11,11 @@ class AbstractAppearance; class ConfigSaveTest : public QObject { Q_OBJECT -public: - ConfigSaveTest(); private slots: - void testGtk2(); - void testGtk3(); + void testOpen(); + +private: + void fillValues(AbstractAppearance* a); }; #endif // CONFIGSAVETEST_H -- cgit v0.11.2