Warning, file /plasma/plasma-workspace/kcms/icons/iconsmodel.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     SPDX-FileCopyrightText: 1999 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
0003     SPDX-FileCopyrightText: 2000 Antonio Larrosa <larrosa@kde.org>
0004     SPDX-FileCopyrightText: 2000 Geert Jansen <jansen@kde.org>
0005     SPDX-FileCopyrightText: 2018 Kai Uwe Broulik <kde@privat.broulik.de>
0006 
0007     KDE Frameworks 5 port
0008     SPDX-FileCopyrightText: 2013 Jonathan Riddell <jr@jriddell.org>
0009 
0010     SPDX-License-Identifier: GPL-2.0-or-later
0011 */
0012 
0013 #include "iconsmodel.h"
0014 
0015 #include <QCollator>
0016 #include <QFileIconProvider>
0017 
0018 #include <KIconTheme>
0019 
0020 #include "iconssettings.h"
0021 
0022 IconsModel::IconsModel(IconsSettings *iconsSettings, QObject *parent)
0023     : QAbstractListModel(parent)
0024     , m_settings(iconsSettings)
0025 {
0026 }
0027 
0028 IconsModel::~IconsModel() = default;
0029 
0030 int IconsModel::rowCount(const QModelIndex &parent) const
0031 {
0032     if (parent.isValid()) {
0033         return 0;
0034     }
0035 
0036     return m_data.count();
0037 }
0038 
0039 QVariant IconsModel::data(const QModelIndex &index, int role) const
0040 {
0041     if (!index.isValid() || index.row() >= m_data.count()) {
0042         return QVariant();
0043     }
0044 
0045     const auto &item = m_data.at(index.row());
0046 
0047     switch (role) {
0048     case Qt::DisplayRole:
0049         return item.display;
0050     case ThemeNameRole:
0051         return item.themeName;
0052     case DescriptionRole:
0053         return item.description;
0054     case RemovableRole:
0055         return item.removable;
0056     case PendingDeletionRole:
0057         return item.pendingDeletion;
0058     }
0059 
0060     return QVariant();
0061 }
0062 
0063 bool IconsModel::setData(const QModelIndex &index, const QVariant &value, int role)
0064 {
0065     if (!index.isValid() || index.row() >= m_data.count()) {
0066         return false;
0067     }
0068 
0069     if (role == PendingDeletionRole) {
0070         auto &item = m_data[index.row()];
0071 
0072         const bool pendingDeletion = value.toBool();
0073 
0074         if (item.pendingDeletion != pendingDeletion) {
0075             item.pendingDeletion = pendingDeletion;
0076             Q_EMIT dataChanged(index, index, {PendingDeletionRole});
0077 
0078             // if we delete current selected theme move to the next non-pending theme
0079             const auto nonPending = match(index, PendingDeletionRole, false);
0080             if (m_settings->theme() == index.data(ThemeNameRole) && !nonPending.isEmpty()) {
0081                 m_settings->setTheme(nonPending.first().data(ThemeNameRole).toString());
0082             }
0083             Q_EMIT pendingDeletionsChanged();
0084             return true;
0085         }
0086     }
0087 
0088     return false;
0089 }
0090 
0091 QHash<int, QByteArray> IconsModel::roleNames() const
0092 {
0093     return {
0094         {Qt::DisplayRole, QByteArrayLiteral("display")},
0095         {DescriptionRole, QByteArrayLiteral("description")},
0096         {ThemeNameRole, QByteArrayLiteral("themeName")},
0097         {RemovableRole, QByteArrayLiteral("removable")},
0098         {PendingDeletionRole, QByteArrayLiteral("pendingDeletion")},
0099     };
0100 }
0101 
0102 void IconsModel::load()
0103 {
0104     beginResetModel();
0105 
0106     m_data.clear();
0107 
0108     const QStringList themes = KIconTheme::list();
0109 
0110     m_data.reserve(themes.count());
0111 
0112     for (const QString &themeName : themes) {
0113         KIconTheme theme(themeName);
0114         if (!theme.isValid()) {
0115             // qCWarning(KCM_ICONS) << "Not a valid theme" << themeName;
0116         }
0117         if (theme.isHidden()) {
0118             continue;
0119         }
0120 
0121         IconsModelData item{
0122             theme.name(),
0123             themeName,
0124             theme.description(),
0125             themeName != KIconTheme::defaultThemeName() && QFileInfo(theme.dir()).isWritable(),
0126             false // pending deletion
0127         };
0128 
0129         m_data.append(item);
0130     }
0131 
0132     // Sort case-insensitively
0133     QCollator collator;
0134     collator.setCaseSensitivity(Qt::CaseInsensitive);
0135     std::sort(m_data.begin(), m_data.end(), [&collator](const IconsModelData &a, const IconsModelData &b) {
0136         return collator.compare(a.display, b.display) < 0;
0137     });
0138 
0139     endResetModel();
0140 }
0141 
0142 QStringList IconsModel::pendingDeletions() const
0143 {
0144     QStringList pendingDeletions;
0145 
0146     for (const auto &item : m_data) {
0147         if (item.pendingDeletion) {
0148             pendingDeletions.append(item.themeName);
0149         }
0150     }
0151 
0152     return pendingDeletions;
0153 }
0154 
0155 void IconsModel::removeItemsPendingDeletion()
0156 {
0157     for (int i = m_data.count() - 1; i >= 0; --i) {
0158         if (m_data.at(i).pendingDeletion) {
0159             beginRemoveRows(QModelIndex(), i, i);
0160             m_data.remove(i);
0161             endRemoveRows();
0162         }
0163     }
0164 }