File indexing completed on 2026-07-05 20:13:14

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2013 Antonis Tsiapaliokas <kok3rs@gmail.com>
0006     SPDX-FileCopyrightText: 2018 Vlad Zahorodnii <vlad.zahorodnii@kde.org>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 
0011 #pragma once
0012 
0013 #include <kwin_export.h>
0014 
0015 #include <KSharedConfig>
0016 
0017 #include <QAbstractItemModel>
0018 #include <QString>
0019 #include <QUrl>
0020 #include <QWindow>
0021 
0022 namespace KWin
0023 {
0024 
0025 class KWIN_EXPORT EffectsModel : public QAbstractItemModel
0026 {
0027     Q_OBJECT
0028 
0029 public:
0030     /**
0031      * This enum type is used to specify data roles.
0032      */
0033     enum AdditionalRoles {
0034         /**
0035          * The user-friendly name of the effect.
0036          */
0037         NameRole = Qt::UserRole + 1,
0038         /**
0039          * The description of the effect.
0040          */
0041         DescriptionRole,
0042         /**
0043          * The name of the effect's author. If there are several authors, they
0044          * will be comma separated.
0045          */
0046         AuthorNameRole,
0047         /**
0048          * The email of the effect's author. If there are several authors, the
0049          * emails will be comma separated.
0050          */
0051         AuthorEmailRole,
0052         /**
0053          * The license of the effect.
0054          */
0055         LicenseRole,
0056         /**
0057          * The version of the effect.
0058          */
0059         VersionRole,
0060         /**
0061          * The category of the effect.
0062          */
0063         CategoryRole,
0064         /**
0065          * The service name(plugin name) of the effect.
0066          */
0067         ServiceNameRole,
0068         /**
0069          * The icon name of the effect.
0070          */
0071         IconNameRole,
0072         /**
0073          * Whether the effect is enabled or disabled.
0074          */
0075         StatusRole,
0076         /**
0077          * Link to a video demonstration of the effect.
0078          */
0079         VideoRole,
0080         /**
0081          * Link to the home page of the effect.
0082          */
0083         WebsiteRole,
0084         /**
0085          * Whether the effect is supported.
0086          */
0087         SupportedRole,
0088         /**
0089          * The exclusive group of the effect.
0090          */
0091         ExclusiveRole,
0092         /**
0093          * Whether the effect is internal.
0094          */
0095         InternalRole,
0096         /**
0097          * Whether the effect has a KCM.
0098          */
0099         ConfigurableRole,
0100         /**
0101          * Whether this is a scripted effect.
0102          */
0103         ScriptedRole,
0104         /**
0105          * Whether the effect is enabled by default.
0106          */
0107         EnabledByDefaultRole,
0108         /**
0109          * Id of the effect's config module, empty if the effect has no config.
0110          */
0111         ConfigModuleRole,
0112         /**
0113          * Whether the effect has a function to determine if the effect is enabled by default.
0114          */
0115         EnabledByDefaultFunctionRole,
0116     };
0117 
0118     /**
0119      * This enum type is used to specify the status of a given effect.
0120      */
0121     enum class Status {
0122         /**
0123          * The effect is disabled.
0124          */
0125         Disabled = Qt::Unchecked,
0126         /**
0127          * An enable function is used to determine whether the effect is enabled.
0128          * For example, such function can be useful to disable the blur effect
0129          * when running in a virtual machine.
0130          */
0131         EnabledUndeterminded = Qt::PartiallyChecked,
0132         /**
0133          * The effect is enabled.
0134          */
0135         Enabled = Qt::Checked
0136     };
0137 
0138     explicit EffectsModel(QObject *parent = nullptr);
0139 
0140     // Reimplemented from QAbstractItemModel.
0141     QHash<int, QByteArray> roleNames() const override;
0142     QModelIndex index(int row, int column, const QModelIndex &parent = {}) const override;
0143     QModelIndex parent(const QModelIndex &child) const override;
0144     int rowCount(const QModelIndex &parent = {}) const override;
0145     int columnCount(const QModelIndex &parent = {}) const override;
0146     QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
0147     bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
0148 
0149     /**
0150      * Changes the status of a given effect.
0151      *
0152      * @param rowIndex An effect represented by the given index.
0153      * @param effectState The new state.
0154      * @note In order to actually apply the change, you have to call save().
0155      */
0156     void updateEffectStatus(const QModelIndex &rowIndex, Status effectState);
0157 
0158     /**
0159      * This enum type is used to specify load options.
0160      */
0161     enum class LoadOptions {
0162         None,
0163         /**
0164          * Do not discard unsaved changes when reloading the model.
0165          */
0166         KeepDirty
0167     };
0168 
0169     /**
0170      * Loads effects.
0171      *
0172      * You have to call this method in order to populate the model.
0173      */
0174     void load(LoadOptions options = LoadOptions::None);
0175 
0176     /**
0177      * Saves status of each modified effect.
0178      */
0179     void save();
0180 
0181     /**
0182      * Resets the status of each effect to the default state.
0183      *
0184      * @note In order to actually apply the change, you have to call save().
0185      */
0186     void defaults();
0187 
0188     /**
0189      * Whether the status of each effect is its default state.
0190      */
0191     bool isDefaults() const;
0192 
0193     /**
0194      * Whether the model has unsaved changes.
0195      */
0196     bool needsSave() const;
0197 
0198     /**
0199      * Finds an effect with the given plugin id.
0200      */
0201     QModelIndex findByPluginId(const QString &pluginId) const;
0202 
0203     /**
0204      * Shows a configuration dialog for a given effect.
0205      *
0206      * @param index An effect represented by the given index.
0207      * @param transientParent The transient parent of the configuration dialog.
0208      */
0209     void requestConfigure(const QModelIndex &index, QWindow *transientParent);
0210 
0211 Q_SIGNALS:
0212     /**
0213      * This signal is emitted when the model is loaded or reloaded.
0214      *
0215      * @see load
0216      */
0217     void loaded();
0218 
0219 protected:
0220     enum class Kind {
0221         BuiltIn,
0222         Binary,
0223         Scripted
0224     };
0225 
0226     struct EffectData
0227     {
0228         QString name;
0229         QString description;
0230         QString authorName;
0231         QString authorEmail;
0232         QString license;
0233         QString version;
0234         QString untranslatedCategory;
0235         QString category;
0236         QString serviceName;
0237         QString iconName;
0238         Status status;
0239         Status originalStatus;
0240         bool enabledByDefault;
0241         bool enabledByDefaultFunction;
0242         QUrl video;
0243         QUrl website;
0244         bool supported;
0245         QString exclusiveGroup;
0246         bool internal;
0247         bool configurable;
0248         Kind kind;
0249         bool changed = false;
0250         QString configModule;
0251     };
0252 
0253     /**
0254      * Returns whether the given effect should be stored in the model.
0255      *
0256      * @param data The effect.
0257      * @returns @c true if the effect should be stored, otherwise @c false.
0258      */
0259     virtual bool shouldStore(const EffectData &data) const;
0260 
0261 private:
0262     void loadBuiltInEffects(const KConfigGroup &kwinConfig);
0263     void loadJavascriptEffects(const KConfigGroup &kwinConfig);
0264     void loadPluginEffects(const KConfigGroup &kwinConfig);
0265 
0266     QVector<EffectData> m_effects;
0267     QVector<EffectData> m_pendingEffects;
0268     int m_lastSerial = -1;
0269 
0270     Q_DISABLE_COPY(EffectsModel)
0271 };
0272 
0273 }