Don't enforce metadata.desktop, cleanup constructor
Makes it possible to use plugins that offer a metadata.json file. Define the service type when falling back to the desktop file parser, so the type system is proper. Don't destroy a KPluginMetadata tuple to instanciate it right away. REVIEW: 129102
This commit is contained in:
parent
e06fe3ebdd
commit
0ebe2ca1fa
@ -60,6 +60,13 @@
|
||||
namespace Plasma
|
||||
{
|
||||
|
||||
static KPluginMetaData appletMetadataForDirectory(const QString &path)
|
||||
{
|
||||
return QFile::exists(path + QLatin1String("/metadata.json"))
|
||||
? KPluginMetaData(path + QLatin1String("/metadata.json"))
|
||||
: KPluginMetaData::fromDesktopFile(path + QLatin1String("/metadata.desktop"), { QStringLiteral("plasma-applet.desktop") });
|
||||
}
|
||||
|
||||
Applet::Applet(const KPluginMetaData &info, QObject *parent, uint appletId)
|
||||
: QObject(parent),
|
||||
d(new AppletPrivate(info, appletId, this))
|
||||
@ -88,14 +95,19 @@ Applet::Applet(QObject *parent, const QString &serviceID, uint appletId)
|
||||
|
||||
Applet::Applet(QObject *parentObject, const QVariantList &args)
|
||||
: QObject(0),
|
||||
d(new AppletPrivate(
|
||||
KPluginMetaData(args.count() > 0 && args.first().canConvert<QString>() ? args[0].toString() : QString()),
|
||||
args.count() > 1 ? args[1].toInt() : 0, this))
|
||||
d(new AppletPrivate(KPluginMetaData(), args.count() > 1 ? args[1].toInt() : 0, this))
|
||||
{
|
||||
setParent(parentObject);
|
||||
if (args.count() > 0 && args.first().canConvert<QVariantMap>()) {
|
||||
d->appletDescription = KPluginInfo(args).toMetaData();
|
||||
if (args.count() > 0) {
|
||||
const QVariant first = args.first();
|
||||
if (first.canConvert<QString>()) {
|
||||
d->appletDescription = KPluginMetaData(first.toString());
|
||||
} else if (first.canConvert<QVariantMap>()) {
|
||||
auto metadata = first.toMap().value(QStringLiteral("MetaData")).toMap();
|
||||
d->appletDescription = KPluginMetaData(QJsonObject::fromVariantMap(metadata), {});
|
||||
}
|
||||
}
|
||||
d->icon = d->appletDescription.iconName();
|
||||
|
||||
if (args.contains("org.kde.plasma:force-create")) {
|
||||
setProperty("org.kde.plasma:force-create", true);
|
||||
@ -109,7 +121,7 @@ Applet::Applet(QObject *parentObject, const QVariantList &args)
|
||||
|
||||
Applet::Applet(const QString &packagePath, uint appletId)
|
||||
: QObject(0),
|
||||
d(new AppletPrivate(KPluginMetaData(packagePath + QStringLiteral("/metadata.desktop")), appletId, this))
|
||||
d(new AppletPrivate(appletMetadataForDirectory(packagePath), appletId, this))
|
||||
{
|
||||
d->init(packagePath);
|
||||
d->setupPackage();
|
||||
@ -767,15 +779,14 @@ bool Applet::hasValidAssociatedApplication() const
|
||||
|
||||
Applet *Applet::loadPlasmoid(const QString &path, uint appletId)
|
||||
{
|
||||
const QString metadataPath = path + QLatin1String("/metadata.desktop");
|
||||
if (QFile::exists(metadataPath)) {
|
||||
KService service(metadataPath);
|
||||
const QStringList &types = service.serviceTypes();
|
||||
const KPluginMetaData md = appletMetadataForDirectory(path);
|
||||
if (md.isValid()) {
|
||||
QStringList types = md.serviceTypes();
|
||||
|
||||
if (types.contains(QStringLiteral("Plasma/Containment"))) {
|
||||
return new Containment(path, appletId);
|
||||
return new Containment(md, appletId);
|
||||
} else {
|
||||
return new Applet(path, appletId);
|
||||
return new Applet(md, nullptr, appletId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,8 +79,8 @@ Containment::Containment(QObject *parent, const QVariantList &args)
|
||||
setHasConfigurationInterface(true);
|
||||
}
|
||||
|
||||
Containment::Containment(const QString &packagePath, uint appletId)
|
||||
: Applet(packagePath, appletId),
|
||||
Containment::Containment(const KPluginMetaData &md, uint appletId)
|
||||
: Applet(md, nullptr, appletId),
|
||||
d(new ContainmentPrivate(this))
|
||||
{
|
||||
// WARNING: do not access config() OR globalConfig() in this method!
|
||||
|
@ -330,7 +330,7 @@ private:
|
||||
* @param parent a QObject parent; you probably want to pass in 0
|
||||
* @since 4.3
|
||||
*/
|
||||
Containment(const QString &packagePath, uint appletId);
|
||||
Containment(const KPluginMetaData &md, uint appletId);
|
||||
|
||||
Q_PRIVATE_SLOT(d, void appletDeleted(Plasma::Applet *))
|
||||
Q_PRIVATE_SLOT(d, void triggerShowAddWidgets())
|
||||
|
@ -221,7 +221,7 @@ Applet *PluginLoader::loadApplet(const QString &name, uint appletId, const QVari
|
||||
p.setRequired("mainscript", false);
|
||||
p.setPath(name);
|
||||
|
||||
KPluginMetaData md(p.filePath("metadata"));
|
||||
const KPluginMetaData md(p.metadata());
|
||||
const KPackage::Package fp = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/Applet"), md.value(QStringLiteral("X-Plasma-RootPath")));
|
||||
p.setFallbackPackage(fp);
|
||||
|
||||
@ -234,8 +234,7 @@ Applet *PluginLoader::loadApplet(const QString &name, uint appletId, const QVari
|
||||
if (!applet) {
|
||||
//qCDebug(LOG_PLASMA) << name << "not a C++ applet: Falling back to an empty one";
|
||||
|
||||
QVariantList allArgs;
|
||||
allArgs << p.metadata().fileName() << appletId << args;
|
||||
QVariantList allArgs = { p.metadata().fileName(), appletId, args };
|
||||
|
||||
if (p.metadata().serviceTypes().contains(QStringLiteral("Plasma/Containment"))) {
|
||||
return new Containment(0, allArgs);
|
||||
@ -499,42 +498,22 @@ Package PluginLoader::loadPackage(const QString &packageFormat, const QString &s
|
||||
return Package();
|
||||
}
|
||||
|
||||
KPluginInfo::List PluginLoader::listAppletInfo(const QString &category, const QString &parentApp)
|
||||
QList<KPluginMetaData> PluginLoader::listAppletMetaData(const QString &category, const QString &parentApp)
|
||||
{
|
||||
KPluginInfo::List list;
|
||||
|
||||
if (!d->isDefaultLoader && (parentApp.isEmpty() || parentApp == QCoreApplication::instance()->applicationName())) {
|
||||
list = internalAppletInfo(category);
|
||||
}
|
||||
|
||||
//FIXME: this assumes we are always use packages.. no pure c++
|
||||
std::function<bool(const KPluginMetaData&)> filter;
|
||||
if (category.isEmpty()) { //use all but the excluded categories
|
||||
KConfigGroup group(KSharedConfig::openConfig(), "General");
|
||||
QStringList excluded = group.readEntry("ExcludeCategories", QStringList());
|
||||
|
||||
auto filter = [&excluded, &parentApp](const KPluginMetaData &md) -> bool
|
||||
filter = [excluded, parentApp](const KPluginMetaData &md) -> bool
|
||||
{
|
||||
const QString pa = md.value(QStringLiteral("X-KDE-ParentApp"));
|
||||
return (pa.isEmpty() || pa == parentApp) && !excluded.contains(md.category());
|
||||
};
|
||||
|
||||
//NOTE: it still produces kplugininfos from KServices because some user code expects
|
||||
//info.sevice() to be valid and would crash ohtherwise
|
||||
auto plugins = KPackage::PackageLoader::self()->findPackages(QStringLiteral("Plasma/Applet"), QString(), filter);
|
||||
foreach (auto& md, plugins) {
|
||||
auto pi = KPluginInfo(KService::serviceByStorageId(md.metaDataFileName()));
|
||||
if (!pi.isValid()) {
|
||||
qCWarning(LOG_PLASMA) << "Could not load plugin info for plugin :" << md.pluginId() << "skipping plugin";
|
||||
continue;
|
||||
}
|
||||
list << pi;
|
||||
}
|
||||
return list;
|
||||
|
||||
|
||||
} else { //specific category (this could be an excluded one - is that bad?)
|
||||
|
||||
auto filter = [&category, &parentApp](const KPluginMetaData &md) -> bool
|
||||
filter = [category, parentApp](const KPluginMetaData &md) -> bool
|
||||
{
|
||||
const QString pa = md.value(QStringLiteral("X-KDE-ParentApp"));
|
||||
if (category == QLatin1String("Miscellaneous")) {
|
||||
@ -543,13 +522,24 @@ KPluginInfo::List PluginLoader::listAppletInfo(const QString &category, const QS
|
||||
return (pa.isEmpty() || pa == parentApp) && md.category() == category;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
QList<KPluginMetaData> list;
|
||||
if (!d->isDefaultLoader && (parentApp.isEmpty() || parentApp == QCoreApplication::instance()->applicationName())) {
|
||||
list = KPluginInfo::toMetaData(internalAppletInfo(category)).toList();
|
||||
}
|
||||
return KPackage::PackageLoader::self()->findPackages(QStringLiteral("Plasma/Applet"), QString(), filter);
|
||||
}
|
||||
|
||||
KPluginInfo::List PluginLoader::listAppletInfo(const QString &category, const QString &parentApp)
|
||||
{
|
||||
KPluginInfo::List list;
|
||||
const auto plugins = listAppletMetaData(category, parentApp);
|
||||
|
||||
//NOTE: it still produces kplugininfos from KServices because some user code expects
|
||||
//info.sevice() to be valid and would crash ohtherwise
|
||||
const auto plugins = KPackage::PackageLoader::self()->findPackages(QStringLiteral("Plasma/Applet"), QString(), filter);
|
||||
foreach (auto& md, plugins) {
|
||||
auto pi = KPluginInfo(KService::serviceByStorageId(md.metaDataFileName()));
|
||||
auto pi = md.metaDataFileName().endsWith(".json") ? KPluginInfo(md) : KPluginInfo(KService::serviceByStorageId(md.metaDataFileName()));
|
||||
if (!pi.isValid()) {
|
||||
qCWarning(LOG_PLASMA) << "Could not load plugin info for plugin :" << md.pluginId() << "skipping plugin";
|
||||
continue;
|
||||
@ -558,7 +548,6 @@ KPluginInfo::List PluginLoader::listAppletInfo(const QString &category, const QS
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
KPluginInfo::List PluginLoader::listAppletInfoForMimeType(const QString &mimeType)
|
||||
{
|
||||
|
@ -167,8 +167,31 @@ public:
|
||||
* list containing only applets not specifically
|
||||
* registered to an application.
|
||||
* @return list of applets
|
||||
*
|
||||
* @deprecated use listAppletMetaData. Doesn't support metadata.json packages.
|
||||
**/
|
||||
KPluginInfo::List listAppletInfo(const QString &category, const QString &parentApp = QString());
|
||||
PLASMA_DEPRECATED KPluginInfo::List listAppletInfo(const QString &category, const QString &parentApp = QString());
|
||||
|
||||
/**
|
||||
* Returns a list of all known applets.
|
||||
* This may skip applets based on security settings and ExcludeCategories in the application's config.
|
||||
*
|
||||
* @param category Only applets matchin this category will be returned.
|
||||
* Useful in conjunction with knownCategories.
|
||||
* If "Misc" is passed in, then applets without a
|
||||
* Categories= entry are also returned.
|
||||
* If an empty string is passed in, all applets are
|
||||
* returned.
|
||||
* @param parentApp the application to filter applets on. Uses the
|
||||
* X-KDE-ParentApp entry (if any) in the plugin info.
|
||||
* The default value of QString() will result in a
|
||||
* list containing only applets not specifically
|
||||
* registered to an application.
|
||||
* @return list of applets
|
||||
*
|
||||
* @since 5.28
|
||||
**/
|
||||
QList<KPluginMetaData> listAppletMetaData(const QString &category, const QString &parentApp = QString());
|
||||
|
||||
/**
|
||||
* Returns a list of all known applets associated with a certain mimetype.
|
||||
|
@ -57,7 +57,7 @@ AppletPrivate::AppletPrivate(const KPluginMetaData &info, int uniqueID, Applet *
|
||||
immutability(Types::Mutable),
|
||||
oldImmutability(Types::Mutable),
|
||||
appletDescription(info),
|
||||
icon(appletDescription.isValid() ? appletDescription.iconName() : QString()),
|
||||
icon(appletDescription.iconName()),
|
||||
mainConfig(0),
|
||||
pendingConstraints(Types::NoConstraint),
|
||||
script(0),
|
||||
|
Loading…
Reference in New Issue
Block a user