diff --git a/kcms/style/kcmstyle.cpp b/kcms/style/kcmstyle.cpp index ba11d6793..abd051c8d 100644 --- a/kcms/style/kcmstyle.cpp +++ b/kcms/style/kcmstyle.cpp @@ -1,328 +1,310 @@ /* * KCMStyle * Copyright (C) 2002 Karol Szwed * Copyright (C) 2002 Daniel Molkentin * Copyright (C) 2007 Urs Wolfer * Copyright (C) 2009 by Davide Bettio * Copyright (C) 2019 Kai Uwe Broulik * Copyright (C) 2019 Cyril Rossi * * Portions Copyright (C) 2007 Paolo Capriotti * Portions Copyright (C) 2007 Ivan Cukic * Portions Copyright (C) 2008 by Petri Damsten * Portions Copyright (C) 2000 TrollTech AS. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License version 2 as published by the Free Software Foundation. * * 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; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kcmstyle.h" #include "styleconfdialog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../krdb/krdb.h" #include "stylesmodel.h" #include "previewitem.h" #include "stylesettings.h" K_PLUGIN_FACTORY_WITH_JSON(KCMStyleFactory, "kcm_style.json", registerPlugin();) extern "C" { Q_DECL_EXPORT void kcminit_style() { uint flags = KRdbExportQtSettings | KRdbExportGtkColors | KRdbExportQtColors | KRdbExportXftSettings | KRdbExportGtkTheme; KConfig _config( QStringLiteral("kcmdisplayrc"), KConfig::NoGlobals ); KConfigGroup config(&_config, "X11"); // This key is written by the "colors" module. bool exportKDEColors = config.readEntry("exportKDEColors", true); - if (exportKDEColors) + if (exportKDEColors) { flags |= KRdbExportColors; + } runRdb( flags ); } } KCMStyle::KCMStyle(QObject *parent, const QVariantList &args) - : KQuickAddons::ConfigModule(parent, args) + : KQuickAddons::ManagedConfigModule(parent, args) , m_settings(new StyleSettings(this)) , m_model(new StylesModel(this)) { qmlRegisterUncreatableType("org.kde.private.kcms.style", 1, 0, "KCM", QStringLiteral("Cannot create instances of KCM")); qmlRegisterType(); qmlRegisterType(); qmlRegisterType("org.kde.private.kcms.style", 1, 0, "PreviewItem"); KAboutData *about = new KAboutData( QStringLiteral("kcm_style"), i18n("Application Style"), QStringLiteral("2.0"), QString(), KAboutLicense::GPL, i18n("(c) 2002 Karol Szwed, Daniel Molkentin, (c) 2019 Kai Uwe Broulik")); about->addAuthor(i18n("Karol Szwed"), QString(), QStringLiteral("gallium@kde.org")); about->addAuthor(i18n("Daniel Molkentin"), QString(), QStringLiteral("molkentin@kde.org")); about->addAuthor(i18n("Kai Uwe Broulik"), QString(), QStringLiteral("kde@broulik.de")); setAboutData(about); - connect(m_model, &StylesModel::selectedStyleChanged, this, [this] { - m_selectedStyleDirty = true; - setNeedsSave(true); + connect(m_model, &StylesModel::selectedStyleChanged, this, [this](const QString &style) { + m_settings->setWidgetStyle(style); + }); + connect(m_settings, &StyleSettings::widgetStyleChanged, this, [this] { + m_model->setSelectedStyle(m_settings->widgetStyle()); }); connect(m_settings, &StyleSettings::iconsOnButtonsChanged, this, [this] { m_effectsDirty = true; - setNeedsSave(true); }); connect(m_settings, &StyleSettings::iconsInMenusChanged, this, [this] { m_effectsDirty = true; - setNeedsSave(true); }); } KCMStyle::~KCMStyle() = default; StylesModel *KCMStyle::model() const { return m_model; } StyleSettings *KCMStyle::styleSettings() const { return m_settings; } KCMStyle::ToolBarStyle KCMStyle::mainToolBarStyle() const { return m_mainToolBarStyle; } void KCMStyle::setMainToolBarStyle(ToolBarStyle style) { if (m_mainToolBarStyle != style) { m_mainToolBarStyle = style; emit mainToolBarStyleChanged(); + const QMetaEnum toolBarStyleEnum = QMetaEnum::fromType(); + m_settings->setToolButtonStyle(toolBarStyleEnum.valueToKey(m_mainToolBarStyle)); m_effectsDirty = true; - setNeedsSave(true); } } KCMStyle::ToolBarStyle KCMStyle::otherToolBarStyle() const { return m_otherToolBarStyle; } void KCMStyle::setOtherToolBarStyle(ToolBarStyle style) { if (m_otherToolBarStyle != style) { m_otherToolBarStyle = style; emit otherToolBarStyleChanged(); + const QMetaEnum toolBarStyleEnum = QMetaEnum::fromType(); + m_settings->setToolButtonStyleOtherToolbars(toolBarStyleEnum.valueToKey(m_otherToolBarStyle)); m_effectsDirty = true; - setNeedsSave(true); } } void KCMStyle::configure(const QString &styleName, QQuickItem *ctx) { if (m_styleConfigDialog) { return; } const QString configPage = m_model->styleConfigPage(styleName); if (configPage.isEmpty()) { return; } QLibrary library(KPluginLoader::findPlugin(configPage)); if (!library.load()) { qWarning() << "Failed to load style config page" << configPage << library.errorString(); emit showErrorMessage(i18n("There was an error loading the configuration dialog for this style.")); return; } auto allocPtr = library.resolve("allocate_kstyle_config"); if (!allocPtr) { qWarning() << "Failed to resolve allocate_kstyle_config in" << configPage; emit showErrorMessage(i18n("There was an error loading the configuration dialog for this style.")); return; } m_styleConfigDialog = new StyleConfigDialog(nullptr/*this*/, configPage); m_styleConfigDialog->setAttribute(Qt::WA_DeleteOnClose); m_styleConfigDialog->setWindowModality(Qt::WindowModal); m_styleConfigDialog->winId(); // so it creates windowHandle if (ctx && ctx->window()) { if (QWindow *actualWindow = QQuickRenderControl::renderWindowFor(ctx->window())) { m_styleConfigDialog->windowHandle()->setTransientParent(actualWindow); } } typedef QWidget*(* factoryRoutine)( QWidget* parent ); //Get the factory, and make the widget. factoryRoutine factory = (factoryRoutine)(allocPtr); //Grmbl. So here I am on my //"never use C casts" moralizing streak, and I find that one can't go void* -> function ptr //even with a reinterpret_cast. QWidget* pluginConfig = factory( m_styleConfigDialog.data() ); //Insert it in... m_styleConfigDialog->setMainWidget( pluginConfig ); //..and connect it to the wrapper connect(pluginConfig, SIGNAL(changed(bool)), m_styleConfigDialog.data(), SLOT(setDirty(bool))); connect(m_styleConfigDialog.data(), SIGNAL(defaults()), pluginConfig, SLOT(defaults())); connect(m_styleConfigDialog.data(), SIGNAL(save()), pluginConfig, SLOT(save())); connect(m_styleConfigDialog.data(), &QDialog::accepted, this, [this, styleName] { if (!m_styleConfigDialog->isDirty()) { return; } // Force re-rendering of the preview, to apply settings emit styleReconfigured(styleName); //For now, ask all KDE apps to recreate their styles to apply the setitngs KGlobalSettings::self()->emitChange(KGlobalSettings::StyleChanged); // When user edited a style, assume they want to use it, too - m_model->setSelectedStyle(styleName); + m_settings->setWidgetStyle(styleName); - // We call setStyleDirty here to make sure we force style re-creation - m_selectedStyleDirty = true; + // We call setNeedsSave(true) here to make sure we force style re-creation setNeedsSave(true); }); m_styleConfigDialog->show(); } void KCMStyle::load() { + ManagedConfigModule::load(); m_model->load(); - - m_settings->load(); + m_previousStyle = m_settings->widgetStyle(); loadSettingsToModel(); - m_selectedStyleDirty = false; m_effectsDirty = false; - setNeedsSave(false); } void KCMStyle::save() { - if (!m_selectedStyleDirty && !m_effectsDirty) { - return; - } - // Check whether the new style can actually be loaded before saving it. // Otherwise apps will use the default style despite something else having been written to the config bool newStyleLoaded = false; - if (m_selectedStyleDirty) { - QScopedPointer newStyle(QStyleFactory::create(m_model->selectedStyle())); + if (m_settings->widgetStyle() != m_previousStyle) { + QScopedPointer newStyle(QStyleFactory::create(m_settings->widgetStyle())); if (newStyle) { newStyleLoaded = true; + m_previousStyle = m_settings->widgetStyle(); } else { - const QString styleDisplay = m_model->data(m_model->index(m_model->selectedStyleIndex(), 0), Qt::DisplayRole).toString(); + const QString styleDisplay = m_model->data(m_model->index(m_model->indexOfStyle(m_settings->widgetStyle()), 0), Qt::DisplayRole).toString(); emit showErrorMessage(i18n("Failed to apply selected style '%1'.", styleDisplay)); - } - } - if (newStyleLoaded) { - m_settings->setWidgetStyle(m_model->selectedStyle()); + // Reset selected style back to current in case of failure + m_settings->setWidgetStyle(m_previousStyle); + } } - const QMetaEnum toolBarStyleEnum = QMetaEnum::fromType(); - m_settings->setToolButtonStyle(toolBarStyleEnum.valueToKey(m_mainToolBarStyle)); - m_settings->setToolButtonStyleOtherToolbars(toolBarStyleEnum.valueToKey(m_otherToolBarStyle)); - - m_settings->save(); + ManagedConfigModule::save(); // Export the changes we made to qtrc, and update all qt-only // applications on the fly, ensuring that we still follow the user's // export fonts/colors settings. - if (m_selectedStyleDirty || m_effectsDirty) { - uint flags = KRdbExportQtSettings | KRdbExportGtkTheme; - KConfig _kconfig( QStringLiteral("kcmdisplayrc"), KConfig::NoGlobals ); - KConfigGroup kconfig(&_kconfig, "X11"); - bool exportKDEColors = kconfig.readEntry("exportKDEColors", true); - if (exportKDEColors) { - flags |= KRdbExportColors; - } - runRdb( flags ); + uint flags = KRdbExportQtSettings | KRdbExportGtkTheme; + KConfig _kconfig( QStringLiteral("kcmdisplayrc"), KConfig::NoGlobals ); + KConfigGroup kconfig(&_kconfig, "X11"); + bool exportKDEColors = kconfig.readEntry("exportKDEColors", true); + if (exportKDEColors) { + flags |= KRdbExportColors; } + runRdb( flags ); // Now allow KDE apps to reconfigure themselves. if (newStyleLoaded) { KGlobalSettings::self()->emitChange(KGlobalSettings::StyleChanged); } if (m_effectsDirty) { KGlobalSettings::self()->emitChange(KGlobalSettings::SettingsChanged, KGlobalSettings::SETTINGS_STYLE); // ##### FIXME - Doesn't apply all settings correctly due to bugs in // KApplication/KToolbar KGlobalSettings::self()->emitChange(KGlobalSettings::ToolbarStyleChanged); } - // Reset selected style back to current in case of failure - if (!newStyleLoaded) { - m_model->setSelectedStyle(m_settings->widgetStyle()); - } - - m_selectedStyleDirty = false; m_effectsDirty = false; } void KCMStyle::defaults() { // TODO the old code had a fallback chain but do we actually support not having Breeze for Plasma? // defaultStyle() -> oxygen -> plastique -> windows -> platinum -> motif - m_settings->setDefaults(); + ManagedConfigModule::defaults(); loadSettingsToModel(); - - setNeedsSave(m_settings->isSaveNeeded()); } void KCMStyle::loadSettingsToModel() { - m_model->setSelectedStyle(m_settings->widgetStyle()); + emit m_settings->widgetStyleChanged(); const QMetaEnum toolBarStyleEnum = QMetaEnum::fromType(); setMainToolBarStyle(static_cast(toolBarStyleEnum.keyToValue(qUtf8Printable(m_settings->toolButtonStyle())))); setOtherToolBarStyle(static_cast(toolBarStyleEnum.keyToValue(qUtf8Printable(m_settings->toolButtonStyleOtherToolbars())))); } #include "kcmstyle.moc" diff --git a/kcms/style/kcmstyle.h b/kcms/style/kcmstyle.h index 81ec00d55..227b1400e 100644 --- a/kcms/style/kcmstyle.h +++ b/kcms/style/kcmstyle.h @@ -1,101 +1,101 @@ /* * KCMStyle * Copyright (C) 2002 Karol Szwed * Copyright (C) 2002 Daniel Molkentin * Copyright (C) 2007 Urs Wolfer * Copyright (C) 2019 Kai Uwe Broulik * Copyright (C) 2019 Cyril Rossi * * Portions Copyright (C) TrollTech AS. * * Based on kcmdisplay * Copyright (C) 1997-2002 kcmdisplay Authors. * (see Help -> About Style Settings) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License version 2 as published by the Free Software Foundation. * * 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; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef KCMSTYLE_H #define KCMSTYLE_H #include -#include +#include class QQuickItem; class StyleSettings; class StylesModel; class StyleConfigDialog; -class KCMStyle : public KQuickAddons::ConfigModule +class KCMStyle : public KQuickAddons::ManagedConfigModule { Q_OBJECT Q_PROPERTY(StylesModel *model READ model CONSTANT) Q_PROPERTY(StyleSettings *styleSettings READ styleSettings CONSTANT) Q_PROPERTY(ToolBarStyle mainToolBarStyle READ mainToolBarStyle WRITE setMainToolBarStyle NOTIFY mainToolBarStyleChanged) Q_PROPERTY(ToolBarStyle otherToolBarStyle READ otherToolBarStyle WRITE setOtherToolBarStyle NOTIFY otherToolBarStyleChanged) public: KCMStyle(QObject *parent, const QVariantList &args); ~KCMStyle() override; enum ToolBarStyle { NoText, TextOnly, TextBesideIcon, TextUnderIcon }; Q_ENUM(ToolBarStyle) StylesModel *model() const; StyleSettings *styleSettings() const; ToolBarStyle mainToolBarStyle() const; void setMainToolBarStyle(ToolBarStyle style); Q_SIGNAL void mainToolBarStyleChanged(); ToolBarStyle otherToolBarStyle() const; void setOtherToolBarStyle(ToolBarStyle style); Q_SIGNAL void otherToolBarStyleChanged(); Q_INVOKABLE void configure(const QString &styleName, QQuickItem *ctx = nullptr); void load() override; void save() override; void defaults() override; Q_SIGNALS: void showErrorMessage(const QString &message); void styleReconfigured(const QString &styleName); private: void loadSettingsToModel(); StyleSettings *m_settings; StylesModel *m_model; - bool m_selectedStyleDirty = false; + QString m_previousStyle; bool m_effectsDirty = false; ToolBarStyle m_mainToolBarStyle = NoText; ToolBarStyle m_otherToolBarStyle = NoText; QPointer m_styleConfigDialog; }; #endif // __KCMSTYLE_H