KReport

KReportPluginManager.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2010 by Adam Pigg (adam@piggz.co.uk)
3 Copyright (C) 2015-2016 Jarosław Staniek <staniek@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21#include "KReportPluginManager.h"
22#include "KReportPluginManagerPrivate.h"
23#include "KReportPluginMetaData.h"
24#include "KReportUtils_p.h"
25
26#include "kreport_debug.h"
27#include <QAction>
28
29#include <KPluginMetaData>
30#include <KPluginLoader>
31
32//Include the static items
33#include "../items/label/KReportLabelPlugin.h"
34#include "../items/check/KReportCheckBoxPlugin.h"
35#include "../items/field/KReportFieldPlugin.h"
36#include "../items/image/KReportImagePlugin.h"
37#include "../items/text/KReportTextPlugin.h"
38
39KReportPluginManager::Private::Private(KReportPluginManager *qq)
40 : q(qq), m_parent(new QObject), m_findPlugins(true)
41{
42 Q_UNUSED(q)
43}
44
45// ---
46
48 : m_loader(nullptr), m_interface(nullptr), m_metaData(nullptr)
49{
50}
51
53 : m_loader(nullptr), m_interface(staticInterface), m_metaData(nullptr)
54{
55}
56
57KReportPluginEntry::~KReportPluginEntry()
58{
59 delete m_metaData;
60 delete m_interface;
61}
62
63KReportPluginInterface* KReportPluginEntry::plugin()
64{
65 if (m_interface) {
66 return m_interface;
67 }
68 if (!m_loader) {
69 kreportWarning() << "No such plugin";
70 return nullptr;
71 }
72 if (!m_loader->load()) {
73 kreportWarning() << "Could not load plugin" << m_loader->fileName();
74 return nullptr;
75 }
76 KPluginFactory *factory = qobject_cast<KPluginFactory*>(m_loader->instance());
77 if (!factory) {
78 kreportWarning() << "Could not create factory for plugin" << m_loader->fileName();
79 return nullptr;
80 }
81 m_interface = factory->create<KReportPluginInterface>();
82 if (!m_interface) {
83 kreportWarning() << "Could not create instance of plugin" << m_loader->fileName();
84 return nullptr;
85 }
86 m_interface->setMetaData(m_metaData);
87 return m_interface;
88}
89
90void KReportPluginEntry::setBuiltIn(bool set)
91{
92 m_metaData->setBuiltIn(set);
93}
94
95void KReportPluginEntry::setStatic(bool set)
96{
97 m_metaData->setStatic(set);
98}
99
100const KReportPluginMetaData *KReportPluginEntry::metaData() const
101{
102 return m_metaData;
103}
104
105void KReportPluginEntry::setMetaData(KReportPluginMetaData *metaData)
106{
107 delete m_metaData;
108 m_metaData = metaData;
109 if (m_interface) {
110 m_interface->setMetaData(m_metaData);
111 }
112}
113
114void KReportPluginEntry::setMetaData(const QJsonObject &metaData)
115{
116 setMetaData(new KReportPluginMetaData(metaData));
117}
118
119void KReportPluginEntry::setMetaData(QPluginLoader *loader)
120{
121 m_loader = loader;
122 setMetaData(new KReportPluginMetaData(*m_loader));
123}
124
125// ---
126
127KReportPluginManager::Private::~Private()
128{
129 delete m_parent;
130}
131
132template<class PluginClass>
134{
135 KReportPluginEntry *entry = new KReportPluginEntry(new PluginClass(m_parent));
136 QJsonObject j = json.value(QLatin1String("MetaData")).toObject();
137 //kreportDebug() << j;
138 entry->setMetaData(j);
139 entry->setBuiltIn(true);
140 if (entry->metaData()->id().isEmpty()) {
141 kreportWarning() << "Plugin" << entry->metaData()->name() << "has no identifier so won't be added to manager";
142 delete entry;
143 return;
144 }
145 entry->setStatic(true);
146 m_plugins.insert(entry->metaData()->id(), entry);
147 m_pluginsByLegacyName.insert(entry->metaData()->value(QLatin1String("X-KDE-PluginInfo-LegacyName"), entry->metaData()->id()), entry);
148}
149
150#define KREPORT_ADD_BUILTIN_PLUGIN(name) \
151 addBuiltInPlugin<name>(KREPORT_STATIC_PLUGIN_METADATA(name))
152
153QMap<QString, KReportPluginEntry*>* KReportPluginManager::Private::plugins()
154{
155 if (m_findPlugins) {
156 findPlugins();
157 }
158 return &m_plugins;
159}
160
161QMap<QString, KReportPluginEntry*>* KReportPluginManager::Private::pluginsByLegacyName()
162{
163 if (m_findPlugins) {
164 findPlugins();
165 }
166 return &m_pluginsByLegacyName;
167}
168
169void KReportPluginManager::Private::findPlugins()
170{
171 KREPORT_ADD_BUILTIN_PLUGIN(KReportLabelPlugin);
172 KREPORT_ADD_BUILTIN_PLUGIN(KReportCheckBoxPlugin);
173 KREPORT_ADD_BUILTIN_PLUGIN(KReportFieldPlugin);
174 KREPORT_ADD_BUILTIN_PLUGIN(KReportImagePlugin);
175 KREPORT_ADD_BUILTIN_PLUGIN(KReportTextPlugin);
176
177 //kreportDebug() << "Load all plugins";
178 const QVector<KPluginMetaData> metaDataList = KPluginLoader::findPlugins(QStringLiteral(KREPORT_BASE_NAME_LOWER));
179 const QString expectedVersion = QString::fromLatin1("%1.%2")
180 .arg(KREPORT_STABLE_VERSION_MAJOR).arg(KREPORT_STABLE_VERSION_MINOR);
181 for (const KPluginMetaData &pluginMetaData : metaDataList) {
182 auto *loader = new QPluginLoader(pluginMetaData.fileName());
184 entry->setMetaData(loader);
185 const KReportPluginMetaData *metaData = entry->metaData();
186 if (metaData->version() != expectedVersion) {
187 kreportWarning() << "KReport element plugin with ID" << metaData->id()
188 << "(" << metaData->fileName() << ")"
189 << "has version" << metaData->version() << "but expected version is"
190 << expectedVersion
191 << "-- skipping it";
192 continue;
193 }
194 if (m_plugins.contains(metaData->id())) {
195 kreportWarning() << "KReport element plugin with ID" << metaData->id()
196 << "already found at"
197 << m_plugins.value(metaData->id())->metaData()->fileName()
198 << "-- skipping another at" << metaData->fileName();
199 continue;
200 }
201 if (!KReportPrivate::setupPrivateIconsResourceWithMessage(
202 QLatin1String(KREPORT_BASE_NAME_LOWER),
203 QString::fromLatin1("icons/%1_%2.rcc")
204 .arg(metaData->id()).arg(KReportPrivate::supportedIconTheme),
205 QtWarningMsg,
206 QString::fromLatin1(":/icons/%1").arg(metaData->id())))
207 {
208 continue;
209 }
210 addEntry(entry.take());
211 }
212 m_findPlugins = false;
213}
214
215void KReportPluginManager::Private::addEntry(KReportPluginEntry *entry)
216{
217 m_plugins.insert(entry->metaData()->id(), entry);
218 const QString legacyName(entry->metaData()->value(QLatin1String("X-KDE-PluginInfo-LegacyName"), entry->metaData()->id()));
219 if (!legacyName.isEmpty() && entry->metaData()->id().startsWith(QLatin1String("org.kde.kreport"))) {
220 m_pluginsByLegacyName.insert(legacyName, entry);
221 }
222}
223
224// ---
225
226//! Class for access to KReportPluginManager constructor
227class KReportPluginManagerSingleton
228{
229public:
231};
232
233
234KReportPluginManager::KReportPluginManager()
235 : d(new Private(this))
236{
237 KReportPrivate::setupPrivateIconsResourceWithMessage(
238 QLatin1String(KREPORT_BASE_NAME_LOWER),
239 QString::fromLatin1("icons/kreport_%1.rcc").arg(KReportPrivate::supportedIconTheme), QtFatalMsg);
240}
241
242KReportPluginManager::~KReportPluginManager()
243{
244 delete d;
245}
246
247Q_GLOBAL_STATIC(KReportPluginManagerSingleton, s_self)
248
249KReportPluginManager* KReportPluginManager::self()
250{
251 return &s_self->object;
252}
253
254QStringList KReportPluginManager::pluginIds() const
255{
256 return d->plugins()->keys();
257}
258
259const KReportPluginMetaData *KReportPluginManager::pluginMetaData(const QString& id) const
260{
261 KReportPluginEntry *entry = d->plugins()->value(id);
262 if (!entry) {
263 return nullptr;
264 }
265 return entry->metaData();
266}
267
268KReportPluginInterface* KReportPluginManager::plugin(const QString& id) const
269{
270 KReportPluginEntry *entry;
271
272 entry = d->plugins()->value(id);
273
274 if (!entry) {
275 entry = d->pluginsByLegacyName()->value(id);
276 }
277
278 if (!entry) {
279 return nullptr;
280 }
281 return entry->plugin();
282}
283
284QList<QAction*> KReportPluginManager::createActions(QObject *parent)
285{
286 Q_ASSERT(parent);
287 const QMap<QString, KReportPluginEntry*> *plugins = d->plugins();
288 QList<QAction*> actList;
289 foreach(KReportPluginEntry* plugin, *plugins) {
290 const KReportPluginMetaData *metaData = plugin->metaData();
291 if (metaData) {
292 QAction *act = new QAction(QIcon::fromTheme(metaData->iconName()), metaData->name(), parent);
293 act->setObjectName(metaData->id());
294 act->setCheckable(true);
295
296 //Store the order priority in the user data field
297 act->setData(metaData->priority());
298 actList << act;
299 }
300 }
301 return actList;
302}
T * create(QObject *parent=nullptr, const QVariantList &args={})
bool value(const QString &key, bool defaultValue) const
QString fileName() const
QString iconName() const
QString name() const
QString version() const
KReportPluginEntry()
Used for dynamic plugins.
An interface for plugins delivering KReport elements.
void addBuiltInPlugin(const QJsonObject &json)
Add a built-in element plugins.
Manager class for finding and loading available plugins.
Information about a KReport plugin.
void setCheckable(bool)
void setData(const QVariant &data)
QIcon fromTheme(const QString &name)
QJsonValue value(QLatin1StringView key) const const
QJsonObject toObject() const const
QList< Key > keys() const const
T value(const Key &key, const T &defaultValue) const const
QObject * parent() const const
void setObjectName(QAnyStringView name)
QObject * instance()
QString arg(Args &&... args) const const
QString fromLatin1(QByteArrayView str)
bool isEmpty() const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:21:31 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.