diff --git a/kcmkwin/kwindecoration/CMakeLists.txt b/kcmkwin/kwindecoration/CMakeLists.txt index f591f69d5..5be050484 100644 --- a/kcmkwin/kwindecoration/CMakeLists.txt +++ b/kcmkwin/kwindecoration/CMakeLists.txt @@ -1,30 +1,33 @@ # KI18N Translation Domain for this library add_definitions(-DTRANSLATION_DOMAIN=\"kcm_kwindecoration\") add_subdirectory(declarative-plugin) set(kcmkwindecoration_SRCS declarative-plugin/buttonsmodel.cpp decorationmodel.cpp kcm.cpp utils.cpp ) +kconfig_add_kcfg_files(kcmkwindecoration_SRCS kwindecorationsettings.kcfgc GENERATE_MOC) + add_library(kcm_kwindecoration MODULE ${kcmkwindecoration_SRCS}) target_link_libraries(kcm_kwindecoration KDecoration2::KDecoration KF5::I18n KF5::NewStuff KF5::QuickAddons Qt5::Quick ) kcoreaddons_desktop_to_json(kcm_kwindecoration "kwindecoration.desktop" SERVICE_TYPES kcmodule.desktop) # This desktop file is installed only for retrocompatibility with sycoca +install(FILES kwindecorationsettings.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR}) install(FILES kwindecoration.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}) install(FILES window-decorations.knsrc DESTINATION ${KDE_INSTALL_KNSRCDIR}) install(TARGETS kcm_kwindecoration DESTINATION ${KDE_INSTALL_PLUGINDIR}/kcms) kpackage_install_package(package kcm_kwindecoration kcms) diff --git a/kcmkwin/kwindecoration/kcm.cpp b/kcmkwin/kwindecoration/kcm.cpp index f8d6be618..afd523646 100644 --- a/kcmkwin/kwindecoration/kcm.cpp +++ b/kcmkwin/kwindecoration/kcm.cpp @@ -1,375 +1,278 @@ /* * Copyright (c) 2019 Valerio Pilo + * Copyright (c) 2019 Cyril Rossi * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License version 2 as published by the Free Software Foundation. * * 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kcm.h" #include "decorationmodel.h" #include "declarative-plugin/buttonsmodel.h" #include #include #include #include #include #include #include #include #include #include #include #include #include +#include "kwindecorationsettings.h" K_PLUGIN_FACTORY_WITH_JSON(KCMKWinDecorationFactory, "kwindecoration.json", registerPlugin();) Q_DECLARE_METATYPE(KDecoration2::BorderSize) namespace { -const QString s_configFile { QStringLiteral("kwinrc") }; -const QString s_configGroup { QStringLiteral("org.kde.kdecoration2") }; -const QString s_configPlugin { QStringLiteral("library") }; -const QString s_configTheme { QStringLiteral("theme") }; -const QString s_configBorderSize { QStringLiteral("BorderSize") }; -const QString s_configBorderSizeAuto { QStringLiteral("BorderSizeAuto") }; -const QString s_configCloseOnDoubleClickOnMenu { QStringLiteral("CloseOnDoubleClickOnMenu") }; -const QString s_configShowToolTips { QStringLiteral("ShowToolTips") }; -const QString s_configDecoButtonsOnLeft { QStringLiteral("ButtonsOnLeft") }; -const QString s_configDecoButtonsOnRight { QStringLiteral("ButtonsOnRight") }; - -const KDecoration2::BorderSize s_defaultBorderSize = KDecoration2::BorderSize::Normal; const KDecoration2::BorderSize s_defaultRecommendedBorderSize = KDecoration2::BorderSize::Normal; -const bool s_defaultBorderSizeAuto = true; -const bool s_defaultCloseOnDoubleClickOnMenu = false; -const bool s_defaultShowToolTips = true; - -const DecorationButtonsList s_defaultDecoButtonsOnLeft { - KDecoration2::DecorationButtonType::Menu, - KDecoration2::DecorationButtonType::OnAllDesktops -}; -const DecorationButtonsList s_defaultDecoButtonsOnRight { - KDecoration2::DecorationButtonType::ContextHelp, - KDecoration2::DecorationButtonType::Minimize, - KDecoration2::DecorationButtonType::Maximize, - KDecoration2::DecorationButtonType::Close -}; - -#if HAVE_BREEZE_DECO -const QString s_defaultPlugin { QStringLiteral(BREEZE_KDECORATION_PLUGIN_ID) }; -const QString s_defaultTheme { QStringLiteral("Breeze") }; -#else -const QString s_defaultPlugin { QStringLiteral("org.kde.kwin.aurorae") }; -const QString s_defaultTheme { QStringLiteral("kwin4_decoration_qml_plastik") }; -#endif } KCMKWinDecoration::KCMKWinDecoration(QObject *parent, const QVariantList &arguments) - : KQuickAddons::ConfigModule(parent, arguments) + : KQuickAddons::ManagedConfigModule(parent, arguments) , m_themesModel(new KDecoration2::Configuration::DecorationsModel(this)) , m_proxyThemesModel(new QSortFilterProxyModel(this)) , m_leftButtonsModel(new KDecoration2::Preview::ButtonsModel(DecorationButtonsList(), this)) , m_rightButtonsModel(new KDecoration2::Preview::ButtonsModel(DecorationButtonsList(), this)) , m_availableButtonsModel(new KDecoration2::Preview::ButtonsModel(this)) - , m_savedSettings{ s_defaultBorderSize, s_defaultBorderSizeAuto, -2 /* for setTheme() */, false, s_defaultShowToolTips, s_defaultDecoButtonsOnLeft, s_defaultDecoButtonsOnRight } - , m_currentSettings(m_savedSettings) + , m_settings(new KWinDecorationSettings(this)) { auto about = new KAboutData(QStringLiteral("kcm_kwindecoration"), i18n("Window Decorations"), QStringLiteral("1.0"), QString(), KAboutLicense::GPL); about->addAuthor(i18n("Valerio Pilo"), i18n("Author"), QStringLiteral("vpilo@coldshock.net")); setAboutData(about); + setButtons(Apply | Default | Help); #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) qmlRegisterType(); qmlRegisterType(); + qmlRegisterType(); #else qmlRegisterAnonymousType("org.kde.kwin.KWinDecoration", 1); qmlRegisterAnonymousType("org.kde.kwin.KWinDecoration", 1); + qmlRegisterAnonymousType("org.kde.kwin.KWinDecoration", 1); #endif m_proxyThemesModel->setSourceModel(m_themesModel); m_proxyThemesModel->setFilterCaseSensitivity(Qt::CaseInsensitive); m_proxyThemesModel->setSortCaseSensitivity(Qt::CaseInsensitive); m_proxyThemesModel->sort(0); - connect(m_leftButtonsModel, &QAbstractItemModel::rowsInserted, this, &KCMKWinDecoration::updateNeedsSave); - connect(m_leftButtonsModel, &QAbstractItemModel::rowsMoved, this, &KCMKWinDecoration::updateNeedsSave); - connect(m_leftButtonsModel, &QAbstractItemModel::rowsRemoved, this, &KCMKWinDecoration::updateNeedsSave); - connect(m_leftButtonsModel, &QAbstractItemModel::modelReset, this, &KCMKWinDecoration::updateNeedsSave); - connect(m_rightButtonsModel, &QAbstractItemModel::rowsInserted, this, &KCMKWinDecoration::updateNeedsSave); - connect(m_rightButtonsModel, &QAbstractItemModel::rowsMoved, this, &KCMKWinDecoration::updateNeedsSave); - connect(m_rightButtonsModel, &QAbstractItemModel::rowsRemoved, this, &KCMKWinDecoration::updateNeedsSave); - connect(m_rightButtonsModel, &QAbstractItemModel::modelReset, this, &KCMKWinDecoration::updateNeedsSave); + connect(m_settings, &KWinDecorationSettings::themeChanged, this, &KCMKWinDecoration::themeChanged); + connect(m_settings, &KWinDecorationSettings::borderSizeChanged, this, &KCMKWinDecoration::borderSizeChanged); + + connect(m_leftButtonsModel, &QAbstractItemModel::rowsInserted, this, &KCMKWinDecoration::onLeftButtonsChanged); + connect(m_leftButtonsModel, &QAbstractItemModel::rowsMoved, this, &KCMKWinDecoration::onLeftButtonsChanged); + connect(m_leftButtonsModel, &QAbstractItemModel::rowsRemoved, this, &KCMKWinDecoration::onLeftButtonsChanged); + connect(m_leftButtonsModel, &QAbstractItemModel::modelReset, this, &KCMKWinDecoration::onLeftButtonsChanged); + + connect(m_rightButtonsModel, &QAbstractItemModel::rowsInserted, this, &KCMKWinDecoration::onRightButtonsChanged); + connect(m_rightButtonsModel, &QAbstractItemModel::rowsMoved, this, &KCMKWinDecoration::onRightButtonsChanged); + connect(m_rightButtonsModel, &QAbstractItemModel::rowsRemoved, this, &KCMKWinDecoration::onRightButtonsChanged); + connect(m_rightButtonsModel, &QAbstractItemModel::modelReset, this, &KCMKWinDecoration::onRightButtonsChanged); + + connect(this, &KCMKWinDecoration::borderSizeChanged, this, &KCMKWinDecoration::settingsChanged); // Update the themes when the color scheme or a theme's settings change QDBusConnection::sessionBus() .connect(QString(), QStringLiteral("/KWin"), QStringLiteral("org.kde.KWin"), QStringLiteral("reloadConfig"), this, SLOT(reloadKWinSettings())); QMetaObject::invokeMethod(m_themesModel, "init", Qt::QueuedConnection); } +KWinDecorationSettings *KCMKWinDecoration::settings() const +{ + return m_settings; +} + void KCMKWinDecoration::reloadKWinSettings() { QMetaObject::invokeMethod(m_themesModel, "init", Qt::QueuedConnection); } void KCMKWinDecoration::getNewStuff(QQuickItem *context) { if (!m_newStuffDialog) { m_newStuffDialog = new KNS3::DownloadDialog(QStringLiteral("window-decorations.knsrc")); m_newStuffDialog->setWindowTitle(i18n("Download New Window Decorations")); m_newStuffDialog->setWindowModality(Qt::WindowModal); connect(m_newStuffDialog, &KNS3::DownloadDialog::accepted, this, &KCMKWinDecoration::load); } if (context && context->window()) { m_newStuffDialog->winId(); // so it creates the windowHandle() m_newStuffDialog->windowHandle()->setTransientParent(context->window()); } connect(m_newStuffDialog, &QDialog::finished, this, &KCMKWinDecoration::reloadKWinSettings); m_newStuffDialog->show(); } void KCMKWinDecoration::load() { - const KConfigGroup config = KSharedConfig::openConfig(s_configFile)->group(s_configGroup); - - const QString plugin = config.readEntry(s_configPlugin, s_defaultPlugin); - const QString theme = config.readEntry(s_configTheme, s_defaultTheme); - int themeIndex = m_proxyThemesModel->mapFromSource(m_themesModel->findDecoration(plugin, theme)).row(); - if (themeIndex < 0) { - qWarning() << "Plugin" << plugin << "and theme" << theme << "not found"; - } else { - qDebug() << "Current theme: plugin" << plugin << "and theme" << theme; - } - setTheme(themeIndex); + ManagedConfigModule::load(); - setCloseOnDoubleClickOnMenu(config.readEntry(s_configCloseOnDoubleClickOnMenu, s_defaultCloseOnDoubleClickOnMenu)); - setShowToolTips(config.readEntry(s_configShowToolTips, s_defaultShowToolTips)); + m_leftButtonsModel->replace(Utils::buttonsFromString(m_settings->buttonsOnLeft())); + m_rightButtonsModel->replace(Utils::buttonsFromString(m_settings->buttonsOnRight())); - const QString defaultSizeName = Utils::borderSizeToString(s_defaultBorderSize); - setBorderSize(Utils::stringToBorderSize(config.readEntry(s_configBorderSize, defaultSizeName))); - setBorderSizeAuto(config.readEntry(s_configBorderSizeAuto, s_defaultBorderSizeAuto)); + setBorderSize(borderSizeIndexFromString(m_settings->borderSize())); - m_leftButtonsModel->replace(Utils::readDecorationButtons(config, s_configDecoButtonsOnLeft, s_defaultDecoButtonsOnLeft)); - m_rightButtonsModel->replace(Utils::readDecorationButtons(config, s_configDecoButtonsOnRight, s_defaultDecoButtonsOnRight)); - m_currentSettings.buttonsOnLeft = m_leftButtonsModel->buttons(); - m_currentSettings.buttonsOnRight = m_rightButtonsModel->buttons(); - - m_savedSettings = m_currentSettings; - - updateNeedsSave(); + emit themeChanged(); } void KCMKWinDecoration::save() { - KConfigGroup config = KSharedConfig::openConfig(s_configFile)->group(s_configGroup); - - if (m_currentSettings.themeIndex >= 0) { - const QModelIndex index = m_proxyThemesModel->index(m_currentSettings.themeIndex, 0); - if (index.isValid()) { - const QString plugin = index.data(KDecoration2::Configuration::DecorationsModel::PluginNameRole).toString(); - const QString theme = index.data(KDecoration2::Configuration::DecorationsModel::ThemeNameRole).toString(); - config.writeEntry(s_configPlugin, plugin); - config.writeEntry(s_configTheme, theme); - qDebug() << "Saved theme: plugin" << plugin << "and theme" << theme; - } else { - qWarning() << "Cannot match theme index" << m_currentSettings.themeIndex << "in model"; - } + if (!m_settings->borderSizeAuto()) { + m_settings->setBorderSize(borderSizeIndexToString(m_borderSizeIndex)); + } else { + m_settings->setBorderSize(m_settings->defaultBorderSizeValue()); } - config.writeEntry(s_configCloseOnDoubleClickOnMenu, m_currentSettings.closeOnDoubleClickOnMenu); - config.writeEntry(s_configShowToolTips, m_currentSettings.showToolTips); - config.writeEntry(s_configBorderSize, Utils::borderSizeToString(m_currentSettings.borderSize)); - config.writeEntry(s_configBorderSizeAuto, m_currentSettings.borderSizeAuto); - config.writeEntry(s_configDecoButtonsOnLeft, Utils::buttonsToString(m_currentSettings.buttonsOnLeft), KConfigGroup::Notify); - config.writeEntry(s_configDecoButtonsOnRight, Utils::buttonsToString(m_currentSettings.buttonsOnRight), KConfigGroup::Notify); - config.sync(); - - m_savedSettings = m_currentSettings; + ManagedConfigModule::save(); // Send a signal to all kwin instances QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/KWin"), QStringLiteral("org.kde.KWin"), QStringLiteral("reloadConfig")); QDBusConnection::sessionBus().send(message); - - updateNeedsSave(); } void KCMKWinDecoration::defaults() { - int themeIndex = m_proxyThemesModel->mapFromSource(m_themesModel->findDecoration(s_defaultPlugin, s_defaultTheme)).row(); - if (themeIndex < 0) { - qWarning() << "Default plugin" << s_defaultPlugin << "and theme" << s_defaultTheme << "not found"; - } - setTheme(themeIndex); - setBorderSize(s_defaultBorderSize); - setBorderSizeAuto(s_defaultBorderSizeAuto); - setCloseOnDoubleClickOnMenu(s_defaultCloseOnDoubleClickOnMenu); - setShowToolTips(s_defaultShowToolTips); + ManagedConfigModule::defaults(); - m_leftButtonsModel->replace(s_defaultDecoButtonsOnLeft); - m_rightButtonsModel->replace(s_defaultDecoButtonsOnRight); + setBorderSize(recommendedBorderSize()); - updateNeedsSave(); + m_leftButtonsModel->replace(Utils::buttonsFromString(m_settings->buttonsOnLeft())); + m_rightButtonsModel->replace(Utils::buttonsFromString(m_settings->buttonsOnRight())); } -void KCMKWinDecoration::updateNeedsSave() +void KCMKWinDecoration::onLeftButtonsChanged() { - m_currentSettings.buttonsOnLeft = m_leftButtonsModel->buttons(); - m_currentSettings.buttonsOnRight = m_rightButtonsModel->buttons(); - - setNeedsSave(m_savedSettings.closeOnDoubleClickOnMenu != m_currentSettings.closeOnDoubleClickOnMenu - || m_savedSettings.showToolTips != m_currentSettings.showToolTips - || m_savedSettings.borderSize != m_currentSettings.borderSize - || m_savedSettings.borderSizeAuto != m_currentSettings.borderSizeAuto - || m_savedSettings.themeIndex != m_currentSettings.themeIndex - || m_savedSettings.buttonsOnLeft != m_currentSettings.buttonsOnLeft - || m_savedSettings.buttonsOnRight != m_currentSettings.buttonsOnRight); + m_settings->setButtonsOnLeft(Utils::buttonsToString(m_leftButtonsModel->buttons())); +} + +void KCMKWinDecoration::onRightButtonsChanged() +{ + m_settings->setButtonsOnRight(Utils::buttonsToString(m_rightButtonsModel->buttons())); } QSortFilterProxyModel *KCMKWinDecoration::themesModel() const { return m_proxyThemesModel; } QAbstractListModel *KCMKWinDecoration::leftButtonsModel() { return m_leftButtonsModel; } QAbstractListModel *KCMKWinDecoration::rightButtonsModel() { return m_rightButtonsModel; } QAbstractListModel *KCMKWinDecoration::availableButtonsModel() const { return m_availableButtonsModel; } QStringList KCMKWinDecoration::borderSizesModel() const { return Utils::getBorderSizeNames().values(); } int KCMKWinDecoration::borderSize() const { - return Utils::getBorderSizeNames().keys().indexOf(m_currentSettings.borderSize); + return m_borderSizeIndex; } int KCMKWinDecoration::recommendedBorderSize() const { typedef KDecoration2::Configuration::DecorationsModel::DecorationRole DecoRole; - const QModelIndex proxyIndex = m_proxyThemesModel->index(m_currentSettings.themeIndex, 0); + const QModelIndex proxyIndex = m_proxyThemesModel->index(theme(), 0); if (proxyIndex.isValid()) { const QModelIndex index = m_proxyThemesModel->mapToSource(proxyIndex); if (index.isValid()) { QVariant ret = m_themesModel->data(index, DecoRole::RecommendedBorderSizeRole); return Utils::getBorderSizeNames().keys().indexOf(Utils::stringToBorderSize(ret.toString())); } } return Utils::getBorderSizeNames().keys().indexOf(s_defaultRecommendedBorderSize); } -bool KCMKWinDecoration::borderSizeAuto() const -{ - return m_currentSettings.borderSizeAuto; -} - int KCMKWinDecoration::theme() const { - return m_currentSettings.themeIndex; + return m_proxyThemesModel->mapFromSource(m_themesModel->findDecoration(m_settings->pluginName(), m_settings->theme())).row(); } -bool KCMKWinDecoration::closeOnDoubleClickOnMenu() const -{ - return m_currentSettings.closeOnDoubleClickOnMenu; -} - -bool KCMKWinDecoration::showToolTips() const +void KCMKWinDecoration::setBorderSize(int index) { - return m_currentSettings.showToolTips; + if (m_borderSizeIndex != index) { + m_borderSizeIndex = index; + emit borderSizeChanged(); + } } -void KCMKWinDecoration::setBorderSize(int index) +void KCMKWinDecoration::setBorderSize(KDecoration2::BorderSize size) { - setBorderSize(Utils::getBorderSizeNames().keys().at(index)); + m_settings->setBorderSize(Utils::borderSizeToString(size)); } -void KCMKWinDecoration::setBorderSize(KDecoration2::BorderSize size) +void KCMKWinDecoration::setTheme(int index) { - if (m_currentSettings.borderSize == size) { - return; + QModelIndex dataIndex = m_proxyThemesModel->index(index, 0); + if (dataIndex.isValid()) { + m_settings->setTheme(m_proxyThemesModel->data(dataIndex, KDecoration2::Configuration::DecorationsModel::ThemeNameRole).toString()); + m_settings->setPluginName(m_proxyThemesModel->data(dataIndex, KDecoration2::Configuration::DecorationsModel::PluginNameRole).toString()); + emit themeChanged(); } - m_currentSettings.borderSize = size; - emit borderSizeChanged(); - updateNeedsSave(); } -void KCMKWinDecoration::setBorderSizeAuto(bool set) +bool KCMKWinDecoration::isSaveNeeded() const { - if (m_currentSettings.borderSizeAuto == set) { - return; - } - m_currentSettings.borderSizeAuto = set; - emit borderSizeAutoChanged(); - updateNeedsSave(); + return !m_settings->borderSizeAuto() && borderSizeIndexFromString(m_settings->borderSize()) != m_borderSizeIndex; } -void KCMKWinDecoration::setTheme(int index) +bool KCMKWinDecoration::isDefaults() const { - // The initial themeIndex is set to -2 to always initially apply a theme, any theme - if (m_currentSettings.themeIndex == index) { - return; - } - m_currentSettings.themeIndex = index; - emit themeChanged(); - updateNeedsSave(); + return m_settings->borderSizeAuto() && recommendedBorderSize() == m_borderSizeIndex; } -void KCMKWinDecoration::setCloseOnDoubleClickOnMenu(bool enable) +int KCMKWinDecoration::borderSizeIndexFromString(const QString &size) const { - if (m_currentSettings.closeOnDoubleClickOnMenu == enable) { - return; - } - m_currentSettings.closeOnDoubleClickOnMenu = enable; - emit closeOnDoubleClickOnMenuChanged(); - updateNeedsSave(); + return Utils::getBorderSizeNames().keys().indexOf(Utils::stringToBorderSize(size)); } -void KCMKWinDecoration::setShowToolTips(bool show) +QString KCMKWinDecoration::borderSizeIndexToString(int index) const { - if (m_currentSettings.showToolTips == show) { - return; - } - m_currentSettings.showToolTips = show; - emit showToolTipsChanged(); - updateNeedsSave(); + return Utils::borderSizeToString(Utils::getBorderSizeNames().keys().at(index)); } #include "kcm.moc" diff --git a/kcmkwin/kwindecoration/kcm.h b/kcmkwin/kwindecoration/kcm.h index ba0534f78..75944695a 100644 --- a/kcmkwin/kwindecoration/kcm.h +++ b/kcmkwin/kwindecoration/kcm.h @@ -1,128 +1,117 @@ /* * Copyright (c) 2019 Valerio Pilo + * Copyright (c) 2019 Cyril Rossi * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License version 2 as published by the Free Software Foundation. * * 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #pragma once #include "utils.h" -#include +#include class QAbstractItemModel; class QSortFilterProxyModel; class QQuickItem; namespace KNS3 { class DownloadDialog; } namespace KDecoration2 { enum class BorderSize; namespace Preview { class ButtonsModel; } namespace Configuration { class DecorationsModel; } } -class KCMKWinDecoration : public KQuickAddons::ConfigModule +class KWinDecorationSettings; + +class KCMKWinDecoration : public KQuickAddons::ManagedConfigModule { Q_OBJECT + Q_PROPERTY(KWinDecorationSettings *settings READ settings CONSTANT) Q_PROPERTY(QSortFilterProxyModel *themesModel READ themesModel CONSTANT) Q_PROPERTY(QStringList borderSizesModel READ borderSizesModel CONSTANT) Q_PROPERTY(int borderSize READ borderSize WRITE setBorderSize NOTIFY borderSizeChanged) Q_PROPERTY(int recommendedBorderSize READ recommendedBorderSize CONSTANT) - Q_PROPERTY(bool borderSizeAuto READ borderSizeAuto WRITE setBorderSizeAuto NOTIFY borderSizeAutoChanged) Q_PROPERTY(int theme READ theme WRITE setTheme NOTIFY themeChanged) Q_PROPERTY(QAbstractListModel *leftButtonsModel READ leftButtonsModel NOTIFY buttonsChanged) Q_PROPERTY(QAbstractListModel *rightButtonsModel READ rightButtonsModel NOTIFY buttonsChanged) Q_PROPERTY(QAbstractListModel *availableButtonsModel READ availableButtonsModel CONSTANT) - Q_PROPERTY(bool closeOnDoubleClickOnMenu READ closeOnDoubleClickOnMenu WRITE setCloseOnDoubleClickOnMenu NOTIFY closeOnDoubleClickOnMenuChanged) - Q_PROPERTY(bool showToolTips READ showToolTips WRITE setShowToolTips NOTIFY showToolTipsChanged) public: KCMKWinDecoration(QObject *parent, const QVariantList &arguments); + KWinDecorationSettings *settings() const; QSortFilterProxyModel *themesModel() const; QAbstractListModel *leftButtonsModel(); QAbstractListModel *rightButtonsModel(); QAbstractListModel *availableButtonsModel() const; QStringList borderSizesModel() const; int borderSize() const; int recommendedBorderSize() const; - bool borderSizeAuto() const; int theme() const; - bool closeOnDoubleClickOnMenu() const; - bool showToolTips() const; void setBorderSize(int index); void setBorderSize(KDecoration2::BorderSize size); - void setBorderSizeAuto(bool set); void setTheme(int index); - void setCloseOnDoubleClickOnMenu(bool enable); - void setShowToolTips(bool show); Q_INVOKABLE void getNewStuff(QQuickItem *context); Q_SIGNALS: void themeChanged(); void buttonsChanged(); void borderSizeChanged(); - void borderSizeAutoChanged(); - void closeOnDoubleClickOnMenuChanged(); - void showToolTipsChanged(); public Q_SLOTS: void load() override; void save() override; void defaults() override; private Q_SLOTS: - void updateNeedsSave(); + void onLeftButtonsChanged(); + void onRightButtonsChanged(); void reloadKWinSettings(); private: + bool isSaveNeeded() const override; + bool isDefaults() const override; + + int borderSizeIndexFromString(const QString &size) const; + QString borderSizeIndexToString(int index) const; + KDecoration2::Configuration::DecorationsModel *m_themesModel; QSortFilterProxyModel *m_proxyThemesModel; KDecoration2::Preview::ButtonsModel *m_leftButtonsModel; KDecoration2::Preview::ButtonsModel *m_rightButtonsModel; KDecoration2::Preview::ButtonsModel *m_availableButtonsModel; QPointer m_newStuffDialog; - struct Settings - { - KDecoration2::BorderSize borderSize; - bool borderSizeAuto; - int themeIndex; - bool closeOnDoubleClickOnMenu; - bool showToolTips; - DecorationButtonsList buttonsOnLeft; - DecorationButtonsList buttonsOnRight; - }; - - Settings m_savedSettings; - Settings m_currentSettings; + int m_borderSizeIndex = -1; + KWinDecorationSettings *m_settings; }; diff --git a/kcmkwin/kwindecoration/kwindecorationsettings.kcfg b/kcmkwin/kwindecoration/kwindecorationsettings.kcfg new file mode 100644 index 000000000..496cecf85 --- /dev/null +++ b/kcmkwin/kwindecoration/kwindecorationsettings.kcfg @@ -0,0 +1,53 @@ + + + + + + + #if HAVE_BREEZE_DECO + const QString s_defaultPlugin { QStringLiteral(BREEZE_KDECORATION_PLUGIN_ID) }; + #else + const QString s_defaultPlugin { QStringLiteral("org.kde.kwin.aurorae") }; + #endif + + s_defaultPlugin + + + + #if HAVE_BREEZE_DECO + const QString s_defaultTheme { QStringLiteral("Breeze") }; + #else + const QString s_defaultTheme { QStringLiteral("kwin4_decoration_qml_plastik") }; + #endif + + s_defaultTheme + + + + Normal + + + + true + + + + false + + + + true + + + + MS + + + + HIAX + + + diff --git a/kcmkwin/kwindecoration/kwindecorationsettings.kcfgc b/kcmkwin/kwindecoration/kwindecorationsettings.kcfgc new file mode 100644 index 000000000..9d45368f4 --- /dev/null +++ b/kcmkwin/kwindecoration/kwindecorationsettings.kcfgc @@ -0,0 +1,6 @@ +File=kwindecorationsettings.kcfgc +ClassName=KWinDecorationSettings +Mutators=true +DefaultValueGetters=true +GenerateProperties=true +ParentInConstructor=true diff --git a/kcmkwin/kwindecoration/package/contents/ui/Buttons.qml b/kcmkwin/kwindecoration/package/contents/ui/Buttons.qml index f571a5841..ee7e6e241 100644 --- a/kcmkwin/kwindecoration/package/contents/ui/Buttons.qml +++ b/kcmkwin/kwindecoration/package/contents/ui/Buttons.qml @@ -1,245 +1,250 @@ /* * Copyright 2014 Martin Gräßlin * Copyright (c) 2019 Valerio Pilo * * 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 . */ import QtQuick 2.7 import QtQuick.Layouts 1.3 import QtQuick.Controls 2.4 as Controls import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.kirigami 2.5 as Kirigami import org.kde.kwin.private.kdecoration 1.0 as KDecoration ColumnLayout { Layout.fillWidth: true Layout.fillHeight: true property int buttonIconSize: units.iconSizes.medium property int titleBarSpacing: units.smallSpacing * 2 + readonly property bool draggingTitlebarButtons: leftButtonsView.dragging || rightButtonsView.dragging + readonly property bool hideDragHint: draggingTitlebarButtons || availableButtonsGrid.dragging KDecoration.Bridge { id: bridgeItem plugin: "org.kde.breeze" } KDecoration.Settings { id: settingsItem bridge: bridgeItem.bridge } Rectangle { Layout.fillWidth: true color: palette.base radius: units.smallSpacing height: fakeWindow.height Layout.margins: units.smallSpacing ColumnLayout { id: fakeWindow width: parent.width Rectangle { id: titleBar Layout.fillWidth: true height: buttonPreviewRow.height + 2 * titleBarSpacing radius: units.smallSpacing gradient: Gradient { GradientStop { position: 0.0; color: palette.midlight } GradientStop { position: 1.0; color: palette.window } } RowLayout { id: buttonPreviewRow anchors { margins: titleBarSpacing left: parent.left right: parent.right top: parent.top } ButtonGroup { id: leftButtonsView iconSize: buttonIconSize model: kcm.leftButtonsModel key: "decoButtonLeft" } Controls.Label { id: titleBarLabel Layout.fillWidth: true horizontalAlignment: Text.AlignHCenter font.bold: true text: i18n("Titlebar") } ButtonGroup { id: rightButtonsView iconSize: buttonIconSize model: kcm.rightButtonsModel key: "decoButtonRight" } } DropArea { id: titleBarDropArea anchors { fill: parent margins: -titleBarSpacing } keys: [ "decoButtonAdd", "decoButtonRight", "decoButtonLeft" ] onEntered: { drag.accept(); } onDropped: { var view = undefined; var left = drag.x - (leftButtonsView.x + leftButtonsView.width); var right = drag.x - rightButtonsView.x; if (Math.abs(left) <= Math.abs(right)) { view = leftButtonsView; } else { view = rightButtonsView; } if (!view) { return; } var point = mapToItem(view, drag.x, drag.y); var index = 0 for(var childIndex = 0 ; childIndex < (view.count - 1) ; childIndex++) { var child = view.contentItem.children[childIndex] if (child.x > point.x) { break } index = childIndex + 1 } - if (drop.keys.indexOf("decoButtonAdd") != -1) { + if (drop.keys.indexOf("decoButtonAdd") !== -1) { view.model.add(index, drag.source.type); - } else if (drop.keys.indexOf("decoButtonLeft") != -1) { - if (view == leftButtonsView) { + } else if (drop.keys.indexOf("decoButtonLeft") !== -1) { + if (view === leftButtonsView) { // move in same view - if (index != drag.source.itemIndex) { + if (index !== drag.source.itemIndex) { drag.source.buttonsModel.move(drag.source.itemIndex, index); } } else { // move to right view view.model.add(index, drag.source.type); drag.source.buttonsModel.remove(drag.source.itemIndex); } - } else if (drop.keys.indexOf("decoButtonRight") != -1) { - if (view == rightButtonsView) { + } else if (drop.keys.indexOf("decoButtonRight") !== -1) { + if (view === rightButtonsView) { // move in same view - if (index != drag.source.itemIndex) { + if (index !== drag.source.itemIndex) { drag.source.buttonsModel.move(drag.source.itemIndex, index); } } else { // move to left view view.model.add(index, drag.source.type); drag.source.buttonsModel.remove(drag.source.itemIndex); } } } } } GridView { id: availableButtonsGrid + property bool dragging: false Layout.fillWidth: true Layout.minimumHeight: availableButtonsGrid.cellHeight * 2 Layout.margins: units.largeSpacing model: kcm.availableButtonsModel interactive: false delegate: Item { id: availableDelegate Layout.margins: units.largeSpacing width: availableButtonsGrid.cellWidth height: availableButtonsGrid.cellHeight - opacity: (leftButtonsView.dragging || rightButtonsView.dragging) ? 0.15 : 1.0 + opacity: draggingTitlebarButtons ? 0.15 : 1.0 Rectangle { id: availableButtonFrame anchors.horizontalCenter: parent.horizontalCenter color: palette.window radius: units.smallSpacing width: buttonIconSize + units.largeSpacing height: buttonIconSize + units.largeSpacing KDecoration.Button { id: availableButton anchors.centerIn: Drag.active ? undefined : availableButtonFrame bridge: bridgeItem.bridge settings: settingsItem type: model["button"] width: buttonIconSize height: buttonIconSize Drag.keys: [ "decoButtonAdd" ] Drag.active: dragArea.drag.active + Drag.onActiveChanged: availableButtonsGrid.dragging = Drag.active color: palette.windowText } MouseArea { id: dragArea anchors.fill: availableButton drag.target: availableButton cursorShape: Qt.SizeAllCursor onReleased: { if (availableButton.Drag.target) { availableButton.Drag.drop(); } else { availableButton.Drag.cancel(); } } } } Controls.Label { id: iconLabel text: model["display"] horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignTop anchors.top: availableButtonFrame.bottom anchors.topMargin: units.smallSpacing anchors.left: parent.left anchors.right: parent.right elide: Text.ElideRight wrapMode: Text.Wrap height: 2 * implicitHeight + lineHeight } } DropArea { anchors.fill: parent keys: [ "decoButtonRemove" ] onEntered: { drag.accept(); } onDropped: { drag.source.buttonsModel.remove(drag.source.itemIndex); } Kirigami.Heading { text: i18n("Drop button here to remove it") font.weight: Font.Bold level: 2 anchors.centerIn: parent - opacity: (leftButtonsView.dragging || rightButtonsView.dragging) ? 1.0 : 0.0 + opacity: draggingTitlebarButtons ? 1.0 : 0.0 } } } Text { id: dragHint + readonly property real dragHintOpacitiy: enabled ? 1.0 : 0.3 color: palette.windowText - opacity: (leftButtonsView.dragging || rightButtonsView.dragging || availableButtonsGrid.dragging) ? 0.0 : 1.0 + opacity: hideDragHint ? 0.0 : dragHintOpacitiy Layout.fillWidth: true Layout.topMargin: titleBarSpacing Layout.bottomMargin: titleBarSpacing horizontalAlignment: Text.AlignHCenter wrapMode: Text.NoWrap text: i18n("Drag buttons between here and the titlebar") } } } } diff --git a/kcmkwin/kwindecoration/package/contents/ui/Themes.qml b/kcmkwin/kwindecoration/package/contents/ui/Themes.qml index e9b27ca4d..28e5899db 100644 --- a/kcmkwin/kwindecoration/package/contents/ui/Themes.qml +++ b/kcmkwin/kwindecoration/package/contents/ui/Themes.qml @@ -1,113 +1,119 @@ /* * Copyright 2014 Martin Gräßlin * Copyright (c) 2019 Valerio Pilo * * 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 . */ import QtQuick 2.7 import org.kde.kcm 1.1 as KCM import org.kde.kirigami 2.2 as Kirigami import org.kde.kwin.private.kdecoration 1.0 as KDecoration KCM.GridView { function updateDecoration(item, marginTopLeft, marginBottomRight) { var mainMargin = units.largeSpacing var shd = item.shadow item.anchors.leftMargin = mainMargin + marginTopLeft - (shd ? shd.paddingLeft : 0) item.anchors.rightMargin = mainMargin + marginBottomRight - (shd ? shd.paddingRight : 0) item.anchors.topMargin = mainMargin + marginTopLeft - (shd ? shd.paddingTop : 0) item.anchors.bottomMargin = mainMargin + marginBottomRight - (shd ? shd.paddingBottom : 0) } view.model: kcm.themesModel view.currentIndex: kcm.theme - view.onCurrentIndexChanged: kcm.theme = view.currentIndex view.onContentHeightChanged: view.positionViewAtIndex(view.currentIndex, GridView.Visible) view.implicitCellWidth: Kirigami.Units.gridUnit * 18 view.delegate: KCM.GridDelegate { text: model.display thumbnailAvailable: true thumbnail: Rectangle { anchors.fill: parent color: palette.base clip: true KDecoration.Bridge { id: bridgeItem plugin: model.plugin theme: model.theme } KDecoration.Settings { id: settingsItem bridge: bridgeItem.bridge } KDecoration.Decoration { id: inactivePreview bridge: bridgeItem.bridge settings: settingsItem anchors.fill: parent onShadowChanged: updateDecoration(inactivePreview, 0, client.decoration.titleBar.height) Component.onCompleted: { client.active = false client.caption = model.display updateDecoration(inactivePreview, 0, client.decoration.titleBar.height) } } KDecoration.Decoration { id: activePreview bridge: bridgeItem.bridge settings: settingsItem anchors.fill: parent onShadowChanged: updateDecoration(activePreview, client.decoration.titleBar.height, 0) Component.onCompleted: { client.active = true client.caption = model.display updateDecoration(activePreview, client.decoration.titleBar.height, 0) } } MouseArea { anchors.fill: parent - onClicked: view.currentIndex = index + onClicked: { + kcm.theme = index + view.currentIndex = index + } } Connections { target: kcm onBorderSizeChanged: settingsItem.borderSizesIndex = kcm.borderSize } } actions: [ Kirigami.Action { iconName: "edit-entry" tooltip: i18n("Edit %1 Theme", model.display) enabled: model.configureable onTriggered: { + kcm.theme = index view.currentIndex = index bridgeItem.bridge.configure() } } ] - onClicked: view.currentIndex = index + onClicked: { + kcm.theme = index + view.currentIndex = index + } } Connections { target: kcm onThemeChanged: view.currentIndex = kcm.theme } } diff --git a/kcmkwin/kwindecoration/package/contents/ui/main.qml b/kcmkwin/kwindecoration/package/contents/ui/main.qml index 403db2ab8..677bcd5f6 100644 --- a/kcmkwin/kwindecoration/package/contents/ui/main.qml +++ b/kcmkwin/kwindecoration/package/contents/ui/main.qml @@ -1,164 +1,167 @@ /* Copyright (c) 2019 Valerio Pilo This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.7 import QtQuick.Layouts 1.3 import QtQuick.Controls 2.4 as Controls import org.kde.kcm 1.1 as KCM import org.kde.kconfig 1.0 // for KAuthorized import org.kde.kirigami 2.4 as Kirigami Kirigami.Page { KCM.ConfigModule.quickHelp: i18n("This module lets you configure the window decorations.") - KCM.ConfigModule.buttons: KCM.ConfigModule.Help | KCM.ConfigModule.Default | KCM.ConfigModule.Apply title: kcm.name SystemPalette { id: palette colorGroup: SystemPalette.Active } // To match SimpleKCM's borders of Page + headerParent/footerParent (also specified in raw pixels) leftPadding: Kirigami.Settings.isMobile ? 0 : 8 topPadding: leftPadding rightPadding: leftPadding bottomPadding: leftPadding implicitWidth: Kirigami.Units.gridUnit * 48 implicitHeight: Kirigami.Units.gridUnit * 33 // TODO: replace this TabBar-plus-Frame-in-a-ColumnLayout with whatever shakes // out of https://bugs.kde.org/show_bug.cgi?id=394296 ColumnLayout { id: tabLayout anchors.fill: parent spacing: 0 Controls.TabBar { id: tabBar // Tab styles generally assume that they're touching the inner layout, // not the frame, so we need to move the tab bar down a pixel and make // sure it's drawn on top of the frame z: 1 Layout.bottomMargin: -1 Layout.fillWidth: true Controls.TabButton { text: i18nc("tab label", "Theme") } Controls.TabButton { text: i18nc("tab label", "Titlebar Buttons") } } Controls.Frame { Layout.fillWidth: true Layout.fillHeight: true StackLayout { anchors.fill: parent currentIndex: tabBar.currentIndex ColumnLayout { Themes { Layout.fillWidth: true Layout.fillHeight: true + enabled: !kcm.settings.isImmutable("pluginName") && !kcm.settings.isImmutable("theme") } RowLayout { Controls.CheckBox { id: borderSizeAutoCheckbox // Let it elide but don't make it push the ComboBox away from it Layout.fillWidth: true Layout.maximumWidth: implicitWidth text: i18nc("checkbox label", "Use theme's default window border size") - checked: kcm.borderSizeAuto - onCheckedChanged: { - kcm.borderSizeAuto = checked; + enabled: !kcm.settings.isImmutable("borderSizeAuto") + checked: kcm.settings.borderSizeAuto + onToggled: { + kcm.settings.borderSizeAuto = checked; borderSizeComboBox.autoBorderUpdate() } } Controls.ComboBox { id: borderSizeComboBox - enabled: !borderSizeAutoCheckbox.checked + enabled: !borderSizeAutoCheckbox.checked && !kcm.settings.isImmutable("borderSize") model: kcm.borderSizesModel + currentIndex: kcm.borderSize onActivated: { kcm.borderSize = currentIndex } function autoBorderUpdate() { if (borderSizeAutoCheckbox.checked) { - currentIndex = kcm.recommendedBorderSize - } else { - currentIndex = kcm.borderSize + kcm.borderSize = kcm.recommendedBorderSize } } Connections { target: kcm onThemeChanged: borderSizeComboBox.autoBorderUpdate() } } Item { Layout.fillWidth: true } Controls.Button { text: i18nc("button text", "Get New Window Decorations...") icon.name: "get-hot-new-stuff" onClicked: kcm.getNewStuff(this) visible: KAuthorized.authorize("ghns") } } } ColumnLayout { Buttons { Layout.fillWidth: true Layout.fillHeight: true + enabled: !kcm.settings.isImmutable("buttonsOnLeft") && !kcm.settings.isImmutable("buttonsOnRight") } Controls.CheckBox { id: closeOnDoubleClickOnMenuCheckBox text: i18nc("checkbox label", "Close windows by double clicking the menu button") - checked: kcm.closeOnDoubleClickOnMenu + enabled: !kcm.settings.isImmutable("closeOnDoubleClickOnMenu") + checked: kcm.settings.closeOnDoubleClickOnMenu onToggled: { - kcm.closeOnDoubleClickOnMenu = checked + kcm.settings.closeOnDoubleClickOnMenu = checked infoLabel.visible = checked } } Kirigami.InlineMessage { Layout.fillWidth: true id: infoLabel type: Kirigami.MessageType.Information text: i18nc("popup tip", "Close by double clicking: Keep the window's Menu button pressed until it appears.") showCloseButton: true visible: false } Controls.CheckBox { id: showToolTipsCheckBox text: i18nc("checkbox label", "Show titlebar button tooltips") - checked: kcm.showToolTips - onToggled: kcm.showToolTips = checked + enabled: !kcm.settings.isImmutable("showToolTips") + checked: kcm.settings.showToolTips + onToggled: kcm.settings.showToolTips = checked } } } } } } diff --git a/kcmkwin/kwindecoration/utils.cpp b/kcmkwin/kwindecoration/utils.cpp index b26b698bf..2f8c45bb4 100644 --- a/kcmkwin/kwindecoration/utils.cpp +++ b/kcmkwin/kwindecoration/utils.cpp @@ -1,119 +1,121 @@ /* * Copyright (c) 2019 Valerio Pilo * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License version 2 as published by the Free Software Foundation. * * 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "utils.h" #include #include namespace { const QMap s_borderSizes { { QStringLiteral("None"), KDecoration2::BorderSize::None }, { QStringLiteral("NoSides"), KDecoration2::BorderSize::NoSides }, { QStringLiteral("Tiny"), KDecoration2::BorderSize::Tiny }, { QStringLiteral("Normal"), KDecoration2::BorderSize::Normal }, { QStringLiteral("Large"), KDecoration2::BorderSize::Large }, { QStringLiteral("VeryLarge"), KDecoration2::BorderSize::VeryLarge }, { QStringLiteral("Huge"), KDecoration2::BorderSize::Huge }, { QStringLiteral("VeryHuge"), KDecoration2::BorderSize::VeryHuge }, { QStringLiteral("Oversized"), KDecoration2::BorderSize::Oversized } }; const QMap s_borderSizeNames { { KDecoration2::BorderSize::None, i18n("No Borders") }, { KDecoration2::BorderSize::NoSides, i18n("No Side Borders") }, { KDecoration2::BorderSize::Tiny, i18n("Tiny") }, { KDecoration2::BorderSize::Normal, i18n("Normal") }, { KDecoration2::BorderSize::Large, i18n("Large") }, { KDecoration2::BorderSize::VeryLarge, i18n("Very Large") }, { KDecoration2::BorderSize::Huge, i18n("Huge") }, { KDecoration2::BorderSize::VeryHuge, i18n("Very Huge") }, { KDecoration2::BorderSize::Oversized, i18n("Oversized") } }; const QHash s_buttonNames { {KDecoration2::DecorationButtonType::Menu, QChar('M') }, {KDecoration2::DecorationButtonType::ApplicationMenu, QChar('N') }, {KDecoration2::DecorationButtonType::OnAllDesktops, QChar('S') }, {KDecoration2::DecorationButtonType::ContextHelp, QChar('H') }, {KDecoration2::DecorationButtonType::Minimize, QChar('I') }, {KDecoration2::DecorationButtonType::Maximize, QChar('A') }, {KDecoration2::DecorationButtonType::Close, QChar('X') }, {KDecoration2::DecorationButtonType::KeepAbove, QChar('F') }, {KDecoration2::DecorationButtonType::KeepBelow, QChar('B') }, {KDecoration2::DecorationButtonType::Shade, QChar('L') } }; } namespace Utils { QString buttonsToString(const DecorationButtonsList &buttons) { auto buttonToString = [](KDecoration2::DecorationButtonType button) -> QChar { const auto it = s_buttonNames.constFind(button); if (it != s_buttonNames.constEnd()) { return it.value(); } return QChar(); }; QString ret; for (auto button : buttons) { ret.append(buttonToString(button)); } return ret; } -DecorationButtonsList readDecorationButtons(const KConfigGroup &config, const QString &key, const DecorationButtonsList &defaultValue) +DecorationButtonsList buttonsFromString(const QString &buttons) { - auto buttonsFromString = [](const QString &buttons) -> DecorationButtonsList { - DecorationButtonsList ret; - for (auto it = buttons.begin(); it != buttons.end(); ++it) { - for (auto it2 = s_buttonNames.constBegin(); it2 != s_buttonNames.constEnd(); ++it2) { - if (it2.value() == (*it)) { - ret << it2.key(); - } + DecorationButtonsList ret; + for (auto it = buttons.begin(); it != buttons.end(); ++it) { + for (auto it2 = s_buttonNames.constBegin(); it2 != s_buttonNames.constEnd(); ++it2) { + if (it2.value() == (*it)) { + ret << it2.key(); } } - return ret; - }; + } + return ret; +} + +DecorationButtonsList readDecorationButtons(const KConfigGroup &config, const QString &key, const DecorationButtonsList &defaultValue) +{ return buttonsFromString(config.readEntry(key, buttonsToString(defaultValue))); } KDecoration2::BorderSize stringToBorderSize(const QString &name) { auto it = s_borderSizes.constFind(name); if (it == s_borderSizes.constEnd()) { // non sense values are interpreted just like normal return KDecoration2::BorderSize::Normal; } return it.value(); } QString borderSizeToString(KDecoration2::BorderSize size) { return s_borderSizes.key(size); } const QMap &getBorderSizeNames() { return s_borderSizeNames; } } // namespace Utils diff --git a/kcmkwin/kwindecoration/utils.h b/kcmkwin/kwindecoration/utils.h index 1df5b3efb..3a54196ab 100644 --- a/kcmkwin/kwindecoration/utils.h +++ b/kcmkwin/kwindecoration/utils.h @@ -1,40 +1,41 @@ /* * Copyright (c) 2019 Valerio Pilo * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License version 2 as published by the Free Software Foundation. * * 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #pragma once #include #include #include using DecorationButtonsList = QVector; namespace Utils { QString buttonsToString(const DecorationButtonsList &buttons); +DecorationButtonsList buttonsFromString(const QString &buttons); DecorationButtonsList readDecorationButtons(const KConfigGroup &config, const QString &key, const DecorationButtonsList &defaultValue); KDecoration2::BorderSize stringToBorderSize(const QString &name); QString borderSizeToString(KDecoration2::BorderSize size); const QMap &getBorderSizeNames(); }