File indexing completed on 2025-01-05 04:58:22

0001 /*
0002   SPDX-FileCopyrightText: 2015-2024 Laurent Montel <montel@kde.org>
0003 
0004   SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "plugininterface.h"
0008 
0009 #include "pimcommonakonadi_debug.h"
0010 #include <PimCommon/GenericPluginManager>
0011 
0012 #include <KActionCollection>
0013 #include <KXMLGUIClient>
0014 #include <QAction>
0015 
0016 #include <PimCommon/GenericPlugin>
0017 
0018 using namespace PimCommon;
0019 
0020 class PimCommon::PluginInterfacePrivate
0021 {
0022 public:
0023     PluginInterfacePrivate() = default;
0024 
0025     QString mPluginName;
0026     QString mPluginDirectory;
0027     QWidget *mParentWidget = nullptr;
0028     KActionCollection *mActionCollection = nullptr;
0029     QList<PimCommon::GenericPluginInterface *> mListGenericInterface;
0030     GenericPluginManager *mGenericPluginManager = nullptr;
0031 };
0032 
0033 PluginInterface::PluginInterface(QObject *parent)
0034     : QObject(parent)
0035     , d(new PimCommon::PluginInterfacePrivate)
0036 {
0037     d->mGenericPluginManager = new GenericPluginManager(this);
0038 }
0039 
0040 PluginInterface::~PluginInterface() = default;
0041 
0042 void PimCommon::PluginInterface::setActionCollection(KActionCollection *ac)
0043 {
0044     d->mActionCollection = ac;
0045 }
0046 
0047 void PluginInterface::initializePlugins()
0048 {
0049     d->mGenericPluginManager->setPluginName(d->mPluginName);
0050     d->mGenericPluginManager->setPluginDirectory(d->mPluginDirectory);
0051     if (!d->mGenericPluginManager->initializePlugins()) {
0052         qCDebug(PIMCOMMONAKONADI_LOG) << " Impossible to initialize plugins";
0053     }
0054 }
0055 
0056 void PluginInterface::setPluginName(const QString &name)
0057 {
0058     d->mPluginName = name;
0059 }
0060 
0061 void PluginInterface::setPluginDirectory(const QString &name)
0062 {
0063     d->mPluginDirectory = name;
0064 }
0065 
0066 void PluginInterface::createPluginInterface()
0067 {
0068     if (!d->mActionCollection) {
0069         qCWarning(PIMCOMMONAKONADI_LOG) << "Missing action collection";
0070         return;
0071     }
0072     const auto pluginsList = d->mGenericPluginManager->pluginsList();
0073     for (PimCommon::GenericPlugin *plugin : pluginsList) {
0074         if (plugin->isEnabled()) {
0075             auto interface = static_cast<PimCommon::GenericPluginInterface *>(plugin->createInterface(this));
0076             interface->setParentWidget(d->mParentWidget);
0077             // Add parent before creating action
0078             interface->createAction(d->mActionCollection);
0079             interface->setPlugin(plugin);
0080             connect(interface, &PimCommon::GenericPluginInterface::emitPluginActivated, this, &PluginInterface::slotPluginActivated);
0081             d->mListGenericInterface.append(interface);
0082         }
0083     }
0084 }
0085 
0086 bool PluginInterface::initializeInterfaceRequires(PimCommon::AbstractGenericPluginInterface *interface)
0087 {
0088     Q_UNUSED(interface)
0089     return true;
0090 }
0091 
0092 QString PluginInterface::actionXmlExtension(ActionType::Type type)
0093 {
0094     switch (type) {
0095     case PimCommon::ActionType::Tools:
0096         return QStringLiteral("_plugins_tools");
0097     case PimCommon::ActionType::Edit:
0098         return QStringLiteral("_plugins_edit");
0099     case PimCommon::ActionType::File:
0100         return QStringLiteral("_plugins_file");
0101     case PimCommon::ActionType::Action:
0102         return QStringLiteral("_plugins_actions");
0103     case PimCommon::ActionType::PopupMenu:
0104         return QStringLiteral("_popupmenu_actions");
0105     case PimCommon::ActionType::ToolBar:
0106         return QStringLiteral("_toolbar_actions");
0107     case PimCommon::ActionType::Message:
0108         return QStringLiteral("_plugins_message");
0109     case PimCommon::ActionType::Folder:
0110         return QStringLiteral("_plugins_folder");
0111     }
0112     return {};
0113 }
0114 
0115 void PluginInterface::slotPluginActivated(PimCommon::AbstractGenericPluginInterface *interface)
0116 {
0117     if (interface) {
0118         if (initializeInterfaceRequires(interface)) {
0119             interface->exec();
0120         }
0121     }
0122 }
0123 
0124 void PluginInterface::setParentWidget(QWidget *widget)
0125 {
0126     d->mParentWidget = widget;
0127 }
0128 
0129 void PluginInterface::clearPluginActions(const QString &prefix, KXMLGUIClient *guiClient)
0130 {
0131     if (guiClient->factory()) {
0132         QHashIterator<PimCommon::ActionType::Type, QList<QAction *>> localActionsType(actionsType());
0133         while (localActionsType.hasNext()) {
0134             localActionsType.next();
0135             QList<QAction *> lst = localActionsType.value();
0136             if (!lst.isEmpty()) {
0137                 const QString actionlistname = prefix + PimCommon::PluginInterface::actionXmlExtension(localActionsType.key());
0138                 guiClient->unplugActionList(actionlistname);
0139             }
0140         }
0141     }
0142 }
0143 
0144 void PluginInterface::initializePluginActions(const QString &prefix, KXMLGUIClient *guiClient)
0145 {
0146     if (guiClient->factory()) {
0147         QHashIterator<PimCommon::ActionType::Type, QList<QAction *>> localActionsType(actionsType());
0148         while (localActionsType.hasNext()) {
0149             localActionsType.next();
0150             QList<QAction *> lst = localActionsType.value();
0151             if (!lst.isEmpty()) {
0152                 const QString actionlistname = prefix + PimCommon::PluginInterface::actionXmlExtension(localActionsType.key());
0153                 guiClient->unplugActionList(actionlistname);
0154                 guiClient->plugActionList(actionlistname, lst);
0155             }
0156         }
0157     }
0158 }
0159 
0160 void PluginInterface::updateActions(int numberOfSelectedItems, int numberOfSelectedCollections)
0161 {
0162     for (PimCommon::GenericPluginInterface *interface : std::as_const(d->mListGenericInterface)) {
0163         interface->updateActions(numberOfSelectedItems, numberOfSelectedCollections);
0164     }
0165 }
0166 
0167 QHash<PimCommon::ActionType::Type, QList<QAction *>> PluginInterface::actionsType()
0168 {
0169     QHash<PimCommon::ActionType::Type, QList<QAction *>> listType;
0170     for (PimCommon::GenericPluginInterface *interface : std::as_const(d->mListGenericInterface)) {
0171         const auto actionTypes = interface->actionTypes();
0172         for (const PimCommon::ActionType &actionType : actionTypes) {
0173             PimCommon::ActionType::Type type = actionType.type();
0174             QList<QAction *> lst = listType.value(type);
0175             if (!lst.isEmpty()) {
0176                 auto act = new QAction(this);
0177                 act->setSeparator(true);
0178                 lst << act << actionType.action();
0179                 listType.insert(type, lst);
0180             } else {
0181                 listType.insert(type, QList<QAction *>() << actionType.action());
0182             }
0183             if (interface->plugin()->hasPopupMenuSupport()) {
0184                 type = PimCommon::ActionType::PopupMenu;
0185                 lst = listType.value(type);
0186                 if (!lst.isEmpty()) {
0187                     auto act = new QAction(this);
0188                     act->setSeparator(true);
0189                     lst << act << actionType.action();
0190                     listType.insert(type, lst);
0191                 } else {
0192                     listType.insert(type, QList<QAction *>() << actionType.action());
0193                 }
0194             }
0195             if (interface->plugin()->hasToolBarSupport()) {
0196                 type = PimCommon::ActionType::ToolBar;
0197                 lst = listType.value(type);
0198                 if (!lst.isEmpty()) {
0199                     auto act = new QAction(this);
0200                     act->setSeparator(true);
0201                     lst << act << actionType.action();
0202                     listType.insert(type, lst);
0203                 } else {
0204                     listType.insert(type, QList<QAction *>() << actionType.action());
0205                 }
0206             }
0207         }
0208     }
0209 
0210     return listType;
0211 }
0212 
0213 QList<PimCommon::PluginUtilData> PluginInterface::pluginsDataList() const
0214 {
0215     return d->mGenericPluginManager->pluginsDataList();
0216 }
0217 
0218 QString PluginInterface::configGroupName() const
0219 {
0220     return d->mGenericPluginManager->configGroupName();
0221 }
0222 
0223 QString PluginInterface::configPrefixSettingKey() const
0224 {
0225     return d->mGenericPluginManager->configPrefixSettingKey();
0226 }
0227 
0228 PimCommon::GenericPlugin *PluginInterface::pluginFromIdentifier(const QString &id)
0229 {
0230     return d->mGenericPluginManager->pluginFromIdentifier(id);
0231 }
0232 
0233 #include "moc_plugininterface.cpp"