1 /*
2     This file is part of the KDE project
3     SPDX-FileCopyrightText: 2003, 2007 Matthias Kretz <kretz@kde.org>
4 
5     SPDX-License-Identifier: LGPL-2.0-only
6 */
7 
8 #ifndef KPLUGININFO_H
9 #define KPLUGININFO_H
10 
11 #include <QExplicitlySharedDataPointer>
12 #include <QString>
13 #include <QStringList>
14 
15 #include <KConfigGroup>
16 #include <QList>
17 #include <kservice.h>
18 
19 class KPluginMetaData;
20 class KPluginInfoPrivate;
21 
22 /**
23  * @class KPluginInfo kplugininfo.h <KPluginInfo>
24  *
25  * Information about a plugin.
26  *
27  * This holds all the information about a plugin there is. It's used for the
28  * user to decide whether he wants to use this plugin or not.
29  *
30  * @author Matthias Kretz <kretz@kde.org>
31  */
32 class KSERVICE_EXPORT KPluginInfo
33 {
34 public:
35     /**
36      * A list of KPluginInfo objects.
37      */
38     typedef QList<KPluginInfo> List;
39 
40     /**
41      * Read plugin info from @p filename.
42      *
43      * The file should be of the following form:
44      * \verbatim
45        [Desktop Entry]
46        Icon=mypluginicon
47        Type=Service
48        X-KDE-ServiceTypes=KPluginInfo
49 
50        Name=User Visible Name
51        Comment=Description of what the plugin does
52 
53        X-KDE-PluginInfo-Author=Author's Name
54        X-KDE-PluginInfo-Email=author@foo.bar
55        X-KDE-PluginInfo-Name=internalname
56        X-KDE-PluginInfo-Version=1.1
57        X-KDE-PluginInfo-Website=http://www.plugin.org/
58        X-KDE-PluginInfo-Category=playlist
59        X-KDE-PluginInfo-Depends=plugin1,plugin3
60        X-KDE-PluginInfo-License=GPL
61        X-KDE-PluginInfo-EnabledByDefault=true
62        \endverbatim
63      * The Name and Comment fields must always be present.
64      *
65      * The "X-KDE-PluginInfo" keys you may add further entries which
66      * will be available using property(). The Website,Category,Require
67      * keys are optional.
68      * For EnabledByDefault look at isPluginEnabledByDefault.
69      *
70      * @param filename  The filename of the .desktop file.
71      * @param resource  If filename is relative, you need to specify a resource type
72      * (e.g. "service", "apps"... KStandardDirs). Otherwise,
73      * resource isn't used.
74      */
75     explicit KPluginInfo(const QString &filename /*, QStandardPaths::StandardLocation resource = ...? GenericDataLocation + services ? Is this used? */);
76 
77 #if KSERVICE_ENABLE_DEPRECATED_SINCE(5, 88)
78     /**
79      * Read plugin info from a KService object.
80      *
81      * The .desktop file should look like this:
82      * \verbatim
83        [Desktop Entry]
84        Icon=mypluginicon
85        Type=Service
86        X-KDE-ServiceTypes=KPluginInfo
87 
88        X-KDE-PluginInfo-Author=Author's Name
89        X-KDE-PluginInfo-Email=author@foo.bar
90        X-KDE-PluginInfo-Name=internalname
91        X-KDE-PluginInfo-Version=1.1
92        X-KDE-PluginInfo-Website=http://www.plugin.org/
93        X-KDE-PluginInfo-Category=playlist
94        X-KDE-PluginInfo-Depends=plugin1,plugin3
95        X-KDE-PluginInfo-License=GPL
96        X-KDE-PluginInfo-EnabledByDefault=true
97 
98        Name=User Visible Name
99        Comment=Description of what the plugin does
100        \endverbatim
101      * In the first three entries the Icon entry is optional.
102      * @deprecated since 5.0, use (Q|K)PluginLoader instead and build the
103      * metadata into the plugin using K_PLUGIN_CLASS_WITH_JSON( ..., "mypluginmetadata.json")
104      * @deprecated since 5.88, use QPluginLoader/KPluginMetaData instead and build the
105      * metadata into the plugins using K_PLUGIN_CLASS_WITH_JSON( ..., "mypluginmetadata.json")
106      */
107     KSERVICE_DEPRECATED_VERSION(5, 88, "see API docs")
108     explicit KPluginInfo(const KService::Ptr service);
109 #endif
110 
111     /**
112      * Read plugin info from arguments passed to the plugin. These arguments should contain
113      * the plugin's metadata (as read from QPluginLoader::metaData(). This constructor uses
114      * the metadata read from the QVariantList. It reads the first QVariantMap it finds in a
115      * field called "MetaData".
116      *
117      * Use (Q|K)PluginLoader and build the metadata into the plugin using
118      * K_PLUGIN_CLASS_WITH_JSON( ..., "mypluginmetadata.json")
119      *
120      * You can use the "desktoptojson tool to generate a .json file from your .desktop file.
121      * The .json file should look like this:
122      *
123      * \verbatim
124         {
125             "Comment": "Date and time by timezone",
126             "Icon": "preferences-system-time",
127             "Name": "Date and Time",
128             "Type": "Service",
129             "X-KDE-Library": "plasma_engine_time",
130             "X-KDE-PluginInfo-Author": "Aaron Seigo",
131             "X-KDE-PluginInfo-Category": "Date and Time",
132             "X-KDE-PluginInfo-Depends": [
133             ],
134             "X-KDE-PluginInfo-Email": "aseigo@kde.org",
135             "X-KDE-PluginInfo-EnabledByDefault": true,
136             "X-KDE-PluginInfo-License": "LGPL",
137             "X-KDE-PluginInfo-Name": "time",
138             "X-KDE-PluginInfo-Version": "1.0",
139             "X-KDE-PluginInfo-Website": "http://plasma.kde.org/",
140             "X-KDE-ServiceTypes": [
141                 "Plasma/DataEngine"
142             ],
143             "X-KDE-FormFactors": [
144                 "tablet",
145                 "handset"
146             ]
147         }
148        \endverbatim
149      * @param args QVariantList with arguments, should contain a QVariantMap, keyed "MetaData"
150      * as provided by QPluginLoader::metaData()
151      * @param libraryPath The path to the plugin file on disk
152      *
153      * \see K_PLUGIN_CLASS_WITH_JSON()
154      * \see KPluginFactory::factory()
155      * @since 5.0
156      */
157     explicit KPluginInfo(const QVariantList &args, const QString &libraryPath = QString());
158 
159     /**
160      * Read plugin info from a KPluginMetaData object.
161      *
162      * @param md The KPluginMetaData to read the information from
163      * @see K_PLUGIN_CLASS_WITH_JSON()
164      * @see KPluginLoader
165      * @since 5.5
166      */
167     explicit KPluginInfo(const KPluginMetaData &md);
168 
169     /**
170      * Creates an invalid plugin.
171      *
172      * \see isValid
173      */
174     KPluginInfo();
175 
176     ~KPluginInfo();
177 
178 #if KSERVICE_ENABLE_DEPRECATED_SINCE(5, 88)
179     /**
180      * @return A list of KPluginInfo objects constructed from a list of
181      * KService objects. If you get a trader offer of the plugins you want
182      * to use you can just pass them to this function.
183      *
184      * @param services The list of services to construct the list of KPluginInfo objects from
185      * @param config The config group where to save/load whether the plugin is enabled/disabled
186      * @deprecated since 5.88, use QPluginLoader/KPluginMetaData instead and build the
187      * metadata into the plugins using K_PLUGIN_CLASS_WITH_JSON( ..., "mypluginmetadata.json")
188      */
189     KSERVICE_DEPRECATED_VERSION(5, 88, "see API docs")
190     static KPluginInfo::List fromServices(const KService::List &services, const KConfigGroup &config = KConfigGroup());
191 #endif
192 
193     /**
194      * @return A list of KPluginInfo objects constructed from a list of
195      * filenames. If you make a lookup using, for example,
196      * KStandardDirs::findAllResources() you pass the list of files to this
197      * function.
198      *
199      * @param files The list of files to construct the list of KPluginInfo objects from
200      * @param config The config group where to save/load whether the plugin is enabled/disabled
201      */
202     static KPluginInfo::List fromFiles(const QStringList &files, const KConfigGroup &config = KConfigGroup());
203 
204 #if KSERVICE_ENABLE_DEPRECATED_SINCE(5, 81)
205     /**
206      * @return A list of KPluginInfo objects for the KParts plugins of a
207      * component.
208      *
209      * @param componentName Use the component name to look up all KParts plugins for it.
210      * @param config The config group where to save/load whether the plugin is enabled/disabled
211      * @deprecated since 5.81, removed for lack of usage, KParts loads the plugins all by itself
212      */
213     KSERVICE_DEPRECATED_VERSION(5, 81, "Removed for lack of usage, KParts plugins don't use this anymore (or never did)")
214     static KPluginInfo::List fromKPartsInstanceName(const QString &componentName, const KConfigGroup &config = KConfigGroup());
215 #endif
216 
217     /**
218      * @return Whether the plugin should be hidden.
219      */
220     bool isHidden() const;
221 
222     /**
223      * Set whether the plugin is currently loaded.
224      *
225      * @see isPluginEnabled()
226      * @see save()
227      */
228     void setPluginEnabled(bool enabled);
229 
230     /**
231      * @return Whether the plugin is currently loaded.
232      *
233      * @see setPluginEnabled()
234      * @see load()
235      */
236     bool isPluginEnabled() const;
237 
238     /**
239      * @return The default value whether the plugin is enabled or not.
240      * Defaults to the value set in the desktop file, or if that isn't set
241      * to false.
242      */
243     bool isPluginEnabledByDefault() const;
244 
245     /**
246      * @return The value associated to the @p key. You can use it if you
247      *         want to read custom values. To do this you need to define
248      *         your own servicetype and add it to the ServiceTypes keys.
249      */
250     QVariant property(const QString &key) const;
251 
252     /**
253      * @return All properties of this object. This can be used to read custom values.
254      * @since 5.3
255      * @see KPluginInfo::property()
256      */
257     QVariantMap properties() const;
258 
259     /**
260      * @return The user visible name of the plugin.
261      */
262     QString name() const;
263 
264     /**
265      * @return A comment describing the plugin.
266      */
267     QString comment() const;
268 
269     /**
270      * @return The iconname for this plugin
271      */
272     QString icon() const;
273 
274     /**
275      * @return The file containing the information about the plugin.
276      */
277     QString entryPath() const;
278 
279     /**
280      * @return The author of this plugin.
281      */
282     QString author() const;
283 
284     /**
285      * @return The email address of the author.
286      */
287     QString email() const;
288 
289     /**
290      * @return The category of this plugin (e.g. playlist/skin).
291      */
292     QString category() const;
293 
294     /**
295      * @return The internal name of the plugin (for KParts Plugins this is
296      * the same name as set in the .rc file).
297      */
298     QString pluginName() const;
299 
300     /**
301      * @return The version of the plugin.
302      */
303     QString version() const;
304 
305     /**
306      * @return The website of the plugin/author.
307      */
308     QString website() const;
309 
310     /**
311      * @return The license keyword of this plugin.
312      */
313     QString license() const;
314 
315 #if KSERVICE_ENABLE_DEPRECATED_SINCE(5, 79)
316 #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 79)
317     /**
318      * @return A list of plugins required for this plugin to be enabled. Use
319      *         the pluginName in this list.
320      * @deprecated Since 5.79, plugin dependencies are deprecated and will be removed in KF6
321      */
322     KSERVICE_DEPRECATED_VERSION(5, 79, "Plugin dependencies are deprecated and will be removed in KF6")
323     QStringList dependencies() const;
324 #endif
325 #endif
326 
327     /**
328      * @return A list of ServiceTypes this plugin offers
329      * @since 5.0
330      */
331     QStringList serviceTypes() const;
332 
333     /**
334      * @return A list of FormFactors this plugin offers, corresponds to the
335      * "X-KDE-FormFactors" value in a .desktop service file, or to the "FormFactors"
336      * value in the "KPlugin" block of the json metadata. Formfactor values are
337      * freestyle, common values are "desktop", "handset", "tablet", "mediacenter".
338      * Values are comma-separated.
339      * @since 5.14
340      */
341     QStringList formFactors() const;
342 
343     /**
344      * @return The absolute path of the plugin on disk. This can be used to load the plugin from, using
345      * KPluginLoader or QPluginLoader
346      * @since 5.0
347      */
348     QString libraryPath() const;
349     // visibility check set to a later version because the BUILD variant was used before
350 #if KSERVICE_ENABLE_DEPRECATED_SINCE(5, 88)
351     /**
352      * @return The KService object for this plugin. You might need it if you
353      *         want to read custom values. To do this you need to define
354      *         your own servicetype and add it to the ServiceTypes keys.
355      *         Then you can use the KService::property() method to read your
356      *         keys.
357      *
358      * @see property()
359      *
360      * @deprecated since 5.70, use KPluginMetaData and KPluginLoader(info.libraryPath())
361      */
362     KSERVICE_DEPRECATED_VERSION(5, 70, "Use KPluginMetaData and KPluginLoader(info.libraryPath())")
363     KService::Ptr service() const;
364 #endif
365 
366     /**
367      * @return A list of Service pointers if the plugin installs one or more
368      *         KCModule
369      */
370     QList<KService::Ptr> kcmServices() const;
371 
372     /**
373      * Set the KConfigGroup to use for load()ing and save()ing the
374      * configuration. This will be overridden by the KConfigGroup passed to
375      * save() or load() (if one is passed).
376      */
377     void setConfig(const KConfigGroup &config);
378 
379     /**
380      * @return If the KPluginInfo object has a KConfig object set return
381      * it, else returns an invalid KConfigGroup.
382      */
383     KConfigGroup config() const;
384 
385     /**
386      * Save state of the plugin - enabled or not.
387      *
388      * @param config    The KConfigGroup holding the information whether
389      *                  plugin is enabled.
390      */
391     void save(KConfigGroup config = KConfigGroup());
392 
393     /**
394      * Load the state of the plugin - enabled or not.
395      *
396      * @param config    The KConfigGroup holding the information whether
397      *                  plugin is enabled.
398      */
399     void load(const KConfigGroup &config = KConfigGroup());
400 
401     /**
402      * Restore defaults (enabled or not).
403      */
404     void defaults();
405 
406     /**
407      * Returns whether the object is valid. Treat invalid KPluginInfo objects like you would
408      * treat a null pointer.
409      */
410     bool isValid() const;
411 
412     /**
413      * Creates a KPluginInfo object that shares the data with \p copy.
414      */
415     KPluginInfo(const KPluginInfo &copy);
416 
417     /**
418      * Copies the KPluginInfo object to share the data with \p copy.
419      */
420     KPluginInfo &operator=(const KPluginInfo &rhs);
421 
422     /**
423      * Compares two objects whether they share the same data.
424      */
425     bool operator==(const KPluginInfo &rhs) const;
426 
427     /**
428      * Compares two objects whether they don't share the same data.
429      */
430     bool operator!=(const KPluginInfo &rhs) const;
431 
432     /**
433      * Less than relation comparing the categories and if they are the same using the names.
434      */
435     bool operator<(const KPluginInfo &rhs) const;
436 
437     /**
438      * Greater than relation comparing the categories and if they are the same using the names.
439      */
440     bool operator>(const KPluginInfo &rhs) const;
441 
442     friend class KPluginTrader;
443 
444     /**
445      * @return a KPluginMetaData object with equivalent meta data.
446      * @since 5.3
447      */
448     KPluginMetaData toMetaData() const;
449 
450     /**
451      * @param info the KPluginInfo object to convert
452      * @return a KPluginMetaData object with equivalent meta data.
453      * @since 5.3
454      */
455     static KPluginMetaData toMetaData(const KPluginInfo &info);
456 
457     /**
458      * @param meta the KPluginMetaData to convert
459      * @return a KPluginInfo object with equivalent meta data.
460      * @since 5.3
461      */
462     static KPluginInfo fromMetaData(const KPluginMetaData &meta);
463 
464     /**
465      * @param list the list of KPluginInfo objects to convert
466      * @return a list of KPluginMetaData objects with equivalent meta data.
467      * @since 5.3
468      */
469     static QVector<KPluginMetaData> toMetaData(const KPluginInfo::List &list);
470 
471     /**
472      * @param list the list of KPluginMetaData objects to convert
473      * @return a list of KPluginInfo objects with equivalent meta data.
474      * @since 5.3
475      */
476     static KPluginInfo::List fromMetaData(const QVector<KPluginMetaData> &list);
477 
478 private:
479     friend KSERVICE_EXPORT uint qHash(const KPluginInfo &);
480     QExplicitlySharedDataPointer<KPluginInfoPrivate> d;
481 };
482 
483 KSERVICE_EXPORT uint qHash(const KPluginInfo &);
484 
485 #endif // KPLUGININFO_H
486