summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--demos/declarative/calculator/calculator.qml22
-rw-r--r--demos/declarative/flickr/flickr.qml2
-rw-r--r--demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml6
-rw-r--r--demos/declarative/webbrowser/content/FlickableWebView.qml2
-rw-r--r--examples/declarative/touchinteraction/pincharea/flickresize.qml50
-rw-r--r--examples/declarative/touchinteraction/pincharea/qt-logo.jpgbin0 -> 40886 bytes
-rw-r--r--src/declarative/debugger/debugger.pri9
-rw-r--r--src/declarative/debugger/qdeclarativedebugclient.cpp36
-rw-r--r--src/declarative/debugger/qdeclarativedebugserver.cpp361
-rw-r--r--src/declarative/debugger/qdeclarativedebugserver_p.h88
-rw-r--r--src/declarative/debugger/qdeclarativedebugserverconnection_p.h73
-rw-r--r--src/declarative/debugger/qdeclarativedebugserverplugin_p.h0
-rw-r--r--src/declarative/debugger/qdeclarativedebugservice.cpp319
-rw-r--r--src/declarative/debugger/qdeclarativedebugservice_p_p.h71
-rw-r--r--src/declarative/debugger/qdeclarativedebugtrace.cpp106
-rw-r--r--src/declarative/debugger/qdeclarativedebugtrace_p.h43
-rw-r--r--src/declarative/debugger/qpacketprotocol.cpp8
-rw-r--r--src/declarative/debugger/qpacketprotocol_p.h5
-rw-r--r--src/declarative/graphicsitems/graphicsitems.pri7
-rw-r--r--src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp12
-rw-r--r--src/declarative/graphicsitems/qdeclarativeborderimage.cpp47
-rw-r--r--src/declarative/graphicsitems/qdeclarativeborderimage_p.h4
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable.cpp54
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable_p.h4
-rw-r--r--src/declarative/graphicsitems/qdeclarativeimage.cpp112
-rw-r--r--src/declarative/graphicsitems/qdeclarativeimagebase.cpp45
-rw-r--r--src/declarative/graphicsitems/qdeclarativeimagebase_p.h10
-rw-r--r--src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h6
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitem.cpp46
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitem_p.h1
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp4
-rw-r--r--src/declarative/graphicsitems/qdeclarativepincharea.cpp579
-rw-r--r--src/declarative/graphicsitems/qdeclarativepincharea_p.h308
-rw-r--r--src/declarative/graphicsitems/qdeclarativepincharea_p_p.h109
-rw-r--r--src/declarative/graphicsitems/qdeclarativetext.cpp11
-rw-r--r--src/declarative/graphicsitems/qdeclarativetext_p.h3
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextedit.cpp1
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextedit_p.h3
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput.cpp8
-rw-r--r--src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp5
-rw-r--r--src/declarative/qml/qdeclarativebinding.cpp30
-rw-r--r--src/declarative/qml/qdeclarativebinding_p.h3
-rw-r--r--src/declarative/qml/qdeclarativeboundsignal.cpp4
-rw-r--r--src/declarative/qml/qdeclarativecompiledbindings.cpp3
-rw-r--r--src/declarative/qml/qdeclarativecompiler.cpp70
-rw-r--r--src/declarative/qml/qdeclarativecompiler_p.h1
-rw-r--r--src/declarative/qml/qdeclarativecomponent.cpp4
-rw-r--r--src/declarative/qml/qdeclarativecontext_p.h1
-rw-r--r--src/declarative/qml/qdeclarativecustomparser.cpp9
-rw-r--r--src/declarative/qml/qdeclarativecustomparser_p.h3
-rw-r--r--src/declarative/qml/qdeclarativeengine.cpp5
-rw-r--r--src/declarative/qml/qdeclarativeenginedebug.cpp152
-rw-r--r--src/declarative/qml/qdeclarativeenginedebug_p.h6
-rw-r--r--src/declarative/qml/qdeclarativerewrite.cpp62
-rw-r--r--src/declarative/qml/qdeclarativerewrite_p.h4
-rw-r--r--src/declarative/qml/qdeclarativestringconverters.cpp6
-rw-r--r--src/declarative/qml/qdeclarativetypeloader.cpp4
-rw-r--r--src/declarative/qml/qdeclarativetypenamescriptclass.cpp5
-rw-r--r--src/declarative/qml/qml.pri9
-rw-r--r--src/declarative/qml/qperformancetimer.cpp226
-rw-r--r--src/declarative/qml/qperformancetimer_p.h79
-rw-r--r--src/declarative/util/qdeclarativelistmodel.cpp2
-rw-r--r--src/declarative/util/qdeclarativepixmapcache.cpp22
-rw-r--r--src/declarative/util/qdeclarativepixmapcache_p.h12
-rw-r--r--src/declarative/util/qdeclarativepropertychanges.cpp26
-rw-r--r--src/declarative/util/qdeclarativestate.cpp2
-rw-r--r--src/declarative/util/qdeclarativestateoperations.cpp116
-rw-r--r--src/declarative/util/qdeclarativeview.cpp24
-rw-r--r--src/plugins/plugins.pro3
-rw-r--r--src/plugins/qmldebugging/qmldebugging.pro4
-rw-r--r--src/plugins/qmldebugging/tcpserver/qtcpserverconnection.cpp173
-rw-r--r--src/plugins/qmldebugging/tcpserver/qtcpserverconnection.h84
-rw-r--r--src/plugins/qmldebugging/tcpserver/tcpserver.pro18
-rw-r--r--src/script/bridge/qscriptdeclarativeclass.cpp8
-rw-r--r--src/script/bridge/qscriptdeclarativeclass_p.h1
-rw-r--r--tests/auto/declarative/qdeclarativeanimatedimage/data/hearts.gifbin0 -> 6524 bytes
-rw-r--r--tests/auto/declarative/qdeclarativeanimatedimage/data/hearts.qml6
-rw-r--r--tests/auto/declarative/qdeclarativeanimatedimage/tst_qdeclarativeanimatedimage.cpp103
-rw-r--r--tests/auto/declarative/qdeclarativeborderimage/data/heart200.pngbin0 -> 7943 bytes
-rw-r--r--tests/auto/declarative/qdeclarativeborderimage/tst_qdeclarativeborderimage.cpp38
-rw-r--r--tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp198
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/data/nonExistentAttachedObject.qml (renamed from tests/auto/declarative/qdeclarativeecmascript/data/nonExistantAttachedObject.qml)0
-rw-r--r--tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp8
-rw-r--r--tests/auto/declarative/qdeclarativeflickable/data/resize.qml27
-rw-r--r--tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp54
-rw-r--r--tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp115
-rw-r--r--tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp2
-rw-r--r--tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp79
-rw-r--r--tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp6
-rw-r--r--tests/auto/declarative/qdeclarativelistmodel/data/setmodelcachelist.qml20
-rw-r--r--tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp12
-rw-r--r--tests/auto/declarative/qdeclarativepincharea/data/pinchproperties.qml46
-rw-r--r--tests/auto/declarative/qdeclarativepincharea/qdeclarativepincharea.pro16
-rw-r--r--tests/auto/declarative/qdeclarativepincharea/tst_qdeclarativepincharea.cpp315
-rw-r--r--tests/auto/declarative/qdeclarativeview/tst_qdeclarativeview.cpp21
-rw-r--r--tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-MAC/justify.0.pngbin0 -> 7233 bytes
-rw-r--r--tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-MAC/justify.qml11
-rw-r--r--tests/auto/declarative/qmlvisual/qdeclarativetext/align/justify.qml22
-rw-r--r--tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-MAC/justify.0.pngbin0 -> 7233 bytes
-rw-r--r--tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-MAC/justify.qml11
-rw-r--r--tests/auto/declarative/qmlvisual/qdeclarativetextedit/justify.qml22
-rw-r--r--tests/auto/declarative/qperformancetimer/qperformancetimer.pro7
-rw-r--r--tests/auto/declarative/qperformancetimer/tst_qperformancetimer.cpp68
-rw-r--r--tests/benchmarks/declarative/qperformancetimer/qperformancetimer.pro8
-rw-r--r--tests/benchmarks/declarative/qperformancetimer/tst_qperformancetimer.cpp100
-rw-r--r--tools/qml/qml.pro5
106 files changed, 4474 insertions, 607 deletions
diff --git a/demos/declarative/calculator/calculator.qml b/demos/declarative/calculator/calculator.qml
index 3e1c650..b3e4f2f 100644
--- a/demos/declarative/calculator/calculator.qml
+++ b/demos/declarative/calculator/calculator.qml
@@ -46,7 +46,7 @@ import "Core/calculator.js" as CalcEngine
Rectangle {
id: window
- width: 480; height: 360
+ width: 360; height: 480
color: "#282828"
property string rotateLeft: "\u2939"
@@ -63,7 +63,15 @@ Rectangle {
id: main
state: "orientation " + runtime.orientation
- width: parent.width; height: parent.height; anchors.centerIn: parent
+ property bool landscapeWindow: window.width > window.height
+ property real baseWidth: landscapeWindow ? window.height : window.width
+ property real baseHeight: landscapeWindow ? window.width : window.height
+ property real rotationDelta: landscapeWindow ? -90 : 0
+
+ rotation: rotationDelta
+ width: main.baseWidth
+ height: main.baseHeight
+ anchors.centerIn: parent
Column {
id: box; spacing: 8
@@ -132,24 +140,20 @@ Rectangle {
states: [
State {
name: "orientation " + Orientation.Landscape
- PropertyChanges { target: main; rotation: 90; width: window.height; height: window.width }
- PropertyChanges { target: rotateButton; operation: rotateLeft }
+ PropertyChanges { target: main; rotation: 90 + rotationDelta; width: main.baseHeight; height: main.baseWidth }
},
State {
name: "orientation " + Orientation.PortraitInverted
- PropertyChanges { target: main; rotation: 180; }
- PropertyChanges { target: rotateButton; operation: rotateRight }
+ PropertyChanges { target: main; rotation: 180 + rotationDelta; }
},
State {
name: "orientation " + Orientation.LandscapeInverted
- PropertyChanges { target: main; rotation: 270; width: window.height; height: window.width }
- PropertyChanges { target: rotateButton; operation: rotateLeft }
+ PropertyChanges { target: main; rotation: 270 + rotationDelta; width: main.baseHeight; height: main.baseWidth }
}
]
transitions: Transition {
SequentialAnimation {
- PropertyAction { target: rotateButton; property: "operation" }
RotationAnimation { direction: RotationAnimation.Shortest; duration: 300; easing.type: Easing.InOutQuint }
NumberAnimation { properties: "x,y,width,height"; duration: 300; easing.type: Easing.InOutQuint }
}
diff --git a/demos/declarative/flickr/flickr.qml b/demos/declarative/flickr/flickr.qml
index 740ee35..9387948 100644
--- a/demos/declarative/flickr/flickr.qml
+++ b/demos/declarative/flickr/flickr.qml
@@ -62,7 +62,7 @@ Item {
GridView {
id: photoGridView; model: rssModel; delegate: Mobile.GridDelegate {}
- cacheBuffer: 100
+ cacheBuffer: 1000
cellWidth: (parent.width-2)/4; cellHeight: cellWidth; width: parent.width; height: parent.height
}
diff --git a/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml b/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml
index 5948b5d..6248745 100644
--- a/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml
+++ b/demos/declarative/photoviewer/PhotoViewerCore/PhotoDelegate.qml
@@ -61,7 +61,7 @@ Package {
BorderImage {
anchors {
- fill: border.visible ? border : placeHolder
+ fill: originalImage.status == Image.Ready ? border : placeHolder
leftMargin: -6; topMargin: -6; rightMargin: -8; bottomMargin: -8
}
source: 'images/box-shadow.png'; smooth: true
@@ -88,11 +88,11 @@ Package {
}
BusyIndicator { anchors.centerIn: parent; on: originalImage.status != Image.Ready }
Image {
- id: originalImage; smooth: true; source: "http://" + Script.getImagePath(content)
+ id: originalImage; smooth: true; source: "http://" + Script.getImagePath(content); cached: false
fillMode: Image.PreserveAspectFit; width: photoWrapper.width; height: photoWrapper.height
}
Image {
- id: hqImage; smooth: true; source: ""; visible: false
+ id: hqImage; smooth: true; source: ""; visible: false; cached: false
fillMode: Image.PreserveAspectFit; width: photoWrapper.width; height: photoWrapper.height
}
Binding {
diff --git a/demos/declarative/webbrowser/content/FlickableWebView.qml b/demos/declarative/webbrowser/content/FlickableWebView.qml
index 6f4e09c..a82a151 100644
--- a/demos/declarative/webbrowser/content/FlickableWebView.qml
+++ b/demos/declarative/webbrowser/content/FlickableWebView.qml
@@ -128,7 +128,7 @@ Flickable {
if (!heuristicZoom(clickX,clickY,2.5)) {
var zf = flickable.width / contentsSize.width
if (zf >= contentsScale)
- zf = 2.0/zoomFactor // zoom in (else zooming out)
+ zf = 2.0*contentsScale // zoom in (else zooming out)
doZoom(zf,clickX*zf,clickY*zf)
}
}
diff --git a/examples/declarative/touchinteraction/pincharea/flickresize.qml b/examples/declarative/touchinteraction/pincharea/flickresize.qml
new file mode 100644
index 0000000..8034e29
--- /dev/null
+++ b/examples/declarative/touchinteraction/pincharea/flickresize.qml
@@ -0,0 +1,50 @@
+import QtQuick 1.1
+
+Rectangle {
+ width: 640
+ height: 360
+ color: "gray"
+
+ Flickable {
+ id: flick
+ anchors.fill: parent
+ contentWidth: 500
+ contentHeight: 500
+
+ PinchArea {
+ width: Math.max(flick.contentWidth, flick.width)
+ height: Math.max(flick.contentHeight, flick.height)
+ onPinchChanged: {
+ // adjust content pos due to drag
+ flick.contentX += pinch.lastCenter.x - pinch.center.x
+ flick.contentY += pinch.lastCenter.y - pinch.center.y
+
+ // resize content
+ var scale = 1.0 + pinch.scale - pinch.lastScale
+ flick.resizeContent(flick.contentWidth * scale, flick.contentHeight * scale, pinch.center)
+ }
+
+ onPinchFinished: {
+ // Move its content within bounds.
+ flick.returnToBounds()
+ }
+
+ Rectangle {
+ width: flick.contentWidth
+ height: flick.contentHeight
+ color: "white"
+ Image {
+ anchors.fill: parent
+ source: "qt-logo.jpg"
+ MouseArea {
+ anchors.fill: parent
+ onDoubleClicked: {
+ flick.contentWidth = 500
+ flick.contentHeight = 500
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/examples/declarative/touchinteraction/pincharea/qt-logo.jpg b/examples/declarative/touchinteraction/pincharea/qt-logo.jpg
new file mode 100644
index 0000000..4014b46
--- /dev/null
+++ b/examples/declarative/touchinteraction/pincharea/qt-logo.jpg
Binary files differ
diff --git a/src/declarative/debugger/debugger.pri b/src/declarative/debugger/debugger.pri
index 25f7687..9152677 100644
--- a/src/declarative/debugger/debugger.pri
+++ b/src/declarative/debugger/debugger.pri
@@ -7,13 +7,18 @@ SOURCES += \
$$PWD/qdeclarativedebugclient.cpp \
$$PWD/qdeclarativedebug.cpp \
$$PWD/qdeclarativedebugtrace.cpp \
- $$PWD/qdeclarativedebughelper.cpp
+ $$PWD/qdeclarativedebughelper.cpp \
+ $$PWD/qdeclarativedebugserver.cpp
HEADERS += \
$$PWD/qdeclarativedebuggerstatus_p.h \
$$PWD/qpacketprotocol_p.h \
$$PWD/qdeclarativedebugservice_p.h \
+ $$PWD/qdeclarativedebugservice_p_p.h \
$$PWD/qdeclarativedebugclient_p.h \
$$PWD/qdeclarativedebug_p.h \
$$PWD/qdeclarativedebugtrace_p.h \
- $$PWD/qdeclarativedebughelper_p.h
+ $$PWD/qdeclarativedebughelper_p.h \
+ $$PWD/qdeclarativedebugserverplugin_p.h \
+ $$PWD/qdeclarativedebugserver_p.h \
+ debugger/qdeclarativedebugserverconnection_p.h
diff --git a/src/declarative/debugger/qdeclarativedebugclient.cpp b/src/declarative/debugger/qdeclarativedebugclient.cpp
index f5c5751..204ca4f 100644
--- a/src/declarative/debugger/qdeclarativedebugclient.cpp
+++ b/src/declarative/debugger/qdeclarativedebugclient.cpp
@@ -61,7 +61,7 @@ public:
QDeclarativeDebugClientPrivate();
QString name;
- QDeclarativeDebugConnection *client;
+ QDeclarativeDebugConnection *connection;
};
class QDeclarativeDebugConnectionPrivate : public QObject
@@ -202,7 +202,7 @@ QDeclarativeDebugConnection::~QDeclarativeDebugConnection()
{
QHash<QString, QDeclarativeDebugClient*>::iterator iter = d->plugins.begin();
for (; iter != d->plugins.end(); ++iter) {
- iter.value()->d_func()->client = 0;
+ iter.value()->d_func()->connection = 0;
iter.value()->statusChanged(QDeclarativeDebugClient::NotConnected);
}
}
@@ -213,7 +213,7 @@ bool QDeclarativeDebugConnection::isConnected() const
}
QDeclarativeDebugClientPrivate::QDeclarativeDebugClientPrivate()
-: client(0)
+: connection(0)
{
}
@@ -223,26 +223,26 @@ QDeclarativeDebugClient::QDeclarativeDebugClient(const QString &name,
{
Q_D(QDeclarativeDebugClient);
d->name = name;
- d->client = parent;
+ d->connection = parent;
- if (!d->client)
+ if (!d->connection)
return;
- if (d->client->d->plugins.contains(name)) {
+ if (d->connection->d->plugins.contains(name)) {
qWarning() << "QDeclarativeDebugClient: Conflicting plugin name" << name;
- d->client = 0;
+ d->connection = 0;
} else {
- d->client->d->plugins.insert(name, this);
- d->client->d->advertisePlugins();
+ d->connection->d->plugins.insert(name, this);
+ d->connection->d->advertisePlugins();
}
}
QDeclarativeDebugClient::~QDeclarativeDebugClient()
{
Q_D(const QDeclarativeDebugClient);
- if (d->client && d->client->d) {
- d->client->d->plugins.remove(d->name);
- d->client->d->advertisePlugins();
+ if (d->connection && d->connection->d) {
+ d->connection->d->plugins.remove(d->name);
+ d->connection->d->advertisePlugins();
}
}
@@ -255,12 +255,12 @@ QString QDeclarativeDebugClient::name() const
QDeclarativeDebugClient::Status QDeclarativeDebugClient::status() const
{
Q_D(const QDeclarativeDebugClient);
- if (!d->client
- || !d->client->isConnected()
- || !d->client->d->gotHello)
+ if (!d->connection
+ || !d->connection->isConnected()
+ || !d->connection->d->gotHello)
return NotConnected;
- if (d->client->d->serverPlugins.contains(d->name))
+ if (d->connection->d->serverPlugins.contains(d->name))
return Enabled;
return Unavailable;
@@ -275,8 +275,8 @@ void QDeclarativeDebugClient::sendMessage(const QByteArray &message)
QPacket pack;
pack << d->name << message;
- d->client->d->protocol->send(pack);
- d->client->d->q->flush();
+ d->connection->d->protocol->send(pack);
+ d->connection->d->q->flush();
}
void QDeclarativeDebugClient::statusChanged(Status)
diff --git a/src/declarative/debugger/qdeclarativedebugserver.cpp b/src/declarative/debugger/qdeclarativedebugserver.cpp
new file mode 100644
index 0000000..a269984
--- /dev/null
+++ b/src/declarative/debugger/qdeclarativedebugserver.cpp
@@ -0,0 +1,361 @@
+/****************************************************************************
+**
+** 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 QtDeclarative module 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$
+**
+****************************************************************************/
+
+#include "private/qdeclarativedebugserver_p.h"
+#include "private/qdeclarativedebugservice_p.h"
+#include "private/qdeclarativedebugservice_p_p.h"
+#include "private/qdeclarativeengine_p.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QPluginLoader>
+#include <QtCore/QStringList>
+
+#include <private/qobject_p.h>
+#include <private/qapplication_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/*
+ QDeclarativeDebug Protocol (Version 1):
+
+ handshake:
+ 1. Client sends
+ "QDeclarativeDebugServer" 0 version pluginNames
+ version: an int representing the highest protocol version the client knows
+ pluginNames: plugins available on client side
+ 2. Server sends
+ "QDeclarativeDebugClient" 0 version pluginNames
+ version: an int representing the highest protocol version the client & server know
+ pluginNames: plugins available on server side. plugins both in the client and server message are enabled.
+ client plugin advertisement
+ 1. Client sends
+ "QDeclarativeDebugServer" 1 pluginNames
+ server plugin advertisement
+ 1. Server sends
+ "QDeclarativeDebugClient" 1 pluginNames
+ plugin communication:
+ Everything send with a header different to "QDeclarativeDebugServer" is sent to the appropriate plugin.
+ */
+
+const int protocolVersion = 1;
+
+
+class QDeclarativeDebugServerPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QDeclarativeDebugServer)
+public:
+ QDeclarativeDebugServerPrivate();
+
+ void advertisePlugins();
+
+ QDeclarativeDebugServerConnection *connection;
+ QHash<QString, QDeclarativeDebugService *> plugins;
+ QStringList clientPlugins;
+ bool gotHello;
+
+ static QDeclarativeDebugServerConnection *loadConnectionPlugin();
+};
+
+QDeclarativeDebugServerPrivate::QDeclarativeDebugServerPrivate() :
+ connection(0),
+ gotHello(false)
+{
+}
+
+void QDeclarativeDebugServerPrivate::advertisePlugins()
+{
+ if (!gotHello)
+ return;
+
+ QByteArray message;
+ {
+ QDataStream out(&message, QIODevice::WriteOnly);
+ out << QString(QLatin1String("QDeclarativeDebugClient")) << 1 << plugins.keys();
+ }
+ connection->send(message);
+}
+
+QDeclarativeDebugServerConnection *QDeclarativeDebugServerPrivate::loadConnectionPlugin()
+{
+ QStringList pluginCandidates;
+ const QStringList paths = QCoreApplication::libraryPaths();
+ foreach (const QString &libPath, paths) {
+ const QDir dir(libPath + QLatin1String("/qmldebugging"));
+ if (dir.exists()) {
+ QStringList plugins(dir.entryList(QDir::Files));
+ foreach (const QString &pluginPath, plugins) {
+ pluginCandidates << dir.absoluteFilePath(pluginPath);
+ }
+ }
+ }
+
+ foreach (const QString &pluginPath, pluginCandidates) {
+ QPluginLoader loader(pluginPath);
+ if (!loader.load()) {
+ continue;
+ }
+ QDeclarativeDebugServerConnection *connection = 0;
+ if (QObject *instance = loader.instance())
+ connection = qobject_cast<QDeclarativeDebugServerConnection*>(instance);
+
+ if (connection)
+ return connection;
+ loader.unload();
+ }
+ return 0;
+}
+
+bool QDeclarativeDebugServer::hasDebuggingClient() const
+{
+ Q_D(const QDeclarativeDebugServer);
+ return d->connection
+ && d->connection->isConnected()
+ && d->gotHello;
+}
+
+QDeclarativeDebugServer *QDeclarativeDebugServer::instance()
+{
+ static bool commandLineTested = false;
+ static QDeclarativeDebugServer *server = 0;
+
+ if (!commandLineTested) {
+ commandLineTested = true;
+
+#ifndef QDECLARATIVE_NO_DEBUG_PROTOCOL
+ QApplicationPrivate *appD = static_cast<QApplicationPrivate*>(QObjectPrivate::get(qApp));
+ // ### remove port definition when protocol is changed
+ int port = 0;
+ bool block = false;
+ bool ok = false;
+
+ // format: qmljsdebugger=port:3768[,block]
+ if (!appD->qmljsDebugArgumentsString().isEmpty()) {
+ if (!QDeclarativeEnginePrivate::qml_debugging_enabled) {
+ const QString message =
+ QString::fromAscii("QDeclarativeDebugServer: Ignoring \"-qmljsdebugger=%1\". "
+ "Debugging has not been enabled.").arg(
+ appD->qmljsDebugArgumentsString());
+ qWarning("%s", qPrintable(message));
+ return 0;
+ }
+
+ if (appD->qmljsDebugArgumentsString().indexOf(QLatin1String("port:")) == 0) {
+ int separatorIndex = appD->qmljsDebugArgumentsString().indexOf(QLatin1Char(','));
+ port = appD->qmljsDebugArgumentsString().mid(5, separatorIndex - 5).toInt(&ok);
+ }
+ block = appD->qmljsDebugArgumentsString().contains(QLatin1String("block"));
+
+ if (ok) {
+ server = new QDeclarativeDebugServer();
+
+ QDeclarativeDebugServerConnection *connection
+ = QDeclarativeDebugServerPrivate::loadConnectionPlugin();
+ if (connection) {
+ server->d_func()->connection = connection;
+
+ connection->setServer(server);
+ connection->setPort(port, block);
+ } else {
+ qWarning() << QString::fromAscii("QDeclarativeDebugServer: Ignoring\"-qmljsdebugger=%1\". "
+ "Remote debugger plugin has not been found.").arg(appD->qmljsDebugArgumentsString());
+ }
+
+ } else {
+ qWarning(QString::fromAscii("QDeclarativeDebugServer: Ignoring \"-qmljsdebugger=%1\". "
+ "Format is -qmljsdebugger=port:<port>[,block]").arg(
+ appD->qmljsDebugArgumentsString()).toAscii().constData());
+ }
+ }
+#endif
+ }
+
+ return server;
+}
+
+QDeclarativeDebugServer::QDeclarativeDebugServer()
+: QObject(*(new QDeclarativeDebugServerPrivate))
+{
+}
+
+void QDeclarativeDebugServer::receiveMessage(const QByteArray &message)
+{
+ Q_D(QDeclarativeDebugServer);
+
+ QDataStream in(message);
+ if (!d->gotHello) {
+
+ QString name;
+ int op;
+ in >> name >> op;
+
+ if (name != QLatin1String("QDeclarativeDebugServer")
+ || op != 0) {
+ qWarning("QDeclarativeDebugServer: Invalid hello message");
+ d->connection->disconnect();
+ return;
+ }
+
+ int version;
+ in >> version >> d->clientPlugins;
+
+ QHash<QString, QDeclarativeDebugService*>::Iterator iter = d->plugins.begin();
+ for (; iter != d->plugins.end(); ++iter) {
+ QDeclarativeDebugService::Status newStatus = QDeclarativeDebugService::Unavailable;
+ if (d->clientPlugins.contains(iter.key()))
+ newStatus = QDeclarativeDebugService::Enabled;
+ iter.value()->d_func()->status = newStatus;
+ iter.value()->statusChanged(newStatus);
+ }
+
+ QByteArray helloAnswer;
+ {
+ QDataStream out(&helloAnswer, QIODevice::WriteOnly);
+ out << QString(QLatin1String("QDeclarativeDebugClient")) << 0 << protocolVersion << d->plugins.keys();
+ }
+ d->connection->send(helloAnswer);
+
+ d->gotHello = true;
+ qWarning("QDeclarativeDebugServer: Connection established");
+ } else {
+
+ QString debugServer(QLatin1String("QDeclarativeDebugServer"));
+
+ QString name;
+ in >> name;
+
+ if (name == debugServer) {
+ int op = -1;
+ in >> op;
+
+ if (op == 1) {
+ // Service Discovery
+ QStringList oldClientPlugins = d->clientPlugins;
+ in >> d->clientPlugins;
+
+ QHash<QString, QDeclarativeDebugService*>::Iterator iter = d->plugins.begin();
+ for (; iter != d->plugins.end(); ++iter) {
+ const QString pluginName = iter.key();
+ QDeclarativeDebugService::Status newStatus = QDeclarativeDebugService::Unavailable;
+ if (d->clientPlugins.contains(pluginName))
+ newStatus = QDeclarativeDebugService::Enabled;
+
+ if (oldClientPlugins.contains(pluginName)
+ != d->clientPlugins.contains(pluginName)) {
+ iter.value()->d_func()->status = newStatus;
+ iter.value()->statusChanged(newStatus);
+ }
+ }
+ } else {
+ qWarning("QDeclarativeDebugServer: Invalid control message %d", op);
+ }
+ } else {
+ QByteArray message;
+ in >> message;
+
+ QHash<QString, QDeclarativeDebugService *>::Iterator iter =
+ d->plugins.find(name);
+ if (iter == d->plugins.end()) {
+ qWarning() << "QDeclarativeDebugServer: Message received for missing plugin" << name;
+ } else {
+ (*iter)->messageReceived(message);
+ }
+ }
+ }
+}
+
+QList<QDeclarativeDebugService*> QDeclarativeDebugServer::services() const
+{
+ const Q_D(QDeclarativeDebugServer);
+ return d->plugins.values();
+}
+
+QStringList QDeclarativeDebugServer::serviceNames() const
+{
+ const Q_D(QDeclarativeDebugServer);
+ return d->plugins.keys();
+}
+
+bool QDeclarativeDebugServer::addService(QDeclarativeDebugService *service)
+{
+ Q_D(QDeclarativeDebugServer);
+ if (!service || d->plugins.contains(service->name()))
+ return false;
+
+ d->plugins.insert(service->name(), service);
+ d->advertisePlugins();
+
+ QDeclarativeDebugService::Status newStatus = QDeclarativeDebugService::Unavailable;
+ if (d->clientPlugins.contains(service->name()))
+ newStatus = QDeclarativeDebugService::Enabled;
+ service->d_func()->status = newStatus;
+ service->statusChanged(newStatus);
+ return true;
+}
+
+bool QDeclarativeDebugServer::removeService(QDeclarativeDebugService *service)
+{
+ Q_D(QDeclarativeDebugServer);
+ if (!service || !d->plugins.contains(service->name()))
+ return false;
+
+ d->plugins.remove(service->name());
+ d->advertisePlugins();
+
+ QDeclarativeDebugService::Status newStatus = QDeclarativeDebugService::NotConnected;
+ service->d_func()->server = 0;
+ service->d_func()->status = newStatus;
+ service->statusChanged(newStatus);
+ return true;
+}
+
+void QDeclarativeDebugServer::sendMessage(QDeclarativeDebugService *service,
+ const QByteArray &message)
+{
+ Q_D(QDeclarativeDebugServer);
+ QByteArray msg;
+ {
+ QDataStream out(&msg, QIODevice::WriteOnly);
+ out << service->name() << message;
+ }
+ d->connection->send(msg);
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/debugger/qdeclarativedebugserver_p.h b/src/declarative/debugger/qdeclarativedebugserver_p.h
new file mode 100644
index 0000000..ec3e60f
--- /dev/null
+++ b/src/declarative/debugger/qdeclarativedebugserver_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** 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 QtDeclarative module 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$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEDEBUGSERVER_H
+#define QDECLARATIVEDEBUGSERVER_H
+
+#include <private/qdeclarativeglobal_p.h>
+#include <private/qdeclarativedebugserverconnection_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeDebugService;
+
+class QDeclarativeDebugServerPrivate;
+class Q_DECLARATIVE_EXPORT QDeclarativeDebugServer : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QDeclarativeDebugServer)
+ Q_DISABLE_COPY(QDeclarativeDebugServer)
+public:
+ static QDeclarativeDebugServer *instance();
+
+ void setConnection(QDeclarativeDebugServerConnection *connection);
+
+ bool hasDebuggingClient() const;
+
+ QList<QDeclarativeDebugService*> services() const;
+ QStringList serviceNames() const;
+
+ bool addService(QDeclarativeDebugService *service);
+ bool removeService(QDeclarativeDebugService *service);
+
+ void sendMessage(QDeclarativeDebugService *service, const QByteArray &message);
+ void receiveMessage(const QByteArray &message);
+
+private:
+ friend class QDeclarativeDebugService;
+ friend class QDeclarativeDebugServicePrivate;
+ QDeclarativeDebugServer();
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDECLARATIVEDEBUGSERVICE_H
diff --git a/src/declarative/debugger/qdeclarativedebugserverconnection_p.h b/src/declarative/debugger/qdeclarativedebugserverconnection_p.h
new file mode 100644
index 0000000..631da74
--- /dev/null
+++ b/src/declarative/debugger/qdeclarativedebugserverconnection_p.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** 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 QtDeclarative module 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$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEDEBUGSERVERCONNECTION_H
+#define QDECLARATIVEDEBUGSERVERCONNECTION_H
+
+#include <QtDeclarative/private/qdeclarativeglobal_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeDebugServer;
+class Q_DECLARATIVE_EXPORT QDeclarativeDebugServerConnection
+{
+public:
+ QDeclarativeDebugServerConnection() {}
+ virtual ~QDeclarativeDebugServerConnection() {}
+
+ virtual void setServer(QDeclarativeDebugServer *server) = 0;
+ virtual void setPort(int port, bool bock) = 0;
+ virtual bool isConnected() const = 0;
+ virtual void send(const QByteArray &message) = 0;
+ virtual void disconnect() = 0;
+};
+
+Q_DECLARE_INTERFACE(QDeclarativeDebugServerConnection, "com.trolltech.Qt.QDeclarativeDebugServerConnection/1.0")
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDECLARATIVEDEBUGSERVERCONNECTION_H
diff --git a/src/declarative/debugger/qdeclarativedebugserverplugin_p.h b/src/declarative/debugger/qdeclarativedebugserverplugin_p.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/declarative/debugger/qdeclarativedebugserverplugin_p.h
diff --git a/src/declarative/debugger/qdeclarativedebugservice.cpp b/src/declarative/debugger/qdeclarativedebugservice.cpp
index 849df73..9d321da 100644
--- a/src/declarative/debugger/qdeclarativedebugservice.cpp
+++ b/src/declarative/debugger/qdeclarativedebugservice.cpp
@@ -40,301 +40,14 @@
****************************************************************************/
#include "private/qdeclarativedebugservice_p.h"
+#include "private/qdeclarativedebugservice_p_p.h"
+#include "private/qdeclarativedebugserver_p.h"
-#include "private/qpacketprotocol_p.h"
-#include "private/qdeclarativeengine_p.h"
-
-#include <QtCore/qdebug.h>
-#include <QtNetwork/qtcpserver.h>
-#include <QtNetwork/qtcpsocket.h>
-#include <QtCore/qstringlist.h>
-
-#include <private/qobject_p.h>
-#include <private/qapplication_p.h>
-#include <QtGui/qapplication.h>
+#include <QtCore/QDebug>
+#include <QtCore/QStringList>
QT_BEGIN_NAMESPACE
-/*
- QDeclarativeDebug Protocol (Version 1):
-
- handshake:
- 1. Client sends
- "QDeclarativeDebugServer" 0 version pluginNames
- version: an int representing the highest protocol version the client knows
- pluginNames: plugins available on client side
- 2. Server sends
- "QDeclarativeDebugClient" 0 version pluginNames
- version: an int representing the highest protocol version the client & server know
- pluginNames: plugins available on server side. plugins both in the client and server message are enabled.
- client plugin advertisement
- 1. Client sends
- "QDeclarativeDebugServer" 1 pluginNames
- server plugin advertisement
- 1. Server sends
- "QDeclarativeDebugClient" 1 pluginNames
- plugin communication:
- Everything send with a header different to "QDeclarativeDebugServer" is sent to the appropriate plugin.
- */
-
-const int protocolVersion = 1;
-
-class QDeclarativeDebugServerPrivate;
-class QDeclarativeDebugServer : public QObject
-{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QDeclarativeDebugServer)
- Q_DISABLE_COPY(QDeclarativeDebugServer)
-public:
- static QDeclarativeDebugServer *instance();
- void listen();
- void waitForConnection();
- bool hasDebuggingClient() const;
-
-private Q_SLOTS:
- void readyRead();
- void newConnection();
-
-private:
- friend class QDeclarativeDebugService;
- friend class QDeclarativeDebugServicePrivate;
- QDeclarativeDebugServer(int);
-};
-
-class QDeclarativeDebugServerPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QDeclarativeDebugServer)
-public:
- QDeclarativeDebugServerPrivate();
-
- void advertisePlugins();
-
- int port;
- QTcpSocket *connection;
- QPacketProtocol *protocol;
- QHash<QString, QDeclarativeDebugService *> plugins;
- QStringList clientPlugins;
- QTcpServer *tcpServer;
- bool gotHello;
-};
-
-class QDeclarativeDebugServicePrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QDeclarativeDebugService)
-public:
- QDeclarativeDebugServicePrivate();
-
- QString name;
- QDeclarativeDebugServer *server;
-};
-
-QDeclarativeDebugServerPrivate::QDeclarativeDebugServerPrivate()
-: connection(0), protocol(0), gotHello(false)
-{
-}
-
-void QDeclarativeDebugServerPrivate::advertisePlugins()
-{
- if (!connection
- || connection->state() != QTcpSocket::ConnectedState
- || !gotHello)
- return;
-
- QPacket pack;
- pack << QString(QLatin1String("QDeclarativeDebugClient")) << 1 << plugins.keys();
- protocol->send(pack);
- connection->flush();
-}
-
-void QDeclarativeDebugServer::listen()
-{
- Q_D(QDeclarativeDebugServer);
-
- d->tcpServer = new QTcpServer(this);
- QObject::connect(d->tcpServer, SIGNAL(newConnection()), this, SLOT(newConnection()));
- if (d->tcpServer->listen(QHostAddress::Any, d->port))
- qWarning("QDeclarativeDebugServer: Waiting for connection on port %d...", d->port);
- else
- qWarning("QDeclarativeDebugServer: Unable to listen on port %d", d->port);
-}
-
-void QDeclarativeDebugServer::waitForConnection()
-{
- Q_D(QDeclarativeDebugServer);
- d->tcpServer->waitForNewConnection(-1);
-}
-
-void QDeclarativeDebugServer::newConnection()
-{
- Q_D(QDeclarativeDebugServer);
-
- if (d->connection) {
- qWarning("QDeclarativeDebugServer error: another client is already connected");
- QTcpSocket *faultyConnection = d->tcpServer->nextPendingConnection();
- delete faultyConnection;
- return;
- }
-
- d->connection = d->tcpServer->nextPendingConnection();
- d->connection->setParent(this);
- d->protocol = new QPacketProtocol(d->connection, this);
- QObject::connect(d->protocol, SIGNAL(readyRead()), this, SLOT(readyRead()));
-}
-
-bool QDeclarativeDebugServer::hasDebuggingClient() const
-{
- Q_D(const QDeclarativeDebugServer);
- return d->connection
- && (d->connection->state() == QTcpSocket::ConnectedState)
- && d->gotHello;
-}
-
-QDeclarativeDebugServer *QDeclarativeDebugServer::instance()
-{
- static bool commandLineTested = false;
- static QDeclarativeDebugServer *server = 0;
-
- if (!commandLineTested) {
- commandLineTested = true;
-
-#ifndef QDECLARATIVE_NO_DEBUG_PROTOCOL
- QApplicationPrivate *appD = static_cast<QApplicationPrivate*>(QObjectPrivate::get(qApp));
- // ### remove port definition when protocol is changed
- int port = 0;
- bool block = false;
- bool ok = false;
-
- // format: qmljsdebugger=port:3768[,block]
- if (!appD->qmljsDebugArgumentsString().isEmpty()) {
- if (!QDeclarativeEnginePrivate::qml_debugging_enabled) {
- qWarning() << QString::fromLatin1("QDeclarativeDebugServer: Ignoring \"-qmljsdebugger=%1\". "
- "Debugging has not been enabled.").arg(
- appD->qmljsDebugArgumentsString()).toAscii().constData();
- return 0;
- }
-
- if (appD->qmljsDebugArgumentsString().indexOf(QLatin1String("port:")) == 0) {
- int separatorIndex = appD->qmljsDebugArgumentsString().indexOf(QLatin1Char(','));
- port = appD->qmljsDebugArgumentsString().mid(5, separatorIndex - 5).toInt(&ok);
- }
- block = appD->qmljsDebugArgumentsString().contains(QLatin1String("block"));
-
- if (ok) {
- server = new QDeclarativeDebugServer(port);
- server->listen();
- if (block) {
- server->waitForConnection();
- }
- } else {
- const QString message =
- QString::fromAscii("QDeclarativeDebugServer: Ignoring \"-qmljsdebugger=%1\". "
- "Format is -qmljsdebugger=port:<port>[,block]").
- arg(appD->qmljsDebugArgumentsString());
- qWarning("%s", qPrintable(message));
- }
- }
-#endif
- }
-
- return server;
-}
-
-QDeclarativeDebugServer::QDeclarativeDebugServer(int port)
-: QObject(*(new QDeclarativeDebugServerPrivate))
-{
- Q_D(QDeclarativeDebugServer);
- d->port = port;
-}
-
-void QDeclarativeDebugServer::readyRead()
-{
- Q_D(QDeclarativeDebugServer);
-
- if (!d->gotHello) {
- QPacket hello = d->protocol->read();
-
- QString name;
- int op;
- hello >> name >> op;
-
- if (name != QLatin1String("QDeclarativeDebugServer")
- || op != 0) {
- qWarning("QDeclarativeDebugServer: Invalid hello message");
- QObject::disconnect(d->protocol, SIGNAL(readyRead()), this, SLOT(readyRead()));
- d->protocol->deleteLater();
- d->protocol = 0;
- d->connection->deleteLater();
- d->connection = 0;
- return;
- }
-
- int version;
- hello >> version >> d->clientPlugins;
-
- QHash<QString, QDeclarativeDebugService*>::Iterator iter = d->plugins.begin();
- for (; iter != d->plugins.end(); ++iter) {
- QDeclarativeDebugService::Status newStatus = QDeclarativeDebugService::Unavailable;
- if (d->clientPlugins.contains(iter.key()))
- newStatus = QDeclarativeDebugService::Enabled;
- iter.value()->statusChanged(newStatus);
- }
-
- QPacket helloAnswer;
- helloAnswer << QString(QLatin1String("QDeclarativeDebugClient")) << 0 << protocolVersion << d->plugins.keys();
- d->protocol->send(helloAnswer);
- d->connection->flush();
-
- d->gotHello = true;
- qWarning("QDeclarativeDebugServer: Connection established");
- }
-
- QString debugServer(QLatin1String("QDeclarativeDebugServer"));
-
- while (d->protocol->packetsAvailable()) {
- QPacket pack = d->protocol->read();
-
- QString name;
- pack >> name;
-
- if (name == debugServer) {
- int op = -1;
- pack >> op;
-
- if (op == 1) {
- // Service Discovery
- QStringList oldClientPlugins = d->clientPlugins;
- pack >> d->clientPlugins;
-
- QHash<QString, QDeclarativeDebugService*>::Iterator iter = d->plugins.begin();
- for (; iter != d->plugins.end(); ++iter) {
- const QString pluginName = iter.key();
- QDeclarativeDebugService::Status newStatus = QDeclarativeDebugService::Unavailable;
- if (d->clientPlugins.contains(pluginName))
- newStatus = QDeclarativeDebugService::Enabled;
-
- if (oldClientPlugins.contains(pluginName)
- != d->clientPlugins.contains(pluginName)) {
- iter.value()->statusChanged(newStatus);
- }
- }
- } else {
- qWarning("QDeclarativeDebugServer: Invalid control message %d", op);
- }
- } else {
- QByteArray message;
- pack >> message;
-
- QHash<QString, QDeclarativeDebugService *>::Iterator iter =
- d->plugins.find(name);
- if (iter == d->plugins.end()) {
- qWarning() << "QDeclarativeDebugServer: Message received for missing plugin" << name;
- } else {
- (*iter)->messageReceived(message);
- }
- }
- }
-}
-
QDeclarativeDebugServicePrivate::QDeclarativeDebugServicePrivate()
: server(0)
{
@@ -346,16 +59,16 @@ QDeclarativeDebugService::QDeclarativeDebugService(const QString &name, QObject
Q_D(QDeclarativeDebugService);
d->name = name;
d->server = QDeclarativeDebugServer::instance();
+ d->status = QDeclarativeDebugService::NotConnected;
if (!d->server)
return;
- if (d->server->d_func()->plugins.contains(name)) {
+ if (d->server->serviceNames().contains(name)) {
qWarning() << "QDeclarativeDebugService: Conflicting plugin name" << name;
d->server = 0;
} else {
- d->server->d_func()->plugins.insert(name, this);
- d->server->d_func()->advertisePlugins();
+ d->server->addService(this);
}
}
@@ -363,8 +76,7 @@ QDeclarativeDebugService::~QDeclarativeDebugService()
{
Q_D(const QDeclarativeDebugService);
if (d->server) {
- d->server->d_func()->plugins.remove(d->name);
- d->server->d_func()->advertisePlugins();
+ d->server->removeService(this);
}
}
@@ -377,13 +89,7 @@ QString QDeclarativeDebugService::name() const
QDeclarativeDebugService::Status QDeclarativeDebugService::status() const
{
Q_D(const QDeclarativeDebugService);
- if (!d->server
- || !d->server->hasDebuggingClient())
- return NotConnected;
- if (d->server->d_func()->clientPlugins.contains(d->name))
- return Enabled;
-
- return Unavailable;
+ return d->status;
}
namespace {
@@ -500,10 +206,7 @@ void QDeclarativeDebugService::sendMessage(const QByteArray &message)
if (status() != Enabled)
return;
- QPacket pack;
- pack << d->name << message;
- d->server->d_func()->protocol->send(pack);
- d->server->d_func()->connection->flush();
+ d->server->sendMessage(this, message);
}
void QDeclarativeDebugService::statusChanged(Status)
@@ -515,5 +218,3 @@ void QDeclarativeDebugService::messageReceived(const QByteArray &)
}
QT_END_NAMESPACE
-
-#include <qdeclarativedebugservice.moc>
diff --git a/src/declarative/debugger/qdeclarativedebugservice_p_p.h b/src/declarative/debugger/qdeclarativedebugservice_p_p.h
new file mode 100644
index 0000000..d2c8dda
--- /dev/null
+++ b/src/declarative/debugger/qdeclarativedebugservice_p_p.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** 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 QtDeclarative module 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$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEDEBUGSERVICE_P_H
+#define QDECLARATIVEDEBUGSERVICE_P_H
+
+#include <QtCore/qglobal.h>
+#include <private/qobject_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeDebugServer;
+
+class QDeclarativeDebugServicePrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QDeclarativeDebugService)
+public:
+ QDeclarativeDebugServicePrivate();
+
+ QString name;
+ QDeclarativeDebugServer *server;
+ QDeclarativeDebugService::Status status;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QDECLARATIVEDEBUGSERVICE_P_H
diff --git a/src/declarative/debugger/qdeclarativedebugtrace.cpp b/src/declarative/debugger/qdeclarativedebugtrace.cpp
index 03e2d56..314db70 100644
--- a/src/declarative/debugger/qdeclarativedebugtrace.cpp
+++ b/src/declarative/debugger/qdeclarativedebugtrace.cpp
@@ -43,11 +43,27 @@
#include <QtCore/qdatastream.h>
#include <QtCore/qurl.h>
+#include <QtCore/qtimer.h>
Q_GLOBAL_STATIC(QDeclarativeDebugTrace, traceInstance);
+// convert to a QByteArray that can be sent to the debug client
+// use of QDataStream can skew results if m_deferredSend == false
+// (see tst_qperformancetimer::trace() benchmark)
+QByteArray QDeclarativeDebugData::toByteArray() const
+{
+ QByteArray data;
+ //### using QDataStream is relatively expensive
+ QDataStream ds(&data, QIODevice::WriteOnly);
+ ds << time << messageType << detailType;
+ if (messageType == (int)QDeclarativeDebugTrace::RangeData)
+ ds << detailData;
+ return data;
+}
+
QDeclarativeDebugTrace::QDeclarativeDebugTrace()
-: QDeclarativeDebugService(QLatin1String("CanvasFrameRate"))
+: QDeclarativeDebugService(QLatin1String("CanvasFrameRate")),
+ m_enabled(false), m_deferredSend(true)
{
m_timer.start();
}
@@ -64,10 +80,16 @@ void QDeclarativeDebugTrace::startRange(RangeType t)
traceInstance()->startRangeImpl(t);
}
-void QDeclarativeDebugTrace::rangeData(RangeType t, const QUrl &url)
+void QDeclarativeDebugTrace::rangeData(RangeType t, const QString &data)
{
if (QDeclarativeDebugService::isDebuggingEnabled())
- traceInstance()->rangeDataImpl(t, url);
+ traceInstance()->rangeDataImpl(t, data);
+}
+
+void QDeclarativeDebugTrace::rangeData(RangeType t, const QUrl &data)
+{
+ if (QDeclarativeDebugService::isDebuggingEnabled())
+ traceInstance()->rangeDataImpl(t, data);
}
void QDeclarativeDebugTrace::endRange(RangeType t)
@@ -78,45 +100,81 @@ void QDeclarativeDebugTrace::endRange(RangeType t)
void QDeclarativeDebugTrace::addEventImpl(EventType event)
{
- if (status() != Enabled)
+ if (status() != Enabled || !m_enabled)
return;
- QByteArray data;
- QDataStream ds(&data, QIODevice::WriteOnly);
- ds << m_timer.elapsed() << (int)Event << (int)event;
- sendMessage(data);
+ QDeclarativeDebugData ed = {m_timer.elapsed(), (int)Event, (int)event, QString()};
+ processMessage(ed);
}
void QDeclarativeDebugTrace::startRangeImpl(RangeType range)
{
- if (status() != Enabled)
+ if (status() != Enabled || !m_enabled)
return;
- QByteArray data;
- QDataStream ds(&data, QIODevice::WriteOnly);
- ds << m_timer.elapsed() << (int)RangeStart << (int)range;
- sendMessage(data);
+ QDeclarativeDebugData rd = {m_timer.elapsed(), (int)RangeStart, (int)range, QString()};
+ processMessage(rd);
}
-void QDeclarativeDebugTrace::rangeDataImpl(RangeType range, const QUrl &u)
+void QDeclarativeDebugTrace::rangeDataImpl(RangeType range, const QString &rData)
{
- if (status() != Enabled)
+ if (status() != Enabled || !m_enabled)
return;
- QByteArray data;
- QDataStream ds(&data, QIODevice::WriteOnly);
- ds << m_timer.elapsed() << (int)RangeData << (int)range << (QString)u.toString();
- sendMessage(data);
+ QDeclarativeDebugData rd = {m_timer.elapsed(), (int)RangeData, (int)range, rData};
+ processMessage(rd);
+}
+
+void QDeclarativeDebugTrace::rangeDataImpl(RangeType range, const QUrl &rData)
+{
+ if (status() != Enabled || !m_enabled)
+ return;
+
+ QDeclarativeDebugData rd = {m_timer.elapsed(), (int)RangeData, (int)range, rData.toEncoded(QUrl::FormattingOption(0x100))};
+ processMessage(rd);
}
void QDeclarativeDebugTrace::endRangeImpl(RangeType range)
{
- if (status() != Enabled)
+ if (status() != Enabled || !m_enabled)
return;
- QByteArray data;
- QDataStream ds(&data, QIODevice::WriteOnly);
- ds << m_timer.elapsed() << (int)RangeEnd << (int)range;
- sendMessage(data);
+ QDeclarativeDebugData rd = {m_timer.elapsed(), (int)RangeEnd, (int)range, QString()};
+ processMessage(rd);
+}
+
+/*
+ Either send the message directly, or queue up
+ a list of messages to send later (via sendMessages)
+*/
+void QDeclarativeDebugTrace::processMessage(const QDeclarativeDebugData &message)
+{
+ if (m_deferredSend)
+ m_data.append(message);
+ else
+ sendMessage(message.toByteArray());
}
+/*
+ Send the messages queued up by processMessage
+*/
+void QDeclarativeDebugTrace::sendMessages()
+{
+ if (m_deferredSend) {
+ //### this is a suboptimal way to send batched messages
+ for (int i = 0; i < m_data.count(); ++i)
+ sendMessage(m_data.at(i).toByteArray());
+ m_data.clear();
+ }
+}
+
+void QDeclarativeDebugTrace::messageReceived(const QByteArray &message)
+{
+ QByteArray rwData = message;
+ QDataStream stream(&rwData, QIODevice::ReadOnly);
+
+ stream >> m_enabled;
+
+ if (!m_enabled)
+ sendMessages();
+}
diff --git a/src/declarative/debugger/qdeclarativedebugtrace_p.h b/src/declarative/debugger/qdeclarativedebugtrace_p.h
index 704c49a..3f9b904 100644
--- a/src/declarative/debugger/qdeclarativedebugtrace_p.h
+++ b/src/declarative/debugger/qdeclarativedebugtrace_p.h
@@ -43,24 +43,28 @@
#define QDECLARATIVEDEBUGTRACE_P_H
#include <private/qdeclarativedebugservice_p.h>
-#include <QtCore/qelapsedtimer.h>
+#include <private/qperformancetimer_p.h>
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
+struct QDeclarativeDebugData
+{
+ qint64 time;
+ int messageType;
+ int detailType;
+ QString detailData;
+
+ QByteArray toByteArray() const;
+};
+
+Q_DECLARE_TYPEINFO(QDeclarativeDebugData,Q_PRIMITIVE_TYPE);
+
class QUrl;
class Q_AUTOTEST_EXPORT QDeclarativeDebugTrace : public QDeclarativeDebugService
{
public:
- enum EventType {
- FramePaint,
- Mouse,
- Key,
-
- MaximumEventType
- };
-
enum Message {
Event,
RangeStart,
@@ -70,10 +74,20 @@ public:
MaximumMessage
};
+ enum EventType {
+ FramePaint,
+ Mouse,
+ Key,
+
+ MaximumEventType
+ };
+
enum RangeType {
Painting,
Compiling,
Creating,
+ Binding, //running a binding
+ HandlingSignal, //running a signal handler
MaximumRangeType
};
@@ -81,16 +95,25 @@ public:
static void addEvent(EventType);
static void startRange(RangeType);
+ static void rangeData(RangeType, const QString &);
static void rangeData(RangeType, const QUrl &);
static void endRange(RangeType);
QDeclarativeDebugTrace();
+protected:
+ virtual void messageReceived(const QByteArray &);
private:
void addEventImpl(EventType);
void startRangeImpl(RangeType);
+ void rangeDataImpl(RangeType, const QString &);
void rangeDataImpl(RangeType, const QUrl &);
void endRangeImpl(RangeType);
- QElapsedTimer m_timer;
+ void processMessage(const QDeclarativeDebugData &);
+ void sendMessages();
+ QPerformanceTimer m_timer;
+ bool m_enabled;
+ bool m_deferredSend;
+ QList<QDeclarativeDebugData> m_data;
};
QT_END_NAMESPACE
diff --git a/src/declarative/debugger/qpacketprotocol.cpp b/src/declarative/debugger/qpacketprotocol.cpp
index c2f7709..ad1e767 100644
--- a/src/declarative/debugger/qpacketprotocol.cpp
+++ b/src/declarative/debugger/qpacketprotocol.cpp
@@ -452,6 +452,14 @@ bool QPacket::isEmpty() const
}
/*!
+ Returns raw packet data.
+ */
+QByteArray QPacket::data() const
+{
+ return b;
+}
+
+/*!
Clears data in the packet. This is useful for reusing one writable packet.
For example
\code
diff --git a/src/declarative/debugger/qpacketprotocol_p.h b/src/declarative/debugger/qpacketprotocol_p.h
index d153833..1c69cdd 100644
--- a/src/declarative/debugger/qpacketprotocol_p.h
+++ b/src/declarative/debugger/qpacketprotocol_p.h
@@ -59,7 +59,7 @@ class QPacket;
class QPacketAutoSend;
class QPacketProtocolPrivate;
-class Q_DECLARATIVE_PRIVATE_EXPORT QPacketProtocol : public QObject
+class Q_DECLARATIVE_EXPORT QPacketProtocol : public QObject
{
Q_OBJECT
public:
@@ -89,7 +89,7 @@ private:
};
-class Q_DECLARATIVE_PRIVATE_EXPORT QPacket : public QDataStream
+class Q_DECLARATIVE_EXPORT QPacket : public QDataStream
{
public:
QPacket();
@@ -98,6 +98,7 @@ public:
void clear();
bool isEmpty() const;
+ QByteArray data() const;
protected:
friend class QPacketProtocol;
diff --git a/src/declarative/graphicsitems/graphicsitems.pri b/src/declarative/graphicsitems/graphicsitems.pri
index ffdeb29..2cd3323 100644
--- a/src/declarative/graphicsitems/graphicsitems.pri
+++ b/src/declarative/graphicsitems/graphicsitems.pri
@@ -50,7 +50,9 @@ HEADERS += \
$$PWD/qdeclarativelayoutitem_p.h \
$$PWD/qdeclarativeitemchangelistener_p.h \
$$PWD/qdeclarativegraphicswidget_p.h \
- $$PWD/qdeclarativetextlayout_p.h
+ $$PWD/qdeclarativetextlayout_p.h \
+ $$PWD/qdeclarativepincharea_p.h \
+ $$PWD/qdeclarativepincharea_p_p.h
SOURCES += \
$$PWD/qdeclarativeitemsmodule.cpp \
@@ -83,5 +85,6 @@ SOURCES += \
$$PWD/qdeclarativelistview.cpp \
$$PWD/qdeclarativelayoutitem.cpp \
$$PWD/qdeclarativegraphicswidget.cpp \
- $$PWD/qdeclarativetextlayout.cpp
+ $$PWD/qdeclarativetextlayout.cpp \
+ $$PWD/qdeclarativepincharea.cpp
diff --git a/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp b/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp
index 12a820f..abdfdfa 100644
--- a/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp
@@ -86,6 +86,16 @@ QT_BEGIN_NAMESPACE
\sa BorderImage, Image
*/
+/*!
+ \qmlproperty bool AnimatedImage::mirror
+ \since Quick 1.1
+
+ This property holds whether the image should be horizontally inverted
+ (effectively displaying a mirrored image).
+
+ The default value is false.
+*/
+
QDeclarativeAnimatedImage::QDeclarativeAnimatedImage(QDeclarativeItem *parent)
: QDeclarativeImage(*(new QDeclarativeAnimatedImagePrivate), parent)
{
@@ -126,7 +136,7 @@ void QDeclarativeAnimatedImage::setPaused(bool pause)
\qmlproperty bool AnimatedImage::playing
This property holds whether the animated image is playing.
- By defaults, this property is true, meaning that the animation
+ By default, this property is true, meaning that the animation
will start playing immediately.
*/
bool QDeclarativeAnimatedImage::isPlaying() const
diff --git a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp
index c0a7d72..63b2b9a 100644
--- a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp
@@ -200,6 +200,16 @@ QDeclarativeBorderImage::~QDeclarativeBorderImage()
*/
/*!
+ \qmlproperty bool BorderImage::mirror
+ \since Quick 1.1
+
+ This property holds whether the image should be horizontally inverted
+ (effectively displaying a mirrored image).
+
+ The default value is false.
+*/
+
+/*!
\qmlproperty url BorderImage::source
This property holds the URL that refers to the source image.
@@ -226,6 +236,16 @@ QDeclarativeBorderImage::~QDeclarativeBorderImage()
\sa QDeclarativeImageProvider
*/
+
+/*!
+ \qmlproperty QSize BorderImage::sourceSize
+
+ This property holds the actual width and height of the loaded image.
+
+ In BorderImage, this property is read-only.
+
+ \sa Image::sourceSize
+*/
void QDeclarativeBorderImage::setSource(const QUrl &url)
{
Q_D(QDeclarativeBorderImage);
@@ -290,7 +310,12 @@ void QDeclarativeBorderImage::load()
}
} else {
- d->pix.load(qmlEngine(this), d->url, d->async);
+ QDeclarativePixmap::Options options;
+ if (d->async)
+ options |= QDeclarativePixmap::Asynchronous;
+ if (d->cached)
+ options |= QDeclarativePixmap::Cached;
+ d->pix.load(qmlEngine(this), d->url, options);
if (d->pix.isLoading()) {
d->pix.connectFinished(this, SLOT(requestFinished()));
@@ -310,6 +335,7 @@ void QDeclarativeBorderImage::load()
d->progress = 1.0;
emit statusChanged(d->status);
emit progressChanged(d->progress);
+ requestFinished();
update();
}
}
@@ -413,7 +439,12 @@ void QDeclarativeBorderImage::setGridScaledImage(const QDeclarativeGridScaledIma
d->sciurl = d->url.resolved(QUrl(sci.pixmapUrl()));
- d->pix.load(qmlEngine(this), d->sciurl, d->async);
+ QDeclarativePixmap::Options options;
+ if (d->async)
+ options |= QDeclarativePixmap::Asynchronous;
+ if (d->cached)
+ options |= QDeclarativePixmap::Cached;
+ d->pix.load(qmlEngine(this), d->sciurl, options);
if (d->pix.isLoading()) {
static int thisRequestProgress = -1;
@@ -465,6 +496,9 @@ void QDeclarativeBorderImage::requestFinished()
setImplicitWidth(impsize.width());
setImplicitHeight(impsize.height());
+ if (d->sourcesize.width() != d->pix.width() || d->sourcesize.height() != d->pix.height())
+ emit sourceSizeChanged();
+
d->progress = 1.0;
emit statusChanged(d->status);
emit progressChanged(1.0);
@@ -514,8 +548,15 @@ void QDeclarativeBorderImage::paint(QPainter *p, const QStyleOptionGraphicsItem
bool oldAA = p->testRenderHint(QPainter::Antialiasing);
bool oldSmooth = p->testRenderHint(QPainter::SmoothPixmapTransform);
+ QTransform oldTransform;
if (d->smooth)
p->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, d->smooth);
+ if (d->mirror) {
+ oldTransform = p->transform();
+ QTransform mirror;
+ mirror.translate(d->width(), 0).scale(-1, 1.0);
+ p->setWorldTransform(mirror * oldTransform);
+ }
const QDeclarativeScaleGrid *border = d->getScaleGrid();
int left = border->left();
@@ -541,6 +582,8 @@ void QDeclarativeBorderImage::paint(QPainter *p, const QStyleOptionGraphicsItem
p->setRenderHint(QPainter::Antialiasing, oldAA);
p->setRenderHint(QPainter::SmoothPixmapTransform, oldSmooth);
}
+ if (d->mirror)
+ p->setWorldTransform(oldTransform);
}
QT_END_NAMESPACE
diff --git a/src/declarative/graphicsitems/qdeclarativeborderimage_p.h b/src/declarative/graphicsitems/qdeclarativeborderimage_p.h
index 9944cbe..d9db0ac 100644
--- a/src/declarative/graphicsitems/qdeclarativeborderimage_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeborderimage_p.h
@@ -63,6 +63,9 @@ class Q_AUTOTEST_EXPORT QDeclarativeBorderImage : public QDeclarativeImageBase
Q_PROPERTY(TileMode horizontalTileMode READ horizontalTileMode WRITE setHorizontalTileMode NOTIFY horizontalTileModeChanged)
Q_PROPERTY(TileMode verticalTileMode READ verticalTileMode WRITE setVerticalTileMode NOTIFY verticalTileModeChanged)
+ // read-only for BorderImage
+ Q_PROPERTY(QSize sourceSize READ sourceSize NOTIFY sourceSizeChanged)
+
public:
QDeclarativeBorderImage(QDeclarativeItem *parent=0);
~QDeclarativeBorderImage();
@@ -83,6 +86,7 @@ public:
Q_SIGNALS:
void horizontalTileModeChanged();
void verticalTileModeChanged();
+ void sourceSizeChanged();
protected:
virtual void load();
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
index f1d92c5..337965f 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
@@ -1269,6 +1269,60 @@ void QDeclarativeFlickable::setContentHeight(qreal h)
d->updateBeginningEnd();
}
+/*!
+ \qmlmethod Flickable::resizeContent(real width, real height, QPointF center)
+ \preliminary
+
+ Resizes the content to \a width x \a height about \a center.
+
+ \bold {This method was added in QtQuick 1.1.}
+
+ This does not scale the contents of the Flickable - it only resizes the \l contentWidth
+ and \l contentHeight.
+
+ Resizing the content may result in the content being positioned outside
+ the bounds of the Flickable. Calling \l returnToBounds() will
+ move the content back within legal bounds.
+*/
+void QDeclarativeFlickable::resizeContent(qreal w, qreal h, QPointF center)
+{
+ Q_D(QDeclarativeFlickable);
+ if (w != d->hData.viewSize) {
+ qreal oldSize = d->hData.viewSize;
+ setContentWidth(w);
+ if (center.x() != 0) {
+ qreal pos = center.x() * w / oldSize;
+ setContentX(contentX() + pos - center.x());
+ }
+ }
+ if (h != d->vData.viewSize) {
+ qreal oldSize = d->vData.viewSize;
+ setContentHeight(h);
+ if (center.y() != 0) {
+ qreal pos = center.y() * h / oldSize;
+ setContentY(contentY() + pos - center.y());
+ }
+ }
+}
+
+/*!
+ \qmlmethod Flickable::returnToBounds()
+ \preliminary
+
+ Ensures the content is within legal bounds.
+
+ \bold {This method was added in QtQuick 1.1.}
+
+ This may be called to ensure that the content is within legal bounds
+ after manually positioning the content.
+*/
+void QDeclarativeFlickable::returnToBounds()
+{
+ Q_D(QDeclarativeFlickable);
+ d->fixupX();
+ d->fixupY();
+}
+
qreal QDeclarativeFlickable::vWidth() const
{
Q_D(const QDeclarativeFlickable);
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable_p.h b/src/declarative/graphicsitems/qdeclarativeflickable_p.h
index 6e4d8ed..ece2db7 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeflickable_p.h
@@ -149,6 +149,10 @@ public:
FlickableDirection flickableDirection() const;
void setFlickableDirection(FlickableDirection);
+ //XXX Added in QtQuick 1.1
+ Q_INVOKABLE void resizeContent(qreal w, qreal h, QPointF center);
+ Q_INVOKABLE void returnToBounds();
+
Q_SIGNALS:
void contentWidthChanged();
void contentHeightChanged();
diff --git a/src/declarative/graphicsitems/qdeclarativeimage.cpp b/src/declarative/graphicsitems/qdeclarativeimage.cpp
index aa74716..68a1ecb 100644
--- a/src/declarative/graphicsitems/qdeclarativeimage.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeimage.cpp
@@ -458,84 +458,102 @@ QRectF QDeclarativeImage::boundingRect() const
are always loaded asynchonously.
*/
+/*!
+ \qmlproperty bool Image::cached
+ \since Quick 1.1
+
+ Specifies that the image should be cached. The default value is
+ true. Setting \a cached to false is useful when dealing with large images,
+ to make sure that they aren't cached at the expense of small 'ui element' images.
+*/
+
+/*!
+ \qmlproperty bool Image::mirror
+ \since Quick 1.1
+
+ This property holds whether the image should be horizontally inverted
+ (effectively displaying a mirrored image).
+
+ The default value is false.
+*/
+
+
void QDeclarativeImage::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
{
Q_D(QDeclarativeImage);
if (d->pix.pixmap().isNull() )
return;
- bool oldAA = p->testRenderHint(QPainter::Antialiasing);
- bool oldSmooth = p->testRenderHint(QPainter::SmoothPixmapTransform);
- if (d->smooth)
- p->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, d->smooth);
+ int drawWidth = width();
+ int drawHeight = height();
+ bool doClip = false;
+ QTransform transform;
+ qreal widthScale = width() / qreal(d->pix.width());
+ qreal heightScale = height() / qreal(d->pix.height());
if (width() != d->pix.width() || height() != d->pix.height()) {
if (d->fillMode >= Tile) {
- if (d->fillMode == Tile) {
- p->drawTiledPixmap(QRectF(0,0,width(),height()), d->pix);
- } else {
- qreal widthScale = width() / qreal(d->pix.width());
- qreal heightScale = height() / qreal(d->pix.height());
-
- QTransform scale;
- if (d->fillMode == TileVertically) {
- scale.scale(widthScale, 1.0);
- QTransform old = p->transform();
- p->setWorldTransform(scale * old);
- p->drawTiledPixmap(QRectF(0,0,d->pix.width(),height()), d->pix);
- p->setWorldTransform(old);
- } else {
- scale.scale(1.0, heightScale);
- QTransform old = p->transform();
- p->setWorldTransform(scale * old);
- p->drawTiledPixmap(QRectF(0,0,width(),d->pix.height()), d->pix);
- p->setWorldTransform(old);
- }
+ if (d->fillMode == TileVertically) {
+ transform.scale(widthScale, 1.0);
+ drawWidth = d->pix.width();
+ } else if (d->fillMode == TileHorizontally) {
+ transform.scale(1.0, heightScale);
+ drawHeight = d->pix.height();
}
} else {
- qreal widthScale = width() / qreal(d->pix.width());
- qreal heightScale = height() / qreal(d->pix.height());
-
- QTransform scale;
-
if (d->fillMode == PreserveAspectFit) {
if (widthScale <= heightScale) {
heightScale = widthScale;
- scale.translate(0, (height() - heightScale * d->pix.height()) / 2);
+ transform.translate(0, (height() - heightScale * d->pix.height()) / 2);
} else if(heightScale < widthScale) {
widthScale = heightScale;
- scale.translate((width() - widthScale * d->pix.width()) / 2, 0);
+ transform.translate((width() - widthScale * d->pix.width()) / 2, 0);
}
} else if (d->fillMode == PreserveAspectCrop) {
if (widthScale < heightScale) {
widthScale = heightScale;
- scale.translate((width() - widthScale * d->pix.width()) / 2, 0);
+ transform.translate((width() - widthScale * d->pix.width()) / 2, 0);
} else if(heightScale < widthScale) {
heightScale = widthScale;
- scale.translate(0, (height() - heightScale * d->pix.height()) / 2);
+ transform.translate(0, (height() - heightScale * d->pix.height()) / 2);
}
}
- if (clip()) {
- p->save();
- p->setClipRect(QRectF(0, 0, d->mWidth, d->mHeight), Qt::IntersectClip);
- }
- scale.scale(widthScale, heightScale);
- QTransform old = p->transform();
- p->setWorldTransform(scale * old);
- p->drawPixmap(0, 0, d->pix);
- p->setWorldTransform(old);
- if (clip()) {
- p->restore();
- }
+ transform.scale(widthScale, heightScale);
+ drawWidth = d->pix.width();
+ drawHeight = d->pix.height();
+ doClip = clip();
}
- } else {
- p->drawPixmap(0, 0, d->pix);
}
+ QTransform oldTransform;
+ bool oldAA = p->testRenderHint(QPainter::Antialiasing);
+ bool oldSmooth = p->testRenderHint(QPainter::SmoothPixmapTransform);
+ if (d->smooth)
+ p->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, d->smooth);
+ if (doClip) {
+ p->save();
+ p->setClipRect(QRectF(0, 0, d->mWidth, d->mHeight), Qt::IntersectClip);
+ }
+ if (d->mirror)
+ transform.translate(drawWidth, 0).scale(-1.0, 1.0);
+ if (!transform.isIdentity()) {
+ oldTransform = p->transform();
+ p->setWorldTransform(transform * oldTransform);
+ }
+
+ if (d->fillMode >= Tile)
+ p->drawTiledPixmap(QRectF(0, 0, drawWidth, drawHeight), d->pix);
+ else
+ p->drawPixmap(QRectF(0, 0, drawWidth, drawHeight), d->pix, QRectF(0, 0, drawWidth, drawHeight));
+
if (d->smooth) {
p->setRenderHint(QPainter::Antialiasing, oldAA);
p->setRenderHint(QPainter::SmoothPixmapTransform, oldSmooth);
}
+ if (doClip)
+ p->restore();
+ if (!transform.isIdentity())
+ p->setWorldTransform(oldTransform);
}
void QDeclarativeImage::pixmapChange()
diff --git a/src/declarative/graphicsitems/qdeclarativeimagebase.cpp b/src/declarative/graphicsitems/qdeclarativeimagebase.cpp
index c3bac2d..c745635 100644
--- a/src/declarative/graphicsitems/qdeclarativeimagebase.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeimagebase.cpp
@@ -128,6 +128,44 @@ QSize QDeclarativeImageBase::sourceSize() const
return QSize(width != -1 ? width : implicitWidth(), height != -1 ? height : implicitHeight());
}
+bool QDeclarativeImageBase::cached() const
+{
+ Q_D(const QDeclarativeImageBase);
+ return d->cached;
+}
+
+void QDeclarativeImageBase::setCached(bool cached)
+{
+ Q_D(QDeclarativeImageBase);
+ if (d->cached == cached)
+ return;
+
+ d->cached = cached;
+ emit cachedChanged();
+ if (isComponentComplete())
+ load();
+}
+
+void QDeclarativeImageBase::setMirror(bool mirror)
+{
+ Q_D(QDeclarativeImageBase);
+ if (mirror == d->mirror)
+ return;
+
+ d->mirror = mirror;
+
+ if (isComponentComplete())
+ update();
+
+ emit mirrorChanged();
+}
+
+bool QDeclarativeImageBase::mirror() const
+{
+ Q_D(const QDeclarativeImageBase);
+ return d->mirror;
+}
+
void QDeclarativeImageBase::load()
{
Q_D(QDeclarativeImageBase);
@@ -143,7 +181,12 @@ void QDeclarativeImageBase::load()
pixmapChange();
update();
} else {
- d->pix.load(qmlEngine(this), d->url, d->explicitSourceSize ? sourceSize() : QSize(), d->async);
+ QDeclarativePixmap::Options options;
+ if (d->async)
+ options |= QDeclarativePixmap::Asynchronous;
+ if (d->cached)
+ options |= QDeclarativePixmap::Cached;
+ d->pix.load(qmlEngine(this), d->url, d->explicitSourceSize ? sourceSize() : QSize(), options);
if (d->pix.isLoading()) {
d->progress = 0.0;
diff --git a/src/declarative/graphicsitems/qdeclarativeimagebase_p.h b/src/declarative/graphicsitems/qdeclarativeimagebase_p.h
index 68eb8d0..b6e55ec 100644
--- a/src/declarative/graphicsitems/qdeclarativeimagebase_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeimagebase_p.h
@@ -58,7 +58,9 @@ class Q_AUTOTEST_EXPORT QDeclarativeImageBase : public QDeclarativeItem
Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged)
Q_PROPERTY(bool asynchronous READ asynchronous WRITE setAsynchronous NOTIFY asynchronousChanged)
+ Q_PROPERTY(bool cached READ cached WRITE setCached NOTIFY cachedChanged) // ### VERSIONING: Only in QtQuick 1.1
Q_PROPERTY(QSize sourceSize READ sourceSize WRITE setSourceSize NOTIFY sourceSizeChanged)
+ Q_PROPERTY(bool mirror READ mirror WRITE setMirror NOTIFY mirrorChanged) // ### VERSIONING: Only in QtQuick 1.1
public:
~QDeclarativeImageBase();
@@ -72,15 +74,23 @@ public:
bool asynchronous() const;
void setAsynchronous(bool);
+ bool cached() const;
+ void setCached(bool);
+
virtual void setSourceSize(const QSize&);
QSize sourceSize() const;
+ virtual void setMirror(bool mirror);
+ bool mirror() const;
+
Q_SIGNALS:
void sourceChanged(const QUrl &);
void sourceSizeChanged();
void statusChanged(QDeclarativeImageBase::Status);
void progressChanged(qreal progress);
void asynchronousChanged();
+ void cachedChanged();
+ void mirrorChanged();
protected:
virtual void load();
diff --git a/src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h b/src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h
index 3d23ba9..950914f 100644
--- a/src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeimagebase_p_p.h
@@ -70,7 +70,9 @@ public:
: status(QDeclarativeImageBase::Null),
progress(0.0),
explicitSourceSize(false),
- async(false)
+ async(false),
+ cached(true),
+ mirror(false)
{
QGraphicsItemPrivate::flags = QGraphicsItemPrivate::flags & ~QGraphicsItem::ItemHasNoContents;
}
@@ -82,6 +84,8 @@ public:
QSize sourcesize;
bool explicitSourceSize : 1;
bool async : 1;
+ bool cached : 1;
+ bool mirror: 1;
};
QT_END_NAMESPACE
diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp
index 75e4a0b..4cf9b26 100644
--- a/src/declarative/graphicsitems/qdeclarativeitem.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp
@@ -444,6 +444,11 @@ void QDeclarativeItemKeyFilter::componentComplete()
\c KeyNavigation.BeforeItem allows the event to be used for key navigation
before the item, rather than after.
+ If item to which the focus is switching is not enabled or visible, an attempt will
+ be made to skip this item and focus on the next. This is possible if there are
+ a chain of items with the same KeyNavigation handler. If multiple items in a row are not enabled
+ or visible, they will also be skipped.
+
\sa {Keys}{Keys attached property}
*/
@@ -452,10 +457,12 @@ void QDeclarativeItemKeyFilter::componentComplete()
\qmlproperty Item KeyNavigation::right
\qmlproperty Item KeyNavigation::up
\qmlproperty Item KeyNavigation::down
+ \qmlproperty Item KeyNavigation::tab
+ \qmlproperty Item KeyNavigation::backtab
These properties hold the item to assign focus to
- when Key_Left, Key_Right, Key_Up or Key_Down are
- pressed.
+ when Key_Left, Key_Right, Key_Up, Key_Down, Key_Tab or Key_BackTab
+ are pressed.
*/
QDeclarativeKeyNavigationAttached::QDeclarativeKeyNavigationAttached(QObject *parent)
@@ -603,37 +610,37 @@ void QDeclarativeKeyNavigationAttached::keyPressed(QKeyEvent *event, bool post)
switch(event->key()) {
case Qt::Key_Left:
if (d->left) {
- d->left->setFocus(true);
+ setFocusNavigation(d->left, "left");
event->accept();
}
break;
case Qt::Key_Right:
if (d->right) {
- d->right->setFocus(true);
+ setFocusNavigation(d->right, "right");
event->accept();
}
break;
case Qt::Key_Up:
if (d->up) {
- d->up->setFocus(true);
+ setFocusNavigation(d->up, "up");
event->accept();
}
break;
case Qt::Key_Down:
if (d->down) {
- d->down->setFocus(true);
+ setFocusNavigation(d->down, "down");
event->accept();
}
break;
case Qt::Key_Tab:
if (d->tab) {
- d->tab->setFocus(true);
+ setFocusNavigation(d->tab, "tab");
event->accept();
}
break;
case Qt::Key_Backtab:
if (d->backtab) {
- d->backtab->setFocus(true);
+ setFocusNavigation(d->backtab, "backtab");
event->accept();
}
break;
@@ -692,6 +699,29 @@ void QDeclarativeKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post)
if (!event->isAccepted()) QDeclarativeItemKeyFilter::keyReleased(event, post);
}
+void QDeclarativeKeyNavigationAttached::setFocusNavigation(QDeclarativeItem *currentItem, const char *dir)
+{
+ QDeclarativeItem *initialItem = currentItem;
+ bool isNextItem = false;
+ do {
+ isNextItem = false;
+ if (currentItem->isVisible() && currentItem->isEnabled()) {
+ currentItem->setFocus(true);
+ } else {
+ QObject *attached =
+ qmlAttachedPropertiesObject<QDeclarativeKeyNavigationAttached>(currentItem, false);
+ if (attached) {
+ QDeclarativeItem *tempItem = qvariant_cast<QDeclarativeItem*>(attached->property(dir));
+ if (tempItem) {
+ currentItem = tempItem;
+ isNextItem = true;
+ }
+ }
+ }
+ }
+ while (currentItem != initialItem && isNextItem);
+}
+
/*!
\qmlclass Keys QDeclarativeKeysAttached
\ingroup qml-basic-interaction-elements
diff --git a/src/declarative/graphicsitems/qdeclarativeitem_p.h b/src/declarative/graphicsitems/qdeclarativeitem_p.h
index a36ee34..7e4d157 100644
--- a/src/declarative/graphicsitems/qdeclarativeitem_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeitem_p.h
@@ -415,6 +415,7 @@ Q_SIGNALS:
private:
virtual void keyPressed(QKeyEvent *event, bool post);
virtual void keyReleased(QKeyEvent *event, bool post);
+ void setFocusNavigation(QDeclarativeItem *currentItem, const char *dir);
};
class QDeclarativeKeysAttachedPrivate : public QObjectPrivate
diff --git a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp
index 52703c2..a462763 100644
--- a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp
@@ -78,6 +78,7 @@
#include "private/qdeclarativewebview_p_p.h"
#endif
#include "private/qdeclarativeanchors_p.h"
+#include "private/qdeclarativepincharea_p.h"
static QDeclarativePrivate::AutoParentResult qgraphicsobject_autoParent(QObject *obj, QObject *parent)
{
@@ -147,10 +148,13 @@ void QDeclarativeItemModule::defineModule()
qmlRegisterType<QDeclarativeViewSection>("QtQuick",1,0,"ViewSection");
qmlRegisterType<QDeclarativeVisualDataModel>("QtQuick",1,0,"VisualDataModel");
qmlRegisterType<QDeclarativeVisualItemModel>("QtQuick",1,0,"VisualItemModel");
+ qmlRegisterType<QDeclarativePinchArea>("QtQuick",1,1,"PinchArea");
+ qmlRegisterType<QDeclarativePinch>();
qmlRegisterType<QDeclarativeAnchors>();
qmlRegisterType<QDeclarativeKeyEvent>();
qmlRegisterType<QDeclarativeMouseEvent>();
+ qmlRegisterType<QDeclarativePinchEvent>();
qmlRegisterType<QGraphicsObject>();
qmlRegisterType<QGraphicsWidget>("QtQuick",1,0,"QGraphicsWidget");
qmlRegisterExtendedType<QGraphicsWidget,QDeclarativeGraphicsWidget>("QtQuick",1,0,"QGraphicsWidget");
diff --git a/src/declarative/graphicsitems/qdeclarativepincharea.cpp b/src/declarative/graphicsitems/qdeclarativepincharea.cpp
new file mode 100644
index 0000000..998c30d
--- /dev/null
+++ b/src/declarative/graphicsitems/qdeclarativepincharea.cpp
@@ -0,0 +1,579 @@
+/****************************************************************************
+**
+** 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 QtDeclarative module 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$
+**
+****************************************************************************/
+
+#include "qdeclarativepincharea_p.h"
+#include "qdeclarativepincharea_p_p.h"
+
+#include <QApplication>
+#include <QGraphicsScene>
+
+#include <float.h>
+#include <math.h>
+
+QT_BEGIN_NAMESPACE
+
+
+/*!
+ \qmlclass PinchEvent QDeclarativePinchEvent
+ \ingroup qml-event-elements
+ \brief The PinchEvent object provides information about a pinch event.
+
+ \bold {The PinchEvent element was added in QtQuick 1.1}
+
+ The \c center, \c startCenter, \c lastCenter properties provide the center position between the two touch points.
+
+ The \c scale and \c lastScale properties provide the scale factor.
+
+ The \c angle, \c lastAngle and \c rotation properties provide the angle between the two points and the amount of rotation.
+
+ The \c point1, \c point2, \c startPoint1, \c startPoint2 properties provide the positions of the touch points.
+
+ The \c accepted property may be set to false in the \c onPinchStarted handler if the gesture should not
+ be handled.
+
+ \sa PinchArea
+*/
+
+/*!
+ \qmlproperty QPointF PinchEvent::center
+ \qmlproperty QPointF PinchEvent::startCenter
+ \qmlproperty QPointF PinchEvent::lastCenter
+
+ These properties hold the position of the center point between the two touch points.
+
+ \list
+ \o \c center is the current center point
+ \o \c lastCenter is the center point of the previous event.
+ \o \c startCenter is the center point when the gesture began
+ \endlist
+*/
+
+/*!
+ \qmlproperty real PinchEvent::scale
+ \qmlproperty real PinchEvent::lastScale
+
+ These properties hold the scale factor determined by the change in distance between the two touch points.
+
+ \list
+ \o \c scale is the current scale factor.
+ \o \c lastScale is the scale factor of the previous event.
+ \endlist
+
+ When a pinch gesture is started, the scale is 1.0.
+*/
+
+/*!
+ \qmlproperty real PinchEvent::angle
+ \qmlproperty real PinchEvent::lastAngle
+ \qmlproperty real PinchEvent::rotation
+
+ These properties hold the angle between the two touch points.
+
+ \list
+ \o \c angle is the current angle between the two points in the range -180 to 180.
+ \o \c lastAngle is the angle of the previous event.
+ \o \c rotation is the total rotation since the pinch gesture started.
+ \endlist
+
+ When a pinch gesture is started, the rotation is 0.0.
+*/
+
+/*!
+ \qmlproperty QPointF PinchEvent::point1
+ \qmlproperty QPointF PinchEvent::startPoint1
+ \qmlproperty QPointF PinchEvent::point2
+ \qmlproperty QPointF PinchEvent::startPoint2
+
+ These properties provide the actual touch points generating the pinch.
+
+ \list
+ \o \c point1 and \c point2 hold the current positions of the points.
+ \o \c startPoint1 and \c startPoint2 hold the positions of the points when the second point was touched.
+ \endlist
+*/
+
+/*!
+ \qmlproperty bool PinchEvent::accepted
+
+ Setting this property to false in the \c PinchArea::onPinchStarted handler
+ will result in no further pinch events being generated, and the gesture
+ ignored.
+*/
+
+QDeclarativePinch::QDeclarativePinch()
+ : m_target(0), m_minScale(1.0), m_maxScale(1.0)
+ , m_minRotation(0.0), m_maxRotation(0.0)
+ , m_axis(NoDrag), m_xmin(-FLT_MAX), m_xmax(FLT_MAX)
+ , m_ymin(-FLT_MAX), m_ymax(FLT_MAX), m_active(false)
+{
+}
+
+QDeclarativePinchAreaPrivate::~QDeclarativePinchAreaPrivate()
+{
+ delete pinch;
+}
+
+/*!
+ \qmlclass PinchArea QDeclarativePinchArea
+ \brief The PinchArea item enables simple pinch gesture handling.
+ \inherits Item
+
+ \bold {The PinchArea element was added in QtQuick 1.1}
+
+ A PinchArea is an invisible item that is typically used in conjunction with
+ a visible item in order to provide pinch gesture handling for that item.
+
+ The \l enabled property is used to enable and disable pinch handling for
+ the proxied item. When disabled, the pinch area becomes transparent to
+ mouse/touch events.
+
+ PinchArea can be used in two ways:
+
+ \list
+ \o setting a \c pinch.target to provide automatic interaction with an element
+ \o using the onPinchStarted, onPinchChanged and onPinchFinished handlers
+ \endlist
+
+ \sa PinchEvent
+*/
+
+/*!
+ \qmlsignal PinchArea::onPinchStarted()
+
+ This handler is called when the pinch area detects that a pinch gesture has started.
+
+ The \l {PinchEvent}{pinch} parameter provides information about the pinch gesture,
+ including the scale, center and angle of the pinch.
+
+ To ignore this gesture set the \c pinch.accepted property to false. The gesture
+ will be cancelled and no further events will be sent.
+*/
+
+/*!
+ \qmlsignal PinchArea::onPinchChanged()
+
+ This handler is called when the pinch area detects that a pinch gesture has changed.
+
+ The \l {PinchEvent}{pinch} parameter provides information about the pinch gesture,
+ including the scale, center and angle of the pinch.
+*/
+
+/*!
+ \qmlsignal PinchArea::onPinchFinished()
+
+ This handler is called when the pinch area detects that a pinch gesture has finished.
+
+ The \l {PinchEvent}{pinch} parameter provides information about the pinch gesture,
+ including the scale, center and angle of the pinch.
+*/
+
+
+/*!
+ \qmlproperty Item PinchArea::pinch.target
+ \qmlproperty bool PinchArea::pinch.active
+ \qmlproperty real PinchArea::pinch.minimumScale
+ \qmlproperty real PinchArea::pinch.maximumScale
+ \qmlproperty real PinchArea::pinch.minimumRotation
+ \qmlproperty real PinchArea::pinch.maximumRotation
+ \qmlproperty enumeration PinchArea::pinch.dragAxis
+ \qmlproperty real PinchArea::pinch.minimumX
+ \qmlproperty real PinchArea::pinch.maximumX
+ \qmlproperty real PinchArea::pinch.minimumY
+ \qmlproperty real PinchArea::pinch.maximumY
+
+ \c pinch provides a convenient way to make an item react to pinch gestures.
+
+ \list
+ \i \c pinch.target specifies the id of the item to drag.
+ \i \c pinch.active specifies if the target item is currently being dragged.
+ \i \c pinch.minimumScale and \c pinch.maximumScale limit the range of the Item::scale property.
+ \i \c pinch.minimumRotation and \c pinch.maximumRotation limit the range of the Item::rotation property.
+ \i \c pinch.dragAxis specifies whether dragging in not allowed (\c Pinch.NoDrag), can be done horizontally (\c Pinch.XAxis), vertically (\c Pinch.YAxis), or both (\c Pinch.XandYAxis)
+ \i \c pinch.minimum and \c pinch.maximum limit how far the target can be dragged along the corresponding axes.
+ \endlist
+*/
+
+QDeclarativePinchArea::QDeclarativePinchArea(QDeclarativeItem *parent)
+ : QDeclarativeItem(*(new QDeclarativePinchAreaPrivate), parent)
+{
+ Q_D(QDeclarativePinchArea);
+ d->init();
+}
+
+QDeclarativePinchArea::~QDeclarativePinchArea()
+{
+}
+
+/*!
+ \qmlproperty bool PinchArea::enabled
+ This property holds whether the item accepts pinch gestures.
+
+ This property defaults to true.
+*/
+bool QDeclarativePinchArea::isEnabled() const
+{
+ Q_D(const QDeclarativePinchArea);
+ return d->absorb;
+}
+
+void QDeclarativePinchArea::setEnabled(bool a)
+{
+ Q_D(QDeclarativePinchArea);
+ if (a != d->absorb) {
+ d->absorb = a;
+ emit enabledChanged();
+ }
+}
+
+bool QDeclarativePinchArea::event(QEvent *event)
+{
+ Q_D(QDeclarativePinchArea);
+ if (!d->absorb || !isVisible())
+ return QDeclarativeItem::event(event);
+ switch (event->type()) {
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate: {
+ QTouchEvent *touch = static_cast<QTouchEvent*>(event);
+ d->touchPoints.clear();
+ for (int i = 0; i < touch->touchPoints().count(); ++i) {
+ if (!(touch->touchPoints().at(i).state() & Qt::TouchPointReleased)) {
+ d->touchPoints << touch->touchPoints().at(i);
+ }
+ }
+ updatePinch();
+ }
+ return true;
+ case QEvent::TouchEnd:
+ d->touchPoints.clear();
+ updatePinch();
+ break;
+ default:
+ return QDeclarativeItem::event(event);
+ }
+
+ return QDeclarativeItem::event(event);
+}
+
+void QDeclarativePinchArea::updatePinch()
+{
+ Q_D(QDeclarativePinchArea);
+ if (d->touchPoints.count() != 2) {
+ if (d->inPinch) {
+ d->stealMouse = false;
+ setKeepMouseGrab(false);
+ d->inPinch = false;
+ const qreal rotationAngle = d->pinchStartAngle - d->pinchLastAngle;
+ QPointF pinchCenter = mapFromScene(d->sceneLastCenter);
+ QDeclarativePinchEvent pe(pinchCenter, d->pinchLastScale, d->pinchLastAngle, rotationAngle);
+ pe.setStartCenter(d->pinchStartCenter);
+ pe.setLastCenter(pinchCenter);
+ pe.setLastAngle(d->pinchLastAngle);
+ pe.setLastScale(d->pinchLastScale);
+ pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
+ pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
+ pe.setPoint1(d->lastPoint1);
+ pe.setPoint2(d->lastPoint2);
+ emit pinchFinished(&pe);
+ if (d->pinch && d->pinch->target())
+ d->pinch->setActive(false);
+ }
+ return;
+ }
+ if (d->touchPoints.at(0).state() & Qt::TouchPointPressed
+ || d->touchPoints.at(1).state() & Qt::TouchPointPressed) {
+ d->sceneStartPoint1 = d->touchPoints.at(0).scenePos();
+ d->sceneStartPoint2 = d->touchPoints.at(1).scenePos();
+ d->inPinch = false;
+ d->pinchRejected = false;
+ } else if (!d->pinchRejected){
+ QDeclarativeItem *grabber = scene() ? qobject_cast<QDeclarativeItem*>(scene()->mouseGrabberItem()) : 0;
+ if (grabber == this || !grabber || !grabber->keepMouseGrab()) {
+ const int dragThreshold = QApplication::startDragDistance();
+ QPointF p1 = d->touchPoints.at(0).scenePos();
+ QPointF p2 = d->touchPoints.at(1).scenePos();
+ qreal dx = p1.x() - p2.x();
+ qreal dy = p1.y() - p2.y();
+ qreal dist = sqrt(dx*dx + dy*dy);
+ QPointF sceneCenter = (p1 + p2)/2;
+ qreal angle = QLineF(p1, p2).angle();
+ if (angle > 180)
+ angle -= 360;
+ if (!d->inPinch) {
+ if (qAbs(p1.x()-d->sceneStartPoint1.x()) > dragThreshold
+ || qAbs(p1.y()-d->sceneStartPoint1.y()) > dragThreshold
+ || qAbs(p2.x()-d->sceneStartPoint2.x()) > dragThreshold
+ || qAbs(p2.y()-d->sceneStartPoint2.y()) > dragThreshold) {
+ d->sceneStartCenter = sceneCenter;
+ d->sceneLastCenter = sceneCenter;
+ d->pinchStartCenter = mapFromScene(sceneCenter);
+ d->pinchStartDist = dist;
+ d->pinchStartAngle = angle;
+ d->pinchLastScale = 1.0;
+ d->pinchLastAngle = angle;
+ d->lastPoint1 = d->touchPoints.at(0).pos();
+ d->lastPoint2 = d->touchPoints.at(1).pos();
+ QDeclarativePinchEvent pe(d->pinchStartCenter, 1.0, angle, 0.0);
+ pe.setStartCenter(d->pinchStartCenter);
+ pe.setLastCenter(d->pinchStartCenter);
+ pe.setLastAngle(d->pinchLastAngle);
+ pe.setLastScale(d->pinchLastScale);
+ pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
+ pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
+ pe.setPoint1(d->lastPoint1);
+ pe.setPoint2(d->lastPoint2);
+ emit pinchStarted(&pe);
+ if (pe.accepted()) {
+ d->inPinch = true;
+ d->stealMouse = true;
+ grabMouse();
+ setKeepMouseGrab(true);
+ if (d->pinch && d->pinch->target()) {
+ d->pinchStartPos = pinch()->target()->pos();
+ d->pinchStartScale = d->pinch->target()->scale();
+ d->pinchStartRotation = d->pinch->target()->rotation();
+ d->pinch->setActive(true);
+ }
+ } else {
+ d->pinchRejected = true;
+ }
+ }
+ } else if (d->pinchStartDist > 0) {
+ qreal scale = dist / d->pinchStartDist;
+ qreal rotationAngle = d->pinchStartAngle - angle;
+ if (rotationAngle > 180)
+ rotationAngle -= 360;
+ QPointF pinchCenter = mapFromScene(sceneCenter);
+ QDeclarativePinchEvent pe(pinchCenter, scale, angle, rotationAngle);
+ pe.setStartCenter(d->pinchStartCenter);
+ pe.setLastCenter(mapFromScene(d->sceneLastCenter));
+ pe.setLastAngle(d->pinchLastAngle);
+ pe.setLastScale(d->pinchLastScale);
+ pe.setStartPoint1(mapFromScene(d->sceneStartPoint1));
+ pe.setStartPoint2(mapFromScene(d->sceneStartPoint2));
+ pe.setPoint1(d->touchPoints.at(0).pos());
+ pe.setPoint2(d->touchPoints.at(1).pos());
+ d->pinchLastScale = scale;
+ d->sceneLastCenter = sceneCenter;
+ d->pinchLastAngle = angle;
+ d->lastPoint1 = d->touchPoints.at(0).pos();
+ d->lastPoint2 = d->touchPoints.at(1).pos();
+ emit pinchChanged(&pe);
+ if (d->pinch && d->pinch->target()) {
+ qreal s = d->pinchStartScale * scale;
+ s = qMin(qMax(pinch()->minimumScale(),s), pinch()->maximumScale());
+ pinch()->target()->setScale(s);
+ QPointF pos = sceneCenter - d->sceneStartCenter + d->pinchStartPos;
+ if (pinch()->axis() & QDeclarativePinch::XAxis) {
+ qreal x = pos.x();
+ if (x < pinch()->xmin())
+ x = pinch()->xmin();
+ else if (x > pinch()->xmax())
+ x = pinch()->xmax();
+ pinch()->target()->setX(x);
+ }
+ if (pinch()->axis() & QDeclarativePinch::YAxis) {
+ qreal y = pos.y();
+ if (y < pinch()->ymin())
+ y = pinch()->ymin();
+ else if (y > pinch()->ymax())
+ y = pinch()->ymax();
+ pinch()->target()->setY(y);
+ }
+ if (d->pinchStartRotation >= pinch()->minimumRotation()
+ && d->pinchStartRotation <= pinch()->maximumRotation()) {
+ qreal r = rotationAngle + d->pinchStartRotation;
+ r = qMin(qMax(pinch()->minimumRotation(),r), pinch()->maximumRotation());
+ pinch()->target()->setRotation(r);
+ }
+ }
+ }
+ }
+ }
+}
+
+void QDeclarativePinchArea::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_D(QDeclarativePinchArea);
+ d->stealMouse = false;
+ if (!d->absorb)
+ QDeclarativeItem::mousePressEvent(event);
+ else {
+ setKeepMouseGrab(false);
+ event->setAccepted(true);
+ }
+}
+
+void QDeclarativePinchArea::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_D(QDeclarativePinchArea);
+ if (!d->absorb) {
+ QDeclarativeItem::mouseMoveEvent(event);
+ return;
+ }
+}
+
+void QDeclarativePinchArea::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_D(QDeclarativePinchArea);
+ d->stealMouse = false;
+ if (!d->absorb) {
+ QDeclarativeItem::mouseReleaseEvent(event);
+ } else {
+ QGraphicsScene *s = scene();
+ if (s && s->mouseGrabberItem() == this)
+ ungrabMouse();
+ setKeepMouseGrab(false);
+ }
+}
+
+bool QDeclarativePinchArea::sceneEvent(QEvent *event)
+{
+ bool rv = QDeclarativeItem::sceneEvent(event);
+ if (event->type() == QEvent::UngrabMouse) {
+ setKeepMouseGrab(false);
+ }
+ return rv;
+}
+
+bool QDeclarativePinchArea::sendMouseEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_D(QDeclarativePinchArea);
+ QGraphicsSceneMouseEvent mouseEvent(event->type());
+ QRectF myRect = mapToScene(QRectF(0, 0, width(), height())).boundingRect();
+
+ QGraphicsScene *s = scene();
+ QDeclarativeItem *grabber = s ? qobject_cast<QDeclarativeItem*>(s->mouseGrabberItem()) : 0;
+ bool stealThisEvent = d->stealMouse;
+ if ((stealThisEvent || myRect.contains(event->scenePos().toPoint())) && (!grabber || !grabber->keepMouseGrab())) {
+ mouseEvent.setAccepted(false);
+ for (int i = 0x1; i <= 0x10; i <<= 1) {
+ if (event->buttons() & i) {
+ Qt::MouseButton button = Qt::MouseButton(i);
+ mouseEvent.setButtonDownPos(button, mapFromScene(event->buttonDownPos(button)));
+ }
+ }
+ mouseEvent.setScenePos(event->scenePos());
+ mouseEvent.setLastScenePos(event->lastScenePos());
+ mouseEvent.setPos(mapFromScene(event->scenePos()));
+ mouseEvent.setLastPos(mapFromScene(event->lastScenePos()));
+
+ switch(mouseEvent.type()) {
+ case QEvent::GraphicsSceneMouseMove:
+ mouseMoveEvent(&mouseEvent);
+ break;
+ case QEvent::GraphicsSceneMousePress:
+ mousePressEvent(&mouseEvent);
+ break;
+ case QEvent::GraphicsSceneMouseRelease:
+ mouseReleaseEvent(&mouseEvent);
+ break;
+ default:
+ break;
+ }
+ grabber = qobject_cast<QDeclarativeItem*>(s->mouseGrabberItem());
+ if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this)
+ grabMouse();
+
+ return stealThisEvent;
+ }
+ if (mouseEvent.type() == QEvent::GraphicsSceneMouseRelease) {
+ d->stealMouse = false;
+ if (s && s->mouseGrabberItem() == this)
+ ungrabMouse();
+ setKeepMouseGrab(false);
+ }
+ return false;
+}
+
+bool QDeclarativePinchArea::sceneEventFilter(QGraphicsItem *i, QEvent *e)
+{
+ Q_D(QDeclarativePinchArea);
+ if (!d->absorb || !isVisible())
+ return QDeclarativeItem::sceneEventFilter(i, e);
+ switch (e->type()) {
+ case QEvent::GraphicsSceneMousePress:
+ case QEvent::GraphicsSceneMouseMove:
+ case QEvent::GraphicsSceneMouseRelease:
+ return sendMouseEvent(static_cast<QGraphicsSceneMouseEvent *>(e));
+ break;
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate: {
+ QTouchEvent *touch = static_cast<QTouchEvent*>(e);
+ d->touchPoints.clear();
+ for (int i = 0; i < touch->touchPoints().count(); ++i)
+ if (!(touch->touchPoints().at(i).state() & Qt::TouchPointReleased))
+ d->touchPoints << touch->touchPoints().at(i);
+ updatePinch();
+ }
+ return d->inPinch;
+ case QEvent::TouchEnd:
+ d->touchPoints.clear();
+ updatePinch();
+ break;
+ default:
+ break;
+ }
+
+ return QDeclarativeItem::sceneEventFilter(i, e);
+}
+
+void QDeclarativePinchArea::geometryChanged(const QRectF &newGeometry,
+ const QRectF &oldGeometry)
+{
+ QDeclarativeItem::geometryChanged(newGeometry, oldGeometry);
+}
+
+QVariant QDeclarativePinchArea::itemChange(GraphicsItemChange change,
+ const QVariant &value)
+{
+ return QDeclarativeItem::itemChange(change, value);
+}
+
+QDeclarativePinch *QDeclarativePinchArea::pinch()
+{
+ Q_D(QDeclarativePinchArea);
+ if (!d->pinch)
+ d->pinch = new QDeclarativePinch;
+ return d->pinch;
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/declarative/graphicsitems/qdeclarativepincharea_p.h b/src/declarative/graphicsitems/qdeclarativepincharea_p.h
new file mode 100644
index 0000000..9a73a17
--- /dev/null
+++ b/src/declarative/graphicsitems/qdeclarativepincharea_p.h
@@ -0,0 +1,308 @@
+/****************************************************************************
+**
+** 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 QtDeclarative module 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$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEPINCHAREA_H
+#define QDECLARATIVEPINCHAREA_H
+
+#include <qdeclarativeitem.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class Q_AUTOTEST_EXPORT QDeclarativePinch : public QObject
+{
+ Q_OBJECT
+
+ Q_ENUMS(Axis)
+ Q_PROPERTY(QGraphicsObject *target READ target WRITE setTarget RESET resetTarget)
+ Q_PROPERTY(qreal minimumScale READ minimumScale WRITE setMinimumScale NOTIFY minimumScaleChanged)
+ Q_PROPERTY(qreal maximumScale READ maximumScale WRITE setMaximumScale NOTIFY maximumScaleChanged)
+ Q_PROPERTY(qreal minimumRotation READ minimumRotation WRITE setMinimumRotation NOTIFY minimumRotationChanged)
+ Q_PROPERTY(qreal maximumRotation READ maximumRotation WRITE setMaximumRotation NOTIFY maximumRotationChanged)
+ Q_PROPERTY(Axis dragAxis READ axis WRITE setAxis NOTIFY dragAxisChanged)
+ Q_PROPERTY(qreal minimumX READ xmin WRITE setXmin NOTIFY minimumXChanged)
+ Q_PROPERTY(qreal maximumX READ xmax WRITE setXmax NOTIFY maximumXChanged)
+ Q_PROPERTY(qreal minimumY READ ymin WRITE setYmin NOTIFY minimumYChanged)
+ Q_PROPERTY(qreal maximumY READ ymax WRITE setYmax NOTIFY maximumYChanged)
+ Q_PROPERTY(bool active READ active NOTIFY activeChanged)
+
+public:
+ QDeclarativePinch();
+
+ QGraphicsObject *target() const { return m_target; }
+ void setTarget(QGraphicsObject *target) {
+ if (target == m_target)
+ return;
+ m_target = target;
+ emit targetChanged();
+ }
+ void resetTarget() {
+ if (!m_target)
+ return;
+ m_target = 0;
+ emit targetChanged();
+ }
+
+ qreal minimumScale() const { return m_minScale; }
+ void setMinimumScale(qreal s) {
+ if (s == m_minScale)
+ return;
+ m_minScale = s;
+ emit minimumScaleChanged();
+ }
+ qreal maximumScale() const { return m_maxScale; }
+ void setMaximumScale(qreal s) {
+ if (s == m_maxScale)
+ return;
+ m_maxScale = s;
+ emit maximumScaleChanged();
+ }
+
+ qreal minimumRotation() const { return m_minRotation; }
+ void setMinimumRotation(qreal r) {
+ if (r == m_minRotation)
+ return;
+ m_minRotation = r;
+ emit minimumRotationChanged();
+ }
+ qreal maximumRotation() const { return m_maxRotation; }
+ void setMaximumRotation(qreal r) {
+ if (r == m_maxRotation)
+ return;
+ m_maxRotation = r;
+ emit maximumRotationChanged();
+ }
+
+ enum Axis { NoDrag=0x00, XAxis=0x01, YAxis=0x02, XandYAxis=0x03 };
+ Axis axis() const { return m_axis; }
+ void setAxis(Axis a) {
+ if (a == m_axis)
+ return;
+ m_axis = a;
+ emit dragAxisChanged();
+ }
+
+ qreal xmin() const { return m_xmin; }
+ void setXmin(qreal x) {
+ if (x == m_xmin)
+ return;
+ m_xmin = x;
+ emit minimumXChanged();
+ }
+ qreal xmax() const { return m_xmax; }
+ void setXmax(qreal x) {
+ if (x == m_xmax)
+ return;
+ m_xmax = x;
+ emit maximumXChanged();
+ }
+ qreal ymin() const { return m_ymin; }
+ void setYmin(qreal y) {
+ if (y == m_ymin)
+ return;
+ m_ymin = y;
+ emit minimumYChanged();
+ }
+ qreal ymax() const { return m_ymax; }
+ void setYmax(qreal y) {
+ if (y == m_ymax)
+ return;
+ m_ymax = y;
+ emit maximumYChanged();
+ }
+
+ bool active() const { return m_active; }
+ void setActive(bool a) {
+ if (a == m_active)
+ return;
+ m_active = a;
+ emit activeChanged();
+ }
+
+signals:
+ void targetChanged();
+ void minimumScaleChanged();
+ void maximumScaleChanged();
+ void minimumRotationChanged();
+ void maximumRotationChanged();
+ void dragAxisChanged();
+ void minimumXChanged();
+ void maximumXChanged();
+ void minimumYChanged();
+ void maximumYChanged();
+ void activeChanged();
+
+private:
+ QGraphicsObject *m_target;
+ qreal m_minScale;
+ qreal m_maxScale;
+ qreal m_minRotation;
+ qreal m_maxRotation;
+ Axis m_axis;
+ qreal m_xmin;
+ qreal m_xmax;
+ qreal m_ymin;
+ qreal m_ymax;
+ bool m_active;
+};
+
+class Q_AUTOTEST_EXPORT QDeclarativePinchEvent : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QPointF center READ center)
+ Q_PROPERTY(QPointF startCenter READ startCenter)
+ Q_PROPERTY(QPointF lastCenter READ lastCenter)
+ Q_PROPERTY(qreal scale READ scale)
+ Q_PROPERTY(qreal lastScale READ lastScale)
+ Q_PROPERTY(qreal angle READ angle)
+ Q_PROPERTY(qreal lastAngle READ lastAngle)
+ Q_PROPERTY(qreal rotation READ rotation)
+ Q_PROPERTY(QPointF point1 READ point1)
+ Q_PROPERTY(QPointF startPoint1 READ startPoint1)
+ Q_PROPERTY(QPointF point2 READ point2)
+ Q_PROPERTY(QPointF startPoint2 READ startPoint2)
+ Q_PROPERTY(bool accepted READ accepted WRITE setAccepted)
+
+public:
+ QDeclarativePinchEvent(QPointF c, qreal s, qreal a, qreal r)
+ : QObject(), m_center(c), m_scale(s), m_angle(a), m_rotation(r) {}
+
+ QPointF center() const { return m_center; }
+ QPointF startCenter() const { return m_startCenter; }
+ void setStartCenter(QPointF c) { m_startCenter = c; }
+ QPointF lastCenter() const { return m_lastCenter; }
+ void setLastCenter(QPointF c) { m_lastCenter = c; }
+ qreal scale() const { return m_scale; }
+ qreal lastScale() const { return m_lastScale; }
+ void setLastScale(qreal s) { m_lastScale = s; }
+ qreal angle() const { return m_angle; }
+ qreal lastAngle() const { return m_lastAngle; }
+ void setLastAngle(qreal a) { m_lastAngle = a; }
+ qreal rotation() const { return m_rotation; }
+ QPointF point1() const { return m_point1; }
+ void setPoint1(QPointF p) { m_point1 = p; }
+ QPointF startPoint1() const { return m_startPoint1; }
+ void setStartPoint1(QPointF p) { m_startPoint1 = p; }
+ QPointF point2() const { return m_point2; }
+ void setPoint2(QPointF p) { m_point2 = p; }
+ QPointF startPoint2() const { return m_startPoint2; }
+ void setStartPoint2(QPointF p) { m_startPoint2 = p; }
+
+ bool accepted() const { return m_accepted; }
+ void setAccepted(bool a) { m_accepted = a; }
+
+private:
+ QPointF m_center;
+ QPointF m_startCenter;
+ QPointF m_lastCenter;
+ qreal m_scale;
+ qreal m_lastScale;
+ qreal m_angle;
+ qreal m_lastAngle;
+ qreal m_rotation;
+ QPointF m_point1;
+ QPointF m_point2;
+ QPointF m_startPoint1;
+ QPointF m_startPoint2;
+ bool m_accepted;
+};
+
+
+class QDeclarativeMouseEvent;
+class QDeclarativePinchAreaPrivate;
+class Q_AUTOTEST_EXPORT QDeclarativePinchArea : public QDeclarativeItem
+{
+ Q_OBJECT
+
+ Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
+ Q_PROPERTY(QDeclarativePinch *pinch READ pinch CONSTANT)
+
+public:
+ QDeclarativePinchArea(QDeclarativeItem *parent=0);
+ ~QDeclarativePinchArea();
+
+ bool isEnabled() const;
+ void setEnabled(bool);
+
+ QDeclarativePinch *pinch();
+
+Q_SIGNALS:
+ void enabledChanged();
+ void pinchStarted(QDeclarativePinchEvent *pinch);
+ void pinchChanged(QDeclarativePinchEvent *pinch);
+ void pinchFinished(QDeclarativePinchEvent *pinch);
+
+protected:
+ void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+ void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+ bool sceneEvent(QEvent *);
+ bool sendMouseEvent(QGraphicsSceneMouseEvent *event);
+ bool sceneEventFilter(QGraphicsItem *i, QEvent *e);
+ bool event(QEvent *);
+
+ virtual void geometryChanged(const QRectF &newGeometry,
+ const QRectF &oldGeometry);
+ virtual QVariant itemChange(GraphicsItemChange change, const QVariant& value);
+
+private:
+ void updatePinch();
+ void handlePress();
+ void handleRelease();
+
+private:
+ Q_DISABLE_COPY(QDeclarativePinchArea)
+ Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QDeclarativePinchArea)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QDeclarativePinch)
+QML_DECLARE_TYPE(QDeclarativePinchEvent)
+QML_DECLARE_TYPE(QDeclarativePinchArea)
+
+QT_END_HEADER
+
+#endif // QDECLARATIVEPINCHAREA_H
diff --git a/src/declarative/graphicsitems/qdeclarativepincharea_p_p.h b/src/declarative/graphicsitems/qdeclarativepincharea_p_p.h
new file mode 100644
index 0000000..b1cdf68
--- /dev/null
+++ b/src/declarative/graphicsitems/qdeclarativepincharea_p_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** 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 QtDeclarative module 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$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEPINCHAREA_P_H
+#define QDECLARATIVEPINCHAREA_P_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 <qdatetime.h>
+#include <qbasictimer.h>
+#include <qevent.h>
+#include <qgraphicssceneevent.h>
+#include "qdeclarativeitem_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativePinch;
+class QDeclarativePinchAreaPrivate : public QDeclarativeItemPrivate
+{
+ Q_DECLARE_PUBLIC(QDeclarativePinchArea)
+public:
+ QDeclarativePinchAreaPrivate()
+ : absorb(true), stealMouse(false), inPinch(false)
+ , pinchRejected(false), pinch(0)
+ {
+ }
+
+ ~QDeclarativePinchAreaPrivate();
+
+ void init()
+ {
+ Q_Q(QDeclarativePinchArea);
+ q->setAcceptedMouseButtons(Qt::LeftButton);
+ q->setAcceptTouchEvents(true);
+ q->setFiltersChildEvents(true);
+ }
+
+ bool absorb : 1;
+ bool stealMouse : 1;
+ bool inPinch : 1;
+ bool pinchRejected : 1;
+ QDeclarativePinch *pinch;
+ QPointF sceneStartPoint1;
+ QPointF sceneStartPoint2;
+ QPointF lastPoint1;
+ QPointF lastPoint2;
+ qreal pinchStartDist;
+ qreal pinchStartScale;
+ qreal pinchLastScale;
+ qreal pinchStartRotation;
+ qreal pinchStartAngle;
+ qreal pinchLastAngle;
+ QPointF sceneStartCenter;
+ QPointF pinchStartCenter;
+ QPointF sceneLastCenter;
+ QPointF pinchStartPos;
+ QList<QTouchEvent::TouchPoint> touchPoints;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDECLARATIVEPINCHAREA_P_H
diff --git a/src/declarative/graphicsitems/qdeclarativetext.cpp b/src/declarative/graphicsitems/qdeclarativetext.cpp
index 303b21c..cf11be6 100644
--- a/src/declarative/graphicsitems/qdeclarativetext.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetext.cpp
@@ -297,6 +297,8 @@ QSize QDeclarativeTextPrivate::setupTextLayout()
lineWidth = q->width();
QTextOption textOption = layout.textOption();
+ if (hAlign == QDeclarativeText::AlignJustify)
+ textOption.setAlignment(Qt::Alignment(hAlign));
textOption.setWrapMode(QTextOption::WrapMode(wrapMode));
layout.setTextOption(textOption);
@@ -325,7 +327,7 @@ QSize QDeclarativeTextPrivate::setupTextLayout()
height += line.height();
if (!cacheAllTextAsImage) {
- if (hAlign == QDeclarativeText::AlignLeft) {
+ if ((hAlign == QDeclarativeText::AlignLeft) || (hAlign == QDeclarativeText::AlignJustify)) {
x = 0;
} else if (hAlign == QDeclarativeText::AlignRight) {
x = layoutWidth - line.naturalTextWidth();
@@ -351,7 +353,7 @@ QPixmap QDeclarativeTextPrivate::textLayoutImage(bool drawStyle)
qreal x = 0;
for (int i = 0; i < layout.lineCount(); ++i) {
QTextLine line = layout.lineAt(i);
- if (hAlign == QDeclarativeText::AlignLeft) {
+ if ((hAlign == QDeclarativeText::AlignLeft) || (hAlign == QDeclarativeText::AlignJustify)) {
x = 0;
} else if (hAlign == QDeclarativeText::AlignRight) {
x = size.width() - line.naturalTextWidth();
@@ -898,8 +900,8 @@ void QDeclarativeText::setStyleColor(const QColor &color)
Sets the horizontal and vertical alignment of the text within the Text items
width and height. By default, the text is top-left aligned.
- The valid values for \c horizontalAlignment are \c Text.AlignLeft, \c Text.AlignRight and
- \c Text.AlignHCenter. The valid values for \c verticalAlignment are \c Text.AlignTop, \c Text.AlignBottom
+ The valid values for \c horizontalAlignment are \c Text.AlignLeft, \c Text.AlignRight, \c Text.AlignHCenter and
+ \c Text.AlignJustify. The valid values for \c verticalAlignment are \c Text.AlignTop, \c Text.AlignBottom
and \c Text.AlignVCenter.
Note that for a single line of text, the size of the text is the area of the text. In this common case,
@@ -1117,6 +1119,7 @@ QRectF QDeclarativeText::boundingRect() const
switch (d->hAlign) {
case AlignLeft:
+ case AlignJustify:
x = 0;
break;
case AlignRight:
diff --git a/src/declarative/graphicsitems/qdeclarativetext_p.h b/src/declarative/graphicsitems/qdeclarativetext_p.h
index 51434d5..49bff14 100644
--- a/src/declarative/graphicsitems/qdeclarativetext_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetext_p.h
@@ -82,7 +82,8 @@ public:
enum HAlignment { AlignLeft = Qt::AlignLeft,
AlignRight = Qt::AlignRight,
- AlignHCenter = Qt::AlignHCenter };
+ AlignHCenter = Qt::AlignHCenter,
+ AlignJustify = Qt::AlignJustify }; // ### VERSIONING: Only in QtQuick 1.1
enum VAlignment { AlignTop = Qt::AlignTop,
AlignBottom = Qt::AlignBottom,
AlignVCenter = Qt::AlignVCenter };
diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
index e05f4e4..f37fa62 100644
--- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
@@ -442,6 +442,7 @@ void QDeclarativeTextEdit::setSelectedTextColor(const QColor &color)
\o TextEdit.AlignLeft (default)
\o TextEdit.AlignRight
\o TextEdit.AlignHCenter
+ \o TextEdit.AlignJustify
\endlist
Valid values for \c verticalAlignment are:
diff --git a/src/declarative/graphicsitems/qdeclarativetextedit_p.h b/src/declarative/graphicsitems/qdeclarativetextedit_p.h
index 68fde3d..7f12c85 100644
--- a/src/declarative/graphicsitems/qdeclarativetextedit_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextedit_p.h
@@ -97,7 +97,8 @@ public:
enum HAlignment {
AlignLeft = Qt::AlignLeft,
AlignRight = Qt::AlignRight,
- AlignHCenter = Qt::AlignHCenter
+ AlignHCenter = Qt::AlignHCenter,
+ AlignJustify = Qt::AlignJustify // ### VERSIONING: Only in QtQuick 1.1
};
enum VAlignment {
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
index df103de..4649be8 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
@@ -361,6 +361,14 @@ void QDeclarativeTextInput::setReadOnly(bool ro)
emit readOnlyChanged(ro);
}
+/*!
+ \qmlproperty int TextInput::maximumLength
+ The maximum permitted length of the text in the TextInput.
+
+ If the text is too long, it is truncated at the limit.
+
+ By default, this property contains a value of 32767.
+*/
int QDeclarativeTextInput::maxLength() const
{
Q_D(const QDeclarativeTextInput);
diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
index 4f5213a..dd07067 100644
--- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
+++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
@@ -557,8 +557,9 @@ QDeclarativeVisualDataModelData::~QDeclarativeVisualDataModelData()
void QDeclarativeVisualDataModelData::ensureProperties()
{
QDeclarativeVisualDataModelPrivate *modelPriv = QDeclarativeVisualDataModelPrivate::get(m_model);
- if (modelPriv->m_metaDataCacheable && !modelPriv->m_metaDataCreated) {
- modelPriv->createMetaData();
+ if (modelPriv->m_metaDataCacheable) {
+ if (!modelPriv->m_metaDataCreated)
+ modelPriv->createMetaData();
if (modelPriv->m_metaDataCreated)
m_meta->setCached(true);
}
diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp
index a7fbf44..1ead6ce 100644
--- a/src/declarative/qml/qdeclarativebinding.cpp
+++ b/src/declarative/qml/qdeclarativebinding.cpp
@@ -46,9 +46,11 @@
#include "qdeclarativecontext.h"
#include "qdeclarativeinfo.h"
#include "private/qdeclarativecontext_p.h"
+#include "private/qdeclarativecompiler_p.h"
#include "private/qdeclarativedata_p.h"
#include "private/qdeclarativestringconverters_p.h"
#include "private/qdeclarativestate_p_p.h"
+#include "private/qdeclarativedebugtrace_p.h"
#include <QVariant>
#include <QtCore/qdebug.h>
@@ -232,6 +234,19 @@ QDeclarativeBinding::QDeclarativeBinding(void *data, QDeclarativeRefCount *rc, Q
setNotifyOnValueChanged(true);
}
+QDeclarativeBinding *
+QDeclarativeBinding::createBinding(Identifier id, QObject *obj, QDeclarativeContext *ctxt,
+ const QString &url, int lineNumber, QObject *parent)
+{
+ QDeclarativeContextData *ctxtdata = QDeclarativeContextData::get(ctxt);
+
+ QDeclarativeEnginePrivate *engine = QDeclarativeEnginePrivate::get(qmlEngine(obj));
+ QDeclarativeCompiledData *cdata = 0;
+ if (engine && ctxtdata && !ctxtdata->url.isEmpty())
+ cdata = engine->typeLoader.get(ctxtdata->url)->compiledData();
+ return cdata ? new QDeclarativeBinding((void*)cdata->datas.at(id).constData(), cdata, obj, ctxtdata, url, lineNumber, parent) : 0;
+}
+
QDeclarativeBinding::QDeclarativeBinding(const QString &str, QObject *obj, QDeclarativeContext *ctxt,
QObject *parent)
: QDeclarativeExpression(QDeclarativeContextData::get(ctxt), obj, str, *new QDeclarativeBindingPrivate)
@@ -266,6 +281,20 @@ QDeclarativeProperty QDeclarativeBinding::property() const
return d->property;
}
+class QDeclarativeBindingProfiler {
+public:
+ QDeclarativeBindingProfiler(QDeclarativeBinding *bind)
+ {
+ QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Binding);
+ QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Binding, bind->expression());
+ }
+
+ ~QDeclarativeBindingProfiler()
+ {
+ QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Binding);
+ }
+};
+
void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags)
{
Q_D(QDeclarativeBinding);
@@ -274,6 +303,7 @@ void QDeclarativeBinding::update(QDeclarativePropertyPrivate::WriteFlags flags)
return;
if (!d->updating) {
+ QDeclarativeBindingProfiler prof(this);
d->updating = true;
bool wasDeleted = false;
d->deleted = &wasDeleted;
diff --git a/src/declarative/qml/qdeclarativebinding_p.h b/src/declarative/qml/qdeclarativebinding_p.h
index 7823a3d..787a3b9 100644
--- a/src/declarative/qml/qdeclarativebinding_p.h
+++ b/src/declarative/qml/qdeclarativebinding_p.h
@@ -162,6 +162,9 @@ public:
virtual void update(QDeclarativePropertyPrivate::WriteFlags flags);
virtual QString expression() const;
+ typedef int Identifier;
+ static QDeclarativeBinding *createBinding(Identifier, QObject *, QDeclarativeContext *, const QString &, int, QObject *parent=0);
+
public Q_SLOTS:
void update() { update(QDeclarativePropertyPrivate::DontRemoveBinding); }
diff --git a/src/declarative/qml/qdeclarativeboundsignal.cpp b/src/declarative/qml/qdeclarativeboundsignal.cpp
index 6af3e05..030fb2c 100644
--- a/src/declarative/qml/qdeclarativeboundsignal.cpp
+++ b/src/declarative/qml/qdeclarativeboundsignal.cpp
@@ -49,6 +49,7 @@
#include "qdeclarative.h"
#include "qdeclarativecontext.h"
#include "private/qdeclarativeglobal_p.h"
+#include "private/qdeclarativedebugtrace_p.h"
#include <QtCore/qdebug.h>
@@ -165,6 +166,8 @@ QDeclarativeBoundSignal *QDeclarativeBoundSignal::cast(QObject *o)
int QDeclarativeBoundSignal::qt_metacall(QMetaObject::Call c, int id, void **a)
{
if (c == QMetaObject::InvokeMetaMethod && id == evaluateIdx) {
+ QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::HandlingSignal);
+ QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::HandlingSignal, QLatin1String(m_signal.signature()) + QLatin1String(": ") + (m_expression ? m_expression->expression() : ""));
m_isEvaluating = true;
if (!m_paramsValid) {
if (!m_signal.parameterTypes().isEmpty())
@@ -180,6 +183,7 @@ int QDeclarativeBoundSignal::qt_metacall(QMetaObject::Call c, int id, void **a)
}
if (m_params) m_params->clearValues();
m_isEvaluating = false;
+ QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::HandlingSignal);
return -1;
} else {
return QObject::qt_metacall(c, id, a);
diff --git a/src/declarative/qml/qdeclarativecompiledbindings.cpp b/src/declarative/qml/qdeclarativecompiledbindings.cpp
index 5c295b9..48f8b84 100644
--- a/src/declarative/qml/qdeclarativecompiledbindings.cpp
+++ b/src/declarative/qml/qdeclarativecompiledbindings.cpp
@@ -54,6 +54,7 @@
#include <private/qdeclarativeanchors_p_p.h>
#include <private/qdeclarativeglobal_p.h>
#include <private/qdeclarativefastproperties_p.h>
+#include <private/qdeclarativedebugtrace_p.h>
QT_BEGIN_NAMESPACE
@@ -302,7 +303,9 @@ void QDeclarativeCompiledBindingsPrivate::Binding::setEnabled(bool e, QDeclarati
void QDeclarativeCompiledBindingsPrivate::Binding::update(QDeclarativePropertyPrivate::WriteFlags flags)
{
+ QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Binding);
parent->run(this, flags);
+ QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Binding);
}
void QDeclarativeCompiledBindingsPrivate::Binding::destroy()
diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp
index df428b1..b2b0990 100644
--- a/src/declarative/qml/qdeclarativecompiler.cpp
+++ b/src/declarative/qml/qdeclarativecompiler.cpp
@@ -1894,14 +1894,22 @@ bool QDeclarativeCompiler::buildValueTypeProperty(QObject *type,
COMPILE_EXCEPTION(prop, tr("Unexpected object assignment"));
} else if (value->value.isScript()) {
// ### Check for writability
- BindingReference reference;
- reference.expression = value->value;
- reference.property = prop;
- reference.value = value;
- reference.bindingContext = ctxt;
- reference.bindingContext.owner++;
- addBindingReference(reference);
- value->type = Value::PropertyBinding;
+
+ //optimization for <Type>.<EnumValue> enum assignments
+ bool isEnumAssignment = false;
+ COMPILE_CHECK(testQualifiedEnumAssignment(p, obj, value, &isEnumAssignment));
+ if (isEnumAssignment) {
+ value->type = Value::Literal;
+ } else {
+ BindingReference reference;
+ reference.expression = value->value;
+ reference.property = prop;
+ reference.value = value;
+ reference.bindingContext = ctxt;
+ reference.bindingContext.owner++;
+ addBindingReference(reference);
+ value->type = Value::PropertyBinding;
+ }
} else {
COMPILE_CHECK(testLiteralAssignment(p, value));
value->type = Value::Literal;
@@ -2196,7 +2204,15 @@ bool QDeclarativeCompiler::testQualifiedEnumAssignment(const QMetaProperty &prop
QDeclarativeType *type = 0;
unit->imports().resolveType(typeName.toUtf8(), &type, 0, 0, 0, 0);
- if (!type || obj->typeName != type->qmlTypeName())
+ //handle enums on value types (where obj->typeName is empty)
+ QByteArray objTypeName = obj->typeName;
+ if (objTypeName.isEmpty()) {
+ QDeclarativeType *objType = toQmlType(obj);
+ if (objType)
+ objTypeName = objType->qmlTypeName();
+ }
+
+ if (!type || objTypeName != type->qmlTypeName())
return true;
QString enumValue = parts.at(1);
@@ -2246,6 +2262,35 @@ const QMetaObject *QDeclarativeCompiler::resolveType(const QByteArray& name) con
return qmltype->metaObject();
}
+// similar to logic of completeComponentBuild, but also sticks data
+// into datas at the end
+int QDeclarativeCompiler::rewriteBinding(const QString& expression, const QByteArray& name)
+{
+ QDeclarativeRewrite::RewriteBinding rewriteBinding;
+ rewriteBinding.setName('$' + name.mid(name.lastIndexOf('.') + 1));
+ bool isSharable = false;
+ QString rewrite = rewriteBinding(expression, 0, &isSharable);
+
+ quint32 length = rewrite.length();
+ quint32 pc;
+
+ if (isSharable) {
+ pc = output->cachedClosures.count();
+ pc |= 0x80000000;
+ output->cachedClosures.append(0);
+ } else {
+ pc = output->cachedPrograms.length();
+ output->cachedPrograms.append(0);
+ }
+
+ QByteArray compiledData =
+ QByteArray((const char *)&pc, sizeof(quint32)) +
+ QByteArray((const char *)&length, sizeof(quint32)) +
+ QByteArray((const char *)rewrite.constData(),
+ rewrite.length() * sizeof(QChar));
+
+ return output->indexForByteArray(compiledData);
+}
// Ensures that the dynamic meta specification on obj is valid
bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj)
@@ -2849,13 +2894,10 @@ bool QDeclarativeCompiler::completeComponentBuild()
// Pre-rewrite the expression
QString expression = binding.expression.asScript();
- // ### Optimize
- QDeclarativeRewrite::SharedBindingTester sharableTest;
- bool isSharable = sharableTest.isSharable(expression);
-
QDeclarativeRewrite::RewriteBinding rewriteBinding;
rewriteBinding.setName('$'+binding.property->name);
- expression = rewriteBinding(expression);
+ bool isSharable = false;
+ expression = rewriteBinding(binding.expression.asAST(), expression, &isSharable);
quint32 length = expression.length();
quint32 pc;
diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h
index 7d76ad9..bface8f 100644
--- a/src/declarative/qml/qdeclarativecompiler_p.h
+++ b/src/declarative/qml/qdeclarativecompiler_p.h
@@ -161,6 +161,7 @@ public:
int evaluateEnum(const QByteArray& script) const; // for QDeclarativeCustomParser::evaluateEnum
const QMetaObject *resolveType(const QByteArray& name) const; // for QDeclarativeCustomParser::resolveType
+ int rewriteBinding(const QString& expression, const QByteArray& name); // for QDeclarativeCustomParser::rewriteBinding
private:
static void reset(QDeclarativeCompiledData *);
diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp
index 77fc925..a8b1c3f 100644
--- a/src/declarative/qml/qdeclarativecomponent.cpp
+++ b/src/declarative/qml/qdeclarativecomponent.cpp
@@ -789,8 +789,10 @@ QObject * QDeclarativeComponentPrivate::begin(QDeclarativeContextData *parentCon
Q_ASSERT(!isRoot || state); // Either this isn't a root component, or a state data must be provided
Q_ASSERT((state != 0) ^ (errors != 0)); // One of state or errors (but not both) must be provided
- if (isRoot)
+ if (isRoot) {
QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Creating);
+ QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Creating, component->url);
+ }
QDeclarativeContextData *ctxt = new QDeclarativeContextData;
ctxt->isInternal = true;
diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h
index 6c14feb..6b71381 100644
--- a/src/declarative/qml/qdeclarativecontext_p.h
+++ b/src/declarative/qml/qdeclarativecontext_p.h
@@ -77,7 +77,6 @@ class QDeclarativeEngine;
class QDeclarativeExpression;
class QDeclarativeExpressionPrivate;
class QDeclarativeAbstractExpression;
-class QDeclarativeBinding_Id;
class QDeclarativeCompiledBindings;
class QDeclarativeContextData;
diff --git a/src/declarative/qml/qdeclarativecustomparser.cpp b/src/declarative/qml/qdeclarativecustomparser.cpp
index 97a6a00..58ffc56 100644
--- a/src/declarative/qml/qdeclarativecustomparser.cpp
+++ b/src/declarative/qml/qdeclarativecustomparser.cpp
@@ -304,5 +304,14 @@ const QMetaObject *QDeclarativeCustomParser::resolveType(const QByteArray& name)
return compiler->resolveType(name);
}
+/*!
+ Rewrites \a expression and returns an identifier that can be
+ used to construct the binding later. \a name
+ is used as the name of the rewritten function.
+*/
+QDeclarativeBinding::Identifier QDeclarativeCustomParser::rewriteBinding(const QString& expression, const QByteArray& name)
+{
+ return compiler->rewriteBinding(expression, name);
+}
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qdeclarativecustomparser_p.h b/src/declarative/qml/qdeclarativecustomparser_p.h
index c3f9dd2..9b419c2 100644
--- a/src/declarative/qml/qdeclarativecustomparser_p.h
+++ b/src/declarative/qml/qdeclarativecustomparser_p.h
@@ -56,6 +56,7 @@
#include "private/qdeclarativemetatype_p.h"
#include "qdeclarativeerror.h"
#include "private/qdeclarativeparser_p.h"
+#include "private/qdeclarativebinding_p.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qxmlstream.h>
@@ -140,6 +141,8 @@ protected:
const QMetaObject *resolveType(const QByteArray&) const;
+ QDeclarativeBinding::Identifier rewriteBinding(const QString&, const QByteArray&);
+
private:
QList<QDeclarativeError> exceptions;
QDeclarativeCompiler *compiler;
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp
index 201e675..3a5fe66 100644
--- a/src/declarative/qml/qdeclarativeengine.cpp
+++ b/src/declarative/qml/qdeclarativeengine.cpp
@@ -69,6 +69,7 @@
#include "private/qdeclarativetypenamecache_p.h"
#include "private/qdeclarativeinclude_p.h"
#include "private/qdeclarativenotifier_p.h"
+#include "private/qdeclarativedebugtrace_p.h"
#include <QtCore/qmetaobject.h>
#include <QScriptClass>
@@ -955,7 +956,8 @@ Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
QDeclarativeData *data = QDeclarativeData::get(object);
if (data && data->deferredComponent) {
-
+ QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Creating);
+ QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Creating, QLatin1String("Deferred Creation:") + object->metaObject()->className());
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(data->context->engine);
QDeclarativeComponentPrivate::ConstructionState state;
@@ -965,6 +967,7 @@ Q_AUTOTEST_EXPORT void qmlExecuteDeferred(QObject *object)
data->deferredComponent = 0;
QDeclarativeComponentPrivate::complete(ep, &state);
+ QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Creating);
}
}
diff --git a/src/declarative/qml/qdeclarativeenginedebug.cpp b/src/declarative/qml/qdeclarativeenginedebug.cpp
index e54f7d6..b6b4b49 100644
--- a/src/declarative/qml/qdeclarativeenginedebug.cpp
+++ b/src/declarative/qml/qdeclarativeenginedebug.cpp
@@ -52,6 +52,7 @@
#include "private/qdeclarativevaluetype_p.h"
#include "private/qdeclarativevmemetaobject_p.h"
#include "private/qdeclarativeexpression_p.h"
+#include "private/qdeclarativepropertychanges_p.h"
#include <QtCore/qdebug.h>
#include <QtCore/qmetaobject.h>
@@ -195,11 +196,6 @@ void QDeclarativeEngineDebugServer::buildObjectDump(QDataStream &message,
{
message << objectData(object);
- // Some children aren't added to an object until particular properties are read
- // - e.g. child state objects aren't added until the 'states' property is read -
- // but this should only affect internal objects that aren't shown by the
- // debugger anyway.
-
QObjectList children = object->children();
int childrenCount = children.count();
@@ -260,6 +256,18 @@ void QDeclarativeEngineDebugServer::buildObjectDump(QDataStream &message,
message << fakeProperties[ii];
}
+void QDeclarativeEngineDebugServer::prepareDeferredObjects(QObject *obj)
+{
+ qmlExecuteDeferred(obj);
+
+ QObjectList children = obj->children();
+ for (int ii = 0; ii < children.count(); ++ii) {
+ QObject *child = children.at(ii);
+ prepareDeferredObjects(child);
+ }
+
+}
+
void QDeclarativeEngineDebugServer::buildObjectList(QDataStream &message, QDeclarativeContext *ctxt)
{
QDeclarativeContextData *p = QDeclarativeContextData::get(ctxt);
@@ -300,6 +308,35 @@ void QDeclarativeEngineDebugServer::buildObjectList(QDataStream &message, QDecla
}
}
+void QDeclarativeEngineDebugServer::buildStatesList(QDeclarativeContext *ctxt, bool cleanList=false)
+{
+ if (cleanList)
+ m_allStates.clear();
+
+ QDeclarativeContextPrivate *ctxtPriv = QDeclarativeContextPrivate::get(ctxt);
+ for (int ii = 0; ii < ctxtPriv->instances.count(); ++ii) {
+ buildStatesList(ctxtPriv->instances.at(ii));
+ }
+
+ QDeclarativeContextData *child = QDeclarativeContextData::get(ctxt)->childContexts;
+ while (child) {
+ buildStatesList(child->asQDeclarativeContext());
+ child = child->nextChild;
+ }
+}
+
+void QDeclarativeEngineDebugServer::buildStatesList(QObject *obj)
+{
+ if (QDeclarativeState *state = dynamic_cast<QDeclarativeState *>(obj)) {
+ m_allStates.append(state);
+ }
+
+ QObjectList children = obj->children();
+ for (int ii = 0; ii < children.count(); ++ii) {
+ buildStatesList(children.at(ii));
+ }
+}
+
QDeclarativeEngineDebugServer::QDeclarativeObjectData
QDeclarativeEngineDebugServer::objectData(QObject *object)
{
@@ -378,8 +415,10 @@ void QDeclarativeEngineDebugServer::messageReceived(const QByteArray &message)
QDataStream rs(&reply, QIODevice::WriteOnly);
rs << QByteArray("LIST_OBJECTS_R") << queryId;
- if (engine)
+ if (engine) {
buildObjectList(rs, engine->rootContext());
+ buildStatesList(engine->rootContext(), true);
+ }
sendMessage(reply);
} else if (type == "FETCH_OBJECT") {
@@ -396,8 +435,11 @@ void QDeclarativeEngineDebugServer::messageReceived(const QByteArray &message)
QDataStream rs(&reply, QIODevice::WriteOnly);
rs << QByteArray("FETCH_OBJECT_R") << queryId;
- if (object)
+ if (object) {
+ if (recurse)
+ prepareDeferredObjects(object);
buildObjectDump(rs, object, recurse, dumpProperties);
+ }
sendMessage(reply);
} else if (type == "WATCH_OBJECT") {
@@ -497,26 +539,66 @@ void QDeclarativeEngineDebugServer::setBinding(int objectId,
{
QObject *object = objectForId(objectId);
QDeclarativeContext *context = qmlContext(object);
+ QByteArray propertyNameArray = propertyName.toUtf8();
if (object && context) {
-
QDeclarativeProperty property(object, propertyName, context);
- if (isLiteralValue) {
- property.write(expression);
- } else if (hasValidSignal(object, propertyName)) {
- QDeclarativeExpression *declarativeExpression = new QDeclarativeExpression(context, object, expression.toString());
- QDeclarativeExpression *oldExpression = QDeclarativePropertyPrivate::setSignalExpression(property, declarativeExpression);
- declarativeExpression->setSourceLocation(oldExpression->sourceFile(), oldExpression->lineNumber());
- } else if (property.isProperty()) {
- QDeclarativeBinding *binding = new QDeclarativeBinding(expression.toString(), object, context);
- binding->setTarget(property);
- binding->setNotifyOnValueChanged(true);
- QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::setBinding(property, binding);
- if (oldBinding)
- oldBinding->destroy();
- binding->update();
+ if (property.isValid()) {
+
+ bool inBaseState = true;
+
+ foreach(QWeakPointer<QDeclarativeState> statePointer, m_allStates) {
+ if (QDeclarativeState *state = statePointer.data()) {
+ // here we assume that the revert list on itself defines the base state
+ if ( state->isStateActive() && state->containsPropertyInRevertList(object, propertyNameArray) ) {
+ inBaseState = false;
+
+ QDeclarativeBinding *newBinding = 0;
+ if (!isLiteralValue) {
+ newBinding = new QDeclarativeBinding(expression.toString(), object, context);
+ newBinding->setTarget(property);
+ newBinding->setNotifyOnValueChanged(true);
+ }
+
+ state->changeBindingInRevertList(object,propertyNameArray, newBinding);
+
+ if (isLiteralValue)
+ state->changeValueInRevertList(object, propertyNameArray, expression);
+ }
+ }
+ }
+
+ if (inBaseState) {
+ if (isLiteralValue) {
+ property.write(expression);
+ } else if (hasValidSignal(object, propertyName)) {
+ QDeclarativeExpression *declarativeExpression = new QDeclarativeExpression(context, object, expression.toString());
+ QDeclarativeExpression *oldExpression = QDeclarativePropertyPrivate::setSignalExpression(property, declarativeExpression);
+ declarativeExpression->setSourceLocation(oldExpression->sourceFile(), oldExpression->lineNumber());
+ } else if (property.isProperty()) {
+ QDeclarativeBinding *binding = new QDeclarativeBinding(expression.toString(), object, context);
+ binding->setTarget(property);
+ binding->setNotifyOnValueChanged(true);
+ QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::setBinding(property, binding);
+ if (oldBinding)
+ oldBinding->destroy();
+ binding->update();
+ } else {
+ qWarning() << "QDeclarativeEngineDebugServer::setBinding: unable to set property" << propertyName << "on object" << object;
+ }
+ }
+
} else {
- qWarning() << "QDeclarativeEngineDebugServer::setBinding: unable to set property" << propertyName << "on object" << object;
+ // not a valid property
+ if (QDeclarativePropertyChanges *propertyChanges = dynamic_cast<QDeclarativePropertyChanges *>(object)) {
+ if (isLiteralValue) {
+ propertyChanges->changeValue(propertyName.toUtf8(),expression);
+ } else {
+ propertyChanges->changeExpression(propertyName.toUtf8(),expression.toString());
+ }
+ } else {
+ qWarning() << "QDeclarativeEngineDebugServer::setBinding: unable to set property" << propertyName << "on object" << object;
+ }
}
}
}
@@ -534,11 +616,31 @@ void QDeclarativeEngineDebugServer::resetBinding(int objectId, const QString &pr
QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::setBinding(property, 0);
if (oldBinding)
oldBinding->destroy();
+ }
+ if (property.isResettable()) {
+ // Note: this will reset the property in any case, without regard to states
+ // Right now almost no QDeclarativeItem has reset methods for its properties (with the
+ // notable exception of QDeclarativeAnchors), so this is not a big issue
+ // later on, setBinding does take states into account
+ property.reset();
} else {
- if (property.isResettable()) {
- property.reset();
+ // overwrite with default value
+ if (QDeclarativeType *objType = QDeclarativeMetaType::qmlType(object->metaObject())) {
+ if (QObject *emptyObject = objType->create()) {
+ if (emptyObject->property(propertyName.toLatin1()).isValid()) {
+ QVariant defaultValue = QDeclarativeProperty(emptyObject, propertyName).read();
+ if (defaultValue.isValid()) {
+ setBinding(objectId, propertyName, defaultValue, true);
+ }
+ }
+ delete emptyObject;
+ }
}
}
+ } else {
+ if (QDeclarativePropertyChanges *propertyChanges = dynamic_cast<QDeclarativePropertyChanges *>(object)) {
+ propertyChanges->removeProperty(propertyName.toUtf8());
+ }
}
}
}
diff --git a/src/declarative/qml/qdeclarativeenginedebug_p.h b/src/declarative/qml/qdeclarativeenginedebug_p.h
index 97b8121..65eb1ff 100644
--- a/src/declarative/qml/qdeclarativeenginedebug_p.h
+++ b/src/declarative/qml/qdeclarativeenginedebug_p.h
@@ -57,6 +57,7 @@
#include <QtCore/qurl.h>
#include <QtCore/qvariant.h>
+#include <QWeakPointer>
QT_BEGIN_NAMESPACE
@@ -64,6 +65,7 @@ class QDeclarativeEngine;
class QDeclarativeContext;
class QDeclarativeWatcher;
class QDataStream;
+class QDeclarativeState;
class QDeclarativeEngineDebugServer : public QDeclarativeDebugService
{
@@ -105,8 +107,11 @@ private Q_SLOTS:
void propertyChanged(int id, int objectId, const QMetaProperty &property, const QVariant &value);
private:
+ void prepareDeferredObjects(QObject *);
void buildObjectList(QDataStream &, QDeclarativeContext *);
void buildObjectDump(QDataStream &, QObject *, bool, bool);
+ void buildStatesList(QDeclarativeContext *, bool);
+ void buildStatesList(QObject *obj);
QDeclarativeObjectData objectData(QObject *);
QDeclarativeObjectProperty propertyData(QObject *, int);
QVariant valueContents(const QVariant &defaultValue) const;
@@ -116,6 +121,7 @@ private:
QList<QDeclarativeEngine *> m_engines;
QDeclarativeWatcher *m_watch;
+ QList<QWeakPointer<QDeclarativeState> > m_allStates;
};
Q_DECLARATIVE_PRIVATE_EXPORT QDataStream &operator<<(QDataStream &, const QDeclarativeEngineDebugServer::QDeclarativeObjectData &);
Q_DECLARATIVE_PRIVATE_EXPORT QDataStream &operator>>(QDataStream &, QDeclarativeEngineDebugServer::QDeclarativeObjectData &);
diff --git a/src/declarative/qml/qdeclarativerewrite.cpp b/src/declarative/qml/qdeclarativerewrite.cpp
index bc9a114..219674f 100644
--- a/src/declarative/qml/qdeclarativerewrite.cpp
+++ b/src/declarative/qml/qdeclarativerewrite.cpp
@@ -62,12 +62,17 @@ bool SharedBindingTester::isSharable(const QString &code)
if (!parser.statement())
return false;
+ return isSharable(parser.statement());
+}
+
+bool SharedBindingTester::isSharable(AST::Node *node)
+{
_sharable = true;
- AST::Node::acceptChild(parser.statement(), this);
+ AST::Node::acceptChild(node, this);
return _sharable;
}
-QString RewriteBinding::operator()(const QString &code, bool *ok)
+QString RewriteBinding::operator()(const QString &code, bool *ok, bool *sharable)
{
Engine engine;
NodePool pool(QString(), &engine);
@@ -80,10 +85,63 @@ QString RewriteBinding::operator()(const QString &code, bool *ok)
return QString();
} else {
if (ok) *ok = true;
+ if (sharable) {
+ SharedBindingTester tester;
+ *sharable = tester.isSharable(parser.statement());
+ }
}
return rewrite(code, 0, parser.statement());
}
+QString RewriteBinding::operator()(QDeclarativeJS::AST::Node *node, const QString &code, bool *sharable)
+{
+ if (!node)
+ return code;
+
+ if (sharable) {
+ SharedBindingTester tester;
+ *sharable = tester.isSharable(node);
+ }
+
+ QDeclarativeJS::AST::ExpressionNode *expression = node->expressionCast();
+ QDeclarativeJS::AST::Statement *statement = node->statementCast();
+ if(!expression && !statement)
+ return code;
+
+ TextWriter w;
+ _writer = &w;
+ _position = expression ? expression->firstSourceLocation().begin() : statement->firstSourceLocation().begin();
+ _inLoop = 0;
+
+ accept(node);
+
+ unsigned startOfStatement = 0;
+ unsigned endOfStatement = (expression ? expression->lastSourceLocation().end() : statement->lastSourceLocation().end()) - _position;
+
+ QString startString = QLatin1String("(function ") + QString::fromUtf8(_name) + QLatin1String("() { ");
+ if (expression)
+ startString += QLatin1String("return ");
+ _writer->replace(startOfStatement, 0, startString);
+ _writer->replace(endOfStatement, 0, QLatin1String(" })"));
+
+ if (rewriteDump()) {
+ qWarning() << "=============================================================";
+ qWarning() << "Rewrote:";
+ qWarning() << qPrintable(code);
+ }
+
+ QString codeCopy = code;
+ w.write(&codeCopy);
+
+ if (rewriteDump()) {
+ qWarning() << "To:";
+ qWarning() << qPrintable(code);
+ qWarning() << "=============================================================";
+ }
+
+ return codeCopy;
+}
+
void RewriteBinding::accept(AST::Node *node)
{
AST::Node::acceptChild(node, this);
diff --git a/src/declarative/qml/qdeclarativerewrite_p.h b/src/declarative/qml/qdeclarativerewrite_p.h
index 6f3c46e..310ef3c 100644
--- a/src/declarative/qml/qdeclarativerewrite_p.h
+++ b/src/declarative/qml/qdeclarativerewrite_p.h
@@ -68,6 +68,7 @@ class SharedBindingTester : protected AST::Visitor
bool _sharable;
public:
bool isSharable(const QString &code);
+ bool isSharable(AST::Node *Node);
virtual bool visit(AST::FunctionDeclaration *) { _sharable = false; return false; }
virtual bool visit(AST::FunctionExpression *) { _sharable = false; return false; }
@@ -81,7 +82,8 @@ class RewriteBinding: protected AST::Visitor
QByteArray _name;
public:
- QString operator()(const QString &code, bool *ok = 0);
+ QString operator()(const QString &code, bool *ok = 0, bool *sharable = 0);
+ QString operator()(QDeclarativeJS::AST::Node *node, const QString &code, bool *sharable = 0);
//name of the function: used for the debugger
void setName(const QByteArray &name) { _name = name; }
diff --git a/src/declarative/qml/qdeclarativestringconverters.cpp b/src/declarative/qml/qdeclarativestringconverters.cpp
index 7534a2c..55fae87 100644
--- a/src/declarative/qml/qdeclarativestringconverters.cpp
+++ b/src/declarative/qml/qdeclarativestringconverters.cpp
@@ -136,7 +136,7 @@ QVariant QDeclarativeStringConverters::variantFromString(const QString &s, int p
QColor QDeclarativeStringConverters::colorFromString(const QString &s, bool *ok)
{
- if (s.startsWith(QLatin1Char('#')) && s.length() == 9) {
+ if (s.length() == 9 && s.startsWith(QLatin1Char('#'))) {
uchar a = fromHex(s, 1);
uchar r = fromHex(s, 3);
uchar g = fromHex(s, 5);
@@ -144,9 +144,7 @@ QColor QDeclarativeStringConverters::colorFromString(const QString &s, bool *ok)
if (ok) *ok = true;
return QColor(r, g, b, a);
} else {
- QColor rv;
- if (s.startsWith(QLatin1Char('#')) || QColor::colorNames().contains(s.toLower()))
- rv = QColor(s);
+ QColor rv(s);
if (ok) *ok = rv.isValid();
return rv;
}
diff --git a/src/declarative/qml/qdeclarativetypeloader.cpp b/src/declarative/qml/qdeclarativetypeloader.cpp
index c015519..f42e8a7 100644
--- a/src/declarative/qml/qdeclarativetypeloader.cpp
+++ b/src/declarative/qml/qdeclarativetypeloader.cpp
@@ -45,6 +45,7 @@
#include <private/qdeclarativecompiler_p.h>
#include <private/qdeclarativecomponent_p.h>
#include <private/qdeclarativeglobal_p.h>
+#include <private/qdeclarativedebugtrace_p.h>
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtCore/qdebug.h>
@@ -895,10 +896,12 @@ void QDeclarativeTypeData::downloadProgressChanged(qreal p)
void QDeclarativeTypeData::compile()
{
Q_ASSERT(m_compiledData == 0);
+ QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Compiling);
m_compiledData = new QDeclarativeCompiledData(typeLoader()->engine());
m_compiledData->url = m_imports.baseUrl();
m_compiledData->name = m_compiledData->url.toString();
+ QDeclarativeDebugTrace::rangeData(QDeclarativeDebugTrace::Compiling, m_compiledData->name);
QDeclarativeCompiler compiler;
if (!compiler.compile(typeLoader()->engine(), this, m_compiledData)) {
@@ -906,6 +909,7 @@ void QDeclarativeTypeData::compile()
m_compiledData->release();
m_compiledData = 0;
}
+ QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Compiling);
}
void QDeclarativeTypeData::resolveTypes()
diff --git a/src/declarative/qml/qdeclarativetypenamescriptclass.cpp b/src/declarative/qml/qdeclarativetypenamescriptclass.cpp
index cba7b4a..e93aae2 100644
--- a/src/declarative/qml/qdeclarativetypenamescriptclass.cpp
+++ b/src/declarative/qml/qdeclarativetypenamescriptclass.cpp
@@ -109,9 +109,8 @@ QDeclarativeTypeNameScriptClass::queryProperty(Object *obj, const Identifier &na
} else if (data->type) {
- QString strName = toString(name);
-
- if (strName.at(0).isUpper()) {
+ if (startsWithUpper(name)) {
+ QString strName = toString(name);
// Must be an enum
if (data->mode == IncludeEnums) {
// ### Optimize
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index 66b69f9..bf9e54a 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -55,7 +55,8 @@ SOURCES += \
$$PWD/qdeclarativedirparser.cpp \
$$PWD/qdeclarativeextensionplugin.cpp \
$$PWD/qdeclarativeimport.cpp \
- $$PWD/qdeclarativelist.cpp
+ $$PWD/qdeclarativelist.cpp \
+ $$PWD/qperformancetimer.cpp
HEADERS += \
$$PWD/qdeclarativeparser_p.h \
@@ -129,8 +130,12 @@ HEADERS += \
$$PWD/qdeclarativedirparser_p.h \
$$PWD/qdeclarativeextensioninterface.h \
$$PWD/qdeclarativeimport_p.h \
- $$PWD/qdeclarativeextensionplugin.h
+ $$PWD/qdeclarativeextensionplugin.h \
+ $$PWD/qperformancetimer_p.h
QT += sql
include(parser/parser.pri)
include(rewriter/rewriter.pri)
+
+# mirrors logic in corelib/kernel/kernel.pri
+unix:!symbian: contains(QT_CONFIG, clock-gettime):include($$QT_SOURCE_TREE/config.tests/unix/clock-gettime/clock-gettime.pri)
diff --git a/src/declarative/qml/qperformancetimer.cpp b/src/declarative/qml/qperformancetimer.cpp
new file mode 100644
index 0000000..1d7ca80
--- /dev/null
+++ b/src/declarative/qml/qperformancetimer.cpp
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** 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 QtDeclarative module 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$
+**
+****************************************************************************/
+
+#include "qperformancetimer_p.h"
+
+#if defined(Q_OS_MAC)
+#include <sys/time.h>
+#include <unistd.h>
+#include <mach/mach_time.h>
+#elif defined(Q_OS_UNIX)
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+#elif defined(Q_OS_SYMBIAN)
+#include <e32std.h>
+#include <sys/time.h>
+#include <hal.h>
+#elif defined(Q_OS_WIN)
+#include <windows.h>
+#endif
+
+// mac/unix code heavily copied from QElapsedTimer
+
+QT_BEGIN_NAMESPACE
+
+////////////////////////////// Mac //////////////////////////////
+#if defined(Q_OS_MAC)
+
+static mach_timebase_info_data_t info = {0,0};
+static qint64 absoluteToNSecs(qint64 cpuTime)
+{
+ if (info.denom == 0)
+ mach_timebase_info(&info);
+ qint64 nsecs = cpuTime * info.numer / info.denom;
+ return nsecs;
+}
+
+void QPerformanceTimer::start()
+{
+ t1 = mach_absolute_time();
+}
+
+qint64 QPerformanceTimer::elapsed() const
+{
+ uint64_t cpu_time = mach_absolute_time();
+ return absoluteToNSecs(cpu_time - t1);
+}
+
+////////////////////////////// Unix //////////////////////////////
+#elif defined(Q_OS_UNIX)
+
+#if defined(QT_NO_CLOCK_MONOTONIC) || defined(QT_BOOTSTRAPPED)
+// turn off the monotonic clock
+# ifdef _POSIX_MONOTONIC_CLOCK
+# undef _POSIX_MONOTONIC_CLOCK
+# endif
+# define _POSIX_MONOTONIC_CLOCK -1
+#endif
+
+#if (_POSIX_MONOTONIC_CLOCK-0 != 0)
+static const bool monotonicClockChecked = true;
+static const bool monotonicClockAvailable = _POSIX_MONOTONIC_CLOCK > 0;
+#else
+static int monotonicClockChecked = false;
+static int monotonicClockAvailable = false;
+#endif
+
+#ifdef Q_CC_GNU
+# define is_likely(x) __builtin_expect((x), 1)
+#else
+# define is_likely(x) (x)
+#endif
+#define load_acquire(x) ((volatile const int&)(x))
+#define store_release(x,v) ((volatile int&)(x) = (v))
+
+static void unixCheckClockType()
+{
+#if (_POSIX_MONOTONIC_CLOCK-0 == 0)
+ if (is_likely(load_acquire(monotonicClockChecked)))
+ return;
+
+# if defined(_SC_MONOTONIC_CLOCK)
+ // detect if the system support monotonic timers
+ long x = sysconf(_SC_MONOTONIC_CLOCK);
+ store_release(monotonicClockAvailable, x >= 200112L);
+# endif
+
+ store_release(monotonicClockChecked, true);
+#endif
+}
+
+static inline void do_gettime(qint64 *sec, qint64 *frac)
+{
+#if (_POSIX_MONOTONIC_CLOCK-0 >= 0)
+ unixCheckClockType();
+ if (is_likely(monotonicClockAvailable)) {
+ timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ *sec = ts.tv_sec;
+ *frac = ts.tv_nsec;
+ return;
+ }
+#endif
+ *sec = 0;
+ *frac = 0;
+}
+
+void QPerformanceTimer::start()
+{
+ do_gettime(&t1, &t2);
+}
+
+qint64 QPerformanceTimer::elapsed() const
+{
+ qint64 sec, frac;
+ do_gettime(&sec, &frac);
+ sec = sec - t1;
+ frac = frac - t2;
+
+ return sec * Q_INT64_C(1000000000) + frac;
+}
+
+////////////////////////////// Symbian //////////////////////////////
+#elif defined(Q_OS_SYMBIAN)
+
+static qint64 getTimeFromTick(quint64 elapsed)
+{
+ static TInt freq;
+ if (!freq)
+ HAL::Get(HALData::EFastCounterFrequency, freq);
+
+ // ### not sure on units
+ return elapsed / freq;
+}
+
+void QPerformanceTimer::start()
+{
+ t1 = User::FastCounter();
+}
+
+qint64 QPerformanceTimer::elapsed() const
+{
+ return getTimeFromTick(User::FastCounter() - t1);
+}
+
+////////////////////////////// Windows //////////////////////////////
+#elif defined(Q_OS_WIN)
+
+static qint64 getTimeFromTick(quint64 elapsed)
+{
+ static LARGE_INTEGER freq;
+ if (!freq.QuadPart)
+ QueryPerformanceFrequency(&freq);
+ return 1000000000 * elapsed / freq.QuadPart;
+}
+
+void QPerformanceTimer::start()
+{
+ LARGE_INTEGER li;
+ QueryPerformanceCounter(&li);
+ t1 = li.QuadPart;
+}
+
+qint64 QPerformanceTimer::elapsed() const
+{
+ LARGE_INTEGER li;
+ QueryPerformanceCounter(&li);
+ return getTimeFromTick(li.QuadPart - t1);
+}
+
+////////////////////////////// Default //////////////////////////////
+#else
+
+// default implementation (no hi-perf timer) does nothing
+void QPerformanceTimer::start()
+{
+}
+
+qint64 QPerformanceTimer::elapsed() const
+{
+ return 0;
+}
+
+#endif
+
+QT_END_NAMESPACE
+
+
diff --git a/src/declarative/qml/qperformancetimer_p.h b/src/declarative/qml/qperformancetimer_p.h
new file mode 100644
index 0000000..14310bf
--- /dev/null
+++ b/src/declarative/qml/qperformancetimer_p.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** 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 QtDeclarative module 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$
+**
+****************************************************************************/
+
+#ifndef QPERFORMANCETIMER_P_H
+#define QPERFORMANCETIMER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of moc. This header file may change from version to version without notice,
+// or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class Q_AUTOTEST_EXPORT QPerformanceTimer
+{
+public:
+ void start();
+ qint64 elapsed() const;
+
+private:
+ qint64 t1;
+ qint64 t2;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPERFORMANCETIMER_P_H
diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp
index 398480e..538e8af 100644
--- a/src/declarative/util/qdeclarativelistmodel.cpp
+++ b/src/declarative/util/qdeclarativelistmodel.cpp
@@ -1450,6 +1450,8 @@ void ModelNode::setObjectValue(const QScriptValue& valuemap, bool writeToCache)
if (v.isArray()) {
value->isArray = true;
value->setListValue(v);
+ if (writeToCache && objectCache)
+ objectCache->setValue(it.name().toUtf8(), QVariant::fromValue(value->model(m_model)));
} else {
value->values << v.toVariant();
if (writeToCache && objectCache)
diff --git a/src/declarative/util/qdeclarativepixmapcache.cpp b/src/declarative/util/qdeclarativepixmapcache.cpp
index 380d9bc..7c0a7f0 100644
--- a/src/declarative/util/qdeclarativepixmapcache.cpp
+++ b/src/declarative/util/qdeclarativepixmapcache.cpp
@@ -959,20 +959,20 @@ QRect QDeclarativePixmap::rect() const
void QDeclarativePixmap::load(QDeclarativeEngine *engine, const QUrl &url)
{
- load(engine, url, QSize(), false);
+ load(engine, url, QSize(), QDeclarativePixmap::Cached);
}
-void QDeclarativePixmap::load(QDeclarativeEngine *engine, const QUrl &url, bool async)
+void QDeclarativePixmap::load(QDeclarativeEngine *engine, const QUrl &url, QDeclarativePixmap::Options options)
{
- load(engine, url, QSize(), async);
+ load(engine, url, QSize(), options);
}
void QDeclarativePixmap::load(QDeclarativeEngine *engine, const QUrl &url, const QSize &size)
{
- load(engine, url, size, false);
+ load(engine, url, size, QDeclarativePixmap::Cached);
}
-void QDeclarativePixmap::load(QDeclarativeEngine *engine, const QUrl &url, const QSize &requestSize, bool async)
+void QDeclarativePixmap::load(QDeclarativeEngine *engine, const QUrl &url, const QSize &requestSize, QDeclarativePixmap::Options options)
{
if (d) { d->release(); d = 0; }
@@ -982,19 +982,20 @@ void QDeclarativePixmap::load(QDeclarativeEngine *engine, const QUrl &url, const
QHash<QDeclarativePixmapKey, QDeclarativePixmapData *>::Iterator iter = store->m_cache.find(key);
if (iter == store->m_cache.end()) {
- if (async) {
+ if (options & QDeclarativePixmap::Asynchronous) {
// pixmaps can only be loaded synchronously
if (url.scheme() == QLatin1String("image")
&& QDeclarativeEnginePrivate::get(engine)->getImageProviderType(url) == QDeclarativeImageProvider::Pixmap) {
- async = false;
+ options &= ~QDeclarativePixmap::Asynchronous;
}
}
- if (!async) {
+ if (!(options & QDeclarativePixmap::Asynchronous)) {
bool ok = false;
d = createPixmapDataSync(engine, url, requestSize, &ok);
if (ok) {
- d->addToCache();
+ if (options & QDeclarativePixmap::Cached)
+ d->addToCache();
return;
}
if (d) // loadable, but encountered error while loading
@@ -1007,7 +1008,8 @@ void QDeclarativePixmap::load(QDeclarativeEngine *engine, const QUrl &url, const
QDeclarativePixmapReader *reader = QDeclarativePixmapReader::instance(engine);
d = new QDeclarativePixmapData(url, requestSize);
- d->addToCache();
+ if (options & QDeclarativePixmap::Cached)
+ d->addToCache();
d->reply = reader->getImage(d);
} else {
diff --git a/src/declarative/util/qdeclarativepixmapcache_p.h b/src/declarative/util/qdeclarativepixmapcache_p.h
index 2e83cc4..9e1016f 100644
--- a/src/declarative/util/qdeclarativepixmapcache_p.h
+++ b/src/declarative/util/qdeclarativepixmapcache_p.h
@@ -66,6 +66,12 @@ public:
enum Status { Null, Ready, Error, Loading };
+ enum Option {
+ Asynchronous = 0x00000001,
+ Cached = 0x00000002
+ };
+ Q_DECLARE_FLAGS(Options, Option)
+
bool isNull() const;
bool isReady() const;
bool isError() const;
@@ -85,9 +91,9 @@ public:
inline operator const QPixmap &() const;
void load(QDeclarativeEngine *, const QUrl &);
- void load(QDeclarativeEngine *, const QUrl &, bool);
+ void load(QDeclarativeEngine *, const QUrl &, QDeclarativePixmap::Options options);
void load(QDeclarativeEngine *, const QUrl &, const QSize &);
- void load(QDeclarativeEngine *, const QUrl &, const QSize &, bool);
+ void load(QDeclarativeEngine *, const QUrl &, const QSize &, QDeclarativePixmap::Options options);
void clear();
void clear(QObject *);
@@ -107,6 +113,8 @@ inline QDeclarativePixmap::operator const QPixmap &() const
return pixmap();
}
+Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativePixmap::Options)
+
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/declarative/util/qdeclarativepropertychanges.cpp b/src/declarative/util/qdeclarativepropertychanges.cpp
index 8d01b80..400803e 100644
--- a/src/declarative/util/qdeclarativepropertychanges.cpp
+++ b/src/declarative/util/qdeclarativepropertychanges.cpp
@@ -42,6 +42,9 @@
#include "private/qdeclarativepropertychanges_p.h"
#include "private/qdeclarativeopenmetaobject_p.h"
+#include "private/qdeclarativerewrite_p.h"
+#include "private/qdeclarativeengine_p.h"
+#include "private/qdeclarativecompiler_p.h"
#include <qdeclarativeinfo.h>
#include <qdeclarativecustomparser_p.h>
@@ -219,6 +222,7 @@ public:
QList<QPair<QByteArray, QVariant> > properties;
QList<QPair<QByteArray, QDeclarativeExpression *> > expressions;
+ QList<QDeclarativeBinding::Identifier> ids;
QList<QDeclarativeReplaceSignalHandler*> signalReplacements;
QDeclarativeProperty property(const QByteArray &);
@@ -267,6 +271,7 @@ QDeclarativePropertyChangesParser::compile(const QList<QDeclarativeCustomParserP
QDeclarativeParser::Variant v = qvariant_cast<QDeclarativeParser::Variant>(data.at(ii).second);
QVariant var;
bool isScript = v.isScript();
+ QDeclarativeBinding::Identifier id;
switch(v.type()) {
case QDeclarativeParser::Variant::Boolean:
var = QVariant(v.asBoolean());
@@ -280,10 +285,17 @@ QDeclarativePropertyChangesParser::compile(const QList<QDeclarativeCustomParserP
case QDeclarativeParser::Variant::Invalid:
case QDeclarativeParser::Variant::Script:
var = QVariant(v.asScript());
+ {
+ // Pre-rewrite the expression
+ QString expression = v.asScript();
+ id = rewriteBinding(expression, data.at(ii).first); //### recreates the AST, which is slow
+ }
break;
}
ds << data.at(ii).first << isScript << var;
+ if (isScript)
+ ds << id;
}
return rv;
@@ -303,9 +315,12 @@ void QDeclarativePropertyChangesPrivate::decode()
QByteArray name;
bool isScript;
QVariant data;
+ QDeclarativeBinding::Identifier id;
ds >> name;
ds >> isScript;
ds >> data;
+ if (isScript)
+ ds >> id;
QDeclarativeProperty prop = property(name); //### better way to check for signal property?
if (prop.type() & QDeclarativeProperty::SignalProperty) {
@@ -323,6 +338,7 @@ void QDeclarativePropertyChangesPrivate::decode()
if (ddata && ddata->outerContext && !ddata->outerContext->url.isEmpty())
expression->setSourceLocation(ddata->outerContext->url.toString(), ddata->lineNumber);
expressions << qMakePair(name, expression);
+ ids << id;
} else {
properties << qMakePair(name, data);
}
@@ -452,10 +468,14 @@ QDeclarativePropertyChanges::ActionList QDeclarativePropertyChanges::actions()
a.toValue = d->expressions.at(ii).second->evaluate();
} else {
QDeclarativeExpression *e = d->expressions.at(ii).second;
- QDeclarativeBinding *newBinding =
- new QDeclarativeBinding(e->expression(), object(), qmlContext(this));
+
+ QDeclarativeBinding::Identifier id = d->ids.at(ii);
+ QDeclarativeBinding *newBinding = QDeclarativeBinding::createBinding(id, object(), qmlContext(this), e->sourceFile(), e->lineNumber());
+ if (!newBinding) {
+ newBinding = new QDeclarativeBinding(e->expression(), object(), qmlContext(this));
+ newBinding->setSourceLocation(e->sourceFile(), e->lineNumber());
+ }
newBinding->setTarget(prop);
- newBinding->setSourceLocation(e->sourceFile(), e->lineNumber());
a.toBinding = newBinding;
a.deletableToBinding = true;
}
diff --git a/src/declarative/util/qdeclarativestate.cpp b/src/declarative/util/qdeclarativestate.cpp
index 3915485..6925e03 100644
--- a/src/declarative/util/qdeclarativestate.cpp
+++ b/src/declarative/util/qdeclarativestate.cpp
@@ -66,7 +66,7 @@ QDeclarativeAction::QDeclarativeAction()
QDeclarativeAction::QDeclarativeAction(QObject *target, const QString &propertyName,
const QVariant &value)
: restore(true), actionDone(false), reverseEvent(false), deletableToBinding(false),
- property(target, propertyName), toValue(value),
+ property(target, propertyName, qmlEngine(target)), toValue(value),
fromBinding(0), event(0),
specifiedObject(target), specifiedProperty(propertyName)
{
diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp
index d1d7822..b606ff3 100644
--- a/src/declarative/util/qdeclarativestateoperations.cpp
+++ b/src/declarative/util/qdeclarativestateoperations.cpp
@@ -83,6 +83,13 @@ public:
QDeclarativeNullableValue<QDeclarativeScriptString> scaleString;
QDeclarativeNullableValue<QDeclarativeScriptString> rotationString;
+ QDeclarativeNullableValue<qreal> x;
+ QDeclarativeNullableValue<qreal> y;
+ QDeclarativeNullableValue<qreal> width;
+ QDeclarativeNullableValue<qreal> height;
+ QDeclarativeNullableValue<qreal> scale;
+ QDeclarativeNullableValue<qreal> rotation;
+
void doChange(QDeclarativeItem *targetParent, QDeclarativeItem *stackBefore = 0);
};
@@ -213,10 +220,21 @@ QDeclarativeScriptString QDeclarativeParentChange::x() const
return d->xString.value;
}
+void tryReal(QDeclarativeNullableValue<qreal> &value, const QString &string)
+{
+ bool ok = false;
+ qreal realValue = string.toFloat(&ok);
+ if (ok)
+ value = realValue;
+ else
+ value.invalidate();
+}
+
void QDeclarativeParentChange::setX(QDeclarativeScriptString x)
{
Q_D(QDeclarativeParentChange);
d->xString = x;
+ tryReal(d->x, x.script());
}
bool QDeclarativeParentChange::xIsSet() const
@@ -235,6 +253,7 @@ void QDeclarativeParentChange::setY(QDeclarativeScriptString y)
{
Q_D(QDeclarativeParentChange);
d->yString = y;
+ tryReal(d->y, y.script());
}
bool QDeclarativeParentChange::yIsSet() const
@@ -253,6 +272,7 @@ void QDeclarativeParentChange::setWidth(QDeclarativeScriptString width)
{
Q_D(QDeclarativeParentChange);
d->widthString = width;
+ tryReal(d->width, width.script());
}
bool QDeclarativeParentChange::widthIsSet() const
@@ -271,6 +291,7 @@ void QDeclarativeParentChange::setHeight(QDeclarativeScriptString height)
{
Q_D(QDeclarativeParentChange);
d->heightString = height;
+ tryReal(d->height, height.script());
}
bool QDeclarativeParentChange::heightIsSet() const
@@ -289,6 +310,7 @@ void QDeclarativeParentChange::setScale(QDeclarativeScriptString scale)
{
Q_D(QDeclarativeParentChange);
d->scaleString = scale;
+ tryReal(d->scale, scale.script());
}
bool QDeclarativeParentChange::scaleIsSet() const
@@ -307,6 +329,7 @@ void QDeclarativeParentChange::setRotation(QDeclarativeScriptString rotation)
{
Q_D(QDeclarativeParentChange);
d->rotationString = rotation;
+ tryReal(d->rotation, rotation.script());
}
bool QDeclarativeParentChange::rotationIsSet() const
@@ -367,16 +390,15 @@ QDeclarativeStateOperation::ActionList QDeclarativeParentChange::actions()
a.event = this;
actions << a;
+ QDeclarativeContext *ctxt = qmlContext(this);
+
if (d->xString.isValid()) {
- bool ok = false;
- QString script = d->xString.value.script();
- qreal x = script.toFloat(&ok);
- if (ok) {
- QDeclarativeAction xa(d->target, QLatin1String("x"), x);
+ if (d->x.isValid()) {
+ QDeclarativeAction xa(d->target, QLatin1String("x"), ctxt, d->x.value);
actions << xa;
} else {
- QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
- newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("x")));
+ QDeclarativeBinding *newBinding = new QDeclarativeBinding(d->xString.value.script(), d->target, ctxt);
+ newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("x"), ctxt));
QDeclarativeAction xa;
xa.property = newBinding->property();
xa.toBinding = newBinding;
@@ -387,15 +409,12 @@ QDeclarativeStateOperation::ActionList QDeclarativeParentChange::actions()
}
if (d->yString.isValid()) {
- bool ok = false;
- QString script = d->yString.value.script();
- qreal y = script.toFloat(&ok);
- if (ok) {
- QDeclarativeAction ya(d->target, QLatin1String("y"), y);
+ if (d->y.isValid()) {
+ QDeclarativeAction ya(d->target, QLatin1String("y"), ctxt, d->y.value);
actions << ya;
} else {
- QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
- newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("y")));
+ QDeclarativeBinding *newBinding = new QDeclarativeBinding(d->yString.value.script(), d->target, ctxt);
+ newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("y"), ctxt));
QDeclarativeAction ya;
ya.property = newBinding->property();
ya.toBinding = newBinding;
@@ -406,15 +425,12 @@ QDeclarativeStateOperation::ActionList QDeclarativeParentChange::actions()
}
if (d->scaleString.isValid()) {
- bool ok = false;
- QString script = d->scaleString.value.script();
- qreal scale = script.toFloat(&ok);
- if (ok) {
- QDeclarativeAction sa(d->target, QLatin1String("scale"), scale);
+ if (d->scale.isValid()) {
+ QDeclarativeAction sa(d->target, QLatin1String("scale"), ctxt, d->scale.value);
actions << sa;
} else {
- QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
- newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("scale")));
+ QDeclarativeBinding *newBinding = new QDeclarativeBinding(d->scaleString.value.script(), d->target, ctxt);
+ newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("scale"), ctxt));
QDeclarativeAction sa;
sa.property = newBinding->property();
sa.toBinding = newBinding;
@@ -425,15 +441,12 @@ QDeclarativeStateOperation::ActionList QDeclarativeParentChange::actions()
}
if (d->rotationString.isValid()) {
- bool ok = false;
- QString script = d->rotationString.value.script();
- qreal rotation = script.toFloat(&ok);
- if (ok) {
- QDeclarativeAction ra(d->target, QLatin1String("rotation"), rotation);
+ if (d->rotation.isValid()) {
+ QDeclarativeAction ra(d->target, QLatin1String("rotation"), ctxt, d->rotation.value);
actions << ra;
} else {
- QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
- newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("rotation")));
+ QDeclarativeBinding *newBinding = new QDeclarativeBinding(d->rotationString.value.script(), d->target, ctxt);
+ newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("rotation"), ctxt));
QDeclarativeAction ra;
ra.property = newBinding->property();
ra.toBinding = newBinding;
@@ -444,15 +457,12 @@ QDeclarativeStateOperation::ActionList QDeclarativeParentChange::actions()
}
if (d->widthString.isValid()) {
- bool ok = false;
- QString script = d->widthString.value.script();
- qreal width = script.toFloat(&ok);
- if (ok) {
- QDeclarativeAction wa(d->target, QLatin1String("width"), width);
+ if (d->width.isValid()) {
+ QDeclarativeAction wa(d->target, QLatin1String("width"), ctxt, d->width.value);
actions << wa;
} else {
- QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
- newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("width")));
+ QDeclarativeBinding *newBinding = new QDeclarativeBinding(d->widthString.value.script(), d->target, ctxt);
+ newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("width"), ctxt));
QDeclarativeAction wa;
wa.property = newBinding->property();
wa.toBinding = newBinding;
@@ -463,15 +473,12 @@ QDeclarativeStateOperation::ActionList QDeclarativeParentChange::actions()
}
if (d->heightString.isValid()) {
- bool ok = false;
- QString script = d->heightString.value.script();
- qreal height = script.toFloat(&ok);
- if (ok) {
- QDeclarativeAction ha(d->target, QLatin1String("height"), height);
+ if (d->height.isValid()) {
+ QDeclarativeAction ha(d->target, QLatin1String("height"), ctxt, d->height.value);
actions << ha;
} else {
- QDeclarativeBinding *newBinding = new QDeclarativeBinding(script, d->target, qmlContext(this));
- newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("height")));
+ QDeclarativeBinding *newBinding = new QDeclarativeBinding(d->heightString.value.script(), d->target, ctxt);
+ newBinding->setTarget(QDeclarativeProperty(d->target, QLatin1String("height"), ctxt));
QDeclarativeAction ha;
ha.property = newBinding->property();
ha.toBinding = newBinding;
@@ -1075,32 +1082,34 @@ QDeclarativeAnchorChanges::ActionList QDeclarativeAnchorChanges::actions()
d->vCenterProp = QDeclarativeProperty(d->target, QLatin1String("anchors.verticalCenter"));
d->baselineProp = QDeclarativeProperty(d->target, QLatin1String("anchors.baseline"));
+ QDeclarativeContext *ctxt = qmlContext(this);
+
if (d->anchorSet->d_func()->usedAnchors & QDeclarativeAnchors::LeftAnchor) {
- d->leftBinding = new QDeclarativeBinding(d->anchorSet->d_func()->leftScript.script(), d->target, qmlContext(this));
+ d->leftBinding = new QDeclarativeBinding(d->anchorSet->d_func()->leftScript.script(), d->target, ctxt);
d->leftBinding->setTarget(d->leftProp);
}
if (d->anchorSet->d_func()->usedAnchors & QDeclarativeAnchors::RightAnchor) {
- d->rightBinding = new QDeclarativeBinding(d->anchorSet->d_func()->rightScript.script(), d->target, qmlContext(this));
+ d->rightBinding = new QDeclarativeBinding(d->anchorSet->d_func()->rightScript.script(), d->target, ctxt);
d->rightBinding->setTarget(d->rightProp);
}
if (d->anchorSet->d_func()->usedAnchors & QDeclarativeAnchors::HCenterAnchor) {
- d->hCenterBinding = new QDeclarativeBinding(d->anchorSet->d_func()->hCenterScript.script(), d->target, qmlContext(this));
+ d->hCenterBinding = new QDeclarativeBinding(d->anchorSet->d_func()->hCenterScript.script(), d->target, ctxt);
d->hCenterBinding->setTarget(d->hCenterProp);
}
if (d->anchorSet->d_func()->usedAnchors & QDeclarativeAnchors::TopAnchor) {
- d->topBinding = new QDeclarativeBinding(d->anchorSet->d_func()->topScript.script(), d->target, qmlContext(this));
+ d->topBinding = new QDeclarativeBinding(d->anchorSet->d_func()->topScript.script(), d->target, ctxt);
d->topBinding->setTarget(d->topProp);
}
if (d->anchorSet->d_func()->usedAnchors & QDeclarativeAnchors::BottomAnchor) {
- d->bottomBinding = new QDeclarativeBinding(d->anchorSet->d_func()->bottomScript.script(), d->target, qmlContext(this));
+ d->bottomBinding = new QDeclarativeBinding(d->anchorSet->d_func()->bottomScript.script(), d->target, ctxt);
d->bottomBinding->setTarget(d->bottomProp);
}
if (d->anchorSet->d_func()->usedAnchors & QDeclarativeAnchors::VCenterAnchor) {
- d->vCenterBinding = new QDeclarativeBinding(d->anchorSet->d_func()->vCenterScript.script(), d->target, qmlContext(this));
+ d->vCenterBinding = new QDeclarativeBinding(d->anchorSet->d_func()->vCenterScript.script(), d->target, ctxt);
d->vCenterBinding->setTarget(d->vCenterProp);
}
if (d->anchorSet->d_func()->usedAnchors & QDeclarativeAnchors::BaselineAnchor) {
- d->baselineBinding = new QDeclarativeBinding(d->anchorSet->d_func()->baselineScript.script(), d->target, qmlContext(this));
+ d->baselineBinding = new QDeclarativeBinding(d->anchorSet->d_func()->baselineScript.script(), d->target, ctxt);
d->baselineBinding->setTarget(d->baselineProp);
}
@@ -1380,24 +1389,25 @@ QList<QDeclarativeAction> QDeclarativeAnchorChanges::additionalActions()
bool vChange = combined & QDeclarativeAnchors::Vertical_Mask;
if (d->target) {
+ QDeclarativeContext *ctxt = qmlContext(this);
QDeclarativeAction a;
if (hChange && d->fromX != d->toX) {
- a.property = QDeclarativeProperty(d->target, QLatin1String("x"));
+ a.property = QDeclarativeProperty(d->target, QLatin1String("x"), ctxt);
a.toValue = d->toX;
extra << a;
}
if (vChange && d->fromY != d->toY) {
- a.property = QDeclarativeProperty(d->target, QLatin1String("y"));
+ a.property = QDeclarativeProperty(d->target, QLatin1String("y"), ctxt);
a.toValue = d->toY;
extra << a;
}
if (hChange && d->fromWidth != d->toWidth) {
- a.property = QDeclarativeProperty(d->target, QLatin1String("width"));
+ a.property = QDeclarativeProperty(d->target, QLatin1String("width"), ctxt);
a.toValue = d->toWidth;
extra << a;
}
if (vChange && d->fromHeight != d->toHeight) {
- a.property = QDeclarativeProperty(d->target, QLatin1String("height"));
+ a.property = QDeclarativeProperty(d->target, QLatin1String("height"), ctxt);
a.toValue = d->toHeight;
extra << a;
}
diff --git a/src/declarative/util/qdeclarativeview.cpp b/src/declarative/util/qdeclarativeview.cpp
index 0e31a20..a87ca37 100644
--- a/src/declarative/util/qdeclarativeview.cpp
+++ b/src/declarative/util/qdeclarativeview.cpp
@@ -77,7 +77,7 @@ extern Q_GUI_EXPORT bool qt_applefontsmoothing_enabled;
class QDeclarativeScene : public QGraphicsScene
{
public:
- QDeclarativeScene();
+ QDeclarativeScene(QObject *parent = 0);
protected:
virtual void keyPressEvent(QKeyEvent *);
@@ -88,7 +88,7 @@ protected:
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
};
-QDeclarativeScene::QDeclarativeScene()
+QDeclarativeScene::QDeclarativeScene(QObject *parent) : QGraphicsScene(parent)
{
}
@@ -132,7 +132,8 @@ class QDeclarativeViewPrivate : public QGraphicsViewPrivate, public QDeclarative
Q_DECLARE_PUBLIC(QDeclarativeView)
public:
QDeclarativeViewPrivate()
- : root(0), declarativeItemRoot(0), graphicsWidgetRoot(0), component(0), resizeMode(QDeclarativeView::SizeViewToRootObject), initialSize(0,0) {}
+ : root(0), declarativeItemRoot(0), graphicsWidgetRoot(0), component(0),
+ resizeMode(QDeclarativeView::SizeViewToRootObject), initialSize(0,0) {}
~QDeclarativeViewPrivate() { delete root; delete engine; }
void execute();
void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry);
@@ -155,8 +156,6 @@ public:
QElapsedTimer frameTimer;
void init();
-
- QDeclarativeScene scene;
};
void QDeclarativeViewPrivate::execute()
@@ -234,6 +233,9 @@ void QDeclarativeViewPrivate::itemGeometryChanged(QDeclarativeItem *resizeItem,
you can connect to the statusChanged() signal and monitor for QDeclarativeView::Error.
The errors are available via QDeclarativeView::errors().
+ If you're using your own QGraphicsScene-based scene with QDeclarativeView, remember to
+ enable scene's sticky focus mode and to set itemIndexMethod to QGraphicsScene::NoIndex.
+
\sa {Integrating QML with existing Qt UI code}, {Using QML in C++ Applications}
*/
@@ -277,7 +279,7 @@ void QDeclarativeViewPrivate::init()
{
Q_Q(QDeclarativeView);
engine = new QDeclarativeEngine();
- q->setScene(&scene);
+ q->setScene(new QDeclarativeScene(q));
q->setOptimizationFlags(QGraphicsView::DontSavePainterState);
q->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
@@ -286,11 +288,11 @@ void QDeclarativeViewPrivate::init()
// These seem to give the best performance
q->setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
- scene.setItemIndexMethod(QGraphicsScene::NoIndex);
+ q->scene()->setItemIndexMethod(QGraphicsScene::NoIndex);
q->viewport()->setFocusPolicy(Qt::NoFocus);
q->setFocusPolicy(Qt::StrongFocus);
- scene.setStickyFocus(true); //### needed for correct focus handling
+ q->scene()->setStickyFocus(true); //### needed for correct focus handling
}
/*!
@@ -556,14 +558,14 @@ void QDeclarativeView::continueExecute()
void QDeclarativeView::setRootObject(QObject *obj)
{
Q_D(QDeclarativeView);
- if (d->root == obj)
+ if (d->root == obj || !scene())
return;
if (QDeclarativeItem *declarativeItem = qobject_cast<QDeclarativeItem *>(obj)) {
- d->scene.addItem(declarativeItem);
+ scene()->addItem(declarativeItem);
d->root = declarativeItem;
d->declarativeItemRoot = declarativeItem;
} else if (QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject *>(obj)) {
- d->scene.addItem(graphicsObject);
+ scene()->addItem(graphicsObject);
d->root = graphicsObject;
if (graphicsObject->isWidget()) {
d->graphicsWidgetRoot = static_cast<QGraphicsWidget*>(graphicsObject);
diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro
index 722979d..07825d9 100644
--- a/src/plugins/plugins.pro
+++ b/src/plugins/plugins.pro
@@ -14,5 +14,4 @@ embedded:SUBDIRS *= gfxdrivers decorations mousedrivers kbddrivers
symbian:SUBDIRS += s60
contains(QT_CONFIG, phonon): SUBDIRS *= phonon
contains(QT_CONFIG, multimedia): SUBDIRS *= audio
-
-
+contains(QT_CONFIG, declarative): SUBDIRS *= qmldebugging
diff --git a/src/plugins/qmldebugging/qmldebugging.pro b/src/plugins/qmldebugging/qmldebugging.pro
new file mode 100644
index 0000000..01cf1a9
--- /dev/null
+++ b/src/plugins/qmldebugging/qmldebugging.pro
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+
+SUBDIRS = tcpserver
+
diff --git a/src/plugins/qmldebugging/tcpserver/qtcpserverconnection.cpp b/src/plugins/qmldebugging/tcpserver/qtcpserverconnection.cpp
new file mode 100644
index 0000000..69c1ef5
--- /dev/null
+++ b/src/plugins/qmldebugging/tcpserver/qtcpserverconnection.cpp
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** 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 QtDeclarative module 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$
+**
+****************************************************************************/
+
+#include "qtcpserverconnection.h"
+
+#include <QtNetwork/qtcpserver.h>
+#include <QtNetwork/qtcpsocket.h>
+
+#include <private/qdeclarativedebugserver_p.h>
+#include <private/qpacketprotocol_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QTcpServerConnectionPrivate {
+public:
+ QTcpServerConnectionPrivate();
+
+ int port;
+ QTcpSocket *socket;
+ QPacketProtocol *protocol;
+ QTcpServer *tcpServer;
+
+ QDeclarativeDebugServer *debugServer;
+};
+
+QTcpServerConnectionPrivate::QTcpServerConnectionPrivate() :
+ port(0),
+ socket(0),
+ protocol(0),
+ tcpServer(0),
+ debugServer(0)
+{
+}
+
+QTcpServerConnection::QTcpServerConnection() :
+ d_ptr(new QTcpServerConnectionPrivate)
+{
+
+}
+
+QTcpServerConnection::~QTcpServerConnection()
+{
+ delete d_ptr;
+}
+
+void QTcpServerConnection::setServer(QDeclarativeDebugServer *server)
+{
+ Q_D(QTcpServerConnection);
+ d->debugServer = server;
+}
+
+bool QTcpServerConnection::isConnected() const
+{
+ Q_D(const QTcpServerConnection);
+ return d->socket && d->socket->state() == QTcpSocket::ConnectedState;
+}
+
+void QTcpServerConnection::send(const QByteArray &message)
+{
+ Q_D(QTcpServerConnection);
+
+ if (!isConnected())
+ return;
+
+ QPacket pack;
+ pack.writeRawData(message.data(), message.length());
+
+ d->protocol->send(pack);
+ d->socket->flush();
+}
+
+void QTcpServerConnection::disconnect()
+{
+ Q_D(QTcpServerConnection);
+
+ delete d->protocol;
+ d->protocol = 0;
+ delete d->socket;
+ d->socket = 0;
+}
+
+void QTcpServerConnection::setPort(int port, bool block)
+{
+ Q_D(QTcpServerConnection);
+ d->port = port;
+
+ listen();
+ if (block)
+ d->tcpServer->waitForNewConnection(-1);
+}
+
+void QTcpServerConnection::listen()
+{
+ Q_D(QTcpServerConnection);
+
+ d->tcpServer = new QTcpServer(this);
+ QObject::connect(d->tcpServer, SIGNAL(newConnection()), this, SLOT(newConnection()));
+ if (d->tcpServer->listen(QHostAddress::Any, d->port))
+ qWarning("QDeclarativeDebugServer: Waiting for connection on port %d...", d->port);
+ else
+ qWarning("QDeclarativeDebugServer: Unable to listen on port %d", d->port);
+}
+
+
+void QTcpServerConnection::readyRead()
+{
+ Q_D(QTcpServerConnection);
+ QPacket packet = d->protocol->read();
+
+ QByteArray content = packet.data();
+ d->debugServer->receiveMessage(content);
+}
+
+void QTcpServerConnection::newConnection()
+{
+ Q_D(QTcpServerConnection);
+
+ if (d->socket) {
+ qWarning("QDeclarativeDebugServer: Another client is already connected");
+ QTcpSocket *faultyConnection = d->tcpServer->nextPendingConnection();
+ delete faultyConnection;
+ return;
+ }
+
+ d->socket = d->tcpServer->nextPendingConnection();
+ d->socket->setParent(this);
+ d->protocol = new QPacketProtocol(d->socket, this);
+ QObject::connect(d->protocol, SIGNAL(readyRead()), this, SLOT(readyRead()));
+}
+
+
+Q_EXPORT_PLUGIN2(tcpserver, QTcpServerConnection)
+
+QT_END_NAMESPACE
+
diff --git a/src/plugins/qmldebugging/tcpserver/qtcpserverconnection.h b/src/plugins/qmldebugging/tcpserver/qtcpserverconnection.h
new file mode 100644
index 0000000..a6e17e6
--- /dev/null
+++ b/src/plugins/qmldebugging/tcpserver/qtcpserverconnection.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** 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 QtDeclarative module 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$
+**
+****************************************************************************/
+
+#ifndef QTCPSERVERCONNECTION_H
+#define QTCPSERVERCONNECTION_H
+
+#include <QtGui/QStylePlugin>
+#include <QtDeclarative/private/qdeclarativedebugserverconnection_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeDebugServer;
+class QTcpServerConnectionPrivate;
+class QTcpServerConnection : public QObject, public QDeclarativeDebugServerConnection
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QTcpServerConnection)
+ Q_DISABLE_COPY(QTcpServerConnection)
+ Q_INTERFACES(QDeclarativeDebugServerConnection)
+
+
+public:
+ QTcpServerConnection();
+ ~QTcpServerConnection();
+
+ void setServer(QDeclarativeDebugServer *server);
+ void setPort(int port, bool bock);
+
+ bool isConnected() const;
+ void send(const QByteArray &message);
+ void disconnect();
+
+ void listen();
+ void waitForConnection();
+
+private Q_SLOTS:
+ void readyRead();
+ void newConnection();
+
+private:
+ QTcpServerConnectionPrivate *d_ptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QTCPSERVERCONNECTION_H
diff --git a/src/plugins/qmldebugging/tcpserver/tcpserver.pro b/src/plugins/qmldebugging/tcpserver/tcpserver.pro
new file mode 100644
index 0000000..e90fb34
--- /dev/null
+++ b/src/plugins/qmldebugging/tcpserver/tcpserver.pro
@@ -0,0 +1,18 @@
+TARGET = tcpserver
+QT += declarative network
+
+include(../../qpluginbase.pri)
+
+QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/qmldebugging
+QTDIR_build:REQUIRES += "contains(QT_CONFIG, declarative)"
+
+SOURCES += \
+ qtcpserverconnection.cpp
+
+HEADERS += \
+ qtcpserverconnection.h
+
+target.path += $$[QT_INSTALL_PLUGINS]/qmldebugging
+INSTALLS += target
+
+symbian:TARGET.UID3=0x20031E90 \ No newline at end of file
diff --git a/src/script/bridge/qscriptdeclarativeclass.cpp b/src/script/bridge/qscriptdeclarativeclass.cpp
index 8080b9f..13736bc 100644
--- a/src/script/bridge/qscriptdeclarativeclass.cpp
+++ b/src/script/bridge/qscriptdeclarativeclass.cpp
@@ -468,6 +468,14 @@ QString QScriptDeclarativeClass::toString(const Identifier &identifier)
return QString((QChar *)r->data(), r->size());
}
+bool QScriptDeclarativeClass::startsWithUpper(const Identifier &identifier)
+{
+ JSC::UString::Rep *r = (JSC::UString::Rep *)identifier;
+ if (r->size() < 1)
+ return false;
+ return QChar::category((ushort)(r->data()[0])) == QChar::Letter_Uppercase;
+}
+
quint32 QScriptDeclarativeClass::toArrayIndex(const Identifier &identifier, bool *ok)
{
JSC::UString::Rep *r = (JSC::UString::Rep *)identifier;
diff --git a/src/script/bridge/qscriptdeclarativeclass_p.h b/src/script/bridge/qscriptdeclarativeclass_p.h
index 420b133..fe38eeb 100644
--- a/src/script/bridge/qscriptdeclarativeclass_p.h
+++ b/src/script/bridge/qscriptdeclarativeclass_p.h
@@ -126,6 +126,7 @@ public:
PersistentIdentifier createPersistentIdentifier(const Identifier &);
QString toString(const Identifier &);
+ bool startsWithUpper(const Identifier &);
quint32 toArrayIndex(const Identifier &, bool *ok);
virtual QScriptClass::QueryFlags queryProperty(Object *, const Identifier &,
diff --git a/tests/auto/declarative/qdeclarativeanimatedimage/data/hearts.gif b/tests/auto/declarative/qdeclarativeanimatedimage/data/hearts.gif
new file mode 100644
index 0000000..cfb55f2
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeanimatedimage/data/hearts.gif
Binary files differ
diff --git a/tests/auto/declarative/qdeclarativeanimatedimage/data/hearts.qml b/tests/auto/declarative/qdeclarativeanimatedimage/data/hearts.qml
new file mode 100644
index 0000000..8729dd2
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeanimatedimage/data/hearts.qml
@@ -0,0 +1,6 @@
+import QtQuick 1.0
+
+AnimatedImage {
+ source: "hearts.gif"
+ playing: false
+}
diff --git a/tests/auto/declarative/qdeclarativeanimatedimage/tst_qdeclarativeanimatedimage.cpp b/tests/auto/declarative/qdeclarativeanimatedimage/tst_qdeclarativeanimatedimage.cpp
index 8cbe813..bd701e7 100644
--- a/tests/auto/declarative/qdeclarativeanimatedimage/tst_qdeclarativeanimatedimage.cpp
+++ b/tests/auto/declarative/qdeclarativeanimatedimage/tst_qdeclarativeanimatedimage.cpp
@@ -45,6 +45,7 @@
#include <private/qdeclarativerectangle_p.h>
#include <private/qdeclarativeimage_p.h>
#include <private/qdeclarativeanimatedimage_p.h>
+#include <QSignalSpy>
#include "../shared/testhttpserver.h"
#include "../../../shared/util.h"
@@ -66,13 +67,28 @@ private slots:
void stopped();
void setFrame();
void frameCount();
+ void mirror_running();
+ void mirror_notRunning();
+ void mirror_notRunning_data();
void remote();
void remote_data();
void sourceSize();
void sourceSizeReadOnly();
void invalidSource();
+
+private:
+ QPixmap grabScene(QGraphicsScene *scene, int width, int height);
};
+QPixmap tst_qdeclarativeanimatedimage::grabScene(QGraphicsScene *scene, int width, int height)
+{
+ QPixmap screenshot(width, height);
+ screenshot.fill();
+ QPainter p_screenshot(&screenshot);
+ scene->render(&p_screenshot, QRect(0, 0, width, height), QRect(0, 0, width, height));
+ return screenshot;
+}
+
void tst_qdeclarativeanimatedimage::play()
{
QDeclarativeEngine engine;
@@ -132,6 +148,93 @@ void tst_qdeclarativeanimatedimage::frameCount()
delete anim;
}
+void tst_qdeclarativeanimatedimage::mirror_running()
+{
+ // test where mirror is set to true after animation has started
+
+ QDeclarativeEngine engine;
+ QDeclarativeComponent component(&engine, QUrl::fromLocalFile(SRCDIR "/data/hearts.qml"));
+ QDeclarativeAnimatedImage *anim = qobject_cast<QDeclarativeAnimatedImage *>(component.create());
+ QVERIFY(anim);
+
+ QGraphicsScene scene;
+ int width = anim->property("width").toInt();
+ int height = anim->property("height").toInt();
+ scene.addItem(qobject_cast<QGraphicsObject *>(anim));
+
+ QCOMPARE(anim->currentFrame(), 0);
+ QPixmap frame0 = grabScene(&scene, width, height);
+ anim->setCurrentFrame(1);
+ QPixmap frame1 = grabScene(&scene, width, height);
+
+ anim->setCurrentFrame(0);
+
+ QSignalSpy spy(anim, SIGNAL(frameChanged()));
+ anim->setPlaying(true);
+
+ QTRY_VERIFY(spy.count() == 1); spy.clear();
+ anim->setProperty("mirror", true);
+
+ QCOMPARE(anim->currentFrame(), 1);
+ QPixmap frame1_flipped = grabScene(&scene, width, height);
+
+ QTRY_VERIFY(spy.count() == 1); spy.clear();
+ QCOMPARE(anim->currentFrame(), 0); // animation only has 2 frames, should cycle back to first
+ QPixmap frame0_flipped = grabScene(&scene, width, height);
+
+ QTransform transform;
+ transform.translate(width, 0).scale(-1, 1.0);
+ QPixmap frame0_expected = frame0.transformed(transform);
+ QPixmap frame1_expected = frame1.transformed(transform);
+
+ QCOMPARE(frame0_flipped, frame0_expected);
+ QCOMPARE(frame1_flipped, frame1_expected);
+}
+
+void tst_qdeclarativeanimatedimage::mirror_notRunning()
+{
+ QFETCH(QUrl, fileUrl);
+
+ QDeclarativeEngine engine;
+ QDeclarativeComponent component(&engine, fileUrl);
+ QDeclarativeAnimatedImage *anim = qobject_cast<QDeclarativeAnimatedImage *>(component.create());
+ QVERIFY(anim);
+
+ QGraphicsScene scene;
+ int width = anim->property("width").toInt();
+ int height = anim->property("height").toInt();
+ scene.addItem(qobject_cast<QGraphicsObject *>(anim));
+ QPixmap screenshot = grabScene(&scene, width, height);
+
+ QTransform transform;
+ transform.translate(width, 0).scale(-1, 1.0);
+ QPixmap expected = screenshot.transformed(transform);
+
+ int frame = anim->currentFrame();
+ bool playing = anim->isPlaying();
+ bool paused = anim->isPlaying();
+
+ anim->setProperty("mirror", true);
+ screenshot = grabScene(&scene, width, height);
+
+ QCOMPARE(screenshot, expected);
+
+ // mirroring should not change the current frame or playing status
+ QCOMPARE(anim->currentFrame(), frame);
+ QCOMPARE(anim->isPlaying(), playing);
+ QCOMPARE(anim->isPaused(), paused);
+
+ delete anim;
+}
+
+void tst_qdeclarativeanimatedimage::mirror_notRunning_data()
+{
+ QTest::addColumn<QUrl>("fileUrl");
+
+ QTest::newRow("paused") << QUrl::fromLocalFile(SRCDIR "/data/stickmanpause.qml");
+ QTest::newRow("stopped") << QUrl::fromLocalFile(SRCDIR "/data/stickmanstopped.qml");
+}
+
void tst_qdeclarativeanimatedimage::remote()
{
QFETCH(QString, fileName);
diff --git a/tests/auto/declarative/qdeclarativeborderimage/data/heart200.png b/tests/auto/declarative/qdeclarativeborderimage/data/heart200.png
new file mode 100644
index 0000000..5a31ae8
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeborderimage/data/heart200.png
Binary files differ
diff --git a/tests/auto/declarative/qdeclarativeborderimage/tst_qdeclarativeborderimage.cpp b/tests/auto/declarative/qdeclarativeborderimage/tst_qdeclarativeborderimage.cpp
index 2f00f60..c22cde2 100644
--- a/tests/auto/declarative/qdeclarativeborderimage/tst_qdeclarativeborderimage.cpp
+++ b/tests/auto/declarative/qdeclarativeborderimage/tst_qdeclarativeborderimage.cpp
@@ -43,6 +43,8 @@
#include <QTcpServer>
#include <QTcpSocket>
#include <QDir>
+#include <QGraphicsScene>
+#include <QPainter>
#include <QtDeclarative/qdeclarativeengine.h>
#include <QtDeclarative/qdeclarativecomponent.h>
@@ -77,6 +79,7 @@ private slots:
void clearSource();
void resized();
void smooth();
+ void mirror();
void tileModes();
void sciSource();
void sciSource_data();
@@ -153,6 +156,8 @@ void tst_qdeclarativeborderimage::imageSource()
QTRY_VERIFY(obj->status() == QDeclarativeBorderImage::Ready);
QCOMPARE(obj->width(), 120.);
QCOMPARE(obj->height(), 120.);
+ QCOMPARE(obj->sourceSize().width(), 120);
+ QCOMPARE(obj->sourceSize().height(), 120);
QCOMPARE(obj->horizontalTileMode(), QDeclarativeBorderImage::Stretch);
QCOMPARE(obj->verticalTileMode(), QDeclarativeBorderImage::Stretch);
} else {
@@ -192,6 +197,8 @@ void tst_qdeclarativeborderimage::resized()
QVERIFY(obj != 0);
QCOMPARE(obj->width(), 300.);
QCOMPARE(obj->height(), 300.);
+ QCOMPARE(obj->sourceSize().width(), 120);
+ QCOMPARE(obj->sourceSize().height(), 120);
QCOMPARE(obj->horizontalTileMode(), QDeclarativeBorderImage::Stretch);
QCOMPARE(obj->verticalTileMode(), QDeclarativeBorderImage::Stretch);
@@ -214,6 +221,37 @@ void tst_qdeclarativeborderimage::smooth()
delete obj;
}
+void tst_qdeclarativeborderimage::mirror()
+{
+ QString componentStr = "import QtQuick 1.0\nBorderImage { source: \"" SRCDIR "/data/heart200.png\"; smooth: true; width: 300; height: 300; border { top: 50; right: 50; bottom: 50; left: 50 } }";
+ QDeclarativeComponent component(&engine);
+ component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QDeclarativeBorderImage *obj = qobject_cast<QDeclarativeBorderImage*>(component.create());
+ QVERIFY(obj != 0);
+
+ int width = obj->property("width").toInt();
+ int height = obj->property("height").toInt();
+
+ QGraphicsScene scene;
+ scene.addItem(qobject_cast<QGraphicsObject *>(obj));
+ QPixmap screenshot(width, height);
+ screenshot.fill();
+ QPainter p_screenshot(&screenshot);
+ scene.render(&p_screenshot, QRect(0, 0, width, height), QRect(0, 0, width, height));
+
+ QTransform transform;
+ transform.translate(width, 0).scale(-1, 1.0);
+ QPixmap expected = screenshot.transformed(transform);
+
+ obj->setProperty("mirror", true);
+ p_screenshot.fillRect(QRect(0, 0, width, height), Qt::white);
+ scene.render(&p_screenshot, QRect(0, 0, width, height), QRect(0, 0, width, height));
+
+ QCOMPARE(screenshot, expected);
+
+ delete obj;
+}
+
void tst_qdeclarativeborderimage::tileModes()
{
{
diff --git a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp
index 53471bf..fac32d7 100644
--- a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp
+++ b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp
@@ -72,7 +72,7 @@ class tst_QDeclarativeDebug : public QObject
Q_OBJECT
private:
- QDeclarativeDebugObjectReference findRootObject(int context = 0);
+ QDeclarativeDebugObjectReference findRootObject(int context = 0, bool recursive = false);
QDeclarativeDebugPropertyReference findProperty(const QList<QDeclarativeDebugPropertyReference> &props, const QString &name) const;
void waitForQuery(QDeclarativeDebugQuery *query);
@@ -114,9 +114,11 @@ private slots:
void tst_QDeclarativeDebugPropertyReference();
void setMethodBody();
+ void queryObjectTree();
+ void setBindingInStates();
};
-QDeclarativeDebugObjectReference tst_QDeclarativeDebug::findRootObject(int context)
+QDeclarativeDebugObjectReference tst_QDeclarativeDebug::findRootObject(int context, bool recursive)
{
QDeclarativeDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this);
waitForQuery(q_engines);
@@ -128,7 +130,9 @@ QDeclarativeDebugObjectReference tst_QDeclarativeDebug::findRootObject(int conte
if (q_context->rootContext().objects().count() == 0)
return QDeclarativeDebugObjectReference();
- QDeclarativeDebugObjectQuery *q_obj = m_dbg->queryObject(q_context->rootContext().objects()[context], this);
+ QDeclarativeDebugObjectQuery *q_obj = recursive ?
+ m_dbg->queryObjectRecursive(q_context->rootContext().objects()[context], this) :
+ m_dbg->queryObject(q_context->rootContext().objects()[context], this);
waitForQuery(q_obj);
QDeclarativeDebugObjectReference result = q_obj->object();
@@ -308,6 +312,34 @@ void tst_QDeclarativeDebug::initTestCase()
"function myMethodIndirect() { myMethod(3); }\n"
"}";
+ // and a fourth to test states
+ qml << "import QtQuick 1.0\n"
+ "Rectangle {\n"
+ "id:rootRect\n"
+ "width:100\n"
+ "states: [\n"
+ "State {\n"
+ "name:\"state1\"\n"
+ "PropertyChanges {\n"
+ "target:rootRect\n"
+ "width:200\n"
+ "}\n"
+ "}\n"
+ "]\n"
+ "transitions: [\n"
+ "Transition {\n"
+ "from:\"*\"\n"
+ "to:\"state1\"\n"
+ "PropertyAnimation {\n"
+ "target:rootRect\n"
+ "property:\"width\"\n"
+ "duration:100\n"
+ "}\n"
+ "}\n"
+ "]\n"
+ "}\n"
+ ;
+
for (int i=0; i<qml.count(); i++) {
QDeclarativeComponent component(m_engine);
component.setData(qml[i], QUrl::fromLocalFile(""));
@@ -635,14 +667,14 @@ void tst_QDeclarativeDebug::queryRootContexts()
QCOMPARE(context.debugId(), QDeclarativeDebugService::idForObject(actualContext));
QCOMPARE(context.name(), actualContext->objectName());
- QCOMPARE(context.objects().count(), 3); // 3 qml component objects created for context in main()
+ QCOMPARE(context.objects().count(), 4); // 4 qml component objects created for context in main()
// root context query sends only root object data - it doesn't fill in
// the children or property info
QCOMPARE(context.objects()[0].properties().count(), 0);
QCOMPARE(context.objects()[0].children().count(), 0);
- QCOMPARE(context.contexts().count(), 4);
+ QCOMPARE(context.contexts().count(), 5);
QVERIFY(context.contexts()[0].debugId() >= 0);
QCOMPARE(context.contexts()[0].name(), QString("tst_QDeclarativeDebug_childContext"));
@@ -897,6 +929,162 @@ void tst_QDeclarativeDebug::tst_QDeclarativeDebugPropertyReference()
compareProperties(r, ref);
}
+void tst_QDeclarativeDebug::setBindingInStates()
+{
+ // Check if changing bindings of propertychanges works
+
+ const int sourceIndex = 3;
+
+ QDeclarativeDebugObjectReference obj = findRootObject(sourceIndex);
+
+ QVERIFY(obj.debugId() != -1);
+ QVERIFY(obj.children().count() >= 2);
+
+ // We are going to switch state a couple of times, we need to get rid of the transition before
+ QDeclarativeDebugExpressionQuery *q_deleteTransition = m_dbg->queryExpressionResult(obj.debugId(),QString("transitions = []"),this);
+ waitForQuery(q_deleteTransition);
+ delete q_deleteTransition;
+
+
+ // check initial value of the property that is changing
+ QDeclarativeDebugExpressionQuery *q_setState;
+ q_setState = m_dbg->queryExpressionResult(obj.debugId(),QString("state=\"state1\""),this);
+ waitForQuery(q_setState);
+ delete q_setState;
+
+ obj = findRootObject(sourceIndex);
+ QCOMPARE(findProperty(obj.properties(),"width").value().toInt(),200);
+
+
+ q_setState = m_dbg->queryExpressionResult(obj.debugId(),QString("state=\"\""),this);
+ waitForQuery(q_setState);
+ delete q_setState;
+
+
+ obj = findRootObject(sourceIndex, true);
+ QCOMPARE(findProperty(obj.properties(),"width").value().toInt(),100);
+
+
+ // change the binding
+ QDeclarativeDebugObjectReference state = obj.children()[0];
+ QCOMPARE(state.className(), QString("State"));
+ QVERIFY(state.children().count() > 0);
+
+ QDeclarativeDebugObjectReference propertyChange = state.children()[0];
+ QVERIFY(propertyChange.debugId() != -1);
+
+ QVERIFY( m_dbg->setBindingForObject(propertyChange.debugId(), "width",QVariant(300),true) );
+
+ // check properties changed in state
+ obj = findRootObject(sourceIndex);
+ QCOMPARE(findProperty(obj.properties(),"width").value().toInt(),100);
+
+
+ q_setState = m_dbg->queryExpressionResult(obj.debugId(),QString("state=\"state1\""),this);
+ waitForQuery(q_setState);
+ delete q_setState;
+
+ obj = findRootObject(sourceIndex);
+ QCOMPARE(findProperty(obj.properties(),"width").value().toInt(),300);
+
+ // check changing properties of base state from within a state
+ QVERIFY(m_dbg->setBindingForObject(obj.debugId(),"width","height*2",false));
+ QVERIFY(m_dbg->setBindingForObject(obj.debugId(),"height","200",true));
+
+ obj = findRootObject(sourceIndex);
+ QCOMPARE(findProperty(obj.properties(),"width").value().toInt(),300);
+
+ q_setState = m_dbg->queryExpressionResult(obj.debugId(),QString("state=\"\""),this);
+ waitForQuery(q_setState);
+ delete q_setState;
+
+ obj = findRootObject(sourceIndex);
+ QCOMPARE(findProperty(obj.properties(),"width").value().toInt(), 400);
+
+ // reset binding while in a state
+ q_setState = m_dbg->queryExpressionResult(obj.debugId(),QString("state=\"state1\""),this);
+ waitForQuery(q_setState);
+ delete q_setState;
+
+ obj = findRootObject(sourceIndex);
+ QCOMPARE(findProperty(obj.properties(),"width").value().toInt(), 300);
+
+ m_dbg->resetBindingForObject(propertyChange.debugId(), "width");
+
+ obj = findRootObject(sourceIndex);
+ QCOMPARE(findProperty(obj.properties(),"width").value().toInt(), 400);
+
+ // re-add binding
+ m_dbg->setBindingForObject(propertyChange.debugId(), "width", "300", true);
+
+ obj = findRootObject(sourceIndex);
+ QCOMPARE(findProperty(obj.properties(),"width").value().toInt(), 300);
+}
+
+void tst_QDeclarativeDebug::queryObjectTree()
+{
+ const int sourceIndex = 3;
+
+ // Check if states/transitions are initialized when fetching root item
+ QDeclarativeDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this);
+ waitForQuery(q_engines);
+
+ QDeclarativeDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this);
+ waitForQuery(q_context);
+
+ QVERIFY(q_context->rootContext().objects().count() > sourceIndex);
+ QDeclarativeDebugObjectReference rootObject = q_context->rootContext().objects()[sourceIndex];
+
+ QDeclarativeDebugObjectQuery *q_obj = m_dbg->queryObjectRecursive(rootObject, this);
+ waitForQuery(q_obj);
+
+ QDeclarativeDebugObjectReference obj = q_obj->object();
+
+ delete q_engines;
+ delete q_context;
+ delete q_obj;
+
+ QVERIFY(obj.debugId() != -1);
+ QVERIFY(obj.children().count() >= 2);
+
+
+
+ // check state
+ QDeclarativeDebugObjectReference state = obj.children()[0];
+ QCOMPARE(state.className(), QString("State"));
+ QVERIFY(state.children().count() > 0);
+
+ QDeclarativeDebugObjectReference propertyChange = state.children()[0];
+ QVERIFY(propertyChange.debugId() != -1);
+
+ QDeclarativeDebugPropertyReference propertyChangeTarget = findProperty(propertyChange.properties(),"target");
+ QCOMPARE(propertyChangeTarget.objectDebugId(), propertyChange.debugId());
+
+ QDeclarativeDebugObjectReference targetReference = qvariant_cast<QDeclarativeDebugObjectReference>(propertyChangeTarget.value());
+ QVERIFY(targetReference.debugId() != -1);
+
+
+
+ // check transition
+ QDeclarativeDebugObjectReference transition = obj.children()[1];
+ QCOMPARE(transition.className(), QString("Transition"));
+ QCOMPARE(findProperty(transition.properties(),"from").value().toString(), QString("*"));
+ QCOMPARE(findProperty(transition.properties(),"to").value(), findProperty(state.properties(),"name").value());
+ QVERIFY(transition.children().count() > 0);
+
+ QDeclarativeDebugObjectReference animation = transition.children()[0];
+ QVERIFY(animation.debugId() != -1);
+
+ QDeclarativeDebugPropertyReference animationTarget = findProperty(animation.properties(),"target");
+ QCOMPARE(animationTarget.objectDebugId(), animation.debugId());
+
+ targetReference = qvariant_cast<QDeclarativeDebugObjectReference>(animationTarget.value());
+ QVERIFY(targetReference.debugId() != -1);
+
+ QCOMPARE(findProperty(animation.properties(),"property").value().toString(), QString("width"));
+ QCOMPARE(findProperty(animation.properties(),"duration").value().toInt(), 100);
+}
+
int main(int argc, char *argv[])
{
int _argc = argc + 1;
diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/nonExistantAttachedObject.qml b/tests/auto/declarative/qdeclarativeecmascript/data/nonExistentAttachedObject.qml
index f9585db..f9585db 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/data/nonExistantAttachedObject.qml
+++ b/tests/auto/declarative/qdeclarativeecmascript/data/nonExistentAttachedObject.qml
diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
index 77fab91..4228bc4 100644
--- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
+++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp
@@ -105,7 +105,7 @@ private slots:
void constantsOverrideBindings();
void outerBindingOverridesInnerBinding();
void aliasPropertyAndBinding();
- void nonExistantAttachedObject();
+ void nonExistentAttachedObject();
void scope();
void signalParameterTypes();
void objectsCompareAsEqual();
@@ -643,7 +643,7 @@ void tst_qdeclarativeecmascript::attachedProperties()
void tst_qdeclarativeecmascript::enums()
{
- // Existant enums
+ // Existent enums
{
QDeclarativeComponent component(&engine, TEST_FILE("enums.1.qml"));
QObject *object = component.create();
@@ -785,9 +785,9 @@ Access a non-existent attached object.
Tests for a regression where this used to crash.
*/
-void tst_qdeclarativeecmascript::nonExistantAttachedObject()
+void tst_qdeclarativeecmascript::nonExistentAttachedObject()
{
- QDeclarativeComponent component(&engine, TEST_FILE("nonExistantAttachedObject.qml"));
+ QDeclarativeComponent component(&engine, TEST_FILE("nonExistentAttachedObject.qml"));
QString warning = component.url().toString() + ":4: Unable to assign [undefined] to QString stringProperty";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
diff --git a/tests/auto/declarative/qdeclarativeflickable/data/resize.qml b/tests/auto/declarative/qdeclarativeflickable/data/resize.qml
new file mode 100644
index 0000000..e2abb99
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeflickable/data/resize.qml
@@ -0,0 +1,27 @@
+import QtQuick 1.1
+
+Rectangle {
+ function resizeContent() {
+ flick.resizeContent(600, 600, Qt.point(100, 100))
+ }
+ function returnToBounds() {
+ flick.returnToBounds()
+ }
+ width: 400
+ height: 360
+ color: "gray"
+
+ Flickable {
+ id: flick
+ objectName: "flick"
+ anchors.fill: parent
+ contentWidth: 300
+ contentHeight: 300
+
+ Rectangle {
+ width: flick.contentWidth
+ height: flick.contentHeight
+ color: "red"
+ }
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp
index 25edb36..c1564bc 100644
--- a/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp
+++ b/tests/auto/declarative/qdeclarativeflickable/tst_qdeclarativeflickable.cpp
@@ -46,6 +46,7 @@
#include <private/qdeclarativevaluetype_p.h>
#include <QtGui/qgraphicswidget.h>
#include <math.h>
+#include "../../../shared/util.h"
#ifdef Q_OS_SYMBIAN
// In Symbian OS test data is located in applications private dir
@@ -69,6 +70,8 @@ private slots:
void pressDelay();
void flickableDirection();
void qgraphicswidget();
+ void resizeContent();
+ void returnToBounds();
private:
QDeclarativeEngine engine;
@@ -277,6 +280,57 @@ void tst_qdeclarativeflickable::qgraphicswidget()
QVERIFY(widget);
}
+// QtQuick 1.1
+void tst_qdeclarativeflickable::resizeContent()
+{
+ QDeclarativeEngine engine;
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/resize.qml"));
+ QDeclarativeItem *root = qobject_cast<QDeclarativeItem*>(c.create());
+ QDeclarativeFlickable *obj = findItem<QDeclarativeFlickable>(root, "flick");
+
+ QVERIFY(obj != 0);
+ QCOMPARE(obj->contentX(), 0.);
+ QCOMPARE(obj->contentY(), 0.);
+ QCOMPARE(obj->contentWidth(), 300.);
+ QCOMPARE(obj->contentHeight(), 300.);
+
+ QMetaObject::invokeMethod(root, "resizeContent");
+
+ QCOMPARE(obj->contentX(), 100.);
+ QCOMPARE(obj->contentY(), 100.);
+ QCOMPARE(obj->contentWidth(), 600.);
+ QCOMPARE(obj->contentHeight(), 600.);
+
+ delete root;
+}
+
+// QtQuick 1.1
+void tst_qdeclarativeflickable::returnToBounds()
+{
+ QDeclarativeEngine engine;
+ QDeclarativeComponent c(&engine, QUrl::fromLocalFile(SRCDIR "/data/resize.qml"));
+ QDeclarativeItem *root = qobject_cast<QDeclarativeItem*>(c.create());
+ QDeclarativeFlickable *obj = findItem<QDeclarativeFlickable>(root, "flick");
+
+ QVERIFY(obj != 0);
+ QCOMPARE(obj->contentX(), 0.);
+ QCOMPARE(obj->contentY(), 0.);
+ QCOMPARE(obj->contentWidth(), 300.);
+ QCOMPARE(obj->contentHeight(), 300.);
+
+ obj->setContentX(100);
+ obj->setContentY(400);
+ QTRY_COMPARE(obj->contentX(), 100.);
+ QTRY_COMPARE(obj->contentY(), 400.);
+
+ QMetaObject::invokeMethod(root, "returnToBounds");
+
+ QTRY_COMPARE(obj->contentX(), 0.);
+ QTRY_COMPARE(obj->contentY(), 0.);
+
+ delete root;
+}
+
template<typename T>
T *tst_qdeclarativeflickable::findItem(QGraphicsObject *parent, const QString &objectName)
{
diff --git a/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp b/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp
index 447210d..27c7964 100644
--- a/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp
+++ b/tests/auto/declarative/qdeclarativeimage/tst_qdeclarativeimage.cpp
@@ -79,6 +79,8 @@ private slots:
void resized();
void preserveAspectRatio();
void smooth();
+ void mirror();
+ void mirror_data();
void svg();
void geometry();
void geometry_data();
@@ -124,19 +126,21 @@ void tst_qdeclarativeimage::imageSource_data()
QTest::addColumn<double>("height");
QTest::addColumn<bool>("remote");
QTest::addColumn<bool>("async");
+ QTest::addColumn<bool>("cached");
QTest::addColumn<QString>("error");
- QTest::newRow("local") << QUrl::fromLocalFile(SRCDIR "/data/colors.png").toString() << 120.0 << 120.0 << false << false << "";
- QTest::newRow("local async") << QUrl::fromLocalFile(SRCDIR "/data/colors1.png").toString() << 120.0 << 120.0 << false << true << "";
+ QTest::newRow("local") << QUrl::fromLocalFile(SRCDIR "/data/colors.png").toString() << 120.0 << 120.0 << false << false << true << "";
+ QTest::newRow("local no cache") << QUrl::fromLocalFile(SRCDIR "/data/colors.png").toString() << 120.0 << 120.0 << false << false << false << "";
+ QTest::newRow("local async") << QUrl::fromLocalFile(SRCDIR "/data/colors1.png").toString() << 120.0 << 120.0 << false << true << true << "";
QTest::newRow("local not found") << QUrl::fromLocalFile(SRCDIR "/data/no-such-file.png").toString() << 0.0 << 0.0 << false
- << false << "file::2:1: QML Image: Cannot open: " + QUrl::fromLocalFile(SRCDIR "/data/no-such-file.png").toString();
+ << false << true << "file::2:1: QML Image: Cannot open: " + QUrl::fromLocalFile(SRCDIR "/data/no-such-file.png").toString();
QTest::newRow("local async not found") << QUrl::fromLocalFile(SRCDIR "/data/no-such-file-1.png").toString() << 0.0 << 0.0 << false
- << true << "file::2:1: QML Image: Cannot open: " + QUrl::fromLocalFile(SRCDIR "/data/no-such-file-1.png").toString();
- QTest::newRow("remote") << SERVER_ADDR "/colors.png" << 120.0 << 120.0 << true << false << "";
- QTest::newRow("remote redirected") << SERVER_ADDR "/oldcolors.png" << 120.0 << 120.0 << true << false << "";
- QTest::newRow("remote svg") << SERVER_ADDR "/heart.svg" << 550.0 << 500.0 << true << false << "";
+ << true << true << "file::2:1: QML Image: Cannot open: " + QUrl::fromLocalFile(SRCDIR "/data/no-such-file-1.png").toString();
+ QTest::newRow("remote") << SERVER_ADDR "/colors.png" << 120.0 << 120.0 << true << false << true << "";
+ QTest::newRow("remote redirected") << SERVER_ADDR "/oldcolors.png" << 120.0 << 120.0 << true << false << false << "";
+ QTest::newRow("remote svg") << SERVER_ADDR "/heart.svg" << 550.0 << 500.0 << true << false << false << "";
QTest::newRow("remote not found") << SERVER_ADDR "/no-such-file.png" << 0.0 << 0.0 << true
- << false << "file::2:1: QML Image: Error downloading " SERVER_ADDR "/no-such-file.png - server replied: Not found";
+ << false << true << "file::2:1: QML Image: Error downloading " SERVER_ADDR "/no-such-file.png - server replied: Not found";
}
@@ -147,6 +151,7 @@ void tst_qdeclarativeimage::imageSource()
QFETCH(double, height);
QFETCH(bool, remote);
QFETCH(bool, async);
+ QFETCH(bool, cached);
QFETCH(QString, error);
TestHTTPServer server(SERVER_PORT);
@@ -160,7 +165,8 @@ void tst_qdeclarativeimage::imageSource()
QTest::ignoreMessage(QtWarningMsg, error.toUtf8());
QString componentStr = "import QtQuick 1.0\nImage { source: \"" + source + "\"; asynchronous: "
- + (async ? QLatin1String("true") : QLatin1String("false")) + " }";
+ + (async ? QLatin1String("true") : QLatin1String("false")) + "; cached: "
+ + (cached ? QLatin1String("true") : QLatin1String("false")) + " }";
QDeclarativeComponent component(&engine);
component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
QDeclarativeImage *obj = qobject_cast<QDeclarativeImage*>(component.create());
@@ -168,6 +174,13 @@ void tst_qdeclarativeimage::imageSource()
if (async)
QVERIFY(obj->asynchronous() == true);
+ else
+ QVERIFY(obj->asynchronous() == false);
+
+ if (cached)
+ QVERIFY(obj->cached() == true);
+ else
+ QVERIFY(obj->cached() == false);
if (remote || async)
QTRY_VERIFY(obj->status() == QDeclarativeImage::Loading);
@@ -259,6 +272,90 @@ void tst_qdeclarativeimage::smooth()
delete obj;
}
+void tst_qdeclarativeimage::mirror()
+{
+ QFETCH(int, fillMode);
+
+ qreal width = 300;
+ qreal height = 250;
+
+ QString src = QUrl::fromLocalFile(SRCDIR "/data/heart200.png").toString();
+ QString componentStr = "import QtQuick 1.0\nImage { source: \"" + src + "\"; }";
+
+ QDeclarativeComponent component(&engine);
+ component.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QDeclarativeImage *obj = qobject_cast<QDeclarativeImage*>(component.create());
+ QVERIFY(obj != 0);
+
+ obj->setProperty("width", width);
+ obj->setProperty("height", height);
+ obj->setFillMode((QDeclarativeImage::FillMode)fillMode);
+ obj->setProperty("mirror", true);
+
+ QGraphicsScene scene;
+ scene.addItem(qobject_cast<QGraphicsObject *>(obj));
+ QPixmap screenshot(width, height);
+ screenshot.fill();
+ QPainter p_screenshot(&screenshot);
+ scene.render(&p_screenshot, QRect(0, 0, width, height), QRect(0, 0, width, height));
+
+ QPixmap srcPixmap;
+ QVERIFY(srcPixmap.load(SRCDIR "/data/heart200.png"));
+
+ QPixmap expected(width, height);
+ expected.fill();
+ QPainter p_e(&expected);
+ QTransform transform;
+ transform.translate(width, 0).scale(-1, 1.0);
+ p_e.setTransform(transform);
+
+ switch (fillMode) {
+ case QDeclarativeImage::Stretch:
+ p_e.drawPixmap(QRect(0, 0, width, height), srcPixmap, QRect(0, 0, srcPixmap.width(), srcPixmap.height()));
+ break;
+ case QDeclarativeImage::PreserveAspectFit:
+ p_e.drawPixmap(QRect(25, 0, width / (width/height), height), srcPixmap, QRect(0, 0, srcPixmap.width(), srcPixmap.height()));
+ break;
+ case QDeclarativeImage::PreserveAspectCrop:
+ {
+ qreal ratio = width/srcPixmap.width(); // width is the longer side
+ QRect rect(0, 0, srcPixmap.width()*ratio, srcPixmap.height()*ratio);
+ rect.moveCenter(QRect(0, 0, width, height).center());
+ p_e.drawPixmap(rect, srcPixmap, QRect(0, 0, srcPixmap.width(), srcPixmap.height()));
+ break;
+ }
+ case QDeclarativeImage::Tile:
+ p_e.drawTiledPixmap(QRect(0, 0, width, height), srcPixmap);
+ break;
+ case QDeclarativeImage::TileVertically:
+ transform.scale(width / srcPixmap.width(), 1.0);
+ p_e.setTransform(transform);
+ p_e.drawTiledPixmap(QRect(0, 0, width, height), srcPixmap);
+ break;
+ case QDeclarativeImage::TileHorizontally:
+ transform.scale(1.0, height / srcPixmap.height());
+ p_e.setTransform(transform);
+ p_e.drawTiledPixmap(QRect(0, 0, width, height), srcPixmap);
+ break;
+ }
+
+ QCOMPARE(screenshot, expected);
+
+ delete obj;
+}
+
+void tst_qdeclarativeimage::mirror_data()
+{
+ QTest::addColumn<int>("fillMode");
+
+ QTest::newRow("Stretch") << int(QDeclarativeImage::Stretch);
+ QTest::newRow("PreserveAspectFit") << int(QDeclarativeImage::PreserveAspectFit);
+ QTest::newRow("PreserveAspectCrop") << int(QDeclarativeImage::PreserveAspectCrop);
+ QTest::newRow("Tile") << int(QDeclarativeImage::Tile);
+ QTest::newRow("TileVertically") << int(QDeclarativeImage::TileVertically);
+ QTest::newRow("TileHorizontally") << int(QDeclarativeImage::TileHorizontally);
+}
+
void tst_qdeclarativeimage::svg()
{
QString src = QUrl::fromLocalFile(SRCDIR "/data/heart.svg").toString();
diff --git a/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp b/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp
index 4470d65..304ce61 100644
--- a/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp
+++ b/tests/auto/declarative/qdeclarativeinstruction/tst_qdeclarativeinstruction.cpp
@@ -512,7 +512,7 @@ void tst_qdeclarativeinstruction::dump()
{
QDeclarativeInstruction i;
i.line = 50;
- i.type = (QDeclarativeInstruction::Type)(1234); // Non-existant
+ i.type = (QDeclarativeInstruction::Type)(1234); // Non-existent
data->bytecode << i;
}
diff --git a/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp b/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp
index 711bf00..9587254 100644
--- a/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp
+++ b/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp
@@ -65,6 +65,7 @@ private slots:
void keys();
void keysProcessingOrder();
void keyNavigation();
+ void keyNavigation_skipNotVisible();
void smooth();
void clip();
void mapCoordinates();
@@ -450,6 +451,84 @@ void tst_QDeclarativeItem::keyNavigation()
delete canvas;
}
+void tst_QDeclarativeItem::keyNavigation_skipNotVisible()
+{
+ QDeclarativeView *canvas = new QDeclarativeView(0);
+ canvas->setFixedSize(240,320);
+
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/keynavigationtest.qml"));
+ canvas->show();
+ qApp->processEvents();
+
+ QEvent wa(QEvent::WindowActivate);
+ QApplication::sendEvent(canvas, &wa);
+ QFocusEvent fe(QEvent::FocusIn);
+ QApplication::sendEvent(canvas, &fe);
+
+ QDeclarativeItem *item = findItem<QDeclarativeItem>(canvas->rootObject(), "item1");
+ QVERIFY(item);
+ QVERIFY(item->hasActiveFocus());
+
+ // Set item 2 to not visible
+ item = findItem<QDeclarativeItem>(canvas->rootObject(), "item2");
+ QVERIFY(item);
+ item->setVisible(false);
+ QVERIFY(!item->isVisible());
+
+ // right
+ QKeyEvent key(QEvent::KeyPress, Qt::Key_Right, Qt::NoModifier, "", false, 1);
+ QApplication::sendEvent(canvas, &key);
+ QVERIFY(key.isAccepted());
+
+ item = findItem<QDeclarativeItem>(canvas->rootObject(), "item1");
+ QVERIFY(item);
+ QVERIFY(item->hasActiveFocus());
+
+ // tab
+ key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
+ QApplication::sendEvent(canvas, &key);
+ QVERIFY(key.isAccepted());
+
+ item = findItem<QDeclarativeItem>(canvas->rootObject(), "item3");
+ QVERIFY(item);
+ QVERIFY(item->hasActiveFocus());
+
+ // backtab
+ key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
+ QApplication::sendEvent(canvas, &key);
+ QVERIFY(key.isAccepted());
+
+ item = findItem<QDeclarativeItem>(canvas->rootObject(), "item1");
+ QVERIFY(item);
+ QVERIFY(item->hasActiveFocus());
+
+ //Set item 3 to not visible
+ item = findItem<QDeclarativeItem>(canvas->rootObject(), "item3");
+ QVERIFY(item);
+ item->setVisible(false);
+ QVERIFY(!item->isVisible());
+
+ // tab
+ key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
+ QApplication::sendEvent(canvas, &key);
+ QVERIFY(key.isAccepted());
+
+ item = findItem<QDeclarativeItem>(canvas->rootObject(), "item4");
+ QVERIFY(item);
+ QVERIFY(item->hasActiveFocus());
+
+ // backtab
+ key = QKeyEvent(QEvent::KeyPress, Qt::Key_Backtab, Qt::NoModifier, "", false, 1);
+ QApplication::sendEvent(canvas, &key);
+ QVERIFY(key.isAccepted());
+
+ item = findItem<QDeclarativeItem>(canvas->rootObject(), "item1");
+ QVERIFY(item);
+ QVERIFY(item->hasActiveFocus());
+
+ delete canvas;
+}
+
void tst_QDeclarativeItem::smooth()
{
QDeclarativeComponent component(&engine);
diff --git a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp
index 50463b7..6410853 100644
--- a/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp
+++ b/tests/auto/declarative/qdeclarativelanguage/tst_qdeclarativelanguage.cpp
@@ -947,7 +947,7 @@ void tst_qdeclarativelanguage::aliasProperties()
object->setProperty("value", QVariant(13));
QCOMPARE(object->property("valueAlias").toInt(), 13);
- // Write throught alias
+ // Write through alias
object->setProperty("valueAlias", QVariant(19));
QCOMPARE(object->property("valueAlias").toInt(), 19);
QCOMPARE(object->property("value").toInt(), 19);
@@ -1109,7 +1109,7 @@ void tst_qdeclarativelanguage::aliasProperties()
object->setProperty("rectProperty", QVariant(QRect(33, 12, 99, 100)));
QCOMPARE(object->property("valueAlias").toRect(), QRect(33, 12, 99, 100));
- // Write throught alias
+ // Write through alias
object->setProperty("valueAlias", QVariant(QRect(3, 3, 4, 9)));
QCOMPARE(object->property("valueAlias").toRect(), QRect(3, 3, 4, 9));
QCOMPARE(object->property("rectProperty").toRect(), QRect(3, 3, 4, 9));
@@ -1129,7 +1129,7 @@ void tst_qdeclarativelanguage::aliasProperties()
object->setProperty("rectProperty", QVariant(QRect(33, 8, 102, 111)));
QCOMPARE(object->property("aliasProperty").toInt(), 33);
- // Write throught alias
+ // Write through alias
object->setProperty("aliasProperty", QVariant(4));
QCOMPARE(object->property("aliasProperty").toInt(), 4);
QCOMPARE(object->property("rectProperty").toRect(), QRect(4, 8, 102, 111));
diff --git a/tests/auto/declarative/qdeclarativelistmodel/data/setmodelcachelist.qml b/tests/auto/declarative/qdeclarativelistmodel/data/setmodelcachelist.qml
new file mode 100644
index 0000000..ffe417a
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativelistmodel/data/setmodelcachelist.qml
@@ -0,0 +1,20 @@
+import QtQuick 1.0
+
+ListModel {
+ id: model
+ property bool ok : false
+
+ Component.onCompleted: {
+ model.append({"attrs": []})
+ model.get(0)
+ model.set(0, {"attrs": [{'abc': 123, 'def': 456}] } )
+ ok = ( model.get(0).attrs.get(0).abc == 123
+ && model.get(0).attrs.get(0).def == 456 )
+
+ model.set(0, {"attrs": [{'abc': 789, 'def': 101}] } )
+ ok = ( model.get(0).attrs.get(0).abc == 789
+ && model.get(0).attrs.get(0).def == 101 )
+
+ }
+}
+
diff --git a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp
index 4b8d772..55f7421 100644
--- a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp
+++ b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp
@@ -100,6 +100,7 @@ private slots:
void get_nested();
void get_nested_data();
void crash_model_with_multiple_roles();
+ void set_model_cache();
};
int tst_qdeclarativelistmodel::roleFromName(const QDeclarativeListModel *model, const QString &roleName)
{
@@ -928,6 +929,17 @@ void tst_qdeclarativelistmodel::crash_model_with_multiple_roles()
model->setProperty(0, "black", true);
}
+//QTBUG-15190
+void tst_qdeclarativelistmodel::set_model_cache()
+{
+ QDeclarativeEngine eng;
+ QDeclarativeComponent component(&eng, QUrl::fromLocalFile(SRCDIR "/data/setmodelcachelist.qml"));
+ QObject *model = component.create();
+ QVERIFY2(component.errorString().isEmpty(), QTest::toString(component.errorString()));
+ QVERIFY(model != 0);
+ QVERIFY(model->property("ok").toBool());
+}
+
QTEST_MAIN(tst_qdeclarativelistmodel)
#include "tst_qdeclarativelistmodel.moc"
diff --git a/tests/auto/declarative/qdeclarativepincharea/data/pinchproperties.qml b/tests/auto/declarative/qdeclarativepincharea/data/pinchproperties.qml
new file mode 100644
index 0000000..f39ea06
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativepincharea/data/pinchproperties.qml
@@ -0,0 +1,46 @@
+import QtQuick 1.1
+Rectangle {
+ id: whiteRect
+ property variant center
+ property real scale
+ width: 240; height: 320
+ color: "white"
+ Rectangle {
+ id: blackRect
+ objectName: "blackrect"
+ color: "black"
+ y: 50
+ x: 50
+ width: 100
+ height: 100
+ opacity: (whiteRect.width-blackRect.x+whiteRect.height-blackRect.y-199)/200
+ Text { text: blackRect.opacity}
+ PinchArea {
+ id: pincharea
+ objectName: "pincharea"
+ anchors.fill: parent
+ pinch.target: blackRect
+ pinch.dragAxis: Drag.XandYAxis
+ pinch.minimumX: 0
+ pinch.maximumX: whiteRect.width-blackRect.width
+ pinch.minimumY: 0
+ pinch.maximumY: whiteRect.height-blackRect.height
+ pinch.minimumScale: 1.0
+ pinch.maximumScale: 2.0
+ pinch.minimumRotation: 0.0
+ pinch.maximumRotation: 90.0
+ onPinchStarted: {
+ whiteRect.center = pinch.center
+ whiteRect.scale = pinch.scale
+ }
+ onPinchChanged: {
+ whiteRect.center = pinch.center
+ whiteRect.scale = pinch.scale
+ }
+ onPinchFinished: {
+ whiteRect.center = pinch.center
+ whiteRect.scale = pinch.scale
+ }
+ }
+ }
+ }
diff --git a/tests/auto/declarative/qdeclarativepincharea/qdeclarativepincharea.pro b/tests/auto/declarative/qdeclarativepincharea/qdeclarativepincharea.pro
new file mode 100644
index 0000000..2c13644
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativepincharea/qdeclarativepincharea.pro
@@ -0,0 +1,16 @@
+load(qttest_p4)
+contains(QT_CONFIG,declarative): QT += declarative gui
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qdeclarativepincharea.cpp
+
+symbian: {
+ importFiles.sources = data
+ importFiles.path = .
+ DEPLOYMENT = importFiles
+} else {
+ DEFINES += SRCDIR=\\\"$$PWD\\\"
+}
+
+CONFIG += parallel_test
+
diff --git a/tests/auto/declarative/qdeclarativepincharea/tst_qdeclarativepincharea.cpp b/tests/auto/declarative/qdeclarativepincharea/tst_qdeclarativepincharea.cpp
new file mode 100644
index 0000000..d1015fc
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativepincharea/tst_qdeclarativepincharea.cpp
@@ -0,0 +1,315 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite 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$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QtTest/QSignalSpy>
+#include <private/qdeclarativepincharea_p.h>
+#include <private/qdeclarativerectangle_p.h>
+#include <QtDeclarative/qdeclarativeview.h>
+#include <QtDeclarative/qdeclarativecontext.h>
+
+#ifdef Q_OS_SYMBIAN
+// In Symbian OS test data is located in applications private dir
+#define SRCDIR "."
+#endif
+
+class tst_QDeclarativePinchArea: public QObject
+{
+ Q_OBJECT
+private slots:
+ void pinchProperties();
+ void scale();
+ void pan();
+
+private:
+ QDeclarativeView *createView();
+};
+
+void tst_QDeclarativePinchArea::pinchProperties()
+{
+ QDeclarativeView *canvas = createView();
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pinchproperties.qml"));
+ canvas->show();
+ canvas->setFocus();
+ QVERIFY(canvas->rootObject() != 0);
+
+ QDeclarativePinchArea *pinchArea = canvas->rootObject()->findChild<QDeclarativePinchArea*>("pincharea");
+ QDeclarativePinch *pinch = pinchArea->pinch();
+ QVERIFY(pinchArea != 0);
+ QVERIFY(pinch != 0);
+
+ // target
+ QDeclarativeItem *blackRect = canvas->rootObject()->findChild<QDeclarativeItem*>("blackrect");
+ QVERIFY(blackRect != 0);
+ QVERIFY(blackRect == pinch->target());
+ QDeclarativeItem *rootItem = qobject_cast<QDeclarativeItem*>(canvas->rootObject());
+ QVERIFY(rootItem != 0);
+ QSignalSpy targetSpy(pinch, SIGNAL(targetChanged()));
+ pinch->setTarget(rootItem);
+ QCOMPARE(targetSpy.count(),1);
+ pinch->setTarget(rootItem);
+ QCOMPARE(targetSpy.count(),1);
+
+ // axis
+ QCOMPARE(pinch->axis(), QDeclarativePinch::XandYAxis);
+ QSignalSpy axisSpy(pinch, SIGNAL(dragAxisChanged()));
+ pinch->setAxis(QDeclarativePinch::XAxis);
+ QCOMPARE(pinch->axis(), QDeclarativePinch::XAxis);
+ QCOMPARE(axisSpy.count(),1);
+ pinch->setAxis(QDeclarativePinch::XAxis);
+ QCOMPARE(axisSpy.count(),1);
+
+ // minimum and maximum drag properties
+ QSignalSpy xminSpy(pinch, SIGNAL(minimumXChanged()));
+ QSignalSpy xmaxSpy(pinch, SIGNAL(maximumXChanged()));
+ QSignalSpy yminSpy(pinch, SIGNAL(minimumYChanged()));
+ QSignalSpy ymaxSpy(pinch, SIGNAL(maximumYChanged()));
+
+ QCOMPARE(pinch->xmin(), 0.0);
+ QCOMPARE(pinch->xmax(), rootItem->width()-blackRect->width());
+ QCOMPARE(pinch->ymin(), 0.0);
+ QCOMPARE(pinch->ymax(), rootItem->height()-blackRect->height());
+
+ pinch->setXmin(10);
+ pinch->setXmax(10);
+ pinch->setYmin(10);
+ pinch->setYmax(10);
+
+ QCOMPARE(pinch->xmin(), 10.0);
+ QCOMPARE(pinch->xmax(), 10.0);
+ QCOMPARE(pinch->ymin(), 10.0);
+ QCOMPARE(pinch->ymax(), 10.0);
+
+ QCOMPARE(xminSpy.count(),1);
+ QCOMPARE(xmaxSpy.count(),1);
+ QCOMPARE(yminSpy.count(),1);
+ QCOMPARE(ymaxSpy.count(),1);
+
+ pinch->setXmin(10);
+ pinch->setXmax(10);
+ pinch->setYmin(10);
+ pinch->setYmax(10);
+
+ QCOMPARE(xminSpy.count(),1);
+ QCOMPARE(xmaxSpy.count(),1);
+ QCOMPARE(yminSpy.count(),1);
+ QCOMPARE(ymaxSpy.count(),1);
+
+ // minimum and maximum scale properties
+ QSignalSpy scaleMinSpy(pinch, SIGNAL(minimumScaleChanged()));
+ QSignalSpy scaleMaxSpy(pinch, SIGNAL(maximumScaleChanged()));
+
+ QCOMPARE(pinch->minimumScale(), 1.0);
+ QCOMPARE(pinch->maximumScale(), 2.0);
+
+ pinch->setMinimumScale(0.5);
+ pinch->setMaximumScale(1.5);
+
+ QCOMPARE(pinch->minimumScale(), 0.5);
+ QCOMPARE(pinch->maximumScale(), 1.5);
+
+ QCOMPARE(scaleMinSpy.count(),1);
+ QCOMPARE(scaleMaxSpy.count(),1);
+
+ pinch->setMinimumScale(0.5);
+ pinch->setMaximumScale(1.5);
+
+ QCOMPARE(scaleMinSpy.count(),1);
+ QCOMPARE(scaleMaxSpy.count(),1);
+
+ // minimum and maximum rotation properties
+ QSignalSpy rotMinSpy(pinch, SIGNAL(minimumRotationChanged()));
+ QSignalSpy rotMaxSpy(pinch, SIGNAL(maximumRotationChanged()));
+
+ QCOMPARE(pinch->minimumRotation(), 0.0);
+ QCOMPARE(pinch->maximumRotation(), 90.0);
+
+ pinch->setMinimumRotation(-90.0);
+ pinch->setMaximumRotation(45.0);
+
+ QCOMPARE(pinch->minimumRotation(), -90.0);
+ QCOMPARE(pinch->maximumRotation(), 45.0);
+
+ QCOMPARE(rotMinSpy.count(),1);
+ QCOMPARE(rotMaxSpy.count(),1);
+
+ pinch->setMinimumRotation(-90.0);
+ pinch->setMaximumRotation(45.0);
+
+ QCOMPARE(rotMinSpy.count(),1);
+ QCOMPARE(rotMaxSpy.count(),1);
+
+ delete canvas;
+}
+
+QTouchEvent::TouchPoint makeTouchPoint(int id, QPoint p, QGraphicsView *v, QGraphicsItem *i)
+{
+ QTouchEvent::TouchPoint touchPoint(id);
+ touchPoint.setPos(i->mapFromScene(p));
+ touchPoint.setScreenPos(v->mapToGlobal(p));
+ touchPoint.setScenePos(p);
+ return touchPoint;
+}
+
+void tst_QDeclarativePinchArea::scale()
+{
+ QDeclarativeView *canvas = createView();
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pinchproperties.qml"));
+ canvas->show();
+ canvas->setFocus();
+ QTest::qWaitForWindowShown(canvas);
+ QVERIFY(canvas->rootObject() != 0);
+ qApp->processEvents();
+
+ QDeclarativePinchArea *pinchArea = canvas->rootObject()->findChild<QDeclarativePinchArea*>("pincharea");
+ QDeclarativePinch *pinch = pinchArea->pinch();
+ QVERIFY(pinchArea != 0);
+ QVERIFY(pinch != 0);
+
+ QDeclarativeItem *root = qobject_cast<QDeclarativeItem*>(canvas->rootObject());
+ QVERIFY(root != 0);
+
+ // target
+ QDeclarativeItem *blackRect = canvas->rootObject()->findChild<QDeclarativeItem*>("blackrect");
+ QVERIFY(blackRect != 0);
+
+ QWidget *vp = canvas->viewport();
+
+ QPoint p1(80, 80);
+ QPoint p2(100, 100);
+
+ QTest::touchEvent(vp).press(0, p1);
+ QTest::touchEvent(vp).stationary(0).press(1, p2);
+ p1 -= QPoint(10,10);
+ p2 += QPoint(10,10);
+ QTest::touchEvent(vp).move(0, p1).move(1, p2);
+
+ QCOMPARE(root->property("scale").toReal(), 1.0);
+
+ p1 -= QPoint(10,10);
+ p2 += QPoint(10,10);
+ QTest::touchEvent(vp).move(0, p1).move(1, p2);
+
+ QCOMPARE(root->property("scale").toReal(), 1.5);
+ QCOMPARE(root->property("center").toPointF(), QPointF(90, 90));
+ QCOMPARE(blackRect->scale(), 1.5);
+
+ // scale beyond bound
+ p1 -= QPoint(50,50);
+ p2 += QPoint(50,50);
+ QTest::touchEvent(vp).move(0, p1).move(1, p2);
+
+ QCOMPARE(blackRect->scale(), 2.0);
+
+ QTest::touchEvent(vp).release(0, p1).release(1, p2);
+
+ delete canvas;
+}
+
+void tst_QDeclarativePinchArea::pan()
+{
+ QDeclarativeView *canvas = createView();
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/pinchproperties.qml"));
+ canvas->show();
+ canvas->setFocus();
+ QTest::qWaitForWindowShown(canvas);
+ QVERIFY(canvas->rootObject() != 0);
+ qApp->processEvents();
+
+ QDeclarativePinchArea *pinchArea = canvas->rootObject()->findChild<QDeclarativePinchArea*>("pincharea");
+ QDeclarativePinch *pinch = pinchArea->pinch();
+ QVERIFY(pinchArea != 0);
+ QVERIFY(pinch != 0);
+
+ QDeclarativeItem *root = qobject_cast<QDeclarativeItem*>(canvas->rootObject());
+ QVERIFY(root != 0);
+
+ // target
+ QDeclarativeItem *blackRect = canvas->rootObject()->findChild<QDeclarativeItem*>("blackrect");
+ QVERIFY(blackRect != 0);
+
+ QWidget *vp = canvas->viewport();
+
+ QPoint p1(80, 80);
+ QPoint p2(100, 100);
+
+ QTest::touchEvent(vp).press(0, p1);
+ QTest::touchEvent(vp).stationary(0).press(1, p2);
+ p1 += QPoint(10,10);
+ p2 += QPoint(10,10);
+ QTest::touchEvent(vp).move(0, p1).move(1, p2);
+
+ QCOMPARE(root->property("scale").toReal(), 1.0);
+
+ p1 += QPoint(10,10);
+ p2 += QPoint(10,10);
+ QTest::touchEvent(vp).move(0, p1).move(1, p2);
+
+ QCOMPARE(root->property("center").toPointF(), QPointF(110, 110));
+
+ QCOMPARE(blackRect->x(), 60.0);
+ QCOMPARE(blackRect->y(), 60.0);
+
+ // pan x beyond bound
+ p1 += QPoint(100,100);
+ p2 += QPoint(100,100);
+ QTest::touchEvent(vp).move(0, p1).move(1, p2);
+
+ QCOMPARE(blackRect->x(), 140.0);
+ QCOMPARE(blackRect->y(), 160.0);
+
+ QTest::touchEvent(vp).release(0, p1).release(1, p2);
+
+ delete canvas;
+}
+
+QDeclarativeView *tst_QDeclarativePinchArea::createView()
+{
+ QDeclarativeView *canvas = new QDeclarativeView(0);
+ canvas->viewport()->setAttribute(Qt::WA_AcceptTouchEvents);
+ canvas->setFixedSize(240,320);
+
+ return canvas;
+}
+
+QTEST_MAIN(tst_QDeclarativePinchArea)
+
+#include "tst_qdeclarativepincharea.moc"
diff --git a/tests/auto/declarative/qdeclarativeview/tst_qdeclarativeview.cpp b/tests/auto/declarative/qdeclarativeview/tst_qdeclarativeview.cpp
index 9ac79e4..efa5a9b 100644
--- a/tests/auto/declarative/qdeclarativeview/tst_qdeclarativeview.cpp
+++ b/tests/auto/declarative/qdeclarativeview/tst_qdeclarativeview.cpp
@@ -60,6 +60,7 @@ public:
tst_QDeclarativeView();
private slots:
+ void scene();
void resizemodedeclarativeitem();
void resizemodegraphicswidget();
void errors();
@@ -74,6 +75,26 @@ tst_QDeclarativeView::tst_QDeclarativeView()
{
}
+void tst_QDeclarativeView::scene()
+{
+ // QTBUG-14771
+ QGraphicsScene scene;
+ scene.setItemIndexMethod(QGraphicsScene::NoIndex);
+ scene.setStickyFocus(true);
+
+ QDeclarativeView *view = new QDeclarativeView();
+ QVERIFY(view);
+ QVERIFY(view->scene());
+ view->setScene(&scene);
+ QCOMPARE(view->scene(), &scene);
+
+ view->setSource(QUrl::fromLocalFile(SRCDIR "/data/resizemodedeclarativeitem.qml"));
+ QDeclarativeItem* declarativeItem = qobject_cast<QDeclarativeItem*>(view->rootObject());
+ QVERIFY(declarativeItem);
+ QVERIFY(scene.items().count() > 0);
+ QCOMPARE(scene.items().at(0), declarativeItem);
+}
+
void tst_QDeclarativeView::resizemodedeclarativeitem()
{
QWidget window;
diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-MAC/justify.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-MAC/justify.0.png
new file mode 100644
index 0000000..74c6934
--- /dev/null
+++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-MAC/justify.0.png
Binary files differ
diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-MAC/justify.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-MAC/justify.qml
new file mode 100644
index 0000000..e4dbeb1
--- /dev/null
+++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/align/data-MAC/justify.qml
@@ -0,0 +1,11 @@
+import Qt.VisualTest 4.7
+
+VisualTest {
+ Frame {
+ msec: 0
+ }
+ Frame {
+ msec: 16
+ image: "justify.0.png"
+ }
+}
diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetext/align/justify.qml b/tests/auto/declarative/qmlvisual/qdeclarativetext/align/justify.qml
new file mode 100644
index 0000000..c3a7aaa
--- /dev/null
+++ b/tests/auto/declarative/qmlvisual/qdeclarativetext/align/justify.qml
@@ -0,0 +1,22 @@
+import QtQuick 1.0
+import "../../shared" 1.0
+
+Rectangle {
+ width: 450
+ height: 250
+
+ TestText {
+ anchors.fill: parent
+ anchors { leftMargin: 10; rightMargin: 10; topMargin:10; bottomMargin: 10 }
+ wrapMode: Text.Wrap
+ horizontalAlignment: Text.AlignJustify
+
+ text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin a aliquet massa. Integer id velit a nibh imperdiet sagittis. Cras fringilla enim non nulla porta bibendum. Integer risus urna, hendrerit non interdum ut, dapibus id velit. Nullam fermentum viverra pellentesque. In molestie scelerisque lorem molestie ultrices. Curabitur dolor arcu, tristique in sodales in, varius sed diam. Quisque magna velit, tincidunt sed ullamcorper sit amet, ornare adipiscing ligula. In hac habitasse platea dictumst. Ut tincidunt urna vel mauris fermentum ornare quis a ligula. Suspendisse cursus volutpat sapien eget cursus."
+
+ Rectangle {
+ anchors.fill: parent
+ color: "transparent"
+ border.color: "red"
+ }
+ }
+}
diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-MAC/justify.0.png b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-MAC/justify.0.png
new file mode 100644
index 0000000..74c6934
--- /dev/null
+++ b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-MAC/justify.0.png
Binary files differ
diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-MAC/justify.qml b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-MAC/justify.qml
new file mode 100644
index 0000000..e4dbeb1
--- /dev/null
+++ b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/data-MAC/justify.qml
@@ -0,0 +1,11 @@
+import Qt.VisualTest 4.7
+
+VisualTest {
+ Frame {
+ msec: 0
+ }
+ Frame {
+ msec: 16
+ image: "justify.0.png"
+ }
+}
diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextedit/justify.qml b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/justify.qml
new file mode 100644
index 0000000..4aeb58c
--- /dev/null
+++ b/tests/auto/declarative/qmlvisual/qdeclarativetextedit/justify.qml
@@ -0,0 +1,22 @@
+import QtQuick 1.0
+import "../shared" 1.0
+
+Rectangle {
+ width: 450
+ height: 250
+
+ TestTextEdit {
+ anchors.fill: parent
+ anchors { leftMargin: 10; rightMargin: 10; topMargin:10; bottomMargin: 10 }
+ wrapMode: Text.Wrap
+ horizontalAlignment: Text.AlignJustify
+
+ text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin a aliquet massa. Integer id velit a nibh imperdiet sagittis. Cras fringilla enim non nulla porta bibendum. Integer risus urna, hendrerit non interdum ut, dapibus id velit. Nullam fermentum viverra pellentesque. In molestie scelerisque lorem molestie ultrices. Curabitur dolor arcu, tristique in sodales in, varius sed diam. Quisque magna velit, tincidunt sed ullamcorper sit amet, ornare adipiscing ligula. In hac habitasse platea dictumst. Ut tincidunt urna vel mauris fermentum ornare quis a ligula. Suspendisse cursus volutpat sapien eget cursus."
+
+ Rectangle {
+ anchors.fill: parent
+ color: "transparent"
+ border.color: "red"
+ }
+ }
+}
diff --git a/tests/auto/declarative/qperformancetimer/qperformancetimer.pro b/tests/auto/declarative/qperformancetimer/qperformancetimer.pro
new file mode 100644
index 0000000..656bf68
--- /dev/null
+++ b/tests/auto/declarative/qperformancetimer/qperformancetimer.pro
@@ -0,0 +1,7 @@
+load(qttest_p4)
+contains(QT_CONFIG,declarative): QT += declarative
+SOURCES += tst_qperformancetimer.cpp
+macx:CONFIG -= app_bundle
+
+CONFIG += parallel_test
+
diff --git a/tests/auto/declarative/qperformancetimer/tst_qperformancetimer.cpp b/tests/auto/declarative/qperformancetimer/tst_qperformancetimer.cpp
new file mode 100644
index 0000000..2029c8a
--- /dev/null
+++ b/tests/auto/declarative/qperformancetimer/tst_qperformancetimer.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** 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 test suite 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$
+**
+****************************************************************************/
+
+#include <private/qperformancetimer_p.h>
+#include <QObject>
+#include <qtest.h>
+
+class tst_qperformancetimer : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_qperformancetimer() {}
+
+private slots:
+ void units();
+};
+
+void tst_qperformancetimer::units()
+{
+ QPerformanceTimer timer;
+ timer.start();
+ QTest::qWait(300);
+ qint64 elapsed = timer.elapsed();
+ QVERIFY(elapsed > 300000000 && elapsed < 310000000);
+}
+
+QTEST_MAIN(tst_qperformancetimer)
+
+#include "tst_qperformancetimer.moc"
diff --git a/tests/benchmarks/declarative/qperformancetimer/qperformancetimer.pro b/tests/benchmarks/declarative/qperformancetimer/qperformancetimer.pro
new file mode 100644
index 0000000..a39cd3d
--- /dev/null
+++ b/tests/benchmarks/declarative/qperformancetimer/qperformancetimer.pro
@@ -0,0 +1,8 @@
+load(qttest_p4)
+QT += declarative
+TEMPLATE = app
+TARGET = tst_qperformancetimer
+macx:CONFIG -= app_bundle
+
+SOURCES += tst_qperformancetimer.cpp
+
diff --git a/tests/benchmarks/declarative/qperformancetimer/tst_qperformancetimer.cpp b/tests/benchmarks/declarative/qperformancetimer/tst_qperformancetimer.cpp
new file mode 100644
index 0000000..497a556
--- /dev/null
+++ b/tests/benchmarks/declarative/qperformancetimer/tst_qperformancetimer.cpp
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** 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 test suite 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$
+**
+****************************************************************************/
+
+#include <private/qperformancetimer_p.h>
+#include <QObject>
+#include <qtest.h>
+
+class tst_qperformancetimer : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_qperformancetimer() {}
+
+private slots:
+ void all();
+ void startElapsed();
+ void doubleElapsed();
+ void trace();
+};
+
+void tst_qperformancetimer::all()
+{
+ QBENCHMARK {
+ QPerformanceTimer t;
+ t.start();
+ t.elapsed();
+ }
+}
+
+void tst_qperformancetimer::startElapsed()
+{
+ QPerformanceTimer t;
+ QBENCHMARK {
+ t.start();
+ t.elapsed();
+ }
+}
+
+void tst_qperformancetimer::doubleElapsed()
+{
+ QPerformanceTimer t;
+ t.start();
+ QBENCHMARK {
+ t.elapsed();
+ t.elapsed();
+ }
+}
+
+void tst_qperformancetimer::trace()
+{
+ QString s("A decent sized string of text here.");
+ QBENCHMARK {
+ QByteArray data;
+ QDataStream ds(&data, QIODevice::WriteOnly);
+ ds << (qint64)100 << (int)5 << (int)5 << s;
+ }
+}
+
+QTEST_MAIN(tst_qperformancetimer)
+
+#include "tst_qperformancetimer.moc"
diff --git a/tools/qml/qml.pro b/tools/qml/qml.pro
index bdac6e3..9b07ebe 100644
--- a/tools/qml/qml.pro
+++ b/tools/qml/qml.pro
@@ -43,6 +43,11 @@ symbian {
contains(QT_CONFIG, s60): {
LIBS += -lavkon -lcone
}
+
+ # Deploy plugin for remote debugging
+ qmldebuggingplugin.sources = $$QT_BUILD_TREE/plugins/qmldebugging/tcpserver$${QT_LIBINFIX}.dll
+ qmldebuggingplugin.path = c:$$QT_PLUGINS_BASE_DIR/qmldebugging
+ DEPLOYMENT += qmldebuggingplugin
}
mac {
QMAKE_INFO_PLIST=Info_mac.plist