File indexing completed on 2024-04-28 04:37:21

0001 /*
0002     SPDX-FileCopyrightText: 2007 Andreas Pakulat <apaku@gmx.de>
0003     SPDX-FileCopyrightText: 2004, 2007 Alexander Dymo <adymo@kdevelop.org>
0004     SPDX-FileCopyrightText: 2006 Matt Rogers <mattr@kde.org
0005 
0006     Based on code from Kopete
0007     SPDX-FileCopyrightText: 2002-2003 Martijn Klingens <klingens@kde.org>
0008 
0009     SPDX-License-Identifier: LGPL-2.0-or-later
0010 */
0011 
0012 #ifndef KDEVPLATFORM_PLUGINCONTROLLER_H
0013 #define KDEVPLATFORM_PLUGINCONTROLLER_H
0014 
0015 #include <interfaces/iplugincontroller.h>
0016 
0017 #include "shellexport.h"
0018 
0019 
0020 namespace KDevelop
0021 {
0022 class Core;
0023 class CorePrivate;
0024 class IPlugin;
0025 class PluginControllerPrivate;
0026 /**
0027  * The KDevelop plugin controller.
0028  * The Plugin controller is responsible for querying, loading and unloading
0029  * available plugins.
0030  */
0031 class KDEVPLATFORMSHELL_EXPORT PluginController: public IPluginController
0032 {
0033     Q_OBJECT
0034 friend class Core;
0035 friend class CorePrivate;
0036 
0037 public:
0038 
0039     explicit PluginController(Core *core);
0040 
0041     ~PluginController() override;
0042 
0043     /**
0044      * Get the plugin instance based on the ID. The ID should be whatever is
0045      * in X-KDE-PluginInfo-Name
0046      */
0047     IPlugin* plugin(const QString& pluginId) const;
0048 
0049     /**
0050      * Get the plugin info for a loaded plugin
0051      */
0052     KPluginMetaData pluginInfo( const IPlugin* ) const override;
0053 
0054     /**
0055      * Find the KPluginMetaData structure for the given @p pluginId.
0056      */
0057     KPluginMetaData infoForPluginId(const QString &pluginId) const override;
0058 
0059     /**
0060      * Get a list of currently loaded plugins
0061      */
0062     QList<IPlugin*> loadedPlugins() const override;
0063 
0064     /**
0065      * Returns a uniquely specified plugin. If it isn't already loaded, it will be.
0066      * @param pluginName the name of the plugin, as given in the X-KDE-PluginInfo-Name property
0067      * @returns a pointer to the plugin instance or 0
0068      */
0069     IPlugin * loadPlugin( const QString & pluginName ) override;
0070 
0071     /**
0072      * @brief Unloads the plugin specified by @p plugin
0073      *
0074      * @param plugin The name of the plugin as specified by the
0075      * X-KDE-PluginInfo-Name key of the .desktop file for the plugin
0076      */
0077     bool unloadPlugin( const QString & plugin ) override;
0078 
0079     enum PluginDeletion {
0080         Now,
0081         Later
0082     };
0083 
0084     /**
0085      * retrieve all plugin infos
0086      */
0087     QVector<KPluginMetaData> allPluginInfos() const;
0088 
0089     /**
0090      * loads not-yet-loaded plugins and unloads plugins
0091      * depending on the configuration in the session\
0092      */
0093     void updateLoadedPlugins();
0094 
0095 
0096     /**
0097      * Queries for the plugin which supports given extension interface.
0098      *
0099      * All already loaded plugins will be queried and the first one to support the extension interface
0100      * will be returned. Any plugin can be an extension, only "ServiceTypes=..." entry is
0101      * required in .desktop file for that plugin.
0102      *
0103      * @param extension The extension interface
0104      * @param pluginName The name of the plugin to load if multiple plugins for the extension exist, corresponds to the X-KDE-PluginInfo-Name
0105      * @return A KDevelop extension plugin for given service type or 0 if no plugin supports it
0106      */
0107     IPlugin *pluginForExtension(const QString &extension, const QString &pluginName = {}, const QVariantMap& constraints = QVariantMap()) override;
0108 
0109     QList<IPlugin*> allPluginsForExtension(const QString &extension, const QVariantMap& constraints = QVariantMap()) override;
0110 
0111     QStringList allPluginNames() const;
0112 
0113     QVector<KPluginMetaData> queryExtensionPlugins(const QString& extension, const QVariantMap& constraints = QVariantMap()) const override;
0114 
0115     QList<ContextMenuExtension> queryPluginsForContextMenuExtensions(KDevelop::Context* context, QWidget* parent) const override;
0116 
0117     QStringList projectPlugins() const;
0118 
0119     void loadProjectPlugins();
0120     void unloadProjectPlugins();
0121 
0122     void resetToDefaults();
0123 
0124 private:
0125     /**
0126      * Directly unload the given \a plugin, either deleting it now or \a deletion.
0127      *
0128      * \param plugin plugin to unload
0129      * \param deletion if true, delete the plugin later, if false, delete it now.
0130      */
0131     bool unloadPlugin(IPlugin* plugin, PluginDeletion deletion);
0132 
0133 
0134     /**
0135      * @internal
0136      *
0137      * The internal method for loading plugins.
0138      * Called by @ref loadPlugin directly or through the queue for async plugin
0139      * loading.
0140      */
0141     IPlugin* loadPluginInternal( const QString &pluginId );
0142 
0143     /**
0144      * Check whether the plugin identified by @p info has unresolved dependencies.
0145      *
0146      * Assume a plugin depends on the interfaces Foo and Bar. Then, all available enabled
0147      * plugins are queried to check whether any fulfills the interfaces. If any of the
0148      * interfaces is not found, then it is inserted into @p missing and this method returns
0149      * true. Otherwise, @p missing is empty and this method returns true, indicating that all
0150      * dependencies can be fulfilled.
0151      *
0152      * @return true when there are unresolved dependencies, false otherwise.
0153      */
0154     bool hasUnresolvedDependencies( const KPluginMetaData& info, QStringList& missing ) const;
0155 
0156     bool loadDependencies(const KPluginMetaData&, QString& failedPlugin);
0157     void loadOptionalDependencies(const KPluginMetaData& info);
0158 
0159     void cleanup();
0160     virtual void initialize();
0161 
0162 private:
0163     const QScopedPointer<class PluginControllerPrivate> d_ptr;
0164     Q_DECLARE_PRIVATE(PluginController)
0165 };
0166 
0167 }
0168 #endif
0169 
0170