From f4937a21b61bf2f214d175d77c432c68f25ead21 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Fri, 7 Feb 2020 16:22:53 +0100 Subject: Allow multiple URL interceptors per engine We may want to have, for example, a QQmlFileSelector and a component-specific interceptor that chooses a theme or similar. Also, make the API public. We want to propose this as alternative to dynamically registering QML files via qmlRegisterType(QUrl, ...). Change-Id: I4a535d3ea556da6710fde816579ec188b3f57099 Reviewed-by: Fabian Kosmale --- src/qml/qml/qqmlengine.cpp | 55 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 13 deletions(-) (limited to 'src/qml/qml/qqmlengine.cpp') diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 725d2e7c7a..c2f8459fb1 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -626,7 +626,7 @@ QQmlEnginePrivate::QQmlEnginePrivate(QQmlEngine *e) #if QT_CONFIG(qml_network) networkAccessManager(nullptr), networkAccessManagerFactory(nullptr), #endif - urlInterceptor(nullptr), scarceResourcesRefCount(0), importDatabase(e), typeLoader(e), + scarceResourcesRefCount(0), importDatabase(e), typeLoader(e), uniqueId(1), incubatorCount(0), incubationController(nullptr) { } @@ -1077,32 +1077,62 @@ QQmlContext *QQmlEngine::rootContext() const return d->rootContext; } +#if QT_DEPRECATED_SINCE(6, 0) /*! \internal + \deprecated This API is private for 5.1 - Sets the \a urlInterceptor to be used when resolving URLs in QML. + Returns the last QQmlAbstractUrlInterceptor. It must not be modified outside + the GUI thread. +*/ +QQmlAbstractUrlInterceptor *QQmlEngine::urlInterceptor() const +{ + Q_D(const QQmlEngine); + return d->urlInterceptors.last(); +} +#endif + +/*! + Adds a \a urlInterceptor to be used when resolving URLs in QML. This also applies to URLs used for loading script files and QML types. - This should not be modifed while the engine is loading files, or URL - selection may be inconsistent. + The URL interceptors should not be modifed while the engine is loading files, + or URL selection may be inconsistent. Multiple URL interceptors, when given, + will be called in the order they were added for each URL. + + QQmlEngine does not take ownership of the interceptor and won't delete it. */ -void QQmlEngine::setUrlInterceptor(QQmlAbstractUrlInterceptor *urlInterceptor) +void QQmlEngine::addUrlInterceptor(QQmlAbstractUrlInterceptor *urlInterceptor) { Q_D(QQmlEngine); - d->urlInterceptor = urlInterceptor; + d->urlInterceptors.append(urlInterceptor); } /*! - \internal - This API is private for 5.1 + Remove a \a urlInterceptor that was previously added using + \l addUrlInterceptor. The URL interceptors should not be modifed while the + engine is loading files, or URL selection may be inconsistent. - Returns the current QQmlAbstractUrlInterceptor. It must not be modified outside - the GUI thread. + This does not delete the interceptor, but merely removes it from the engine. + You can re-use it on the same or a different engine afterwards. */ -QQmlAbstractUrlInterceptor *QQmlEngine::urlInterceptor() const +void QQmlEngine::removeUrlInterceptor(QQmlAbstractUrlInterceptor *urlInterceptor) +{ + Q_D(QQmlEngine); + d->urlInterceptors.removeOne(urlInterceptor); +} + +/*! + Run the current URL interceptors on the given \a url of the given \a type and + return the result. + */ +QUrl QQmlEngine::interceptUrl(const QUrl &url, QQmlAbstractUrlInterceptor::DataType type) const { Q_D(const QQmlEngine); - return d->urlInterceptor; + QUrl result = url; + for (QQmlAbstractUrlInterceptor *interceptor : d->urlInterceptors) + result = interceptor->intercept(result, type); + return result; } void QQmlEnginePrivate::registerFinalizeCallback(QObject *obj, int index) @@ -2199,7 +2229,6 @@ void QQmlEngine::addPluginPath(const QString& path) d->importDatabase.addPluginPath(path); } - /*! Returns the list of directories where the engine searches for native plugins for imported modules (referenced in the \c qmldir file). -- cgit v1.2.3