File indexing completed on 2025-01-19 03:55:36
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2018-07-30 0007 * Description : manager to load external plugins at run-time 0008 * 0009 * SPDX-FileCopyrightText: 2018-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * 0011 * SPDX-License-Identifier: GPL-2.0-or-later 0012 * 0013 * ============================================================ */ 0014 0015 #include "dpluginloader_p.h" 0016 0017 // Qt includes 0018 0019 #include <QStringList> 0020 0021 // Local includes 0022 0023 #include "digikam_config.h" 0024 #include "digikam_debug.h" 0025 #include "dplugingeneric.h" 0026 #include "dplugineditor.h" 0027 #include "dplugindimg.h" 0028 #include "dpluginrawimport.h" 0029 0030 namespace Digikam 0031 { 0032 0033 class Q_DECL_HIDDEN DPluginLoaderCreator 0034 { 0035 public: 0036 0037 DPluginLoader object; 0038 }; 0039 0040 Q_GLOBAL_STATIC(DPluginLoaderCreator, creator) 0041 0042 // ----------------------------------------------------- 0043 0044 DPluginLoader::DPluginLoader() 0045 : QObject(), 0046 d (new Private) 0047 { 0048 } 0049 0050 DPluginLoader::~DPluginLoader() 0051 { 0052 delete d; 0053 } 0054 0055 DPluginLoader* DPluginLoader::instance() 0056 { 0057 return &creator->object; 0058 } 0059 0060 void DPluginLoader::init() 0061 { 0062 d->loadPlugins(); 0063 } 0064 0065 void DPluginLoader::cleanUp() 0066 { 0067 Q_FOREACH (DPlugin* const p, d->allPlugins) 0068 { 0069 p->cleanUp(); 0070 } 0071 0072 d->allPlugins.clear(); 0073 } 0074 0075 QString DPluginLoader::configGroupName() const 0076 { 0077 return QLatin1String("EnabledDPlugins"); 0078 } 0079 0080 QList<DPlugin*> DPluginLoader::allPlugins() const 0081 { 0082 return d->allPlugins; 0083 } 0084 0085 QList<DPluginAction*> DPluginLoader::pluginsActions(DPluginAction::ActionType type, QObject* const parent) const 0086 { 0087 QList<DPluginAction*> list; 0088 0089 Q_FOREACH (DPlugin* const p, d->allPlugins) 0090 { 0091 DPluginGeneric* const gene = dynamic_cast<DPluginGeneric*>(p); 0092 0093 if (gene) 0094 { 0095 Q_FOREACH (DPluginAction* const ac, gene->actions(parent)) 0096 { 0097 if (ac && (ac->actionType() == type)) 0098 { 0099 list << ac; 0100 } 0101 } 0102 } 0103 } 0104 0105 if (list.isEmpty()) 0106 { 0107 Q_FOREACH (DPlugin* const p, d->allPlugins) 0108 { 0109 DPluginEditor* const edit = dynamic_cast<DPluginEditor*>(p); 0110 0111 if (edit) 0112 { 0113 Q_FOREACH (DPluginAction* const ac, edit->actions(parent)) 0114 { 0115 if (ac && (ac->actionType() == type)) 0116 { 0117 list << ac; 0118 } 0119 } 0120 } 0121 } 0122 } 0123 0124 std::sort(list.begin(), list.end(), DPluginAction::pluginActionLessThan); 0125 0126 return list; 0127 } 0128 0129 QList<DPluginAction*> DPluginLoader::pluginsActions(DPluginAction::ActionCategory cat, QObject* const parent) const 0130 { 0131 QList<DPluginAction*> list; 0132 0133 Q_FOREACH (DPlugin* const p, d->allPlugins) 0134 { 0135 DPluginGeneric* const gene = dynamic_cast<DPluginGeneric*>(p); 0136 0137 if (gene) 0138 { 0139 Q_FOREACH (DPluginAction* const ac, gene->actions(parent)) 0140 { 0141 if (ac && (ac->actionCategory() == cat)) 0142 { 0143 list << ac; 0144 } 0145 } 0146 } 0147 } 0148 0149 if (list.isEmpty()) 0150 { 0151 Q_FOREACH (DPlugin* const p, d->allPlugins) 0152 { 0153 DPluginEditor* const edit = dynamic_cast<DPluginEditor*>(p); 0154 0155 if (edit) 0156 { 0157 Q_FOREACH (DPluginAction* const ac, edit->actions(parent)) 0158 { 0159 if (ac && (ac->actionCategory() == cat)) 0160 { 0161 list << ac; 0162 } 0163 } 0164 } 0165 } 0166 } 0167 0168 std::sort(list.begin(), list.end(), DPluginAction::pluginActionLessThan); 0169 return list; 0170 } 0171 0172 QList<DPluginAction*> DPluginLoader::pluginActions(const QString& pluginIID, QObject* const parent) const 0173 { 0174 QList<DPluginAction*> list; 0175 0176 Q_FOREACH (DPlugin* const p, d->allPlugins) 0177 { 0178 DPluginGeneric* const gene = dynamic_cast<DPluginGeneric*>(p); 0179 0180 if (gene) 0181 { 0182 if (p->iid() == pluginIID) 0183 { 0184 Q_FOREACH (DPluginAction* const ac, gene->actions(parent)) 0185 { 0186 list << ac; 0187 } 0188 0189 break; 0190 } 0191 } 0192 } 0193 0194 if (list.isEmpty()) 0195 { 0196 Q_FOREACH (DPlugin* const p, d->allPlugins) 0197 { 0198 DPluginEditor* const edit = dynamic_cast<DPluginEditor*>(p); 0199 0200 if (edit) 0201 { 0202 if (p->iid() == pluginIID) 0203 { 0204 Q_FOREACH (DPluginAction* const ac, edit->actions(parent)) 0205 { 0206 list << ac; 0207 } 0208 0209 break; 0210 } 0211 } 0212 } 0213 } 0214 0215 std::sort(list.begin(), list.end(), DPluginAction::pluginActionLessThan); 0216 return list; 0217 } 0218 0219 DPluginAction* DPluginLoader::pluginAction(const QString& actionName, QObject* const parent) const 0220 { 0221 Q_FOREACH (DPlugin* const p, d->allPlugins) 0222 { 0223 DPluginGeneric* const gene = dynamic_cast<DPluginGeneric*>(p); 0224 0225 if (gene) 0226 { 0227 Q_FOREACH (DPluginAction* const ac, gene->actions(parent)) 0228 { 0229 if (ac && (ac->objectName() == actionName)) 0230 { // cppcheck-suppress useStlAlgorithm 0231 return ac; 0232 } 0233 } 0234 } 0235 0236 DPluginEditor* const edit = dynamic_cast<DPluginEditor*>(p); 0237 0238 if (edit) 0239 { 0240 Q_FOREACH (DPluginAction* const ac, edit->actions(parent)) 0241 { 0242 if (ac && (ac->objectName() == actionName)) 0243 { // cppcheck-suppress useStlAlgorithm 0244 return ac; 0245 } 0246 } 0247 } 0248 } 0249 0250 qCCritical(DIGIKAM_GENERAL_LOG) << "DPluginAction named" << actionName 0251 << "not found in" << parent->objectName() 0252 << "(" << parent << ")"; 0253 0254 return nullptr; 0255 } 0256 0257 QString DPluginLoader::pluginXmlSections(DPluginAction::ActionCategory cat, QObject* const parent) const 0258 { 0259 QString xml; 0260 0261 Q_FOREACH (DPluginAction* const ac, pluginsActions(cat, parent)) 0262 { 0263 xml.append(ac->xmlSection()); 0264 } 0265 0266 return xml; 0267 } 0268 0269 void DPluginLoader::appendPluginToBlackList(const QString& filename) 0270 { 0271 d->blacklist << filename; 0272 } 0273 0274 void DPluginLoader::appendPluginToWhiteList(const QString& filename) 0275 { 0276 d->whitelist << filename; 0277 } 0278 0279 void DPluginLoader::registerGenericPlugins(QObject* const parent) 0280 { 0281 Q_FOREACH (DPlugin* const plugin, d->allPlugins) 0282 { 0283 DPluginGeneric* const gene = dynamic_cast<DPluginGeneric*>(plugin); 0284 0285 if (gene) 0286 { 0287 gene->setup(parent); 0288 gene->setVisible(plugin->shouldLoaded()); 0289 /* 0290 qCDebug(DIGIKAM_GENERAL_LOG) << "Generic plugin named" << gene->name() 0291 << "registered to" << parent; 0292 */ 0293 } 0294 } 0295 } 0296 0297 void DPluginLoader::registerEditorPlugins(QObject* const parent) 0298 { 0299 Q_FOREACH (DPlugin* const plugin, d->allPlugins) 0300 { 0301 DPluginEditor* const edit = dynamic_cast<DPluginEditor*>(plugin); 0302 0303 if (edit) 0304 { 0305 edit->setup(parent); 0306 edit->setVisible(plugin->shouldLoaded()); 0307 /* 0308 qCDebug(DIGIKAM_GENERAL_LOG) << "Editor plugin named" << edit->name() 0309 << "registered to" << parent; 0310 */ 0311 } 0312 } 0313 } 0314 0315 void DPluginLoader::registerRawImportPlugins(QObject* const parent) 0316 { 0317 Q_FOREACH (DPlugin* const plugin, d->allPlugins) 0318 { 0319 DPluginRawImport* const raw = dynamic_cast<DPluginRawImport*>(plugin); 0320 0321 if (raw) 0322 { 0323 raw->setup(parent); 0324 /* 0325 qCDebug(DIGIKAM_GENERAL_LOG) << "Raw Import plugin named" << raw->name() 0326 << "registered to" << parent; 0327 */ 0328 } 0329 } 0330 } 0331 0332 DImgLoaderSettings* DPluginLoader::exportWidget(const QString& format) const 0333 { 0334 Q_FOREACH (DPlugin* const plugin, d->allPlugins) 0335 { 0336 DPluginDImg* const dimg = dynamic_cast<DPluginDImg*>(plugin); 0337 0338 if (dimg) 0339 { 0340 DImgLoaderSettings* const widget = dimg->exportWidget(format); 0341 0342 if (widget) 0343 { 0344 return widget; 0345 } 0346 } 0347 } 0348 0349 return nullptr; 0350 } 0351 0352 bool DPluginLoader::canImport(const QString& format) const 0353 { 0354 Q_FOREACH (DPlugin* const plugin, d->allPlugins) 0355 { 0356 DPluginDImg* const dimg = dynamic_cast<DPluginDImg*>(plugin); 0357 0358 if (dimg && dimg->canRead(QFileInfo(QString::fromLatin1("foo.%1").arg(format)), true)) 0359 { 0360 return true; 0361 } 0362 } 0363 0364 return false; 0365 } 0366 0367 bool DPluginLoader::canExport(const QString& format) const 0368 { 0369 Q_FOREACH (DPlugin* const plugin, d->allPlugins) 0370 { 0371 DPluginDImg* const dimg = dynamic_cast<DPluginDImg*>(plugin); 0372 0373 if (dimg && dimg->canWrite(format)) 0374 { 0375 return true; 0376 } 0377 } 0378 0379 return false; 0380 } 0381 0382 } // namespace Digikam 0383 0384 #include "moc_dpluginloader.cpp"