heuristic for finding out what package we want
based on the absolute path requested Change-Id: Ie99bfdc322a409e7ef275499eb8b254d834a98b7
This commit is contained in:
parent
f9e61de51b
commit
ac2f76d9c8
@ -46,6 +46,9 @@ Comment[zh_TW]=Plasma 小程式
|
||||
[PropertyDef::X-Plasma-API]
|
||||
Type=QString
|
||||
|
||||
[PropertyDef::X-Plasma-MinimumAPIVersion]
|
||||
Type=int
|
||||
|
||||
[PropertyDef::X-Plasma-RootPath]
|
||||
Type=QString
|
||||
|
||||
|
@ -53,6 +53,8 @@ AppletQuickItemPrivate::AppletQuickItemPrivate(Plasma::Applet *a, AppletQuickIte
|
||||
{
|
||||
if (!s_engine) {
|
||||
s_engine = new QQmlEngine;
|
||||
PackageUrlInterceptor *interceptor = new PackageUrlInterceptor(s_engine, Plasma::Package());
|
||||
s_engine->setUrlInterceptor(interceptor);
|
||||
}
|
||||
}
|
||||
|
||||
@ -450,11 +452,13 @@ void AppletQuickItem::init()
|
||||
//Initialize the main QML file
|
||||
QQmlEngine *engine = d->qmlObject->engine();
|
||||
|
||||
//TODO: fallback to one engine per applet
|
||||
/*
|
||||
if (d->applet->package().isValid()) {
|
||||
PackageUrlInterceptor *interceptor = new PackageUrlInterceptor(engine, d->applet->package());
|
||||
interceptor->addAllowedPath(d->coronaPackage.path());
|
||||
engine->setUrlInterceptor(interceptor);
|
||||
}
|
||||
}*/
|
||||
|
||||
//Force QtQuickControls to use the "Plasma" style for this engine.
|
||||
//this way is possible to mix QtQuickControls and plasma components in applets
|
||||
|
@ -24,17 +24,36 @@
|
||||
#include <QFile>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#include <Plasma/PluginLoader>
|
||||
|
||||
#include <kdeclarative/kdeclarative.h>
|
||||
|
||||
namespace PlasmaQuick
|
||||
{
|
||||
|
||||
class PackageUrlInterceptorPrivate {
|
||||
public:
|
||||
PackageUrlInterceptorPrivate(QQmlEngine *engine, const Plasma::Package &p)
|
||||
: package(p),
|
||||
engine(engine)
|
||||
{
|
||||
}
|
||||
|
||||
Plasma::Package package;
|
||||
QStringList allowedPaths;
|
||||
QQmlEngine *engine;
|
||||
|
||||
static QHash<QString, Plasma::Package> s_packages;
|
||||
};
|
||||
|
||||
QHash<QString, Plasma::Package> PackageUrlInterceptorPrivate::s_packages = QHash<QString, Plasma::Package>();
|
||||
|
||||
|
||||
PackageUrlInterceptor::PackageUrlInterceptor(QQmlEngine *engine, const Plasma::Package &p)
|
||||
: QQmlAbstractUrlInterceptor(),
|
||||
m_package(p),
|
||||
m_engine(engine)
|
||||
d(new PackageUrlInterceptorPrivate(engine, p))
|
||||
{
|
||||
//m_allowedPaths << m_engine->importPathList();
|
||||
//d->allowedPaths << d->engine->importPathList();
|
||||
}
|
||||
|
||||
PackageUrlInterceptor::~PackageUrlInterceptor()
|
||||
@ -43,29 +62,52 @@ PackageUrlInterceptor::~PackageUrlInterceptor()
|
||||
|
||||
void PackageUrlInterceptor::addAllowedPath(const QString &path)
|
||||
{
|
||||
m_allowedPaths << path;
|
||||
d->allowedPaths << path;
|
||||
}
|
||||
|
||||
void PackageUrlInterceptor::removeAllowedPath(const QString &path)
|
||||
{
|
||||
m_allowedPaths.removeAll(path);
|
||||
d->allowedPaths.removeAll(path);
|
||||
}
|
||||
|
||||
QStringList PackageUrlInterceptor::allowedPaths() const
|
||||
{
|
||||
return m_allowedPaths;
|
||||
return d->allowedPaths;
|
||||
}
|
||||
|
||||
QUrl PackageUrlInterceptor::intercept(const QUrl &path, QQmlAbstractUrlInterceptor::DataType type)
|
||||
{
|
||||
//qDebug() << "Intercepted URL:" << path << type;
|
||||
QString pkgRoot;
|
||||
Plasma::Package package;
|
||||
if (d->package.isValid()) {
|
||||
package = d->package;
|
||||
} else {
|
||||
foreach (const QString &base, QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation)) {
|
||||
pkgRoot = base + "/plasma/plasmoids/";
|
||||
if (path.path().startsWith(pkgRoot)) {
|
||||
const QString pkgName = path.path().mid(pkgRoot.length()).split('/').first();
|
||||
if (PackageUrlInterceptorPrivate::s_packages.contains(pkgName)) {
|
||||
package = PackageUrlInterceptorPrivate::s_packages.value(pkgName);
|
||||
} else {
|
||||
package = Plasma::PluginLoader::self()->loadPackage("Plasma/Applet");
|
||||
package.setPath(pkgName);
|
||||
PackageUrlInterceptorPrivate::s_packages[pkgName] = package;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!package.isValid()) {
|
||||
return path;
|
||||
}
|
||||
|
||||
if (path.scheme() == QStringLiteral("plasmapackage")) {
|
||||
if (d->package.isValid() && path.scheme() == QStringLiteral("plasmapackage")) {
|
||||
//FIXME: this is incorrect but works around a bug in qml in resolution of urls of qmldir files
|
||||
if (type == QQmlAbstractUrlInterceptor::QmldirFile) {
|
||||
return QUrl(m_package.filePath(0, path.path()));
|
||||
return QUrl(d->package.filePath(0, path.path()));
|
||||
} else {
|
||||
return QUrl::fromLocalFile(m_package.filePath(0, path.path()));
|
||||
return QUrl::fromLocalFile(d->package.filePath(0, path.path()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,13 +122,13 @@ QUrl PackageUrlInterceptor::intercept(const QUrl &path, QQmlAbstractUrlIntercept
|
||||
}
|
||||
|
||||
//asked a file inside a package: let's rewrite the url!
|
||||
if (path.path().startsWith(m_package.path())) {
|
||||
if (path.path().startsWith(package.path())) {
|
||||
//qDebug() << "Found URL in package" << path;
|
||||
|
||||
//tries to isolate the relative path asked relative to the contentsPrefixPath: like ui/foo.qml
|
||||
QString relativePath;
|
||||
foreach (const QString &prefix, m_package.contentsPrefixPaths()) {
|
||||
QString root = m_package.path() + prefix;
|
||||
foreach (const QString &prefix, package.contentsPrefixPaths()) {
|
||||
QString root = package.path() + prefix;
|
||||
if (path.path().startsWith(root)) {
|
||||
//obtain a string in the form ui/foo/bar/baz.qml
|
||||
relativePath = path.path().mid(root.length());
|
||||
@ -105,9 +147,9 @@ QUrl PackageUrlInterceptor::intercept(const QUrl &path, QQmlAbstractUrlIntercept
|
||||
//obtain a string in the form foo/bar/baz.qml: ui/ gets discarded
|
||||
const QString &filename = components.join("/");
|
||||
|
||||
//qDebug() << "Returning" << QUrl::fromLocalFile(m_package.filePath(prefixForType(type, filename), filename));
|
||||
//qDebug() << "Returning" << QUrl::fromLocalFile(package.filePath(prefixForType(type, filename), filename));
|
||||
|
||||
QUrl ret = QUrl::fromLocalFile(m_package.filePath(prefixForType(type, filename), filename));
|
||||
QUrl ret = QUrl::fromLocalFile(package.filePath(prefixForType(type, filename), filename));
|
||||
|
||||
if (ret.path().isEmpty()) {
|
||||
return path;
|
||||
@ -116,15 +158,15 @@ QUrl PackageUrlInterceptor::intercept(const QUrl &path, QQmlAbstractUrlIntercept
|
||||
|
||||
//forbid to load random absolute paths
|
||||
} else {
|
||||
if (m_package.allowExternalPaths() || m_package.metadata().property("X-Plasma-RequiredExtensions").toString().contains(QStringLiteral("ExternalScripts"))) {
|
||||
if (package.allowExternalPaths() || package.metadata().property("X-Plasma-RequiredExtensions").toString().contains(QStringLiteral("ExternalScripts"))) {
|
||||
return path;
|
||||
}
|
||||
|
||||
//NOTE: It's needed to build this on the fly because importPathList
|
||||
//can change at runtime
|
||||
QStringList allowedPaths;
|
||||
allowedPaths << m_engine->importPathList();
|
||||
allowedPaths << m_allowedPaths;
|
||||
allowedPaths << d->engine->importPathList();
|
||||
allowedPaths << d->allowedPaths;
|
||||
|
||||
foreach (const QString &allowed, allowedPaths) {
|
||||
//It's a private import
|
||||
@ -132,7 +174,7 @@ QUrl PackageUrlInterceptor::intercept(const QUrl &path, QQmlAbstractUrlIntercept
|
||||
QString pathCheck(path.path());
|
||||
pathCheck = pathCheck.replace(QRegExp(".*org/kde/plasma/private/(.*)/.*"), "org.kde.plasma.\\1");
|
||||
|
||||
if (pathCheck == m_package.metadata().pluginName() || allowed.contains(pathCheck)) {
|
||||
if (pathCheck == package.metadata().pluginName() || allowed.contains(pathCheck)) {
|
||||
return path;
|
||||
} else {
|
||||
continue;
|
||||
@ -144,12 +186,12 @@ QUrl PackageUrlInterceptor::intercept(const QUrl &path, QQmlAbstractUrlIntercept
|
||||
return path;
|
||||
}
|
||||
}
|
||||
qWarning() << "WARNING: Access denied for URL" << path << m_package.path();
|
||||
return path;
|
||||
|
||||
qWarning() << "WARNING: Access denied for URL" << path << package.path();
|
||||
return QUrl::fromLocalFile( allowedPaths.first() + "/org/kde/plasma/accessdenied/qmldir");
|
||||
}
|
||||
|
||||
qWarning() << "WARNING: Access denied for URL" << path << m_package.path();
|
||||
qWarning() << "WARNING: Access denied for URL" << path << package.path();
|
||||
return QUrl();
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,8 @@ class QQmlEngine;
|
||||
namespace PlasmaQuick
|
||||
{
|
||||
|
||||
class PackageUrlInterceptorPrivate;
|
||||
|
||||
//depends from https://codereview.qt-project.org/#change,65626
|
||||
class PLASMAQUICK_EXPORT PackageUrlInterceptor: public QQmlAbstractUrlInterceptor
|
||||
{
|
||||
@ -85,9 +87,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
Plasma::Package m_package;
|
||||
QStringList m_allowedPaths;
|
||||
QQmlEngine *m_engine;
|
||||
PackageUrlInterceptorPrivate *const d;
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user