diff --git a/kcms/icons/CMakeLists.txt b/kcms/icons/CMakeLists.txt --- a/kcms/icons/CMakeLists.txt +++ b/kcms/icons/CMakeLists.txt @@ -4,6 +4,7 @@ set(kcm_icons_PART_SRCS main.cpp iconsmodel.cpp) +kconfig_add_kcfg_files(kcm_icons_PART_SRCS iconssettings.kcfgc GENERATE_MOC) add_library(kcm_icons MODULE ${kcm_icons_PART_SRCS}) target_link_libraries(kcm_icons @@ -24,6 +25,8 @@ target_link_libraries(plasma-changeicons PRIVATE Qt5::Core KF5::KIOWidgets KF5::IconThemes) kcoreaddons_desktop_to_json(kcm_icons "kcm_icons.desktop") + +install(FILES iconssettings.kcfg DESTINATION ${KDE_INSTALL_KCFGDIR}) install(FILES icons_remove_effects.upd DESTINATION ${KDE_INSTALL_DATADIR}/kconf_update) install(FILES kcm_icons.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}) install(TARGETS kcm_icons DESTINATION ${KDE_INSTALL_PLUGINDIR}/kcms) diff --git a/kcms/icons/iconssettings.kcfg b/kcms/icons/iconssettings.kcfg new file mode 100644 --- /dev/null +++ b/kcms/icons/iconssettings.kcfg @@ -0,0 +1,43 @@ + + + + + + + 32 + + + + + + 22 + + + + + + 22 + + + + + + 16 + + + + + + 48 + + + + + + 32 + + + diff --git a/kcms/icons/iconssettings.kcfgc b/kcms/icons/iconssettings.kcfgc new file mode 100644 --- /dev/null +++ b/kcms/icons/iconssettings.kcfgc @@ -0,0 +1,6 @@ +File=iconssettings.kcfg +ClassName=IconsSettings +Mutators=true +DefaultValueGetters=true +GenerateProperties=true +ParentInConstructor=true diff --git a/kcms/icons/main.h b/kcms/icons/main.h --- a/kcms/icons/main.h +++ b/kcms/icons/main.h @@ -4,6 +4,7 @@ * Copyright (c) 1999 Matthias Hoelzer-Kluepfel * KDE Frameworks 5 port Copyright (C) 2013 Jonathan Riddell * Copyright (c) 2018 Kai Uwe Broulik + * Copyright (C) 2019 Benjamin Port * * Requires the Qt widget libraries, available at no cost at * http://www.troll.no/ @@ -25,13 +26,15 @@ #pragma once -#include +#include #include #include +#include class KIconTheme; +class IconsSettings; class QQuickItem; class QTemporaryFile; @@ -43,14 +46,12 @@ class IconsModel; -class IconModule : public KQuickAddons::ConfigModule +class IconModule : public KQuickAddons::ManagedConfigModule { Q_OBJECT - + Q_PROPERTY(IconsSettings *iconsSettings READ iconsSettings CONSTANT) Q_PROPERTY(IconsModel *iconsModel READ iconsModel CONSTANT) - Q_PROPERTY(QStringList iconGroups READ iconGroups CONSTANT) - Q_PROPERTY(bool downloadingFile READ downloadingFile NOTIFY downloadingFileChanged) public: @@ -64,6 +65,8 @@ PendingDeletionRole }; + IconsSettings *iconsSettings() const; + IconsModel *iconsModel() const; QStringList iconGroups() const; @@ -77,9 +80,7 @@ Q_INVOKABLE void getNewStuff(QQuickItem *ctx); Q_INVOKABLE void installThemeFromFile(const QUrl &url); - Q_INVOKABLE int iconSize(int group) const; - Q_INVOKABLE void setIconSize(int group, int size); - Q_INVOKABLE QList availableIconSizes(int group) const; + Q_INVOKABLE QList availableIconSizes(int group); // QML doesn't understand QList, hence wrapped in a QVariantList Q_INVOKABLE QVariantList previewIcons(const QString &themeName, int size, qreal dpr, int limit = -1); @@ -96,6 +97,8 @@ private: void loadIconSizes(); + bool isSaveNeeded() const override; + bool isThemeDirty() const; void processPendingDeletions(); @@ -107,18 +110,16 @@ static QPixmap getBestIcon(KIconTheme &theme, const QStringList &iconNames, int size, qreal dpr); + IconsSettings *m_settings; + IconsModel *m_model; - // so we avoid launching changeicon process when theme didn't change (but only e.g. pending deletions) - bool m_selectedThemeDirty = false; - bool m_iconSizesDirty = false; - QVector m_iconSizes; + QMap m_kicon_theme_map; QStringList m_iconGroups; QScopedPointer m_tempInstallFile; QPointer m_tempCopyJob; QPointer m_newStuffDialog; - }; diff --git a/kcms/icons/main.cpp b/kcms/icons/main.cpp --- a/kcms/icons/main.cpp +++ b/kcms/icons/main.cpp @@ -6,6 +6,7 @@ * Copyright (C) 2000 Geert Jansen * KDE Frameworks 5 port Copyright (C) 2013 Jonathan Riddell * Copyright (C) 2018 Kai Uwe Broulik + * Copyright (C) 2019 Benjamin Port * * Requires the Qt widget libraries, available at no cost at * http://www.troll.no/ @@ -55,6 +56,7 @@ #include #include // for unlink +#include "iconssettings.h" #include "iconsmodel.h" #include "config.h" // for CMAKE_INSTALL_FULL_LIBEXECDIR @@ -66,7 +68,8 @@ K_PLUGIN_FACTORY_WITH_JSON(IconsFactory, "kcm_icons.json", registerPlugin();) IconModule::IconModule(QObject *parent, const QVariantList &args) - : KQuickAddons::ConfigModule(parent, args) + : KQuickAddons::ManagedConfigModule(parent, args) + , m_settings(new IconsSettings(this)) , m_model(new IconsModel(this)) , m_iconGroups{ QStringLiteral("Desktop"), @@ -77,6 +80,7 @@ QStringLiteral("Dialog") } { + qmlRegisterType(); qmlRegisterType(); // to be able to access its enums @@ -94,21 +98,23 @@ setButtons(Apply | Default); - connect(m_model, &IconsModel::selectedThemeChanged, this, [this] { - m_selectedThemeDirty = true; - setNeedsSave(true); - }); - connect(m_model, &IconsModel::pendingDeletionsChanged, this, [this] { - setNeedsSave(true); - }); + connect(m_model, SIGNAL(selectedThemeChanged()), this, SLOT(_k_settingsChanged())); + connect(m_model, SIGNAL(pendingDeletionsChanged()), this, SLOT(_k_settingsChanged())); // When user has a lot of themes installed, preview pixmaps might get evicted prematurely QPixmapCache::setCacheLimit(50 * 1024); // 50 MiB } IconModule::~IconModule() { + foreach (KIconTheme* theme, m_kicon_theme_map) { + delete theme; + } +} +IconsSettings *IconModule::iconsSettings() const +{ + return m_settings; } IconsModel *IconModule::iconsModel() const @@ -126,65 +132,48 @@ return m_tempCopyJob; } -int IconModule::iconSize(int group) const +QList IconModule::availableIconSizes(int group) { - return m_iconSizes[group]; -} - -void IconModule::setIconSize(int group, int size) -{ - if (iconSize(group) == size) { - return; + QString themeName(m_model->selectedTheme()); + if (!m_kicon_theme_map.contains(m_model->selectedTheme())) { + m_kicon_theme_map.insert(themeName, new KIconTheme(themeName)); } - - m_iconSizes[group] = size; - setNeedsSave(true); - m_iconSizesDirty = true; - emit iconSizesChanged(); -} - -QList IconModule::availableIconSizes(int group) const -{ - return KIconLoader::global()->theme()->querySizes(static_cast(group)); + return m_kicon_theme_map[themeName]->querySizes(static_cast(group)); } void IconModule::load() { + ManagedConfigModule::load(); m_model->load(); - loadIconSizes(); m_model->setSelectedTheme(KIconTheme::current()); - setNeedsSave(false); - m_selectedThemeDirty = false; - m_iconSizesDirty = false; } void IconModule::save() { - if (m_selectedThemeDirty) { + bool needToExportToKDE4 = isThemeDirty() || m_settings->isSaveNeeded(); + if (isThemeDirty()) { QProcess::startDetached(CMAKE_INSTALL_FULL_LIBEXECDIR "/plasma-changeicons", {m_model->selectedTheme()}); } - if (m_iconSizesDirty) { - auto cfg = KSharedConfig::openConfig(); - for (int i = 0; i < m_iconGroups.count(); ++i) { - const QString &group = m_iconGroups.at(i); - KConfigGroup cg(cfg, group + QLatin1String("Icons")); - cg.writeEntry("Size", m_iconSizes.at(i), KConfig::Normal | KConfig::Global); - } - cfg->sync(); - } + ManagedConfigModule::save(); - if (m_selectedThemeDirty || m_iconSizesDirty) { + if (needToExportToKDE4) { exportToKDE4(); } processPendingDeletions(); KIconLoader::global()->newIconLoader(); +} + +bool IconModule::isThemeDirty() const +{ + return m_model->selectedTheme() != KIconTheme::current(); +} - setNeedsSave(false); - m_selectedThemeDirty = false; - m_iconSizesDirty = false; +bool IconModule::isSaveNeeded() const +{ + return isThemeDirty() || !m_model->pendingDeletions().isEmpty(); } void IconModule::processPendingDeletions() @@ -205,10 +194,7 @@ void IconModule::defaults() { - if (m_iconSizes != s_defaultIconSizes) { - m_iconSizes = s_defaultIconSizes; - emit iconSizesChanged(); - } + ManagedConfigModule::defaults(); auto setThemeIfAvailable = [this](const QString &themeName) { const auto results = m_model->match(m_model->index(0, 0), ThemeNameRole, themeName); @@ -223,32 +209,6 @@ if (!setThemeIfAvailable(KIconTheme::defaultThemeName())) { setThemeIfAvailable(QStringLiteral("breeze")); } - - setNeedsSave(true); -} - -void IconModule::loadIconSizes() -{ - auto cfg = KSharedConfig::openConfig(); - - QVector iconSizes(6, 0); // why doesn't KIconLoader::LastGroup - 1 work here?! - - int i = KIconLoader::FirstGroup; - for (const QString &group : qAsConst(m_iconGroups)) { - int size = KIconLoader::global()->theme()->defaultSize(static_cast(i)); - - KConfigGroup iconGroup(cfg, group + QLatin1String("Icons")); - size = iconGroup.readEntry("Size", size); - - iconSizes[i] = size; - - ++i; - } - - if (m_iconSizes != iconSizes) { - m_iconSizes = iconSizes; - emit iconSizesChanged(); - } } void IconModule::getNewStuff(QQuickItem *ctx) diff --git a/kcms/icons/package/contents/ui/IconSizePopup.qml b/kcms/icons/package/contents/ui/IconSizePopup.qml --- a/kcms/icons/package/contents/ui/IconSizePopup.qml +++ b/kcms/icons/package/contents/ui/IconSizePopup.qml @@ -36,13 +36,16 @@ onVisibleChanged: { if (visible) { - iconSizeSlider.updateSizes(); + iconSizeSlider.sizes = kcm.availableIconSizes(iconTypeList.currentIndex); + iconSizeSlider.updateSizes() } } Connections { - target: kcm - onIconSizesChanged: iconSizeSlider.updateSizes() + target: iconTypeList + onCurrentIndexChanged: { + iconSizeSlider.sizes = kcm.availableIconSizes(iconTypeList.currentIndex); + } } RowLayout { @@ -75,6 +78,25 @@ model: kcm.iconGroups + property var sizesMap: [ + {"settingName":"desktopSize", "displayName": i18n("Desktop")}, + {"settingName":"toolbarSize", "displayName": i18n("Toolbar")}, + {"settingName":"mainToolbarSize", "displayName": i18n("Main Toolbar")}, + {"settingName":"smallSize", "displayName": i18n("Small Icons")}, + {"settingName":"panelSize", "displayName": i18n("Panel")}, + {"settingName":"dialogSize", "displayName": i18n("Dialogs")} + ] + + function sizeDisplayName(index) { + index = index <0 ? 0 : index; + return iconTypeList.sizesMap[index].displayName; + } + + function sizeSettingName(index) { + index = index <0 ? 0 : index; + return iconTypeList.sizesMap[index].settingName; + } + Keys.onLeftPressed: { LayoutMirroring.enabled ? iconSizeSlider.increase() : iconSizeSlider.decrease() iconSizeSlider.moved(); @@ -87,14 +109,7 @@ delegate: QtControls.ItemDelegate { width: ListView.view.width highlighted: ListView.isCurrentItem - text: [ - i18n("Desktop"), - i18n("Toolbar"), - i18n("Main Toolbar"), - i18n("Small Icons"), - i18n("Panel"), - i18n("Dialogs") - ][index] + text: iconTypeList.sizeDisplayName(index) onClicked: { ListView.view.currentIndex = index; @@ -106,23 +121,24 @@ QtControls.Slider { id: iconSizeSlider - readonly property var sizes: kcm.availableIconSizes(iconTypeList.currentIndex) - readonly property int currentSize: iconSizeSlider.sizes[iconSizeSlider.value] || 0 + property var sizes: kcm.availableIconSizes(iconTypeList.currentIndex) Layout.fillWidth: true from: 0 to: sizes.length - 1 stepSize: 1.0 snapMode: QtControls.Slider.SnapAlways enabled: sizes.length > 0 - onMoved: kcm.setIconSize(iconTypeList.currentIndex, currentSize) + onMoved: { + kcm.iconsSettings[iconTypeList.sizeSettingName(iconTypeList.currentIndex)] = iconSizeSlider.sizes[iconSizeSlider.value] || 0 + } function updateSizes() { // since the icon sizes are queried using invokables, always force an update when opening // in case the user clicked Default or something value = Qt.binding(function() { - var iconSize = kcm.iconSize(iconTypeList.currentIndex) + var iconSize = kcm.iconsSettings[iconTypeList.sizeSettingName(iconTypeList.currentIndex)] // I have no idea what this code does but it works and is just copied from the old KCM var index = -1; @@ -153,7 +169,7 @@ Kirigami.Icon { anchors.centerIn: parent - width: iconSizeSlider.currentSize + width: kcm.iconsSettings[iconTypeList.sizeSettingName(iconTypeList.currentIndex)] height: width source: "folder" } @@ -163,7 +179,7 @@ id: iconSizeLabel Layout.fillWidth: true horizontalAlignment: Text.AlignHCenter - text: iconSizeSlider.currentSize + text: kcm.iconsSettings[iconTypeList.sizeSettingName(iconTypeList.currentIndex)] } } }