9 #include "kplugininfo.h" 11 #include "servicesdebug.h" 12 #include <QDirIterator> 14 #include <QMimeDatabase> 15 #include <QStandardPaths> 18 #include "ksycoca_p.h" 20 #include <KDesktopFile> 21 #include <KPluginMetaData> 22 #include <kservicetypetrader.h> 23 #include <kservicetypefactory_p.h> 26 #define KPLUGININFO_ISVALID_ASSERTION \ 29 qFatal("Accessed invalid KPluginInfo object"); \ 36 #define GlobalQStringLiteral(name, str) inline QString name() { return QStringLiteral(str); } 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")
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")
82 , pluginenabled(false)
83 , kcmservicesCached(false)
90 bool pluginenabled : 1;
91 mutable bool kcmservicesCached : 1;
115 for (
int p = 0; p < data.
length(); p++) {
119 }
else if (data[p].unicode() ==
'\\') {
121 }
else if (data[p].unicode() ==
',' || data[p].
unicode() ==
';') {
135 template<
typename T,
typename Func>
138 const QStringList &formFactors,
const T &data, Func accessor)
158 kplugin[s_nameKey()] = name;
159 kplugin[s_jsonDescriptionKey()] = description;
160 kplugin[s_iconKey()] = accessor(data, s_iconKey());
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());
168 if (!enabledByDefault.
isBool()) {
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());
188 kplugin[s_jsonMimeTypesKey()] = mimeTypes;
194 const QString &metaDataFile,
bool warnOnOldStyle)
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.",
212 QJsonObject kplugin = mapToJsonKPluginKey(name, description,
215 obj.
insert(s_jsonKPluginKey(), kplugin);
219 void KPluginInfoPrivate::setMetaData(
const KPluginMetaData& md,
bool warnOnOldStyle)
222 if (!json.
contains(s_jsonKPluginKey())) {
231 :d(new KPluginInfoPrivate)
233 d->setMetaData(md,
true);
234 if (!d->metaData.isValid()) {
240 : d(new KPluginInfoPrivate)
246 qCWarning(SERVICES) << filename <<
"has no desktop group, cannot construct a KPluginInfo object from it.";
250 d->hidden = cg.
readEntry(s_hiddenKey(),
false);
256 if (!d->metaData.isValid()) {
257 qCWarning(SERVICES) <<
"Failed to read metadata from .desktop file" << file.fileName();
263 : d(new KPluginInfoPrivate)
265 const QString metaData = QStringLiteral(
"MetaData");
267 if (v.canConvert<QVariantMap>()) {
268 const QVariantMap &m = v.toMap();
271 const QVariantMap &map = _metadata.
toMap();
272 if (map.value(s_hiddenKey()).toBool()) {
281 if (!d->metaData.isValid()) {
286 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 0) 288 : d(new KPluginInfoPrivate)
295 if (service->isDeleted()) {
303 const auto propertyList = service->propertyNames();
304 for (
const QString &key : propertyList) {
305 QVariant::Type t = KSycocaPrivate::self()->serviceTypeFactory()->findPropertyTypeByName(key);
309 QVariant v = service->property(key, t);
318 const QStringList services = service->serviceTypes();
325 for (
const QString& s : services) {
329 newServiceTypes << s;
337 d->setMetaData(
KPluginMetaData(json, service->library(), service->entryPath()),
false);
338 if (!d->metaData.isValid()) {
351 return d.
data() !=
nullptr;
397 KPluginInfo::~KPluginInfo()
401 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 0) 406 it != services.
end(); ++it) {
432 for (
const QString &dir : dirs) {
443 KPLUGININFO_ISVALID_ASSERTION;
449 KPLUGININFO_ISVALID_ASSERTION;
451 d->pluginenabled = enabled;
456 KPLUGININFO_ISVALID_ASSERTION;
458 return d->pluginenabled;
463 KPLUGININFO_ISVALID_ASSERTION;
465 return d->metaData.isEnabledByDefault();
470 KPLUGININFO_ISVALID_ASSERTION;
471 return d->metaData.name();
476 KPLUGININFO_ISVALID_ASSERTION;
477 return d->metaData.description();
482 KPLUGININFO_ISVALID_ASSERTION;
483 return d->metaData.iconName();
488 KPLUGININFO_ISVALID_ASSERTION;
489 return d->metaData.metaDataFileName();
494 KPLUGININFO_ISVALID_ASSERTION;
501 KPLUGININFO_ISVALID_ASSERTION;
508 KPLUGININFO_ISVALID_ASSERTION;
509 return d->metaData.category();
514 KPLUGININFO_ISVALID_ASSERTION;
515 return d->metaData.formFactors();
520 KPLUGININFO_ISVALID_ASSERTION;
521 return d->metaData.pluginId();
526 KPLUGININFO_ISVALID_ASSERTION;
527 return d->metaData.fileName();
532 KPLUGININFO_ISVALID_ASSERTION;
533 return d->metaData.version();
538 KPLUGININFO_ISVALID_ASSERTION;
539 return d->metaData.website();
544 KPLUGININFO_ISVALID_ASSERTION;
545 return d->metaData.license();
550 KPLUGININFO_ISVALID_ASSERTION;
551 return d->metaData.dependencies();
556 KPLUGININFO_ISVALID_ASSERTION;
558 return d->metaData.serviceTypes() + d->metaData.mimeTypes();
561 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 70) 564 KPLUGININFO_ISVALID_ASSERTION;
571 KPLUGININFO_ISVALID_ASSERTION;
572 if (!d->kcmservicesCached) {
577 d->kcmservicesCached =
true;
580 return d->kcmservices;
585 KPLUGININFO_ISVALID_ASSERTION;
591 KPLUGININFO_ISVALID_ASSERTION;
597 KPLUGININFO_ISVALID_ASSERTION;
599 return d->service->property(key);
601 QVariant result = d->metaData.rawData().value(key).toVariant();
604 const QVariant::Type t = KSycocaPrivate::self()->serviceTypeFactory()->findPropertyTypeByName(key);
609 result = KPluginInfoPrivate::deserializeList(result.
toString());
610 }
else if (result.
canConvert<QVariantList>()) {
611 const QVariantList list = result.
toList();
613 for (
const QVariant &value : list) {
614 newResult += value.toString();
618 qCWarning(SERVICES) <<
"Cannot interpret" << result <<
"into a string list";
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()));\ 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()) {
638 }
else if (key == s_emailKey()) {
639 RETURN_WITH_DEPRECATED_WARNING(
email());
640 }
else if (key == s_enabledbyDefaultKey()) {
642 }
else if (key == s_libraryKey()) {
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()) {
650 }
else if (key == s_serviceTypesKey()) {
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()) {
658 }
else if (key == s_formFactorsKey()) {
661 #undef RETURN_WITH_DEPRECATED_WARNING 668 return d->metaData.rawData().toVariantMap();
673 KPLUGININFO_ISVALID_ASSERTION;
678 if (!d->config.isValid()) {
679 qCWarning(SERVICES) <<
"no KConfigGroup, cannot save";
688 KPLUGININFO_ISVALID_ASSERTION;
693 if (!d->config.isValid()) {
694 qCWarning(SERVICES) <<
"no KConfigGroup, cannot load";
709 return qHash(reinterpret_cast<quint64>(p.d.
data()));
719 KPLUGININFO_ISVALID_ASSERTION;
743 ret.
append(info.toMetaData());
749 #undef KPLUGININFO_ISVALID_ASSERTION
bool canConvert(int targetTypeId) const const
KPluginInfo()
Creates an invalid plugin.
QStringList formFactors() const
Information about a plugin.
KDB_EXPORT QStringList deserializeList(const QString &data)
QVariant property(const QString &key) 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
KService::Ptr service() const
QString entryPath() const
static KPluginInfo::List fromKPartsInstanceName(const QString &componentName, const KConfigGroup &config=KConfigGroup())
bool isValid() const
Returns whether the object is valid.
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.
KPluginMetaData toMetaData() const
KSharedConfigPtr config()
QJsonValue fromVariant(const QVariant &variant)
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)
bool operator!=(const KPluginInfo &rhs) const
Compares two objects whether they don't share the same data.
void setPluginEnabled(bool enabled)
Set whether the plugin is currently loaded.
bool isEmpty() const const
QList< KService::Ptr > kcmServices() const
bool isEmpty() const const
void defaults()
Restore defaults (enabled or not).
bool contains(const QString &key) const const
bool operator==(const KPluginInfo &rhs) const
Compares two objects whether they share the same data.
KConfigGroup config() const
QMimeType mimeTypeForName(const QString &nameOrAlias) const const
QStringList mimeTypes(Types)
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
void setConfig(const KConfigGroup &config)
Set the KConfigGroup to use for load()ing and save()ing the configuration.
bool isValid() const const
QJsonValue value(const QString &key) const const
KPluginInfo & operator=(const KPluginInfo &rhs)
Copies the KPluginInfo object to share the data with copy.
bool hasNext() 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)
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.