File indexing completed on 2024-11-24 05:01:58
0001 /* 0002 SPDX-FileCopyrightText: 2007 Ivan Cukic <ivan.cukic+kde@gmail.com> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "kcategorizeditemsviewmodels_p.h" 0008 #include <KLocalizedString> 0009 #include <QDebug> 0010 0011 #define COLUMN_COUNT 4 0012 0013 namespace KCategorizedItemsViewModels 0014 { 0015 // AbstractItem 0016 0017 QString AbstractItem::name() const 0018 { 0019 return text(); 0020 } 0021 0022 QString AbstractItem::id() const 0023 { 0024 QString plugin = data().toMap()[QStringLiteral("pluginName")].toString(); 0025 0026 if (plugin.isEmpty()) { 0027 return name(); 0028 } 0029 0030 return plugin; 0031 } 0032 0033 QString AbstractItem::description() const 0034 { 0035 return QLatin1String(""); 0036 } 0037 0038 bool AbstractItem::isFavorite() const 0039 { 0040 return passesFiltering(Filter(QStringLiteral("favorite"), true)); 0041 } 0042 0043 int AbstractItem::running() const 0044 { 0045 return 0; 0046 } 0047 0048 bool AbstractItem::matches(const QString &pattern) const 0049 { 0050 if (name().contains(pattern, Qt::CaseInsensitive) || description().contains(pattern, Qt::CaseInsensitive)) { 0051 return true; 0052 } 0053 const QStringList itemKeywords = keywords(); 0054 return std::any_of(itemKeywords.begin(), itemKeywords.end(), [&pattern](const QString &keyword) { 0055 return keyword.startsWith(pattern, Qt::CaseInsensitive); 0056 }); 0057 } 0058 0059 // DefaultFilterModel 0060 0061 DefaultFilterModel::DefaultFilterModel(QObject *parent) 0062 : QStandardItemModel(0, 1, parent) 0063 { 0064 setHeaderData(1, Qt::Horizontal, i18n("Filters")); 0065 0066 connect(this, &QAbstractItemModel::modelReset, this, &DefaultFilterModel::countChanged); 0067 connect(this, &QAbstractItemModel::rowsInserted, this, &DefaultFilterModel::countChanged); 0068 connect(this, &QAbstractItemModel::rowsRemoved, this, &DefaultFilterModel::countChanged); 0069 } 0070 0071 QHash<int, QByteArray> DefaultFilterModel::roleNames() const 0072 { 0073 static QHash<int, QByteArray> newRoleNames; 0074 if (newRoleNames.isEmpty()) { 0075 newRoleNames = QAbstractItemModel::roleNames(); 0076 newRoleNames[FilterTypeRole] = "filterType"; 0077 newRoleNames[FilterDataRole] = "filterData"; 0078 newRoleNames[SeparatorRole] = "separator"; 0079 } 0080 return newRoleNames; 0081 } 0082 0083 void DefaultFilterModel::addFilter(const QString &caption, const Filter &filter, const QIcon &icon) 0084 { 0085 QList<QStandardItem *> newRow; 0086 QStandardItem *item = new QStandardItem(caption); 0087 item->setData(QVariant::fromValue<Filter>(filter)); 0088 if (!icon.isNull()) { 0089 item->setIcon(icon); 0090 } 0091 item->setData(filter.first, FilterTypeRole); 0092 item->setData(filter.second, FilterDataRole); 0093 0094 newRow << item; 0095 appendRow(newRow); 0096 } 0097 0098 void DefaultFilterModel::addSeparator(const QString &caption) 0099 { 0100 QList<QStandardItem *> newRow; 0101 QStandardItem *item = new QStandardItem(caption); 0102 item->setEnabled(false); 0103 item->setData(true, SeparatorRole); 0104 0105 newRow << item; 0106 appendRow(newRow); 0107 } 0108 0109 QVariantHash DefaultFilterModel::get(int row) const 0110 { 0111 QModelIndex idx = index(row, 0); 0112 QVariantHash hash; 0113 0114 const QHash<int, QByteArray> roles = roleNames(); 0115 for (QHash<int, QByteArray>::const_iterator i = roles.constBegin(); i != roles.constEnd(); ++i) { 0116 hash[i.value()] = data(idx, i.key()); 0117 } 0118 0119 return hash; 0120 } 0121 0122 // DefaultItemFilterProxyModel 0123 0124 DefaultItemFilterProxyModel::DefaultItemFilterProxyModel(QObject *parent) 0125 : QSortFilterProxyModel(parent) 0126 { 0127 } 0128 0129 void DefaultItemFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel) 0130 { 0131 QStandardItemModel *model = qobject_cast<QStandardItemModel *>(sourceModel); 0132 0133 if (!model) { 0134 qWarning() << "Expecting a QStandardItemModel!"; 0135 return; 0136 } 0137 0138 QSortFilterProxyModel::setSourceModel(model); 0139 connect(this, &QAbstractItemModel::modelReset, this, &DefaultItemFilterProxyModel::countChanged); 0140 connect(this, &QAbstractItemModel::rowsInserted, this, &DefaultItemFilterProxyModel::countChanged); 0141 connect(this, &QAbstractItemModel::rowsRemoved, this, &DefaultItemFilterProxyModel::countChanged); 0142 } 0143 0144 QAbstractItemModel *DefaultItemFilterProxyModel::sourceModel() const 0145 { 0146 return QSortFilterProxyModel::sourceModel(); 0147 } 0148 0149 int DefaultItemFilterProxyModel::columnCount(const QModelIndex &index) const 0150 { 0151 Q_UNUSED(index); 0152 return COLUMN_COUNT; 0153 } 0154 0155 QVariant DefaultItemFilterProxyModel::data(const QModelIndex &index, int role) const 0156 { 0157 return QSortFilterProxyModel::data(index, role); 0158 } 0159 0160 bool DefaultItemFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const 0161 { 0162 QStandardItemModel *model = (QStandardItemModel *)sourceModel(); 0163 0164 QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); 0165 0166 AbstractItem *item = (AbstractItem *)model->itemFromIndex(index); 0167 // qDebug() << "ITEM " << (item ? "IS NOT " : "IS") << " NULL\n"; 0168 0169 return item && (m_filter.first.isEmpty() || item->passesFiltering(m_filter)) && (m_searchPattern.isEmpty() || item->matches(m_searchPattern)); 0170 } 0171 0172 QVariantHash DefaultItemFilterProxyModel::get(int row) const 0173 { 0174 QModelIndex idx = index(row, 0); 0175 QVariantHash hash; 0176 0177 const QHash<int, QByteArray> roles = roleNames(); 0178 for (QHash<int, QByteArray>::const_iterator i = roles.constBegin(); i != roles.constEnd(); ++i) { 0179 hash[i.value()] = data(idx, i.key()); 0180 } 0181 0182 return hash; 0183 } 0184 0185 bool DefaultItemFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const 0186 { 0187 return sourceModel()->data(left).toString().localeAwareCompare(sourceModel()->data(right).toString()) < 0; 0188 } 0189 0190 void DefaultItemFilterProxyModel::setSearchTerm(const QString &pattern) 0191 { 0192 m_searchPattern = pattern; 0193 invalidateFilter(); 0194 Q_EMIT searchTermChanged(pattern); 0195 } 0196 0197 QString DefaultItemFilterProxyModel::searchTerm() const 0198 { 0199 return m_searchPattern; 0200 } 0201 0202 void DefaultItemFilterProxyModel::setFilter(const Filter &filter) 0203 { 0204 m_filter = filter; 0205 invalidateFilter(); 0206 Q_EMIT filterChanged(); 0207 } 0208 0209 void DefaultItemFilterProxyModel::setFilterType(const QString &type) 0210 { 0211 m_filter.first = type; 0212 invalidateFilter(); 0213 Q_EMIT filterChanged(); 0214 } 0215 0216 QString DefaultItemFilterProxyModel::filterType() const 0217 { 0218 return m_filter.first; 0219 } 0220 0221 void DefaultItemFilterProxyModel::setFilterQuery(const QVariant &query) 0222 { 0223 m_filter.second = query; 0224 invalidateFilter(); 0225 Q_EMIT filterChanged(); 0226 } 0227 0228 QVariant DefaultItemFilterProxyModel::filterQuery() const 0229 { 0230 return m_filter.second; 0231 } 0232 0233 }