File indexing completed on 2024-05-19 05:38:06
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 }