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(QStringView 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 Mon Nov 4 2024 16:39:31 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.