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
|
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)
|
Applet::Applet(const KPluginMetaData &info, QObject *parent, uint appletId)
|
||||||
: QObject(parent),
|
: QObject(parent),
|
||||||
d(new AppletPrivate(info, appletId, this))
|
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)
|
Applet::Applet(QObject *parentObject, const QVariantList &args)
|
||||||
: QObject(0),
|
: QObject(0),
|
||||||
d(new AppletPrivate(
|
d(new AppletPrivate(KPluginMetaData(), args.count() > 1 ? args[1].toInt() : 0, this))
|
||||||
KPluginMetaData(args.count() > 0 && args.first().canConvert<QString>() ? args[0].toString() : QString()),
|
|
||||||
args.count() > 1 ? args[1].toInt() : 0, this))
|
|
||||||
{
|
{
|
||||||
setParent(parentObject);
|
setParent(parentObject);
|
||||||
if (args.count() > 0 && args.first().canConvert<QVariantMap>()) {
|
if (args.count() > 0) {
|
||||||
d->appletDescription = KPluginInfo(args).toMetaData();
|
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")) {
|
if (args.contains("org.kde.plasma:force-create")) {
|
||||||
setProperty("org.kde.plasma:force-create", true);
|
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)
|
Applet::Applet(const QString &packagePath, uint appletId)
|
||||||
: QObject(0),
|
: QObject(0),
|
||||||
d(new AppletPrivate(KPluginMetaData(packagePath + QStringLiteral("/metadata.desktop")), appletId, this))
|
d(new AppletPrivate(appletMetadataForDirectory(packagePath), appletId, this))
|
||||||
{
|
{
|
||||||
d->init(packagePath);
|
d->init(packagePath);
|
||||||
d->setupPackage();
|
d->setupPackage();
|
||||||
@ -767,15 +779,14 @@ bool Applet::hasValidAssociatedApplication() const
|
|||||||
|
|
||||||
Applet *Applet::loadPlasmoid(const QString &path, uint appletId)
|
Applet *Applet::loadPlasmoid(const QString &path, uint appletId)
|
||||||
{
|
{
|
||||||
const QString metadataPath = path + QLatin1String("/metadata.desktop");
|
const KPluginMetaData md = appletMetadataForDirectory(path);
|
||||||
if (QFile::exists(metadataPath)) {
|
if (md.isValid()) {
|
||||||
KService service(metadataPath);
|
QStringList types = md.serviceTypes();
|
||||||
const QStringList &types = service.serviceTypes();
|
|
||||||
|
|
||||||
if (types.contains(QStringLiteral("Plasma/Containment"))) {
|
if (types.contains(QStringLiteral("Plasma/Containment"))) {
|
||||||
return new Containment(path, appletId);
|
return new Containment(md, appletId);
|
||||||
} else {
|
} 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);
|
setHasConfigurationInterface(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Containment::Containment(const QString &packagePath, uint appletId)
|
Containment::Containment(const KPluginMetaData &md, uint appletId)
|
||||||
: Applet(packagePath, appletId),
|
: Applet(md, nullptr, appletId),
|
||||||
d(new ContainmentPrivate(this))
|
d(new ContainmentPrivate(this))
|
||||||
{
|
{
|
||||||
// WARNING: do not access config() OR globalConfig() in this method!
|
// 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
|
* @param parent a QObject parent; you probably want to pass in 0
|
||||||
* @since 4.3
|
* @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 appletDeleted(Plasma::Applet *))
|
||||||
Q_PRIVATE_SLOT(d, void triggerShowAddWidgets())
|
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.setRequired("mainscript", false);
|
||||||
p.setPath(name);
|
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")));
|
const KPackage::Package fp = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("Plasma/Applet"), md.value(QStringLiteral("X-Plasma-RootPath")));
|
||||||
p.setFallbackPackage(fp);
|
p.setFallbackPackage(fp);
|
||||||
|
|
||||||
@ -234,8 +234,7 @@ Applet *PluginLoader::loadApplet(const QString &name, uint appletId, const QVari
|
|||||||
if (!applet) {
|
if (!applet) {
|
||||||
//qCDebug(LOG_PLASMA) << name << "not a C++ applet: Falling back to an empty one";
|
//qCDebug(LOG_PLASMA) << name << "not a C++ applet: Falling back to an empty one";
|
||||||
|
|
||||||
QVariantList allArgs;
|
QVariantList allArgs = { p.metadata().fileName(), appletId, args };
|
||||||
allArgs << p.metadata().fileName() << appletId << args;
|
|
||||||
|
|
||||||
if (p.metadata().serviceTypes().contains(QStringLiteral("Plasma/Containment"))) {
|
if (p.metadata().serviceTypes().contains(QStringLiteral("Plasma/Containment"))) {
|
||||||
return new Containment(0, allArgs);
|
return new Containment(0, allArgs);
|
||||||
@ -499,42 +498,22 @@ Package PluginLoader::loadPackage(const QString &packageFormat, const QString &s
|
|||||||
return Package();
|
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++
|
//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
|
if (category.isEmpty()) { //use all but the excluded categories
|
||||||
KConfigGroup group(KSharedConfig::openConfig(), "General");
|
KConfigGroup group(KSharedConfig::openConfig(), "General");
|
||||||
QStringList excluded = group.readEntry("ExcludeCategories", QStringList());
|
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"));
|
const QString pa = md.value(QStringLiteral("X-KDE-ParentApp"));
|
||||||
return (pa.isEmpty() || pa == parentApp) && !excluded.contains(md.category());
|
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?)
|
} 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"));
|
const QString pa = md.value(QStringLiteral("X-KDE-ParentApp"));
|
||||||
if (category == QLatin1String("Miscellaneous")) {
|
if (category == QLatin1String("Miscellaneous")) {
|
||||||
@ -543,21 +522,31 @@ KPluginInfo::List PluginLoader::listAppletInfo(const QString &category, const QS
|
|||||||
return (pa.isEmpty() || pa == parentApp) && md.category() == category;
|
return (pa.isEmpty() || pa == parentApp) && md.category() == category;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//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()));
|
|
||||||
if (!pi.isValid()) {
|
|
||||||
qCWarning(LOG_PLASMA) << "Could not load plugin info for plugin :" << md.pluginId() << "skipping plugin";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
list << pi;
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
foreach (auto& md, plugins) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
list << pi;
|
||||||
|
}
|
||||||
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
KPluginInfo::List PluginLoader::listAppletInfoForMimeType(const QString &mimeType)
|
KPluginInfo::List PluginLoader::listAppletInfoForMimeType(const QString &mimeType)
|
||||||
|
@ -167,8 +167,31 @@ public:
|
|||||||
* list containing only applets not specifically
|
* list containing only applets not specifically
|
||||||
* registered to an application.
|
* registered to an application.
|
||||||
* @return list of applets
|
* @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.
|
* 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),
|
immutability(Types::Mutable),
|
||||||
oldImmutability(Types::Mutable),
|
oldImmutability(Types::Mutable),
|
||||||
appletDescription(info),
|
appletDescription(info),
|
||||||
icon(appletDescription.isValid() ? appletDescription.iconName() : QString()),
|
icon(appletDescription.iconName()),
|
||||||
mainConfig(0),
|
mainConfig(0),
|
||||||
pendingConstraints(Types::NoConstraint),
|
pendingConstraints(Types::NoConstraint),
|
||||||
script(0),
|
script(0),
|
||||||
|
Loading…
Reference in New Issue
Block a user