File indexing completed on 2024-04-28 16:29:36

0001 /*
0002     SPDX-FileCopyrightText: 2017 Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "pluginloader.h"
0007 
0008 // ----------------------------------------------------------------------------
0009 // QT Includes
0010 
0011 #include <QMap>
0012 #include <QDebug>
0013 
0014 // ----------------------------------------------------------------------------
0015 // KDE Includes
0016 
0017 #include <KPluginLoader>
0018 #include <KPluginFactory>
0019 #include <KPluginInfo>
0020 #include <KPluginMetaData>
0021 #include <KXMLGUIFactory>
0022 #include <KSharedConfig>
0023 
0024 // ----------------------------------------------------------------------------
0025 // Project Includes
0026 
0027 #include "kmymoneyplugin.h"
0028 #include "onlinepluginextended.h"
0029 
0030 namespace KMyMoneyPlugin
0031 {
0032 Category pluginCategory(const KPluginMetaData& pluginInfo)
0033 {
0034     if (!pluginInfo.serviceTypes().contains(QStringLiteral("KMyMoney/Plugin"))) {
0035         auto jsonKMyMoneyData = pluginInfo.rawData()[QLatin1String("KMyMoney")].toObject();
0036         if (!jsonKMyMoneyData[QLatin1String("OnlineTask")].isNull())
0037             return OnlineBankOperations;
0038         else if (!jsonKMyMoneyData[QLatin1String("PayeeIdentifier")].isNull())
0039             return PayeeIdentifier;
0040     }
0041     return StandardPlugin;
0042 }
0043 
0044 bool isPluginEnabled(const KPluginMetaData& pluginData, const KConfigGroup& pluginSection)
0045 {
0046     return pluginSection.readEntry(QString::fromLatin1("%1Enabled").    // we search here for e.g. "csvimporterEnabled = true"
0047                                    arg(pluginData.pluginId()),
0048                                    pluginData.isEnabledByDefault());    // if not found, then get default from plugin's json file
0049 }
0050 
0051 QMap<QString, KPluginMetaData> listPlugins(bool onlyEnabled)
0052 {
0053     QMap<QString, KPluginMetaData> plugins;
0054     const auto pluginDatas = KPluginLoader::findPlugins(QStringLiteral("kmymoney"));          // that means search for plugins in "/lib64/plugins/kmymoney/"
0055     const auto pluginSection(KSharedConfig::openConfig()->group(QStringLiteral("Plugins")));  // section of config where plugin on/off were saved
0056 
0057     for (const KPluginMetaData& pluginData : pluginDatas) {
0058         if (pluginData.serviceTypes().contains(QStringLiteral("KMyMoney/Plugin"))) {
0059             if (!onlyEnabled || isPluginEnabled(pluginData, pluginSection)) {
0060                 // only use the first one found. Otherwise, always the last one
0061                 // wins (usually the installed system version) and the QT_PLUGIN_PATH
0062                 // env variable nor the current directory have an effect for KMyMoney
0063                 if (!plugins.contains(pluginData.pluginId()))
0064                     plugins.insert(pluginData.pluginId(), pluginData);
0065             }
0066         }
0067     }
0068     return plugins;
0069 }
0070 
0071 void pluginHandling(Action action, Container& ctnPlugins, QObject* parent, KXMLGUIFactory* guiFactory)
0072 {
0073 
0074     if (action == Action::Load ||
0075             action == Action::Reorganize) {
0076         KPluginLoader::forEachPlugin(QStringLiteral("kmymoney"), [&](const QString &pluginPath) {
0077             KPluginMetaData metadata(pluginPath);
0078             qDebug() << "Located plugin" << pluginPath << "Validity" << metadata.isValid();
0079         });
0080     }
0081 
0082     QMap<QString, KPluginMetaData> referencePluginDatas;
0083     if (action == Action::Load ||
0084             action == Action::Reorganize)
0085         referencePluginDatas = listPlugins(true);
0086 
0087     if (action == Action::Unload ||
0088             action == Action::Reorganize) {
0089         auto& plugins = ctnPlugins.standard;
0090         auto& refPlugins = referencePluginDatas;
0091         for (auto it = plugins.begin(); it != plugins.end();) {
0092             if (!refPlugins.contains(it.key())) {
0093 
0094                 ctnPlugins.online.remove(it.key());
0095                 ctnPlugins.extended.remove(it.key());
0096                 ctnPlugins.importer.remove(it.key());
0097                 ctnPlugins.storage.remove(it.key());
0098                 ctnPlugins.data.remove(it.key());
0099 
0100                 guiFactory->removeClient(it.value());
0101                 it.value()->unplug();
0102                 delete it.value();
0103                 it = plugins.erase(it);
0104                 continue;
0105 
0106             }
0107             ++it;
0108         }
0109     }
0110 
0111     if (action == Action::Load ||
0112             action == Action::Reorganize) {
0113 
0114         auto& refPlugins = referencePluginDatas;
0115         for (auto it = refPlugins.cbegin(); it != refPlugins.cend(); ++it) {
0116             if (!ctnPlugins.standard.contains(it.key())) {
0117                 qDebug() << "Loading" << (*it).fileName();
0118                 KPluginLoader loader((*it).fileName());
0119                 auto factory = loader.factory();
0120                 if (!factory) {
0121                     qWarning("Could not load plugin '%s', error: %s", qPrintable((*it).fileName()), qPrintable(loader.errorString()));
0122                     loader.unload();
0123                     continue;
0124                 }
0125 
0126                 Plugin* plugin = factory->create<Plugin>(parent);
0127                 if (!plugin) {
0128                     qWarning("This is not KMyMoney plugin: '%s'", qPrintable((*it).fileName()));
0129                     loader.unload();
0130                     continue;
0131                 }
0132 
0133                 ctnPlugins.standard.insert((*it).pluginId(), plugin);
0134                 plugin->plug();
0135                 guiFactory->addClient(plugin);
0136 
0137                 auto IOnline = qobject_cast<OnlinePlugin *>(plugin);
0138                 if (IOnline)
0139                     ctnPlugins.online.insert((*it).pluginId(), IOnline);
0140 
0141                 auto IExtended = qobject_cast<OnlinePluginExtended *>(plugin);
0142                 if (IExtended )
0143                     ctnPlugins.extended.insert((*it).pluginId(), IExtended );
0144 
0145                 auto IImporter = qobject_cast<ImporterPlugin *>(plugin);
0146                 if (IImporter)
0147                     ctnPlugins.importer.insert((*it).pluginId(), IImporter);
0148 
0149                 auto IStorage = qobject_cast<StoragePlugin *>(plugin);
0150                 if (IStorage)
0151                     ctnPlugins.storage.insert((*it).pluginId(), IStorage);
0152 
0153                 auto IData = qobject_cast<DataPlugin *>(plugin);
0154                 if (IData)
0155                     ctnPlugins.data.insert((*it).pluginId(), IData);
0156 
0157             }
0158         }
0159 
0160     }
0161 }
0162 }