aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dist/changes-5.2.04
-rw-r--r--examples/quick/shared/shared.h2
-rw-r--r--src/qml/qml/qqmlapplicationengine.cpp2
-rw-r--r--src/qml/qml/qqmlfileselector.cpp69
-rw-r--r--src/qml/qml/qqmlfileselector.h12
-rw-r--r--src/qml/qml/qqmlfileselector_p.h14
-rw-r--r--tests/auto/qml/qqmlfileselector/tst_qqmlfileselector.cpp22
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp7
8 files changed, 109 insertions, 23 deletions
diff --git a/dist/changes-5.2.0 b/dist/changes-5.2.0
index 9db8458319..da358191e1 100644
--- a/dist/changes-5.2.0
+++ b/dist/changes-5.2.0
@@ -53,6 +53,10 @@ Third party components
QtQml
------
+- New class QQmlFileSelectors allows applying a QFileSelector to QML assets
+ and types. One is automatically set on QQmlApplicationEngines from now on,
+ plain QQmlEngines must set their own in order to be affected.
+
QtQuick
------
diff --git a/examples/quick/shared/shared.h b/examples/quick/shared/shared.h
index 5cf1333c02..1376459ae7 100644
--- a/examples/quick/shared/shared.h
+++ b/examples/quick/shared/shared.h
@@ -50,7 +50,7 @@
app.setApplicationName(QFileInfo(app.applicationFilePath()).baseName());\
QQuickView view;\
view.connect(view.engine(), SIGNAL(quit()), &app, SLOT(quit()));\
- view.engine()->setUrlInterceptor(new QQmlFileSelector(&view));\
+ new QQmlFileSelector(view.engine(), &view);\
view.setSource(QUrl("qrc:///" #NAME ".qml")); \
view.setResizeMode(QQuickView::SizeRootObjectToView);\
if (QGuiApplication::platformName() == QLatin1String("qnx") || \
diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp
index 3f13f8a140..b4ace17738 100644
--- a/src/qml/qml/qqmlapplicationengine.cpp
+++ b/src/qml/qml/qqmlapplicationengine.cpp
@@ -77,7 +77,7 @@ void QQmlApplicationEnginePrivate::init()
QCoreApplication::installTranslator(qtTranslator);
translators << qtTranslator;
#endif
- q->setUrlInterceptor(new QQmlFileSelector(q));
+ new QQmlFileSelector(q,q);
QCoreApplication::instance()->setProperty("__qml_using_qqmlapplicationengine", QVariant(true));
}
diff --git a/src/qml/qml/qqmlfileselector.cpp b/src/qml/qml/qqmlfileselector.cpp
index 5810e269eb..6ddc2eb2ff 100644
--- a/src/qml/qml/qqmlfileselector.cpp
+++ b/src/qml/qml/qqmlfileselector.cpp
@@ -40,26 +40,30 @@
****************************************************************************/
#include <QtCore/QFileSelector>
+#include <QtQml/QQmlAbstractUrlInterceptor>
+#include <qobjectdefs.h>
#include "qqmlfileselector.h"
#include "qqmlfileselector_p.h"
+#include <QDebug>
QT_BEGIN_NAMESPACE
+typedef QHash<QQmlAbstractUrlInterceptor*, QQmlFileSelector*> interceptorSelectorMap;
+Q_GLOBAL_STATIC(interceptorSelectorMap, interceptorInstances);
/*!
\class QQmlFileSelector
\since 5.2
\inmodule QtQml
- \brief A convenience class for applying a QFileSelector to QML file loading
+ \brief A class for applying a QFileSelector to QML file loading
- QQmlFileSelector is a QQmlAbstractUrlInterceptor which will automatically apply a QFileSelector to
+ QQmlFileSelector will automatically apply a QFileSelector to
qml file and asset paths.
It is used as follows:
\code
QQmlEngine engine;
- QQmlFileSelector selector;
- engine.setUrlInterceptor(&selector);
+ QQmlFileSelector* selector = new QQmlFileSelector(&engine);
\endcode
Then you can swap out files like so:
@@ -86,15 +90,34 @@ QT_BEGIN_NAMESPACE
Your platform may also provide additional selectors for you to use. As specified by QFileSelector,
directories used for selection must start with a '+' character, so you will not accidentally
trigger this feature unless you have directories with such names inside your project.
+
+ If a new QQmlFileSelector is set on the engine, the old one will be replaced. Use
+ \l QQmlFileSelector::get to query or use the existing instance.
*/
/*!
Creates a new QQmlFileSelector, which includes its own QFileSelector.
+ \a engine is the QQmlEngine you wish to apply file selectors too. It will
+ also take ownership of the QQmlFileSelector.
*/
-QQmlFileSelector::QQmlFileSelector(QObject* parent)
+QQmlFileSelector::QQmlFileSelector(QQmlEngine* engine, QObject* parent)
: QObject(*(new QQmlFileSelectorPrivate), parent)
{
+ Q_D(QQmlFileSelector);
+ d->engine = engine;
+ interceptorInstances()->insert(d->myInstance, this);
+ d->engine->setUrlInterceptor(d->myInstance);
+}
+
+QQmlFileSelector::~QQmlFileSelector()
+{
+ Q_D(QQmlFileSelector);
+ if (d->engine && QQmlFileSelector::get(d->engine) == this) {
+ d->engine->setUrlInterceptor(0);
+ d->engine = 0;
+ }
+ interceptorInstances()->remove(d->myInstance);
}
QQmlFileSelectorPrivate::QQmlFileSelectorPrivate()
@@ -102,6 +125,7 @@ QQmlFileSelectorPrivate::QQmlFileSelectorPrivate()
Q_Q(QQmlFileSelector);
ownSelector = true;
selector = new QFileSelector(q);
+ myInstance = new QQmlFileSelectorInterceptor(this);
}
/*!
@@ -127,9 +151,42 @@ void QQmlFileSelector::setSelector(QFileSelector *selector)
}
}
-QUrl QQmlFileSelector::intercept(const QUrl &path, DataType type)
+/*!
+ Adds extra selectors to the current QFileSelector being used. Use this when
+ extra selectors are all you need to avoid having to create your own
+ QFileSelector instance.
+*/
+void QQmlFileSelector::setExtraSelectors(QStringList &strings)
{
Q_D(QQmlFileSelector);
+ d->selector->setExtraSelectors(strings);
+}
+
+/*!
+ Gets the QQmlFileSelector currently active on the target engine.
+*/
+QQmlFileSelector* QQmlFileSelector::get(QQmlEngine* engine)
+{
+ //Since I think we still can't use dynamic_cast inside Qt...
+ QQmlAbstractUrlInterceptor* current = engine->urlInterceptor();
+ if (current && interceptorInstances()->contains(current))
+ return interceptorInstances()->value(current);
+ return 0;
+}
+
+/*!
+ \internal
+*/
+QQmlFileSelectorInterceptor::QQmlFileSelectorInterceptor(QQmlFileSelectorPrivate* pd)
+ : d(pd)
+{
+}
+
+/*!
+ \internal
+*/
+QUrl QQmlFileSelectorInterceptor::intercept(const QUrl &path, DataType type)
+{
if ( type == QQmlAbstractUrlInterceptor::QmldirFile ) //Don't intercept qmldir files, to prevent double interception
return path;
return d->selector->select(path);
diff --git a/src/qml/qml/qqmlfileselector.h b/src/qml/qml/qqmlfileselector.h
index 2be221e0e4..ec9bbc77db 100644
--- a/src/qml/qml/qqmlfileselector.h
+++ b/src/qml/qml/qqmlfileselector.h
@@ -44,23 +44,23 @@
#include <QtCore/QObject>
#include <QtCore/QUrl>
-#include <QtQml/QQmlAbstractUrlInterceptor>
+#include <QtQml/QQmlEngine>
#include <QtQml/qtqmlglobal.h>
QT_BEGIN_NAMESPACE
class QFileSelector;
class QQmlFileSelectorPrivate;
-class Q_QML_EXPORT QQmlFileSelector : public QObject, public QQmlAbstractUrlInterceptor
+class Q_QML_EXPORT QQmlFileSelector : public QObject
{
Q_OBJECT
Q_DECLARE_PRIVATE(QQmlFileSelector)
public:
- QQmlFileSelector(QObject* parent=0);
+ QQmlFileSelector(QQmlEngine* engine, QObject* parent=0);
+ ~QQmlFileSelector();
void setSelector(QFileSelector *selector);
-
-protected:
- virtual QUrl intercept(const QUrl &path, DataType type);
+ void setExtraSelectors(QStringList &strings);
+ static QQmlFileSelector* get(QQmlEngine*);
private:
Q_DISABLE_COPY(QQmlFileSelector)
diff --git a/src/qml/qml/qqmlfileselector_p.h b/src/qml/qml/qqmlfileselector_p.h
index 60d6072c8c..501f563ade 100644
--- a/src/qml/qml/qqmlfileselector_p.h
+++ b/src/qml/qml/qqmlfileselector_p.h
@@ -54,19 +54,33 @@
//
#include "qqmlfileselector.h"
+#include <QSet>
+#include <QQmlAbstractUrlInterceptor>
#include <private/qobject_p.h>
#include <private/qtqmlglobal_p.h>
QT_BEGIN_NAMESPACE
class QFileSelector;
+class QQmlFileSelectorInterceptor;
class Q_QML_PRIVATE_EXPORT QQmlFileSelectorPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QQmlFileSelector)
public:
QQmlFileSelectorPrivate();
QFileSelector* selector;
+ QPointer<QQmlEngine> engine;
bool ownSelector;
+ QQmlFileSelectorInterceptor* myInstance;
+};
+
+class Q_QML_PRIVATE_EXPORT QQmlFileSelectorInterceptor : public QQmlAbstractUrlInterceptor
+{
+public:
+ QQmlFileSelectorInterceptor(QQmlFileSelectorPrivate* pd);
+ QQmlFileSelectorPrivate* d;
+protected:
+ virtual QUrl intercept(const QUrl &path, DataType type);
};
QT_END_NAMESPACE
diff --git a/tests/auto/qml/qqmlfileselector/tst_qqmlfileselector.cpp b/tests/auto/qml/qqmlfileselector/tst_qqmlfileselector.cpp
index a583fd0c4c..a9c1c11549 100644
--- a/tests/auto/qml/qqmlfileselector/tst_qqmlfileselector.cpp
+++ b/tests/auto/qml/qqmlfileselector/tst_qqmlfileselector.cpp
@@ -43,6 +43,7 @@
#include <QQmlEngine>
#include <QQmlComponent>
#include <QQmlFileSelector>
+#include <QQmlApplicationEngine>
#include <QFileSelector>
#include <QQmlContext>
#include <qqmlinfo.h>
@@ -56,17 +57,30 @@ public:
private slots:
void basicTest();
+ void applicationEngineTest();
};
void tst_qqmlfileselector::basicTest()
{
QQmlEngine engine;
- QFileSelector selector;
+ QQmlFileSelector selector(&engine);
selector.setExtraSelectors(QStringList() << "basic");
- QQmlFileSelector qmlSelector;
- qmlSelector.setSelector(&selector);
- engine.setUrlInterceptor(&qmlSelector);
+
+ QQmlComponent component(&engine, testFileUrl("basicTest.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ QCOMPARE(object->property("value").toString(), QString("selected"));
+
+ delete object;
+}
+
+void tst_qqmlfileselector::applicationEngineTest()
+{
+ QQmlApplicationEngine engine;
+ QQmlFileSelector* selector = QQmlFileSelector::get(&engine);
+ QVERIFY(selector != 0);
+ selector->setExtraSelectors(QStringList() << "basic");
QQmlComponent component(&engine, testFileUrl("basicTest.qml"));
QObject *object = component.create();
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index f889036961..621061ab6a 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -3511,12 +3511,9 @@ void tst_qqmllanguage::compositeSingletonJavaScriptPragma()
// Reads values from a Singleton accessed through selectors.
void tst_qqmllanguage::compositeSingletonSelectors()
{
- QFileSelector selector;
- selector.setExtraSelectors(QStringList() << "basicSelector");
- QQmlFileSelector qmlSelector;
- qmlSelector.setSelector(&selector);
QQmlEngine e2;
- e2.setUrlInterceptor(&qmlSelector);
+ QQmlFileSelector qmlSelector(&e2);
+ qmlSelector.setExtraSelectors(QStringList() << "basicSelector");
QQmlComponent component(&e2, testFile("singletonTest1.qml"));
VERIFY_ERRORS(0);
QObject *o = component.create();