File indexing completed on 2024-04-28 04:36:30
0001 /* 0002 SPDX-FileCopyrightText: 2004, 2007 Alexander Dymo <adymo@kdevelop.org> 0003 SPDX-FileCopyrightText: 2006 Matt Rogers <mattr@kde.org> 0004 SPDX-FileCopyrightText: 2007 Andreas Pakulat <apaku@gmx.de> 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_IPLUGINCONTROLLER_H 0013 #define KDEVPLATFORM_IPLUGINCONTROLLER_H 0014 0015 #include <QObject> 0016 #include <QList> 0017 #include <QVector> 0018 #include <QVariant> 0019 0020 #include <KPluginMetaData> 0021 0022 #include "iplugin.h" 0023 #include "interfacesexport.h" 0024 0025 class QExtensionManager; 0026 0027 namespace KDevelop 0028 { 0029 class ProfileEngine; 0030 0031 /** 0032 * The KDevelop plugin controller. 0033 * The Plugin controller is responsible for querying, loading and unloading 0034 * available plugins. 0035 * 0036 * Most of the time if you want to get at a plugin you should be using 0037 * extensionForPlugin with the extension interface name. If you need to get at 0038 * the actual \c IPlugin* pointer to connect signals/slots you should use 0039 * \c pluginForExtension() and then the IPlugin's extension member function to get 0040 * at the extension interface if necessary. 0041 * 0042 * If you have the need to load a specific plugin for a given extension both 0043 * functions have an optional second parameter that allows one to specify the 0044 * name of the plugin as declared in the \c .desktop file under the 0045 * \c X-KDE-PluginInfo-Name property. This should be used only very seldomly in 0046 * real code and is mostly meant for testing and for implementation in the 0047 * shell as it makes the code dependent on the plugin name which may change and 0048 * also the actual plugin implementation so users cannot exchange one plugin 0049 * with another also implementing the same interface. 0050 * 0051 */ 0052 class KDEVPLATFORMINTERFACES_EXPORT IPluginController : public QObject 0053 { 0054 0055 Q_OBJECT 0056 0057 public: 0058 /** 0059 * \brief Indicates the plugin type 0060 * This is used to determine how the plugin is loaded 0061 */ 0062 enum PluginType { 0063 Global = 0, ///< Indicates that the plugin is loaded at startup 0064 Project ///< Indicates that the plugin is loaded with the first opened project 0065 }; 0066 0067 explicit IPluginController( QObject* parent = nullptr ); 0068 0069 ~IPluginController() override; 0070 0071 /** 0072 * Get the plugin info for a loaded plugin 0073 */ 0074 virtual KPluginMetaData pluginInfo(const IPlugin*) const = 0; 0075 0076 /** 0077 * Find the KPluginMetaData structure for the given @p pluginId. 0078 */ 0079 virtual KPluginMetaData infoForPluginId(const QString &pluginId) const = 0; 0080 0081 /** 0082 * Get a list of currently loaded plugins 0083 */ 0084 virtual QList<IPlugin*> loadedPlugins() const = 0; 0085 0086 /** 0087 * @brief Unloads the plugin specified by @p plugin 0088 * 0089 * @param plugin The name of the plugin as specified by the 0090 * X-KDE-PluginInfo-Name key of the .desktop file for the plugin 0091 */ 0092 virtual bool unloadPlugin( const QString & plugin ) = 0; 0093 0094 /** 0095 * @brief Loads the plugin specified by @p pluginName 0096 * 0097 * @param pluginName the name of the plugin, as given in the X-KDE-PluginInfo-Name property 0098 * @returns a pointer to the plugin instance or 0 0099 */ 0100 virtual IPlugin* loadPlugin( const QString & pluginName ) = 0; 0101 0102 /** 0103 * Retrieve a plugin which supports the given extension interface. 0104 * 0105 * All already loaded plugins will be queried and the first one to support the extension interface 0106 * will be returned. Any plugin can be an extension, only the "ServiceTypes=..." entry is 0107 * required in .desktop file for that plugin. 0108 * 0109 * If no already-loaded plugin was found, we try to load a plugin for the given extension. 0110 * 0111 * If no plugin was found, a nullptr will be returned. 0112 * 0113 * @param extension The extension interface. Can be empty if you want to find a plugin by name or other constraint. 0114 * @param pluginName The name of the plugin to load if multiple plugins for the extension exist, corresponds to the X-KDE-PluginInfo-Name 0115 * @param constraints A map of constraints on other plugin info properties. 0116 * @return A KDevelop extension plugin for given service type or 0 if no plugin supports it 0117 */ 0118 virtual IPlugin *pluginForExtension(const QString &extension, const QString& pluginName = {}, const QVariantMap& constraints = QVariantMap()) = 0; 0119 0120 /** 0121 * Retrieve a list of plugins which supports the given extension interface. 0122 * All already loaded plugins will be queried and the first one to support the extension interface 0123 * will be returned. Any plugin can be an extension, only the "ServiceTypes=..." entry is 0124 * required in .desktop file for that plugin. 0125 * @param extension The extension interface 0126 * @param constraints A map of constraints on other plugin info properties. 0127 * @return A KDevelop extension plugin for given service type or 0 if no plugin supports it 0128 */ 0129 virtual QList<IPlugin*> allPluginsForExtension(const QString &extension, const QVariantMap& constraints = QVariantMap()) = 0; 0130 0131 /** 0132 * Retrieve the plugin which supports given extension interface and 0133 * returns a pointer to the extension interface. 0134 * 0135 * All already loaded plugins will be queried and the first one to support the extension interface 0136 * will be returned. Any plugin can be an extension, only "ServiceTypes=..." entry is 0137 * required in .desktop file for that plugin. 0138 * @param extension The extension interface 0139 * @param pluginName The name of the plugin to load if multiple plugins for the extension exist, corresponds to the X-KDE-PluginInfo-Name 0140 * @return Pointer to the extension interface or 0 if no plugin supports it 0141 */ 0142 template<class Extension> Extension* extensionForPlugin( const QString &extension = {}, const QString &pluginName = {}) 0143 { 0144 QString ext; 0145 if( extension.isEmpty() ) { 0146 ext = QString::fromUtf8(qobject_interface_iid<Extension*>()); 0147 } else { 0148 ext = extension; 0149 } 0150 IPlugin *plugin = pluginForExtension(ext, pluginName); 0151 if (plugin) { 0152 return plugin->extension<Extension>(); 0153 } 0154 return nullptr; 0155 } 0156 0157 /** 0158 * Query for plugin information on KDevelop plugins implementing the given extension. 0159 * 0160 * The service version is checked for automatically and the only serviceType 0161 * searched for is "KDevelop/Plugin" 0162 * 0163 * @param extension The extension that should be implemented by the plugin, i.e. listed in X-KDevelop-Interfaces. 0164 * @param constraints A map of constraints on other plugin info properties. 0165 * @return The list of plugin offers. 0166 */ 0167 virtual QVector<KPluginMetaData> queryExtensionPlugins(const QString &extension, const QVariantMap& constraints = QVariantMap()) const = 0; 0168 0169 virtual QList<ContextMenuExtension> queryPluginsForContextMenuExtensions(KDevelop::Context* context, QWidget* parent) const = 0; 0170 0171 Q_SIGNALS: 0172 void loadingPlugin( const QString& ); 0173 void pluginLoaded( KDevelop::IPlugin* ); 0174 void unloadingPlugin( KDevelop::IPlugin* ); 0175 /** 0176 * This signal is emitted whenever a plugin is unloaded. 0177 * @note: that you shouldn't use the pointer anymore 0178 * except for comparing it against against other pointers. The plugin instance can already have been completely 0179 * deleted when this signal is emitted. 0180 */ 0181 void pluginUnloaded( KDevelop::IPlugin* ); 0182 0183 private: 0184 friend class IPlugin; 0185 }; 0186 0187 } 0188 #endif 0189