diff options
author | Liang Qi <liang.qi@qt.io> | 2016-12-25 18:28:32 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2016-12-25 18:35:38 +0100 |
commit | 9a272ad1854d744ea57296ba633b9d0dc19d1625 (patch) | |
tree | 096752ec339e18998517a4598f907e4b42b9403d | |
parent | 70c6b9639c53d2a530ccabd1395f561211c16fa4 (diff) | |
parent | d8a052bc6b0349045db3d43a373b09cb16b41a48 (diff) |
Merge remote-tracking branch 'origin/5.8' into dev
Conflicts:
tools/qmlimportscanner/main.cpp
Change-Id: I01e17581f6691a03f83788773364d0cf96319514
23 files changed, 329 insertions, 77 deletions
diff --git a/dist/changes-5.8.0 b/dist/changes-5.8.0 new file mode 100644 index 0000000000..2fa4173c2e --- /dev/null +++ b/dist/changes-5.8.0 @@ -0,0 +1,172 @@ +Qt 5.8 introduces many new features and improvements as well as bugfixes +over the 5.7.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + + http://doc.qt.io/qt-5/index.html + +The Qt version 5.8 series is binary compatible with the 5.7.x series. +Applications compiled for 5.7 will continue to run with 5.8. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* General * +**************************************************************************** + - [QTBUG-54982] Add qmlRegisterUncreatableMetaObject convenience function + needed to register Q_NAMESPACE QMetaObjects. + +**************************************************************************** +* Important Behavior Changes * +**************************************************************************** + + - [QTBUG-52012] When the engine looks for QML modules / extension + plugins in statically linked applications, the plugins are not + instantiated in the qml loader thread anymore. For this to work + however it is necessary for plugins to use + Q_PLUGIN_METADATA(IID_QQmlExtensionInterface_iid) in their class + declaration instead of hardcoding the interface id as a string literal. + + - A JS null value converted to a QVariant now has type + QMetaType::Nullptr rather than QMetaType::VoidStar. + + - To improve the start-up time and reduce memory consumption, the QML engine + attempts to cache the code and data structures generated during loading of + .qml and .js files. Cache files are - if possible - written to disk in the + directory next to the source file with the .qmlc/.jsc extension. If that + is not possible, they are written to QStandardPaths::CacheLocation. + + +**************************************************************************** +* Library * +**************************************************************************** + +QtQml +----- + + - [QTBUG-53412] Fix mapping of null JS values to null SQL values instead + of empty strings. + - [QTBUG-53794] Fix crash when using the "with" statement with an + expression that throws an exception. + - [QTBUG-54589] Fix assertion when deleting properties of JS objects + - [QTBUG-54360] Added exit(int retCode) method to the Qt global object. An + application can call Qt.exit to specify a return code of the engine. + - QQmlXMLHttpRequest: + * [QTBUG-38175] QQmlXMLHttpRequest now supports the PATCH method in HTTP + requests. + - Fix reading of enum properties from gadgets / value types when the + enum was registered with qRegisterMetaType(). + - Fixed support for using namespaces in property types, signal parameter names + and list types + - Fixed support for declaring default properties of type list<T> + + +QtQuick +------- + + - QQuickWindow: + * The relevant child item is now sent a hover event when the window + receives a QEnterEvent, making sure hovering is recognized without + waiting for mouse movement. + - [QTBUG-50298] Added Qt.application.font property. + - QQuickWidget now properly repaints text on high-DPI screen changes. + - [QTBUG-54238] qt.scenegraph.info logging category got renamed to + qt.scenegraph.general. + - ShaderEffect with OpenGL now supports reading GLSL shader sources from + local files and from the resource system. Whenever a fragmentShader or + vertexShader property is a valid such URL, the value is treated as a + file specification instead of actual source code. + - The threaded scene graph renderer does not sleep up to one vsync + interval before the first frame anymore. + - [QTBUG-48723] Added properties to access color values for the HSV and + HSL color models to the basic QML color type. + - MouseArea no longer thinks it's pressed when it does not accept the + press event. When a press event is not accepted, MouseArea also no + longer receives a cancel event. + - Touch events are now delivered in a well defined order: New touch points + are delivered first to items under the finger which was first touching + the screen. Then to items that are under the second finger and finally + to common ancestors. This means that items that are "on top" will get a + chance to grab touch points before any items in the background. + - [QTBUG-39888] Fix crash with QQuickItems created via JavaScript being + garbage collected sometimes when they're not assigned to a window. + + - Drag: + * [QTBUG-37366] Added imageSource property to attached Drag object: this + allows drag sources to specify the pixmap to be drawn next to the + mouse cursor when starting a drag and drop operation. + + - Important Behavior Changes: + * [QTBUG-54133] QQuickWidget now follows the same behavior as + QQuickWindow when it comes to the persistent scenegraph setting + controlled by QQuickWindow::setPersistentSceneGraph(). In earlier + releases the setting was ignored and the scenegraph was torn down on + every hide event. This is not the case anymore. + * [QTBUG-54133] QQuickWidget now behaves identically to QOpenGLWidget + when it comes to handling window changes when reparenting the widget + into a hierarchy belonging to another top-level widget. Previously the + OpenGL context always got destroyed and recreated in order to ensure + texture resource sharing with the new top-level widget. From now on + this is only true when when AA_ShareOpenGLContexts it not set. + + - LayoutMirroring: + * [QTBUG-55517] Made it possible to attach LayoutMirroring to a Window. + + - MouseArea: + * [QTBUG-40475][QTBUG-42194][QTBUG-33982][QTBUG-42578][QTBUG-52537] + Hover state is now updated once per frame. This means that + MouseArea::containsMouse property will now be correct even if the + mouse is not moving, but items move under the cursor. Likewise the + mouse position properties and positionChanged signal will act as if + the mouse had moved. + + - QQuickItem: + * [QTBUG-31861] Fixed issue with mouse button events being sent even + when they were disabled by setAcceptedMouseButtons. + + - QQuickWindow: + * QQuickWindow::sendEvent() is deprecated. Use + QCoreApplication::sendEvent() directly instead. + + - ShaderEffect: + * Add new mesh type BorderImageMesh. BorderImageMesh provides an + optimized way to use BorderImage-type images with ShaderEffect. + + - Text: + * [QTBUG-52389] Fixed clipping of glyphs that extend beyond font's em + square. + * [QTBUG-54723] Fixed a performance regression when rendering a rich + text item with scaled images. + * [QTBUG-43133] Fixed placement of flowing text objects in the start of + a right-to-left block. + + + +QML Elements +------------ + + - Added a LoggingCategory type and added support for it to the console + object + + - Binding: + * Add delayed property to Binding as a way to avoid potentially expensive + or unexpected intermediate values. + + - Text, TextEdit, TextInput: + * Added "hintingPreference" property + + - Platform Specific Changes: + * [Windows][QTBUG-45321] Worked around an issue with fonts that have corrupt + cmap tables. + +QtTest +------ + + - TestCase: + * [QTBUG-19708] Added tryVerify() function to allow verification of + asynchronous conditions that can't be tested using tryCompare(). diff --git a/examples/qml/doc/src/qml-extending.qdoc b/examples/qml/doc/src/qml-extending.qdoc index e5b364e0bc..0812a3dba1 100644 --- a/examples/qml/doc/src/qml-extending.qdoc +++ b/examples/qml/doc/src/qml-extending.qdoc @@ -174,7 +174,7 @@ and other types can be coerced to it. \section2 Define Boy and Girl -The implementation of Boy and Girl are trivial. +The implementation of Boy and Girl is trivial. \snippet referenceexamples/coercion/person.cpp 1 diff --git a/examples/quick/demos/calqlatr/calqlatr.qml b/examples/quick/demos/calqlatr/calqlatr.qml index 81f95907a6..017d819b01 100644 --- a/examples/quick/demos/calqlatr/calqlatr.qml +++ b/examples/quick/demos/calqlatr/calqlatr.qml @@ -128,6 +128,7 @@ Rectangle { height: parent.height MouseArea { + id: mouseInput property real startX: 0 property real oldP: 0 property bool rewind: false @@ -140,7 +141,7 @@ Rectangle { height: 50 onPositionChanged: { var reverse = startX > window.width / 2 - var mx = mapToItem(window, mouse.x).x + var mx = mapToItem(window, mouseInput.mouseX, mouseInput.mouseY).x var p = Math.abs((mx - startX) / (window.width - display.width)) if (p < oldP) rewind = reverse ? false : true @@ -149,7 +150,7 @@ Rectangle { controller.progress = reverse ? 1 - p : p oldP = p } - onPressed: startX = mapToItem(window, mouse.x).x + onPressed: startX = mapToItem(window, mouseInput.mouseX, mouseInput.mouseY).x onReleased: { if (rewind) controller.completeToBeginning() diff --git a/examples/quick/localstorage/doc/src/localstorage.qdoc b/examples/quick/localstorage/doc/src/localstorage.qdoc index 1bfba147e1..8ffcbe9d14 100644 --- a/examples/quick/localstorage/doc/src/localstorage.qdoc +++ b/examples/quick/localstorage/doc/src/localstorage.qdoc @@ -28,7 +28,7 @@ \title Qt Quick Examples - Local Storage \example localstorage \brief A collection of QML local storage examples. - \image qml-localstorage-example.png + \borderedimage qml-localstorage-example.png \e{Local Storage} is a collection of small QML examples relating to Qt Quick's \l{local storage} functionality. diff --git a/examples/quick/localstorage/localstorage/qml-localstorage-example.png b/examples/quick/localstorage/localstorage/qml-localstorage-example.png Binary files differdeleted file mode 100644 index 7d7edafe63..0000000000 --- a/examples/quick/localstorage/localstorage/qml-localstorage-example.png +++ /dev/null diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp index ebffb07346..d3ea93c80a 100644 --- a/src/imports/localstorage/plugin.cpp +++ b/src/imports/localstorage/plugin.cpp @@ -640,14 +640,32 @@ Below you will find an example of a database transaction which catches exception \snippet qml/localstorage/dbtransaction.js 0 +In the example you can see an \c insert statement where values are assigned to the fields, +and the record is written into the table. That is an \c insert statement with a syntax that is usual +for a relational database. It is however also possible to work with JSON objects and +store them in a table. + +Let's suppose a simple example where we store trips in JSON format using \c date as the unique key. +An example of a table that could be used for that purpose: + +\snippet qml/localstorage/dbtransaction.js 3 + +The assignment of values to a JSON object: + +\snippet qml/localstorage/dbtransaction.js 4 + +In that case, the data could be saved in the following way: + +\snippet qml/localstorage/dbtransaction.js 5 + \section3 db.readTransaction(callback(tx)) This method creates a read-only transaction and passed to \e callback. In this function, -you can call \e executeSql on \e tx to read the database (with SELECT statements). +you can call \e executeSql on \e tx to read the database (with \c select statements). \section3 results = tx.executeSql(statement, values) -This method executes a SQL \e statement, binding the list of \e values to SQL positional parameters ("?"). +This method executes an SQL \e statement, binding the list of \e values to SQL positional parameters ("?"). It returns a results object, with the following properties: diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp index 1f5c22eb97..9dbebd1128 100644 --- a/src/qml/compiler/qv4isel_moth.cpp +++ b/src/qml/compiler/qv4isel_moth.cpp @@ -242,6 +242,11 @@ void InstructionSelection::run(int functionIndex) addInstruction(set); } exceptionHandler = _block->catchBlock; + } else if (_block->catchBlock == nullptr && _block->index() != 0 && _block->in.isEmpty()) { + exceptionHandler = nullptr; + Instruction::SetExceptionHandler set; + set.offset = 0; + addInstruction(set); } for (IR::Stmt *s : _block->statements()) { diff --git a/src/qml/debugger/qqmlprofiler_p.h b/src/qml/debugger/qqmlprofiler_p.h index 242f26ee0d..3a507bef74 100644 --- a/src/qml/debugger/qqmlprofiler_p.h +++ b/src/qml/debugger/qqmlprofiler_p.h @@ -149,40 +149,38 @@ class Q_QML_PRIVATE_EXPORT QQmlProfiler : public QObject, public QQmlProfilerDef Q_OBJECT public: - class BindingRefCount : public QQmlRefCount { + class FunctionRefCount : public QQmlRefCount { public: - BindingRefCount(QQmlBinding *binding): - m_binding(binding) + FunctionRefCount(QV4::Function *function): + m_function(function) { - m_binding->ref.ref(); + m_function->compilationUnit->addref(); } - BindingRefCount(const BindingRefCount &other) : - QQmlRefCount(other), m_binding(other.m_binding) + FunctionRefCount(const FunctionRefCount &other) : + QQmlRefCount(other), m_function(other.m_function) { - m_binding->ref.ref(); + m_function->compilationUnit->addref(); } - BindingRefCount &operator=(const BindingRefCount &other) + FunctionRefCount &operator=(const FunctionRefCount &other) { if (this != &other) { QQmlRefCount::operator=(other); - other.m_binding->ref.ref(); - if (!m_binding->ref.deref()) - delete m_binding; - m_binding = other.m_binding; + other.m_function->compilationUnit->addref(); + m_function->compilationUnit->release(); + m_function = other.m_function; } return *this; } - ~BindingRefCount() + ~FunctionRefCount() { - if (!m_binding->ref.deref()) - delete m_binding; + m_function->compilationUnit->release(); } private: - QQmlBinding *m_binding; + QV4::Function *m_function; }; struct Location { @@ -199,14 +197,10 @@ public: RefLocation() : Location(), locationType(MaximumRangeType), ref(nullptr), sent(false) {} - RefLocation(QQmlBinding *binding, QV4::FunctionObject *function) : + RefLocation(QV4::Function *function) : Location(function->sourceLocation()), locationType(Binding), - ref(new BindingRefCount(binding), QQmlRefPointer<QQmlRefCount>::Adopt), sent(false) - {} - - RefLocation(QQmlBinding *binding, QV4::Function *function) : - Location(function->sourceLocation()), locationType(Binding), - ref(new BindingRefCount(binding), QQmlRefPointer<QQmlRefCount>::Adopt), sent(false) + ref(new FunctionRefCount(function), + QQmlRefPointer<QQmlRefCount>::Adopt), sent(false) {} RefLocation(QV4::CompiledData::CompilationUnit *ref, const QUrl &url, const QV4::CompiledData::Object *obj, @@ -236,16 +230,21 @@ public: typedef QHash<quintptr, Location> LocationHash; - void startBinding(QQmlBinding *binding, QV4::Function *function) + void startBinding(QV4::Function *function) { - quintptr locationId(id(binding)); + // Use the QV4::Function as ID, as that is common among different instances of the same + // component. QQmlBinding is per instance. + // Add 1 to the ID, to make it different from the IDs the V4 profiler produces. The +1 makes + // the pointer point into the middle of the QV4::Function. Thus it still points to valid + // memory but we cannot accidentally create a duplicate key from another object. + quintptr locationId(id(function) + 1); m_data.append(QQmlProfilerData(m_timer.nsecsElapsed(), (1 << RangeStart | 1 << RangeLocation), Binding, locationId)); RefLocation &location = m_locations[locationId]; if (!location.isValid()) - location = RefLocation(binding, function); + location = RefLocation(function); } // Have toByteArrays() construct another RangeData event from the same QString later. @@ -281,7 +280,8 @@ public: Creating, id(obj))); } - void updateCreating(const QV4::CompiledData::Object *obj, QV4::CompiledData::CompilationUnit *ref, + void updateCreating(const QV4::CompiledData::Object *obj, + QV4::CompiledData::CompilationUnit *ref, const QUrl &url, const QString &type) { quintptr locationId(id(obj)); @@ -330,12 +330,11 @@ struct QQmlProfilerHelper : public QQmlProfilerDefinitions { }; struct QQmlBindingProfiler : public QQmlProfilerHelper { - QQmlBindingProfiler(QQmlProfiler *profiler, QQmlBinding *binding, - QV4::Function *function) : + QQmlBindingProfiler(QQmlProfiler *profiler, QV4::Function *function) : QQmlProfilerHelper(profiler) { Q_QML_PROFILE(QQmlProfilerDefinitions::ProfileBinding, profiler, - startBinding(binding, function)); + startBinding(function)); } ~QQmlBindingProfiler() diff --git a/src/qml/jsruntime/qv4profiling_p.h b/src/qml/jsruntime/qv4profiling_p.h index d27e853343..f75ac4d33a 100644 --- a/src/qml/jsruntime/qv4profiling_p.h +++ b/src/qml/jsruntime/qv4profiling_p.h @@ -158,12 +158,11 @@ public: FunctionCall &operator=(const FunctionCall &other) { if (&other != this) { - if (m_function) - m_function->compilationUnit->release(); + other.m_function->compilationUnit->addref(); + m_function->compilationUnit->release(); m_function = other.m_function; m_start = other.m_start; m_end = other.m_end; - m_function->compilationUnit->addref(); } return *this; } diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index 284ae1f36f..62288a5845 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -163,7 +163,7 @@ void QQmlBinding::update(QQmlPropertyData::WriteFlags flags) if (canUseAccessor()) flags.setFlag(QQmlPropertyData::BypassInterceptor); - QQmlBindingProfiler prof(ep->profiler, this, function()); + QQmlBindingProfiler prof(ep->profiler, function()); doUpdate(watcher, flags, scope); if (!watcher.wasDeleted()) diff --git a/src/quick/doc/images/qml-localstorage-example.png b/src/quick/doc/images/qml-localstorage-example.png Binary files differindex e128574683..64e1cb0315 100644 --- a/src/quick/doc/images/qml-localstorage-example.png +++ b/src/quick/doc/images/qml-localstorage-example.png diff --git a/src/quick/doc/snippets/qml/localstorage/dbtransaction.js b/src/quick/doc/snippets/qml/localstorage/dbtransaction.js index 40eb6d2804..38733a8e2c 100644 --- a/src/quick/doc/snippets/qml/localstorage/dbtransaction.js +++ b/src/quick/doc/snippets/qml/localstorage/dbtransaction.js @@ -43,11 +43,11 @@ var db = LocalStorage.openDatabaseSync("ActivityTrackDB", "", "Database tracking db.transaction( try { function(tx) { - tx.executeSql('INSERT INTO trip_log VALUES(?, ?, ?)', - [ '01/10/2016','Sylling - Vikersund', '53' ]); + tx.executeSql("INSERT INTO trip_log VALUES(?, ?, ?)", + [ "01/10/2016","Sylling - Vikersund", "53" ]); } } catch (err) { - console.log("Error inserting into table Greeting: " + err); + console.log("Error inserting into table trip_log: " + err); } ) //![0] @@ -60,11 +60,11 @@ function db_distance_select(Pdistance) var db = LocalStorage.openDatabaseSync("ActivityTrackDB", "", "Database tracking sports activities", 1000000); db.transaction( function(tx) { - var results = tx.executeSql('SELECT rowid, + var results = tx.executeSql("SELECT rowid, date, trip_desc, distance FROM trip_log - where distance >= ?',[Pdistance]'); + where distance >= ?",[Pdistance]); for (var i = 0; i < results.rows.length; i++) { listModel.append({"id": results.rows.item(i).rowid, "date": results.rows.item(i).date, @@ -76,10 +76,22 @@ db.transaction( //![1] //![2] var db = LocalStorage.openDatabaseSync("ActivityTrackDB", "", "Database tracking sports activities", 1000000); -if (db.version == '0.1') { - db.changeVersion('0.1', '0.2', function(tx) { - tx.executeSql('INSERT INTO trip_log VALUES(?, ?, ?)', - [ '01/10/2016','Sylling - Vikersund', '53' ]); +if (db.version == "0.1") { + db.changeVersion("0.1", "0.2", function(tx) { + tx.executeSql("INSERT INTO trip_log VALUES(?, ?, ?)", + [ "01/10/2016","Sylling - Vikersund", "53" ]); } }); //![2] +//![3] +create table trip_log(date text, data text) +//![3] +//![4] +var obj = {description = "Vikersund - Noresund", distance = "60"} +//![4] +//![5] +db.transaction(function(tx) { + result = tx.executeSQL("insert into trip_log values (?,?)", + ["01/11/2016", JSON.stringify(obj)]) +} +//![5] diff --git a/src/quick/items/qquickevents.cpp b/src/quick/items/qquickevents.cpp index 42588fd058..2fad9f5a8d 100644 --- a/src/quick/items/qquickevents.cpp +++ b/src/quick/items/qquickevents.cpp @@ -552,7 +552,7 @@ void QQuickEventTouchPoint::reset(const QTouchEvent::TouchPoint &tp, ulong times QQuickEventPoint::reset(tp.state(), tp.scenePos(), tp.id(), timestamp); m_rotation = tp.rotation(); m_pressure = tp.pressure(); -// m_uniqueId = tp.uniqueId(); + m_uniqueId = tp.uniqueId(); } /*! diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h index 6179791413..7b281623fe 100644 --- a/src/quick/items/qquickevents_p_p.h +++ b/src/quick/items/qquickevents_p_p.h @@ -302,8 +302,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickEventTouchPoint : public QQuickEventPoint Q_OBJECT Q_PROPERTY(qreal rotation READ rotation) Q_PROPERTY(qreal pressure READ pressure) -// TODO rename to QPointingDeviceUniqueId -// Q_PROPERTY(QPointerUniqueId uniqueId READ uniqueId) + Q_PROPERTY(QPointingDeviceUniqueId uniqueId READ uniqueId) public: QQuickEventTouchPoint(QQuickPointerTouchEvent *parent); @@ -312,12 +311,12 @@ public: qreal rotation() const { return m_rotation; } qreal pressure() const { return m_pressure; } -// QPointerUniqueId uniqueId() const { return m_uniqueId; } + QPointingDeviceUniqueId uniqueId() const { return m_uniqueId; } private: qreal m_rotation; qreal m_pressure; -// QPointerUniqueId m_uniqueId; + QPointingDeviceUniqueId m_uniqueId; Q_DISABLE_COPY(QQuickEventTouchPoint) }; @@ -451,7 +450,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickPointerDevice : public QObject Q_PROPERTY(int maximumTouchPoints READ maximumTouchPoints CONSTANT) Q_PROPERTY(int buttonCount READ buttonCount CONSTANT) Q_PROPERTY(QString name READ name CONSTANT) - Q_PROPERTY(qint64 uniqueId READ uniqueId CONSTANT) + Q_PROPERTY(QPointingDeviceUniqueId uniqueId READ uniqueId CONSTANT) public: enum DeviceType { @@ -498,7 +497,8 @@ public: QQuickPointerDevice(DeviceType devType, PointerType pType, Capabilities caps, int maxPoints, int buttonCount, const QString &name, qint64 uniqueId = 0) : m_deviceType(devType), m_pointerType(pType), m_capabilities(caps) - , m_maximumTouchPoints(maxPoints), m_buttonCount(buttonCount), m_name(name), m_uniqueId(uniqueId), m_event(nullptr) + , m_maximumTouchPoints(maxPoints), m_buttonCount(buttonCount), m_name(name) + , m_uniqueId(QPointingDeviceUniqueId::fromNumericId(uniqueId)), m_event(nullptr) { if (m_deviceType == Mouse) { m_event = new QQuickPointerMouseEvent; @@ -517,7 +517,7 @@ public: int maximumTouchPoints() const { return m_maximumTouchPoints; } int buttonCount() const { return m_buttonCount; } QString name() const { return m_name; } - qint64 uniqueId() const { return m_uniqueId; } + QPointingDeviceUniqueId uniqueId() const { return m_uniqueId; } QQuickPointerEvent *pointerEvent() const { return m_event; } static QQuickPointerDevice *touchDevice(QTouchDevice *d); @@ -532,7 +532,7 @@ private: int m_maximumTouchPoints; int m_buttonCount; QString m_name; - qint64 m_uniqueId; + QPointingDeviceUniqueId m_uniqueId; // the device-specific event instance which is reused during event delivery QQuickPointerEvent *m_event; @@ -555,7 +555,7 @@ QML_DECLARE_TYPE(QQuickMouseEvent) QML_DECLARE_TYPE(QQuickWheelEvent) QML_DECLARE_TYPE(QQuickCloseEvent) QML_DECLARE_TYPE(QQuickPointerDevice) -//QML_DECLARE_TYPE(QPointerUniqueId) +QML_DECLARE_TYPE(QPointingDeviceUniqueId) QML_DECLARE_TYPE(QQuickPointerEvent) #endif // QQUICKEVENTS_P_P_H diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp index dbe30fbc83..b0ddbb0034 100644 --- a/src/quick/items/qquickitemsmodule.cpp +++ b/src/quick/items/qquickitemsmodule.cpp @@ -298,8 +298,10 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor) qmlRegisterType<QQuickGrid, 1>(uri, 2, 1, "Grid"); #endif #if QT_CONFIG(quick_itemview) - qmlRegisterUncreatableType<QQuickItemView, 1>(uri, 2, 1, "ItemView", QQuickItemView::tr("ItemView is an abstract base class")); - qmlRegisterUncreatableType<QQuickItemView, 2>(uri, 2, 3, "ItemView", QQuickItemView::tr("ItemView is an abstract base class")); + const char *itemViewName = "ItemView"; + const QString itemViewMessage = QQuickItemView::tr("ItemView is an abstract base class"); + qmlRegisterUncreatableType<QQuickItemView, 1>(uri, 2, 1, itemViewName, itemViewMessage); + qmlRegisterUncreatableType<QQuickItemView, 2>(uri, 2, 3, itemViewName, itemViewMessage); #endif #if QT_CONFIG(quick_listview) qmlRegisterType<QQuickListView, 1>(uri, 2, 1, "ListView"); @@ -361,6 +363,9 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor) #if QT_CONFIG(quick_pathview) qmlRegisterType<QQuickPathView, 7>(uri, 2, 7, "PathView"); #endif +#if QT_CONFIG(quick_itemview) + qmlRegisterUncreatableType<QQuickItemView, 7>(uri, 2, 7, itemViewName, itemViewMessage); +#endif qmlRegisterUncreatableType<QQuickMouseEvent, 7>(uri, 2, 7, nullptr, QQuickMouseEvent::tr("MouseEvent is only available within handlers in MouseArea")); diff --git a/src/quick/items/qquickrendercontrol.cpp b/src/quick/items/qquickrendercontrol.cpp index 13e13890b7..03d96aea1f 100644 --- a/src/quick/items/qquickrendercontrol.cpp +++ b/src/quick/items/qquickrendercontrol.cpp @@ -380,6 +380,9 @@ QImage QQuickRenderControl::grab() if (d->window->rendererInterface()->graphicsApi() == QSGRendererInterface::OpenGL) { #if QT_CONFIG(opengl) + QQuickWindowPrivate *cd = QQuickWindowPrivate::get(d->window); + cd->polishItems(); + cd->syncSceneGraph(); render(); grabContent = qt_gl_read_framebuffer(d->window->size() * d->window->effectiveDevicePixelRatio(), false, false); #endif @@ -394,6 +397,8 @@ QImage QQuickRenderControl::grab() QPaintDevice *prevDev = softwareRenderer->currentPaintDevice(); softwareRenderer->setCurrentPaintDevice(&grabContent); softwareRenderer->markDirty(); + cd->polishItems(); + cd->syncSceneGraph(); render(); softwareRenderer->setCurrentPaintDevice(prevDev); } diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index 6771c0e940..6db96f369c 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -898,6 +898,7 @@ void Renderer::map(Buffer *buffer, int byteSize, bool isIndexBuf) } else if (buffer->size != byteSize) { free(buffer->data); buffer->data = (char *) malloc(byteSize); + Q_CHECK_PTR(buffer->data); } buffer->size = byteSize; } diff --git a/src/quick/scenegraph/coreapi/qsggeometry.cpp b/src/quick/scenegraph/coreapi/qsggeometry.cpp index a278c6079b..69a8c21ed2 100644 --- a/src/quick/scenegraph/coreapi/qsggeometry.cpp +++ b/src/quick/scenegraph/coreapi/qsggeometry.cpp @@ -675,6 +675,7 @@ void QSGGeometry::allocate(int vertexCount, int indexCount) Q_ASSERT(m_index_type == UnsignedIntType || m_index_type == UnsignedShortType); int indexByteSize = indexCount * (m_index_type == UnsignedShortType ? sizeof(quint16) : sizeof(quint32)); m_data = (void *) malloc(vertexByteSize + indexByteSize); + Q_CHECK_PTR(m_data); m_index_data_offset = vertexByteSize; m_owns_data = true; } diff --git a/tests/auto/quick/qquickgridview/data/keyNavigationEnabled.qml b/tests/auto/quick/qquickgridview/data/keyNavigationEnabled.qml new file mode 100644 index 0000000000..868611760e --- /dev/null +++ b/tests/auto/quick/qquickgridview/data/keyNavigationEnabled.qml @@ -0,0 +1,12 @@ +import QtQuick 2.7 + +GridView { + width: 405 + height: 200 + cellWidth: width / 9 + cellHeight: height / 2 + // Ensure that the property is available in QML. + onKeyNavigationEnabledChanged: {} + model: 18 + delegate: Rectangle { objectName: "delegate"; width: 10; height: 10; color: "green" } +} diff --git a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp index 07c03a57d7..1acc36c9b0 100644 --- a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp +++ b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp @@ -6568,7 +6568,7 @@ void tst_QQuickGridView::QTBUG_45640() void tst_QQuickGridView::keyNavigationEnabled() { QScopedPointer<QQuickView> window(createView()); - window->setSource(testFileUrl("gridview4.qml")); + window->setSource(testFileUrl("keyNavigationEnabled.qml")); window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window.data())); diff --git a/tests/auto/quick/qquicklistview/data/keyNavigationEnabled.qml b/tests/auto/quick/qquicklistview/data/keyNavigationEnabled.qml new file mode 100644 index 0000000000..943b0aadbd --- /dev/null +++ b/tests/auto/quick/qquicklistview/data/keyNavigationEnabled.qml @@ -0,0 +1,14 @@ +import QtQuick 2.7 + +ListView { + width: 400 + height: 400 + model: 100 + // Ensure that the property is available in QML. + onKeyNavigationEnabledChanged: {} + delegate: Rectangle { + height: 40 + width: 400 + color: index % 2 ? "lightsteelblue" : "lightgray" + } +} diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index 61ba2caaf7..4816d9c341 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -8271,7 +8271,7 @@ void tst_QQuickListView::QTBUG_48044_currentItemNotVisibleAfterTransition() void tst_QQuickListView::keyNavigationEnabled() { QScopedPointer<QQuickView> window(createView()); - window->setSource(testFileUrl("simplelistview.qml")); + window->setSource(testFileUrl("keyNavigationEnabled.qml")); window->show(); window->requestActivate(); QVERIFY(QTest::qWaitForWindowActive(window.data())); diff --git a/tools/qmlimportscanner/main.cpp b/tools/qmlimportscanner/main.cpp index 84f0d6deb1..ec52491322 100644 --- a/tools/qmlimportscanner/main.cpp +++ b/tools/qmlimportscanner/main.cpp @@ -58,6 +58,7 @@ QStringList g_qmlImportPaths; static inline QString typeLiteral() { return QStringLiteral("type"); } static inline QString versionLiteral() { return QStringLiteral("version"); } static inline QString nameLiteral() { return QStringLiteral("name"); } +static inline QString relativePathLiteral() { return QStringLiteral("relativePath"); } static inline QString pluginsLiteral() { return QStringLiteral("plugins"); } static inline QString pathLiteral() { return QStringLiteral("path"); } static inline QString classnamesLiteral() { return QStringLiteral("classnames"); } @@ -162,8 +163,9 @@ QVariantMap pluginsForModulePath(const QString &modulePath) { return pluginInfo; } -// Search for a given qml import in g_qmlImportPaths. -QString resolveImportPath(const QString &uri, const QString &version) +// Search for a given qml import in g_qmlImportPaths and return a pair +// of absolute / relative paths (for deployment). +QPair<QString, QString> resolveImportPath(const QString &uri, const QString &version) { const QLatin1Char dot('.'); const QLatin1Char slash('/'); @@ -180,18 +182,21 @@ QString resolveImportPath(const QString &uri, const QString &version) // - qml/QtQml.2/Models // - qml/QtQml/Models if (ver.isEmpty()) { - const QString candidatePath = QDir::cleanPath(qmlImportPath + slash + parts.join(slash)); + QString relativePath = parts.join(slash); + if (relativePath.endsWith(slash)) + relativePath.chop(1); + const QString candidatePath = QDir::cleanPath(qmlImportPath + slash + relativePath); if (QDir(candidatePath).exists()) - return candidatePath; // import found + return qMakePair(candidatePath, relativePath); // import found } else { for (int index = parts.count() - 1; index >= 0; --index) { - const QString candidatePath = QDir::cleanPath(qmlImportPath + slash - + parts.mid(0, index + 1).join(slash) - + dot + ver + slash - + parts.mid(index + 1).join(slash)); - + QString relativePath = parts.mid(0, index + 1).join(slash) + + dot + ver + slash + parts.mid(index + 1).join(slash); + if (relativePath.endsWith(slash)) + relativePath.chop(1); + const QString candidatePath = QDir::cleanPath(qmlImportPath + slash + relativePath); if (QDir(candidatePath).exists()) - return candidatePath; // import found + return qMakePair(candidatePath, relativePath); // import found } } } @@ -207,7 +212,7 @@ QString resolveImportPath(const QString &uri, const QString &version) ver = ver.mid(0, lastDot); } - return QString(); // not found + return QPair<QString, QString>(); // not found } // Find absolute file system paths and plugins for a list of modules. @@ -219,9 +224,12 @@ QVariantList findPathsForModuleImports(const QVariantList &imports) for (int i = 0; i < importsCopy.length(); ++i) { QVariantMap import = qvariant_cast<QVariantMap>(importsCopy.at(i)); if (import.value(typeLiteral()) == QLatin1String("module")) { - QString path = resolveImportPath(import.value(nameLiteral()).toString(), import.value(versionLiteral()).toString()); - if (!path.isEmpty()) - import[pathLiteral()] = path; + const QPair<QString, QString> paths = + resolveImportPath(import.value(nameLiteral()).toString(), import.value(versionLiteral()).toString()); + if (!paths.first.isEmpty()) { + import.insert(pathLiteral(), paths.first); + import.insert(relativePathLiteral(), paths.second); + } QVariantMap plugininfo = pluginsForModulePath(import.value(pathLiteral()).toString()); QString plugins = plugininfo.value(pluginsLiteral()).toString(); QString classnames = plugininfo.value(classnamesLiteral()).toString(); |