KService

kplugininfo.cpp
1 /*
2  This file is part of the KDE project
3  SPDX-FileCopyrightText: 2003, 2007 Matthias Kretz <[email protected]>
4  SPDX-FileCopyrightText: 2013 Sebastian K├╝gler <[email protected]>
5 
6  SPDX-License-Identifier: LGPL-2.0-only
7 */
8 
9 #include "kplugininfo.h"
10 
11 #include "servicesdebug.h"
12 #include <QDirIterator>
13 #include <QJsonArray>
14 #include <QMimeDatabase>
15 #include <QStandardPaths>
16 
17 #include "ksycoca.h"
18 #include "ksycoca_p.h"
19 #include <KAboutData>
20 #include <KDesktopFile>
21 #include <KPluginMetaData>
22 #include <kservicetypetrader.h>
23 #include <kservicetypefactory_p.h>
24 
25 //#ifndef NDEBUG
26 #define KPLUGININFO_ISVALID_ASSERTION \
27  do { \
28  if (!d) { \
29  qFatal("Accessed invalid KPluginInfo object"); \
30  } \
31  } while (false)
32 //#else
33 //#define KPLUGININFO_ISVALID_ASSERTION
34 //#endif
35 
36 #define GlobalQStringLiteral(name, str) inline QString name() { return QStringLiteral(str); }
37 
38 namespace {
39 
40 GlobalQStringLiteral(s_hiddenKey, "Hidden")
41 GlobalQStringLiteral(s_nameKey, "Name")
42 GlobalQStringLiteral(s_commentKey, "Comment")
43 GlobalQStringLiteral(s_iconKey, "Icon")
44 GlobalQStringLiteral(s_libraryKey, "X-KDE-Library")
45 GlobalQStringLiteral(s_authorKey, "X-KDE-PluginInfo-Author")
46 GlobalQStringLiteral(s_emailKey, "X-KDE-PluginInfo-Email")
47 GlobalQStringLiteral(s_pluginNameKey, "X-KDE-PluginInfo-Name")
48 GlobalQStringLiteral(s_versionKey, "X-KDE-PluginInfo-Version")
49 GlobalQStringLiteral(s_websiteKey, "X-KDE-PluginInfo-Website")
50 GlobalQStringLiteral(s_categoryKey, "X-KDE-PluginInfo-Category")
51 GlobalQStringLiteral(s_licenseKey, "X-KDE-PluginInfo-License")
52 GlobalQStringLiteral(s_dependenciesKey, "X-KDE-PluginInfo-Depends")
53 GlobalQStringLiteral(s_serviceTypesKey, "ServiceTypes")
54 GlobalQStringLiteral(s_xKDEServiceTypes, "X-KDE-ServiceTypes")
55 GlobalQStringLiteral(s_mimeTypeKey, "MimeType")
56 GlobalQStringLiteral(s_formFactorsKey, "X-KDE-FormFactors")
57 GlobalQStringLiteral(s_enabledbyDefaultKey, "X-KDE-PluginInfo-EnabledByDefault")
58 GlobalQStringLiteral(s_enabledKey, "Enabled")
59 
60 // these keys are used in the json metadata
61 GlobalQStringLiteral(s_jsonDescriptionKey, "Description")
62 GlobalQStringLiteral(s_jsonAuthorsKey, "Authors")
63 GlobalQStringLiteral(s_jsonEmailKey, "Email")
64 GlobalQStringLiteral(s_jsonCategoryKey, "Category")
65 GlobalQStringLiteral(s_jsonDependenciesKey, "Dependencies")
66 GlobalQStringLiteral(s_jsonEnabledByDefaultKey, "EnabledByDefault")
67 GlobalQStringLiteral(s_jsonFormFactorsKey, "FormFactors")
68 GlobalQStringLiteral(s_jsonLicenseKey, "License")
69 GlobalQStringLiteral(s_jsonIdKey, "Id")
70 GlobalQStringLiteral(s_jsonVersionKey, "Version")
71 GlobalQStringLiteral(s_jsonWebsiteKey, "Website")
72 GlobalQStringLiteral(s_jsonMimeTypesKey, "MimeTypes")
73 GlobalQStringLiteral(s_jsonKPluginKey, "KPlugin")
74 
75 }
76 
77 class KPluginInfoPrivate : public QSharedData
78 {
79 public:
80  KPluginInfoPrivate()
81  : hidden(false)
82  , pluginenabled(false)
83  , kcmservicesCached(false)
84  {}
85 
86  static QStringList deserializeList(const QString &data);
87 
88 
89  bool hidden : 1;
90  bool pluginenabled : 1;
91  mutable bool kcmservicesCached : 1;
92 
93  KPluginMetaData metaData;
95  KService::Ptr service;
96  mutable QList<KService::Ptr> kcmservices;
97 
99  void setMetaData(const KPluginMetaData &md, bool warnOnOldStyle);
100 };
101 
102 //This comes from KConfigGroupPrivate::deserializeList()
103 QStringList KPluginInfoPrivate::deserializeList(const QString &data)
104 {
105  if (data.isEmpty()) {
106  return QStringList();
107  }
108  if (data == QLatin1String("\\0")) {
109  return QStringList(QString());
110  }
111  QStringList value;
112  QString val;
113  val.reserve(data.size());
114  bool quoted = false;
115  for (int p = 0; p < data.length(); p++) {
116  if (quoted) {
117  val += data[p];
118  quoted = false;
119  } else if (data[p].unicode() == '\\') {
120  quoted = true;
121  } else if (data[p].unicode() == ',' || data[p].unicode() == ';') {
122  val.squeeze(); // release any unused memory
123  value.append(val);
124  val.clear();
125  val.reserve(data.size() - p);
126  } else {
127  val += data[p];
128  }
129  }
130  value.append(val);
131  return value;
132 }
133 
134 // maps the KService, QVariant and KDesktopFile keys to the new KPluginMetaData keys
135 template<typename T, typename Func>
136 static QJsonObject mapToJsonKPluginKey(const QString &name, const QString &description,
137  const QStringList &dependencies, const QStringList &serviceTypes,
138  const QStringList &formFactors, const T &data, Func accessor)
139 {
140  /* Metadata structure is as follows:
141  "KPlugin": {
142  "Name": "Date and Time",
143  "Description": "Date and time by timezone",
144  "Icon": "preferences-system-time",
145  "Authors": { "Name": "Aaron Seigo", "Email": "[email protected]" },
146  "Category": "Date and Time",
147  "Dependencies": [],
148  "EnabledByDefault": "true",
149  "License": "LGPL",
150  "Id": "time",
151  "Version": "1.0",
152  "Website": "http://plasma.kde.org/",
153  "ServiceTypes": ["Plasma/DataEngine"]
154  "FormFactors": ["tablet", "handset"]
155  }
156  */
157  QJsonObject kplugin;
158  kplugin[s_nameKey()] = name;
159  kplugin[s_jsonDescriptionKey()] = description;
160  kplugin[s_iconKey()] = accessor(data, s_iconKey());
161  QJsonObject authors;
162  authors[s_nameKey()] = accessor(data, s_authorKey());
163  authors[s_jsonEmailKey()] = accessor(data, s_emailKey());
164  kplugin[s_jsonAuthorsKey()] = authors;
165  kplugin[s_jsonCategoryKey()] = accessor(data, s_categoryKey());
166  QJsonValue enabledByDefault = accessor(data, s_enabledbyDefaultKey());
167  // make sure that enabledByDefault is bool and not string
168  if (!enabledByDefault.isBool()) {
169  enabledByDefault = enabledByDefault.toString().compare(QLatin1String("true"), Qt::CaseInsensitive) == 0;
170  }
171  kplugin[s_jsonEnabledByDefaultKey()] = enabledByDefault;
172  kplugin[s_jsonLicenseKey()] = accessor(data, s_licenseKey());
173  kplugin[s_jsonIdKey()] = accessor(data, s_pluginNameKey());
174  kplugin[s_jsonVersionKey()] = accessor(data, s_versionKey());
175  kplugin[s_jsonWebsiteKey()] = accessor(data, s_websiteKey());
176  kplugin[s_jsonFormFactorsKey()] = QJsonArray::fromStringList(formFactors);
177  kplugin[s_serviceTypesKey()] = QJsonArray::fromStringList(serviceTypes);
178  kplugin[s_jsonDependenciesKey()] = QJsonArray::fromStringList(dependencies);
179  QJsonValue mimeTypes = accessor(data, s_mimeTypeKey());
180  if (mimeTypes.isString()) {
181  QStringList mimeList = KPluginInfoPrivate::deserializeList(mimeTypes.toString());
182  if (!mimeList.isEmpty()) {
183  mimeTypes = QJsonArray::fromStringList(mimeList);
184  } else {
185  mimeTypes = QJsonValue();
186  }
187  }
188  kplugin[s_jsonMimeTypesKey()] = mimeTypes;
189  return kplugin;
190 }
191 
192 // TODO: KF6 remove
193 static KPluginMetaData fromCompatibilityJson(const QJsonObject &json, const QString &lib,
194  const QString &metaDataFile, bool warnOnOldStyle)
195 {
196  // This is not added to KPluginMetaData(QJsonObject, QString) to ensure that all the compatility code
197  // remains in kservice and does not increase the size of kcoreaddons
198  QStringList serviceTypes = KPluginMetaData::readStringList(json, s_xKDEServiceTypes());
199  if (serviceTypes.isEmpty()) {
200  serviceTypes = KPluginMetaData::readStringList(json, s_serviceTypesKey());
201  }
202  QJsonObject obj = json;
203  QString name = KPluginMetaData::readTranslatedString(json, s_nameKey());
204  if (warnOnOldStyle) {
205  qWarning("Constructing a KPluginInfo object from old style JSON. Please use"
206  " kcoreaddons_desktop_to_json() for \"%s\" instead of kservice_desktop_to_json()"
207  " in your CMake code.",
208  qPrintable(lib));
209  }
210  QString description = KPluginMetaData::readTranslatedString(json, s_commentKey());
211  QStringList formfactors = KPluginMetaData::readStringList(json, s_jsonFormFactorsKey());
212  QJsonObject kplugin = mapToJsonKPluginKey(name, description,
213  KPluginMetaData::readStringList(json, s_dependenciesKey()), serviceTypes, formfactors, json,
214  [](const QJsonObject &o, const QString &key) { return o.value(key); });
215  obj.insert(s_jsonKPluginKey(), kplugin);
216  return KPluginMetaData(obj, lib, metaDataFile);
217 }
218 
219 void KPluginInfoPrivate::setMetaData(const KPluginMetaData& md, bool warnOnOldStyle)
220 {
221  const QJsonObject json = md.rawData();
222  if (!json.contains(s_jsonKPluginKey())) {
223  // "KPlugin" key does not exists -> convert from compatibility mode
224  metaData = fromCompatibilityJson(json, md.fileName(), md.metaDataFileName(), warnOnOldStyle);
225  } else {
226  metaData = md;
227  }
228 }
229 
231  :d(new KPluginInfoPrivate)
232 {
233  d->setMetaData(md, true);
234  if (!d->metaData.isValid()) {
235  d.reset();
236  }
237 }
238 
239 KPluginInfo::KPluginInfo(const QString &filename /*, QStandardPaths::StandardLocation resource*/)
240  : d(new KPluginInfoPrivate)
241 {
242  KDesktopFile file(/*resource,*/ filename);
243 
244  KConfigGroup cg = file.desktopGroup();
245  if (!cg.exists()) {
246  qCWarning(SERVICES) << filename << "has no desktop group, cannot construct a KPluginInfo object from it.";
247  d.reset();
248  return;
249  }
250  d->hidden = cg.readEntry(s_hiddenKey(), false);
251  if (d->hidden) {
252  return;
253  }
254 
255  d->setMetaData(KPluginMetaData(file.fileName()), true);
256  if (!d->metaData.isValid()) {
257  qCWarning(SERVICES) << "Failed to read metadata from .desktop file" << file.fileName();
258  d.reset();
259  }
260 }
261 
262 KPluginInfo::KPluginInfo(const QVariantList &args, const QString &libraryPath)
263  : d(new KPluginInfoPrivate)
264 {
265  const QString metaData = QStringLiteral("MetaData");
266  for (const QVariant &v : args) {
267  if (v.canConvert<QVariantMap>()) {
268  const QVariantMap &m = v.toMap();
269  const QVariant &_metadata = m.value(metaData);
270  if (_metadata.canConvert<QVariantMap>()) {
271  const QVariantMap &map = _metadata.toMap();
272  if (map.value(s_hiddenKey()).toBool()) {
273  d->hidden = true;
274  break;
275  }
276  d->setMetaData(KPluginMetaData(QJsonObject::fromVariantMap(map), libraryPath), true);
277  break;
278  }
279  }
280  }
281  if (!d->metaData.isValid()) {
282  d.reset();
283  }
284 }
285 
286 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 0)
288  : d(new KPluginInfoPrivate)
289 {
290  if (!service) {
291  d = nullptr; // isValid() == false
292  return;
293  }
294  d->service = service;
295  if (service->isDeleted()) {
296  d->hidden = true;
297  return;
298  }
299 
301 
302  QJsonObject json;
303  const auto propertyList = service->propertyNames();
304  for (const QString &key : propertyList) {
305  QVariant::Type t = KSycocaPrivate::self()->serviceTypeFactory()->findPropertyTypeByName(key);
306  if (t == QVariant::Invalid) {
307  t = QVariant::String; // default to string if the type is not known
308  }
309  QVariant v = service->property(key, t);
310  if (v.isValid()) {
311  json[key] = QJsonValue::fromVariant(v);
312  }
313  }
314  // reintroduce the separation between MimeType= and X-KDE-ServiceTypes=
315  // we could do this by modifying KService and KSyCoCa, but as this is only compatibility
316  // code we just query QMimeDatabase whether a ServiceType is a valid MIME type.
317  // TODO: should we also make sure invalid MimeType= entries end up in KPluginMetaData::mimeTypes()?
318  const QStringList services = service->serviceTypes();
319  if (!services.isEmpty()) {
320  QMimeDatabase db;
321  QStringList mimeTypes;
322  mimeTypes.reserve(services.size());
323  QStringList newServiceTypes;
324  newServiceTypes.reserve(services.size());
325  for (const QString& s : services) {
326  if (db.mimeTypeForName(s).isValid()) {
327  mimeTypes << s;
328  } else {
329  newServiceTypes << s;
330  }
331  }
332  json[s_mimeTypeKey()] = QJsonArray::fromStringList(mimeTypes);
333  json[s_xKDEServiceTypes()] = QJsonArray::fromStringList(newServiceTypes);
334  json[s_serviceTypesKey()] = QJsonValue();
335  }
336 
337  d->setMetaData(KPluginMetaData(json, service->library(), service->entryPath()), false);
338  if (!d->metaData.isValid()) {
339  d.reset();
340  }
341 }
342 #endif
343 
345  : d(nullptr) // isValid() == false
346 {
347 }
348 
350 {
351  return d.data() != nullptr;
352 }
353 
355  : d(rhs.d)
356 {
357 }
358 
360 {
361  d = rhs.d;
362  return *this;
363 }
364 
365 bool KPluginInfo::operator==(const KPluginInfo &rhs) const
366 {
367  return d == rhs.d;
368 }
369 
370 bool KPluginInfo::operator!=(const KPluginInfo &rhs) const
371 {
372  return d != rhs.d;
373 }
374 
375 bool KPluginInfo::operator<(const KPluginInfo &rhs) const
376 {
377  if (category() < rhs.category()) {
378  return true;
379  }
380  if (category() == rhs.category()) {
381  return name() < rhs.name();
382  }
383  return false;
384 }
385 
386 bool KPluginInfo::operator>(const KPluginInfo &rhs) const
387 {
388  if (category() > rhs.category()) {
389  return true;
390  }
391  if (category() == rhs.category()) {
392  return name() > rhs.name();
393  }
394  return false;
395 }
396 
397 KPluginInfo::~KPluginInfo()
398 {
399 }
400 
401 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 0)
403 {
404  QList<KPluginInfo> infolist;
405  for (KService::List::ConstIterator it = services.begin();
406  it != services.end(); ++it) {
407  KPluginInfo info(*it);
408  if (info.isValid()) {
409  info.setConfig(config);
410  infolist += info;
411  }
412  }
413  return infolist;
414 }
415 #endif
416 
418 {
419  QList<KPluginInfo> infolist;
420  for (QStringList::ConstIterator it = files.begin(); it != files.end(); ++it) {
421  KPluginInfo info(*it);
422  info.setConfig(config);
423  infolist += info;
424  }
425  return infolist;
426 }
427 
429 {
430  QStringList files;
432  for (const QString &dir : dirs) {
433  QDirIterator it(dir, QStringList() << QStringLiteral("*.desktop"));
434  while (it.hasNext()) {
435  files.append(it.next());
436  }
437  }
438  return fromFiles(files, config);
439 }
440 
442 {
443  KPLUGININFO_ISVALID_ASSERTION;
444  return d->hidden;
445 }
446 
448 {
449  KPLUGININFO_ISVALID_ASSERTION;
450  //qDebug() << Q_FUNC_INFO;
451  d->pluginenabled = enabled;
452 }
453 
455 {
456  KPLUGININFO_ISVALID_ASSERTION;
457  //qDebug() << Q_FUNC_INFO;
458  return d->pluginenabled;
459 }
460 
462 {
463  KPLUGININFO_ISVALID_ASSERTION;
464  //qDebug() << Q_FUNC_INFO;
465  return d->metaData.isEnabledByDefault();
466 }
467 
469 {
470  KPLUGININFO_ISVALID_ASSERTION;
471  return d->metaData.name();
472 }
473 
475 {
476  KPLUGININFO_ISVALID_ASSERTION;
477  return d->metaData.description();
478 }
479 
481 {
482  KPLUGININFO_ISVALID_ASSERTION;
483  return d->metaData.iconName();
484 }
485 
487 {
488  KPLUGININFO_ISVALID_ASSERTION;
489  return d->metaData.metaDataFileName();
490 }
491 
493 {
494  KPLUGININFO_ISVALID_ASSERTION;
495  const QList<KAboutPerson> &authors = d->metaData.authors();
496  return authors.isEmpty() ? QString() : authors[0].name();
497 }
498 
500 {
501  KPLUGININFO_ISVALID_ASSERTION;
502  const QList<KAboutPerson> &authors = d->metaData.authors();
503  return authors.isEmpty() ? QString() : authors[0].emailAddress();
504 }
505 
507 {
508  KPLUGININFO_ISVALID_ASSERTION;
509  return d->metaData.category();
510 }
511 
513 {
514  KPLUGININFO_ISVALID_ASSERTION;
515  return d->metaData.formFactors();
516 }
517 
519 {
520  KPLUGININFO_ISVALID_ASSERTION;
521  return d->metaData.pluginId();
522 }
523 
525 {
526  KPLUGININFO_ISVALID_ASSERTION;
527  return d->metaData.fileName();
528 }
529 
531 {
532  KPLUGININFO_ISVALID_ASSERTION;
533  return d->metaData.version();
534 }
535 
537 {
538  KPLUGININFO_ISVALID_ASSERTION;
539  return d->metaData.website();
540 }
541 
543 {
544  KPLUGININFO_ISVALID_ASSERTION;
545  return d->metaData.license();
546 }
547 
549 {
550  KPLUGININFO_ISVALID_ASSERTION;
551  return d->metaData.dependencies();
552 }
553 
555 {
556  KPLUGININFO_ISVALID_ASSERTION;
557  // KService/KPluginInfo include the MIME types in serviceTypes()
558  return d->metaData.serviceTypes() + d->metaData.mimeTypes();
559 }
560 
561 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 70)
563 {
564  KPLUGININFO_ISVALID_ASSERTION;
565  return d->service;
566 }
567 #endif
568 
570 {
571  KPLUGININFO_ISVALID_ASSERTION;
572  if (!d->kcmservicesCached) {
573  d->kcmservices = KServiceTypeTrader::self()->query(QStringLiteral("KCModule"), QLatin1Char('\'') + pluginName() +
574  QLatin1String("' in [X-KDE-ParentComponents]"));
575  //qDebug() << "found" << d->kcmservices.count() << "offers for" << d->pluginName;
576 
577  d->kcmservicesCached = true;
578  }
579 
580  return d->kcmservices;
581 }
582 
584 {
585  KPLUGININFO_ISVALID_ASSERTION;
586  d->config = config;
587 }
588 
590 {
591  KPLUGININFO_ISVALID_ASSERTION;
592  return d->config;
593 }
594 
596 {
597  KPLUGININFO_ISVALID_ASSERTION;
598  if (d->service) {
599  return d->service->property(key);
600  }
601  QVariant result = d->metaData.rawData().value(key).toVariant();
602  if (result.isValid()) {
604  const QVariant::Type t = KSycocaPrivate::self()->serviceTypeFactory()->findPropertyTypeByName(key);
605 
606  //special case if we want a stringlist: split values by ',' or ';' and construct the list
607  if (t == QVariant::StringList) {
608  if (result.canConvert<QString>()) {
609  result = KPluginInfoPrivate::deserializeList(result.toString());
610  } else if (result.canConvert<QVariantList>()) {
611  const QVariantList list = result.toList();
612  QStringList newResult;
613  for (const QVariant &value : list) {
614  newResult += value.toString();
615  }
616  result = newResult;
617  } else
618  qCWarning(SERVICES) << "Cannot interpret" << result << "into a string list";
619  }
620  return result;
621  }
622 
623  // If the key was not found check compatibility for old key names and print a warning
624  // These warnings should only happen if JSON was generated with kcoreaddons_desktop_to_json
625  // but the application uses KPluginTrader::query() instead of KPluginLoader::findPlugins()
626  // TODO: KF6 remove
627 #define RETURN_WITH_DEPRECATED_WARNING(ret) \
628  qWarning("Calling KPluginInfo::property(\"%s\") is deprecated, use KPluginInfo::" #ret " in \"%s\" instead.", qPrintable(key), qPrintable(d->metaData.fileName()));\
629  return ret;
630  if (key == s_authorKey()) {
631  RETURN_WITH_DEPRECATED_WARNING(author());
632  } else if (key == s_categoryKey()) {
633  RETURN_WITH_DEPRECATED_WARNING(category());
634  } else if (key == s_commentKey()) {
635  RETURN_WITH_DEPRECATED_WARNING(comment());
636  } else if (key == s_dependenciesKey()) {
637  RETURN_WITH_DEPRECATED_WARNING(dependencies());
638  } else if (key == s_emailKey()) {
639  RETURN_WITH_DEPRECATED_WARNING(email());
640  } else if (key == s_enabledbyDefaultKey()) {
641  RETURN_WITH_DEPRECATED_WARNING(isPluginEnabledByDefault());
642  } else if (key == s_libraryKey()) {
643  RETURN_WITH_DEPRECATED_WARNING(libraryPath());
644  } else if (key == s_licenseKey()) {
645  RETURN_WITH_DEPRECATED_WARNING(license());
646  } else if (key == s_nameKey()) {
647  RETURN_WITH_DEPRECATED_WARNING(name());
648  } else if (key == s_pluginNameKey()) {
649  RETURN_WITH_DEPRECATED_WARNING(pluginName());
650  } else if (key == s_serviceTypesKey()) {
651  RETURN_WITH_DEPRECATED_WARNING(serviceTypes());
652  } else if (key == s_versionKey()) {
653  RETURN_WITH_DEPRECATED_WARNING(version());
654  } else if (key == s_websiteKey()) {
655  RETURN_WITH_DEPRECATED_WARNING(website());
656  } else if (key == s_xKDEServiceTypes()) {
657  RETURN_WITH_DEPRECATED_WARNING(serviceTypes());
658  } else if (key == s_formFactorsKey()) {
659  RETURN_WITH_DEPRECATED_WARNING(formFactors());
660  }
661 #undef RETURN_WITH_DEPRECATED_WARNING
662  // not a compatibility key -> return invalid QVariant
663  return result;
664 }
665 
666 QVariantMap KPluginInfo::properties() const
667 {
668  return d->metaData.rawData().toVariantMap();
669 }
670 
672 {
673  KPLUGININFO_ISVALID_ASSERTION;
674  //qDebug() << Q_FUNC_INFO;
675  if (config.isValid()) {
676  config.writeEntry(pluginName() + s_enabledKey(), isPluginEnabled());
677  } else {
678  if (!d->config.isValid()) {
679  qCWarning(SERVICES) << "no KConfigGroup, cannot save";
680  return;
681  }
682  d->config.writeEntry(pluginName() + s_enabledKey(), isPluginEnabled());
683  }
684 }
685 
687 {
688  KPLUGININFO_ISVALID_ASSERTION;
689  //qDebug() << Q_FUNC_INFO;
690  if (config.isValid()) {
691  setPluginEnabled(config.readEntry(pluginName() + s_enabledKey(), isPluginEnabledByDefault()));
692  } else {
693  if (!d->config.isValid()) {
694  qCWarning(SERVICES) << "no KConfigGroup, cannot load";
695  return;
696  }
697  setPluginEnabled(d->config.readEntry(pluginName() + s_enabledKey(), isPluginEnabledByDefault()));
698  }
699 }
700 
702 {
703  //qDebug() << Q_FUNC_INFO;
705 }
706 
707 uint qHash(const KPluginInfo &p)
708 {
709  return qHash(reinterpret_cast<quint64>(p.d.data()));
710 }
711 
713 {
714  return KPluginInfo(md);
715 }
716 
718 {
719  KPLUGININFO_ISVALID_ASSERTION;
720  return d->metaData;
721 }
722 
724 {
725  return info.toMetaData();
726 }
727 
729 {
730  KPluginInfo::List ret;
731  ret.reserve(list.size());
732  for(const KPluginMetaData &md : list) {
734  }
735  return ret;
736 }
737 
739 {
741  ret.reserve(list.size());
742  for(const KPluginInfo &info : list) {
743  ret.append(info.toMetaData());
744  }
745  return ret;
746 }
747 
748 
749 #undef KPLUGININFO_ISVALID_ASSERTION
QString next()
bool canConvert(int targetTypeId) const const
KPluginInfo()
Creates an invalid plugin.
QStringList formFactors() const
Information about a plugin.
Definition: kplugininfo.h:32
KDB_EXPORT QStringList deserializeList(const QString &data)
QString category() const
QString fileName() const
QVariant property(const QString &key) const
QString email() const
static KPluginInfo::List fromFiles(const QStringList &files, const KConfigGroup &config=KConfigGroup())
QVariantMap properties() const
QStringList locateAll(QStandardPaths::StandardLocation type, const QString &fileName, QStandardPaths::LocateOptions options)
void append(const T &value)
static KPluginInfo fromMetaData(const KPluginMetaData &meta)
static KServiceTypeTrader * self()
This is a static pointer to the KServiceTypeTrader singleton.
QList< QVariant > toList() const const
QJsonObject fromVariantMap(const QVariantMap &map)
bool isPluginEnabled() const
void reserve(int alloc)
KService::Ptr service() const
QString entryPath() const
static KPluginInfo::List fromKPartsInstanceName(const QString &componentName, const KConfigGroup &config=KConfigGroup())
int size() const const
bool isValid() const
Returns whether the object is valid.
QString license() const
QString comment() const
T value() const const
void writeEntry(const QString &key, const QVariant &value, WriteConfigFlags pFlags=Normal)
bool operator<(const KPluginInfo &rhs) const
Less than relation comparing the categories and if they are the same using the names.
QString version() const
bool isValid() const
KPluginMetaData toMetaData() const
int size() const const
KSharedConfigPtr config()
QJsonValue fromVariant(const QVariant &variant)
void clear()
QStringList serviceTypes() const
QStringList dependencies() const
void load(const KConfigGroup &config=KConfigGroup())
Load the state of the plugin - enabled or not.
void append(const T &value)
QString toString() const const
KCOREADDONS_EXPORT void setMetaData(const MetaDataMap &metaData, QMimeData *mimeData)
QString metaDataFileName() const
bool exists() const
bool operator!=(const KPluginInfo &rhs) const
Compares two objects whether they don&#39;t share the same data.
void setPluginEnabled(bool enabled)
Set whether the plugin is currently loaded.
CaseInsensitive
bool isEmpty() const const
static QString readTranslatedString(const QJsonObject &jo, const QString &key, const QString &defaultValue=QString())
QList< KService::Ptr > kcmServices() const
bool isEmpty() const const
void defaults()
Restore defaults (enabled or not).
bool contains(const QString &key) const const
QJsonObject rawData() const
bool operator==(const KPluginInfo &rhs) const
Compares two objects whether they share the same data.
KConfigGroup config() const
static QStringList readStringList(const QJsonObject &jo, const QString &key)
QMimeType mimeTypeForName(const QString &nameOrAlias) const const
QStringList mimeTypes(Types)
QList::iterator end()
QString name() const
void reserve(int size)
QString website() const
bool isString() const const
bool operator>(const KPluginInfo &rhs) const
Greater than relation comparing the categories and if they are the same using the names...
bool isValid() const const
bool isPluginEnabledByDefault() const
void save(KConfigGroup config=KConfigGroup())
Save state of the plugin - enabled or not.
const QChar * unicode() const const
QString libraryPath() const
KService::List query(const QString &servicetype, const QString &constraint=QString()) const
The main function in the KServiceTypeTrader class.
QMap< QString, QVariant > toMap() const const
QString icon() const
void setConfig(const KConfigGroup &config)
Set the KConfigGroup to use for load()ing and save()ing the configuration.
typedef ConstIterator
int length() const const
void reserve(int size)
bool isValid() const const
QJsonValue value(const QString &key) const const
bool isHidden() const
KPluginInfo & operator=(const KPluginInfo &rhs)
Copies the KPluginInfo object to share the data with copy.
QString author() const
bool hasNext() const const
int size() const const
int compare(const QString &other, Qt::CaseSensitivity cs) const const
QString toString() const const
QJsonObject::iterator insert(const QString &key, const QJsonValue &value)
T readEntry(const QString &key, const T &aDefault) const
static KSycoca * self()
Get or create the only instance of KSycoca (read-only)
Definition: ksycoca.cpp:355
QList::iterator begin()
void squeeze()
static KPluginInfo::List fromServices(const KService::List &services, const KConfigGroup &config=KConfigGroup())
bool isBool() const const
QString pluginName() const
QJsonArray fromStringList(const QStringList &list)
void ensureCacheValid()
Ensures the ksycoca database is up to date.
Definition: ksycoca.cpp:801
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Mon Jan 25 2021 22:53:08 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.