File indexing completed on 2024-05-05 04:33:16
0001 /* 0002 SPDX-FileCopyrightText: 2004-2018 Gilles Caulier <caulier dot gilles at gmail dot com> 0003 SPDX-FileCopyrightText: 2004-2005 Renchi Raju <renchi dot raju at gmail dot com> 0004 SPDX-FileCopyrightText: 2009 Andi Clemens <andi dot clemens at googlemail dot com> 0005 SPDX-FileCopyrightText: 2009 Aleix Pol Gonzalez <aleixpol at kde dot org> 0006 SPDX-FileCopyrightText: 2012 Victor Dodon <dodonvictor at gmail dot com> 0007 0008 SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 0011 #ifndef KIPI_PLUGINLOADER_H 0012 #define KIPI_PLUGINLOADER_H 0013 0014 // Std includes 0015 0016 #include <memory> 0017 0018 // Qt includes 0019 0020 #include <QList> 0021 0022 // KF includes 0023 0024 #include <KService> 0025 #include <KXmlGuiWindow> 0026 0027 // Local includes 0028 0029 #include "libkipi_export.h" 0030 0031 namespace KIPI 0032 { 0033 0034 class Plugin; 0035 class Interface; 0036 class ConfigWidget; 0037 0038 /** 0039 \author Gilles Caulier 0040 \par Maintainer: Victor Dodon 0041 \class PluginLoader pluginloader.h <KIPI/PluginLoader> 0042 This is the class that will help host applications to load plugins. 0043 0044 This is a singleton and host applications should create the PluginLoader 0045 just once, and then use the instance() static method to access it. 0046 0047 The host application must create an instance of the plugin loader, and 0048 call the method loadPlugins() to get the plugins loaded. To ensure that 0049 plugins are correctly removed from menus and toolbars when loaded and 0050 unloaded after constructions, the application must connect to either the 0051 signals plug() / unplug() or the signal replug(). These signals are 0052 emitted when a plugin is to be inserted into the menus. 0053 0054 If your application is using KDE XMLGUI, the easiest(nicest) way to get the 0055 plugins inserted into the menus is by adding an item in your application XML 0056 ui.rc file looking like this: 0057 0058 \code 0059 0060 <!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> 0061 <gui version="1" name="MyKipiApplication" > 0062 0063 <MenuBar> 0064 0065 <Menu name="Image" ><text>&Image</text> 0066 <DefineGroup name="kipi_image_group" append="kipi_image_group" /> 0067 </Menu> 0068 0069 <Menu name="Tools"><text>&Tools</text> 0070 <DefineGroup name="kipi_album_group" append="kipi_album_group" /> 0071 <Separator/> 0072 <DefineGroup name="kipi_tool_group" append="kipi_tool_group" /> 0073 <Separator/> 0074 <DefineGroup name="kipi_batch_group" append="kipi_batch_group" /> 0075 </Menu> 0076 0077 <Merge/> 0078 0079 </MenuBar> 0080 0081 <ToolBar name="mainToolBar"> 0082 <text>Main Toolbar</text> 0083 </Toolbar> 0084 0085 <ActionProperties/> 0086 0087 </gui> 0088 0089 \endcode 0090 0091 Then loading plugins into menus could be done with code similar to this implementation: 0092 0093 \code 0094 0095 class MyKipiApplication : public KXmlGuiWindow 0096 { 0097 Q_OBJECT 0098 0099 public: 0100 0101 MyKipiApplication(); 0102 0103 private Q_SLOTS: 0104 0105 void slotKipiPluginPlug(); 0106 0107 private: 0108 0109 KIPI::Interface* m_iface; 0110 KIPI::PluginLoader* m_loader; 0111 }; 0112 0113 // ------------------------------------------------------------------------------- 0114 0115 MyKipiApplication::MyKipiApplication() : KXmlGuiWindow(0) 0116 { 0117 m_iface = new KIPI::Interface(this, "MyKipiApplication_KIPI_interface"); 0118 m_loader = new KIPI::PluginLoader(this); 0119 m_loader->setInterface(m_iface); 0120 m_loader->init(); 0121 0122 connect(m_loader, SIGNAL(replug()), 0123 this, SLOT(slotKipiPluginPlug())); 0124 0125 m_loader->loadPlugins(); 0126 // Do not delete m_loader as long as any of the plugins are in use 0127 } 0128 0129 void MyKipiApplication::slotKipiPluginPlug() 0130 { 0131 QList<QAction*> kipiImageActions, kipiExportActions, kipiToolsActions; 0132 PluginLoader::PluginList list = m_loader->pluginList(); 0133 0134 // We need to remove loaded plugins from the gui factory 0135 for (PluginLoader::PluginList::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it ) 0136 { 0137 Plugin* plugin = (*it)->plugin(); 0138 if ( !plugin || !(*it)->shouldLoad() ) 0139 continue; 0140 0141 guiFactory()->removeClient(plugin); 0142 } 0143 0144 for (PluginLoader::PluginList::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it ) 0145 { 0146 Plugin* plugin = (*it)->plugin(); 0147 if ( !plugin || !(*it)->shouldLoad() ) 0148 continue; 0149 0150 plugin->setup(this); 0151 } 0152 0153 // We add plugins to the factory 0154 for (PluginLoader::PluginList::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it ) 0155 { 0156 Plugin* plugin = (*it)->plugin(); 0157 if ( !plugin || !(*it)->shouldLoad() ) 0158 continue; 0159 0160 guiFactory()->addClient(plugin); 0161 } 0162 } 0163 0164 \endcode 0165 0166 For a implementation sample used to manage Kipi-plugins in host application, 0167 look the code of the kxmlkipicmd test application in the "test" folder from libkipi. 0168 0169 To configure which plugins should be loaded, simply call 0170 PluginLoader::configWidget(), and insert the widget into your normal 0171 configuration dialog. 0172 */ 0173 class LIBKIPI_EXPORT PluginLoader : public QObject 0174 { 0175 Q_OBJECT 0176 0177 public: 0178 0179 /** 0180 * \class Info pluginloader.h <KIPI/PluginLoader> 0181 * 0182 * Info about a plugin. 0183 */ 0184 class LIBKIPI_EXPORT Info 0185 { 0186 0187 public: 0188 0189 Info(KXmlGuiWindow* const parent, const KService::Ptr& service, bool shouldLoad); 0190 ~Info(); 0191 0192 QString name() const; 0193 QString uname() const; 0194 QString author() const; 0195 QString comment() const; 0196 QIcon icon() const; 0197 QString library() const; 0198 KService::Ptr service() const; 0199 Plugin* plugin() const; 0200 QStringList pluginCategories() const; 0201 0202 void reload(); 0203 bool shouldLoad() const; 0204 void setShouldLoad(bool); 0205 0206 private: 0207 0208 class Private; 0209 std::unique_ptr<Private> const d; 0210 }; 0211 0212 public: 0213 0214 typedef QList<Info*> PluginList; 0215 0216 public: 0217 0218 /** 0219 * Use this constructor if your application does not use KDE XML GUI technology. 0220 * 0221 * Note that the PluginLoader is intended to be a singleton, so you 0222 * should create only one and then use instance(). 0223 */ 0224 PluginLoader(); 0225 0226 /** 0227 * Standard constructor. You must pass the instance of KDE XML GUI application as argument. 0228 * 0229 * Note that the PluginLoader is intended to be a singleton, so you 0230 * should create only one and then use instance(). 0231 * 0232 * @param parent the pointer to the KXmlGuiWindow of your application 0233 */ 0234 PluginLoader(KXmlGuiWindow* const parent); 0235 0236 /** 0237 * Standard destructor 0238 * 0239 * Since PluginLoader is a singleton, you should not call this 0240 * in client code. 0241 */ 0242 ~PluginLoader() override; 0243 0244 /** 0245 * Set KIPI interface instance from host application. 0246 */ 0247 void setInterface(Interface* const interface); 0248 0249 /** 0250 * Return KIPI host interface instance. 0251 */ 0252 Interface* interface() const; 0253 0254 /** 0255 * Set Plugins ignore list, with name of obsoletes plugins to not load through init(). 0256 */ 0257 void setIgnoredPluginsList(const QStringList& ignores); 0258 0259 /** 0260 * Set disabled plugin actions that will not be plugged into the gui, 0261 */ 0262 void setDisabledPluginActions(const QStringList& disabledActions); 0263 0264 /** 0265 * Return the list of disabled plugin actions 0266 */ 0267 QStringList disabledPluginActions() const; 0268 0269 /** 0270 * Init plugin loader. Call this method to parse relevant plugins installed on your system. 0271 * Before to call this method, you must setup KIPI interface instance. 0272 * Optionally, setup list of plugins to ignore, the constraint list, and 0273 * the disabled plugin actions 0274 */ 0275 void init(); 0276 0277 /** 0278 * Call this method to load relevant plugins installed on your system to your KIPI host application 0279 * @note Plugins can be loaded through Info item. 0280 */ 0281 void loadPlugins(); 0282 0283 /** 0284 * Returns the list of loaded plugins 0285 */ 0286 const PluginList& pluginList(); 0287 0288 /** 0289 * Return the kipi-plugins version installed on your computer if it's found through kipiplugins.desktop file. 0290 */ 0291 QString kipiPluginsVersion() const; 0292 0293 /** 0294 * Return the config widget with list of plugins to manage. 0295 */ 0296 ConfigWidget* configWidget(QWidget* const parent) const; 0297 0298 /** 0299 * Returns plugin loader instance. 0300 */ 0301 static PluginLoader* instance(); 0302 0303 Q_SIGNALS: 0304 0305 void plug(KIPI::PluginLoader::Info*); 0306 void unplug(KIPI::PluginLoader::Info*); 0307 0308 /// @note Plugin can be plugged through Info item. 0309 void replug(); 0310 0311 private: 0312 0313 class Private; 0314 std::unique_ptr<Private> const d; 0315 0316 private: 0317 0318 friend class ConfigWidget; 0319 }; 0320 0321 } // namespace KIPI 0322 0323 #endif /* KIPI_PLUGINLOADER_H */