File indexing completed on 2024-12-01 11:15:17

0001 /*
0002  * SPDX-FileCopyrightText: 2009 Ben Cooksley <bcooksley@kde.org>
0003  * SPDX-FileCopyrightText: 2007 Will Stephenson <wstephenson@kde.org>
0004  *
0005  * SPDX-License-Identifier: GPL-2.0-or-later
0006  */
0007 
0008 #include "MenuProxyModel.h"
0009 
0010 #include "MenuItem.h"
0011 #include "MenuModel.h"
0012 
0013 #include <KCModuleInfo>
0014 #include <KPluginMetaData>
0015 
0016 MenuProxyModel::MenuProxyModel(QObject *parent)
0017     : KCategorizedSortFilterProxyModel(parent)
0018     , m_filterHighlightsEntries(true)
0019 {
0020     setSortRole(MenuModel::UserSortRole);
0021     setFilterRole(MenuModel::UserFilterRole);
0022     setFilterCaseSensitivity(Qt::CaseInsensitive);
0023 }
0024 
0025 QHash<int, QByteArray> MenuProxyModel::roleNames() const
0026 {
0027     QHash<int, QByteArray> names = KCategorizedSortFilterProxyModel::roleNames();
0028     names[KCategorizedSortFilterProxyModel::CategoryDisplayRole] = "categoryDisplayRole";
0029     return names;
0030 }
0031 
0032 bool MenuProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
0033 {
0034     if (isCategorizedModel()) {
0035         return KCategorizedSortFilterProxyModel::lessThan(left, right);
0036     }
0037 
0038     QVariant leftWeight = left.data(MenuModel::UserSortRole);
0039     QVariant rightWeight = right.data(MenuModel::UserSortRole);
0040 
0041     if (leftWeight.toInt() == rightWeight.toInt()) {
0042         return left.data().toString() < right.data().toString();
0043     }
0044 
0045     return leftWeight.toInt() < rightWeight.toInt();
0046 }
0047 
0048 bool MenuProxyModel::subSortLessThan(const QModelIndex &left, const QModelIndex &right) const
0049 {
0050     if (isCategorizedModel()) {
0051         QVariant leftWeight = left.data(MenuModel::UserSortRole);
0052         QVariant rightWeight = right.data(MenuModel::UserSortRole);
0053 
0054         if (!leftWeight.isValid() || !rightWeight.isValid()) {
0055             return KCategorizedSortFilterProxyModel::subSortLessThan(left, right);
0056         } else {
0057             if (leftWeight.toInt() == rightWeight.toInt()) {
0058                 return left.data().toString() < right.data().toString();
0059             } else {
0060                 return leftWeight.toInt() < rightWeight.toInt();
0061             }
0062         }
0063     }
0064     return KCategorizedSortFilterProxyModel::subSortLessThan(left, right);
0065 }
0066 
0067 bool MenuProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
0068 {
0069     if (!m_filterHighlightsEntries) {
0070         // Don't show empty categories
0071         QModelIndex index = sourceModel()->index(source_row, 0, source_parent);
0072         MenuItem *mItem = index.data(Qt::UserRole).value<MenuItem *>();
0073         if (mItem->menu() && mItem->children().isEmpty()) {
0074             return false;
0075         }
0076         if (mItem->metaData().pluginId() == QLatin1String("kcm_landingpage")) {
0077             return false;
0078         } else {
0079             return KCategorizedSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
0080         }
0081     }
0082 
0083     QModelIndex index = sourceModel()->index(source_row, 0, source_parent);
0084     MenuItem *mItem = index.data(Qt::UserRole).value<MenuItem *>();
0085 
0086     if (mItem->metaData().pluginId() == QLatin1String("kcm_landingpage")) {
0087         return false;
0088     }
0089 
0090     // accept only systemsettings categories that have children
0091     if (mItem->children().isEmpty() && mItem->isSystemsettingsCategory()) {
0092         return false;
0093     } else {
0094         return true; // Items matching the regexp are disabled, not hidden
0095     }
0096 }
0097 
0098 void MenuProxyModel::setFilterHighlightsEntries(bool highlight)
0099 {
0100     m_filterHighlightsEntries = highlight;
0101 }
0102 
0103 bool MenuProxyModel::filterHighlightsEntries() const
0104 {
0105     return m_filterHighlightsEntries;
0106 }
0107 
0108 Qt::ItemFlags MenuProxyModel::flags(const QModelIndex &index) const
0109 {
0110     if (!index.isValid()) {
0111         return Qt::NoItemFlags;
0112     }
0113 
0114     QString matchText = index.data(MenuModel::UserFilterRole).toString();
0115 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0116     QRegExp pattern = KCategorizedSortFilterProxyModel::filterRegExp();
0117 #else
0118     QRegularExpression pattern = KCategorizedSortFilterProxyModel::filterRegularExpression();
0119 #endif
0120 
0121     if (!matchText.contains(pattern)) {
0122         return Qt::NoItemFlags;
0123     } else {
0124         return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
0125     }
0126 }
0127 
0128 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0129 void MenuProxyModel::setFilterRegExp(const QString &pattern)
0130 {
0131     if (pattern == filterRegExp()) {
0132         return;
0133     }
0134     Q_EMIT layoutAboutToBeChanged();
0135     KCategorizedSortFilterProxyModel::setFilterRegExp(pattern);
0136     Q_EMIT layoutChanged();
0137     Q_EMIT filterRegExpChanged();
0138 }
0139 
0140 QString MenuProxyModel::filterRegExp() const
0141 {
0142     return KCategorizedSortFilterProxyModel::filterRegExp().pattern();
0143 }
0144 
0145 void MenuProxyModel::setFilterRegExp(const QRegExp &regExp)
0146 {
0147     Q_EMIT layoutAboutToBeChanged();
0148     KCategorizedSortFilterProxyModel::setFilterRegExp(regExp);
0149     Q_EMIT layoutChanged();
0150 }
0151 #else
0152 void MenuProxyModel::setFilterRegularExpression(const QString &pattern)
0153 {
0154     if (pattern == filterRegularExpression()) {
0155         return;
0156     }
0157     Q_EMIT layoutAboutToBeChanged();
0158     KCategorizedSortFilterProxyModel::setFilterRegularExpression(pattern);
0159     Q_EMIT layoutChanged();
0160     Q_EMIT filterRegularExpressionChanged();
0161 }
0162 
0163 QString MenuProxyModel::filterRegularExpression() const
0164 {
0165     return KCategorizedSortFilterProxyModel::filterRegularExpression().pattern();
0166 }
0167 
0168 void MenuProxyModel::setFilterRegularExpression(const QRegularExpression &regExp)
0169 {
0170     Q_EMIT layoutAboutToBeChanged();
0171     KCategorizedSortFilterProxyModel::setFilterRegularExpression(regExp);
0172     Q_EMIT layoutChanged();
0173 }
0174 #endif