File indexing completed on 2024-04-28 04:41:57
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 "KReportUtils_p.h" 0025 0026 #include "kreport_debug.h" 0027 #include <QAction> 0028 0029 #include <KPluginMetaData> 0030 #include <KPluginLoader> 0031 0032 //Include the static items 0033 #include "../items/label/KReportLabelPlugin.h" 0034 #include "../items/check/KReportCheckBoxPlugin.h" 0035 #include "../items/field/KReportFieldPlugin.h" 0036 #include "../items/image/KReportImagePlugin.h" 0037 #include "../items/text/KReportTextPlugin.h" 0038 0039 KReportPluginManager::Private::Private(KReportPluginManager *qq) 0040 : q(qq), m_parent(new QObject), m_findPlugins(true) 0041 { 0042 Q_UNUSED(q) 0043 } 0044 0045 // --- 0046 0047 KReportPluginEntry::KReportPluginEntry() 0048 : m_loader(nullptr), m_interface(nullptr), m_metaData(nullptr) 0049 { 0050 } 0051 0052 KReportPluginEntry::KReportPluginEntry(KReportPluginInterface *staticInterface) 0053 : m_loader(nullptr), m_interface(staticInterface), m_metaData(nullptr) 0054 { 0055 } 0056 0057 KReportPluginEntry::~KReportPluginEntry() 0058 { 0059 delete m_metaData; 0060 delete m_interface; 0061 } 0062 0063 KReportPluginInterface* KReportPluginEntry::plugin() 0064 { 0065 if (m_interface) { 0066 return m_interface; 0067 } 0068 if (!m_loader) { 0069 kreportWarning() << "No such plugin"; 0070 return nullptr; 0071 } 0072 if (!m_loader->load()) { 0073 kreportWarning() << "Could not load plugin" << m_loader->fileName(); 0074 return nullptr; 0075 } 0076 KPluginFactory *factory = qobject_cast<KPluginFactory*>(m_loader->instance()); 0077 if (!factory) { 0078 kreportWarning() << "Could not create factory for plugin" << m_loader->fileName(); 0079 return nullptr; 0080 } 0081 m_interface = factory->create<KReportPluginInterface>(); 0082 if (!m_interface) { 0083 kreportWarning() << "Could not create instance of plugin" << m_loader->fileName(); 0084 return nullptr; 0085 } 0086 m_interface->setMetaData(m_metaData); 0087 return m_interface; 0088 } 0089 0090 void KReportPluginEntry::setBuiltIn(bool set) 0091 { 0092 m_metaData->setBuiltIn(set); 0093 } 0094 0095 void KReportPluginEntry::setStatic(bool set) 0096 { 0097 m_metaData->setStatic(set); 0098 } 0099 0100 const KReportPluginMetaData *KReportPluginEntry::metaData() const 0101 { 0102 return m_metaData; 0103 } 0104 0105 void KReportPluginEntry::setMetaData(KReportPluginMetaData *metaData) 0106 { 0107 delete m_metaData; 0108 m_metaData = metaData; 0109 if (m_interface) { 0110 m_interface->setMetaData(m_metaData); 0111 } 0112 } 0113 0114 void KReportPluginEntry::setMetaData(const QJsonObject &metaData) 0115 { 0116 setMetaData(new KReportPluginMetaData(metaData)); 0117 } 0118 0119 void KReportPluginEntry::setMetaData(QPluginLoader *loader) 0120 { 0121 m_loader = loader; 0122 setMetaData(new KReportPluginMetaData(*m_loader)); 0123 } 0124 0125 // --- 0126 0127 KReportPluginManager::Private::~Private() 0128 { 0129 delete m_parent; 0130 } 0131 0132 template<class PluginClass> 0133 void KReportPluginManager::Private::addBuiltInPlugin(const QJsonObject &json) 0134 { 0135 KReportPluginEntry *entry = new KReportPluginEntry(new PluginClass(m_parent)); 0136 QJsonObject j = json.value(QLatin1String("MetaData")).toObject(); 0137 //kreportDebug() << j; 0138 entry->setMetaData(j); 0139 entry->setBuiltIn(true); 0140 if (entry->metaData()->id().isEmpty()) { 0141 kreportWarning() << "Plugin" << entry->metaData()->name() << "has no identifier so won't be added to manager"; 0142 delete entry; 0143 return; 0144 } 0145 entry->setStatic(true); 0146 m_plugins.insert(entry->metaData()->id(), entry); 0147 m_pluginsByLegacyName.insert(entry->metaData()->value(QLatin1String("X-KDE-PluginInfo-LegacyName"), entry->metaData()->id()), entry); 0148 } 0149 0150 #define KREPORT_ADD_BUILTIN_PLUGIN(name) \ 0151 addBuiltInPlugin<name>(KREPORT_STATIC_PLUGIN_METADATA(name)) 0152 0153 QMap<QString, KReportPluginEntry*>* KReportPluginManager::Private::plugins() 0154 { 0155 if (m_findPlugins) { 0156 findPlugins(); 0157 } 0158 return &m_plugins; 0159 } 0160 0161 QMap<QString, KReportPluginEntry*>* KReportPluginManager::Private::pluginsByLegacyName() 0162 { 0163 if (m_findPlugins) { 0164 findPlugins(); 0165 } 0166 return &m_pluginsByLegacyName; 0167 } 0168 0169 void KReportPluginManager::Private::findPlugins() 0170 { 0171 KREPORT_ADD_BUILTIN_PLUGIN(KReportLabelPlugin); 0172 KREPORT_ADD_BUILTIN_PLUGIN(KReportCheckBoxPlugin); 0173 KREPORT_ADD_BUILTIN_PLUGIN(KReportFieldPlugin); 0174 KREPORT_ADD_BUILTIN_PLUGIN(KReportImagePlugin); 0175 KREPORT_ADD_BUILTIN_PLUGIN(KReportTextPlugin); 0176 0177 //kreportDebug() << "Load all plugins"; 0178 const QVector<KPluginMetaData> metaDataList = KPluginLoader::findPlugins(QStringLiteral(KREPORT_BASE_NAME_LOWER)); 0179 const QString expectedVersion = QString::fromLatin1("%1.%2") 0180 .arg(KREPORT_STABLE_VERSION_MAJOR).arg(KREPORT_STABLE_VERSION_MINOR); 0181 for (const KPluginMetaData &pluginMetaData : metaDataList) { 0182 auto *loader = new QPluginLoader(pluginMetaData.fileName()); 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 }