diff options
author | Alan Alpert <416365416c@gmail.com> | 2013-11-12 00:11:43 -0800 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-11-13 09:32:27 +0100 |
commit | 87f90a43f450cda5e8ce7bf34145f251dfaa5682 (patch) | |
tree | d18ea8855dc7262b6091fc874c6eade22895e228 | |
parent | 60d86d531811e0ef5a4819395418aaec9f651315 (diff) |
Polish up QQmlFileSelector
Incorporate beta feedback, and hide QQmlAbstractUrlInterceptor as the
implementation (instead of making that "the API").
Change-Id: Ib7b14afeb9205fb8a87ed16a6d38b1f468b2aaaa
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
-rw-r--r-- | dist/changes-5.2.0 | 4 | ||||
-rw-r--r-- | examples/quick/shared/shared.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlapplicationengine.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlfileselector.cpp | 69 | ||||
-rw-r--r-- | src/qml/qml/qqmlfileselector.h | 12 | ||||
-rw-r--r-- | src/qml/qml/qqmlfileselector_p.h | 14 | ||||
-rw-r--r-- | tests/auto/qml/qqmlfileselector/tst_qqmlfileselector.cpp | 22 | ||||
-rw-r--r-- | tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp | 7 |
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(); |