File indexing completed on 2024-11-10 04:56:49

0001 /*
0002     SPDX-FileCopyrightText: 2020 Ismael Asensio <isma.af@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 
0007 #include "optionsmodel.h"
0008 
0009 #include <KLocalizedString>
0010 
0011 namespace KWin
0012 {
0013 
0014 QHash<int, QByteArray> OptionsModel::roleNames() const
0015 {
0016     return {
0017         {Qt::DisplayRole, QByteArrayLiteral("display")},
0018         {Qt::DecorationRole, QByteArrayLiteral("decoration")},
0019         {Qt::ToolTipRole, QByteArrayLiteral("tooltip")},
0020         {ValueRole, QByteArrayLiteral("value")},
0021         {IconNameRole, QByteArrayLiteral("iconName")},
0022         {OptionTypeRole, QByteArrayLiteral("optionType")},
0023         {BitMaskRole, QByteArrayLiteral("bitMask")},
0024     };
0025 }
0026 
0027 int OptionsModel::rowCount(const QModelIndex &parent) const
0028 {
0029     if (parent.isValid()) {
0030         return 0;
0031     }
0032     return m_data.size();
0033 }
0034 
0035 QVariant OptionsModel::data(const QModelIndex &index, int role) const
0036 {
0037     if (!checkIndex(index, CheckIndexOption::IndexIsValid | CheckIndexOption::ParentIsInvalid)) {
0038         return QVariant();
0039     }
0040 
0041     const Data item = m_data.at(index.row());
0042 
0043     switch (role) {
0044     case Qt::DisplayRole:
0045         return item.text;
0046     case Qt::UserRole:
0047         return item.value;
0048     case Qt::DecorationRole:
0049         return item.icon;
0050     case IconNameRole:
0051         return item.icon.name();
0052     case Qt::ToolTipRole:
0053         return item.description;
0054     case OptionTypeRole:
0055         return item.optionType;
0056     case BitMaskRole:
0057         return bitMask(index.row());
0058     }
0059     return QVariant();
0060 }
0061 
0062 int OptionsModel::selectedIndex() const
0063 {
0064     return m_index;
0065 }
0066 
0067 int OptionsModel::indexOf(const QVariant &value) const
0068 {
0069     for (int index = 0; index < m_data.count(); index++) {
0070         if (m_data.at(index).value == value) {
0071             return index;
0072         }
0073     }
0074     return -1;
0075 }
0076 
0077 QString OptionsModel::textOfValue(const QVariant &value) const
0078 {
0079     int index = indexOf(value);
0080     if (index < 0 || index >= m_data.count()) {
0081         return QString();
0082     }
0083     return m_data.at(index).text;
0084 }
0085 
0086 QVariant OptionsModel::value() const
0087 {
0088     if (m_data.isEmpty()) {
0089         return QVariant();
0090     }
0091     if (m_data.at(m_index).optionType == SelectAllOption) {
0092         return allValues();
0093     }
0094     return m_data.at(m_index).value;
0095 }
0096 
0097 void OptionsModel::setValue(QVariant value)
0098 {
0099     if (this->value() == value) {
0100         return;
0101     }
0102     int index = indexOf(value);
0103     if (index >= 0 && index != m_index) {
0104         m_index = index;
0105         Q_EMIT selectedIndexChanged(index);
0106     }
0107 }
0108 
0109 void OptionsModel::resetValue()
0110 {
0111     m_index = 0;
0112     Q_EMIT selectedIndexChanged(m_index);
0113 }
0114 
0115 bool OptionsModel::useFlags() const
0116 {
0117     return m_useFlags;
0118 };
0119 
0120 uint OptionsModel::bitMask(int index) const
0121 {
0122     const Data item = m_data.at(index);
0123 
0124     if (item.optionType == SelectAllOption) {
0125         return allOptionsMask();
0126     }
0127     if (m_useFlags) {
0128         return item.value.toUInt();
0129     }
0130     return 1u << index;
0131 }
0132 
0133 QVariant OptionsModel::allValues() const
0134 {
0135     if (m_useFlags) {
0136         return allOptionsMask();
0137     }
0138 
0139     QVariantList list;
0140     for (const Data &item : std::as_const(m_data)) {
0141         if (item.optionType == NormalOption) {
0142             list << item.value;
0143         }
0144     }
0145     return list;
0146 }
0147 
0148 uint OptionsModel::allOptionsMask() const
0149 {
0150     uint mask = 0;
0151     for (int index = 0; index < m_data.count(); index++) {
0152         if (m_data.at(index).optionType == NormalOption) {
0153             mask += bitMask(index);
0154         }
0155     }
0156     return mask;
0157 }
0158 
0159 void OptionsModel::updateModelData(const QList<Data> &data)
0160 {
0161     beginResetModel();
0162     m_data = data;
0163     endResetModel();
0164     Q_EMIT modelUpdated();
0165 }
0166 
0167 RulePolicy::Type RulePolicy::type() const
0168 {
0169     return m_type;
0170 }
0171 
0172 int RulePolicy::value() const
0173 {
0174     if (m_type == RulePolicy::NoPolicy) {
0175         return Rules::Apply; // To simplify external checks when rule has no policy
0176     }
0177     return OptionsModel::value().toInt();
0178 }
0179 
0180 QString RulePolicy::policyKey(const QString &key) const
0181 {
0182     switch (m_type) {
0183     case NoPolicy:
0184         return QString();
0185     case StringMatch:
0186         return QStringLiteral("%1match").arg(key);
0187     case SetRule:
0188     case ForceRule:
0189         return QStringLiteral("%1rule").arg(key);
0190     }
0191 
0192     return QString();
0193 }
0194 
0195 QList<RulePolicy::Data> RulePolicy::policyOptions(RulePolicy::Type type)
0196 {
0197     static const auto stringMatchOptions = QList<RulePolicy::Data>{
0198         {Rules::UnimportantMatch, i18n("Unimportant")},
0199         {Rules::ExactMatch, i18n("Exact Match")},
0200         {Rules::SubstringMatch, i18n("Substring Match")},
0201         {Rules::RegExpMatch, i18n("Regular Expression")}};
0202 
0203     static const auto setRuleOptions = QList<RulePolicy::Data>{
0204         {Rules::Apply,
0205          i18n("Apply Initially"),
0206          i18n("The window property will be only set to the given value after the window is created."
0207               "\nNo further changes will be affected.")},
0208         {Rules::ApplyNow,
0209          i18n("Apply Now"),
0210          i18n("The window property will be set to the given value immediately and will not be affected later"
0211               "\n(this action will be deleted afterwards).")},
0212         {Rules::Remember,
0213          i18n("Remember"),
0214          i18n("The value of the window property will be remembered and, every time the window"
0215               " is created, the last remembered value will be applied.")},
0216         {Rules::DontAffect,
0217          i18n("Do Not Affect"),
0218          i18n("The window property will not be affected and therefore the default handling for it will be used."
0219               "\nSpecifying this will block more generic window settings from taking effect.")},
0220         {Rules::Force,
0221          i18n("Force"),
0222          i18n("The window property will be always forced to the given value.")},
0223         {Rules::ForceTemporarily,
0224          i18n("Force Temporarily"),
0225          i18n("The window property will be forced to the given value until it is hidden"
0226               "\n(this action will be deleted after the window is hidden).")}};
0227 
0228     static auto forceRuleOptions = QList<RulePolicy::Data>{
0229         setRuleOptions.at(4), // Rules::Force
0230         setRuleOptions.at(5), // Rules::ForceTemporarily
0231         setRuleOptions.at(3), // Rules::DontAffect
0232     };
0233 
0234     switch (type) {
0235     case NoPolicy:
0236         return {};
0237     case StringMatch:
0238         return stringMatchOptions;
0239     case SetRule:
0240         return setRuleOptions;
0241     case ForceRule:
0242         return forceRuleOptions;
0243     }
0244     return {};
0245 }
0246 
0247 } // namespace
0248 
0249 #include "moc_optionsmodel.cpp"