File indexing completed on 2024-04-14 14:18:24

0001 /*
0002     This file is part of the KDE project
0003     SPDX-FileCopyrightText: 2007, 2006 Rafael Fernández López <ereslibre@kde.org>
0004     SPDX-FileCopyrightText: 2002-2003 Matthias Kretz <kretz@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-only
0007 */
0008 
0009 #ifndef KPLUGINSELECTOR_P_H
0010 #define KPLUGINSELECTOR_P_H
0011 
0012 #include <QAbstractListModel>
0013 #include <QSet>
0014 
0015 #include <KCategorizedSortFilterProxyModel>
0016 #include <KConfigGroup>
0017 #include <KPluginInfo>
0018 #include <kwidgetitemdelegate.h>
0019 
0020 class QLabel;
0021 class QCheckBox;
0022 class QLineEdit;
0023 class QPushButton;
0024 class QAbstractItemView;
0025 
0026 class KCategorizedView;
0027 class KCModuleProxy;
0028 class KCategoryDrawer;
0029 
0030 class PluginEntry;
0031 
0032 class Q_DECL_HIDDEN KPluginSelector::Private : public QObject
0033 {
0034     Q_OBJECT
0035 
0036 public:
0037     enum ExtraRoles {
0038         PluginEntryRole = 0x09386561,
0039         ServicesCountRole = 0x1422E2AA,
0040         NameRole = 0x0CBBBB00,
0041         CommentRole = 0x19FC6DE2,
0042         AuthorRole = 0x30861E10,
0043         EmailRole = 0x02BE3775,
0044         WebsiteRole = 0x13095A34,
0045         VersionRole = 0x0A0CB450,
0046         LicenseRole = 0x001F308A,
0047         DependenciesRole = 0x04CAB650,
0048         IsCheckableRole = 0x0AC2AFF8,
0049     };
0050 
0051     Private(KPluginSelector *parent);
0052     ~Private() override;
0053 
0054     void updateDependencies(PluginEntry *pluginEntry, bool added);
0055     int dependantLayoutValue(int value, int width, int totalWidth) const;
0056 
0057 public:
0058     class PluginModel;
0059     class ProxyModel;
0060     class PluginDelegate;
0061     class DependenciesWidget;
0062     KPluginSelector *parent;
0063     QLineEdit *lineEdit;
0064     KCategorizedView *listView;
0065     KCategoryDrawer *categoryDrawer;
0066     PluginModel *pluginModel;
0067     ProxyModel *proxyModel;
0068     PluginDelegate *pluginDelegate;
0069     DependenciesWidget *dependenciesWidget;
0070     bool showIcons;
0071     QStringList kcmArguments;
0072     bool showDefaultIndicator;
0073 };
0074 
0075 class PluginEntry
0076 {
0077 public:
0078     QString category;
0079     KPluginInfo pluginInfo;
0080     bool checked;
0081     bool manuallyAdded;
0082     KConfigGroup cfgGroup;
0083     KPluginSelector::PluginLoadMethod pluginLoadMethod;
0084     bool isCheckable;
0085 
0086     bool operator==(const PluginEntry &pe) const
0087     {
0088         // just comparing the entry path is not enough, since it is now also possible
0089         // to load the plugin information directly from a library (without .desktop files)
0090         return pluginInfo.entryPath() == pe.pluginInfo.entryPath() && pluginInfo.libraryPath() == pe.pluginInfo.libraryPath();
0091     }
0092 };
0093 
0094 Q_DECLARE_METATYPE(PluginEntry *)
0095 
0096 /**
0097  * This widget will inform the user about changes that happened automatically
0098  * due to plugin dependencies.
0099  */
0100 class KPluginSelector::Private::DependenciesWidget : public QWidget
0101 {
0102     Q_OBJECT
0103 
0104 public:
0105     DependenciesWidget(QWidget *parent = nullptr);
0106     ~DependenciesWidget() override;
0107 
0108     void addDependency(const QString &dependency, const QString &pluginCausant, bool added);
0109     void userOverrideDependency(const QString &dependency);
0110 
0111     void clearDependencies();
0112 
0113 private Q_SLOTS:
0114     void showDependencyDetails();
0115 
0116 private:
0117     struct FurtherInfo {
0118         bool added;
0119         QString pluginCausant;
0120     };
0121 
0122     void updateDetails();
0123 
0124     QLabel *details;
0125     QMap<QString, struct FurtherInfo> dependencyMap;
0126     int addedByDependencies;
0127     int removedByDependencies;
0128 };
0129 
0130 class KPluginSelector::Private::PluginModel : public QAbstractListModel
0131 {
0132 public:
0133     PluginModel(KPluginSelector::Private *pluginSelector_d, QObject *parent = nullptr);
0134     ~PluginModel() override;
0135 
0136     void addPlugins(const QList<KPluginInfo> &pluginList,
0137                     const QString &categoryName,
0138                     const QString &categoryKey,
0139                     const KConfigGroup &cfgGroup,
0140                     PluginLoadMethod pluginLoadMethod = ReadConfigFile,
0141                     bool manuallyAdded = false);
0142     void clear();
0143 
0144     QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const override;
0145     QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
0146     bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
0147     int rowCount(const QModelIndex &parent = QModelIndex()) const override;
0148 
0149 public:
0150     QList<PluginEntry> pluginEntryList;
0151 
0152 private:
0153     KPluginSelector::Private *pluginSelector_d;
0154 };
0155 
0156 class KPluginSelector::Private::ProxyModel : public KCategorizedSortFilterProxyModel
0157 {
0158 public:
0159     ProxyModel(KPluginSelector::Private *pluginSelector_d, QObject *parent = nullptr);
0160     ~ProxyModel() override;
0161 
0162 protected:
0163     bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
0164     bool subSortLessThan(const QModelIndex &left, const QModelIndex &right) const override;
0165 
0166 private:
0167     KPluginSelector::Private *pluginSelector_d;
0168 };
0169 
0170 class KPluginSelector::Private::PluginDelegate : public KWidgetItemDelegate
0171 {
0172     Q_OBJECT
0173 
0174 public:
0175     PluginDelegate(KPluginSelector::Private *pluginSelector_d, QObject *parent = nullptr);
0176     ~PluginDelegate() override;
0177 
0178     void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
0179     QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
0180     void configure(const QModelIndex &idx);
0181     inline void clearChangedEntries()
0182     {
0183         changedEntries.clear();
0184     };
0185     inline void addChangedEntry(PluginEntry *entry)
0186     {
0187         changedEntries << entry;
0188     };
0189     void setHandler(std::function<QPushButton *(const KPluginInfo &)> handler);
0190 
0191 public Q_SLOTS:
0192     void slotResetModel();
0193 
0194 Q_SIGNALS:
0195     void changed(bool hasChanged);
0196     void configCommitted(const QByteArray &componentName);
0197 
0198 protected:
0199     QList<QWidget *> createItemWidgets(const QModelIndex &index) const override;
0200     void updateItemWidgets(const QList<QWidget *> widgets, const QStyleOptionViewItem &option, const QPersistentModelIndex &index) const override;
0201 
0202 private Q_SLOTS:
0203     void slotStateChanged(bool state);
0204     void emitChanged(bool state);
0205     void slotAboutClicked();
0206     void slotConfigureClicked();
0207     void slotDefaultClicked();
0208 
0209 private:
0210     QFont titleFont(const QFont &baseFont) const;
0211 
0212     QCheckBox *checkBox;
0213     QPushButton *pushButton;
0214     QList<KCModuleProxy *> moduleProxyList;
0215     QSet<PluginEntry *> changedEntries;
0216     std::function<QPushButton *(const KPluginInfo &)> handler = nullptr;
0217 
0218     KPluginSelector::Private *pluginSelector_d;
0219 };
0220 
0221 #endif // KPLUGINSELECTOR_P_H