diff --git a/kcms/icons/CMakeLists.txt b/kcms/icons/CMakeLists.txt --- a/kcms/icons/CMakeLists.txt +++ b/kcms/icons/CMakeLists.txt @@ -2,8 +2,9 @@ ########### next target ############### -set(kcm_icons_PART_SRCS main.cpp iconsmodel.cpp) +set(kcm_icons_PART_SRCS main.cpp iconsmodel.cpp iconsizecategorymodel.cpp iconssettings.cpp) +kconfig_add_kcfg_files(kcm_icons_PART_SRCS iconssettingsbase.kcfgc GENERATE_MOC) add_library(kcm_icons MODULE ${kcm_icons_PART_SRCS}) target_link_libraries(kcm_icons @@ -20,10 +21,16 @@ file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/config.h CONTENT "#define CMAKE_INSTALL_FULL_LIBEXECDIR \"${CMAKE_INSTALL_FULL_LIBEXECDIR}\"") -add_executable(plasma-changeicons changeicons.cpp) -target_link_libraries(plasma-changeicons PRIVATE Qt5::Core KF5::KIOWidgets KF5::IconThemes) +set(changeicons_SRCS changeicons.cpp iconssettings.cpp) + +kconfig_add_kcfg_files(changeicons_SRCS iconssettingsbase.kcfgc GENERATE_MOC) + +add_executable(plasma-changeicons ${changeicons_SRCS}) +target_link_libraries(plasma-changeicons PRIVATE Qt5::Core KF5::KIOWidgets KF5::KCMUtils KF5::IconThemes) kcoreaddons_desktop_to_json(kcm_icons "kcm_icons.desktop") + +install(FILES iconssettingsbase.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/changeicons.cpp b/kcms/icons/changeicons.cpp --- a/kcms/icons/changeicons.cpp +++ b/kcms/icons/changeicons.cpp @@ -18,12 +18,7 @@ */ #include -#include -#include -#include -#include -#include -#include +#include "iconssettings.h" int main(int argc, char** argv) { @@ -33,28 +28,15 @@ return 1; } - { - //KNS will give us a path - QString themeName = app.arguments().last(); - int idx = themeName.lastIndexOf('/'); - if (idx>=0) { - themeName = themeName.mid(idx); - } - - KConfigGroup config(KSharedConfig::openConfig(QStringLiteral("kdeglobals"), KConfig::SimpleConfig), "Icons"); - config.writeEntry("Theme", themeName); - config.sync(); - } - - KIconTheme::reconfigure(); - - KSharedDataCache::deleteCache(QStringLiteral("icon-cache")); - - for (int i=0; i=0) { + themeName = themeName.mid(idx); } - KBuildSycocaProgressDialog::rebuildKSycoca(nullptr); + IconsSettings settings; + settings.setTheme(themeName); + settings.save(); return 0; } diff --git a/kcms/icons/iconsizecategorymodel.h b/kcms/icons/iconsizecategorymodel.h new file mode 100644 --- /dev/null +++ b/kcms/icons/iconsizecategorymodel.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019 Benjamin Port + * + * 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) any later version. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include + +struct IconSizeCategoryModelData +{ + QString configKey; + QString display; + QString configSection; +}; + +Q_DECLARE_TYPEINFO(IconSizeCategoryModelData, Q_MOVABLE_TYPE); + +class IconSizeCategoryModel : public QAbstractListModel +{ + Q_OBJECT + +public: + IconSizeCategoryModel(QObject *parent); + ~IconSizeCategoryModel() override; + + enum Roles { + ConfigKeyRole = Qt::UserRole + 1, + ConfigSectionRole + }; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role) const override; + QHash roleNames() const override; + + void load(); + +signals: + void categorySelectedIndexChanged(); + +private: + QVector m_data; +}; diff --git a/kcms/icons/iconsizecategorymodel.cpp b/kcms/icons/iconsizecategorymodel.cpp new file mode 100644 --- /dev/null +++ b/kcms/icons/iconsizecategorymodel.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2019 Benjamin Port + * + * 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) any later version. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "iconsizecategorymodel.h" +#include + +IconSizeCategoryModel::IconSizeCategoryModel(QObject *parent) + : QAbstractListModel(parent) + , m_data({ + {QStringLiteral("desktopSize"), I18N_NOOP("Desktop"), QStringLiteral("Desktop")}, + {QStringLiteral("toolbarSize"), I18N_NOOP("Toolbar"), QStringLiteral("Toolbar")}, + {QStringLiteral("mainToolbarSize"), I18N_NOOP("Main Toolbar"), QStringLiteral("MainToolbar")}, + {QStringLiteral("smallSize"), I18N_NOOP("Small Icons"), QStringLiteral("Small")}, + {QStringLiteral("panelSize"), I18N_NOOP("Panel"), QStringLiteral("Panel")}, + {QStringLiteral("dialogSize"), I18N_NOOP("Dialogs"), QStringLiteral("Dialog")} + }) +{ +} + +IconSizeCategoryModel::~IconSizeCategoryModel() = default; + +int IconSizeCategoryModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) { + return 0; + } + + return m_data.count(); +} + +QVariant IconSizeCategoryModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.row() >= m_data.count()) { + return QVariant(); + } + + const auto &item = m_data.at(index.row()); + + switch (role) { + case Qt::DisplayRole: + return item.display; + case ConfigKeyRole: + return item.configKey; + case ConfigSectionRole: + return item.configSection; + } + + return QVariant(); +} + +QHash IconSizeCategoryModel::roleNames() const +{ + QHash roleNames = QAbstractListModel::roleNames(); + roleNames[ConfigKeyRole] = QByteArrayLiteral("configKey"); + roleNames[ConfigSectionRole] = QByteArrayLiteral("configSectionRole"); + return roleNames; +} diff --git a/kcms/icons/iconsmodel.h b/kcms/icons/iconsmodel.h --- a/kcms/icons/iconsmodel.h +++ b/kcms/icons/iconsmodel.h @@ -27,6 +27,8 @@ #include #include +class IconsSettings; + struct IconsModelData { QString display; @@ -41,11 +43,8 @@ { Q_OBJECT - Q_PROPERTY(QString selectedTheme READ selectedTheme WRITE setSelectedTheme NOTIFY selectedThemeChanged) - Q_PROPERTY(int selectedThemeIndex READ selectedThemeIndex NOTIFY selectedThemeIndexChanged) - public: - IconsModel(QObject *parent); + IconsModel(IconsSettings *iconsSettings, QObject *parent = nullptr); ~IconsModel() override; enum Roles { @@ -60,25 +59,16 @@ bool setData(const QModelIndex &index, const QVariant &value, int role) override; QHash roleNames() const override; - QString selectedTheme() const; - void setSelectedTheme(const QString &theme); - - int selectedThemeIndex() const; - QStringList pendingDeletions() const; void removeItemsPendingDeletion(); void load(); signals: - void selectedThemeChanged(); - void selectedThemeIndexChanged(); - void pendingDeletionsChanged(); private: - QString m_selectedTheme; - QVector m_data; + IconsSettings *m_settings; }; diff --git a/kcms/icons/iconsmodel.cpp b/kcms/icons/iconsmodel.cpp --- a/kcms/icons/iconsmodel.cpp +++ b/kcms/icons/iconsmodel.cpp @@ -29,7 +29,11 @@ #include -IconsModel::IconsModel(QObject *parent) : QAbstractListModel(parent) +#include "iconssettings.h" + +IconsModel::IconsModel(IconsSettings *iconsSettings, QObject *parent) + : QAbstractListModel(parent) + , m_settings(iconsSettings) { } @@ -82,7 +86,7 @@ // move to the next non-pending theme const auto nonPending = match(index, PendingDeletionRole, false); if (!nonPending.isEmpty()) { - setSelectedTheme(nonPending.first().data(ThemeNameRole).toString()); + m_settings->setTheme(nonPending.first().data(ThemeNameRole).toString()); } emit pendingDeletionsChanged(); @@ -104,45 +108,10 @@ }; } -QString IconsModel::selectedTheme() const -{ - return m_selectedTheme; -} - -void IconsModel::setSelectedTheme(const QString &theme) -{ - if (m_selectedTheme == theme) { - return; - } - - const bool firstTime = m_selectedTheme.isNull(); - m_selectedTheme = theme; - - if (!firstTime) { - emit selectedThemeChanged(); - } - emit selectedThemeIndexChanged(); -} - -int IconsModel::selectedThemeIndex() const -{ - auto it = std::find_if(m_data.begin(), m_data.end(), [this](const IconsModelData &item) { - return item.themeName == m_selectedTheme; - }); - - if (it != m_data.end()) { - return std::distance(m_data.begin(), it); - } - - return -1; -} - void IconsModel::load() { beginResetModel(); - const int oldCount = m_data.count(); - m_data.clear(); const QStringList themes = KIconTheme::list(); @@ -175,11 +144,6 @@ }); endResetModel(); - - // an item might have been added before the currently selected one - if (oldCount != m_data.count()) { - emit selectedThemeIndexChanged(); - } } QStringList IconsModel::pendingDeletions() const diff --git a/kcms/icons/iconssettings.h b/kcms/icons/iconssettings.h new file mode 100644 --- /dev/null +++ b/kcms/icons/iconssettings.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019 Benjamin Port + * + * 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) any later version. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef PLASMA_DESKTOP_ICONSSETTINGS_H +#define PLASMA_DESKTOP_ICONSSETTINGS_H + +#include "iconssettingsbase.h" + +class IconsSettings : public IconsSettingsBase { + Q_OBJECT +public: + IconsSettings(QObject *parent = nullptr); + ~IconsSettings() override; +public slots: + void updateIconTheme(); + void updateThemeDirty(); +private: + bool m_themeDirty; +}; + + +#endif //PLASMA_DESKTOP_ICONSSETTINGS_H diff --git a/kcms/icons/iconssettings.cpp b/kcms/icons/iconssettings.cpp new file mode 100644 --- /dev/null +++ b/kcms/icons/iconssettings.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2019 Benjamin Port + * + * 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) any later version. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include +#include +#include + +#include "iconssettings.h" + +IconsSettings::IconsSettings(QObject *parent) + : IconsSettingsBase(parent) + , m_themeDirty(false) +{ + connect(this, &IconsSettings::configChanged, this, &IconsSettings::updateIconTheme); + connect(this, &IconsSettings::ThemeChanged, this, &IconsSettings::updateThemeDirty); +} + +IconsSettings::~IconsSettings() +{ +} + +void IconsSettings::updateThemeDirty() +{ + m_themeDirty = theme() != KIconTheme::current(); +} + +void IconsSettings::updateIconTheme() +{ + if (m_themeDirty) { + KIconTheme::reconfigure(); + + KSharedDataCache::deleteCache(QStringLiteral("icon-cache")); + + for (int i = 0; i < KIconLoader::LastGroup; i++) { + KIconLoader::emitChange(KIconLoader::Group(i)); + } + + KBuildSycocaProgressDialog::rebuildKSycoca(nullptr); + } +} diff --git a/kcms/icons/iconssettingsbase.kcfg b/kcms/icons/iconssettingsbase.kcfg new file mode 100644 --- /dev/null +++ b/kcms/icons/iconssettingsbase.kcfg @@ -0,0 +1,49 @@ + + + + + + + breeze + + + + + + 32 + + + + + + 22 + + + + + + 22 + + + + + + 16 + + + + + + 48 + + + + + + 32 + + + diff --git a/kcms/icons/iconssettingsbase.kcfgc b/kcms/icons/iconssettingsbase.kcfgc new file mode 100644 --- /dev/null +++ b/kcms/icons/iconssettingsbase.kcfgc @@ -0,0 +1,6 @@ +File=iconssettingsbase.kcfg +ClassName=IconsSettingsBase +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 * https://www.qt.io/ @@ -25,13 +26,16 @@ #pragma once -#include +#include #include +#include #include +#include class KIconTheme; +class IconsSettings; class QQuickItem; class QTemporaryFile; @@ -42,15 +46,14 @@ } class IconsModel; +class IconSizeCategoryModel; -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(IconSizeCategoryModel *iconSizeCategoryModel READ iconSizeCategoryModel CONSTANT) Q_PROPERTY(bool downloadingFile READ downloadingFile NOTIFY downloadingFileChanged) public: @@ -64,28 +67,26 @@ PendingDeletionRole }; + IconsSettings *iconsSettings() const; IconsModel *iconsModel() const; - - QStringList iconGroups() const; + IconSizeCategoryModel *iconSizeCategoryModel() const; bool downloadingFile() const; void load() override; void save() override; - void defaults() override; 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 int pluginIndex(const QString &pluginName) const; + // QML doesn't understand QList, hence wrapped in a QVariantList Q_INVOKABLE QVariantList previewIcons(const QString &themeName, int size, qreal dpr, int limit = -1); signals: - void iconSizesChanged(); void downloadingFileChanged(); void showSuccessMessage(const QString &message); @@ -95,7 +96,7 @@ void hideProgress(); private: - void loadIconSizes(); + bool isSaveNeeded() const override; void processPendingDeletions(); @@ -107,18 +108,14 @@ 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; + IconSizeCategoryModel *m_iconSizeCategoryModel; - QStringList m_iconGroups; + mutable QCache m_kiconThemeCache; 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 * https://www.qt.io/ @@ -55,29 +56,23 @@ #include #include // for unlink +#include "iconssettings.h" #include "iconsmodel.h" +#include "iconsizecategorymodel.h" #include "config.h" // for CMAKE_INSTALL_FULL_LIBEXECDIR -static const QVector s_defaultIconSizes = { 32, 22, 22, 16, 48, 32 }; -// we try to use KIconTheme::defaultThemeName() but that could be "hicolor" which isn't a "real" theme -static const QString s_defaultThemeName = QStringLiteral("breeze"); - K_PLUGIN_FACTORY_WITH_JSON(IconsFactory, "kcm_icons.json", registerPlugin();) IconModule::IconModule(QObject *parent, const QVariantList &args) - : KQuickAddons::ConfigModule(parent, args) - , m_model(new IconsModel(this)) - , m_iconGroups{ - QStringLiteral("Desktop"), - QStringLiteral("Toolbar"), - QStringLiteral("MainToolbar"), - QStringLiteral("Small"), - QStringLiteral("Panel"), - QStringLiteral("Dialog") - } + : KQuickAddons::ManagedConfigModule(parent, args) + , m_settings(new IconsSettings(this)) + , m_model(new IconsModel(m_settings, this)) + , m_iconSizeCategoryModel(new IconSizeCategoryModel(this)) { + qmlRegisterType(); qmlRegisterType(); + qmlRegisterType(); // to be able to access its enums qmlRegisterUncreatableType("org.kde.private.kcms.icons", 1, 0, "KIconLoader", QString()); @@ -94,105 +89,79 @@ 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, &IconsModel::pendingDeletionsChanged, this, &IconModule::settingsChanged); // When user has a lot of themes installed, preview pixmaps might get evicted prematurely QPixmapCache::setCacheLimit(50 * 1024); // 50 MiB } IconModule::~IconModule() { +} +IconsSettings *IconModule::iconsSettings() const +{ + return m_settings; } IconsModel *IconModule::iconsModel() const { return m_model; } -QStringList IconModule::iconGroups() const +IconSizeCategoryModel *IconModule::iconSizeCategoryModel() const { - return m_iconGroups; + return m_iconSizeCategoryModel; } bool IconModule::downloadingFile() const { return m_tempCopyJob; } -int IconModule::iconSize(int group) const -{ - return m_iconSizes[group]; -} - -void IconModule::setIconSize(int group, int size) -{ - if (iconSize(group) == size) { - return; - } - - 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)); + const auto themeName = m_settings->theme(); + if (!m_kiconThemeCache.contains(m_settings->theme())) { + m_kiconThemeCache.insert(themeName, new KIconTheme(themeName)); + } + return m_kiconThemeCache[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; + // Model has been cleared so pretend the theme name changed to force view update + emit m_settings->ThemeChanged(); } void IconModule::save() { - if (m_selectedThemeDirty) { - QProcess::startDetached(CMAKE_INSTALL_FULL_LIBEXECDIR "/plasma-changeicons", {m_model->selectedTheme()}); - } + bool needToExportToKDE4 = m_settings->isSaveNeeded(); - 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(); +} - setNeedsSave(false); - m_selectedThemeDirty = false; - m_iconSizesDirty = false; +bool IconModule::isSaveNeeded() const +{ + return !m_model->pendingDeletions().isEmpty(); } void IconModule::processPendingDeletions() { const QStringList pendingDeletions = m_model->pendingDeletions(); for (const QString &themeName : pendingDeletions) { - Q_ASSERT(themeName != m_model->selectedTheme()); + Q_ASSERT(themeName != m_settings->theme()); KIconTheme theme(themeName); auto *job = KIO::del(QUrl::fromLocalFile(theme.dir()), KIO::HideProgressInfo); @@ -203,54 +172,6 @@ m_model->removeItemsPendingDeletion(); } -void IconModule::defaults() -{ - if (m_iconSizes != s_defaultIconSizes) { - m_iconSizes = s_defaultIconSizes; - emit iconSizesChanged(); - } - - auto setThemeIfAvailable = [this](const QString &themeName) { - const auto results = m_model->match(m_model->index(0, 0), ThemeNameRole, themeName); - if (results.isEmpty()) { - return false; - } - - m_model->setSelectedTheme(themeName); - return true; - }; - - 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) { if (!m_newStuffDialog) { @@ -347,10 +268,12 @@ KConfig kde4config(configFilePath, KConfig::SimpleConfig); KConfigGroup kde4IconGroup(&kde4config, "Icons"); - kde4IconGroup.writeEntry("Theme", m_model->selectedTheme()); + kde4IconGroup.writeEntry("Theme", m_settings->theme()); //Synchronize icon effects - for (const QString &group : qAsConst(m_iconGroups)) { + for (int row = 0; row < m_iconSizeCategoryModel->rowCount(); row++) { + QModelIndex idx(m_iconSizeCategoryModel->index(row, 0)); + QString group = m_iconSizeCategoryModel->data(idx, IconSizeCategoryModel::ConfigSectionRole).toString(); const QString groupName = group + QLatin1String("Icons"); KConfigGroup cg(kglobalcfg, groupName); KConfigGroup kde4Cg(&kde4config, groupName); @@ -573,4 +496,13 @@ return QPixmap(); } +int IconModule::pluginIndex(const QString &themeName) const +{ + const auto results = m_model->match(m_model->index(0, 0), ThemeNameRole, themeName); + if (results.count() == 1) { + return results.first().row(); + } + return -1; +} + #include "main.moc" 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 { @@ -73,7 +76,8 @@ keyNavigationWraps: true highlightMoveDuration: 0 - model: kcm.iconGroups + model: kcm.iconSizeCategoryModel + currentIndex: 0 // Initialize with the first item Keys.onLeftPressed: { LayoutMirroring.enabled ? iconSizeSlider.increase() : iconSizeSlider.decrease() @@ -87,15 +91,8 @@ 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: model.display + readonly property string configKey: model.configKey onClicked: { ListView.view.currentIndex = index; ListView.view.forceActiveFocus(); @@ -106,23 +103,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.currentItem.configKey] = 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.currentItem.configKey] // I have no idea what this code does but it works and is just copied from the old KCM var index = -1; @@ -153,7 +151,7 @@ Kirigami.Icon { anchors.centerIn: parent - width: iconSizeSlider.currentSize + width: kcm.iconsSettings[iconTypeList.currentItem.configKey] height: width source: "folder" } @@ -163,7 +161,7 @@ id: iconSizeLabel Layout.fillWidth: true horizontalAlignment: Text.AlignHCenter - text: iconSizeSlider.currentSize + text: kcm.iconsSettings[iconTypeList.currentItem.configKey] } } } diff --git a/kcms/icons/package/contents/ui/main.qml b/kcms/icons/package/contents/ui/main.qml --- a/kcms/icons/package/contents/ui/main.qml +++ b/kcms/icons/package/contents/ui/main.qml @@ -34,8 +34,7 @@ KCM.ConfigModule.quickHelp: i18n("This module allows you to choose the icons for your desktop.") view.model: kcm.iconsModel - view.currentIndex: kcm.iconsModel.selectedThemeIndex - + view.currentIndex: kcm.pluginIndex(kcm.iconsSettings.theme) enabled: !kcm.downloadingFile DropArea { @@ -166,7 +165,7 @@ ] onClicked: { if (!model.pendingDeletion) { - kcm.iconsModel.selectedTheme = model.themeName; + kcm.iconsSettings.theme = model.themeName; } view.forceActiveFocus(); }