KReport

KReportPluginManager.cpp
1 /* This file is part of the KDE project
2  Copyright (C) 2010 by Adam Pigg ([email protected])
3  Copyright (C) 2015-2016 JarosÅ‚aw Staniek <[email protected]>
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 
39 KReportPluginManager::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 
57 KReportPluginEntry::~KReportPluginEntry()
58 {
59  delete m_metaData;
60  delete m_interface;
61 }
62 
63 KReportPluginInterface* 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 
90 void KReportPluginEntry::setBuiltIn(bool set)
91 {
92  m_metaData->setBuiltIn(set);
93 }
94 
95 void KReportPluginEntry::setStatic(bool set)
96 {
97  m_metaData->setStatic(set);
98 }
99 
100 const KReportPluginMetaData *KReportPluginEntry::metaData() const
101 {
102  return m_metaData;
103 }
104 
105 void 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 
114 void KReportPluginEntry::setMetaData(const QJsonObject &metaData)
115 {
116  setMetaData(new KReportPluginMetaData(metaData));
117 }
118 
119 void KReportPluginEntry::setMetaData(QPluginLoader *loader)
120 {
121  m_loader = loader;
122  setMetaData(new KReportPluginMetaData(*m_loader));
123 }
124 
125 // ---
126 
127 KReportPluginManager::Private::~Private()
128 {
129  delete m_parent;
130 }
131 
132 template<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 
153 QMap<QString, KReportPluginEntry*>* KReportPluginManager::Private::plugins()
154 {
155  if (m_findPlugins) {
156  findPlugins();
157  }
158  return &m_plugins;
159 }
160 
161 QMap<QString, KReportPluginEntry*>* KReportPluginManager::Private::pluginsByLegacyName()
162 {
163  if (m_findPlugins) {
164  findPlugins();
165  }
166  return &m_pluginsByLegacyName;
167 }
168 
169 void 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 
215 void 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
227 class KReportPluginManagerSingleton
228 {
229 public:
230  KReportPluginManager object;
231 };
232 
233 
234 KReportPluginManager::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 
242 KReportPluginManager::~KReportPluginManager()
243 {
244  delete d;
245 }
246 
247 Q_GLOBAL_STATIC(KReportPluginManagerSingleton, s_self)
248 
249 KReportPluginManager* KReportPluginManager::self()
250 {
251  return &s_self->object;
252 }
253 
254 QStringList KReportPluginManager::pluginIds() const
255 {
256  return d->plugins()->keys();
257 }
258 
259 const 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 
268 KReportPluginInterface* 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 
284 QList<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 }
QJsonObject toObject() const const
T * create(const QString &keyword, QObject *parent=nullptr, const QVariantList &args=QVariantList())
void addBuiltInPlugin(const QJsonObject &json)
Add a built-in element plugins.
const T value(const Key &key, const T &defaultValue) const const
KReportPluginEntry()
Used for dynamic plugins.
QIcon fromTheme(const QString &name)
QString fileName() const
Manager class for finding and loading available plugins.
QString version() const
QString iconName() const
Q_GLOBAL_STATIC(Internal::StaticControl, s_instance) class ControlPrivate
static QVector< KPluginMetaData > findPlugins(const QString &directory, std::function< bool(const KPluginMetaData &)> filter=std::function< bool(const KPluginMetaData &)>())
QString name() const
bool isEmpty() const const
QJsonValue value(const QString &key) const const
Information about a KReport plugin.
void setCheckable(bool)
bool value(const QString &key, bool defaultValue) const
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
void setData(const QVariant &userData)
QList< Key > keys() const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
QString fromLatin1(const char *str, int size)
void setObjectName(const QString &name)
QObject * instance()
QObject * parent() const const
An interface for plugins delivering KReport elements.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Feb 7 2023 04:17:37 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.