File indexing completed on 2024-05-05 16:48:35
0001 /* This file is part of the KDE project 0002 Copyright (C) 2010 by Adam Pigg (adam@piggz.co.uk) 0003 Copyright (C) 2015-2016 Jarosław Staniek <staniek@kde.org> 0004 0005 This library is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU Library General Public 0007 License as published by the Free Software Foundation; either 0008 version 2.1 of the License, or (at your option) any later version. 0009 0010 This library is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 Library General Public License for more details. 0014 0015 You should have received a copy of the GNU Library General Public License 0016 along with this library; see the file COPYING.LIB. If not, write to 0017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 Boston, MA 02110-1301, USA. 0019 */ 0020 0021 #include "KReportPluginManager.h" 0022 #include "KReportPluginManagerPrivate.h" 0023 #include "KReportPluginMetaData.h" 0024 #include "KReportJsonTrader_p.h" 0025 #include "KReportUtils_p.h" 0026 0027 #include "kreport_debug.h" 0028 #include <QAction> 0029 0030 //Include the static items 0031 #include "../items/label/KReportLabelPlugin.h" 0032 #include "../items/check/KReportCheckBoxPlugin.h" 0033 #include "../items/field/KReportFieldPlugin.h" 0034 #include "../items/image/KReportImagePlugin.h" 0035 #include "../items/text/KReportTextPlugin.h" 0036 0037 KReportPluginManager::Private::Private(KReportPluginManager *qq) 0038 : q(qq), m_parent(new QObject), m_findPlugins(true) 0039 { 0040 Q_UNUSED(q) 0041 } 0042 0043 // --- 0044 0045 KReportPluginEntry::KReportPluginEntry() 0046 : m_loader(nullptr), m_interface(nullptr), m_metaData(nullptr) 0047 { 0048 } 0049 0050 KReportPluginEntry::KReportPluginEntry(KReportPluginInterface *staticInterface) 0051 : m_loader(nullptr), m_interface(staticInterface), m_metaData(nullptr) 0052 { 0053 } 0054 0055 KReportPluginEntry::~KReportPluginEntry() 0056 { 0057 delete m_metaData; 0058 delete m_interface; 0059 } 0060 0061 KReportPluginInterface* KReportPluginEntry::plugin() 0062 { 0063 if (m_interface) { 0064 return m_interface; 0065 } 0066 if (!m_loader) { 0067 kreportWarning() << "No such plugin"; 0068 return nullptr; 0069 } 0070 if (!m_loader->load()) { 0071 kreportWarning() << "Could not load plugin" << m_loader->fileName(); 0072 return nullptr; 0073 } 0074 KPluginFactory *factory = qobject_cast<KPluginFactory*>(m_loader->instance()); 0075 if (!factory) { 0076 kreportWarning() << "Could not create factory for plugin" << m_loader->fileName(); 0077 return nullptr; 0078 } 0079 m_interface = factory->create<KReportPluginInterface>(); 0080 if (!m_interface) { 0081 kreportWarning() << "Could not create instance of plugin" << m_loader->fileName(); 0082 return nullptr; 0083 } 0084 m_interface->setMetaData(m_metaData); 0085 return m_interface; 0086 } 0087 0088 void KReportPluginEntry::setBuiltIn(bool set) 0089 { 0090 m_metaData->setBuiltIn(set); 0091 } 0092 0093 void KReportPluginEntry::setStatic(bool set) 0094 { 0095 m_metaData->setStatic(set); 0096 } 0097 0098 const KReportPluginMetaData *KReportPluginEntry::metaData() const 0099 { 0100 return m_metaData; 0101 } 0102 0103 void KReportPluginEntry::setMetaData(KReportPluginMetaData *metaData) 0104 { 0105 delete m_metaData; 0106 m_metaData = metaData; 0107 if (m_interface) { 0108 m_interface->setMetaData(m_metaData); 0109 } 0110 } 0111 0112 void KReportPluginEntry::setMetaData(const QJsonObject &metaData) 0113 { 0114 setMetaData(new KReportPluginMetaData(metaData)); 0115 } 0116 0117 void KReportPluginEntry::setMetaData(QPluginLoader *loader) 0118 { 0119 m_loader = loader; 0120 setMetaData(new KReportPluginMetaData(*m_loader)); 0121 } 0122 0123 // --- 0124 0125 KReportPluginManager::Private::~Private() 0126 { 0127 delete m_parent; 0128 } 0129 0130 template<class PluginClass> 0131 void KReportPluginManager::Private::addBuiltInPlugin(const QJsonObject &json) 0132 { 0133 KReportPluginEntry *entry = new KReportPluginEntry(new PluginClass(m_parent)); 0134 QJsonObject j = json.value(QLatin1String("MetaData")).toObject(); 0135 //kreportDebug() << j; 0136 entry->setMetaData(j); 0137 entry->setBuiltIn(true); 0138 if (entry->metaData()->id().isEmpty()) { 0139 kreportWarning() << "Plugin" << entry->metaData()->name() << "has no identifier so won't be added to manager"; 0140 delete entry; 0141 return; 0142 } 0143 entry->setStatic(true); 0144 m_plugins.insert(entry->metaData()->id(), entry); 0145 m_pluginsByLegacyName.insert(entry->metaData()->value(QLatin1String("X-KDE-PluginInfo-LegacyName"), entry->metaData()->id()), entry); 0146 } 0147 0148 #define KREPORT_ADD_BUILTIN_PLUGIN(name) \ 0149 addBuiltInPlugin<name>(KREPORT_STATIC_PLUGIN_METADATA(name)) 0150 0151 QMap<QString, KReportPluginEntry*>* KReportPluginManager::Private::plugins() 0152 { 0153 if (m_findPlugins) { 0154 findPlugins(); 0155 } 0156 return &m_plugins; 0157 } 0158 0159 QMap<QString, KReportPluginEntry*>* KReportPluginManager::Private::pluginsByLegacyName() 0160 { 0161 if (m_findPlugins) { 0162 findPlugins(); 0163 } 0164 return &m_pluginsByLegacyName; 0165 } 0166 0167 void KReportPluginManager::Private::findPlugins() 0168 { 0169 KREPORT_ADD_BUILTIN_PLUGIN(KReportLabelPlugin); 0170 KREPORT_ADD_BUILTIN_PLUGIN(KReportCheckBoxPlugin); 0171 KREPORT_ADD_BUILTIN_PLUGIN(KReportFieldPlugin); 0172 KREPORT_ADD_BUILTIN_PLUGIN(KReportImagePlugin); 0173 KREPORT_ADD_BUILTIN_PLUGIN(KReportTextPlugin); 0174 0175 //kreportDebug() << "Load all plugins"; 0176 const QList<QPluginLoader*> offers = KReportJsonTrader::self()->query(QLatin1String("KReport/Element")); 0177 const QString expectedVersion = QString::fromLatin1("%1.%2") 0178 .arg(KREPORT_STABLE_VERSION_MAJOR).arg(KREPORT_STABLE_VERSION_MINOR); 0179 foreach(QPluginLoader *loader, offers) { 0180 //QJsonObject json = loader->metaData(); 0181 //kreportDebug() << json; 0182 //! @todo check version 0183 QScopedPointer<KReportPluginEntry> entry(new KReportPluginEntry); 0184 entry->setMetaData(loader); 0185 const KReportPluginMetaData *metaData = entry->metaData(); 0186 if (metaData->version() != expectedVersion) { 0187 kreportWarning() << "KReport element plugin with ID" << metaData->id() 0188 << "(" << metaData->fileName() << ")" 0189 << "has version" << metaData->version() << "but expected version is" 0190 << expectedVersion 0191 << "-- skipping it"; 0192 continue; 0193 } 0194 if (m_plugins.contains(metaData->id())) { 0195 kreportWarning() << "KReport element plugin with ID" << metaData->id() 0196 << "already found at" 0197 << m_plugins.value(metaData->id())->metaData()->fileName() 0198 << "-- skipping another at" << metaData->fileName(); 0199 continue; 0200 } 0201 if (!KReportPrivate::setupPrivateIconsResourceWithMessage( 0202 QLatin1String(KREPORT_BASE_NAME_LOWER), 0203 QString::fromLatin1("icons/%1_%2.rcc") 0204 .arg(metaData->id()).arg(KReportPrivate::supportedIconTheme), 0205 QtWarningMsg, 0206 QString::fromLatin1(":/icons/%1").arg(metaData->id()))) 0207 { 0208 continue; 0209 } 0210 addEntry(entry.take()); 0211 } 0212 m_findPlugins = false; 0213 } 0214 0215 void KReportPluginManager::Private::addEntry(KReportPluginEntry *entry) 0216 { 0217 m_plugins.insert(entry->metaData()->id(), entry); 0218 const QString legacyName(entry->metaData()->value(QLatin1String("X-KDE-PluginInfo-LegacyName"), entry->metaData()->id())); 0219 if (!legacyName.isEmpty() && entry->metaData()->id().startsWith(QLatin1String("org.kde.kreport"))) { 0220 m_pluginsByLegacyName.insert(legacyName, entry); 0221 } 0222 } 0223 0224 // --- 0225 0226 //! Class for access to KReportPluginManager constructor 0227 class KReportPluginManagerSingleton 0228 { 0229 public: 0230 KReportPluginManager object; 0231 }; 0232 0233 0234 KReportPluginManager::KReportPluginManager() 0235 : d(new Private(this)) 0236 { 0237 KReportPrivate::setupPrivateIconsResourceWithMessage( 0238 QLatin1String(KREPORT_BASE_NAME_LOWER), 0239 QString::fromLatin1("icons/kreport_%1.rcc").arg(KReportPrivate::supportedIconTheme), QtFatalMsg); 0240 } 0241 0242 KReportPluginManager::~KReportPluginManager() 0243 { 0244 delete d; 0245 } 0246 0247 Q_GLOBAL_STATIC(KReportPluginManagerSingleton, s_self) 0248 0249 KReportPluginManager* KReportPluginManager::self() 0250 { 0251 return &s_self->object; 0252 } 0253 0254 QStringList KReportPluginManager::pluginIds() const 0255 { 0256 return d->plugins()->keys(); 0257 } 0258 0259 const KReportPluginMetaData *KReportPluginManager::pluginMetaData(const QString& id) const 0260 { 0261 KReportPluginEntry *entry = d->plugins()->value(id); 0262 if (!entry) { 0263 return nullptr; 0264 } 0265 return entry->metaData(); 0266 } 0267 0268 KReportPluginInterface* KReportPluginManager::plugin(const QString& id) const 0269 { 0270 KReportPluginEntry *entry; 0271 0272 entry = d->plugins()->value(id); 0273 0274 if (!entry) { 0275 entry = d->pluginsByLegacyName()->value(id); 0276 } 0277 0278 if (!entry) { 0279 return nullptr; 0280 } 0281 return entry->plugin(); 0282 } 0283 0284 QList<QAction*> KReportPluginManager::createActions(QObject *parent) 0285 { 0286 Q_ASSERT(parent); 0287 const QMap<QString, KReportPluginEntry*> *plugins = d->plugins(); 0288 QList<QAction*> actList; 0289 foreach(KReportPluginEntry* plugin, *plugins) { 0290 const KReportPluginMetaData *metaData = plugin->metaData(); 0291 if (metaData) { 0292 QAction *act = new QAction(QIcon::fromTheme(metaData->iconName()), metaData->name(), parent); 0293 act->setObjectName(metaData->id()); 0294 act->setCheckable(true); 0295 0296 //Store the order priority in the user data field 0297 act->setData(metaData->priority()); 0298 actList << act; 0299 } 0300 } 0301 return actList; 0302 }