* KCMStyle
* Copyright (C) 2002 Karol Szwed <gallium@kde.org>
* Copyright (C) 2002 Daniel Molkentin <molkentin@kde.org>
* Copyright (C) 2007 Urs Wolfer <uwolfer @ kde.org>
* Copyright (C) 2009 by Davide Bettio <davide.bettio@kdemail.net>
* Copyright (C) 2019 Kai Uwe Broulik <kde@broulik.de>
* Copyright (C) 2019 Cyril Rossi <cyril.rossi@enioka.com>
*
* Portions Copyright (C) 2007 Paolo Capriotti <p.capriotti@gmail.com>
* Portions Copyright (C) 2007 Ivan Cukic <ivan.cukic+kde@gmail.com>
* Portions Copyright (C) 2008 by Petri Damsten <damu@iki.fi>
* 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 <KAboutData>
#include <KConfigGroup>
#include <KLocalizedString>
#include <KPluginFactory>
#include <KPluginLoader>
#include <QDBusReply>
#include <QLibrary>
#include <QMetaEnum>
#include <QQuickItem>
#include <QQuickRenderControl>
#include <QQuickWindow>
#include <QScopedPointer>
#include <QStyleFactory>
#include <QWidget>
#include <QWindow>
#include <KGlobal>
#include <KGlobalSettings>
#include "../krdb/krdb.h"
#include "stylesmodel.h"
#include "previewitem.h"
#include "stylesettings.h"
#include "gtkpage.h"
K_PLUGIN_FACTORY_WITH_JSON(KCMStyleFactory, "kcm_style.json", registerPlugin<KCMStyle>();)
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");
bool exportKDEColors = config.readEntry("exportKDEColors", true);
if (exportKDEColors) {
flags |= KRdbExportColors;
}
runRdb( flags );
}
}
KCMStyle::KCMStyle(QObject *parent, const QVariantList &args)
: KQuickAddons::ManagedConfigModule(parent, args)
, m_settings(new StyleSettings(this))
, m_model(new StylesModel(this))
, m_gtkPage()
{
qmlRegisterUncreatableType<KCMStyle>("org.kde.private.kcms.style", 1, 0, "KCM", QStringLiteral("Cannot create instances of KCM"));
qmlRegisterType<StyleSettings>();
qmlRegisterType<StylesModel>();
qmlRegisterType<PreviewItem>("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);
if (gtkConfigKdedModuleLoaded()) {
m_gtkPage = new GtkPage(this);
connect(m_gtkPage, &GtkPage::gtkThemeSettingsChanged, this, [this](){
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;
});
connect(m_settings, &StyleSettings::iconsInMenusChanged, this, [this] {
m_effectsDirty = 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<ToolBarStyle>();
m_settings->setToolButtonStyle(toolBarStyleEnum.valueToKey(m_mainToolBarStyle));
m_effectsDirty = 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<ToolBarStyle>();
m_settings->setToolButtonStyleOtherToolbars(toolBarStyleEnum.valueToKey(m_otherToolBarStyle));
m_effectsDirty = true;
}
}
void KCMStyle::configure(const QString &title, 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, title);
m_styleConfigDialog->setAttribute(Qt::WA_DeleteOnClose);
m_styleConfigDialog->setWindowModality(Qt::WindowModal);
m_styleConfigDialog->winId();
if (ctx && ctx->window()) {
if (QWindow *actualWindow = QQuickRenderControl::renderWindowFor(ctx->window())) {
m_styleConfigDialog->windowHandle()->setTransientParent(actualWindow);
}
}
typedef QWidget*(* factoryRoutine)( QWidget* parent );
factoryRoutine factory = (factoryRoutine)(allocPtr);
QWidget* pluginConfig = factory( m_styleConfigDialog.data() );
m_styleConfigDialog->setMainWidget( pluginConfig );
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;
}
emit styleReconfigured(styleName);
KGlobalSettings::self()->emitChange(KGlobalSettings::StyleChanged);
m_settings->setWidgetStyle(styleName);
setNeedsSave(true);
});
m_styleConfigDialog->show();
}
bool KCMStyle::gtkConfigKdedModuleLoaded()
{
QDBusInterface kdedInterface(
QStringLiteral("org.kde.kded5"),
QStringLiteral("/kded"),
QStringLiteral("org.kde.kded5")
);
QDBusReply<QStringList> loadedKdedModules = kdedInterface.call(QStringLiteral("loadedModules"));
return loadedKdedModules.value().contains(QStringLiteral("gtkconfig"));
}
void KCMStyle::load()
{
if (m_gtkPage) {
m_gtkPage->load();
}
ManagedConfigModule::load();
m_model->load();
m_previousStyle = m_settings->widgetStyle();
loadSettingsToModel();
m_effectsDirty = false;
}
void KCMStyle::save()
{
if (m_gtkPage) {
m_gtkPage->save();
}
bool newStyleLoaded = false;
if (m_settings->widgetStyle() != m_previousStyle) {
QScopedPointer<QStyle> 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->indexOfStyle(m_settings->widgetStyle()), 0), Qt::DisplayRole).toString();
emit showErrorMessage(i18n("Failed to apply selected style '%1'.", styleDisplay));
m_settings->setWidgetStyle(m_previousStyle);
}
}
ManagedConfigModule::save();
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 );
if (newStyleLoaded) {
KGlobalSettings::self()->emitChange(KGlobalSettings::StyleChanged);
}
if (m_effectsDirty) {
KGlobalSettings::self()->emitChange(KGlobalSettings::SettingsChanged, KGlobalSettings::SETTINGS_STYLE);
KGlobalSettings::self()->emitChange(KGlobalSettings::ToolbarStyleChanged);
}
m_effectsDirty = false;
}
void KCMStyle::defaults()
{
if (m_gtkPage) {
m_gtkPage->defaults();
}
ManagedConfigModule::defaults();
loadSettingsToModel();
}
void KCMStyle::loadSettingsToModel()
{
emit m_settings->widgetStyleChanged();
const QMetaEnum toolBarStyleEnum = QMetaEnum::fromType<ToolBarStyle>();
setMainToolBarStyle(static_cast<ToolBarStyle>(toolBarStyleEnum.keyToValue(qUtf8Printable(m_settings->toolButtonStyle()))));
setOtherToolBarStyle(static_cast<ToolBarStyle>(toolBarStyleEnum.keyToValue(qUtf8Printable(m_settings->toolButtonStyleOtherToolbars()))));
}
#include "kcmstyle.moc"