diff options
author | Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> | 2016-02-02 13:12:42 +0100 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> | 2016-02-02 13:12:42 +0100 |
commit | 1d417a7bfa99695db7d8bf6b28a5141bf97e96cc (patch) | |
tree | 71d7fcd63cf14aa608284b436a481dca75014bc9 | |
parent | a1f0e69d162e9d6e1841b7a1e91dcca5e1109373 (diff) | |
parent | 666bc731a0ba930ca0cfda18daf836913fd91361 (diff) |
Merge 5.6 into 5.6.0
Change-Id: I971229ff050c98258729ad70d9e06b89e5bbf617
34 files changed, 361 insertions, 178 deletions
diff --git a/examples/quick/demos/photosurface/doc/src/photosurface.qdoc b/examples/quick/demos/photosurface/doc/src/photosurface.qdoc index 52466843b4..a032d730eb 100644 --- a/examples/quick/demos/photosurface/doc/src/photosurface.qdoc +++ b/examples/quick/demos/photosurface/doc/src/photosurface.qdoc @@ -116,6 +116,7 @@ \quotefromfile demos/photosurface/photosurface.qml \skipto Rectangle + \printuntil Component.onCompleted \printuntil } \section1 Handling Pinch Gestures @@ -123,6 +124,7 @@ We use a PinchArea that contains a MouseArea in the photo frames to handle dragging, rotation and pinch zooming of the frame: + \skipto PinchArea \printuntil onPinchStarted We use the \c pinch group property to control how the photo frames react to @@ -137,13 +139,13 @@ frame is controlled in the \c onEntered signal handler to highlight the selected image: + \skipto MouseArea \printuntil onEntered To enable you to test the example on the desktop, we use the MouseArea's \c onWheel signal handler to simulate pinch gestures by using a mouse: - \printuntil photoFrame.y - \printuntil } + \printuntil photoFrame.scale \printuntil } \printuntil } diff --git a/examples/quick/demos/photosurface/main.cpp b/examples/quick/demos/photosurface/main.cpp index 3058238494..9456694032 100644 --- a/examples/quick/demos/photosurface/main.cpp +++ b/examples/quick/demos/photosurface/main.cpp @@ -44,9 +44,28 @@ #include <QtGui/QGuiApplication> #endif #include <QtQml/QQmlApplicationEngine> +#include <QtQml/QQmlContext> #include <QtQuick/QQuickWindow> +#include <QtGui/QImageReader> +#include <QtCore/QCommandLineParser> +#include <QtCore/QCommandLineOption> +#include <QtCore/QDebug> +#include <QtCore/QDir> +#include <QtCore/QMimeDatabase> +#include <QtCore/QStandardPaths> #include <QtCore/QUrl> +static QStringList imageNameFilters() +{ + QStringList result; + QMimeDatabase mimeDatabase; + foreach (const QByteArray &m, QImageReader::supportedMimeTypes()) { + foreach (const QString &suffix, mimeDatabase.mimeTypeForName(m).suffixes()) + result.append(QStringLiteral("*.") + suffix); + } + return result; +} + int main(int argc, char* argv[]) { // The reason to use QApplication is that QWidget-based dialogs @@ -58,6 +77,51 @@ int main(int argc, char* argv[]) QGuiApplication app(argc, argv); #endif QQuickWindow::setDefaultAlphaBuffer(true); - QQmlApplicationEngine engine(QUrl("qrc:///photosurface.qml")); + + QCoreApplication::setApplicationName(QStringLiteral("Photosurface")); + QCoreApplication::setOrganizationName(QStringLiteral("QtProject")); + QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR)); + QCommandLineParser parser; + parser.setApplicationDescription(QStringLiteral("Qt Quick Demo - Photo Surface")); + parser.addHelpOption(); + parser.addVersionOption(); + parser.addPositionalArgument(QStringLiteral("directory"), + QStringLiteral("The image directory or URL to show.")); + parser.process(app); + + QUrl initialUrl; + if (!parser.positionalArguments().isEmpty()) { + initialUrl = QUrl::fromUserInput(parser.positionalArguments().first(), + QDir::currentPath(), QUrl::AssumeLocalFile); + if (!initialUrl.isValid()) { + qWarning().nospace() << "Invalid argument: \"" + << parser.positionalArguments().first() << "\": " << initialUrl.errorString(); + return 1; + } + } + + const QStringList nameFilters = imageNameFilters(); + + QQmlApplicationEngine engine; + QQmlContext *context = engine.rootContext(); + + QUrl picturesLocationUrl = QUrl::fromLocalFile(QDir::homePath()); + const QStringList picturesLocations = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation); + if (!picturesLocations.isEmpty()) { + picturesLocationUrl = QUrl::fromLocalFile(picturesLocations.first()); + if (initialUrl.isEmpty() + && !QDir(picturesLocations.first()).entryInfoList(nameFilters, QDir::Files).isEmpty()) { + initialUrl = picturesLocationUrl; + } + } + + context->setContextProperty(QStringLiteral("contextPicturesLocation"), picturesLocationUrl); + context->setContextProperty(QStringLiteral("contextInitialUrl"), initialUrl); + context->setContextProperty(QStringLiteral("contextImageNameFilters"), nameFilters); + + engine.load(QUrl("qrc:///photosurface.qml")); + if (engine.rootObjects().isEmpty()) + return -1; + return app.exec(); } diff --git a/examples/quick/demos/photosurface/photosurface.qml b/examples/quick/demos/photosurface/photosurface.qml index 22cef62157..d8a424e8f8 100644 --- a/examples/quick/demos/photosurface/photosurface.qml +++ b/examples/quick/demos/photosurface/photosurface.qml @@ -56,6 +56,7 @@ Window { id: fileDialog title: "Choose a folder with some images" selectFolder: true + folder: picturesLocation onAccepted: folderModel.folder = fileUrl + "/" } @@ -69,7 +70,7 @@ Window { id: folderModel objectName: "folderModel" showDirs: false - nameFilters: ["*.png", "*.jpg", "*.gif"] + nameFilters: imageNameFilters } Rectangle { id: photoFrame @@ -255,5 +256,21 @@ Window { Shortcut { sequence: StandardKey.Quit; onActivated: Qt.quit() } - Component.onCompleted: fileDialog.open() + Component.onCompleted: { + if (typeof contextInitialUrl !== 'undefined') { + // Launched from C++ with context properties set. + imageNameFilters = contextImageNameFilters; + picturesLocation = contextPicturesLocation; + if (contextInitialUrl == "") + fileDialog.open(); + else + folderModel.folder = contextInitialUrl + "/"; + } else { + // Launched via QML viewer without context properties set. + fileDialog.open(); + } + } + + property var imageNameFilters : ["*.png", "*.jpg", "*.gif"]; + property string picturesLocation : ""; } diff --git a/examples/quick/demos/stocqt/content/+windows/Settings.qml b/examples/quick/demos/stocqt/content/+windows/Settings.qml new file mode 100644 index 0000000000..1d4d7edcee --- /dev/null +++ b/examples/quick/demos/stocqt/content/+windows/Settings.qml @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +pragma Singleton +import QtQml 2.0 + +QtObject { + property string fontFamily: "Arial" +} diff --git a/examples/quick/demos/stocqt/content/Button.qml b/examples/quick/demos/stocqt/content/Button.qml index e85a5d41c5..4ef86a2cc3 100644 --- a/examples/quick/demos/stocqt/content/Button.qml +++ b/examples/quick/demos/stocqt/content/Button.qml @@ -39,6 +39,7 @@ ****************************************************************************/ import QtQuick 2.0 +import "." Rectangle { id: button @@ -54,7 +55,7 @@ Rectangle { } Text { anchors.centerIn: parent - font.family: "Open Sans" + font.family: Settings.fontFamily font.pointSize: 19 font.weight: Font.DemiBold color: button.buttonEnabled ? "#000000" : "#14aaff" diff --git a/examples/quick/demos/stocqt/content/Settings.qml b/examples/quick/demos/stocqt/content/Settings.qml new file mode 100644 index 0000000000..39e1c4c241 --- /dev/null +++ b/examples/quick/demos/stocqt/content/Settings.qml @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +pragma Singleton +import QtQml 2.0 + +QtObject { + property string fontFamily: "Open Sans" +} diff --git a/examples/quick/demos/stocqt/content/StockChart.qml b/examples/quick/demos/stocqt/content/StockChart.qml index bbe5b77d0c..147f513456 100644 --- a/examples/quick/demos/stocqt/content/StockChart.qml +++ b/examples/quick/demos/stocqt/content/StockChart.qml @@ -39,6 +39,7 @@ ****************************************************************************/ import QtQuick 2.0 +import "." Rectangle { id: chart @@ -135,7 +136,7 @@ Rectangle { Text { id: fromDate color: "#000000" - font.family: "Open Sans" + font.family: Settings.fontFamily font.pointSize: 8 anchors.left: parent.left anchors.bottom: parent.bottom @@ -145,7 +146,7 @@ Rectangle { Text { id: toDate color: "#000000" - font.family: "Open Sans" + font.family: Settings.fontFamily font.pointSize: 8 anchors.right: parent.right anchors.rightMargin: canvas.tickMargin diff --git a/examples/quick/demos/stocqt/content/StockInfo.qml b/examples/quick/demos/stocqt/content/StockInfo.qml index 50f6b9107e..3c5ee196f2 100644 --- a/examples/quick/demos/stocqt/content/StockInfo.qml +++ b/examples/quick/demos/stocqt/content/StockInfo.qml @@ -39,6 +39,7 @@ ****************************************************************************/ import QtQuick 2.0 +import "." Rectangle { id: root @@ -60,7 +61,7 @@ Rectangle { Text { id: stockIdText color: "#000000" - font.family: "Open Sans" + font.family: Settings.fontFamily font.pointSize: 28 font.weight: Font.DemiBold text: root.stock.stockId @@ -69,7 +70,7 @@ Rectangle { Text { id: price color: "#6d6d6d" - font.family: "Open Sans" + font.family: Settings.fontFamily font.pointSize: 28 font.weight: Font.DemiBold text: parseFloat(Math.round(root.stock.stockPrice * 100) / 100).toFixed(2); @@ -79,7 +80,7 @@ Rectangle { Text { id: stockNameText color: "#0c0c0c" - font.family: "Open Sans" + font.family: Settings.fontFamily font.pointSize: 16 width: stockColumn.width elide: Text.ElideRight @@ -96,7 +97,7 @@ Rectangle { id: priceChange horizontalAlignment: Text.AlignRight color: root.stock.stockPriceChanged < 0 ? "#d40000" : "#328930" - font.family: "Open Sans" + font.family: Settings.fontFamily font.pointSize: 18 text: parseFloat(Math.round(root.stock.stockPriceChanged * 100) / 100).toFixed(2); } @@ -105,7 +106,7 @@ Rectangle { id: priceChangePercentage horizontalAlignment: Text.AlignRight color: root.stock.stockPriceChanged < 0 ? "#d40000" : "#328930" - font.family: "Open Sans" + font.family: Settings.fontFamily font.pointSize: 18 font.weight: Font.DemiBold text: "(" + diff --git a/examples/quick/demos/stocqt/content/StockListView.qml b/examples/quick/demos/stocqt/content/StockListView.qml index 470531a21e..d1f735fde3 100644 --- a/examples/quick/demos/stocqt/content/StockListView.qml +++ b/examples/quick/demos/stocqt/content/StockListView.qml @@ -39,6 +39,7 @@ ****************************************************************************/ import QtQuick 2.0 +import "." Rectangle { id: root @@ -144,7 +145,7 @@ Rectangle { width: 125 height: 40 color: "#000000" - font.family: "Open Sans" + font.family: Settings.fontFamily font.pointSize: 20 font.weight: Font.Bold verticalAlignment: Text.AlignVCenter @@ -160,7 +161,7 @@ Rectangle { width: 190 height: 40 color: "#000000" - font.family: "Open Sans" + font.family: Settings.fontFamily font.pointSize: 20 font.bold: true horizontalAlignment: Text.AlignRight @@ -178,7 +179,7 @@ Rectangle { width: 135 height: 40 color: "#328930" - font.family: "Open Sans" + font.family: Settings.fontFamily font.pointSize: 20 font.bold: true horizontalAlignment: Text.AlignRight @@ -200,7 +201,7 @@ Rectangle { width: 330 height: 30 color: "#000000" - font.family: "Open Sans" + font.family: Settings.fontFamily font.pointSize: 16 font.bold: false elide: Text.ElideRight @@ -217,7 +218,7 @@ Rectangle { width: 120 height: 30 color: "#328930" - font.family: "Open Sans" + font.family: Settings.fontFamily font.pointSize: 18 font.bold: false horizontalAlignment: Text.AlignRight diff --git a/examples/quick/demos/stocqt/content/StockSettingsPanel.qml b/examples/quick/demos/stocqt/content/StockSettingsPanel.qml index 7d71355b31..0c34e453de 100644 --- a/examples/quick/demos/stocqt/content/StockSettingsPanel.qml +++ b/examples/quick/demos/stocqt/content/StockSettingsPanel.qml @@ -39,6 +39,7 @@ ****************************************************************************/ import QtQuick 2.0 +import "." Rectangle { id: root @@ -62,7 +63,7 @@ Rectangle { anchors.left: root.left anchors.top: root.top color: "#000000" - font.family: "Open Sans" + font.family: Settings.fontFamily font.pointSize: 19 text: "Open" } @@ -73,7 +74,7 @@ Rectangle { anchors.top: openText.bottom anchors.topMargin: 10 color: "#000000" - font.family: "Open Sans" + font.family: Settings.fontFamily font.pointSize: 19 text: "Close" } @@ -84,7 +85,7 @@ Rectangle { anchors.top: closeText.bottom anchors.topMargin: 10 color: "#000000" - font.family: "Open Sans" + font.family: Settings.fontFamily font.pointSize: 19 text: "High" } @@ -95,7 +96,7 @@ Rectangle { anchors.top: highText.bottom anchors.topMargin: 10 color: "#000000" - font.family: "Open Sans" + font.family: Settings.fontFamily font.pointSize: 19 text: "Low" } diff --git a/examples/quick/demos/stocqt/content/qmldir b/examples/quick/demos/stocqt/content/qmldir new file mode 100644 index 0000000000..bcfa27b484 --- /dev/null +++ b/examples/quick/demos/stocqt/content/qmldir @@ -0,0 +1,10 @@ +singleton Settings 1.0 Settings.qml +Button 1.0 Button.qml +CheckBox 1.0 CheckBox.qml +StockChart 1.0 StockChart.qml +StockInfo 1.0 StockInfo.qml +StockListModel 1.0 StockListModel.qml +StockListView 1.0 StockListView.qml +StockModel 1.0 StockModel.qml +StockSettingsPanel 1.0 StockSettingsPanel.qml +StockView 1.0 StockView.qml diff --git a/examples/quick/demos/stocqt/stocqt.qrc b/examples/quick/demos/stocqt/stocqt.qrc index ee5dd0c24f..920e56d4d0 100644 --- a/examples/quick/demos/stocqt/stocqt.qrc +++ b/examples/quick/demos/stocqt/stocqt.qrc @@ -1,6 +1,7 @@ <RCC> <qresource prefix="/demos/stocqt"> <file>stocqt.qml</file> + <file>content/qmldir</file> <file>content/Button.qml</file> <file>content/CheckBox.qml</file> <file>content/StockChart.qml</file> @@ -13,5 +14,7 @@ <file>content/images/icon-left-arrow.png</file> <file>content/StockSettingsPanel.qml</file> <file>content/StockInfo.qml</file> + <file>content/Settings.qml</file> + <file>content/+windows/Settings.qml</file> </qresource> </RCC> diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index 16c4cb28ed..791355a668 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -1875,17 +1875,17 @@ QV4::IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int #ifndef V4_BOOTSTRAP -QQmlPropertyData *PropertyResolver::property(const QString &name, bool *notInRevision, QObject *object, QQmlContextData *context) +QQmlPropertyData *PropertyResolver::property(const QString &name, bool *notInRevision, RevisionCheck check) { if (notInRevision) *notInRevision = false; - QQmlPropertyData *d = cache->property(name, object, context); + QQmlPropertyData *d = cache->property(name, 0, 0); // Find the first property while (d && d->isFunction()) d = cache->overrideData(d); - if (d && !cache->isAllowedInRevision(d)) { + if (check != IgnoreRevision && d && !cache->isAllowedInRevision(d)) { if (notInRevision) *notInRevision = true; return 0; } else { @@ -1894,11 +1894,11 @@ QQmlPropertyData *PropertyResolver::property(const QString &name, bool *notInRev } -QQmlPropertyData *PropertyResolver::signal(const QString &name, bool *notInRevision, QObject *object, QQmlContextData *context) +QQmlPropertyData *PropertyResolver::signal(const QString &name, bool *notInRevision) { if (notInRevision) *notInRevision = false; - QQmlPropertyData *d = cache->property(name, object, context); + QQmlPropertyData *d = cache->property(name, 0, 0); if (notInRevision) *notInRevision = false; while (d && !(d->isFunction())) @@ -1914,7 +1914,7 @@ QQmlPropertyData *PropertyResolver::signal(const QString &name, bool *notInRevis if (name.endsWith(QStringLiteral("Changed"))) { QString propName = name.mid(0, name.length() - static_cast<int>(strlen("Changed"))); - d = property(propName, notInRevision, object, context); + d = property(propName, notInRevision); if (d) return cache->signal(d->notifyIndex); } diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h index 9a659f4d72..633a4cc2fb 100644 --- a/src/qml/compiler/qqmlirbuilder_p.h +++ b/src/qml/compiler/qqmlirbuilder_p.h @@ -460,10 +460,15 @@ struct Q_QML_EXPORT PropertyResolver return cache->property(index); } - QQmlPropertyData *property(const QString &name, bool *notInRevision = 0, QObject *object = 0, QQmlContextData *context = 0); + enum RevisionCheck { + CheckRevision, + IgnoreRevision + }; + + QQmlPropertyData *property(const QString &name, bool *notInRevision = 0, RevisionCheck check = CheckRevision); // This code must match the semantics of QQmlPropertyPrivate::findSignalByName - QQmlPropertyData *signal(const QString &name, bool *notInRevision, QObject *object = 0, QQmlContextData *context = 0); + QQmlPropertyData *signal(const QString &name, bool *notInRevision); QQmlPropertyCache *cache; }; diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index cde7a2acb4..6fd15d1eb8 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -1859,6 +1859,7 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD } bool bindingToDefaultProperty = false; + bool isGroupProperty = instantiatingBinding && instantiatingBinding->type == QV4::CompiledData::Binding::Type_GroupProperty; bool notInRevision = false; QQmlPropertyData *pd = 0; @@ -1867,7 +1868,7 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD || binding->flags & QV4::CompiledData::Binding::IsSignalHandlerObject) pd = propertyResolver.signal(name, ¬InRevision); else - pd = propertyResolver.property(name, ¬InRevision); + pd = propertyResolver.property(name, ¬InRevision, isGroupProperty ? QmlIR::PropertyResolver::IgnoreRevision : QmlIR::PropertyResolver::CheckRevision); if (notInRevision) { QString typeName = stringAt(obj->inheritedTypeNameIndex); @@ -1879,7 +1880,7 @@ bool QQmlPropertyValidator::validateObject(int objectIndex, const QV4::CompiledD } } } else { - if (instantiatingBinding && instantiatingBinding->type == QV4::CompiledData::Binding::Type_GroupProperty) + if (isGroupProperty) COMPILE_EXCEPTION(binding, tr("Cannot assign a value directly to a grouped property")); pd = defaultProperty; diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 1a27a487bd..c5d11ee3c3 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -244,7 +244,7 @@ void QQmlType::SingletonInstanceInfo::destroy(QQmlEngine *e) QObject *o = qobjectApis.take(e); if (o) { QQmlData *ddata = QQmlData::get(o, false); - if (ddata && ddata->indestructible) + if (url.isEmpty() && ddata && ddata->indestructible && ddata->explicitIndestructibleSet) return; delete o; } diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index 8ddf91ef3c..5486c14c38 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -357,8 +357,14 @@ ReturnedValue QQmlValueTypeWrapper::get(const Managed *m, String *name, bool *ha VALUE_TYPE_LOAD(QMetaType::QString, QString, v4->newString); VALUE_TYPE_LOAD(QMetaType::Bool, bool, bool); - QVariant v(result->propType, (void *)0); - void *args[] = { v.data(), 0 }; + QVariant v; + void *args[] = { Q_NULLPTR, Q_NULLPTR }; + if (result->propType == QMetaType::QVariant) { + args[0] = &v; + } else { + v = QVariant(result->propType, static_cast<void *>(Q_NULLPTR)); + args[0] = v.data(); + } metaObject->d.static_metacall(reinterpret_cast<QObject*>(gadget), QMetaObject::ReadProperty, index, args); return v4->fromVariant(v); #undef VALUE_TYPE_ACCESSOR diff --git a/src/quick/doc/src/concepts/statesanimations/states.qdoc b/src/quick/doc/src/concepts/statesanimations/states.qdoc index b48a051379..981499ebc5 100644 --- a/src/quick/doc/src/concepts/statesanimations/states.qdoc +++ b/src/quick/doc/src/concepts/statesanimations/states.qdoc @@ -74,7 +74,7 @@ configurations with the \c PropertyChanges type. \snippet qml/states.qml signal states The \l PropertyChanges type will change the values of object properties. Objects are referenced through their -\l{qtqml-syntax-objectattributes.html#the-id-assignment}{id}. Objects outside +\l{qtqml-syntax-objectattributes.html#the-id-attribute}{id}. Objects outside the component are also referenced using the \c id property, exemplified by the property change to the external \c flag object. diff --git a/src/quick/items/qquickanimatedsprite_p.h b/src/quick/items/qquickanimatedsprite_p.h index 87d489a60a..ffaddefb47 100644 --- a/src/quick/items/qquickanimatedsprite_p.h +++ b/src/quick/items/qquickanimatedsprite_p.h @@ -47,7 +47,7 @@ #include <QtQuick/QQuickItem> #include <private/qquicksprite_p.h> -#include <QTime> +#include <QtCore/qelapsedtimer.h> QT_BEGIN_NAMESPACE @@ -366,7 +366,7 @@ private: QQuickAnimatedSpriteMaterial *m_material; QQuickSprite* m_sprite; QQuickSpriteEngine* m_spriteEngine; - QTime m_timestamp; + QElapsedTimer m_timestamp; int m_curFrame; bool m_pleaseReset; bool m_running; diff --git a/src/quick/items/qquickdroparea.cpp b/src/quick/items/qquickdroparea.cpp index e1b33b4660..b8006eedaf 100644 --- a/src/quick/items/qquickdroparea.cpp +++ b/src/quick/items/qquickdroparea.cpp @@ -264,6 +264,8 @@ void QQuickDropArea::dragEnterEvent(QDragEnterEvent *event) QQuickDropEvent dragTargetEvent(d, event); emit entered(&dragTargetEvent); + if (!event->isAccepted()) + return; d->containsDrag = true; if (QQuickDragMimeData *dragMime = qobject_cast<QQuickDragMimeData *>(const_cast<QMimeData *>(mimeData))) diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index 05bf50574c..deb5582495 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -1978,6 +1978,7 @@ void QQuickPathView::refill() break; } if (d->items.contains(item)) { + d->releaseItem(item); break; //Otherwise we'd "re-add" it, and get confused } if (d->currentIndex == idx) { @@ -2008,6 +2009,7 @@ void QQuickPathView::refill() break; } if (d->items.contains(item)) { + d->releaseItem(item); break; //Otherwise we'd "re-add" it, and get confused } if (d->currentIndex == idx) { @@ -2049,6 +2051,8 @@ void QQuickPathView::refill() int lastListIdx = d->items.indexOf(lastItem); d->items.insert(lastListIdx + 1, item); d->updateItem(item, nextPos); + } else { + d->releaseItem(item); } lastItem = item; diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index 5c436d2074..3aec464958 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -224,7 +224,7 @@ void QQuickTextPrivate::setBottomPadding(qreal value, bool reset) The default is true. */ -void QQuickText::q_imagesLoaded() +void QQuickText::q_updateLayout() { Q_D(QQuickText); d->updateLayout(); @@ -1170,7 +1170,7 @@ void QQuickTextPrivate::ensureDoc() extra->doc->setDocumentMargin(0); extra->doc->setBaseUrl(q->baseUrl()); qmlobject_connect(extra->doc, QQuickTextDocumentWithImageResources, SIGNAL(imagesLoaded()), - q, QQuickText, SLOT(q_imagesLoaded())); + q, QQuickText, SLOT(q_updateLayout())); } } diff --git a/src/quick/items/qquicktext_p.h b/src/quick/items/qquicktext_p.h index 5b385aeb0a..ea69aea3f9 100644 --- a/src/quick/items/qquicktext_p.h +++ b/src/quick/items/qquicktext_p.h @@ -292,7 +292,7 @@ protected: void invalidateFontCaches(); private Q_SLOTS: - void q_imagesLoaded(); + void q_updateLayout(); void triggerPreprocess(); void imageDownloadFinished(); diff --git a/src/quick/items/qquicktextnode.cpp b/src/quick/items/qquicktextnode.cpp index d40dedd798..2c7ab254f8 100644 --- a/src/quick/items/qquicktextnode.cpp +++ b/src/quick/items/qquicktextnode.cpp @@ -84,50 +84,6 @@ QQuickTextNode::~QQuickTextNode() qDeleteAll(m_textures); } -#if 0 -void QQuickTextNode::setColor(const QColor &color) -{ - if (m_usePixmapCache) { - setUpdateFlag(UpdateNodes); - } else { - for (QSGNode *childNode = firstChild(); childNode; childNode = childNode->nextSibling()) { - if (childNode->subType() == GlyphNodeSubType) { - QSGGlyphNode *glyphNode = static_cast<QSGGlyphNode *>(childNode); - if (glyphNode->color() == m_color) - glyphNode->setColor(color); - } else if (childNode->subType() == SolidRectNodeSubType) { - QSGSimpleRectNode *solidRectNode = static_cast<QSGSimpleRectNode *>(childNode); - if (solidRectNode->color() == m_color) - solidRectNode->setColor(color); - } - } - } - m_color = color; -} - -void QQuickTextNode::setStyleColor(const QColor &styleColor) -{ - if (m_textStyle != QQuickTextNode::NormalTextStyle) { - if (m_usePixmapCache) { - setUpdateFlag(UpdateNodes); - } else { - for (QSGNode *childNode = firstChild(); childNode; childNode = childNode->nextSibling()) { - if (childNode->subType() == GlyphNodeSubType) { - QSGGlyphNode *glyphNode = static_cast<QSGGlyphNode *>(childNode); - if (glyphNode->color() == m_styleColor) - glyphNode->setColor(styleColor); - } else if (childNode->subType() == SolidRectNodeSubType) { - QSGSimpleRectNode *solidRectNode = static_cast<QSGSimpleRectNode *>(childNode); - if (solidRectNode->color() == m_styleColor) - solidRectNode->setColor(styleColor); - } - } - } - } - m_styleColor = styleColor; -} -#endif - QSGGlyphNode *QQuickTextNode::addGlyphs(const QPointF &position, const QGlyphRun &glyphs, const QColor &color, QQuickText::TextStyle style, const QColor &styleColor, QSGNode *parentNode) @@ -312,78 +268,4 @@ void QQuickTextNode::deleteContent() m_textures.clear(); } -#if 0 -void QQuickTextNode::updateNodes() -{ - return; - deleteContent(); - if (m_text.isEmpty()) - return; - - if (m_usePixmapCache) { - // ### gunnar: port properly -// QPixmap pixmap = generatedPixmap(); -// if (pixmap.isNull()) -// return; - -// QSGImageNode *pixmapNode = m_context->createImageNode(); -// pixmapNode->setRect(pixmap.rect()); -// pixmapNode->setSourceRect(pixmap.rect()); -// pixmapNode->setOpacity(m_opacity); -// pixmapNode->setClampToEdge(true); -// pixmapNode->setLinearFiltering(m_linearFiltering); - -// appendChildNode(pixmapNode); - } else { - if (m_text.isEmpty()) - return; - - // Implement styling by drawing text several times at slight shifts. shiftForStyle - // contains the sequence of shifted positions at which to draw the text. All except - // the last will be drawn with styleColor. - QList<QPointF> shiftForStyle; - switch (m_textStyle) { - case OutlineTextStyle: - // ### Should be made faster by implementing outline material - shiftForStyle << QPointF(-1, 0); - shiftForStyle << QPointF(0, -1); - shiftForStyle << QPointF(1, 0); - shiftForStyle << QPointF(0, 1); - break; - case SunkenTextStyle: - shiftForStyle << QPointF(0, -1); - break; - case RaisedTextStyle: - shiftForStyle << QPointF(0, 1); - break; - default: - break; - } - - shiftForStyle << QPointF(0, 0); // Regular position - while (!shiftForStyle.isEmpty()) { - QPointF shift = shiftForStyle.takeFirst(); - - // Use styleColor for all but last shift - if (m_richText) { - QColor overrideColor = shiftForStyle.isEmpty() ? QColor() : m_styleColor; - - QTextFrame *textFrame = m_textDocument->rootFrame(); - QPointF p = m_textDocument->documentLayout()->frameBoundingRect(textFrame).topLeft(); - - QTextFrame::iterator it = textFrame->begin(); - while (!it.atEnd()) { - addTextBlock(shift + p, it.currentBlock(), overrideColor); - ++it; - } - } else { - addTextLayout(shift, m_textLayout, shiftForStyle.isEmpty() - ? m_color - : m_styleColor); - } - } - } -} -#endif - QT_END_NAMESPACE diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 53527dcbd1..b93aa06336 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -285,6 +285,13 @@ void QQuickWindow::update() QQuickRenderControlPrivate::get(d->renderControl)->update(); } +void QQuickWindow::handleScreenChanged(QScreen *screen) +{ + Q_D(QQuickWindow); + Q_UNUSED(screen) + d->forcePolish(); +} + void forcePolishHelper(QQuickItem *item) { if (item->flags() & QQuickItem::ItemHasContents) { @@ -299,12 +306,12 @@ void forcePolishHelper(QQuickItem *item) /*! Schedules polish events on all items in the scene. */ -void QQuickWindow::forcePolish() +void QQuickWindowPrivate::forcePolish() { - Q_D(QQuickWindow); - if (!screen()) + Q_Q(QQuickWindow); + if (!q->screen()) return; - forcePolishHelper(d->contentItem); + forcePolishHelper(contentItem); } void forceUpdate(QQuickItem *item) @@ -473,7 +480,7 @@ void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control) QObject::connect(context, SIGNAL(invalidated()), q, SLOT(cleanupSceneGraph()), Qt::DirectConnection); QObject::connect(q, SIGNAL(focusObjectChanged(QObject*)), q, SIGNAL(activeFocusItemChanged())); - QObject::connect(q, SIGNAL(screenChanged(QScreen*)), q, SLOT(forcePolish())); + QObject::connect(q, SIGNAL(screenChanged(QScreen*)), q, SLOT(handleScreenChanged(QScreen*))); QObject::connect(q, SIGNAL(frameSwapped()), q, SLOT(runJobsAfterSwap()), Qt::DirectConnection); } diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h index d5bf9fba81..9f8ad095cd 100644 --- a/src/quick/items/qquickwindow.h +++ b/src/quick/items/qquickwindow.h @@ -196,7 +196,7 @@ protected: private Q_SLOTS: void maybeUpdate(); void cleanupSceneGraph(); - void forcePolish(); + void handleScreenChanged(QScreen *screen); void setTransientParent_helper(QQuickWindow *window); void runJobsAfterSwap(); diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h index e475c48b0a..623707140e 100644 --- a/src/quick/items/qquickwindow_p.h +++ b/src/quick/items/qquickwindow_p.h @@ -190,6 +190,7 @@ public: void cleanup(QSGNode *); void polishItems(); + void forcePolish(); void syncSceneGraph(); void renderSceneGraph(const QSize &size); diff --git a/tests/auto/qml/qqmlecmascript/data/metaobjectRevision5.qml b/tests/auto/qml/qqmlecmascript/data/metaobjectRevision5.qml new file mode 100644 index 0000000000..0493a7c0b9 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/metaobjectRevision5.qml @@ -0,0 +1,12 @@ +import Qt.test 1.1 +import QtQuick 2.0 + +MyItemUsingRevisionedObject { + property real test + + revisioned.prop1: 10 + revisioned.prop2: 1 + + Component.onCompleted: test = revisioned.prop1 + revisioned.prop2 +} + diff --git a/tests/auto/qml/qqmlecmascript/testtypes.cpp b/tests/auto/qml/qqmlecmascript/testtypes.cpp index 285158a4ea..b9e088d64c 100644 --- a/tests/auto/qml/qqmlecmascript/testtypes.cpp +++ b/tests/auto/qml/qqmlecmascript/testtypes.cpp @@ -452,6 +452,7 @@ void registerTypes() qmlRegisterType<MyRevisionedSubclass>("Qt.test",1,0,"MyRevisionedSubclass"); // MyRevisionedSubclass 1.1 uses MyRevisionedClass revision 1 qmlRegisterType<MyRevisionedSubclass,1>("Qt.test",1,1,"MyRevisionedSubclass"); + qmlRegisterType<MyItemUsingRevisionedObject>("Qt.test", 1, 0, "MyItemUsingRevisionedObject"); #ifndef QT_NO_WIDGETS qmlRegisterExtendedType<QWidget,QWidgetDeclarativeUI>("Qt.test",1,0,"QWidget"); diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h index eb4a3147d3..5603356ef0 100644 --- a/tests/auto/qml/qqmlecmascript/testtypes.h +++ b/tests/auto/qml/qqmlecmascript/testtypes.h @@ -1084,10 +1084,27 @@ protected: qreal m_p4; }; + +class MyItemUsingRevisionedObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(MyRevisionedClass *revisioned READ revisioned) + +public: + MyItemUsingRevisionedObject() { + m_revisioned = new MyRevisionedClass; + } + + MyRevisionedClass *revisioned() const { return m_revisioned; } +private: + MyRevisionedClass *m_revisioned; +}; + QML_DECLARE_TYPE(MyRevisionedBaseClassRegistered) QML_DECLARE_TYPE(MyRevisionedBaseClassUnregistered) QML_DECLARE_TYPE(MyRevisionedClass) QML_DECLARE_TYPE(MyRevisionedSubclass) +QML_DECLARE_TYPE(MyItemUsingRevisionedObject) Q_DECLARE_METATYPE(MyQmlObject::MyType) diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index b30dfcbd0b..a208bf5634 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -6578,6 +6578,15 @@ void tst_qqmlecmascript::revision() QCOMPARE(object->property("test").toReal(), 11.); delete object; } + + { + QQmlComponent component(&engine, testFileUrl("metaobjectRevision5.qml")); + + QObject *object = component.create(); + QVERIFY(object != 0); + QCOMPARE(object->property("test").toReal(), 11.); + delete object; + } } void tst_qqmlecmascript::realToInt() diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 1f299c0dbb..71f206ed8f 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -249,6 +249,8 @@ private slots: void dataAlignment(); + void deleteSingletons(); + private: QQmlEngine engine; QStringList defaultImportPathList; @@ -4089,6 +4091,24 @@ void tst_qqmllanguage::dataAlignment() QVERIFY(sizeof(QQmlVMEMetaData::MethodData) % sizeof(int) == 0); } +void tst_qqmllanguage::deleteSingletons() +{ + QPointer<QObject> singleton; + { + QQmlEngine tmpEngine; + QQmlComponent component(&tmpEngine, testFile("singletonTest5.qml")); + VERIFY_ERRORS(0); + QObject *o = component.create(); + QVERIFY(o != 0); + QObject *s1 = NULL; + getSingletonInstance(o, "singletonInstance", &s1); + QVERIFY(s1 != 0); + singleton = s1; + QVERIFY(singleton.data() != 0); + } + QVERIFY(singleton.data() == 0); +} + QTEST_MAIN(tst_qqmllanguage) #include "tst_qqmllanguage.moc" diff --git a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp index 58755927b5..04abe0bfcb 100644 --- a/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp +++ b/tests/auto/qml/qqmlvaluetypes/tst_qqmlvaluetypes.cpp @@ -1493,6 +1493,7 @@ struct MyOffice { Q_PROPERTY(int chairs MEMBER m_chairs) Q_PROPERTY(MyDesk desk READ desk WRITE setDesk) + Q_PROPERTY(QVariant myThing READ myThing WRITE setMyThing) Q_GADGET public: MyOffice() : m_chairs(0) {} @@ -1500,8 +1501,12 @@ public: MyDesk desk() const { return m_desk; } void setDesk(const MyDesk &d) { m_desk = d; } + QVariant myThing() const { return m_myThing; } + void setMyThing(const QVariant &thingy) { m_myThing = thingy; } + int m_chairs; MyDesk m_desk; + QVariant m_myThing; }; Q_DECLARE_METATYPE(MyOffice) @@ -1513,6 +1518,11 @@ void tst_qqmlvaluetypes::customValueType() MyOffice cppOffice; cppOffice.m_chairs = 2; + QVariantMap m; + m.insert(QStringLiteral("hasChair"), false); + m.insert(QStringLiteral("textOnWhiteboard"), QStringLiteral("Blah blah")); + cppOffice.m_myThing = m; + QJSValue office = engine.toScriptValue(cppOffice); QCOMPARE(office.property("chairs").toInt(), 2); office.setProperty("chairs", 1); @@ -1530,6 +1540,14 @@ void tst_qqmlvaluetypes::customValueType() cppOffice = engine.fromScriptValue<MyOffice>(office); QCOMPARE(cppOffice.m_chairs, 1); QCOMPARE(cppOffice.desk().monitorCount, 2); + + QJSValue thingy = office.property("myThing"); + QVERIFY(thingy.hasProperty("hasChair")); + QVERIFY(thingy.property("hasChair").isBool()); + QCOMPARE(thingy.property("hasChair").toBool(), false); + QVERIFY(thingy.property("textOnWhiteboard").isString()); + QVERIFY(thingy.hasProperty("textOnWhiteboard")); + QCOMPARE(thingy.property("textOnWhiteboard").toString(), QStringLiteral("Blah blah")); } struct BaseGadget diff --git a/tools/qmlimportscanner/main.cpp b/tools/qmlimportscanner/main.cpp index b16253a192..189459f9af 100644 --- a/tools/qmlimportscanner/main.cpp +++ b/tools/qmlimportscanner/main.cpp @@ -344,6 +344,24 @@ QVariantList mergeImports(const QVariantList &a, const QVariantList &b) return merged; } +// Predicates needed by findQmlImportsInDirectory. + +struct isMetainfo { + bool operator() (const QFileInfo &x) const { + return x.suffix() == QLatin1String("metainfo"); + } +}; + +struct pathStartsWith { + pathStartsWith(const QString &path) : _path(path) {} + bool operator() (const QString &x) const { + return _path.startsWith(x); + } + const QString _path; +}; + + + // Scan all qml files in directory for import statements QVariantList findQmlImportsInDirectory(const QString &qmlDir) { @@ -353,19 +371,6 @@ QVariantList findQmlImportsInDirectory(const QString &qmlDir) QDirIterator iterator(qmlDir, QDir::AllDirs | QDir::NoDotDot, QDirIterator::Subdirectories); QStringList blacklist; - struct isMetainfo { - bool operator() (const QFileInfo &x) const { - return x.suffix() == QLatin1String("metainfo"); - } - }; - struct pathStartsWith { - pathStartsWith(const QString &path) : _path(path) {} - bool operator() (const QString &x) const { - return _path.startsWith(x); - } - const QString _path; - }; - while (iterator.hasNext()) { iterator.next(); |