File indexing completed on 2024-04-28 05:06:07

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