File indexing completed on 2025-03-09 04:54:44

0001 /*
0002    SPDX-FileCopyrightText: 2015-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "viewerpluginmanager.h"
0008 #include "messageviewer_debug.h"
0009 #include "viewerplugin.h"
0010 
0011 #include <KPluginFactory>
0012 #include <KPluginMetaData>
0013 #include <KSharedConfig>
0014 #include <QFileInfo>
0015 
0016 using namespace MessageViewer;
0017 
0018 class ViewerPluginInfo
0019 {
0020 public:
0021     ViewerPluginInfo() = default;
0022 
0023     KPluginMetaData data;
0024     QString metaDataFileNameBaseName;
0025     QString metaDataFileName;
0026     PimCommon::PluginUtilData pluginData;
0027     MessageViewer::ViewerPlugin *plugin = nullptr;
0028     bool isEnabled = false;
0029 };
0030 
0031 class MessageViewer::ViewerPluginManagerPrivate
0032 {
0033 public:
0034     explicit ViewerPluginManagerPrivate(ViewerPluginManager *qq)
0035         : q(qq)
0036     {
0037     }
0038 
0039     bool initializePluginList();
0040     void loadPlugin(ViewerPluginInfo *item);
0041     [[nodiscard]] QList<MessageViewer::ViewerPlugin *> pluginsList() const;
0042     [[nodiscard]] QList<PimCommon::PluginUtilData> pluginDataList() const;
0043 
0044     QString pluginDirectory;
0045     QString pluginName;
0046 
0047     [[nodiscard]] QString configGroupName() const;
0048     [[nodiscard]] QString configPrefixSettingKey() const;
0049     ViewerPlugin *pluginFromIdentifier(const QString &id);
0050 
0051 private:
0052     QList<ViewerPluginInfo> mPluginList;
0053     QList<PimCommon::PluginUtilData> mPluginDataList;
0054     ViewerPluginManager *const q;
0055 };
0056 
0057 namespace
0058 {
0059 QString pluginVersion()
0060 {
0061     return QStringLiteral("2.0");
0062 }
0063 }
0064 
0065 QString ViewerPluginManagerPrivate::configGroupName() const
0066 {
0067     return QStringLiteral("PluginMessageViewer%1").arg(pluginName);
0068 }
0069 
0070 QString ViewerPluginManagerPrivate::configPrefixSettingKey() const
0071 {
0072     return QStringLiteral("MessageViewerPlugins");
0073 }
0074 
0075 bool ViewerPluginManagerPrivate::initializePluginList()
0076 {
0077     if (!mPluginList.isEmpty()) {
0078         return true;
0079     }
0080     if (pluginDirectory.isEmpty()) {
0081         return false;
0082     }
0083 
0084     QList<KPluginMetaData> plugins = KPluginMetaData::findPlugins(pluginDirectory);
0085 
0086     // We need common plugin to avoid to duplicate code between akregator/kmail
0087     plugins += KPluginMetaData::findPlugins(QStringLiteral("pim6/messageviewer/viewercommonplugin"));
0088 
0089     const QPair<QStringList, QStringList> pair = PimCommon::PluginUtil::loadPluginSetting(configGroupName(), configPrefixSettingKey());
0090     QListIterator<KPluginMetaData> i(plugins);
0091     i.toBack();
0092     while (i.hasPrevious()) {
0093         ViewerPluginInfo info;
0094 
0095         const KPluginMetaData data = i.previous();
0096 
0097         // 1) get plugin data => name/description etc.
0098         info.pluginData = PimCommon::PluginUtil::createPluginMetaData(data);
0099         // 2) look at if plugin is activated
0100         const bool isPluginActivated =
0101             PimCommon::PluginUtil::isPluginActivated(pair.first, pair.second, info.pluginData.mEnableByDefault, info.pluginData.mIdentifier);
0102         info.isEnabled = isPluginActivated;
0103         info.metaDataFileNameBaseName = QFileInfo(data.fileName()).baseName();
0104         info.metaDataFileName = data.fileName();
0105         info.data = data;
0106 
0107         if (pluginVersion() == data.version()) {
0108             info.plugin = nullptr;
0109             mPluginList.push_back(info);
0110         } else {
0111             qCWarning(MESSAGEVIEWER_LOG) << "Plugin name :" << data.name() << " doesn't have correct plugin version. Please update it";
0112         }
0113     }
0114     QList<ViewerPluginInfo>::iterator end(mPluginList.end());
0115     for (QList<ViewerPluginInfo>::iterator it = mPluginList.begin(); it != end; ++it) {
0116         loadPlugin(&(*it));
0117     }
0118     return true;
0119 }
0120 
0121 void ViewerPluginManagerPrivate::loadPlugin(ViewerPluginInfo *item)
0122 {
0123     if (auto plugin = KPluginFactory::instantiatePlugin<MessageViewer::ViewerPlugin>(item->data, q, QVariantList() << item->metaDataFileName).plugin) {
0124         item->plugin = plugin;
0125         item->plugin->setIsEnabled(item->isEnabled);
0126         item->pluginData.mHasConfigureDialog = item->plugin->hasConfigureDialog();
0127         mPluginDataList.append(item->pluginData);
0128     }
0129 }
0130 
0131 QList<ViewerPlugin *> ViewerPluginManagerPrivate::pluginsList() const
0132 {
0133     QList<MessageViewer::ViewerPlugin *> lst;
0134     QList<ViewerPluginInfo>::ConstIterator end(mPluginList.constEnd());
0135     for (QList<ViewerPluginInfo>::ConstIterator it = mPluginList.constBegin(); it != end; ++it) {
0136         if (auto plugin = (*it).plugin) {
0137             lst << plugin;
0138         }
0139     }
0140     return lst;
0141 }
0142 
0143 QList<PimCommon::PluginUtilData> ViewerPluginManagerPrivate::pluginDataList() const
0144 {
0145     return mPluginDataList;
0146 }
0147 
0148 ViewerPlugin *ViewerPluginManagerPrivate::pluginFromIdentifier(const QString &id)
0149 {
0150     QList<ViewerPluginInfo>::ConstIterator end(mPluginList.constEnd());
0151     for (QList<ViewerPluginInfo>::ConstIterator it = mPluginList.constBegin(); it != end; ++it) {
0152         if ((*it).pluginData.mIdentifier == id) {
0153             return (*it).plugin;
0154         }
0155     }
0156     return {};
0157 }
0158 
0159 ViewerPluginManager::ViewerPluginManager(QObject *parent)
0160     : QObject(parent)
0161     , d(new MessageViewer::ViewerPluginManagerPrivate(this))
0162 {
0163 }
0164 
0165 MessageViewer::ViewerPluginManager::~ViewerPluginManager() = default;
0166 
0167 bool ViewerPluginManager::initializePluginList()
0168 {
0169     return d->initializePluginList();
0170 }
0171 
0172 ViewerPluginManager *ViewerPluginManager::self()
0173 {
0174     static ViewerPluginManager s_self;
0175     return &s_self;
0176 }
0177 
0178 QList<MessageViewer::ViewerPlugin *> ViewerPluginManager::pluginsList() const
0179 {
0180     return d->pluginsList();
0181 }
0182 
0183 void ViewerPluginManager::setPluginDirectory(const QString &directory)
0184 {
0185     d->pluginDirectory = directory;
0186 }
0187 
0188 QString ViewerPluginManager::pluginDirectory() const
0189 {
0190     return d->pluginDirectory;
0191 }
0192 
0193 QList<PimCommon::PluginUtilData> ViewerPluginManager::pluginsDataList() const
0194 {
0195     return d->pluginDataList();
0196 }
0197 
0198 QString ViewerPluginManager::configGroupName() const
0199 {
0200     return d->configGroupName();
0201 }
0202 
0203 QString ViewerPluginManager::configPrefixSettingKey() const
0204 {
0205     return d->configPrefixSettingKey();
0206 }
0207 
0208 MessageViewer::ViewerPlugin *ViewerPluginManager::pluginFromIdentifier(const QString &id)
0209 {
0210     return d->pluginFromIdentifier(id);
0211 }
0212 
0213 void ViewerPluginManager::setPluginName(const QString &pluginName)
0214 {
0215     d->pluginName = pluginName;
0216 }
0217 
0218 QString ViewerPluginManager::pluginName() const
0219 {
0220     return d->pluginName;
0221 }
0222 
0223 #include "moc_viewerpluginmanager.cpp"