aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-11-16 10:08:49 +0100
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-11-16 10:08:50 +0100
commite7c316504770ce357b2c73be485cdd8c1da9c4c1 (patch)
treeb49032420022617396a83da310ebe01b38cda8f9
parent87265c7ab8743ece92262cd6b79bbba9dddd1fe1 (diff)
parente3948955c961972d34483e7da9c2908f5cb84420 (diff)
Merge remote-tracking branch 'origin/5.12.0' into 5.12
-rw-r--r--dist/changes-5.12.0245
-rw-r--r--src/3rdparty/masm/stubs/wtf/Optional.h3
-rw-r--r--src/3rdparty/masm/yarr/YarrJIT.cpp10
-rw-r--r--src/imports/folderlistmodel/plugins.qmltypes4
-rw-r--r--src/imports/imports.pro1
-rw-r--r--src/imports/labsmodels/dependencies.json2
-rw-r--r--src/imports/labsmodels/plugins.qmltypes4
-rw-r--r--src/imports/qtquick2/plugins.qmltypes82
-rw-r--r--src/imports/wavefrontmesh/plugin.cpp20
-rw-r--r--src/imports/wavefrontmesh/qwavefrontmesh.cpp20
-rw-r--r--src/imports/wavefrontmesh/qwavefrontmesh.h20
-rw-r--r--src/imports/window/plugins.qmltypes10
-rw-r--r--src/imports/xmllistmodel/plugin.cpp67
-rw-r--r--src/imports/xmllistmodel/plugins.qmltypes59
-rw-r--r--src/imports/xmllistmodel/qmldir5
-rw-r--r--src/imports/xmllistmodel/qqmlxmllistmodel.cpp1238
-rw-r--r--src/imports/xmllistmodel/qqmlxmllistmodel_p.h219
-rw-r--r--src/imports/xmllistmodel/xmllistmodel.pro14
-rw-r--r--src/qml/compiler/qv4codegen.cpp52
-rw-r--r--src/qml/compiler/qv4compileddata.cpp38
-rw-r--r--src/qml/compiler/qv4compileddata_p.h2
-rw-r--r--src/qml/compiler/qv4compilercontext.cpp8
-rw-r--r--src/qml/configure.json18
-rw-r--r--src/qml/doc/qtqml.qdocconf2
-rw-r--r--src/qml/jit/qv4baselineassembler.cpp8
-rw-r--r--src/qml/jsruntime/qv4engine.cpp2
-rw-r--r--src/qml/jsruntime/qv4module.cpp77
-rw-r--r--src/qml/jsruntime/qv4module_p.h6
-rw-r--r--src/qml/jsruntime/qv4qmlcontext.cpp15
-rw-r--r--src/qml/jsruntime/qv4qmlcontext_p.h7
-rw-r--r--src/qml/memory/qv4mm.cpp5
-rw-r--r--src/qml/qml/qqmlinfo.cpp63
-rw-r--r--src/qml/qml/qqmltypeloader.cpp86
-rw-r--r--src/qml/qml/qqmltypeloader_p.h3
-rw-r--r--src/qml/types/qqmldelegatecomponent.cpp22
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp2
-rw-r--r--src/qml/types/qqmlitemselectionmodel.qdoc4
-rw-r--r--src/qmltest/doc/qtqmltest.qdocconf2
-rw-r--r--src/quick/doc/qtquick.qdocconf2
-rw-r--r--src/quick/doc/snippets/qml/xmlrole.qml96
-rw-r--r--tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp19
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp16
-rw-r--r--tests/auto/qml/v4misc/tst_v4misc.cpp1
-rw-r--r--tests/auto/quick/examples/examples.pro1
-rw-r--r--tests/auto/quick/examples/tst_examples.cpp6
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/empty.xml0
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/get.qml61
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/groups.qml10
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/groups.xml18
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/model.qml11
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/model.xml54
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/model2.xml14
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/propertychanges.qml11
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/proxyCrash.qml9
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/recipes.qml11
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/recipes.xml90
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/roleCrash.qml8
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/roleErrors.qml11
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/roleKeys.qml13
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/testtypes.qml8
-rw-r--r--tests/auto/quick/qquickxmllistmodel/data/unique.qml9
-rw-r--r--tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro16
-rw-r--r--tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp1011
-rw-r--r--tests/auto/quick/quick.pro6
64 files changed, 635 insertions, 3322 deletions
diff --git a/dist/changes-5.12.0 b/dist/changes-5.12.0
new file mode 100644
index 0000000000..753082a43d
--- /dev/null
+++ b/dist/changes-5.12.0
@@ -0,0 +1,245 @@
+Qt 5.12 introduces many new features and improvements as well as bugfixes
+over the 5.11.x series. For more details, refer to the online documentation
+included in this distribution. The documentation is also available online:
+
+https://doc.qt.io/qt-5/index.html
+
+The Qt version 5.12 series is binary compatible with the 5.11.x series.
+Applications compiled for 5.11 will continue to run with 5.12.
+
+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-51710] Added TableView with a similar architecture as ListView
+ (inheriting Flickable and using QQmlInstanceModel internally)
+ but 2-dimensional. It works best with a QAbstractItemModel that defines
+ multiple columns and rows (i.e. it's the QtQuick counterpart to QTableView)
+ but can also present a single-column view of other model types.
+ As an optimization, it maintains a pool of the delegate instances that
+ are visible (plus a few extras); during scrolling, as delegates fall
+ out of view, they are re-bound to show cells that have just come into view.
+ - [QTBUG-26681] Added DelegateChooser, a new type of Component to choose
+ different delegates in an Item View (e.g. TableView) depending on model
+ roles. DelegateChoice instances specify the available choices.
+ - Pointer Handlers and the Keys handler are now collectively called
+ Input Handlers [QTBUG-66651], and are fully supported as part of
+ Qt Quick 2.12 and forward. The Qt.labs.handlers import is now removed.
+ - [QTBUG-68072] Added HoverHandler to detect the position of the
+ hovering mouse or stylus pointer.
+ - The JavaScript engine now supports ECMAScript 7.
+ - ECMAScript modules can now be loaded directly with QJSEngine::importModule()
+ and imported in .qml files when using the .mjs file extension.
+ - Qt Quick applications can now be deployed via WebAssembly.
+ - The new Qt.labs.wavefrontmesh import provides an experimental
+ WavefrontMesh type which can read a Wavefront .obj file containing
+ a 2D shape, and generate a 2D mesh for use with ShaderEffect.
+
+****************************************************************************
+* Important Behavior Changes *
+****************************************************************************
+
+ - [QTBUG-7329][QTBUG-41977][QTBUG-69196] The automatic translation loading
+ in qml, qmlscene and QQmlApplicationEngine now tries to load
+ translations for all languages in QLocale::uiLanguages(). This might
+ require shipping an empty translation for the source language.
+
+****************************************************************************
+* QtQml *
+****************************************************************************
+
+ - LoggingCategory:
+ * [QTBUG-67094] Added defaultLogLevel property. It is possible to define
+ default log level that LoggingCategory is enabled for.
+
+ - QJSEngine:
+ * [QTBUG-39041] Added API to throw run-time errors.
+ * Added function to import ECMASCript modules from the file system or
+ the Qt resource system.
+ * [QTBUG-71083] Fixed a stack overflow in the parser.
+ * [QTBUG-70632] It's now OK to declare a class in a .mjs module.
+ * [QTBUG-69475] Fixed quadratic behavior when allocating large objects.
+
+ - QQmlEngine:
+ * [QTBUG-56150] QML cache files are now always stored in the
+ application's cache directory when being generated at run-time. If
+ precompiled QML files exist at the source location, then they are
+ loaded and no cache file is being generated. The application's
+ uninstaller is responsible for cleaning up the cache during removal.
+ * [QTBUG-39970] Added API to access singletons associated with a
+ QQmlEngine.
+ * [QTBUG-53111] The onStatusChanged signal from the incubator object
+ that is returned from Component.incubateObject() is more reliable.
+ * [QTBUG-70425] Fixed translation contexts for paths with drive letters
+ on Windows
+ * [QTBUG-68350] Fix QQmlEngine::retranslate() with ListElement objects
+ that use translation functions such as qsTr.
+ * [QTBUG-51581] Properties of the JS global object will now be looked up
+ after local properties in the QML object. This can lead to runtime
+ incompatibilities if your qml file is named the same as a property of
+ the global object (e.g. Date.qml).
+ * [QTBUG-71184] Enums in subclasses can overwrite inherited enums.
+ * Added option to disable unscoped registration of enum classes.
+ * [QTBUG-69884] Fixed the visibility of the Connections.enabled property
+ to appear only when importing QtQml/QtQuick >= 2.3, which was introduced
+ with Qt 5.7. Otherwise it would accidentally shadow an "enabled"
+ context property, for example.
+
+ - QtTest:
+ * We now call cleanupTestCase() on the object given to QUICK_TEST_MAIN
+ before starting destruction.
+ * Add test init function to be called when application object is
+ available.
+ * [QTBUG-47111] ignoreWarning now supports ignoring regular expressions
+ as well as strings.
+
+****************************************************************************
+* QtQuick *
+****************************************************************************
+
+ - Input Handlers:
+ * The QQuickEventPoint::GrabState enum is renamed to GrabTransition.
+ * [QTBUG-68941] PinchHandler.scale is now persistent between gestures,
+ i.e. it's the same as the target Item's scale property if there is a
+ target. Added an activeScale property to provide the scaling value
+ during a single pinch gesture (activeScale will be 1.0 whenever the
+ PinchHandler is not active, whereas the scale property was unintuitively
+ behaving that way in previous versions). This change is intended to
+ increase flexibility when the scaling is not done by setting an Item's
+ scale property, but by other means.
+ * [QTBUG-68077] The pointDistanceThreshold property is renamed to
+ margin, and now allows activating any pointer handler within a margin
+ around the parent Item. This makes it easier to pinch a PinchHandler
+ on a small item, makes it easier to comply with Fitts's Law when
+ a button with a TapHandler is near a screen edge, etc. If margin
+ is set, it overrides the parent Item's containmentMask, if any.
+ * [QTBUG-68106] DragHandler is now a multi-point handler: if
+ declared with minimumPointCount: 2 for example, it will require
+ two fingers to initiate the drag. This is especially useful with
+ target: null to handle 2-finger-drag for some alternate purpose.
+ * DragHandler and PinchHandler (and other future MultiPointHandler
+ subclasses) now have a centroid property, since that is usually
+ the focal point of the action or gesture being performed.
+ * [QTBUG-68101] QQuickHandlerPoint (i.e. a handler's centroid or
+ other exposed point property) includes a modifiers property so
+ that you can see which keyboard modifiers are being held.
+ * [QTBUG-61749][QTBUG-64847] The TapHandler.tapped signal includes an
+ eventPoint parameter so that you can see which button was tapped.
+ * [QTBUG-68074] The PointerHandler.grabChanged signal includes a
+ stateChange parameter so that you can see whether the grab was
+ acquired or lost.
+ * [QTBUG-70075] PinchHandler.centroid now has correct property values
+ on a macOS trackpad.
+ * [QTBUG-70292] The PinchHandler.pinchOrigin property is removed.
+ * [QTBUG-66360] PointHandler handles presses and releases of multiple
+ mouse buttons correctly.
+ * [QTBUG-69607] DragHandler doesn't react to mouse wheel events.
+ * [QTBUG-65012] TapHandler doesn't emit longPressed if the point
+ is dragged.
+
+ - AnimatedSprite:
+ * Added finished() signal to AnimatedSprite as a convenient way to react
+ to an animation finishing.
+
+ - Animation:
+ * Added finished() signal to Animation as a convenient way to react to
+ an animation finishing naturally.
+
+ - Canvas:
+ * [QTBUG-31807] Added set/get lineDash and lineDashOffset to Context2D
+ to allow non solid lines to be drawn.
+
+ - Image:
+ * [QTBUG-66116] Fixed a memory leak in Image in an invisible window.
+
+ - Item:
+ * There's now a warning whenever an Item has multiple states with the
+ same name.
+ * [QTBUG-68271] Fixed an infinite loop in tab focus chain when visiting
+ invisible items.
+
+ - MultiPointTouchArea:
+ * [QTBUG-70258] Avoid emitting gestureStarted until the drag threshold
+ is actually exceeded. In a QML onGestureStarted callback,
+ gesture.touchPoints[0].startX and startY now have correct values.
+
+ - Rectangle:
+ * Added support for horizontal gradients.
+
+ - Repeater:
+ * [QTBUG-54752] If the model is an integer, it must be less than
+ 100,000,000 to avoid running out of memory.
+
+ - Shape:
+ * [QTBUG-66843][QTBUG-66457] The Shape item will not try to use
+ GL_NV_path_rendering by default, unless explicitly requested.
+ Thus the default value of enableVendorExtensions is now false.
+
+ - Flickable and Item Views:
+ * [QTBUG-62902] Added a synchronousDrag property that makes the content
+ jump to the position it would have had if there was no drag threshold,
+ as soon as dragging begins.
+ * [QTBUG-70742][QTBUG-70941] We now cancel flicking when the model is
+ reset, and when programmatically positioning the content, to avoid
+ wasting time instantiating irrelevant delegates.
+ * [QTBUG-49224] Fixed a crash by avoiding movement during layout.
+ * [QTBUG-67051] Improved interaction between snapping and sections.
+ * [QTBUG-69863] GridView LeftMargin and RightMargin are taken into
+ account when calculating positions and columns.
+ * [QTBUG-69059][QTBUG-61144] Fixed the regression that when a
+ mouse-handling Item or Control is used in a Flickable with a
+ pressDelay, the delegate item did not receive touchscreen taps
+ (in the form of mouse clicks). This fix was in 5.9.4 but somehow
+ did not get merged forward into 5.10 and 5.11.
+ * [QTBUG-59620] PathView calls setKeepMouseGrab() so that a parent
+ Flickable will not steal the grab from it.
+
+ - Text:
+ * [QTBUG-53279] Fixed an issue where updating text inside a layout would
+ not cause it to correctly adapt to its new width.
+ * [QTBUG-69356] Support pregenerated loading distance field glyph caches
+ to decrease startup time for applications with large amounts of text.
+
+ - QQuickWindow:
+ * [QTBUG-52748] You can now disable touch->mouse event synthesis in
+ QtQuick by calling
+ qGuiApp.setAttribute(Qt::AA_SynthesizeMouseForUnhandledTouchEvents,
+ false). This will simplify and speed up event delivery, and it will
+ also prevent any and all interaction with mouse-only items like
+ MouseArea and Flickable on a touchscreen.
+ * [QTBUG-70998] Touch->mouse synthesis is canceled when the touch
+ is ungrabbed, rather than when a new touchpoint is pressed. Thus
+ if you are using one finger to interact with a legacy mouse-handling
+ Item, and you press a second finger, the first interaction doesn't
+ necessarily end right away, unless some other handler steals the
+ grab from the first Item.
+ * [QTBUG-70898] Emit a warning rather than crashing if user code
+ calls sendEvent() while a pointer event is being delivered.
+ Nested event delivery is not possible because of the way that
+ the QQuickPointerEvent instances are reused for subsequent events.
+
+ - FolderListModel:
+ * [QTBUG-48757][QTBUG-70212] Added a sortCaseSensitive property that
+ can be set to false to sort filenames in a case-insensitive manner.
+
+ - Software renderer:
+ * [QTBUG-70740] Fixed a memory leak.
+ * Fixed QSGImageNode with QSGLayer.
+ * [QTBUG-68085] Italic text is no longer cut improperly due to line wrap.
+ * [QTBUG-70422] If Qt is built without support for threads, single-threaded
+ rendering is used. (This includes the WebAssembly use case.)
+
+ - Platform Specific Changes:
+ * [QTBUG-63026][QTBUG-65160] Now that macOS provides a proper
+ ScrollMomentum phase in QWheelEvent, Flickable responds more
+ precisely when simulated momentum on the trackpad comes to an
+ end, rather than using a timer to wait for it to end. This improves
+ robustness in some cases where scrolling was jumpy in older versions.
diff --git a/src/3rdparty/masm/stubs/wtf/Optional.h b/src/3rdparty/masm/stubs/wtf/Optional.h
index 235730a87d..fdb7de51ce 100644
--- a/src/3rdparty/masm/stubs/wtf/Optional.h
+++ b/src/3rdparty/masm/stubs/wtf/Optional.h
@@ -40,6 +40,7 @@
#pragma once
#include <QtCore/qglobal.h>
+#include <QtQml/private/qtqmlglobal_p.h>
#include <memory>
#if __cplusplus > 201402L && QT_HAS_INCLUDE(<optional>)
@@ -83,7 +84,7 @@ private:
#endif
-#if __cplusplus < 201402L && !defined(__cpp_lib_make_unique) && !defined(Q_CC_MSVC) && !defined(Q_CC_GHS)
+#if __cplusplus < 201402L && !QT_CONFIG(cxx14_make_unique)
namespace std {
template<typename T, class ...Args>
diff --git a/src/3rdparty/masm/yarr/YarrJIT.cpp b/src/3rdparty/masm/yarr/YarrJIT.cpp
index ce7c7163ed..9a9ab581e8 100644
--- a/src/3rdparty/masm/yarr/YarrJIT.cpp
+++ b/src/3rdparty/masm/yarr/YarrJIT.cpp
@@ -177,11 +177,21 @@ class YarrGenerator : private DefaultMacroAssembler {
uint32_t begin;
uint32_t matchAmount;
uintptr_t returnAddress;
+#if OS(INTEGRITY)
+ union {
+ struct Subpatterns {
+ unsigned start;
+ unsigned end;
+ } subpatterns[1];
+ uintptr_t frameSlots[1];
+ };
+#else
struct Subpatterns {
unsigned start;
unsigned end;
} subpatterns[0];
uintptr_t frameSlots[0];
+#endif
static size_t sizeFor(ParenContextSizes& parenContextSizes)
{
diff --git a/src/imports/folderlistmodel/plugins.qmltypes b/src/imports/folderlistmodel/plugins.qmltypes
index cfa4765116..fd92ab9960 100644
--- a/src/imports/folderlistmodel/plugins.qmltypes
+++ b/src/imports/folderlistmodel/plugins.qmltypes
@@ -16,9 +16,10 @@ Module {
"Qt.labs.folderlistmodel/FolderListModel 2.0",
"Qt.labs.folderlistmodel/FolderListModel 2.1",
"Qt.labs.folderlistmodel/FolderListModel 2.11",
+ "Qt.labs.folderlistmodel/FolderListModel 2.12",
"Qt.labs.folderlistmodel/FolderListModel 2.2"
]
- exportMetaObjectRevisions: [0, 0, 1, 11, 2]
+ exportMetaObjectRevisions: [0, 0, 1, 11, 12, 2]
Enum {
name: "SortField"
values: {
@@ -52,6 +53,7 @@ Module {
Property { name: "caseSensitive"; revision: 2; type: "bool" }
Property { name: "count"; type: "int"; isReadonly: true }
Property { name: "status"; revision: 11; type: "Status"; isReadonly: true }
+ Property { name: "sortCaseSensitive"; revision: 12; type: "bool" }
Signal { name: "rowCountChanged" }
Signal { name: "countChanged"; revision: 1 }
Signal { name: "statusChanged"; revision: 11 }
diff --git a/src/imports/imports.pro b/src/imports/imports.pro
index cf49deb03c..24e93fec1c 100644
--- a/src/imports/imports.pro
+++ b/src/imports/imports.pro
@@ -28,4 +28,3 @@ qtHaveModule(quick) {
qtConfig(quick-path):qtConfig(thread): SUBDIRS += shapes
}
-qtHaveModule(xmlpatterns) : SUBDIRS += xmllistmodel
diff --git a/src/imports/labsmodels/dependencies.json b/src/imports/labsmodels/dependencies.json
new file mode 100644
index 0000000000..0d4f101c7a
--- /dev/null
+++ b/src/imports/labsmodels/dependencies.json
@@ -0,0 +1,2 @@
+[
+]
diff --git a/src/imports/labsmodels/plugins.qmltypes b/src/imports/labsmodels/plugins.qmltypes
index 606b8712da..6272069060 100644
--- a/src/imports/labsmodels/plugins.qmltypes
+++ b/src/imports/labsmodels/plugins.qmltypes
@@ -4,10 +4,10 @@ import QtQuick.tooling 1.2
// It is used for QML tooling purposes only.
//
// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable Qt.labs.qmlmodels 1.0'
+// 'qmlplugindump -nonrelocatable -dependencies dependencies.json Qt.labs.qmlmodels 1.0'
Module {
- dependencies: ["QtQuick 2.12"]
+ dependencies: []
Component {
name: "QQmlAbstractDelegateComponent"
prototype: "QQmlComponent"
diff --git a/src/imports/qtquick2/plugins.qmltypes b/src/imports/qtquick2/plugins.qmltypes
index 456db6316e..035c13a4d3 100644
--- a/src/imports/qtquick2/plugins.qmltypes
+++ b/src/imports/qtquick2/plugins.qmltypes
@@ -922,6 +922,21 @@ Module {
Component {
name: "QQuickAnchors"
prototype: "QObject"
+ Enum {
+ name: "Anchors"
+ values: {
+ "InvalidAnchor": 0,
+ "LeftAnchor": 1,
+ "RightAnchor": 2,
+ "TopAnchor": 4,
+ "BottomAnchor": 8,
+ "HCenterAnchor": 16,
+ "VCenterAnchor": 32,
+ "BaselineAnchor": 64,
+ "Horizontal_Mask": 19,
+ "Vertical_Mask": 108
+ }
+ }
Property { name: "left"; type: "QQuickAnchorLine" }
Property { name: "right"; type: "QQuickAnchorLine" }
Property { name: "horizontalCenter"; type: "QQuickAnchorLine" }
@@ -1688,10 +1703,6 @@ Module {
Signal { name: "synchronousDragChanged"; revision: 12 }
Signal { name: "horizontalOvershootChanged"; revision: 9 }
Signal { name: "verticalOvershootChanged"; revision: 9 }
- Signal { name: "atXEndChanged"; revision: 12 }
- Signal { name: "atYEndChanged"; revision: 12 }
- Signal { name: "atXBeginningChanged"; revision: 12 }
- Signal { name: "atYBeginningChanged"; revision: 12 }
Method {
name: "resizeContent"
Parameter { name: "w"; type: "double" }
@@ -2231,6 +2242,16 @@ Module {
]
exportMetaObjectRevisions: [0, 1, 11, 2, 7]
Enum {
+ name: "Flags"
+ values: {
+ "ItemClipsChildrenToShape": 1,
+ "ItemAcceptsInputMethod": 2,
+ "ItemIsFocusScope": 4,
+ "ItemHasContents": 8,
+ "ItemAcceptsDrops": 16
+ }
+ }
+ Enum {
name: "TransformOrigin"
values: {
"TopLeft": 0,
@@ -3095,6 +3116,12 @@ Module {
"InvertedYFramebufferObject": 2
}
}
+ Enum {
+ name: "PerformanceHints"
+ values: {
+ "FastFBOResizing": 1
+ }
+ }
Property { name: "contentsSize"; type: "QSize" }
Property { name: "fillColor"; type: "QColor" }
Property { name: "contentsScale"; type: "double" }
@@ -3536,19 +3563,6 @@ Module {
isCreatable: false
exportMetaObjectRevisions: [0]
Enum {
- name: "DeviceType"
- values: {
- "UnknownDevice": 0,
- "Mouse": 1,
- "TouchScreen": 2,
- "TouchPad": 4,
- "Puck": 8,
- "Stylus": 16,
- "Airbrush": 32,
- "AllDevices": 32767
- }
- }
- Enum {
name: "DeviceTypes"
values: {
"UnknownDevice": 0,
@@ -3562,17 +3576,6 @@ Module {
}
}
Enum {
- name: "PointerType"
- values: {
- "GenericPointer": 1,
- "Finger": 2,
- "Pen": 4,
- "Eraser": 8,
- "Cursor": 16,
- "AllPointerTypes": 32767
- }
- }
- Enum {
name: "PointerTypes"
values: {
"GenericPointer": 1,
@@ -3584,21 +3587,6 @@ Module {
}
}
Enum {
- name: "CapabilityFlag"
- values: {
- "Position": 1,
- "Area": 2,
- "Pressure": 4,
- "Velocity": 8,
- "MouseEmulation": 64,
- "Scroll": 256,
- "Hover": 512,
- "Rotation": 1024,
- "XTilt": 2048,
- "YTilt": 4096
- }
- }
- Enum {
name: "Capabilities"
values: {
"Position": 1,
@@ -4340,10 +4328,6 @@ Module {
Property { name: "columns"; type: "int"; isReadonly: true }
Property { name: "rowSpacing"; type: "double" }
Property { name: "columnSpacing"; type: "double" }
- Property { name: "topMargin"; type: "double" }
- Property { name: "bottomMargin"; type: "double" }
- Property { name: "leftMargin"; type: "double" }
- Property { name: "rightMargin"; type: "double" }
Property { name: "rowHeightProvider"; type: "QJSValue" }
Property { name: "columnWidthProvider"; type: "QJSValue" }
Property { name: "model"; type: "QVariant" }
@@ -4351,8 +4335,6 @@ Module {
Property { name: "reuseItems"; type: "bool" }
Property { name: "contentWidth"; type: "double" }
Property { name: "contentHeight"; type: "double" }
- Signal { name: "contentWidthOverrideChanged" }
- Signal { name: "contentHeightOverrideChanged" }
Method { name: "forceLayout" }
}
Component {
@@ -4559,12 +4541,10 @@ Module {
Signal { name: "contentSizeChanged" }
Signal {
name: "contentWidthChanged"
- revision: 12
Parameter { name: "contentWidth"; type: "double" }
}
Signal {
name: "contentHeightChanged"
- revision: 12
Parameter { name: "contentHeight"; type: "double" }
}
Signal {
diff --git a/src/imports/wavefrontmesh/plugin.cpp b/src/imports/wavefrontmesh/plugin.cpp
index c974db1161..1a266b7e36 100644
--- a/src/imports/wavefrontmesh/plugin.cpp
+++ b/src/imports/wavefrontmesh/plugin.cpp
@@ -5,7 +5,7 @@
**
** This file is part of the QtQuick module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:GPL$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
@@ -14,14 +14,24 @@
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 or (at your option) any later version
-** approved by the KDE Free Qt Foundation. The licenses are as published by
-** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/imports/wavefrontmesh/qwavefrontmesh.cpp b/src/imports/wavefrontmesh/qwavefrontmesh.cpp
index 3cf1211aae..101e6ab4b0 100644
--- a/src/imports/wavefrontmesh/qwavefrontmesh.cpp
+++ b/src/imports/wavefrontmesh/qwavefrontmesh.cpp
@@ -5,7 +5,7 @@
**
** This file is part of the QtQuick module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:GPL$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
@@ -14,14 +14,24 @@
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 or (at your option) any later version
-** approved by the KDE Free Qt Foundation. The licenses are as published by
-** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/imports/wavefrontmesh/qwavefrontmesh.h b/src/imports/wavefrontmesh/qwavefrontmesh.h
index a13dc780fa..e3ded8078e 100644
--- a/src/imports/wavefrontmesh/qwavefrontmesh.h
+++ b/src/imports/wavefrontmesh/qwavefrontmesh.h
@@ -5,7 +5,7 @@
**
** This file is part of the QtQuick module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:GPL$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
@@ -14,14 +14,24 @@
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 or (at your option) any later version
-** approved by the KDE Free Qt Foundation. The licenses are as published by
-** the Free Software Foundation and appearing in the file LICENSE.GPL3
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/imports/window/plugins.qmltypes b/src/imports/window/plugins.qmltypes
index 8ecb09968c..79fa40dbb2 100644
--- a/src/imports/window/plugins.qmltypes
+++ b/src/imports/window/plugins.qmltypes
@@ -78,6 +78,16 @@ Module {
exports: ["QtQuick.Window/Window 2.0"]
exportMetaObjectRevisions: [0]
Enum {
+ name: "CreateTextureOptions"
+ values: {
+ "TextureHasAlphaChannel": 1,
+ "TextureHasMipmaps": 2,
+ "TextureOwnsGLTexture": 4,
+ "TextureCanUseAtlas": 8,
+ "TextureIsOpaque": 16
+ }
+ }
+ Enum {
name: "SceneGraphError"
values: {
"ContextNotAvailable": 1
diff --git a/src/imports/xmllistmodel/plugin.cpp b/src/imports/xmllistmodel/plugin.cpp
deleted file mode 100644
index c5356b8534..0000000000
--- a/src/imports/xmllistmodel/plugin.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtQml/qqmlextensionplugin.h>
-#include <QtQml/qqml.h>
-
-#include "qqmlxmllistmodel_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QmlXmlListModelPlugin : public QQmlExtensionPlugin
-{
- Q_OBJECT
- Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
-
-public:
- QmlXmlListModelPlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { }
- void registerTypes(const char *uri) override
- {
- Q_ASSERT(QLatin1String(uri) == QLatin1String("QtQuick.XmlListModel"));
- qmlRegisterType<QQuickXmlListModel>(uri,2,0,"XmlListModel");
- qmlRegisterType<QQuickXmlListModelRole>(uri,2,0,"XmlRole");
-
- // Auto-increment the import to stay in sync with ALL future QtQuick minor versions from 5.11 onward
- qmlRegisterModule(uri, 2, QT_VERSION_MINOR);
- }
-};
-
-QT_END_NAMESPACE
-
-#include "plugin.moc"
diff --git a/src/imports/xmllistmodel/plugins.qmltypes b/src/imports/xmllistmodel/plugins.qmltypes
deleted file mode 100644
index 951d0b6eeb..0000000000
--- a/src/imports/xmllistmodel/plugins.qmltypes
+++ /dev/null
@@ -1,59 +0,0 @@
-import QtQuick.tooling 1.2
-
-// This file describes the plugin-supplied types contained in the library.
-// It is used for QML tooling purposes only.
-//
-// This file was auto-generated by:
-// 'qmlplugindump -nonrelocatable QtQuick.XmlListModel 2.12'
-
-Module {
- dependencies: ["QtQuick 2.12"]
- Component {
- name: "QQuickXmlListModel"
- defaultProperty: "roles"
- prototype: "QAbstractListModel"
- exports: ["QtQuick.XmlListModel/XmlListModel 2.0"]
- exportMetaObjectRevisions: [0]
- Enum {
- name: "Status"
- values: {
- "Null": 0,
- "Ready": 1,
- "Loading": 2,
- "Error": 3
- }
- }
- Property { name: "status"; type: "Status"; isReadonly: true }
- Property { name: "progress"; type: "double"; isReadonly: true }
- Property { name: "source"; type: "QUrl" }
- Property { name: "xml"; type: "string" }
- Property { name: "query"; type: "string" }
- Property { name: "namespaceDeclarations"; type: "string" }
- Property { name: "roles"; type: "QQuickXmlListModelRole"; isList: true; isReadonly: true }
- Property { name: "count"; type: "int"; isReadonly: true }
- Signal {
- name: "statusChanged"
- Parameter { type: "QQuickXmlListModel::Status" }
- }
- Signal {
- name: "progressChanged"
- Parameter { name: "progress"; type: "double" }
- }
- Method { name: "reload" }
- Method {
- name: "get"
- type: "QQmlV4Handle"
- Parameter { name: "index"; type: "int" }
- }
- Method { name: "errorString"; type: "string" }
- }
- Component {
- name: "QQuickXmlListModelRole"
- prototype: "QObject"
- exports: ["QtQuick.XmlListModel/XmlRole 2.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "name"; type: "string" }
- Property { name: "query"; type: "string" }
- Property { name: "isKey"; type: "bool" }
- }
-}
diff --git a/src/imports/xmllistmodel/qmldir b/src/imports/xmllistmodel/qmldir
deleted file mode 100644
index 1f17dbb112..0000000000
--- a/src/imports/xmllistmodel/qmldir
+++ /dev/null
@@ -1,5 +0,0 @@
-module QtQuick.XmlListModel
-plugin qmlxmllistmodelplugin
-classname QmlXmlListModelPlugin
-typeinfo plugins.qmltypes
-designersupported
diff --git a/src/imports/xmllistmodel/qqmlxmllistmodel.cpp b/src/imports/xmllistmodel/qqmlxmllistmodel.cpp
deleted file mode 100644
index 470b419c1f..0000000000
--- a/src/imports/xmllistmodel/qqmlxmllistmodel.cpp
+++ /dev/null
@@ -1,1238 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qqmlxmllistmodel_p.h"
-
-#include <qqmlcontext.h>
-#include <private/qqmlengine_p.h>
-#include <private/qv8engine_p.h>
-#include <private/qv4value_p.h>
-#include <private/qv4engine_p.h>
-#include <private/qv4object_p.h>
-
-#include <QDebug>
-#include <QStringList>
-#include <QMap>
-#include <QThread>
-#include <QXmlQuery>
-#include <QXmlResultItems>
-#include <QXmlNodeModelIndex>
-#include <QBuffer>
-#if QT_CONFIG(qml_network)
-#include <QNetworkRequest>
-#include <QNetworkReply>
-#endif
-#include <QTimer>
-#include <QMutex>
-
-#include <private/qabstractitemmodel_p.h>
-
-Q_DECLARE_METATYPE(QQuickXmlQueryResult)
-
-QT_BEGIN_NAMESPACE
-
-using namespace QV4;
-
-typedef QPair<int, int> QQuickXmlListRange;
-
-#define XMLLISTMODEL_CLEAR_ID 0
-
-/*!
- \qmlmodule QtQuick.XmlListModel 2.\QtMinorVersion
- \title Qt Quick XmlListModel QML Types
- \ingroup qmlmodules
- \brief Provides QML types for creating models from XML data
-
- This QML module contains types for creating models from XML data.
-
- To use the types in this module, import the module with the following line:
-
- \qml \QtMinorVersion
- import QtQuick.XmlListModel 2.\1
- \endqml
-*/
-
-/*!
- \qmltype XmlRole
- \instantiates QQuickXmlListModelRole
- \inqmlmodule QtQuick.XmlListModel
- \brief For specifying a role to an XmlListModel.
- \ingroup qtquick-models
-
- \sa {Qt QML}
-*/
-
-/*!
- \qmlproperty string QtQuick.XmlListModel::XmlRole::name
-
- The name for the role. This name is used to access the model data for this role.
-
- For example, the following model has a role named "title", which can be accessed
- from the view's delegate:
-
- \qml
- XmlListModel {
- id: xmlModel
- // ...
- XmlRole {
- name: "title"
- query: "title/string()"
- }
- }
- \endqml
-
- \qml
- ListView {
- model: xmlModel
- delegate: Text { text: title }
- }
- \endqml
-*/
-
-/*!
- \qmlproperty string QtQuick.XmlListModel::XmlRole::query
- The relative XPath expression query for this role. The query must be relative; it cannot start
- with a '/'.
-
- For example, if there is an XML document like this:
-
- \quotefile qml/xmlrole.xml
- Here are some valid XPath expressions for XmlRole queries on this document:
-
- \snippet qml/xmlrole.qml 0
- \dots 4
- \snippet qml/xmlrole.qml 1
-
- Accessing the model data for the above roles from a delegate:
-
- \snippet qml/xmlrole.qml 2
-
- See the \l{http://www.w3.org/TR/xpath20/}{W3C XPath 2.0 specification} for more information.
-*/
-
-/*!
- \qmlproperty bool QtQuick.XmlListModel::XmlRole::isKey
- Defines whether this is a key role.
- Key roles are used to determine whether a set of values should
- be updated or added to the XML list model when XmlListModel::reload()
- is called.
-
- \sa XmlListModel
-*/
-
-struct XmlQueryJob
-{
- int queryId;
- QByteArray data;
- QString query;
- QString namespaces;
- QStringList roleQueries;
- QList<void*> roleQueryErrorId; // the ptr to send back if there is an error
- QStringList keyRoleQueries;
- QStringList keyRoleResultsCache;
- QString prefix;
-};
-
-
-class QQuickXmlQueryEngine;
-class QQuickXmlQueryThreadObject : public QObject
-{
- Q_OBJECT
-public:
- QQuickXmlQueryThreadObject(QQuickXmlQueryEngine *);
-
- void processJobs();
- bool event(QEvent *e) override;
-
-private:
- QQuickXmlQueryEngine *m_queryEngine;
-};
-
-
-class QQuickXmlQueryEngine : public QThread
-{
- Q_OBJECT
-public:
- QQuickXmlQueryEngine(QQmlEngine *eng);
- ~QQuickXmlQueryEngine();
-
- int doQuery(QString query, QString namespaces, QByteArray data, QList<QQuickXmlListModelRole *>* roleObjects, QStringList keyRoleResultsCache);
- void abort(int id);
-
- void processJobs();
-
- static QQuickXmlQueryEngine *instance(QQmlEngine *engine);
-
-signals:
- void queryCompleted(const QQuickXmlQueryResult &);
- void error(void*, const QString&);
-
-protected:
- void run() override;
-
-private:
- void processQuery(XmlQueryJob *job);
- void doQueryJob(XmlQueryJob *job, QQuickXmlQueryResult *currentResult);
- void doSubQueryJob(XmlQueryJob *job, QQuickXmlQueryResult *currentResult);
- void getValuesOfKeyRoles(const XmlQueryJob& currentJob, QStringList *values, QXmlQuery *query) const;
- void addIndexToRangeList(QList<QQuickXmlListRange> *ranges, int index) const;
-
- QMutex m_mutex;
- QQuickXmlQueryThreadObject *m_threadObject;
- QList<XmlQueryJob> m_jobs;
- QSet<int> m_cancelledJobs;
- QAtomicInt m_queryIds;
-
- QQmlEngine *m_engine;
- QObject *m_eventLoopQuitHack;
-
- static QHash<QQmlEngine *,QQuickXmlQueryEngine*> queryEngines;
- static QMutex queryEnginesMutex;
-};
-QHash<QQmlEngine *,QQuickXmlQueryEngine*> QQuickXmlQueryEngine::queryEngines;
-QMutex QQuickXmlQueryEngine::queryEnginesMutex;
-
-
-QQuickXmlQueryThreadObject::QQuickXmlQueryThreadObject(QQuickXmlQueryEngine *e)
- : m_queryEngine(e)
-{
-}
-
-void QQuickXmlQueryThreadObject::processJobs()
-{
- QCoreApplication::postEvent(this, new QEvent(QEvent::User));
-}
-
-bool QQuickXmlQueryThreadObject::event(QEvent *e)
-{
- if (e->type() == QEvent::User) {
- m_queryEngine->processJobs();
- return true;
- } else {
- return QObject::event(e);
- }
-}
-
-
-
-QQuickXmlQueryEngine::QQuickXmlQueryEngine(QQmlEngine *eng)
-: QThread(eng), m_threadObject(0), m_queryIds(XMLLISTMODEL_CLEAR_ID + 1), m_engine(eng), m_eventLoopQuitHack(0)
-{
- qRegisterMetaType<QQuickXmlQueryResult>("QQuickXmlQueryResult");
-
- m_eventLoopQuitHack = new QObject;
- m_eventLoopQuitHack->moveToThread(this);
- connect(m_eventLoopQuitHack, SIGNAL(destroyed(QObject*)), SLOT(quit()), Qt::DirectConnection);
- start(QThread::IdlePriority);
-}
-
-QQuickXmlQueryEngine::~QQuickXmlQueryEngine()
-{
- queryEnginesMutex.lock();
- queryEngines.remove(m_engine);
- queryEnginesMutex.unlock();
-
- m_eventLoopQuitHack->deleteLater();
- wait();
-}
-
-int QQuickXmlQueryEngine::doQuery(QString query, QString namespaces, QByteArray data, QList<QQuickXmlListModelRole *>* roleObjects, QStringList keyRoleResultsCache) {
- {
- QMutexLocker m1(&m_mutex);
- m_queryIds.ref();
- if (m_queryIds.load() <= 0)
- m_queryIds.store(1);
- }
-
- XmlQueryJob job;
- job.queryId = m_queryIds.load();
- job.data = data;
- job.query = QLatin1String("doc($src)") + query;
- job.namespaces = namespaces;
- job.keyRoleResultsCache = keyRoleResultsCache;
-
- for (int i=0; i<roleObjects->count(); i++) {
- if (!roleObjects->at(i)->isValid()) {
- job.roleQueries << QString();
- continue;
- }
- job.roleQueries << roleObjects->at(i)->query();
- job.roleQueryErrorId << static_cast<void*>(roleObjects->at(i));
- if (roleObjects->at(i)->isKey())
- job.keyRoleQueries << job.roleQueries.last();
- }
-
- {
- QMutexLocker ml(&m_mutex);
- m_jobs.append(job);
- if (m_threadObject)
- m_threadObject->processJobs();
- }
-
- return job.queryId;
-}
-
-void QQuickXmlQueryEngine::abort(int id)
-{
- QMutexLocker ml(&m_mutex);
- if (id != -1)
- m_cancelledJobs.insert(id);
-}
-
-void QQuickXmlQueryEngine::run()
-{
- m_mutex.lock();
- m_threadObject = new QQuickXmlQueryThreadObject(this);
- m_mutex.unlock();
-
- processJobs();
- exec();
-
- delete m_threadObject;
- m_threadObject = 0;
-}
-
-void QQuickXmlQueryEngine::processJobs()
-{
- QMutexLocker locker(&m_mutex);
-
- while (true) {
- if (m_jobs.isEmpty())
- return;
-
- XmlQueryJob currentJob = m_jobs.takeLast();
- while (m_cancelledJobs.remove(currentJob.queryId)) {
- if (m_jobs.isEmpty())
- return;
- currentJob = m_jobs.takeLast();
- }
-
- locker.unlock();
- processQuery(&currentJob);
- locker.relock();
- }
-}
-
-QQuickXmlQueryEngine *QQuickXmlQueryEngine::instance(QQmlEngine *engine)
-{
- queryEnginesMutex.lock();
- QQuickXmlQueryEngine *queryEng = queryEngines.value(engine);
- if (!queryEng) {
- queryEng = new QQuickXmlQueryEngine(engine);
- queryEngines.insert(engine, queryEng);
- }
- queryEnginesMutex.unlock();
-
- return queryEng;
-}
-
-void QQuickXmlQueryEngine::processQuery(XmlQueryJob *job)
-{
- QQuickXmlQueryResult result;
- result.queryId = job->queryId;
- doQueryJob(job, &result);
- doSubQueryJob(job, &result);
-
- {
- QMutexLocker ml(&m_mutex);
- if (m_cancelledJobs.contains(job->queryId)) {
- m_cancelledJobs.remove(job->queryId);
- } else {
- emit queryCompleted(result);
- }
- }
-}
-
-void QQuickXmlQueryEngine::doQueryJob(XmlQueryJob *currentJob, QQuickXmlQueryResult *currentResult)
-{
- Q_ASSERT(currentJob->queryId != -1);
-
- QString r;
- QXmlQuery query;
- QBuffer buffer(&currentJob->data);
- buffer.open(QIODevice::ReadOnly);
- query.bindVariable(QLatin1String("src"), &buffer);
- query.setQuery(currentJob->namespaces + currentJob->query);
- query.evaluateTo(&r);
-
- //always need a single root element
- QByteArray xml = "<dummy:items xmlns:dummy=\"http://qtsotware.com/dummy\">\n" + r.toUtf8() + "</dummy:items>";
- QBuffer b(&xml);
- b.open(QIODevice::ReadOnly);
-
- QString namespaces = QLatin1String("declare namespace dummy=\"http://qtsotware.com/dummy\";\n") + currentJob->namespaces;
- QString prefix = QLatin1String("doc($inputDocument)/dummy:items/*");
-
- //figure out how many items we are dealing with
- int count = -1;
- {
- QXmlResultItems result;
- QXmlQuery countquery;
- countquery.bindVariable(QLatin1String("inputDocument"), &b);
- countquery.setQuery(namespaces + QLatin1String("count(") + prefix + QLatin1Char(')'));
- countquery.evaluateTo(&result);
- QXmlItem item(result.next());
- if (item.isAtomicValue())
- count = item.toAtomicValue().toInt();
- }
-
- currentJob->data = xml;
- currentJob->prefix = namespaces + prefix + QLatin1Char('/');
- currentResult->size = (count > 0 ? count : 0);
-}
-
-void QQuickXmlQueryEngine::getValuesOfKeyRoles(const XmlQueryJob& currentJob, QStringList *values, QXmlQuery *query) const
-{
- const QStringList &keysQueries = currentJob.keyRoleQueries;
- QString keysQuery;
- if (keysQueries.count() == 1)
- keysQuery = currentJob.prefix + keysQueries[0];
- else if (keysQueries.count() > 1)
- keysQuery = currentJob.prefix + QLatin1String("concat(") + keysQueries.join(QLatin1Char(',')) + QLatin1Char(')');
-
- if (!keysQuery.isEmpty()) {
- query->setQuery(keysQuery);
- QXmlResultItems resultItems;
- query->evaluateTo(&resultItems);
- QXmlItem item(resultItems.next());
- while (!item.isNull()) {
- values->append(item.toAtomicValue().toString());
- item = resultItems.next();
- }
- }
-}
-
-void QQuickXmlQueryEngine::addIndexToRangeList(QList<QQuickXmlListRange> *ranges, int index) const {
- if (ranges->isEmpty())
- ranges->append(qMakePair(index, 1));
- else if (ranges->last().first + ranges->last().second == index)
- ranges->last().second += 1;
- else
- ranges->append(qMakePair(index, 1));
-}
-
-void QQuickXmlQueryEngine::doSubQueryJob(XmlQueryJob *currentJob, QQuickXmlQueryResult *currentResult)
-{
- Q_ASSERT(currentJob->queryId != -1);
-
- QBuffer b(&currentJob->data);
- b.open(QIODevice::ReadOnly);
-
- QXmlQuery subquery;
- subquery.bindVariable(QLatin1String("inputDocument"), &b);
-
- QStringList keyRoleResults;
- getValuesOfKeyRoles(*currentJob, &keyRoleResults, &subquery);
-
- // See if any values of key roles have been inserted or removed.
-
- if (currentJob->keyRoleResultsCache.isEmpty()) {
- currentResult->inserted << qMakePair(0, currentResult->size);
- } else {
- if (keyRoleResults != currentJob->keyRoleResultsCache) {
- QStringList temp;
- for (int i=0; i<currentJob->keyRoleResultsCache.count(); i++) {
- if (!keyRoleResults.contains(currentJob->keyRoleResultsCache[i]))
- addIndexToRangeList(&currentResult->removed, i);
- else
- temp << currentJob->keyRoleResultsCache[i];
- }
- for (int i=0; i<keyRoleResults.count(); i++) {
- if (temp.count() == i || keyRoleResults[i] != temp[i]) {
- temp.insert(i, keyRoleResults[i]);
- addIndexToRangeList(&currentResult->inserted, i);
- }
- }
- }
- }
- currentResult->keyRoleResultsCache = keyRoleResults;
-
- // Get the new values for each role.
- //### we might be able to condense even further (query for everything in one go)
- const QStringList &queries = currentJob->roleQueries;
- for (int i = 0; i < queries.size(); ++i) {
- QList<QVariant> resultList;
- if (!queries[i].isEmpty()) {
- subquery.setQuery(currentJob->prefix + QLatin1String("(let $v := string(") + queries[i] + QLatin1String(") return if ($v) then ") + queries[i] + QLatin1String(" else \"\")"));
- if (subquery.isValid()) {
- QXmlResultItems resultItems;
- subquery.evaluateTo(&resultItems);
- QXmlItem item(resultItems.next());
- while (!item.isNull()) {
- resultList << item.toAtomicValue(); //### we used to trim strings
- item = resultItems.next();
- }
- } else {
- emit error(currentJob->roleQueryErrorId.at(i), queries[i]);
- }
- }
- //### should warn here if things have gone wrong.
- while (resultList.count() < currentResult->size)
- resultList << QVariant();
- currentResult->data << resultList;
- b.seek(0);
- }
-
- //this method is much slower, but works better for incremental loading
- /*for (int j = 0; j < m_size; ++j) {
- QList<QVariant> resultList;
- for (int i = 0; i < m_roleObjects->size(); ++i) {
- QQuickXmlListModelRole *role = m_roleObjects->at(i);
- subquery.setQuery(m_prefix.arg(j+1) + role->query());
- if (role->isStringList()) {
- QStringList data;
- subquery.evaluateTo(&data);
- resultList << QVariant(data);
- //qDebug() << data;
- } else {
- QString s;
- subquery.evaluateTo(&s);
- if (role->isCData()) {
- //un-escape
- s.replace(QLatin1String("&lt;"), QLatin1String("<"));
- s.replace(QLatin1String("&gt;"), QLatin1String(">"));
- s.replace(QLatin1String("&amp;"), QLatin1String("&"));
- }
- resultList << s.trimmed();
- //qDebug() << s;
- }
- b.seek(0);
- }
- m_modelData << resultList;
- }*/
-}
-
-class QQuickXmlListModelPrivate : public QAbstractItemModelPrivate
-{
- Q_DECLARE_PUBLIC(QQuickXmlListModel)
-public:
- QQuickXmlListModelPrivate()
- : isComponentComplete(true), size(0), highestRole(Qt::UserRole)
-#if QT_CONFIG(qml_network)
- , reply(0)
-#endif
- , status(QQuickXmlListModel::Null), progress(0.0)
- , queryId(-1), roleObjects(), redirectCount(0) {}
-
-
- void notifyQueryStarted(bool remoteSource) {
- Q_Q(QQuickXmlListModel);
- progress = remoteSource ? 0.0 : 1.0;
- status = QQuickXmlListModel::Loading;
- errorString.clear();
- emit q->progressChanged(progress);
- emit q->statusChanged(status);
- }
-
-#if QT_CONFIG(qml_network)
- void deleteReply() {
- Q_Q(QQuickXmlListModel);
- if (reply) {
- QObject::disconnect(reply, 0, q, 0);
- reply->deleteLater();
- reply = 0;
- }
- }
-#endif
-
- bool isComponentComplete;
- QUrl src;
- QString xml;
- QString query;
- QString namespaces;
- int size;
- QList<int> roles;
- QStringList roleNames;
- int highestRole;
-
-#if QT_CONFIG(qml_network)
- QNetworkReply *reply;
-#endif
- QQuickXmlListModel::Status status;
- QString errorString;
- qreal progress;
- int queryId;
- QStringList keyRoleResultsCache;
- QList<QQuickXmlListModelRole *> roleObjects;
-
- static void append_role(QQmlListProperty<QQuickXmlListModelRole> *list, QQuickXmlListModelRole *role);
- static void clear_role(QQmlListProperty<QQuickXmlListModelRole> *list);
- QList<QList<QVariant> > data;
- int redirectCount;
-};
-
-
-void QQuickXmlListModelPrivate::append_role(QQmlListProperty<QQuickXmlListModelRole> *list, QQuickXmlListModelRole *role)
-{
- QQuickXmlListModel *_this = qobject_cast<QQuickXmlListModel *>(list->object);
- if (_this && role) {
- int i = _this->d_func()->roleObjects.count();
- _this->d_func()->roleObjects.append(role);
- if (_this->d_func()->roleNames.contains(role->name())) {
- qmlWarning(role) << QQuickXmlListModel::tr("\"%1\" duplicates a previous role name and will be disabled.").arg(role->name());
- return;
- }
- _this->d_func()->roles.insert(i, _this->d_func()->highestRole);
- _this->d_func()->roleNames.insert(i, role->name());
- ++_this->d_func()->highestRole;
- }
-}
-
-//### clear needs to invalidate any cached data (in data table) as well
-// (and the model should emit the appropriate signals)
-void QQuickXmlListModelPrivate::clear_role(QQmlListProperty<QQuickXmlListModelRole> *list)
-{
- QQuickXmlListModel *_this = static_cast<QQuickXmlListModel *>(list->object);
- _this->d_func()->roles.clear();
- _this->d_func()->roleNames.clear();
- _this->d_func()->roleObjects.clear();
-}
-
-/*!
- \qmltype XmlListModel
- \instantiates QQuickXmlListModel
- \inqmlmodule QtQuick.XmlListModel
- \brief For specifying a read-only model using XPath expressions.
- \ingroup qtquick-models
-
-
- To use this element, you will need to import the module with the following line:
- \code
- import QtQuick.XmlListModel 2.0
- \endcode
-
- XmlListModel is used to create a read-only model from XML data. It can be used as a data source
- for view elements (such as ListView, PathView, GridView) and other elements that interact with model
- data (such as \l Repeater).
-
- For example, if there is a XML document at http://www.mysite.com/feed.xml like this:
-
- \code
- <?xml version="1.0" encoding="utf-8"?>
- <rss version="2.0">
- ...
- <channel>
- <item>
- <title>A blog post</title>
- <pubDate>Sat, 07 Sep 2010 10:00:01 GMT</pubDate>
- </item>
- <item>
- <title>Another blog post</title>
- <pubDate>Sat, 07 Sep 2010 15:35:01 GMT</pubDate>
- </item>
- </channel>
- </rss>
- \endcode
-
- A XmlListModel could create a model from this data, like this:
-
- \qml
- import QtQuick 2.0
- import QtQuick.XmlListModel 2.0
-
- XmlListModel {
- id: xmlModel
- source: "http://www.mysite.com/feed.xml"
- query: "/rss/channel/item"
-
- XmlRole { name: "title"; query: "title/string()" }
- XmlRole { name: "pubDate"; query: "pubDate/string()" }
- }
- \endqml
-
- The \l {XmlListModel::query}{query} value of "/rss/channel/item" specifies that the XmlListModel should generate
- a model item for each \c <item> in the XML document.
-
- The XmlRole objects define the
- model item attributes. Here, each model item will have \c title and \c pubDate
- attributes that match the \c title and \c pubDate values of its corresponding \c <item>.
- (See \l XmlRole::query for more examples of valid XPath expressions for XmlRole.)
-
- The model could be used in a ListView, like this:
-
- \qml
- ListView {
- width: 180; height: 300
- model: xmlModel
- delegate: Text { text: title + ": " + pubDate }
- }
- \endqml
-
- \image qml-xmllistmodel-example.png
-
- The XmlListModel data is loaded asynchronously, and \l status
- is set to \c XmlListModel.Ready when loading is complete.
- Note this means when XmlListModel is used for a view, the view is not
- populated until the model is loaded.
-
-
- \section2 Using Key XML Roles
-
- You can define certain roles as "keys" so that when reload() is called,
- the model will only add and refresh data that contains new values for
- these keys.
-
- For example, if above role for "pubDate" was defined like this instead:
-
- \qml
- XmlRole { name: "pubDate"; query: "pubDate/string()"; isKey: true }
- \endqml
-
- Then when reload() is called, the model will only add and reload
- items with a "pubDate" value that is not already
- present in the model.
-
- This is useful when displaying the contents of XML documents that
- are incrementally updated (such as RSS feeds) to avoid repainting the
- entire contents of a model in a view.
-
- If multiple key roles are specified, the model only adds and reload items
- with a combined value of all key roles that is not already present in
- the model.
-
- \sa {Qt Quick Demo - RSS News}
-*/
-
-QQuickXmlListModel::QQuickXmlListModel(QObject *parent)
- : QAbstractListModel(*(new QQuickXmlListModelPrivate), parent)
-{
-}
-
-QQuickXmlListModel::~QQuickXmlListModel()
-{
-}
-
-/*!
- \qmlproperty list<XmlRole> QtQuick.XmlListModel::XmlListModel::roles
-
- The roles to make available for this model.
-*/
-QQmlListProperty<QQuickXmlListModelRole> QQuickXmlListModel::roleObjects()
-{
- Q_D(QQuickXmlListModel);
- QQmlListProperty<QQuickXmlListModelRole> list(this, d->roleObjects);
- list.append = &QQuickXmlListModelPrivate::append_role;
- list.clear = &QQuickXmlListModelPrivate::clear_role;
- return list;
-}
-
-QModelIndex QQuickXmlListModel::index(int row, int column, const QModelIndex &parent) const
-{
- Q_D(const QQuickXmlListModel);
- return !parent.isValid() && column == 0 && row >= 0 && row < d->size
- ? createIndex(row, column)
- : QModelIndex();
-}
-
-int QQuickXmlListModel::rowCount(const QModelIndex &parent) const
-{
- Q_D(const QQuickXmlListModel);
- return !parent.isValid() ? d->size : 0;
-}
-
-QVariant QQuickXmlListModel::data(const QModelIndex &index, int role) const
-{
- Q_D(const QQuickXmlListModel);
- const int roleIndex = d->roles.indexOf(role);
- return (roleIndex == -1 || !index.isValid())
- ? QVariant()
- : d->data.value(roleIndex).value(index.row());
-}
-
-QHash<int, QByteArray> QQuickXmlListModel::roleNames() const
-{
- Q_D(const QQuickXmlListModel);
- QHash<int,QByteArray> roleNames;
- for (int i = 0; i < d->roles.count(); ++i)
- roleNames.insert(d->roles.at(i), d->roleNames.at(i).toUtf8());
- return roleNames;
-}
-
-/*!
- \qmlproperty int QtQuick.XmlListModel::XmlListModel::count
- The number of data entries in the model.
-*/
-int QQuickXmlListModel::count() const
-{
- Q_D(const QQuickXmlListModel);
- return d->size;
-}
-
-/*!
- \qmlproperty url QtQuick.XmlListModel::XmlListModel::source
- The location of the XML data source.
-
- If both \c source and \l xml are set, \l xml is used.
-*/
-QUrl QQuickXmlListModel::source() const
-{
- Q_D(const QQuickXmlListModel);
- return d->src;
-}
-
-void QQuickXmlListModel::setSource(const QUrl &src)
-{
- Q_D(QQuickXmlListModel);
- if (d->src != src) {
- d->src = src;
- if (d->xml.isEmpty()) // src is only used if d->xml is not set
- reload();
- emit sourceChanged();
- }
-}
-
-/*!
- \qmlproperty string QtQuick.XmlListModel::XmlListModel::xml
- This property holds the XML data for this model, if set.
-
- The text is assumed to be UTF-8 encoded.
-
- If both \l source and \c xml are set, \c xml is used.
-*/
-QString QQuickXmlListModel::xml() const
-{
- Q_D(const QQuickXmlListModel);
- return d->xml;
-}
-
-void QQuickXmlListModel::setXml(const QString &xml)
-{
- Q_D(QQuickXmlListModel);
- if (d->xml != xml) {
- d->xml = xml;
- reload();
- emit xmlChanged();
- }
-}
-
-/*!
- \qmlproperty string QtQuick.XmlListModel::XmlListModel::query
- An absolute XPath query representing the base query for creating model items
- from this model's XmlRole objects. The query should start with '/' or '//'.
-*/
-QString QQuickXmlListModel::query() const
-{
- Q_D(const QQuickXmlListModel);
- return d->query;
-}
-
-void QQuickXmlListModel::setQuery(const QString &query)
-{
- Q_D(QQuickXmlListModel);
- if (!query.startsWith(QLatin1Char('/'))) {
- qmlWarning(this) << QCoreApplication::translate("QQuickXmlRoleList", "An XmlListModel query must start with '/' or \"//\"");
- return;
- }
-
- if (d->query != query) {
- d->query = query;
- reload();
- emit queryChanged();
- }
-}
-
-/*!
- \qmlproperty string QtQuick.XmlListModel::XmlListModel::namespaceDeclarations
- The namespace declarations to be used in the XPath queries.
-
- The namespaces should be declared as in XQuery. For example, if a requested document
- at http://mysite.com/feed.xml uses the namespace "http://www.w3.org/2005/Atom",
- this can be declared as the default namespace:
-
- \qml
- XmlListModel {
- source: "http://mysite.com/feed.xml"
- query: "/feed/entry"
- namespaceDeclarations: "declare default element namespace 'http://www.w3.org/2005/Atom';"
-
- XmlRole { name: "title"; query: "title/string()" }
- }
- \endqml
-*/
-QString QQuickXmlListModel::namespaceDeclarations() const
-{
- Q_D(const QQuickXmlListModel);
- return d->namespaces;
-}
-
-void QQuickXmlListModel::setNamespaceDeclarations(const QString &declarations)
-{
- Q_D(QQuickXmlListModel);
- if (d->namespaces != declarations) {
- d->namespaces = declarations;
- reload();
- emit namespaceDeclarationsChanged();
- }
-}
-
-/*!
- \qmlmethod object QtQuick.XmlListModel::XmlListModel::get(int index)
-
- Returns the item at \a index in the model.
-
- For example, for a model like this:
-
- \qml
- XmlListModel {
- id: model
- source: "http://mysite.com/feed.xml"
- query: "/feed/entry"
- XmlRole { name: "title"; query: "title/string()" }
- }
- \endqml
-
- This will access the \c title value for the first item in the model:
-
- \js
- var title = model.get(0).title;
- \endjs
-*/
-QQmlV4Handle QQuickXmlListModel::get(int index) const
-{
- // Must be called with a context and handle scope
- Q_D(const QQuickXmlListModel);
-
- if (index < 0 || index >= count())
- return QQmlV4Handle(Encode::undefined());
-
- QQmlEngine *engine = qmlContext(this)->engine();
- ExecutionEngine *v4engine = engine->handle();
- Scope scope(v4engine);
- Scoped<Object> o(scope, v4engine->newObject());
- ScopedString name(scope);
- ScopedValue value(scope);
- for (int ii = 0; ii < d->roleObjects.count(); ++ii) {
- name = v4engine->newIdentifier(d->roleObjects[ii]->name());
- value = v4engine->fromVariant(d->data.value(ii).value(index));
- o->insertMember(name.getPointer(), value);
- }
-
- return QQmlV4Handle(o);
-}
-
-/*!
- \qmlproperty enumeration QtQuick.XmlListModel::XmlListModel::status
- Specifies the model loading status, which can be one of the following:
-
- \list
- \li XmlListModel.Null - No XML data has been set for this model.
- \li XmlListModel.Ready - The XML data has been loaded into the model.
- \li XmlListModel.Loading - The model is in the process of reading and loading XML data.
- \li XmlListModel.Error - An error occurred while the model was loading. See errorString() for details
- about the error.
- \endlist
-
- \sa progress
-
-*/
-QQuickXmlListModel::Status QQuickXmlListModel::status() const
-{
- Q_D(const QQuickXmlListModel);
- return d->status;
-}
-
-/*!
- \qmlproperty real QtQuick.XmlListModel::XmlListModel::progress
-
- This indicates the current progress of the downloading of the XML data
- source. This value ranges from 0.0 (no data downloaded) to
- 1.0 (all data downloaded). If the XML data is not from a remote source,
- the progress becomes 1.0 as soon as the data is read.
-
- Note that when the progress is 1.0, the XML data has been downloaded, but
- it is yet to be loaded into the model at this point. Use the status
- property to find out when the XML data has been read and loaded into
- the model.
-
- \sa status, source
-*/
-qreal QQuickXmlListModel::progress() const
-{
- Q_D(const QQuickXmlListModel);
- return d->progress;
-}
-
-/*!
- \qmlmethod QtQuick.XmlListModel::XmlListModel::errorString()
-
- Returns a string description of the last error that occurred
- if \l status is XmlListModel::Error.
-*/
-QString QQuickXmlListModel::errorString() const
-{
- Q_D(const QQuickXmlListModel);
- return d->errorString;
-}
-
-void QQuickXmlListModel::classBegin()
-{
- Q_D(QQuickXmlListModel);
- d->isComponentComplete = false;
-
- QQuickXmlQueryEngine *queryEngine = QQuickXmlQueryEngine::instance(qmlEngine(this));
- connect(queryEngine, SIGNAL(queryCompleted(QQuickXmlQueryResult)),
- SLOT(queryCompleted(QQuickXmlQueryResult)));
- connect(queryEngine, SIGNAL(error(void*,QString)),
- SLOT(queryError(void*,QString)));
-}
-
-void QQuickXmlListModel::componentComplete()
-{
- Q_D(QQuickXmlListModel);
- d->isComponentComplete = true;
- reload();
-}
-
-/*!
- \qmlmethod QtQuick.XmlListModel::XmlListModel::reload()
-
- Reloads the model.
-
- If no key roles have been specified, all existing model
- data is removed, and the model is rebuilt from scratch.
-
- Otherwise, items are only added if the model does not already
- contain items with matching key role values.
-
- \sa {Using key XML roles}, XmlRole::isKey
-*/
-void QQuickXmlListModel::reload()
-{
- Q_D(QQuickXmlListModel);
-
- if (!d->isComponentComplete)
- return;
-
- QQuickXmlQueryEngine::instance(qmlEngine(this))->abort(d->queryId);
- d->queryId = -1;
-
- if (d->size < 0)
- d->size = 0;
-
-#if QT_CONFIG(qml_network)
- if (d->reply) {
- d->reply->abort();
- d->deleteReply();
- }
-#endif
-
- if (!d->xml.isEmpty()) {
- d->queryId = QQuickXmlQueryEngine::instance(qmlEngine(this))->doQuery(d->query, d->namespaces, d->xml.toUtf8(), &d->roleObjects, d->keyRoleResultsCache);
- d->notifyQueryStarted(false);
-
- } else if (d->src.isEmpty()) {
- d->queryId = XMLLISTMODEL_CLEAR_ID;
- d->notifyQueryStarted(false);
- QTimer::singleShot(0, this, SLOT(dataCleared()));
-
- } else if (QQmlFile::isLocalFile(d->src)) {
- QFile file(QQmlFile::urlToLocalFileOrQrc(d->src));
- QByteArray data = file.open(QIODevice::ReadOnly) ? file.readAll() : QByteArray();
- d->notifyQueryStarted(false);
- if (data.isEmpty()) {
- d->queryId = XMLLISTMODEL_CLEAR_ID;
- QTimer::singleShot(0, this, SLOT(dataCleared()));
- } else {
- d->queryId = QQuickXmlQueryEngine::instance(qmlEngine(this))->doQuery(
- d->query, d->namespaces, data, &d->roleObjects, d->keyRoleResultsCache);
- }
- } else {
-#if QT_CONFIG(qml_network)
- d->notifyQueryStarted(true);
- QNetworkRequest req(d->src);
- req.setRawHeader("Accept", "application/xml,*/*");
- d->reply = qmlContext(this)->engine()->networkAccessManager()->get(req);
- QObject::connect(d->reply, SIGNAL(finished()), this, SLOT(requestFinished()));
- QObject::connect(d->reply, SIGNAL(downloadProgress(qint64,qint64)),
- this, SLOT(requestProgress(qint64,qint64)));
-#else
- d->queryId = XMLLISTMODEL_CLEAR_ID;
- d->notifyQueryStarted(false);
- QTimer::singleShot(0, this, SLOT(dataCleared()));
-#endif
- }
-}
-
-#define XMLLISTMODEL_MAX_REDIRECT 16
-
-#if QT_CONFIG(qml_network)
-void QQuickXmlListModel::requestFinished()
-{
- Q_D(QQuickXmlListModel);
-
- d->redirectCount++;
- if (d->redirectCount < XMLLISTMODEL_MAX_REDIRECT) {
- QVariant redirect = d->reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
- if (redirect.isValid()) {
- QUrl url = d->reply->url().resolved(redirect.toUrl());
- d->deleteReply();
- setSource(url);
- return;
- }
- }
- d->redirectCount = 0;
-
- if (d->reply->error() != QNetworkReply::NoError) {
- d->errorString = d->reply->errorString();
- d->deleteReply();
-
- if (d->size > 0) {
- beginRemoveRows(QModelIndex(), 0, d->size - 1);
- d->data.clear();
- d->size = 0;
- endRemoveRows();
- emit countChanged();
- }
-
- d->status = Error;
- d->queryId = -1;
- emit statusChanged(d->status);
- } else {
- QByteArray data = d->reply->readAll();
- if (data.isEmpty()) {
- d->queryId = XMLLISTMODEL_CLEAR_ID;
- QTimer::singleShot(0, this, SLOT(dataCleared()));
- } else {
- d->queryId = QQuickXmlQueryEngine::instance(qmlEngine(this))->doQuery(d->query, d->namespaces, data, &d->roleObjects, d->keyRoleResultsCache);
- }
- d->deleteReply();
-
- d->progress = 1.0;
- emit progressChanged(d->progress);
- }
-}
-#endif
-
-void QQuickXmlListModel::requestProgress(qint64 received, qint64 total)
-{
- Q_D(QQuickXmlListModel);
- if (d->status == Loading && total > 0) {
- d->progress = qreal(received)/total;
- emit progressChanged(d->progress);
- }
-}
-
-void QQuickXmlListModel::dataCleared()
-{
- Q_D(QQuickXmlListModel);
- QQuickXmlQueryResult r;
- r.queryId = XMLLISTMODEL_CLEAR_ID;
- r.size = 0;
- r.removed << qMakePair(0, count());
- r.keyRoleResultsCache = d->keyRoleResultsCache;
- queryCompleted(r);
-}
-
-void QQuickXmlListModel::queryError(void* object, const QString& error)
-{
- // Be extra careful, object may no longer exist, it's just an ID.
- Q_D(QQuickXmlListModel);
- for (int i=0; i<d->roleObjects.count(); i++) {
- if (d->roleObjects.at(i) == static_cast<QQuickXmlListModelRole*>(object)) {
- qmlWarning(d->roleObjects.at(i)) << QQuickXmlListModel::tr("invalid query: \"%1\"").arg(error);
- return;
- }
- }
- qmlWarning(this) << QQuickXmlListModel::tr("invalid query: \"%1\"").arg(error);
-}
-
-void QQuickXmlListModel::queryCompleted(const QQuickXmlQueryResult &result)
-{
- Q_D(QQuickXmlListModel);
- if (result.queryId != d->queryId)
- return;
-
- int origCount = d->size;
- bool sizeChanged = result.size != d->size;
-
- d->keyRoleResultsCache = result.keyRoleResultsCache;
- if (d->src.isEmpty() && d->xml.isEmpty())
- d->status = Null;
- else
- d->status = Ready;
- d->errorString.clear();
- d->queryId = -1;
-
- bool hasKeys = false;
- for (int i=0; i<d->roleObjects.count(); i++) {
- if (d->roleObjects[i]->isKey()) {
- hasKeys = true;
- break;
- }
- }
- if (!hasKeys) {
- if (origCount > 0) {
- beginRemoveRows(QModelIndex(), 0, origCount - 1);
- endRemoveRows();
- }
- d->size = result.size;
- d->data = result.data;
- if (d->size > 0) {
- beginInsertRows(QModelIndex(), 0, d->size - 1);
- endInsertRows();
- }
- } else {
- for (int i=0; i<result.removed.count(); i++) {
- const int index = result.removed[i].first;
- const int count = result.removed[i].second;
- if (count > 0) {
- beginRemoveRows(QModelIndex(), index, index + count - 1);
- endRemoveRows();
- }
- }
- d->size = result.size;
- d->data = result.data;
- for (int i=0; i<result.inserted.count(); i++) {
- const int index = result.inserted[i].first;
- const int count = result.inserted[i].second;
- if (count > 0) {
- beginInsertRows(QModelIndex(), index, index + count - 1);
- endInsertRows();
- }
- }
- }
- if (sizeChanged)
- emit countChanged();
-
- emit statusChanged(d->status);
-}
-
-QT_END_NAMESPACE
-
-#include <qqmlxmllistmodel.moc>
diff --git a/src/imports/xmllistmodel/qqmlxmllistmodel_p.h b/src/imports/xmllistmodel/qqmlxmllistmodel_p.h
deleted file mode 100644
index 65f1299324..0000000000
--- a/src/imports/xmllistmodel/qqmlxmllistmodel_p.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QQUICKXMLLISTMODEL_H
-#define QQUICKXMLLISTMODEL_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <qqml.h>
-#include <qqmlinfo.h>
-
-#include <QtCore/qurl.h>
-#include <QtCore/qstringlist.h>
-#include <QtCore/qabstractitemmodel.h>
-#include <private/qv8engine_p.h>
-
-QT_BEGIN_NAMESPACE
-
-
-class QQmlContext;
-class QQuickXmlListModelRole;
-class QQuickXmlListModelPrivate;
-
-struct QQuickXmlQueryResult {
- int queryId;
- int size;
- QList<QList<QVariant> > data;
- QList<QPair<int, int> > inserted;
- QList<QPair<int, int> > removed;
- QStringList keyRoleResultsCache;
-};
-
-class QQuickXmlListModel : public QAbstractListModel, public QQmlParserStatus
-{
- Q_OBJECT
- Q_INTERFACES(QQmlParserStatus)
-
- Q_PROPERTY(Status status READ status NOTIFY statusChanged)
- Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged)
- Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
- Q_PROPERTY(QString xml READ xml WRITE setXml NOTIFY xmlChanged)
- Q_PROPERTY(QString query READ query WRITE setQuery NOTIFY queryChanged)
- Q_PROPERTY(QString namespaceDeclarations READ namespaceDeclarations WRITE setNamespaceDeclarations NOTIFY namespaceDeclarationsChanged)
- Q_PROPERTY(QQmlListProperty<QQuickXmlListModelRole> roles READ roleObjects)
- Q_PROPERTY(int count READ count NOTIFY countChanged)
- Q_CLASSINFO("DefaultProperty", "roles")
-
-public:
- QQuickXmlListModel(QObject *parent = 0);
- ~QQuickXmlListModel();
-
- QModelIndex index(int row, int column, const QModelIndex &parent) const override;
- int rowCount(const QModelIndex &parent) const override;
- QVariant data(const QModelIndex &index, int role) const override;
- QHash<int, QByteArray> roleNames() const override;
-
- int count() const;
-
- QQmlListProperty<QQuickXmlListModelRole> roleObjects();
-
- QUrl source() const;
- void setSource(const QUrl&);
-
- QString xml() const;
- void setXml(const QString&);
-
- QString query() const;
- void setQuery(const QString&);
-
- QString namespaceDeclarations() const;
- void setNamespaceDeclarations(const QString&);
-
- Q_INVOKABLE QQmlV4Handle get(int index) const;
-
- enum Status { Null, Ready, Loading, Error };
- Q_ENUM(Status)
- Status status() const;
- qreal progress() const;
-
- Q_INVOKABLE QString errorString() const;
-
- void classBegin() override;
- void componentComplete() override;
-
-Q_SIGNALS:
- void statusChanged(QQuickXmlListModel::Status);
- void progressChanged(qreal progress);
- void countChanged();
- void sourceChanged();
- void xmlChanged();
- void queryChanged();
- void namespaceDeclarationsChanged();
-
-public Q_SLOTS:
- // ### need to use/expose Expiry to guess when to call this?
- // ### property to auto-call this on reasonable Expiry?
- // ### LastModified/Age also useful to guess.
- // ### Probably also applies to other network-requesting types.
- void reload();
-
-private Q_SLOTS:
-#if QT_CONFIG(qml_network)
- void requestFinished();
-#endif
- void requestProgress(qint64,qint64);
- void dataCleared();
- void queryCompleted(const QQuickXmlQueryResult &);
- void queryError(void* object, const QString& error);
-
-private:
- Q_DECLARE_PRIVATE(QQuickXmlListModel)
- Q_DISABLE_COPY(QQuickXmlListModel)
-};
-
-class QQuickXmlListModelRole : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
- Q_PROPERTY(QString query READ query WRITE setQuery NOTIFY queryChanged)
- Q_PROPERTY(bool isKey READ isKey WRITE setIsKey NOTIFY isKeyChanged)
-public:
- QQuickXmlListModelRole() : m_isKey(false) {}
- ~QQuickXmlListModelRole() {}
-
- QString name() const { return m_name; }
- void setName(const QString &name) {
- if (name == m_name)
- return;
- m_name = name;
- Q_EMIT nameChanged();
- }
-
- QString query() const { return m_query; }
- void setQuery(const QString &query)
- {
- if (query.startsWith(QLatin1Char('/'))) {
- qmlWarning(this) << tr("An XmlRole query must not start with '/'");
- return;
- }
- if (m_query == query)
- return;
- m_query = query;
- Q_EMIT queryChanged();
- }
-
- bool isKey() const { return m_isKey; }
- void setIsKey(bool b) {
- if (m_isKey == b)
- return;
- m_isKey = b;
- Q_EMIT isKeyChanged();
- }
-
- bool isValid() const {
- return !m_name.isEmpty() && !m_query.isEmpty();
- }
-
-Q_SIGNALS:
- void nameChanged();
- void queryChanged();
- void isKeyChanged();
-
-private:
- QString m_name;
- QString m_query;
- bool m_isKey;
-};
-
-QT_END_NAMESPACE
-
-QML_DECLARE_TYPE(QQuickXmlListModel)
-QML_DECLARE_TYPE(QQuickXmlListModelRole)
-
-#endif // QQUICKXMLLISTMODEL_H
diff --git a/src/imports/xmllistmodel/xmllistmodel.pro b/src/imports/xmllistmodel/xmllistmodel.pro
deleted file mode 100644
index 1e61f4d3d9..0000000000
--- a/src/imports/xmllistmodel/xmllistmodel.pro
+++ /dev/null
@@ -1,14 +0,0 @@
-CXX_MODULE = qml
-TARGET = qmlxmllistmodelplugin
-TARGETPATH = QtQuick/XmlListModel
-IMPORT_VERSION = 2.$$QT_MINOR_VERSION
-
-QT = xmlpatterns qml-private core-private
-qtConfig(qml-network): QT += network
-
-SOURCES += qqmlxmllistmodel.cpp plugin.cpp
-HEADERS += qqmlxmllistmodel_p.h
-
-load(qml_plugin)
-
-requires(qtConfig(qml-network))
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 09c0e60f4d..75c47164c9 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -3059,34 +3059,36 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast,
statementList(body);
- bytecodeGenerator->setLocation(ast->lastSourceLocation());
- _context->emitBlockFooter(this);
-
- if (_returnLabel || hasError || !functionEndsWithReturn) {
- if (_returnLabel)
- _returnLabel->link();
+ if (!hasError) {
+ bytecodeGenerator->setLocation(ast->lastSourceLocation());
+ _context->emitBlockFooter(this);
+
+ if (_returnLabel || !functionEndsWithReturn) {
+ if (_returnLabel)
+ _returnLabel->link();
+
+ if (_returnLabel || requiresReturnValue) {
+ Instruction::LoadReg load;
+ load.reg = Moth::StackSlot::createRegister(_returnAddress);
+ bytecodeGenerator->addInstruction(load);
+ } else {
+ Reference::fromConst(this, Encode::undefined()).loadInAccumulator();
+ }
- if (_returnLabel || requiresReturnValue) {
- Instruction::LoadReg load;
- load.reg = Moth::StackSlot::createRegister(_returnAddress);
- bytecodeGenerator->addInstruction(load);
- } else {
- Reference::fromConst(this, Encode::undefined()).loadInAccumulator();
+ bytecodeGenerator->addInstruction(Instruction::Ret());
}
- bytecodeGenerator->addInstruction(Instruction::Ret());
- }
-
- Q_ASSERT(_context == _functionContext);
- bytecodeGenerator->finalize(_context);
- _context->registerCountInFunction = bytecodeGenerator->registerCount();
- static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_BYTECODE");
- if (showCode) {
- qDebug() << "=== Bytecode for" << _context->name << "strict mode" << _context->isStrict
- << "register count" << _context->registerCountInFunction << "implicit return" << requiresReturnValue;
- QV4::Moth::dumpBytecode(_context->code, _context->locals.size(), _context->arguments.size(),
- _context->line, _context->lineNumberMapping);
- qDebug();
+ Q_ASSERT(_context == _functionContext);
+ bytecodeGenerator->finalize(_context);
+ _context->registerCountInFunction = bytecodeGenerator->registerCount();
+ static const bool showCode = qEnvironmentVariableIsSet("QV4_SHOW_BYTECODE");
+ if (showCode) {
+ qDebug() << "=== Bytecode for" << _context->name << "strict mode" << _context->isStrict
+ << "register count" << _context->registerCountInFunction << "implicit return" << requiresReturnValue;
+ QV4::Moth::dumpBytecode(_context->code, _context->locals.size(), _context->arguments.size(),
+ _context->line, _context->lineNumberMapping);
+ qDebug();
+ }
}
qSwap(_returnAddress, returnAddress);
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index 3b2d6e0a48..b8497937c1 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -415,13 +415,20 @@ QStringList CompilationUnit::moduleRequests() const
Heap::Module *CompilationUnit::instantiate(ExecutionEngine *engine)
{
- if (m_module)
+ if (isESModule() && m_module)
return m_module;
+ if (data->indexOfRootFunction < 0)
+ return nullptr;
+
if (!this->engine)
linkToEngine(engine);
- m_module = engine->memoryManager->allocate<Module>(engine, this);
+ Scope scope(engine);
+ Scoped<Module> module(scope, engine->memoryManager->allocate<Module>(engine, this));
+
+ if (isESModule())
+ m_module = module->d();
for (const QString &request: moduleRequests()) {
auto dependentModuleUnit = engine->loadModule(QUrl(request), this);
@@ -430,7 +437,6 @@ Heap::Module *CompilationUnit::instantiate(ExecutionEngine *engine)
dependentModuleUnit->instantiate(engine);
}
- Scope scope(engine);
ScopedString importName(scope);
const uint importCount = data->importEntryTableSize;
@@ -465,7 +471,7 @@ Heap::Module *CompilationUnit::instantiate(ExecutionEngine *engine)
}
}
- return m_module;
+ return module->d();
}
const Value *CompilationUnit::resolveExport(QV4::String *exportName)
@@ -590,10 +596,13 @@ void CompilationUnit::getExportedNamesRecursively(QStringList *names, QVector<co
void CompilationUnit::evaluate()
{
- if (m_moduleEvaluated)
- return;
- m_moduleEvaluated = true;
+ QV4::Scope scope(engine);
+ QV4::Scoped<Module> module(scope, m_module);
+ module->evaluate();
+}
+void CompilationUnit::evaluateModuleRequests()
+{
for (const QString &request: moduleRequests()) {
auto dependentModuleUnit = engine->loadModule(QUrl(request), this);
if (engine->hasException)
@@ -602,19 +611,6 @@ void CompilationUnit::evaluate()
if (engine->hasException)
return;
}
-
- QV4::Function *moduleFunction = runtimeFunctions[data->indexOfRootFunction];
- CppStackFrame frame;
- frame.init(engine, moduleFunction, nullptr, 0);
- frame.setupJSFrame(engine->jsStackTop, Value::undefinedValue(), m_module->scope,
- Value::undefinedValue(), Value::undefinedValue());
-
- frame.push();
- engine->jsStackTop += frame.requiredJSStackFrameSize();
- auto frameCleanup = qScopeGuard([&frame]() {
- frame.pop();
- });
- Moth::VME::exec(&frame, engine);
}
bool CompilationUnit::loadFromDisk(const QUrl &url, const QDateTime &sourceTimeStamp, QString *errorString)
@@ -768,7 +764,7 @@ QString Binding::valueAsString(const CompilationUnit *unit) const
case Type_Translation: {
const TranslationData &translation = unit->unitData()->translations()[value.translationDataIndex];
// This code must match that in the qsTr() implementation
- const QString &path = unit->stringAt(unit->unitData()->sourceFileIndex);
+ const QString &path = unit->fileName();
int lastSlash = path.lastIndexOf(QLatin1Char('/'));
QStringRef context = (lastSlash > -1) ? path.midRef(lastSlash + 1, path.length() - lastSlash - 5)
: QStringRef();
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index d0785c6883..7c26b0b67d 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -1223,6 +1223,7 @@ public:
const Value *resolveExport(QV4::String *exportName);
QStringList exportedNames() const;
void evaluate();
+ void evaluateModuleRequests();
QV4::Function *linkToEngine(QV4::ExecutionEngine *engine);
void unlink();
@@ -1265,7 +1266,6 @@ private:
Q_NEVER_INLINE IdentifierHash createNamedObjectsPerComponent(int componentObjectIndex);
Heap::Module *m_module = nullptr;
- bool m_moduleEvaluated = false;
public:
#if defined(V4_BOOTSTRAP)
diff --git a/src/qml/compiler/qv4compilercontext.cpp b/src/qml/compiler/qv4compilercontext.cpp
index 572f24f148..ca4cbfc4fc 100644
--- a/src/qml/compiler/qv4compilercontext.cpp
+++ b/src/qml/compiler/qv4compilercontext.cpp
@@ -207,7 +207,7 @@ void Context::emitBlockHeader(Codegen *codegen)
blockIndex = codegen->module()->blocks.count() - 1;
}
- if (contextType == ContextType::Global || contextType == ContextType::ScriptImportedByQML) {
+ if (contextType == ContextType::Global) {
Instruction::PushScriptContext scriptContext;
scriptContext.index = blockIndex;
bytecodeGenerator->addInstruction(scriptContext);
@@ -222,7 +222,7 @@ void Context::emitBlockHeader(Codegen *codegen)
blockContext.index = blockIndex;
bytecodeGenerator->addInstruction(blockContext);
}
- } else if (contextType != ContextType::ESModule) {
+ } else if (contextType != ContextType::ESModule && contextType != ContextType::ScriptImportedByQML) {
Instruction::CreateCallContext createContext;
bytecodeGenerator->addInstruction(createContext);
}
@@ -316,9 +316,9 @@ void Context::emitBlockFooter(Codegen *codegen)
QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Wmaybe-uninitialized") // the loads below are empty structs.
- if (contextType == ContextType::Global || contextType == ContextType::ScriptImportedByQML)
+ if (contextType == ContextType::Global)
bytecodeGenerator->addInstruction(Instruction::PopScriptContext());
- else if (contextType != ContextType::ESModule)
+ else if (contextType != ContextType::ESModule && contextType != ContextType::ScriptImportedByQML)
bytecodeGenerator->addInstruction(Instruction::PopContext());
QT_WARNING_POP
}
diff --git a/src/qml/configure.json b/src/qml/configure.json
index aea62c3439..878ec0119b 100644
--- a/src/qml/configure.json
+++ b/src/qml/configure.json
@@ -12,7 +12,25 @@
}
},
+ "tests": {
+ "cxx14_make_unique": {
+ "label": "C++14 make_unique()",
+ "type": "compile",
+ "test": {
+ "include": "memory",
+ "main": [
+ "std::unique_ptr<int> ptr = std::make_unique<int>();"
+ ]
+ }
+ }
+ },
+
"features": {
+ "cxx14_make_unique": {
+ "label": "C++14 make_unique",
+ "condition": "tests.cxx14_make_unique",
+ "output": [ "privateFeature" ]
+ },
"qml-network": {
"label": "QML network support",
"purpose": "Provides network transparency.",
diff --git a/src/qml/doc/qtqml.qdocconf b/src/qml/doc/qtqml.qdocconf
index 6161760471..40acc7c13f 100644
--- a/src/qml/doc/qtqml.qdocconf
+++ b/src/qml/doc/qtqml.qdocconf
@@ -33,7 +33,7 @@ qhp.QtQml.subprojects.qmltypes.sortPages = true
tagfile = ../../../doc/qtqml/qtqml.tags
-depends += qtcore qtxmlpatterns qtgui qtquick qtdoc qtlinguist qmake qtscript qtwidgets
+depends += qtcore qtgui qtquick qtdoc qtlinguist qmake qtscript qtwidgets
headerdirs += .. \
../../imports/models
diff --git a/src/qml/jit/qv4baselineassembler.cpp b/src/qml/jit/qv4baselineassembler.cpp
index f6b745632b..c62d6e5388 100644
--- a/src/qml/jit/qv4baselineassembler.cpp
+++ b/src/qml/jit/qv4baselineassembler.cpp
@@ -444,12 +444,12 @@ public:
void moveReg(Address sourceRegAddress, Address destRegAddress)
{
- load32(sourceRegAddress, ReturnValueRegisterValue);
+ load32(sourceRegAddress, ScratchRegister);
+ store32(ScratchRegister, destRegAddress);
sourceRegAddress.offset += 4;
- load32(sourceRegAddress, ReturnValueRegisterTag);
- store32(ReturnValueRegisterValue, destRegAddress);
destRegAddress.offset += 4;
- store32(ReturnValueRegisterTag, destRegAddress);
+ load32(sourceRegAddress, ScratchRegister);
+ store32(ScratchRegister, destRegAddress);
}
void loadString(int stringId)
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 169ab0a4a4..57a364b205 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -342,7 +342,7 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine)
jsObjects[BooleanProto] = memoryManager->allocate<BooleanPrototype>();
jsObjects[DateProto] = memoryManager->allocate<DatePrototype>();
-#ifdef QT_NO_DEBUG
+#if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS)
InternalClassEntry *index = nullptr;
#else
InternalClassEntry _index;
diff --git a/src/qml/jsruntime/qv4module.cpp b/src/qml/jsruntime/qv4module.cpp
index 19a036374f..237ada8321 100644
--- a/src/qml/jsruntime/qv4module.cpp
+++ b/src/qml/jsruntime/qv4module.cpp
@@ -46,6 +46,8 @@
#include <private/qv4symbol_p.h>
#include <private/qv4identifiertable_p.h>
+#include <QScopeGuard>
+
using namespace QV4;
DEFINE_OBJECT_VTABLE(Module);
@@ -98,20 +100,60 @@ void Heap::Module::init(ExecutionEngine *engine, CompiledData::CompilationUnit *
This->setPrototypeUnchecked(nullptr);
}
+void Module::evaluate()
+{
+ if (d()->evaluated)
+ return;
+ d()->evaluated = true;
+
+ CompiledData::CompilationUnit *unit = d()->unit;
+
+ unit->evaluateModuleRequests();
+
+ ExecutionEngine *v4 = engine();
+ Function *moduleFunction = unit->runtimeFunctions[unit->data->indexOfRootFunction];
+ CppStackFrame frame;
+ frame.init(v4, moduleFunction, nullptr, 0);
+ frame.setupJSFrame(v4->jsStackTop, Value::undefinedValue(), d()->scope,
+ Value::undefinedValue(), Value::undefinedValue());
+
+ frame.push();
+ v4->jsStackTop += frame.requiredJSStackFrameSize();
+ auto frameCleanup = qScopeGuard([&frame]() {
+ frame.pop();
+ });
+ Moth::VME::exec(&frame, v4);
+}
+
+const Value *Module::resolveExport(PropertyKey id) const
+{
+ if (d()->unit->isESModule()) {
+ if (!id.isString())
+ return nullptr;
+ Scope scope(engine());
+ ScopedString name(scope, id.asStringOrSymbol());
+ return d()->unit->resolveExport(name);
+ } else {
+ InternalClassEntry entry = d()->scope->internalClass->find(id);
+ if (entry.isValid())
+ return &d()->scope->locals[entry.index];
+ return nullptr;
+ }
+}
+
ReturnedValue Module::virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty)
{
if (id.isSymbol())
return Object::virtualGet(m, id, receiver, hasProperty);
const Module *module = static_cast<const Module *>(m);
- Scope scope(m->engine());
- ScopedString expectedName(scope, id.toStringOrSymbol(scope.engine));
- const Value *v = module->d()->unit->resolveExport(expectedName);
+ const Value *v = module->resolveExport(id);
if (hasProperty)
*hasProperty = v != nullptr;
if (!v)
return Encode::undefined();
if (v->isEmpty()) {
+ Scope scope(m->engine());
ScopedValue propName(scope, id.toStringOrSymbol(scope.engine));
return scope.engine->throwReferenceError(propName);
}
@@ -124,9 +166,7 @@ PropertyAttributes Module::virtualGetOwnProperty(const Managed *m, PropertyKey i
return Object::virtualGetOwnProperty(m, id, p);
const Module *module = static_cast<const Module *>(m);
- Scope scope(m->engine());
- ScopedString expectedName(scope, id.toStringOrSymbol(scope.engine));
- const Value *v = module->d()->unit->resolveExport(expectedName);
+ const Value *v = module->resolveExport(id);
if (!v) {
if (p)
p->value = Encode::undefined();
@@ -135,6 +175,7 @@ PropertyAttributes Module::virtualGetOwnProperty(const Managed *m, PropertyKey i
if (p)
p->value = v->isEmpty() ? Encode::undefined() : v->asReturnedValue();
if (v->isEmpty()) {
+ Scope scope(m->engine());
ScopedValue propName(scope, id.toStringOrSymbol(scope.engine));
scope.engine->throwReferenceError(propName);
}
@@ -147,9 +188,7 @@ bool Module::virtualHasProperty(const Managed *m, PropertyKey id)
return Object::virtualHasProperty(m, id);
const Module *module = static_cast<const Module *>(m);
- Scope scope(m->engine());
- ScopedString expectedName(scope, id.toStringOrSymbol(scope.engine));
- const Value *v = module->d()->unit->resolveExport(expectedName);
+ const Value *v = module->resolveExport(id);
return v != nullptr;
}
@@ -173,11 +212,7 @@ bool Module::virtualDeleteProperty(Managed *m, PropertyKey id)
if (id.isSymbol())
return Object::virtualDeleteProperty(m, id);
const Module *module = static_cast<const Module *>(m);
- Scope scope(m->engine());
- ScopedString expectedName(scope, id.toStringOrSymbol(scope.engine));
- if (!expectedName)
- return true;
- const Value *v = module->d()->unit->resolveExport(expectedName);
+ const Value *v = module->resolveExport(id);
if (v)
return false;
return true;
@@ -202,7 +237,7 @@ PropertyKey ModuleNamespaceIterator::next(const Object *o, Property *pd, Propert
Scope scope(module->engine());
ScopedString exportName(scope, scope.engine->newString(exportedNames.at(exportIndex)));
exportIndex++;
- const Value *v = module->d()->unit->resolveExport(exportName);
+ const Value *v = module->resolveExport(exportName->toPropertyKey());
if (pd) {
if (v->isEmpty())
scope.engine->throwReferenceError(exportName);
@@ -218,7 +253,17 @@ OwnPropertyKeyIterator *Module::virtualOwnPropertyKeys(const Object *o, Value *t
{
const Module *module = static_cast<const Module *>(o);
*target = *o;
- return new ModuleNamespaceIterator(module->d()->unit->exportedNames());
+
+ QStringList names;
+ if (module->d()->unit->isESModule()) {
+ names = module->d()->unit->exportedNames();
+ } else {
+ Heap::InternalClass *scopeClass = module->d()->scope->internalClass;
+ for (uint i = 0; i < scopeClass->size; ++i)
+ names << scopeClass->keyAt(i);
+ }
+
+ return new ModuleNamespaceIterator(names);
}
Heap::Object *Module::virtualGetPrototypeOf(const Managed *)
diff --git a/src/qml/jsruntime/qv4module_p.h b/src/qml/jsruntime/qv4module_p.h
index 0cab161b82..dca0678fe9 100644
--- a/src/qml/jsruntime/qv4module_p.h
+++ b/src/qml/jsruntime/qv4module_p.h
@@ -62,7 +62,8 @@ namespace Heap {
#define ModuleMembers(class, Member) \
Member(class, NoMark, CompiledData::CompilationUnit *, unit) \
Member(class, Pointer, CallContext *, scope) \
- Member(class, HeapValue, HeapValue, self)
+ Member(class, HeapValue, HeapValue, self) \
+ Member(class, NoMark, bool, evaluated)
DECLARE_EXPORTED_HEAP_OBJECT(Module, Object) {
DECLARE_MARKOBJECTS(Module)
@@ -75,6 +76,9 @@ DECLARE_EXPORTED_HEAP_OBJECT(Module, Object) {
struct Q_QML_EXPORT Module : public Object {
V4_OBJECT2(Module, Object)
+ void evaluate();
+ const Value *resolveExport(PropertyKey key) const;
+
static ReturnedValue virtualGet(const Managed *m, PropertyKey id, const Value *receiver, bool *hasProperty);
static PropertyAttributes virtualGetOwnProperty(const Managed *m, PropertyKey id, Property *p);
static bool virtualHasProperty(const Managed *m, PropertyKey id);
diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp
index cc0b0feeee..88b0822f42 100644
--- a/src/qml/jsruntime/qv4qmlcontext.cpp
+++ b/src/qml/jsruntime/qv4qmlcontext.cpp
@@ -54,6 +54,7 @@
#include <private/qqmljavascriptexpression_p.h>
#include <private/qjsvalue_p.h>
#include <private/qv4qobjectwrapper_p.h>
+#include <private/qv4module_p.h>
QT_BEGIN_NAMESPACE
@@ -87,8 +88,20 @@ ReturnedValue QQmlContextWrapper::virtualGet(const Managed *m, PropertyKey id, c
QV4::ExecutionEngine *v4 = resource->engine();
QV4::Scope scope(v4);
- if (v4->callingQmlContext() != *resource->d()->context)
+ if (v4->callingQmlContext() != *resource->d()->context) {
+ if (resource->d()->module) {
+ Scoped<Module> module(scope, resource->d()->module);
+ bool hasProp = false;
+ ScopedValue value(scope, module->get(id, receiver, &hasProp));
+ if (hasProp) {
+ if (hasProperty)
+ *hasProperty = hasProp;
+ return value->asReturnedValue();
+ }
+ }
+
return Object::virtualGet(m, id, receiver, hasProperty);
+ }
bool hasProp = false;
ScopedValue result(scope, Object::virtualGet(m, id, receiver, &hasProp));
diff --git a/src/qml/jsruntime/qv4qmlcontext_p.h b/src/qml/jsruntime/qv4qmlcontext_p.h
index 4fe34a0a06..dd6de3323d 100644
--- a/src/qml/jsruntime/qv4qmlcontext_p.h
+++ b/src/qml/jsruntime/qv4qmlcontext_p.h
@@ -66,7 +66,12 @@ struct QQmlContextWrapper;
namespace Heap {
-struct QQmlContextWrapper : Object {
+#define QQmlContextWrapperMembers(class, Member) \
+ Member(class, Pointer, Module *, module)
+
+DECLARE_HEAP_OBJECT(QQmlContextWrapper, Object) {
+ DECLARE_MARKOBJECTS(QQmlContextWrapper);
+
void init(QQmlContextData *context, QObject *scopeObject);
void destroy();
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index fb6d9478db..97254b9172 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -666,11 +666,10 @@ HeapItem *HugeItemAllocator::allocate(size_t size) {
Chunk *c = nullptr;
if (size >= MemorySegment::SegmentSize/2) {
// too large to handle through the ChunkAllocator, let's get our own memory segement
- size_t segmentSize = size + Chunk::HeaderSize; // space required for the Chunk header
+ size += Chunk::HeaderSize; // space required for the Chunk header
size_t pageSize = WTF::pageSize();
- segmentSize = (segmentSize + pageSize - 1) & ~(pageSize - 1); // align to page sizes
- m = new MemorySegment(segmentSize);
size = (size + pageSize - 1) & ~(pageSize - 1); // align to page sizes
+ m = new MemorySegment(size);
c = m->allocate(size);
} else {
c = chunkAllocator->allocate(size);
diff --git a/src/qml/qml/qqmlinfo.cpp b/src/qml/qml/qqmlinfo.cpp
index c8f5ba506f..6322302422 100644
--- a/src/qml/qml/qqmlinfo.cpp
+++ b/src/qml/qml/qqmlinfo.cpp
@@ -50,6 +50,12 @@
QT_BEGIN_NAMESPACE
/*!
+ \namespace QtQml
+ \inmodule QtQml
+ \brief Provides functions for producing logging messages for QML types.
+*/
+
+/*!
\fn QQmlInfo QtQml::qmlDebug(const QObject *object)
\relates QQmlEngine
\since 5.9
@@ -57,6 +63,7 @@ QT_BEGIN_NAMESPACE
Prints debug messages that include the file and line number for the
specified QML \a object.
+//! [qqmlinfo-desc]
When QML types produce logging messages, it improves traceability
if they include the QML file and line number on which the
particular instance was instantiated.
@@ -65,6 +72,7 @@ QT_BEGIN_NAMESPACE
the file and line number is not available for that instance
(either it was not instantiated by the QML engine or location
information is disabled), "unknown location" will be used instead.
+//! [qqmlinfo-desc]
For example,
@@ -74,7 +82,7 @@ QT_BEGIN_NAMESPACE
prints
- \code
+ \badcode
QML MyCustomType (unknown location): Internal state: 42
\endcode
@@ -88,14 +96,7 @@ QT_BEGIN_NAMESPACE
Prints informational messages that include the file and line number for the
specified QML \a object.
- When QML types produce logging messages, it improves traceability
- if they include the QML file and line number on which the
- particular instance was instantiated.
-
- To include the file and line number, an object must be passed. If
- the file and line number is not available for that instance
- (either it was not instantiated by the QML engine or location
- information is disabled), "unknown location" will be used instead.
+ \include qqmlinfo.cpp qqmlinfo-desc
For example,
@@ -105,7 +106,7 @@ QT_BEGIN_NAMESPACE
prints
- \code
+ \badcode
QML MyCustomType (unknown location): component property is a write-once property
\endcode
@@ -116,7 +117,6 @@ QT_BEGIN_NAMESPACE
\sa QtQml::qmlDebug, QtQml::qmlWarning
*/
-
/*!
\fn QQmlInfo QtQml::qmlWarning(const QObject *object)
\relates QQmlEngine
@@ -125,14 +125,7 @@ QT_BEGIN_NAMESPACE
Prints warning messages that include the file and line number for the
specified QML \a object.
- When QML types produce logging messages, it improves traceability
- if they include the QML file and line number on which the
- particular instance was instantiated.
-
- To include the file and line number, an object must be passed. If
- the file and line number is not available for that instance
- (either it was not instantiated by the QML engine or location
- information is disabled), "unknown location" will be used instead.
+ \include qqmlinfo.cpp qqmlinfo-desc
For example,
@@ -142,13 +135,43 @@ QT_BEGIN_NAMESPACE
prints
- \code
+ \badcode
QML MyCustomType (unknown location): property cannot be set to 0
\endcode
\sa QtQml::qmlDebug, QtQml::qmlInfo
*/
+/*!
+ \fn QQmlInfo QtQml::qmlDebug(const QObject *object, const QQmlError &error)
+ \internal
+*/
+
+/*!
+ \fn QQmlInfo QtQml::qmlDebug(const QObject *object, const QList<QQmlError> &errors)
+ \internal
+*/
+
+/*!
+ \fn QQmlInfo QtQml::qmlInfo(const QObject *object, const QQmlError &error)
+ \internal
+*/
+
+/*!
+ \fn QQmlInfo QtQml::qmlInfo(const QObject *object, const QList<QQmlError> &errors)
+ \internal
+*/
+
+/*!
+ \fn QQmlInfo QtQml::qmlWarning(const QObject *object, const QQmlError &error)
+ \internal
+*/
+
+/*!
+ \fn QQmlInfo QtQml::qmlWarning(const QObject *object, const QList<QQmlError> &errors)
+ \internal
+*/
+
class QQmlInfoPrivate
{
public:
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index 89b023c164..7480475ca7 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -2881,30 +2881,9 @@ void QQmlTypeData::scriptImported(const QQmlRefPointer<QQmlScriptBlob> &blob, co
QQmlScriptData::QQmlScriptData()
: typeNameCache(nullptr)
, m_loaded(false)
- , m_program(nullptr)
{
}
-QQmlScriptData::~QQmlScriptData()
-{
- delete m_program;
-}
-
-void QQmlScriptData::initialize(QQmlEngine *engine)
-{
- Q_ASSERT(!m_program);
- Q_ASSERT(engine);
- Q_ASSERT(!hasEngine());
-
- QV4::ExecutionEngine *v4 = engine->handle();
-
- m_program = new QV4::Script(v4, nullptr, m_precompiledScript);
-
- addToEngine(engine);
-
- addref();
-}
-
QQmlContextData *QQmlScriptData::qmlContextDataForContext(QQmlContextData *parentQmlContextData)
{
Q_ASSERT(parentQmlContextData && parentQmlContextData->engine);
@@ -2954,57 +2933,54 @@ QQmlContextData *QQmlScriptData::qmlContextDataForContext(QQmlContextData *paren
return qmlContextData;
}
-QV4::ReturnedValue QQmlScriptData::scriptValueForContext(QQmlContextData *parentCtxt)
+QV4::ReturnedValue QQmlScriptData::scriptValueForContext(QQmlContextData *parentQmlContextData)
{
if (m_loaded)
return m_value.value();
- Q_ASSERT(parentCtxt && parentCtxt->engine);
- QV4::ExecutionEngine *v4 = parentCtxt->engine->handle();
-
- if (m_precompiledScript->isESModule()) {
- m_loaded = true;
-
- m_value.set(v4, m_precompiledScript->instantiate(v4));
- if (!m_value.isNullOrUndefined())
- m_precompiledScript->evaluate();
+ Q_ASSERT(parentQmlContextData && parentQmlContextData->engine);
+ QV4::ExecutionEngine *v4 = parentQmlContextData->engine->handle();
+ QV4::Scope scope(v4);
- return m_value.value();
+ if (!hasEngine()) {
+ addToEngine(parentQmlContextData->engine);
+ addref();
}
- QQmlEnginePrivate *ep = QQmlEnginePrivate::get(parentCtxt->engine);
- QV4::Scope scope(v4);
-
- // Create the script context if required
- QQmlContextDataRef ctxt(qmlContextDataForContext(parentCtxt));
+ QQmlContextDataRef qmlContextData = qmlContextDataForContext(parentQmlContextData);
+ QV4::Scoped<QV4::QmlContext> qmlExecutionContext(scope);
+ if (qmlContextData)
+ qmlExecutionContext =
+ QV4::QmlContext::create(v4->rootContext(), qmlContextData, /* scopeObject: */ nullptr);
- if (!hasEngine())
- initialize(parentCtxt->engine);
+ QV4::Scoped<QV4::Module> module(scope, m_precompiledScript->instantiate(v4));
+ if (module) {
+ if (qmlContextData) {
+ module->d()->scope->outer.set(v4, qmlExecutionContext->d());
+ qmlExecutionContext->d()->qml()->module.set(v4, module->d());
+ }
- if (!m_program) {
- if (m_precompiledScript->isSharedLibrary())
- m_loaded = true;
- return QV4::Encode::undefined();
+ module->evaluate();
}
- QV4::Scoped<QV4::QmlContext> qmlContext(scope, QV4::QmlContext::create(v4->rootContext(), ctxt, nullptr));
-
- m_program->qmlContext.set(scope.engine, qmlContext);
- m_program->run();
- m_program->qmlContext.clear();
- if (scope.engine->hasException) {
- QQmlError error = scope.engine->catchExceptionAsQmlError();
+ if (v4->hasException) {
+ QQmlError error = v4->catchExceptionAsQmlError();
if (error.isValid())
- ep->warning(error);
+ QQmlEnginePrivate::get(v4)->warning(error);
}
- QV4::ScopedValue retval(scope, qmlContext->d()->qml());
- if (m_precompiledScript->isSharedLibrary()) {
- m_value.set(scope.engine, retval);
+ QV4::ScopedValue value(scope);
+ if (qmlContextData)
+ value = qmlExecutionContext->d()->qml();
+ else if (module)
+ value = module->d();
+
+ if (m_precompiledScript->isSharedLibrary() || m_precompiledScript->isESModule()) {
m_loaded = true;
+ m_value.set(v4, value);
}
- return retval->asReturnedValue();
+ return value->asReturnedValue();
}
void QQmlScriptData::clear()
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index 29c91346de..5bb4e9d490 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -534,8 +534,6 @@ private:
QQmlScriptData();
public:
- ~QQmlScriptData() override;
-
QUrl url;
QString urlString;
QQmlTypeNameCache *typeNameCache;
@@ -556,7 +554,6 @@ private:
bool m_loaded;
QQmlRefPointer<QV4::CompiledData::CompilationUnit> m_precompiledScript;
- QV4::Script *m_program;
QV4::PersistentValue m_value;
};
diff --git a/src/qml/types/qqmldelegatecomponent.cpp b/src/qml/types/qqmldelegatecomponent.cpp
index 007e8e2ec6..470f6cab6a 100644
--- a/src/qml/types/qqmldelegatecomponent.cpp
+++ b/src/qml/types/qqmldelegatecomponent.cpp
@@ -66,9 +66,9 @@ QVariant QQmlAbstractDelegateComponent::value(QQmlAdaptorModel *adaptorModel, in
To use this module, import the module with the following line:
- \code
+ \qml
import Qt.labs.qmlmodels 1.0
- \endcode
+ \endqml
*/
/*!
@@ -79,6 +79,7 @@ QVariant QQmlAbstractDelegateComponent::value(QQmlAdaptorModel *adaptorModel, in
The DelegateChoice type wraps a delegate and defines the circumstances
in which it should be chosen.
+
DelegateChoices can be nested inside a DelegateChooser.
\sa DelegateChooser
@@ -86,7 +87,7 @@ QVariant QQmlAbstractDelegateComponent::value(QQmlAdaptorModel *adaptorModel, in
/*!
\qmlproperty string QtQml.Models::DelegateChoice::roleValue
- This property holds the value used to match the role data for the role provided by \l DefaultDelegateChooser::role.
+ This property holds the value used to match the role data for the role provided by \l DelegateChooser::role.
*/
QVariant QQmlDelegateChoice::roleValue() const
{
@@ -106,20 +107,20 @@ void QQmlDelegateChoice::setRoleValue(const QVariant &value)
\qmlproperty index QtQml.Models::DelegateChoice::row
This property holds the value used to match the row value of model elements.
With models that have only the index property (and thus only one column), this property
- should be intended as index, and set to the desired index value.
+ should be intended as an index, and set to the desired index value.
\note Setting both row and index has undefined behavior. The two are equivalent and only
one should be used.
- \sa QtQml.Models::DelegateChoice::index
+ \sa index
*/
/*!
\qmlproperty index QtQml.Models::DelegateChoice::index
This property holds the value used to match the index value of model elements.
- This is effectively an alias for \l QtQml.Models::DelegateChoice::row
+ This is effectively an alias for \l row.
- \sa QtQml.Models::DelegateChoice::row
+ \sa row
*/
int QQmlDelegateChoice::row() const
{
@@ -190,14 +191,14 @@ bool QQmlDelegateChoice::match(int row, int column, const QVariant &value) const
}
/*!
- \qmltype QQmlDelegateChooser
+ \qmltype DelegateChooser
\instantiates QQmlDelegateChooser
\inqmlmodule Qt.labs.qmlmodels
\brief Allows a view to use different delegates for different types of items in the model.
The DelegateChooser is a special \l Component type intended for those scenarios where a Component is required
by a view and used as a delegate.
- DelegateChooser encapsulates a set of \l DelegateChoices.
+ DelegateChooser encapsulates a set of \l {DelegateChoice}s.
These choices are used determine the delegate that will be instantiated for each
item in the model.
The selection of the choice is performed based on the value that a model item has for \l role,
@@ -227,13 +228,14 @@ void QQmlDelegateChooser::setRole(const QString &role)
/*!
\qmlproperty list<DelegateChoice> QtQml.Models::DelegateChooser::choices
\default
+
The list of DelegateChoices for the chooser.
The list is treated as an ordered list, where the first DelegateChoice to match
will be used be a view.
It should not generally be necessary to refer to the \c choices property,
- as it is the default property for DefaultDelegateChooser and thus all child items are
+ as it is the default property for DelegateChooser and thus all child items are
automatically assigned to this property.
*/
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
index 243a7ce749..8a0d60a092 100644
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -437,8 +437,6 @@ void QQmlDelegateModel::setModel(const QVariant &model)
The delegate provides a template defining each item instantiated by a view.
The index is exposed as an accessible \c index property. Properties of the
model are also available depending upon the type of \l {qml-data-models}{Data Model}.
-
- \sa DelegateComponent
*/
QQmlComponent *QQmlDelegateModel::delegate() const
{
diff --git a/src/qml/types/qqmlitemselectionmodel.qdoc b/src/qml/types/qqmlitemselectionmodel.qdoc
index 7ddfd79217..43da4f7a55 100644
--- a/src/qml/types/qqmlitemselectionmodel.qdoc
+++ b/src/qml/types/qqmlitemselectionmodel.qdoc
@@ -52,7 +52,7 @@
It will trigger property binding updates every time \l selectionChanged()
is emitted, even though its value hasn't changed.
- \sa selection(), selectedIndexes, select(), selectionChanged()
+ \sa selection, selectedIndexes, select(), selectionChanged()
*/
/*!
@@ -235,5 +235,5 @@
Note that this signal will not be emitted when the item model is reset.
- \sa currentIndex(), setCurrentIndex(), selectionChanged()
+ \sa currentIndex, setCurrentIndex(), selectionChanged()
*/
diff --git a/src/qmltest/doc/qtqmltest.qdocconf b/src/qmltest/doc/qtqmltest.qdocconf
index 33e8ae334c..a819546fba 100644
--- a/src/qmltest/doc/qtqmltest.qdocconf
+++ b/src/qmltest/doc/qtqmltest.qdocconf
@@ -31,7 +31,7 @@ qhp.QtQmlTest.subprojects.qmltypes.sortPages = true
tagfile = ../../../doc/qtqmltest/qtqmltest.tags
-depends += qtcore qtxmlpatterns qtgui qttestlib qtqml qtquick qtdoc
+depends += qtcore qtgui qttestlib qtqml qtquick qtdoc
headerdirs += ..
diff --git a/src/quick/doc/qtquick.qdocconf b/src/quick/doc/qtquick.qdocconf
index 1dbf199bc8..8c69eba6a6 100644
--- a/src/quick/doc/qtquick.qdocconf
+++ b/src/quick/doc/qtquick.qdocconf
@@ -37,7 +37,7 @@ qhp.QtQuick.subprojects.examples.selectors = fake:example
tagfile = ../../../doc/qtquick/qtquick.tags
-depends += qtcore qtxmlpatterns qtqml qtqmltest qtgui qtlinguist qtquickcontrols qtdoc qtquickdialogs qtsensors qtwidgets qmake qtmultimedia qtgraphicaleffects qtsql
+depends += qtcore qtqml qtqmltest qtgui qtlinguist qtquickcontrols qtquickcontrols2 qtdoc qtquickdialogs qtsensors qtwidgets qmake qtmultimedia qtgraphicaleffects qtsql
headerdirs += ..\
../../quickwidgets
diff --git a/src/quick/doc/snippets/qml/xmlrole.qml b/src/quick/doc/snippets/qml/xmlrole.qml
deleted file mode 100644
index 9c5172ba45..0000000000
--- a/src/quick/doc/snippets/qml/xmlrole.qml
+++ /dev/null
@@ -1,96 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, 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$
-**
-****************************************************************************/
-
-import QtQuick 2.0
-import QtQuick.XmlListModel 2.0
-
-Rectangle {
- width: 300; height: 200
-
-//![0]
-XmlListModel {
- id: model
-//![0]
- source: "xmlrole.xml"
-
-//![1]
- // XmlRole queries will be made on <book> elements
- query: "/catalog/book"
-
- // query the book title
- XmlRole { name: "title"; query: "title/string()" }
-
- // query the book's year
- XmlRole { name: "year"; query: "year/number()" }
-
- // query the book's type (the '@' indicates 'type' is an attribute, not an element)
- XmlRole { name: "type"; query: "@type/string()" }
-
- // query the book's first listed author (note in XPath the first index is 1, not 0)
- XmlRole { name: "first_author"; query: "author[1]/string()" }
-
- // query the wanted attribute as a boolean
- XmlRole { name: "wanted"; query: "boolean(@wanted)" }
-}
-//![1]
-
-//![2]
-ListView {
- width: 300; height: 200
- model: model
- delegate: Column {
- Text { text: title + " (" + type + ")"; font.bold: wanted }
- Text { text: first_author }
- Text { text: year }
- }
-//![2]
-}
-
-}
diff --git a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
index 6c399f6874..97ac466e94 100644
--- a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
+++ b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp
@@ -36,6 +36,7 @@
#include <QSysInfo>
#include <QLoggingCategory>
#include <private/qqmlcomponent_p.h>
+#include <qtranslator.h>
class tst_qmlcachegen: public QObject
{
@@ -169,11 +170,26 @@ void tst_qmlcachegen::loadGeneratedFile()
QVERIFY(unitData->flags & QV4::CompiledData::Unit::StaticData);
}
+class QTestTranslator : public QTranslator
+{
+public:
+ QString translate(const char *context, const char *sourceText, const char */*disambiguation*/, int /*n*/) const override
+ {
+ m_lastContext = QString::fromUtf8(context);
+ return QString::fromUtf8(sourceText).toUpper();
+ }
+ bool isEmpty() const override { return true; }
+ mutable QString m_lastContext;
+};
+
void tst_qmlcachegen::translationExpressionSupport()
{
QTemporaryDir tempDir;
QVERIFY(tempDir.isValid());
+ QTestTranslator translator;
+ qApp->installTranslator(&translator);
+
const auto writeTempFile = [&tempDir](const QString &fileName, const char *contents) {
QFile f(tempDir.path() + '/' + fileName);
const bool ok = f.open(QIODevice::WriteOnly | QIODevice::Truncate);
@@ -207,7 +223,8 @@ void tst_qmlcachegen::translationExpressionSupport()
CleanlyLoadingComponent component(&engine, QUrl::fromLocalFile(testFilePath));
QScopedPointer<QObject> obj(component.create());
QVERIFY(!obj.isNull());
- QCOMPARE(obj->property("text").toString(), QString("All Ok"));
+ QCOMPARE(obj->property("text").toString(), QString("ALL Ok"));
+ QCOMPARE(translator.m_lastContext, QStringLiteral("test"));
}
void tst_qmlcachegen::signalHandlerParameters()
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index 8f388fcac6..71c4e03812 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -359,6 +359,7 @@ private slots:
void temporaryDeadZone();
void importLexicalVariables_data();
void importLexicalVariables();
+ void hugeObject();
private:
// static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter);
@@ -8821,10 +8822,10 @@ void tst_qqmlecmascript::importLexicalVariables_data()
QTest::newRow("script")
<< testFileUrl("importLexicalVariables_script.qml")
- << QStringLiteral("0?? 1?? 2??");
+ << QStringLiteral("000 100 210");
QTest::newRow("pragmaLibrary")
<< testFileUrl("importLexicalVariables_pragmaLibrary.qml")
- << QStringLiteral("0?? 1?? 2??");
+ << QStringLiteral("000 100 210");
QTest::newRow("module")
<< testFileUrl("importLexicalVariables_module.qml")
<< QStringLiteral("000 000 110");
@@ -8846,6 +8847,17 @@ void tst_qqmlecmascript::importLexicalVariables()
QCOMPARE(result, QVariant(expected));
}
+void tst_qqmlecmascript::hugeObject()
+{
+ // mainly check that this doesn't crash
+ QJSEngine engine;
+ QJSValue v = engine.evaluate(QString::fromLatin1(
+ "var known = {}, prefix = 'x'\n"
+ "for (var i = 0; i < 150000; i++) known[prefix + i] = true;"
+ ));
+ QVERIFY(!v.isError());
+}
+
QTEST_MAIN(tst_qqmlecmascript)
#include "tst_qqmlecmascript.moc"
diff --git a/tests/auto/qml/v4misc/tst_v4misc.cpp b/tests/auto/qml/v4misc/tst_v4misc.cpp
index da7b610978..c35f412870 100644
--- a/tests/auto/qml/v4misc/tst_v4misc.cpp
+++ b/tests/auto/qml/v4misc/tst_v4misc.cpp
@@ -115,6 +115,7 @@ void tst_v4misc::parserMisc_data()
QTest::newRow("for (va() in obj) {}") << QString("ReferenceError: Invalid left-hand side expression for 'in' expression");
QTest::newRow("[1]=7[A=8=9]") << QString("ReferenceError: left-hand side of assignment operator is not an lvalue");
QTest::newRow("var asmvalsLen = asmvals{{{{{ngth}}}}};") << QString("SyntaxError: Expected token `;'");
+ QTest::newRow("T||9[---L6i]") << QString("ReferenceError: Prefix ++ operator applied to value that is not a reference.");
}
void tst_v4misc::parserMisc()
diff --git a/tests/auto/quick/examples/examples.pro b/tests/auto/quick/examples/examples.pro
index fd8cfd83c8..c047f993ea 100644
--- a/tests/auto/quick/examples/examples.pro
+++ b/tests/auto/quick/examples/examples.pro
@@ -8,5 +8,4 @@ DEFINES += SRCDIR=\\\"$$PWD\\\"
#temporary
QT += core-private gui-private qml-private quick-private testlib
-!qtHaveModule(xmlpatterns): DEFINES += QT_NO_XMLPATTERNS
diff --git a/tests/auto/quick/examples/tst_examples.cpp b/tests/auto/quick/examples/tst_examples.cpp
index b3fc87a8de..9b3fa8fd2c 100644
--- a/tests/auto/quick/examples/tst_examples.cpp
+++ b/tests/auto/quick/examples/tst_examples.cpp
@@ -88,12 +88,6 @@ tst_examples::tst_examples()
excludedFiles << "examples/quick/shapes/content/main.qml"; // relies on resources
excludedFiles << "examples/quick/shapes/content/interactive.qml"; // relies on resources
-#ifdef QT_NO_XMLPATTERNS
- excludedFiles << "snippets/qml/xmlrole.qml";
- excludedFiles << "particles/itemparticle/particleview.qml";
- excludedFiles << "views/visualdatamodel/slideshow.qml";
-#endif
-
#if !QT_CONFIG(opengl)
//No support for Particles
excludedFiles << "examples/qml/dynamicscene/dynamicscene.qml";
diff --git a/tests/auto/quick/qquickxmllistmodel/data/empty.xml b/tests/auto/quick/qquickxmllistmodel/data/empty.xml
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/empty.xml
+++ /dev/null
diff --git a/tests/auto/quick/qquickxmllistmodel/data/get.qml b/tests/auto/quick/qquickxmllistmodel/data/get.qml
deleted file mode 100644
index 509da7174b..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/get.qml
+++ /dev/null
@@ -1,61 +0,0 @@
-import QtQuick 2.0
-import QtQuick.XmlListModel 2.0
-
-XmlListModel {
- source: "model.xml"
- query: "/Pets/Pet"
- XmlRole { name: "name"; query: "name/string()" }
- XmlRole { name: "type"; query: "type/string()" }
- XmlRole { name: "age"; query: "age/number()" }
- XmlRole { name: "size"; query: "size/string()" }
-
- id: root
-
- property bool preTest: false
- property bool postTest: false
-
- function runPreTest() {
- if (root.get(0) != undefined)
- return;
-
- preTest = true;
- }
-
- function runPostTest() {
- if (root.get(-1) != undefined)
- return;
-
- var row = root.get(0);
- if (row.name != "Polly" ||
- row.type != "Parrot" ||
- row.age != 12 ||
- row.size != "Small")
- return;
-
- row = root.get(1);
- if (row.name != "Penny" ||
- row.type != "Turtle" ||
- row.age != 4 ||
- row.size != "Small")
- return;
-
- row = root.get(7);
- if (row.name != "Rover" ||
- row.type != "Dog" ||
- row.age != 0 ||
- row.size != "Large")
- return;
-
- row = root.get(8);
- if (row.name != "Tiny" ||
- row.type != "Elephant" ||
- row.age != 15 ||
- row.size != "Large")
- return;
-
- if (root.get(9) != undefined)
- return;
-
- postTest = true;
- }
-}
diff --git a/tests/auto/quick/qquickxmllistmodel/data/groups.qml b/tests/auto/quick/qquickxmllistmodel/data/groups.qml
deleted file mode 100644
index c1b574a822..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/groups.qml
+++ /dev/null
@@ -1,10 +0,0 @@
-import QtQuick 2.0
-import QtQuick.XmlListModel 2.0
-
-XmlListModel {
- source: "groups.xml"
- query: "//animal[@name='Garfield']/parent::group"
-
- XmlRole { name: "id"; query: "@id/string()" }
- XmlRole { name: "name"; query: "@name/string()" }
-}
diff --git a/tests/auto/quick/qquickxmllistmodel/data/groups.xml b/tests/auto/quick/qquickxmllistmodel/data/groups.xml
deleted file mode 100644
index 5de4d2ec71..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/groups.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<groups version="2.0">
- <group id="1" name="Animals" type="root">
- <group id="11" name="dogs">
- <animal id="111" name="Lassie"/>
- <animal id="112" name="Laika"/>
- <animal id="113" name="Wile E. Coyote" type="fictional"/>
- </group>
- <group id="12" name="cats">
- <animal id="121" name="Garfield" type="fictional"/>
- <animal id="122" name="Sylvester" type="fictional"/>
- </group>
- <group id="13" name="birds">
- <animal id="131" name="Donald Duck" type="fictional"/>
- <animal id="132" name="Phoenix" type="fictional"/>
- </group>
- </group>
-</groups>
diff --git a/tests/auto/quick/qquickxmllistmodel/data/model.qml b/tests/auto/quick/qquickxmllistmodel/data/model.qml
deleted file mode 100644
index 2df3927479..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/model.qml
+++ /dev/null
@@ -1,11 +0,0 @@
-import QtQuick 2.0
-import QtQuick.XmlListModel 2.0
-
-XmlListModel {
- source: "model.xml"
- query: "/Pets/Pet"
- XmlRole { name: "name"; query: "name/string()" }
- XmlRole { name: "type"; query: "type/string()" }
- XmlRole { name: "age"; query: "age/number()" }
- XmlRole { name: "size"; query: "size/string()" }
-}
diff --git a/tests/auto/quick/qquickxmllistmodel/data/model.xml b/tests/auto/quick/qquickxmllistmodel/data/model.xml
deleted file mode 100644
index 40cd6d0432..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/model.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-<Pets>
- <Pet>
- <name>Polly</name>
- <type>Parrot</type>
- <age>12</age>
- <size>Small</size>
- </Pet>
- <Pet>
- <name>Penny</name>
- <type>Turtle</type>
- <age>4</age>
- <size>Small</size>
- </Pet>
- <Pet>
- <name>Warren</name>
- <type>Rabbit</type>
- <age>2</age>
- <size>Small</size>
- </Pet>
- <Pet>
- <name>Spot</name>
- <type>Dog</type>
- <age>9</age>
- <size>Medium</size>
- </Pet>
- <Pet>
- <name>Whiskers</name>
- <type>Cat</type>
- <age>2</age>
- <size>Medium</size>
- </Pet>
- <Pet>
- <name>Joey</name>
- <type>Kangaroo</type>
- <age>1</age>
- </Pet>
- <Pet>
- <name>Kimba</name>
- <type>Bunny</type>
- <age>65</age>
- <size>Large</size>
- </Pet>
- <Pet>
- <name>Rover</name>
- <type>Dog</type>
- <size>Large</size>
- </Pet>
- <Pet>
- <name>Tiny</name>
- <type>Elephant</type>
- <age>15</age>
- <size>Large</size>
- </Pet>
-</Pets>
diff --git a/tests/auto/quick/qquickxmllistmodel/data/model2.xml b/tests/auto/quick/qquickxmllistmodel/data/model2.xml
deleted file mode 100644
index dab2ec6dc0..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/model2.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-<Pets>
- <Pet>
- <name>Polly</name>
- <type>Parrot</type>
- <age>12</age>
- <size>Small</size>
- </Pet>
- <Pet>
- <name>Penny</name>
- <type>Turtle</type>
- <age>4</age>
- <size>Small</size>
- </Pet>
-</Pets>
diff --git a/tests/auto/quick/qquickxmllistmodel/data/propertychanges.qml b/tests/auto/quick/qquickxmllistmodel/data/propertychanges.qml
deleted file mode 100644
index f8a97bffc3..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/propertychanges.qml
+++ /dev/null
@@ -1,11 +0,0 @@
-import QtQuick 2.0
-import QtQuick.XmlListModel 2.0
-
-XmlListModel {
- source: "model.xml"
- query: "/Pets/Pet"
- XmlRole { objectName: "role"; name: "name"; query: "name/string()" }
- XmlRole { name: "type"; query: "type/string()" }
- XmlRole { name: "age"; query: "age/number()" }
- XmlRole { name: "size"; query: "size/string()" }
-}
diff --git a/tests/auto/quick/qquickxmllistmodel/data/proxyCrash.qml b/tests/auto/quick/qquickxmllistmodel/data/proxyCrash.qml
deleted file mode 100644
index c0c5a25e3c..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/proxyCrash.qml
+++ /dev/null
@@ -1,9 +0,0 @@
-import QtQuick 2.0
-import QtQuick.XmlListModel 2.0
-import SortFilterProxyModel 1.0
-
-SortFilterProxyModel {
- source: XmlListModel {
- XmlRole { }
- }
-}
diff --git a/tests/auto/quick/qquickxmllistmodel/data/recipes.qml b/tests/auto/quick/qquickxmllistmodel/data/recipes.qml
deleted file mode 100644
index dc609e95e3..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/recipes.qml
+++ /dev/null
@@ -1,11 +0,0 @@
-import QtQuick 2.0
-import QtQuick.XmlListModel 2.0
-
-XmlListModel {
- source: "recipes.xml"
- query: "/recipes/recipe"
- XmlRole { name: "title"; query: "@title/string()" }
- XmlRole { name: "picture"; query: "picture/string()" }
- XmlRole { name: "ingredients"; query: "ingredients/string()" }
- XmlRole { name: "preparation"; query: "method/string()" }
-}
diff --git a/tests/auto/quick/qquickxmllistmodel/data/recipes.xml b/tests/auto/quick/qquickxmllistmodel/data/recipes.xml
deleted file mode 100644
index d71de60710..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/recipes.xml
+++ /dev/null
@@ -1,90 +0,0 @@
-<recipes>
- <recipe title="Pancakes">
- <picture>content/pics/pancakes.jpg</picture>
- <ingredients><![CDATA[<html>
- <ul>
- <li> 1 cup (150g) self-raising flour
- <li> 1 tbs caster sugar
- <li> 3/4 cup (185ml) milk
- <li> 1 egg
- </ul>
- </html>
- ]]></ingredients>
- <method><![CDATA[<html>
- <ol>
- <li> Sift flour and sugar together into a bowl. Add a pinch of salt.
- <li> Beat milk and egg together, then add to dry ingredients. Beat until smooth.
- <li> Pour mixture into a pan on medium heat and cook until bubbles appear on the surface.
- <li> Turn over and cook other side until golden.
- </ol>
- </html>
- ]]></method>
- </recipe>
- <recipe title="Fruit Salad">
- <picture>content/pics/fruit-salad.jpg</picture>
- <ingredients><![CDATA[* Seasonal Fruit]]></ingredients>
- <method><![CDATA[* Chop fruit and place in a bowl.]]></method>
- </recipe>
- <recipe title="Vegetable Soup">
- <picture>content/pics/vegetable-soup.jpg</picture>
- <ingredients><![CDATA[<html>
- <ul>
- <li> 1 onion
- <li> 1 turnip
- <li> 1 potato
- <li> 1 carrot
- <li> 1 head of celery
- <li> 1 1/2 litres of water
- </ul>
- </html>
- ]]></ingredients>
- <method><![CDATA[<html>
- <ol>
- <li> Chop vegetables.
- <li> Boil in water until vegetables soften.
- <li> Season with salt and pepper to taste.
- </ol>
- </html>
- ]]></method>
- </recipe>
- <recipe title="Hamburger">
- <picture>content/pics/hamburger.jpg</picture>
- <ingredients><![CDATA[<html>
- <ul>
- <li> 500g minced beef
- <li> Seasoning
- <li> lettuce, tomato, onion, cheese
- <li> 1 hamburger bun for each burger
- </ul>
- </html>
- ]]></ingredients>
- <method><![CDATA[<html>
- <ol>
- <li> Mix the beef, together with seasoning, in a food processor.
- <li> Shape the beef into burgers.
- <li> Grill the burgers for about 5 mins on each side (until cooked through)
- <li> Serve each burger on a bun with ketchup, cheese, lettuce, tomato and onion.
- </ol>
- </html>
- ]]></method>
- </recipe>
- <recipe title="Lemonade">
- <picture>content/pics/lemonade.jpg</picture>
- <ingredients><![CDATA[<html>
- <ul>
- <li> 1 cup Lemon Juice
- <li> 1 cup Sugar
- <li> 6 Cups of Water (2 cups warm water, 4 cups cold water)
- </ul>
- </html>
- ]]></ingredients>
- <method><![CDATA[<html>
- <ol>
- <li> Pour 2 cups of warm water into a pitcher and stir in sugar until it dissolves.
- <li> Pour in lemon juice, stir again, and add 4 cups of cold water.
- <li> Chill or serve over ice cubes.
- </ol>
- </html>
- ]]></method>
- </recipe>
-</recipes>
diff --git a/tests/auto/quick/qquickxmllistmodel/data/roleCrash.qml b/tests/auto/quick/qquickxmllistmodel/data/roleCrash.qml
deleted file mode 100644
index 6a7059bb45..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/roleCrash.qml
+++ /dev/null
@@ -1,8 +0,0 @@
-import QtQuick 2.0
-import QtQuick.XmlListModel 2.0
-
-XmlListModel {
- id: model
- XmlRole {}
- Component.onCompleted: model.roles = 0
-}
diff --git a/tests/auto/quick/qquickxmllistmodel/data/roleErrors.qml b/tests/auto/quick/qquickxmllistmodel/data/roleErrors.qml
deleted file mode 100644
index 91664b6d4a..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/roleErrors.qml
+++ /dev/null
@@ -1,11 +0,0 @@
-import QtQuick 2.0
-import QtQuick.XmlListModel 2.0
-
-XmlListModel {
- source: "model.xml"
- query: "/Pets/Pet"
- XmlRole { name: "name"; query: "/name/string()" } //starts with '/'
- XmlRole { name: "type"; query: "type" } //no type
- XmlRole { name: "age"; query: "age/" } //ends with '/'
- XmlRole { name: "size"; query: "size/number()" } //wrong type
-}
diff --git a/tests/auto/quick/qquickxmllistmodel/data/roleKeys.qml b/tests/auto/quick/qquickxmllistmodel/data/roleKeys.qml
deleted file mode 100644
index 9f667d86e5..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/roleKeys.qml
+++ /dev/null
@@ -1,13 +0,0 @@
-import QtQuick 2.0
-import QtQuick.XmlListModel 2.0
-
-XmlListModel {
- query: "/data/item"
- XmlRole { id: nameRole; name: "name"; query: "name/string()"; isKey: true }
- XmlRole { name: "age"; query: "age/number()"; isKey: true }
- XmlRole { name: "sport"; query: "sport/string()" }
-
- function disableNameKey() {
- nameRole.isKey = false;
- }
-}
diff --git a/tests/auto/quick/qquickxmllistmodel/data/testtypes.qml b/tests/auto/quick/qquickxmllistmodel/data/testtypes.qml
deleted file mode 100644
index 5ec1ffa35f..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/testtypes.qml
+++ /dev/null
@@ -1,8 +0,0 @@
-import QtQuick 2.0
-import QtQuick.XmlListModel 2.0
-
-XmlListModel {
- query: "/data"
- XmlRole { name: "stringValue"; query: "a-string/string()" }
- XmlRole { name: "numberValue"; query: "a-number/number()" }
-}
diff --git a/tests/auto/quick/qquickxmllistmodel/data/unique.qml b/tests/auto/quick/qquickxmllistmodel/data/unique.qml
deleted file mode 100644
index 322a2e4e5c..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/data/unique.qml
+++ /dev/null
@@ -1,9 +0,0 @@
-import QtQuick 2.0
-import QtQuick.XmlListModel 2.0
-
-XmlListModel {
- source: "model.xml"
- query: "/Pets/Pet"
- XmlRole { name: "name"; query: "name/string()" }
- XmlRole { name: "name"; query: "type/string()" }
-}
diff --git a/tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro b/tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro
deleted file mode 100644
index 902325802c..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/qquickxmllistmodel.pro
+++ /dev/null
@@ -1,16 +0,0 @@
-CONFIG += testcase
-TARGET = tst_qquickxmllistmodel
-macx:CONFIG -= app_bundle
-
-SOURCES += tst_qquickxmllistmodel.cpp \
- ../../../../src/imports/xmllistmodel/qqmlxmllistmodel.cpp
-HEADERS += ../../../../src/imports/xmllistmodel/qqmlxmllistmodel_p.h
-
-include (../../shared/util.pri)
-
-TESTDATA = data/*
-
-QT += core-private gui-private qml-private network testlib xmlpatterns
-
-OTHER_FILES += \
- data/groups.qml
diff --git a/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp b/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp
deleted file mode 100644
index bcff0c46fb..0000000000
--- a/tests/auto/quick/qquickxmllistmodel/tst_qquickxmllistmodel.cpp
+++ /dev/null
@@ -1,1011 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtTest/QtTest>
-#include <QtGlobal>
-#include <math.h>
-#include <QMetaObject>
-#include <qtest.h>
-#include <QtTest/qsignalspy.h>
-#include <QtQml/qqmlnetworkaccessmanagerfactory.h>
-#include <QtNetwork/qnetworkaccessmanager.h>
-#include <QtNetwork/qnetworkrequest.h>
-#include <QtCore/qtimer.h>
-#include <QtCore/qfile.h>
-#include <QtCore/qtemporaryfile.h>
-#include <QtCore/qsortfilterproxymodel.h>
-#include "../../shared/util.h"
-#include <private/qqmlengine_p.h>
-
-#include <QtQml/qqmlengine.h>
-#include <QtQml/qqmlcomponent.h>
-#include "../../../../src/imports/xmllistmodel/qqmlxmllistmodel_p.h"
-
-#include <algorithm>
-
-typedef QPair<int, int> QQuickXmlListRange;
-typedef QList<QVariantList> QQmlXmlModelData;
-
-Q_DECLARE_METATYPE(QList<QQuickXmlListRange>)
-Q_DECLARE_METATYPE(QQmlXmlModelData)
-Q_DECLARE_METATYPE(QQuickXmlListModel::Status)
-
-class tst_qquickxmllistmodel : public QQmlDataTest
-
-{
- Q_OBJECT
-public:
- tst_qquickxmllistmodel() {}
-
-private slots:
- void initTestCase() {
- QQmlDataTest::initTestCase();
- qRegisterMetaType<QQuickXmlListModel::Status>();
- }
-
- void buildModel();
- void testTypes();
- void testTypes_data();
- void cdata();
- void attributes();
- void roles();
- void roleErrors();
- void uniqueRoleNames();
- void headers();
- void xml();
- void xml_data();
- void source();
- void source_data();
- void data();
- void get();
- void reload();
- void useKeys();
- void useKeys_data();
- void noKeysValueChanges();
- void keysChanged();
- void threading();
- void threading_data();
- void propertyChanges();
- void selectAncestor();
-
- void roleCrash();
- void proxyCrash();
-
-private:
- QString errorString(QAbstractItemModel *model) {
- QString ret;
- QMetaObject::invokeMethod(model, "errorString", Q_RETURN_ARG(QString, ret));
- return ret;
- }
-
- QString makeItemXmlAndData(const QString &data, QQmlXmlModelData *modelData = 0) const
- {
- if (modelData)
- modelData->clear();
- QString xml;
-
- if (!data.isEmpty()) {
- QStringList items = data.split(QLatin1Char(';'));
- foreach(const QString &item, items) {
- if (item.isEmpty())
- continue;
- QVariantList variants;
- xml += QLatin1String("<item>");
- QStringList fields = item.split(QLatin1Char(','));
- foreach(const QString &field, fields) {
- QStringList values = field.split(QLatin1Char('='));
- if (values.count() != 2) {
- qWarning() << "makeItemXmlAndData: invalid field:" << field;
- continue;
- }
- xml += QString("<%1>%2</%1>").arg(values[0], values[1]);
- if (!modelData)
- continue;
- bool isNum = false;
- int number = values[1].toInt(&isNum);
- if (isNum)
- variants << number;
- else
- variants << values[1];
- }
- xml += QLatin1String("</item>");
- if (modelData)
- modelData->append(variants);
- }
- }
-
- QString decl = "<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?>";
- return decl + QLatin1String("<data>") + xml + QLatin1String("</data>");
- }
-
- QQmlEngine engine;
-};
-
-class CustomNetworkAccessManagerFactory : public QObject, public QQmlNetworkAccessManagerFactory
-{
- Q_OBJECT
-public:
- QVariantMap lastSentHeaders;
-
-protected:
- QNetworkAccessManager *create(QObject *parent);
-};
-
-class CustomNetworkAccessManager : public QNetworkAccessManager
-{
- Q_OBJECT
-public:
- CustomNetworkAccessManager(CustomNetworkAccessManagerFactory *factory, QObject *parent)
- : QNetworkAccessManager(parent), m_factory(factory) {}
-
-protected:
- QNetworkReply *createRequest(Operation op, const QNetworkRequest &req, QIODevice * outgoingData = 0)
- {
- if (m_factory) {
- QVariantMap map;
- foreach (const QString &header, req.rawHeaderList())
- map[header] = req.rawHeader(header.toUtf8());
- m_factory->lastSentHeaders = map;
- }
- return QNetworkAccessManager::createRequest(op, req, outgoingData);
- }
-
- QPointer<CustomNetworkAccessManagerFactory> m_factory;
-};
-
-QNetworkAccessManager *CustomNetworkAccessManagerFactory::create(QObject *parent)
-{
- return new CustomNetworkAccessManager(this, parent);
-}
-
-
-void tst_qquickxmllistmodel::buildModel()
-{
- QQmlComponent component(&engine, testFileUrl("model.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
- QTRY_COMPARE(model->rowCount(), 9);
-
- QModelIndex index = model->index(3, 0);
- QCOMPARE(model->data(index, Qt::UserRole).toString(), QLatin1String("Spot"));
- QCOMPARE(model->data(index, Qt::UserRole+1).toString(), QLatin1String("Dog"));
- QCOMPARE(model->data(index, Qt::UserRole+2).toInt(), 9);
- QCOMPARE(model->data(index, Qt::UserRole+3).toString(), QLatin1String("Medium"));
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::testTypes()
-{
- QFETCH(QString, xml);
- QFETCH(QString, roleName);
- QFETCH(QVariant, expectedValue);
-
- QQmlComponent component(&engine, testFileUrl("testtypes.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
- model->setProperty("xml",xml.toUtf8());
- QMetaObject::invokeMethod(model, "reload");
- QTRY_COMPARE(model->rowCount(), 1);
-
- int role = model->roleNames().key(roleName.toUtf8(), -1);
- QVERIFY(role >= 0);
-
- QModelIndex index = model->index(0, 0);
- if (expectedValue.toString() == "nan")
- QVERIFY(qIsNaN(model->data(index, role).toDouble()));
- else
- QCOMPARE(model->data(index, role), expectedValue);
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::testTypes_data()
-{
- QTest::addColumn<QString>("xml");
- QTest::addColumn<QString>("roleName");
- QTest::addColumn<QVariant>("expectedValue");
-
- QTest::newRow("missing string field") << "<data></data>"
- << "stringValue" << QVariant("");
- QTest::newRow("empty string") << "<data><a-string></a-string></data>"
- << "stringValue" << QVariant("");
- QTest::newRow("1-char string") << "<data><a-string>5</a-string></data>"
- << "stringValue" << QVariant("5");
- QTest::newRow("string ok") << "<data><a-string>abc def g</a-string></data>"
- << "stringValue" << QVariant("abc def g");
-
- QTest::newRow("missing number field") << "<data></data>"
- << "numberValue" << QVariant("");
- double nan = qQNaN();
- QTest::newRow("empty number field") << "<data><a-number></a-number></data>"
- << "numberValue" << QVariant(nan);
- QTest::newRow("number field with string") << "<data><a-number>a string</a-number></data>"
- << "numberValue" << QVariant(nan);
- QTest::newRow("-1") << "<data><a-number>-1</a-number></data>"
- << "numberValue" << QVariant("-1");
- QTest::newRow("-1.5") << "<data><a-number>-1.5</a-number></data>"
- << "numberValue" << QVariant("-1.5");
- QTest::newRow("0") << "<data><a-number>0</a-number></data>"
- << "numberValue" << QVariant("0");
- QTest::newRow("+1") << "<data><a-number>1</a-number></data>"
- << "numberValue" << QVariant("1");
- QTest::newRow("+1.5") << "<data><a-number>1.5</a-number></data>"
- << "numberValue" << QVariant("1.5");
-}
-
-void tst_qquickxmllistmodel::cdata()
-{
- QQmlComponent component(&engine, testFileUrl("recipes.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
- QTRY_COMPARE(model->rowCount(), 5);
-
- QVERIFY(model->data(model->index(2, 0), Qt::UserRole+2).toString().startsWith(QLatin1String("<html>")));
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::attributes()
-{
- QQmlComponent component(&engine, testFileUrl("recipes.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
- QTRY_COMPARE(model->rowCount(), 5);
- QCOMPARE(model->data(model->index(2, 0), Qt::UserRole).toString(), QLatin1String("Vegetable Soup"));
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::roles()
-{
- QQmlComponent component(&engine, testFileUrl("model.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
- QTRY_COMPARE(model->rowCount(), 9);
-
- QHash<int, QByteArray> roleNames = model->roleNames();
- QCOMPARE(roleNames.count(), 4);
- QVERIFY(roleNames.key("name", -1) >= 0);
- QVERIFY(roleNames.key("type", -1) >= 0);
- QVERIFY(roleNames.key("age", -1) >= 0);
- QVERIFY(roleNames.key("size", -1) >= 0);
-
- QSet<int> roles;
- roles.insert(roleNames.key("name"));
- roles.insert(roleNames.key("type"));
- roles.insert(roleNames.key("age"));
- roles.insert(roleNames.key("size"));
- QCOMPARE(roles.count(), 4);
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::roleErrors()
-{
- QQmlComponent component(&engine, testFileUrl("roleErrors.qml"));
- QTest::ignoreMessage(QtWarningMsg, (testFileUrl("roleErrors.qml").toString() + ":7:5: QML XmlRole: An XmlRole query must not start with '/'").toUtf8().constData());
- QTest::ignoreMessage(QtWarningMsg, (testFileUrl("roleErrors.qml").toString() + ":10:5: QML XmlRole: invalid query: \"age/\"").toUtf8().constData());
-
- //### make sure we receive all expected warning messages.
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
- QTRY_COMPARE(model->rowCount(), 9);
-
- QModelIndex index = model->index(3, 0);
- //### should any of these return valid values?
- QCOMPARE(model->data(index, Qt::UserRole), QVariant());
- QCOMPARE(model->data(index, Qt::UserRole+1), QVariant());
- QCOMPARE(model->data(index, Qt::UserRole+2), QVariant());
-
- QEXPECT_FAIL("", "QTBUG-10797", Continue);
- QCOMPARE(model->data(index, Qt::UserRole+3), QVariant());
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::uniqueRoleNames()
-{
- QQmlComponent component(&engine, testFileUrl("unique.qml"));
- QTest::ignoreMessage(QtWarningMsg, (testFileUrl("unique.qml").toString() + ":8:5: QML XmlRole: \"name\" duplicates a previous role name and will be disabled.").toUtf8().constData());
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
- QTRY_COMPARE(model->rowCount(), 9);
-
- QHash<int, QByteArray> roleNames = model->roleNames();
- QCOMPARE(roleNames.count(), 1);
-
- delete model;
-}
-
-
-void tst_qquickxmllistmodel::xml()
-{
- QFETCH(QString, xml);
- QFETCH(int, count);
-
- QQmlComponent component(&engine, testFileUrl("model.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
-
- QSignalSpy spy(model, SIGNAL(statusChanged(QQuickXmlListModel::Status)));
- QVERIFY(errorString(model).isEmpty());
- QCOMPARE(model->property("progress").toDouble(), qreal(1.0));
- QCOMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
- QQuickXmlListModel::Loading);
- QTRY_COMPARE(spy.count(), 1); spy.clear();
- QTest::qWait(50);
- QCOMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
- QQuickXmlListModel::Ready);
- QVERIFY(errorString(model).isEmpty());
- QCOMPARE(model->property("progress").toDouble(), qreal(1.0));
- QCOMPARE(model->rowCount(), 9);
-
- // if xml is empty (i.e. clearing) it won't have any effect if a source is set
- if (xml.isEmpty())
- model->setProperty("source",QUrl());
- model->setProperty("xml",xml);
- QCOMPARE(model->property("progress").toDouble(), qreal(1.0)); // immediately goes to 1.0 if using setXml()
- QTRY_COMPARE(spy.count(), 1); spy.clear();
- QCOMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
- QQuickXmlListModel::Loading);
- QTRY_COMPARE(spy.count(), 1); spy.clear();
- if (xml.isEmpty())
- QCOMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
- QQuickXmlListModel::Null);
- else
- QCOMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
- QQuickXmlListModel::Ready);
- QVERIFY(errorString(model).isEmpty());
- QCOMPARE(model->rowCount(), count);
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::xml_data()
-{
- QTest::addColumn<QString>("xml");
- QTest::addColumn<int>("count");
-
- QTest::newRow("xml with no items") << "<Pets></Pets>" << 0;
- QTest::newRow("empty xml") << "" << 0;
- QTest::newRow("one item") << "<Pets><Pet><name>Hobbes</name><type>Tiger</type><age>7</age><size>Large</size></Pet></Pets>" << 1;
-}
-
-void tst_qquickxmllistmodel::headers()
-{
- // ensure the QNetworkAccessManagers created for this test are immediately deleted
- QQmlEngine qmlEng;
-
- CustomNetworkAccessManagerFactory factory;
- qmlEng.setNetworkAccessManagerFactory(&factory);
-
- QQmlComponent component(&qmlEng, testFileUrl("model.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
- QTRY_COMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
- QQuickXmlListModel::Ready);
-
- // It doesn't do a network request for a local file
- QCOMPARE(factory.lastSentHeaders.count(), 0);
-
- model->setProperty("source", QUrl("http://localhost/filethatdoesnotexist.xml"));
- QTRY_COMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
- QQuickXmlListModel::Error);
-
- QVariantMap expectedHeaders;
- expectedHeaders["Accept"] = "application/xml,*/*";
-
- QCOMPARE(factory.lastSentHeaders.count(), expectedHeaders.count());
- foreach (const QString &header, expectedHeaders.keys()) {
- QVERIFY(factory.lastSentHeaders.contains(header));
- QCOMPARE(factory.lastSentHeaders[header].toString(), expectedHeaders[header].toString());
- }
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::source()
-{
- QFETCH(QUrl, source);
- QFETCH(int, count);
- QFETCH(QQuickXmlListModel::Status, status);
-
- QQmlComponent component(&engine, testFileUrl("model.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QSignalSpy spy(model, SIGNAL(statusChanged(QQuickXmlListModel::Status)));
-
- QVERIFY(errorString(model).isEmpty());
- QCOMPARE(model->property("progress").toDouble(), qreal(1.0));
- QCOMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
- QQuickXmlListModel::Loading);
- QTRY_COMPARE(spy.count(), 1); spy.clear();
- QCOMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
- QQuickXmlListModel::Ready);
- QVERIFY(errorString(model).isEmpty());
- QCOMPARE(model->property("progress").toDouble(), qreal(1.0));
- QCOMPARE(model->rowCount(), 9);
-
- model->setProperty("source",source);
- if (model->property("source").toString().isEmpty())
- QCOMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
- QQuickXmlListModel::Null);
- QCOMPARE(model->property("progress").toDouble(), qreal(source.isLocalFile() ? 1.0 : 0.0));
- QTRY_COMPARE(spy.count(), 1); spy.clear();
- QCOMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")),
- QQuickXmlListModel::Loading);
- QVERIFY(errorString(model).isEmpty());
-
- QEventLoop loop;
- QTimer timer;
- timer.setSingleShot(true);
- connect(model, SIGNAL(statusChanged(QQuickXmlListModel::Status)), &loop, SLOT(quit()));
- connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
- timer.start(20000);
- loop.exec();
-
- if (spy.count() == 0 && status != QQuickXmlListModel::Ready) {
- qWarning("QQuickXmlListModel invalid source test timed out");
- } else {
- QCOMPARE(spy.count(), 1); spy.clear();
- }
-
- QCOMPARE(qvariant_cast<QQuickXmlListModel::Status>(model->property("status")), status);
- QCOMPARE(model->rowCount(), count);
-
- if (status == QQuickXmlListModel::Ready)
- QCOMPARE(model->property("progress").toDouble(), qreal(1.0));
-
- QCOMPARE(errorString(model).isEmpty(), status == QQuickXmlListModel::Ready);
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::source_data()
-{
- QTest::addColumn<QUrl>("source");
- QTest::addColumn<int>("count");
- QTest::addColumn<QQuickXmlListModel::Status>("status");
-
- QTest::newRow("valid") << testFileUrl("model2.xml") << 2
- << QQuickXmlListModel::Ready;
- QTest::newRow("invalid") << QUrl("http://blah.blah/blah.xml") << 0
- << QQuickXmlListModel::Error;
-
- // empty file
- QTemporaryFile *temp = new QTemporaryFile(this);
- if (temp->open())
- QTest::newRow("empty file") << QUrl::fromLocalFile(temp->fileName()) << 0
- << QQuickXmlListModel::Ready;
- temp->close();
-}
-
-void tst_qquickxmllistmodel::data()
-{
- QQmlComponent component(&engine, testFileUrl("model.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
-
- for (int i=0; i<9; i++) {
- QModelIndex index = model->index(i, 0);
- for (int j=0; j<model->roleNames().count(); j++) {
- QCOMPARE(model->data(index, j), QVariant());
- }
- }
- QTRY_COMPARE(model->rowCount(), 9);
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::get()
-{
- QQmlComponent component(&engine, testFileUrl("get.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
-
- QVERIFY(model != 0);
-
- QVERIFY(QMetaObject::invokeMethod(model, "runPreTest"));
- QCOMPARE(model->property("preTest").toBool(), true);
-
- QTRY_COMPARE(model->rowCount(), 9);
-
- QVERIFY(QMetaObject::invokeMethod(model, "runPostTest"));
- QCOMPARE(model->property("postTest").toBool(), true);
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::reload()
-{
- // If no keys are used, the model should be rebuilt from scratch when
- // reload() is called.
-
- QQmlComponent component(&engine, testFileUrl("model.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
- QTRY_COMPARE(model->rowCount(), 9);
-
- QSignalSpy spyInsert(model, SIGNAL(rowsInserted(QModelIndex,int,int)));
- QSignalSpy spyRemove(model, SIGNAL(rowsRemoved(QModelIndex,int,int)));
- QSignalSpy spyCount(model, SIGNAL(countChanged()));
- //reload multiple times to test the xml query aborting
- QMetaObject::invokeMethod(model, "reload");
- QMetaObject::invokeMethod(model, "reload");
- QCoreApplication::processEvents();
- QMetaObject::invokeMethod(model, "reload");
- QMetaObject::invokeMethod(model, "reload");
- QTRY_COMPARE(spyCount.count(), 0);
- QTRY_COMPARE(spyInsert.count(), 1);
- QTRY_COMPARE(spyRemove.count(), 1);
-
- QCOMPARE(spyInsert[0][1].toInt(), 0);
- QCOMPARE(spyInsert[0][2].toInt(), 8);
-
- QCOMPARE(spyRemove[0][1].toInt(), 0);
- QCOMPARE(spyRemove[0][2].toInt(), 8);
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::useKeys()
-{
- // If using incremental updates through keys, the model should only
- // insert & remove some of the items, instead of throwing everything
- // away and causing the view to repaint the whole view.
-
- QFETCH(QString, oldXml);
- QFETCH(int, oldCount);
- QFETCH(QString, newXml);
- QFETCH(QQmlXmlModelData, newData);
- QFETCH(QList<QQuickXmlListRange>, insertRanges);
- QFETCH(QList<QQuickXmlListRange>, removeRanges);
-
- QQmlComponent component(&engine, testFileUrl("roleKeys.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
-
- model->setProperty("xml",oldXml);
- QTRY_COMPARE(model->rowCount(), oldCount);
-
- QSignalSpy spyInsert(model, SIGNAL(rowsInserted(QModelIndex,int,int)));
- QSignalSpy spyRemove(model, SIGNAL(rowsRemoved(QModelIndex,int,int)));
- QSignalSpy spyCount(model, SIGNAL(countChanged()));
-
- model->setProperty("xml",newXml);
-
- if (oldCount != newData.count()) {
- QTRY_COMPARE(model->rowCount(), newData.count());
- QCOMPARE(spyCount.count(), 1);
- } else {
- QTRY_VERIFY(spyInsert.count() > 0 || spyRemove.count() > 0);
- QCOMPARE(spyCount.count(), 0);
- }
-
- QList<int> roles = model->roleNames().keys();
- std::sort(roles.begin(), roles.end());
- for (int i=0; i<model->rowCount(); i++) {
- QModelIndex index = model->index(i, 0);
- for (int j=0; j<roles.count(); j++)
- QCOMPARE(model->data(index, roles.at(j)), newData[i][j]);
- }
-
- QCOMPARE(spyInsert.count(), insertRanges.count());
- for (int i=0; i<spyInsert.count(); i++) {
- QCOMPARE(spyInsert[i][1].toInt(), insertRanges[i].first);
- QCOMPARE(spyInsert[i][2].toInt(), insertRanges[i].first + insertRanges[i].second - 1);
- }
-
- QCOMPARE(spyRemove.count(), removeRanges.count());
- for (int i=0; i<spyRemove.count(); i++) {
- QCOMPARE(spyRemove[i][1].toInt(), removeRanges[i].first);
- QCOMPARE(spyRemove[i][2].toInt(), removeRanges[i].first + removeRanges[i].second - 1);
- }
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::useKeys_data()
-{
- QTest::addColumn<QString>("oldXml");
- QTest::addColumn<int>("oldCount");
- QTest::addColumn<QString>("newXml");
- QTest::addColumn<QQmlXmlModelData>("newData");
- QTest::addColumn<QList<QQuickXmlListRange> >("insertRanges");
- QTest::addColumn<QList<QQuickXmlListRange> >("removeRanges");
-
- QQmlXmlModelData modelData;
-
- QTest::newRow("append 1")
- << makeItemXmlAndData("name=A,age=25,sport=Football") << 1
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics", &modelData)
- << modelData
- << (QList<QQuickXmlListRange>() << qMakePair(1, 1))
- << QList<QQuickXmlListRange>();
-
- QTest::newRow("append multiple")
- << makeItemXmlAndData("name=A,age=25,sport=Football") << 1
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling", &modelData)
- << modelData
- << (QList<QQuickXmlListRange>() << qMakePair(1, 2))
- << QList<QQuickXmlListRange>();
-
- QTest::newRow("insert in different spots")
- << makeItemXmlAndData("name=B,age=35,sport=Athletics") << 1
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling;name=D,age=55,sport=Golf", &modelData)
- << modelData
- << (QList<QQuickXmlListRange>() << qMakePair(0, 1) << qMakePair(2,2))
- << QList<QQuickXmlListRange>();
-
- QTest::newRow("insert in middle")
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=D,age=55,sport=Golf") << 2
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling;name=D,age=55,sport=Golf", &modelData)
- << modelData
- << (QList<QQuickXmlListRange>() << qMakePair(1, 2))
- << QList<QQuickXmlListRange>();
-
- QTest::newRow("remove first")
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics") << 2
- << makeItemXmlAndData("name=B,age=35,sport=Athletics", &modelData)
- << modelData
- << QList<QQuickXmlListRange>()
- << (QList<QQuickXmlListRange>() << qMakePair(0, 1));
-
- QTest::newRow("remove last")
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics") << 2
- << makeItemXmlAndData("name=A,age=25,sport=Football", &modelData)
- << modelData
- << QList<QQuickXmlListRange>()
- << (QList<QQuickXmlListRange>() << qMakePair(1, 1));
-
- QTest::newRow("remove from multiple spots")
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling;name=D,age=55,sport=Golf;name=E,age=65,sport=Fencing") << 5
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=C,age=45,sport=Curling", &modelData)
- << modelData
- << QList<QQuickXmlListRange>()
- << (QList<QQuickXmlListRange>() << qMakePair(1, 1) << qMakePair(3,2));
-
- QTest::newRow("remove all")
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling") << 3
- << makeItemXmlAndData("", &modelData)
- << modelData
- << QList<QQuickXmlListRange>()
- << (QList<QQuickXmlListRange>() << qMakePair(0, 3));
-
- QTest::newRow("replace item")
- << makeItemXmlAndData("name=A,age=25,sport=Football") << 1
- << makeItemXmlAndData("name=ZZZ,age=25,sport=Football", &modelData)
- << modelData
- << (QList<QQuickXmlListRange>() << qMakePair(0, 1))
- << (QList<QQuickXmlListRange>() << qMakePair(0, 1));
-
- QTest::newRow("add and remove simultaneously, in different spots")
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling;name=D,age=55,sport=Golf") << 4
- << makeItemXmlAndData("name=B,age=35,sport=Athletics;name=E,age=65,sport=Fencing", &modelData)
- << modelData
- << (QList<QQuickXmlListRange>() << qMakePair(1, 1))
- << (QList<QQuickXmlListRange>() << qMakePair(0, 1) << qMakePair(2,2));
-
- QTest::newRow("insert at start, remove at end i.e. rss feed")
- << makeItemXmlAndData("name=C,age=45,sport=Curling;name=D,age=55,sport=Golf;name=E,age=65,sport=Fencing") << 3
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling", &modelData)
- << modelData
- << (QList<QQuickXmlListRange>() << qMakePair(0, 2))
- << (QList<QQuickXmlListRange>() << qMakePair(1, 2));
-
- QTest::newRow("remove at start, insert at end")
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics;name=C,age=45,sport=Curling") << 3
- << makeItemXmlAndData("name=C,age=45,sport=Curling;name=D,age=55,sport=Golf;name=E,age=65,sport=Fencing", &modelData)
- << modelData
- << (QList<QQuickXmlListRange>() << qMakePair(1, 2))
- << (QList<QQuickXmlListRange>() << qMakePair(0, 2));
-
- QTest::newRow("all data has changed")
- << makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35") << 2
- << makeItemXmlAndData("name=C,age=45,sport=Curling;name=D,age=55,sport=Golf", &modelData)
- << modelData
- << (QList<QQuickXmlListRange>() << qMakePair(0, 2))
- << (QList<QQuickXmlListRange>() << qMakePair(0, 2));
-}
-
-void tst_qquickxmllistmodel::noKeysValueChanges()
-{
- // The 'key' roles are 'name' and 'age', as defined in roleKeys.qml.
- // If a 'sport' value is changed, the model should not be reloaded,
- // since 'sport' is not marked as a key.
-
- QQmlComponent component(&engine, testFileUrl("roleKeys.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
-
- QString xml;
-
- xml = makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics");
- model->setProperty("xml",xml);
- QTRY_COMPARE(model->rowCount(), 2);
-
- model->setProperty("xml","");
-
- QSignalSpy spyInsert(model, SIGNAL(rowsInserted(QModelIndex,int,int)));
- QSignalSpy spyRemove(model, SIGNAL(rowsRemoved(QModelIndex,int,int)));
- QSignalSpy spyCount(model, SIGNAL(countChanged()));
-
- xml = makeItemXmlAndData("name=A,age=25,sport=AussieRules;name=B,age=35,sport=Athletics");
- model->setProperty("xml",xml);
-
- QList<int> roles = model->roleNames().keys();
- std::sort(roles.begin(), roles.end());
- // wait for the new xml data to be set, and verify no signals were emitted
- QTRY_VERIFY(model->data(model->index(0, 0), roles.at(2)).toString() != QLatin1String("Football"));
- QCOMPARE(model->data(model->index(0, 0), roles.at(2)).toString(), QLatin1String("AussieRules"));
-
- QCOMPARE(spyInsert.count(), 0);
- QCOMPARE(spyRemove.count(), 0);
- QCOMPARE(spyCount.count(), 0);
-
- QCOMPARE(model->rowCount(), 2);
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::keysChanged()
-{
- // If the key roles change, the next time the data is reloaded, it should
- // delete all its data and build a clean model (i.e. same behaviour as
- // if no keys are set).
-
- QQmlComponent component(&engine, testFileUrl("roleKeys.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
-
- QString xml = makeItemXmlAndData("name=A,age=25,sport=Football;name=B,age=35,sport=Athletics");
- model->setProperty("xml",xml);
- QTRY_COMPARE(model->rowCount(), 2);
-
- model->setProperty("xml","");
-
- QSignalSpy spyInsert(model, SIGNAL(rowsInserted(QModelIndex,int,int)));
- QSignalSpy spyRemove(model, SIGNAL(rowsRemoved(QModelIndex,int,int)));
- QSignalSpy spyCount(model, SIGNAL(countChanged()));
-
- QVERIFY(QMetaObject::invokeMethod(model, "disableNameKey"));
- model->setProperty("xml",xml);
-
- QTRY_VERIFY(spyInsert.count() > 0 && spyRemove.count() > 0);
-
- QCOMPARE(spyInsert.count(), 1);
- QCOMPARE(spyInsert[0][1].toInt(), 0);
- QCOMPARE(spyInsert[0][2].toInt(), 1);
-
- QCOMPARE(spyRemove.count(), 1);
- QCOMPARE(spyRemove[0][1].toInt(), 0);
- QCOMPARE(spyRemove[0][2].toInt(), 1);
-
- QCOMPARE(spyCount.count(), 0);
-
- delete model;
-}
-
-void tst_qquickxmllistmodel::threading()
-{
- QFETCH(int, xmlDataCount);
-
- QQmlComponent component(&engine, testFileUrl("roleKeys.qml"));
-
- QAbstractItemModel *m1 = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(m1 != 0);
- QAbstractItemModel *m2 = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(m2 != 0);
- QAbstractItemModel *m3 = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(m3 != 0);
-
- for (int dataCount=0; dataCount<xmlDataCount; dataCount++) {
-
- QString data1, data2, data3;
- for (int i=0; i<dataCount; i++) {
- data1 += "name=A" + QString::number(i) + ",age=1" + QString::number(i) + ",sport=Football;";
- data2 += "name=B" + QString::number(i) + ",age=2" + QString::number(i) + ",sport=Athletics;";
- data3 += "name=C" + QString::number(i) + ",age=3" + QString::number(i) + ",sport=Curling;";
- }
-
- //Set the xml data multiple times with randomized order and mixed with multiple event loops
- //to test the xml query reloading/aborting, the result should be stable.
- m1->setProperty("xml",makeItemXmlAndData(data1));
- m2->setProperty("xml",makeItemXmlAndData(data2));
- m3->setProperty("xml",makeItemXmlAndData(data3));
- QCoreApplication::processEvents();
- m2->setProperty("xml",makeItemXmlAndData(data2));
- m1->setProperty("xml",makeItemXmlAndData(data1));
- m2->setProperty("xml",makeItemXmlAndData(data2));
- QCoreApplication::processEvents();
- m3->setProperty("xml",makeItemXmlAndData(data3));
- QCoreApplication::processEvents();
- m2->setProperty("xml",makeItemXmlAndData(data2));
- m1->setProperty("xml",makeItemXmlAndData(data1));
- m2->setProperty("xml",makeItemXmlAndData(data2));
- m3->setProperty("xml",makeItemXmlAndData(data3));
- QCoreApplication::processEvents();
- m2->setProperty("xml",makeItemXmlAndData(data2));
- m3->setProperty("xml",makeItemXmlAndData(data3));
- m3->setProperty("xml",makeItemXmlAndData(data3));
- QCoreApplication::processEvents();
-
- QTRY_VERIFY(m1->rowCount() == dataCount && m2->rowCount() == dataCount && m3->rowCount() == dataCount);
-
- for (int i=0; i<dataCount; i++) {
- QModelIndex index = m1->index(i, 0);
- QList<int> roles = m1->roleNames().keys();
- std::sort(roles.begin(), roles.end());
- QCOMPARE(m1->data(index, roles.at(0)).toString(), QLatin1Char('A') + QString::number(i));
- QCOMPARE(m1->data(index, roles.at(1)).toString(), QLatin1Char('1') + QString::number(i));
- QCOMPARE(m1->data(index, roles.at(2)).toString(), QString("Football"));
-
- index = m2->index(i, 0);
- roles = m2->roleNames().keys();
- std::sort(roles.begin(), roles.end());
- QCOMPARE(m2->data(index, roles.at(0)).toString(), QLatin1Char('B') + QString::number(i));
- QCOMPARE(m2->data(index, roles.at(1)).toString(), QLatin1Char('2') + QString::number(i));
- QCOMPARE(m2->data(index, roles.at(2)).toString(), QString("Athletics"));
-
- index = m3->index(i, 0);
- roles = m3->roleNames().keys();
- std::sort(roles.begin(), roles.end());
- QCOMPARE(m3->data(index, roles.at(0)).toString(), QLatin1Char('C') + QString::number(i));
- QCOMPARE(m3->data(index, roles.at(1)).toString(), QLatin1Char('3') + QString::number(i));
- QCOMPARE(m3->data(index, roles.at(2)).toString(), QString("Curling"));
- }
- }
-
- delete m1;
- delete m2;
- delete m3;
-}
-
-void tst_qquickxmllistmodel::threading_data()
-{
- QTest::addColumn<int>("xmlDataCount");
-
- QTest::newRow("1") << 1;
- QTest::newRow("2") << 2;
- QTest::newRow("10") << 10;
-}
-
-void tst_qquickxmllistmodel::propertyChanges()
-{
- QQmlComponent component(&engine, testFileUrl("propertychanges.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel*>(component.create());
- QVERIFY(model != 0);
- QTRY_COMPARE(model->rowCount(), 9);
-
- QObject *role = model->findChild<QObject*>("role");
- QVERIFY(role);
-
- QSignalSpy nameSpy(role, SIGNAL(nameChanged()));
- QSignalSpy querySpy(role, SIGNAL(queryChanged()));
- QSignalSpy isKeySpy(role, SIGNAL(isKeyChanged()));
-
- role->setProperty("name","size");
- role->setProperty("query","size/string()");
- role->setProperty("isKey",true);
-
- QCOMPARE(role->property("name").toString(), QString("size"));
- QCOMPARE(role->property("query").toString(), QString("size/string()"));
- QVERIFY(role->property("isKey").toBool());
-
- QCOMPARE(nameSpy.count(),1);
- QCOMPARE(querySpy.count(),1);
- QCOMPARE(isKeySpy.count(),1);
-
- role->setProperty("name","size");
- role->setProperty("query","size/string()");
- role->setProperty("isKey",true);
-
- QCOMPARE(nameSpy.count(),1);
- QCOMPARE(querySpy.count(),1);
- QCOMPARE(isKeySpy.count(),1);
-
- QSignalSpy sourceSpy(model, SIGNAL(sourceChanged()));
- QSignalSpy xmlSpy(model, SIGNAL(xmlChanged()));
- QSignalSpy modelQuerySpy(model, SIGNAL(queryChanged()));
- QSignalSpy namespaceDeclarationsSpy(model, SIGNAL(namespaceDeclarationsChanged()));
-
- model->setProperty("source",QUrl(""));
- model->setProperty("xml","<Pets><Pet><name>Polly</name><type>Parrot</type><age>12</age><size>Small</size></Pet></Pets>");
- model->setProperty("query","/Pets");
- model->setProperty("namespaceDeclarations","declare namespace media=\"http://search.yahoo.com/mrss/\";");
-
- QCOMPARE(model->property("source").toUrl(), QUrl(""));
- QCOMPARE(model->property("xml").toString(), QString("<Pets><Pet><name>Polly</name><type>Parrot</type><age>12</age><size>Small</size></Pet></Pets>"));
- QCOMPARE(model->property("query").toString(), QString("/Pets"));
- QCOMPARE(model->property("namespaceDeclarations").toString(), QString("declare namespace media=\"http://search.yahoo.com/mrss/\";"));
-
- QTRY_COMPARE(model->rowCount(), 1);
-
- QCOMPARE(sourceSpy.count(),1);
- QCOMPARE(xmlSpy.count(),1);
- QCOMPARE(modelQuerySpy.count(),1);
- QCOMPARE(namespaceDeclarationsSpy.count(),1);
-
- model->setProperty("source",QUrl(""));
- model->setProperty("xml","<Pets><Pet><name>Polly</name><type>Parrot</type><age>12</age><size>Small</size></Pet></Pets>");
- model->setProperty("query","/Pets");
- model->setProperty("namespaceDeclarations","declare namespace media=\"http://search.yahoo.com/mrss/\";");
-
- QCOMPARE(sourceSpy.count(),1);
- QCOMPARE(xmlSpy.count(),1);
- QCOMPARE(modelQuerySpy.count(),1);
- QCOMPARE(namespaceDeclarationsSpy.count(),1);
-
- QTRY_COMPARE(model->rowCount(), 1);
- delete model;
-}
-
-void tst_qquickxmllistmodel::selectAncestor()
-{
- QQmlComponent component(&engine, testFileUrl("groups.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
- QTRY_COMPARE(model->rowCount(), 1);
-
- QModelIndex index = model->index(0, 0);
- QCOMPARE(model->data(index, Qt::UserRole).toInt(), 12);
- QCOMPARE(model->data(index, Qt::UserRole+1).toString(), QLatin1String("cats"));
-}
-
-void tst_qquickxmllistmodel::roleCrash()
-{
- // don't crash
- QQmlComponent component(&engine, testFileUrl("roleCrash.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
- delete model;
-}
-
-class SortFilterProxyModel : public QSortFilterProxyModel
-{
- Q_OBJECT
- Q_PROPERTY(QObject *source READ source WRITE setSource)
-
-public:
- SortFilterProxyModel(QObject *parent = 0) : QSortFilterProxyModel(parent) { sort(0); }
- QObject *source() const { return sourceModel(); }
- void setSource(QObject *source) { setSourceModel(qobject_cast<QAbstractItemModel *>(source)); }
-};
-
-void tst_qquickxmllistmodel::proxyCrash()
-{
- qmlRegisterType<SortFilterProxyModel>("SortFilterProxyModel", 1, 0, "SortFilterProxyModel");
-
- // don't crash
- QQmlComponent component(&engine, testFileUrl("proxyCrash.qml"));
- QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(component.create());
- QVERIFY(model != 0);
- delete model;
-}
-
-QTEST_MAIN(tst_qquickxmllistmodel)
-
-#include "tst_qquickxmllistmodel.moc"
diff --git a/tests/auto/quick/quick.pro b/tests/auto/quick/quick.pro
index 6fc3bb5b1b..7257a99d2a 100644
--- a/tests/auto/quick/quick.pro
+++ b/tests/auto/quick/quick.pro
@@ -41,11 +41,7 @@ PRIVATETESTS += \
qquickstyledtext \
qquickstates \
qquicksystempalette \
- qquicktimeline \
- qquickxmllistmodel
-
-# This test requires the xmlpatterns module
-!qtHaveModule(xmlpatterns): PRIVATETESTS -= qquickxmllistmodel
+ qquicktimeline
QUICKTESTS += \
pointerhandlers \