KCoreAddons

kpluginmetadata.h
1/*
2 This file is part of the KDE project
3
4 SPDX-FileCopyrightText: 2014 Alex Richardson <arichardson.kde@gmail.com>
5 SPDX-FileCopyrightText: 2021 Alexander Lohnau <alexander.lohnau@gmx.de>
6
7 SPDX-License-Identifier: LGPL-2.0-or-later
8*/
9
10#ifndef KPLUGINMETADATA_H
11#define KPLUGINMETADATA_H
12
13#include "kcoreaddons_export.h"
14
15#include <QExplicitlySharedDataPointer>
16#include <QJsonObject>
17#include <QMetaType>
18#include <QString>
19#include <QStringList>
20
21#include <functional>
22
23class QPluginLoader;
24class QStaticPlugin;
25class KPluginMetaDataPrivate;
26class KAboutPerson;
27/**
28 * @class KPluginMetaData kpluginmetadata.h KPluginMetaData
29 *
30 * This class allows easily accessing some standardized values from the JSON metadata that
31 * can be embedded into Qt plugins. Additional plugin-specific metadata can be retrieved by
32 * directly reading from the QJsonObject returned by KPluginMetaData::rawData().
33 *
34 * For embedded metadata, you should not specify an id manually. Instead the id will
35 * be derived from the file basename.
36 *
37 * The following keys will be read from an object "KPlugin" inside the metadata JSON:
38 *
39 * Key | Accessor function | JSON Type
40 * -------------------| -------------------- | ---------------------
41 * Name | name() | string
42 * Description | description() | string
43 * Icon | iconName() | string
44 * Authors | authors() | object array (KAboutPerson)
45 * Category | category() | string
46 * License | license() | string
47 * Copyright | copyrightText() | string
48 * Id | pluginId() | string
49 * Version | version() | string
50 * Website | website() | string
51 * BugReportUrl | bugReportUrl() | string
52 * EnabledByDefault | isEnabledByDefault() | bool
53 * MimeTypes | mimeTypes() | string array
54 * FormFactors | formFactors() | string array
55 * Translators | translators() | object array (KAboutPerson)
56 * OtherContributors | otherContributors() | object array (KAboutPerson)
57 *
58 * The Authors, Translators and OtherContributors keys are expected to be
59 * list of objects that match the structure expected by KAboutPerson::fromJSON().
60 *
61 * An example metadata json file could look like this:
62 * @verbatim
63 {
64 "KPlugin": {
65 "Name": "Date and Time",
66 "Description": "Date and time by timezone",
67 "Icon": "preferences-system-time",
68 "Authors": [ { "Name": "Aaron Seigo", "Email": "aseigo@kde.org" } ],
69 "Category": "Date and Time",
70 "EnabledByDefault": "true",
71 "License": "LGPL",
72 "Version": "1.0",
73 "Website": "https://plasma.kde.org/"
74 }
75 }
76 @endverbatim
77 *
78 * @sa KAboutPerson::fromJSON()
79 * @since 5.1
80 */
81class KCOREADDONS_EXPORT KPluginMetaData
82{
83 Q_GADGET
84 Q_PROPERTY(bool isValid READ isValid CONSTANT)
85 Q_PROPERTY(bool isHidden READ isHidden CONSTANT)
86 Q_PROPERTY(QString fileName READ fileName CONSTANT)
87 Q_PROPERTY(QJsonObject rawData READ rawData CONSTANT)
88 Q_PROPERTY(QString name READ name CONSTANT)
89 Q_PROPERTY(QString description READ description CONSTANT)
90 Q_PROPERTY(QList<KAboutPerson> authors READ authors CONSTANT)
91 Q_PROPERTY(QList<KAboutPerson> translators READ translators CONSTANT)
92 Q_PROPERTY(QList<KAboutPerson> otherContributors READ otherContributors CONSTANT)
93 Q_PROPERTY(QString category READ category CONSTANT)
94 Q_PROPERTY(QString iconName READ iconName CONSTANT)
95 Q_PROPERTY(QString license READ license CONSTANT)
96 Q_PROPERTY(QString licenseText READ licenseText CONSTANT)
97 Q_PROPERTY(QString copyrightText READ copyrightText CONSTANT)
98 Q_PROPERTY(QString pluginId READ pluginId CONSTANT)
99 Q_PROPERTY(QString version READ version CONSTANT)
100 Q_PROPERTY(QString website READ website CONSTANT)
101 Q_PROPERTY(QString bugReportUrl READ bugReportUrl CONSTANT)
102 Q_PROPERTY(QStringList mimeTypes READ mimeTypes CONSTANT)
103 Q_PROPERTY(QStringList formFactors READ formFactors CONSTANT)
104 Q_PROPERTY(bool isEnabledByDefault READ isEnabledByDefault CONSTANT)
105
106public:
107 /**
108 * Options for creating a KPluginMetaData object.
109 * @since 5.91
110 */
112 AllowEmptyMetaData = 1, ///< Plugins with empty metaData are considered valid
113 /**
114 * If KCoreAddons should keep metadata in cache. This makes querying the namespace again faster. Consider using this if you need revalidation of plugins
115 * @since 6.0
116 */
117 CacheMetaData = 2,
118 };
119 Q_DECLARE_FLAGS(KPluginMetaDataOptions, KPluginMetaDataOption)
120 Q_FLAG(KPluginMetaDataOption)
121
122 /** Creates an invalid KPluginMetaData instance */
124
125 /**
126 * Reads the plugin metadata from a QPluginLoader instance. You must call QPluginLoader::setFileName()
127 * or use the appropriate constructor on @p loader before calling this.
128 * @param option Added in 6.0, see enum docs
129 */
130 KPluginMetaData(const QPluginLoader &loader, KPluginMetaDataOptions options = {});
131
132 /**
133 * Reads the plugin metadata from a plugin which can be loaded from @p file.
134 *
135 * Platform-specific library suffixes may be omitted since @p file will be resolved
136 * using the same logic as QPluginLoader.
137 *
138 * @see QPluginLoader::setFileName()
139 */
140 KPluginMetaData(const QString &pluginFile, KPluginMetaDataOptions options = {});
141
142 /**
143 * Creates a KPluginMetaData from a QJsonObject holding the metadata and a file name
144 * This can be used if the data is not retrieved from a Qt C++ plugin library but from some
145 * other source.
146 *
147 * @param metaData the JSON metadata to use for this object
148 * @param pluginFile the file that the plugin can be loaded from
149 *
150 * @since 6.0
151 */
152 KPluginMetaData(const QJsonObject &metaData, const QString &fileName);
153
154 /**
155 * Copy contructor
156 */
158 /**
159 * Copy assignment
160 */
161 KPluginMetaData &operator=(const KPluginMetaData &);
162 /**
163 * Destructor
164 */
166
167 /**
168 * Load a KPluginMetaData instance from a .json file. Unlike the constructor with a single file argument,
169 * this ensure that only JSON format plugins are loaded and any other type is rejected.
170 *
171 * @param jsonFile the .json file to load
172 * @since 5.91
173 */
174 static KPluginMetaData fromJsonFile(const QString &jsonFile);
175
176 /**
177 * @param directory The directory to search for plugins. If a relative path is given for @p directory,
178 * all entries of QCoreApplication::libraryPaths() will be checked with @p directory appended as a
179 * subdirectory. If an absolute path is given only that directory will be searched.
180 * @note Check if the returned KPluginMetaData is valid before continuing to use it.
181 *
182 * @param pluginId The Id of the plugin. The id should be the same as the filename, see KPluginMetaData::pluginId()
183 * @param option Added in 6.0, see enum docs
184 * @since 5.84
185 */
186 static KPluginMetaData findPluginById(const QString &directory, const QString &pluginId, KPluginMetaDataOptions options = {});
187
188 /**
189 * Find all plugins inside @p directory. Only plugins which have JSON metadata will be considered.
190 *
191 * @param directory The directory to search for plugins. If a relative path is given for @p directory,
192 * all entries of QCoreApplication::libraryPaths() will be checked with @p directory appended as a
193 * subdirectory. If an absolute path is given only that directory will be searched.
194 *
195 * @param filter a callback function that returns @c true if the found plugin should be loaded
196 * and @c false if it should be skipped. If this argument is omitted all plugins will be loaded
197 * @param option Weather or not allow plugins with empty metadata to be considered valid
198 *
199 * @return all plugins found in @p directory that fulfil the constraints of @p filter
200 * @since 5.86
201 */
203 findPlugins(const QString &directory, std::function<bool(const KPluginMetaData &)> filter = {}, KPluginMetaDataOptions options = {});
204
205 /**
206 * @return whether this object holds valid information about a plugin.
207 * If this is @c true pluginId() will return a non-empty string.
208 */
209 bool isValid() const;
210
211 /**
212 * @return whether this object should be hidden
213 *
214 * @since 5.8
215 */
216 bool isHidden() const;
217
218 /**
219 * @return the path to the plugin.
220 * When the KPluginMetaData(QJsonObject, QString) constructor is used, the string is not modified.
221 * Otherwise, the path is resolved using QPluginLoader.
222 * For static plugins the fileName is the namespace and pluginId concatenated
223 *
224 * @note It is not guaranteed that this is a valid path to a shared library (i.e. loadable
225 * by QPluginLoader) since the metadata could also refer to a non-C++ plugin.
226 */
227 QString fileName() const;
228
229 /**
230 * @return the full metadata stored inside the plugin file.
231 */
232 QJsonObject rawData() const;
233
234 /**
235 * @return the user visible name of the plugin.
236 */
237 QString name() const;
238
239 /**
240 * @return a short description of the plugin.
241 */
242 QString description() const;
243
244 /**
245 * @return the author(s) of this plugin.
246 */
247 QList<KAboutPerson> authors() const;
248
249 /**
250 * @return the translator(s) of this plugin.
251 *
252 * @since 5.18
253 */
254 QList<KAboutPerson> translators() const;
255
256 /**
257 * @return a list of people that contributed to this plugin (other than the authors and translators).
258 *
259 * @since 5.18
260 */
261 QList<KAboutPerson> otherContributors() const;
262
263 /**
264 * @return the categories of this plugin (e.g. "playlist/skin").
265 */
266 QString category() const;
267
268 /**
269 * @return the icon name for this plugin
270 * @see QIcon::fromTheme()
271 */
272 QString iconName() const;
273
274 /**
275 * @return the short license identifier (e.g. LGPL).
276 * @see KAboutLicense::byKeyword() for retrieving the full license information
277 */
278 QString license() const;
279
280 /**
281 * @return the text of the license, equivalent to KAboutLicense::byKeyword(license()).text()
282 * @since 5.73
283 */
284 QString licenseText() const;
285
286 /**
287 * @return a short copyright statement
288 *
289 * @since 5.18
290 */
291 QString copyrightText() const;
292
293 /**
294 * @return the unique identifier within the namespace of the plugin
295 *
296 * For C++ plugins, this ID is derived from the filename.
297 * It should not be set in the metadata explicitly.
298 *
299 * When using @ref KPluginMetaData::fromJsonFile or @ref KPluginMetaData(QJsonObject, QString),
300 * the "Id" of the "KPlugin" object will be used. If unset, it will be derived
301 * from the filename.
302 */
303 QString pluginId() const;
304
305 /**
306 * @return the version of the plugin.
307 */
308 QString version() const;
309
310 /**
311 * @return the website of the plugin.
312 */
313 QString website() const;
314
315 /**
316 * @return the website where people can report a bug found in this plugin
317 * @since 5.99
318 */
319 QString bugReportUrl() const;
320
321 /**
322 * @return a list of MIME types this plugin can handle (e.g. "application/pdf", "image/png", etc.)
323 * @since 5.16
324 */
325 QStringList mimeTypes() const;
326
327 /**
328 * @return true if this plugin can handle the given mimetype
329 * This is more accurate than mimeTypes().contains(mimeType) because it also
330 * takes MIME type inheritance into account.
331 * @since 5.66
332 */
333 bool supportsMimeType(const QString &mimeType) const;
334
335 /**
336 * @return A string list of formfactors this plugin is useful for, e.g. desktop, handset or mediacenter.
337 * The keys for this are not formally defined, though the above-mentioned values should be used when applicable.
338 *
339 * @since 5.12
340 */
341 QStringList formFactors() const;
342
343 /**
344 * @return whether the plugin should be enabled by default.
345 * This is only a recommendation, applications can ignore this value if they want to.
346 */
347 bool isEnabledByDefault() const;
348
349 /**
350 * Returns @c true if the plugin is enabled in @p config, otherwise returns isEnabledByDefault().
351 * This can be used in conjunction with KPluginWidget.
352 *
353 * The @p config param should be a KConfigGroup object, because KCoreAddons can not depend
354 * on KConfig directly, this parameter is a template.
355 * @param config KConfigGroup where the enabled state is stored
356 * @since 5.89
357 */
358 template<typename T>
359 bool isEnabled(const T &config) const
360 {
361 Q_ASSERT(config.isValid());
362 return config.readEntry(pluginId() + QLatin1String("Enabled"), isEnabledByDefault());
363 }
364
365 /**
366 * @return the string value for @p key from the metadata or @p defaultValue if the key does not exist
367 *
368 * if QString is not the correct type for @p key you should use the other overloads or @ref KPluginMetaData::rawData
369 */
370 QString value(QStringView key, const QString &defaultValue = QString()) const;
371 QString value(const QString &key, const QString &defaultValue = QString()) const; // TODO KF7: remove
372 QString value(const QString &key, const char *ch) const = delete;
373
374 /**
375 * @overload
376 * @since 5.88
377 */
378 bool value(QStringView key, bool defaultValue) const;
379 bool value(const QString &key, bool defaultValue) const; // TODO KF7: remove
380
381 /**
382 * @overload
383 * @since 5.88
384 */
385 int value(QStringView key, int defaultValue) const;
386 int value(const QString &key, int defaultValue) const; // TODO KF7: remove
387
388 /** @return the value for @p key from the metadata or @p defaultValue if the key does not exist.
389 * If the type of @p key is string, a list containing just that string will be returned.
390 * If the type is array, the list will contain one entry for each array member.
391 * @overload
392 * @since 5.88
393 */
394 QStringList value(QStringView key, const QStringList &defaultValue) const;
395 QStringList value(const QString &key, const QStringList &defaultValue) const; // TODO KF7: remove
396
397 /**
398 * @return @c true if this object is equal to @p other, otherwise @c false
399 */
400 bool operator==(const KPluginMetaData &other) const;
401
402 /**
403 * @return @c true if this object is not equal to @p other, otherwise @c false.
404 */
405 inline bool operator!=(const KPluginMetaData &other) const
406 {
407 return !(*this == other);
408 }
409
410 /**
411 * @note for loading plugin the plugin independently of it being static/dynamic
412 * use @ref KPluginFactory::loadFactory or @ref KPluginFactory::instantiatePlugin.
413 * @return true if the instance represents a static plugin
414 * @since 5.89
415 */
416 bool isStaticPlugin() const;
417
418private:
419 KCOREADDONS_NO_EXPORT QStaticPlugin staticPlugin() const;
420 KCOREADDONS_NO_EXPORT QString requestedFileName() const;
421
423 friend class KPluginFactory;
424 friend class KPluginMetaDataPrivate;
425};
426
427inline size_t qHash(const KPluginMetaData &md, size_t seed)
428{
429 return qHash(md.pluginId(), seed);
430}
431
432/// @since 6.0
433KCOREADDONS_EXPORT QDebug operator<<(QDebug debug, const KPluginMetaData &metaData);
434
435Q_DECLARE_TYPEINFO(KPluginMetaData, Q_RELOCATABLE_TYPE);
436Q_DECLARE_OPERATORS_FOR_FLAGS(KPluginMetaData::KPluginMetaDataOptions)
437
438#endif // KPLUGINMETADATA_H
This class is used to store information about a person or developer.
Definition kaboutdata.h:64
KPluginFactory provides a convenient way to provide factory-style plugins.
This class allows easily accessing some standardized values from the JSON metadata that can be embedd...
bool operator!=(const KPluginMetaData &other) const
~KPluginMetaData()
Destructor.
bool isEnabled(const T &config) const
Returns true if the plugin is enabled in config, otherwise returns isEnabledByDefault().
KPluginMetaDataOption
Options for creating a KPluginMetaData object.
KDB_EXPORT KDbVersionInfo version()
bool isValid(QStringView ifopt)
QString name(StandardAction id)
Category category(StandardShortcut id)
KTEXTEDITOR_EXPORT size_t qHash(KTextEditor::Cursor cursor, size_t seed=0) noexcept
QDebug operator<<(QDebug dbg, const PerceptualColor::MultiSpinBoxSection &value)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:08:22 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.