summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--demos/declarative/flickr/flickr-mobile.qml2
-rw-r--r--demos/declarative/flickr/mobile/TitleBar.qml7
-rw-r--r--doc/src/declarative/binding.qdoc2
-rw-r--r--examples/declarative/easing/easing.qml2
-rw-r--r--examples/declarative/focusscope/test.qml76
-rw-r--r--examples/declarative/focusscope/test2.qml40
-rw-r--r--examples/declarative/focusscope/test3.qml50
-rw-r--r--examples/declarative/follow/pong.qml2
-rw-r--r--examples/declarative/listview/itemlist.qml2
-rw-r--r--examples/declarative/minehunt/minehunt.qml2
-rw-r--r--examples/declarative/velocity/Day.qml2
-rw-r--r--examples/declarative/velocity/velocity.qml2
-rw-r--r--src/declarative/debugger/qpacketprotocol.cpp2
-rw-r--r--src/declarative/extra/extra.pri4
-rw-r--r--src/declarative/extra/qmlbehavior.cpp (renamed from src/declarative/extra/qmlbehaviour.cpp)74
-rw-r--r--src/declarative/extra/qmlbehavior.h (renamed from src/declarative/extra/qmlbehaviour.h)18
-rw-r--r--src/declarative/fx/qfxcomponentinstance.cpp2
-rw-r--r--src/declarative/fx/qfxflickable.cpp19
-rw-r--r--src/declarative/fx/qfxflickable.h2
-rw-r--r--src/declarative/fx/qfxfocusscope.cpp2
-rw-r--r--src/declarative/fx/qfxgridview.cpp7
-rw-r--r--src/declarative/fx/qfxitem.cpp67
-rw-r--r--src/declarative/fx/qfxitem_p.h3
-rw-r--r--src/declarative/fx/qfxlistview.cpp13
-rw-r--r--src/declarative/fx/qfxpathview_p.h2
-rw-r--r--src/declarative/fx/qfxrepeater.cpp130
-rw-r--r--src/declarative/fx/qfxrepeater.h19
-rw-r--r--src/declarative/fx/qfxrepeater_p.h1
-rw-r--r--src/declarative/fx/qfxtextinput.cpp14
-rw-r--r--src/declarative/qml/qml.h1
-rw-r--r--src/declarative/qml/qml.pri6
-rw-r--r--src/declarative/qml/qmlcompiler.cpp41
-rw-r--r--src/declarative/qml/qmlengine.cpp82
-rw-r--r--src/declarative/qml/qmlengine_p.h7
-rw-r--r--src/declarative/qml/qmlexpression.cpp2
-rw-r--r--src/declarative/qml/qmlinstruction.cpp2
-rw-r--r--src/declarative/qml/qmlinstruction_p.h1
-rw-r--r--src/declarative/qml/qmlmetaproperty.cpp2
-rw-r--r--src/declarative/qml/qmlmetatype.cpp30
-rw-r--r--src/declarative/qml/qmlmetatype.h20
-rw-r--r--src/declarative/qml/qmlpropertyvaluesource.cpp22
-rw-r--r--src/declarative/qml/qmlpropertyvaluesource.h23
-rw-r--r--src/declarative/qml/qmlvme.cpp9
-rw-r--r--src/declarative/qml/qmlxmlhttprequest.cpp535
-rw-r--r--src/declarative/qml/qmlxmlhttprequest_p.h60
-rw-r--r--src/declarative/util/qmlanimation.cpp18
-rw-r--r--src/declarative/util/qmlanimation.h2
-rw-r--r--src/declarative/util/qmlfollow.cpp2
-rw-r--r--src/declarative/util/qmlfollow.h3
-rw-r--r--src/declarative/util/qmlstate.cpp2
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp79
-rw-r--r--src/gui/graphicsview/qgraphicsitem.h4
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h40
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp117
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h2
-rw-r--r--tests/auto/declarative/qmlengine/functions.qml6
-rw-r--r--tests/auto/declarative/qmlengine/tst_qmlengine.cpp87
-rw-r--r--tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp71
-rw-r--r--tools/qmlviewer/main.cpp1
60 files changed, 1374 insertions, 473 deletions
diff --git a/.gitignore b/.gitignore
index 9e9898e..589f9d3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,9 +5,11 @@ examples/*/*/*
!examples/*/*/*[.]*
!examples/*/*/README
examples/*/*/*[.]app
+!examples/declarative/*
demos/*/*
!demos/*/*[.]*
demos/*/*[.]app
+!demos/declarative/*
config.tests/*/*/*
!config.tests/*/*/*[.]*
config.tests/*/*/*[.]app
diff --git a/demos/declarative/flickr/flickr-mobile.qml b/demos/declarative/flickr/flickr-mobile.qml
index ee6366d..a4692a3 100644
--- a/demos/declarative/flickr/flickr-mobile.qml
+++ b/demos/declarative/flickr/flickr-mobile.qml
@@ -33,7 +33,7 @@ Item {
}
}
- Mobile.ImageDetails { id: ImageDetails; width: parent.width; x: parent.width; height: parent.height }
+ Common.ImageDetails { id: ImageDetails; width: parent.width; x: parent.width; height: parent.height }
Mobile.TitleBar { id: TitleBar; width: parent.width; height: 40; opacity: 0.9 }
Mobile.ToolBar { id: ToolBar; height: 40; anchors.bottom: parent.bottom; width: parent.width; opacity: 0.9 }
diff --git a/demos/declarative/flickr/mobile/TitleBar.qml b/demos/declarative/flickr/mobile/TitleBar.qml
index 6d655a6..49d670f 100644
--- a/demos/declarative/flickr/mobile/TitleBar.qml
+++ b/demos/declarative/flickr/mobile/TitleBar.qml
@@ -3,6 +3,8 @@ import Qt 4.6
Item {
id: TitleBar
+ property string untaggedString: "Uploads from everyone"
+ property string taggedString: "Recent uploads tagged "
BorderImage { source: "images/titlebar2.sci"; width: parent.width; height: parent.height + 14; y: -7 }
Item {
@@ -22,13 +24,14 @@ Item {
anchors.leftMargin: 10; anchors.rightMargin: 10
anchors.verticalCenter: parent.verticalCenter
elide: "ElideLeft"
- text: (RssModel.tags=="" ? "Uploads from everyone" : "Recent Uploads tagged " + RssModel.tags)
+ text: (RssModel.tags=="" ? untaggedString : taggedString + RssModel.tags)
font.bold: true; color: "white"; style: "Raised"; styleColor: "black"
}
Button {
- id: TagButton; x: TitleBar.width - 50; y: 3; width: 45; height: 32; text: "..."
+ id: TagButton; x: TitleBar.width - 50; width: 45; height: 32; text: "..."
onClicked: if (TitleBar.state == "Tags") accept(); else TitleBar.state = "Tags"
+ anchors.verticalCenter: parent.verticalCenter
}
Item {
diff --git a/doc/src/declarative/binding.qdoc b/doc/src/declarative/binding.qdoc
index dfddf75..7e8933f 100644
--- a/doc/src/declarative/binding.qdoc
+++ b/doc/src/declarative/binding.qdoc
@@ -34,7 +34,7 @@ Data can be bound to C++ objects - see \l {QML/C++ Data Binding}.
\target qtbinding
\title QML/C++ Data Binding
-The QML mechanisms of \l {Data Binding} can also be used to bind Qt C++ objects.
+The QML mechanisms of data binding can also be used to bind Qt C++ objects.
The data binding framework is based on Qt's property system (see the Qt documentation for more details on this system). If a binding is meant to be dynamic (where changes in one object are reflected in another object), \c NOTIFY must be specified for the property being tracked. If \c NOTIFY is not specified, any binding to that property will be an 'intialization' binding (the tracking object will be updated only once with the initial value of the tracked object).
diff --git a/examples/declarative/easing/easing.qml b/examples/declarative/easing/easing.qml
index 60c2040..df301d8 100644
--- a/examples/declarative/easing/easing.qml
+++ b/examples/declarative/easing/easing.qml
@@ -56,7 +56,7 @@ Rectangle {
anchors.left: Window.left
anchors.right: Window.right
Repeater {
- dataSource: EasingTypes
+ model: EasingTypes
Component {
Text {
id: Text
diff --git a/examples/declarative/focusscope/test.qml b/examples/declarative/focusscope/test.qml
new file mode 100644
index 0000000..22ffc8d
--- /dev/null
+++ b/examples/declarative/focusscope/test.qml
@@ -0,0 +1,76 @@
+import Qt 4.6
+
+Rectangle {
+ color: "white"
+ width: 800
+ height: 600
+
+ Keys.onDigit9Pressed: print("Error - Root")
+
+ FocusScope {
+ id: MyScope
+ focus: true
+
+ Keys.onDigit9Pressed: print("Error - FocusScope")
+
+ Rectangle {
+ height: 120
+ width: 420
+
+ color: "transparent"
+ border.width: 5
+ border.color: MyScope.focus?"blue":"black"
+
+ Rectangle {
+ id: Item1
+ x: 10; y: 10
+ width: 100; height: 100; color: "green"
+ border.width: 5
+ border.color: focus?"blue":"black"
+ Keys.onDigit9Pressed: print("Top Left");
+ KeyNavigation.right: Item2
+ focus: true
+
+ Rectangle {
+ width: 50; height: 50; anchors.centerIn: parent
+ color: parent.activeFocus?"red":"transparent"
+ }
+ }
+
+ Rectangle {
+ id: Item2
+ x: 310; y: 10
+ width: 100; height: 100; color: "green"
+ border.width: 5
+ border.color: focus?"blue":"black"
+ KeyNavigation.left: Item1
+ Keys.onDigit9Pressed: print("Top Right");
+
+ Rectangle {
+ width: 50; height: 50; anchors.centerIn: parent
+ color: parent.activeFocus?"red":"transparent"
+ }
+ }
+ }
+ KeyNavigation.down: Item3
+ }
+
+ Text { x:100; y:170; text: "Blue border indicates scoped focus\nBlack border indicates NOT scoped focus\nRed box indicates active focus\nUse arrow keys to navigate\nPress \"9\" to print currently focused item" }
+
+ Rectangle {
+ id: Item3
+ x: 10; y: 300
+ width: 100; height: 100; color: "green"
+ border.width: 5
+ border.color: focus?"blue":"black"
+
+ Keys.onDigit9Pressed: print("Bottom Left");
+ KeyNavigation.up: MyScope
+
+ Rectangle {
+ width: 50; height: 50; anchors.centerIn: parent
+ color: parent.activeFocus?"red":"transparent"
+ }
+ }
+
+}
diff --git a/examples/declarative/focusscope/test2.qml b/examples/declarative/focusscope/test2.qml
new file mode 100644
index 0000000..0ac0f5d
--- /dev/null
+++ b/examples/declarative/focusscope/test2.qml
@@ -0,0 +1,40 @@
+import Qt 4.6
+
+Rectangle {
+ color: "white"
+ width: 800
+ height: 600
+
+ Text { text: "All five rectangles should be red" }
+
+ FocusScope {
+ y: 100
+ focus: true
+ Rectangle { width: 50; height: 50; color: parent.focus?"red":"blue" }
+
+ FocusScope {
+ y: 100
+ focus: true
+ Rectangle { width: 50; height: 50; color: parent.focus?"red":"blue" }
+
+ FocusScope {
+ y: 100
+ focus: true
+ Rectangle { width: 50; height: 50; color: parent.focus?"red":"blue" }
+
+ FocusScope {
+ y: 100
+ focus: true
+ Rectangle { width: 50; height: 50; color: parent.focus?"red":"blue" }
+
+ FocusScope {
+ y: 100
+ focus: true
+ Rectangle { width: 50; height: 50; color: parent.focus?"red":"blue" }
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/examples/declarative/focusscope/test3.qml b/examples/declarative/focusscope/test3.qml
new file mode 100644
index 0000000..51fa35a
--- /dev/null
+++ b/examples/declarative/focusscope/test3.qml
@@ -0,0 +1,50 @@
+import Qt 4.6
+
+Rectangle {
+ color: "white"
+ width: 800
+ height: 600
+
+ ListModel {
+ id: Model
+ ListElement { name: "1" }
+ ListElement { name: "2" }
+ ListElement { name: "3" }
+ ListElement { name: "4" }
+ ListElement { name: "5" }
+ ListElement { name: "6" }
+ ListElement { name: "6" }
+ ListElement { name: "8" }
+ ListElement { name: "9" }
+ }
+
+ Component {
+ id: VerticalDelegate
+ FocusScope {
+ id: Root
+ width: 50; height: 50;
+ Keys.onDigit9Pressed: print("Error - " + name)
+ Rectangle {
+ focus: true
+ Keys.onDigit9Pressed: print(name)
+ width: 50; height: 50;
+ color: Root.ListView.isCurrentItem?"red":"green"
+ Text { text: name; anchors.centerIn: parent }
+ }
+ }
+ }
+
+ ListView {
+ width: 800; height: 50; orientation: "Horizontal"
+ focus: true
+ model: Model
+ delegate: VerticalDelegate
+ currentItemPositioning: "SnapAuto"
+ }
+
+
+ Text {
+ y: 100; x: 50
+ text: "Currently selected element should be red\nPressing \"9\" should print the number of the currently selected item\nBe sure to scroll all the way to the right, pause, and then all the way to the left."
+ }
+}
diff --git a/examples/declarative/follow/pong.qml b/examples/declarative/follow/pong.qml
index d2aaba9..0314bb8 100644
--- a/examples/declarative/follow/pong.qml
+++ b/examples/declarative/follow/pong.qml
@@ -63,7 +63,7 @@ Rectangle {
Rectangle { color: "#00ee00"; x: Page.width/2+40; y: 0; width: 40; height: 60 }
Rectangle { color: "#000000"; x: Page.width/2+50; y: 10; width: 20; height: 40 }
Repeater {
- dataSource: Page.height/20
+ model: Page.height/20
Rectangle { color: "#00ee00"; x: Page.width/2-5; y: index*20; width: 10; height: 10 }
}
}
diff --git a/examples/declarative/listview/itemlist.qml b/examples/declarative/listview/itemlist.qml
index c25ee59..061fab3 100644
--- a/examples/declarative/listview/itemlist.qml
+++ b/examples/declarative/listview/itemlist.qml
@@ -44,7 +44,7 @@ Rectangle {
anchors.centerIn: parent
spacing: 20
Repeater {
- dataSource: ItemModel.count
+ model: ItemModel.count
Rectangle {
width: 5; height: 5
radius: 3
diff --git a/examples/declarative/minehunt/minehunt.qml b/examples/declarative/minehunt/minehunt.qml
index 11748a8..4bae64d 100644
--- a/examples/declarative/minehunt/minehunt.qml
+++ b/examples/declarative/minehunt/minehunt.qml
@@ -130,7 +130,7 @@ Item {
anchors.verticalCenter: parent.verticalCenter
}
Repeater {
- dataSource: tiles
+ model: tiles
x: 1
y: 1
Component {
diff --git a/examples/declarative/velocity/Day.qml b/examples/declarative/velocity/Day.qml
index e488ae1..1a336b7 100644
--- a/examples/declarative/velocity/Day.qml
+++ b/examples/declarative/velocity/Day.qml
@@ -26,7 +26,7 @@ Rectangle {
styleColor: "#dedede"
}
Repeater {
- dataSource: Page.stickies
+ model: Page.stickies
Item {
x: Math.random() * 200 + 100
y: Math.random() * 300 + 50
diff --git a/examples/declarative/velocity/velocity.qml b/examples/declarative/velocity/velocity.qml
index c2425da..8ac42e1 100644
--- a/examples/declarative/velocity/velocity.qml
+++ b/examples/declarative/velocity/velocity.qml
@@ -101,7 +101,7 @@ Rectangle {
Row {
id: Lay
Repeater {
- dataSource: List
+ model: List
Component {
Day {
day: name
diff --git a/src/declarative/debugger/qpacketprotocol.cpp b/src/declarative/debugger/qpacketprotocol.cpp
index 6bccf4b..84882dd 100644
--- a/src/declarative/debugger/qpacketprotocol.cpp
+++ b/src/declarative/debugger/qpacketprotocol.cpp
@@ -391,7 +391,7 @@ QIODevice * QPacketProtocol::device()
Only packets returned from QPacketProtocol::read() may be read from. QPacket
instances constructed by directly by applications are for transmission only
and are considered "write only". Attempting to read data from them will
- result in undefined behaviour.
+ result in undefined behavior.
\ingroup io
\sa QPacketProtocol
diff --git a/src/declarative/extra/extra.pri b/src/declarative/extra/extra.pri
index 1f84406..ae07a19 100644
--- a/src/declarative/extra/extra.pri
+++ b/src/declarative/extra/extra.pri
@@ -7,7 +7,7 @@ SOURCES += \
extra/qfxanimatedimageitem.cpp \
extra/qfxflowview.cpp \
extra/qfxparticles.cpp \
- extra/qmlbehaviour.cpp \
+ extra/qmlbehavior.cpp \
extra/qbindablemap.cpp \
extra/qmlfontloader.cpp
@@ -21,7 +21,7 @@ HEADERS += \
extra/qfxanimatedimageitem_p.h \
extra/qfxflowview.h \
extra/qfxparticles.h \
- extra/qmlbehaviour.h \
+ extra/qmlbehavior.h \
extra/qbindablemap.h \
extra/qmlfontloader.h
diff --git a/src/declarative/extra/qmlbehaviour.cpp b/src/declarative/extra/qmlbehavior.cpp
index 767f1ed..7784ef5 100644
--- a/src/declarative/extra/qmlbehaviour.cpp
+++ b/src/declarative/extra/qmlbehavior.cpp
@@ -42,19 +42,19 @@
#include <private/qobject_p.h>
#include "qmlanimation.h"
#include "qmltransition.h"
-#include "qmlbehaviour.h"
+#include "qmlbehavior.h"
#include <QtDeclarative/qmlcontext.h>
#include <QtCore/qparallelanimationgroup.h>
QT_BEGIN_NAMESPACE
-QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Behavior,QmlBehaviour)
+QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Behavior,QmlBehavior)
-class QmlBehaviourData : public QObject
+class QmlBehaviorData : public QObject
{
Q_OBJECT
public:
- QmlBehaviourData(QObject *parent)
+ QmlBehaviorData(QObject *parent)
: QObject(parent) {}
Q_PROPERTY(QVariant endValue READ endValue NOTIFY valuesChanged)
@@ -69,13 +69,13 @@ Q_SIGNALS:
void valuesChanged();
private:
- friend class QmlBehaviour;
+ friend class QmlBehavior;
};
-class QmlBehaviourPrivate : public QObjectPrivate
+class QmlBehaviorPrivate : public QObjectPrivate
{
public:
- QmlBehaviourPrivate() : operations(this) {}
+ QmlBehaviorPrivate() : operations(this) {}
QmlMetaProperty property;
QVariant currentValue;
@@ -84,7 +84,7 @@ public:
class AnimationList : public QmlConcreteList<QmlAbstractAnimation *>
{
public:
- AnimationList(QmlBehaviourPrivate *parent) : _parent(parent) {}
+ AnimationList(QmlBehaviorPrivate *parent) : _parent(parent) {}
virtual void append(QmlAbstractAnimation *a)
{
QmlConcreteList<QmlAbstractAnimation *>::append(a);
@@ -95,14 +95,14 @@ public:
}
virtual void clear() { QmlConcreteList<QmlAbstractAnimation *>::clear(); } //###
private:
- QmlBehaviourPrivate *_parent;
+ QmlBehaviorPrivate *_parent;
};
AnimationList operations;
QParallelAnimationGroup *group;
};
/*!
- \qmlclass Behavior QmlBehaviour
+ \qmlclass Behavior QmlBehavior
\brief The Behavior element allows you to specify a default animation for a property change.
In example below, the rect will use a bounce easing curve over 200 millisecond for any changes to its y property:
@@ -121,77 +121,77 @@ public:
\endcode
*/
-QmlBehaviour::QmlBehaviour(QObject *parent)
-: QmlPropertyValueSource(*(new QmlBehaviourPrivate), parent)
+QmlBehavior::QmlBehavior(QObject *parent)
+: QObject(*(new QmlBehaviorPrivate), parent)
{
- Q_D(QmlBehaviour);
+ Q_D(QmlBehavior);
d->group = new QParallelAnimationGroup;
QFx_setParent_noEvent(d->group, this);
}
/*!
- \qmlproperty QVariant Behavior::fromValue
- This property holds a selector specifying a starting value for the behavior
+ \qmlproperty QVariant Behavior::from
+ This property holds a selector specifying a starting value for the behavior.
If you only want the behavior to apply when the change starts at a
specific value you can specify fromValue. This selector is used in conjunction
- with the toValue selector.
+ with the to selector.
*/
-QVariant QmlBehaviour::fromValue() const
+QVariant QmlBehavior::fromValue() const
{
- Q_D(const QmlBehaviour);
+ Q_D(const QmlBehavior);
return d->fromValue;
}
-void QmlBehaviour::setFromValue(const QVariant &v)
+void QmlBehavior::setFromValue(const QVariant &v)
{
- Q_D(QmlBehaviour);
+ Q_D(QmlBehavior);
d->fromValue = v;
}
/*!
- \qmlproperty QVariant Behavior::toValue
- This property holds a selector specifying a ending value for the behavior
+ \qmlproperty QVariant Behavior::to
+ This property holds a selector specifying a ending value for the behavior.
If you only want the behavior to apply when the change ends at a
specific value you can specify toValue. This selector is used in conjunction
- with the fromValue selector.
+ with the from selector.
*/
-QVariant QmlBehaviour::toValue() const
+QVariant QmlBehavior::toValue() const
{
- Q_D(const QmlBehaviour);
+ Q_D(const QmlBehavior);
return d->toValue;
}
-void QmlBehaviour::setToValue(const QVariant &v)
+void QmlBehavior::setToValue(const QVariant &v)
{
- Q_D(QmlBehaviour);
+ Q_D(QmlBehavior);
d->toValue = v;
}
-QmlList<QmlAbstractAnimation *>* QmlBehaviour::operations()
+QmlList<QmlAbstractAnimation *>* QmlBehavior::operations()
{
- Q_D(QmlBehaviour);
+ Q_D(QmlBehavior);
return &d->operations;
}
-QmlBehaviour::~QmlBehaviour()
+QmlBehavior::~QmlBehavior()
{
//### do we need any other cleanup here?
}
-bool QmlBehaviour::_ignore = false;
-void QmlBehaviour::propertyValueChanged()
+bool QmlBehavior::_ignore = false;
+void QmlBehavior::propertyValueChanged()
{
- Q_D(QmlBehaviour);
+ Q_D(QmlBehavior);
if (_ignore)
return;
QVariant newValue = d->property.read();
- if ((!fromValue().isValid() || fromValue() == d->currentValue) &&
+ if ((!fromValue().isValid() || fromValue() == d->currentValue) &&
(!toValue().isValid() || toValue() == newValue)) {
//### does this clean up everything needed?
@@ -220,9 +220,9 @@ void QmlBehaviour::propertyValueChanged()
d->currentValue = newValue;
}
-void QmlBehaviour::setTarget(const QmlMetaProperty &property)
+void QmlBehavior::setTarget(const QmlMetaProperty &property)
{
- Q_D(QmlBehaviour);
+ Q_D(QmlBehavior);
d->property = property;
d->currentValue = property.read();
d->property.connectNotifier(this, SLOT(propertyValueChanged()));
@@ -233,4 +233,4 @@ void QmlBehaviour::setTarget(const QmlMetaProperty &property)
QT_END_NAMESPACE
-#include "qmlbehaviour.moc"
+#include "qmlbehavior.moc"
diff --git a/src/declarative/extra/qmlbehaviour.h b/src/declarative/extra/qmlbehavior.h
index 99fc779..a4a0679 100644
--- a/src/declarative/extra/qmlbehaviour.h
+++ b/src/declarative/extra/qmlbehavior.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QMLBEHAVIOUR_H
-#define QMLBEHAVIOUR_H
+#ifndef QMLBEHAVIOR_H
+#define QMLBEHAVIOR_H
#include <QtDeclarative/qmlpropertyvaluesource.h>
#include <QtDeclarative/qml.h>
@@ -53,11 +53,11 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
class QmlAbstractAnimation;
-class QmlBehaviourPrivate;
-class Q_DECLARATIVE_EXPORT QmlBehaviour : public QmlPropertyValueSource
+class QmlBehaviorPrivate;
+class Q_DECLARATIVE_EXPORT QmlBehavior : public QObject, public QmlPropertyValueSource
{
Q_OBJECT
- Q_DECLARE_PRIVATE(QmlBehaviour)
+ Q_DECLARE_PRIVATE(QmlBehavior)
Q_PROPERTY(QVariant from READ fromValue WRITE setFromValue)
Q_PROPERTY(QVariant to READ toValue WRITE setToValue)
@@ -65,8 +65,8 @@ class Q_DECLARATIVE_EXPORT QmlBehaviour : public QmlPropertyValueSource
Q_PROPERTY(QmlList<QmlAbstractAnimation *>* operations READ operations)
public:
- QmlBehaviour(QObject *parent=0);
- ~QmlBehaviour();
+ QmlBehavior(QObject *parent=0);
+ ~QmlBehavior();
QVariant fromValue() const;
void setFromValue(const QVariant &);
@@ -84,8 +84,8 @@ private Q_SLOTS:
QT_END_NAMESPACE
-QML_DECLARE_TYPE(QmlBehaviour)
+QML_DECLARE_TYPE(QmlBehavior)
QT_END_HEADER
-#endif // QMLBEHAVIOUR_H
+#endif // QMLBEHAVIOR_H
diff --git a/src/declarative/fx/qfxcomponentinstance.cpp b/src/declarative/fx/qfxcomponentinstance.cpp
index def7a9f..7a712aa 100644
--- a/src/declarative/fx/qfxcomponentinstance.cpp
+++ b/src/declarative/fx/qfxcomponentinstance.cpp
@@ -73,13 +73,11 @@ QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,ComponentInstance,QFxComponentIn
QFxComponentInstance::QFxComponentInstance(QFxItem *parent)
: QFxItem(*(new QFxComponentInstancePrivate), parent)
{
- setFlag(QGraphicsItem::ItemAutoDetectsFocusProxy);
}
QFxComponentInstance::QFxComponentInstance(QFxComponentInstancePrivate &dd, QFxItem *parent)
: QFxItem(dd, parent)
{
- setFlag(QGraphicsItem::ItemAutoDetectsFocusProxy);
}
/*!
diff --git a/src/declarative/fx/qfxflickable.cpp b/src/declarative/fx/qfxflickable.cpp
index 428815a..440c1ca 100644
--- a/src/declarative/fx/qfxflickable.cpp
+++ b/src/declarative/fx/qfxflickable.cpp
@@ -607,7 +607,6 @@ void QFxFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event)
void QFxFlickablePrivate::handleMouseReleaseEvent(QGraphicsSceneMouseEvent *)
{
Q_Q(QFxFlickable);
-
pressed = false;
if (lastPosTime.isNull())
return;
@@ -871,13 +870,8 @@ void QFxFlickable::setViewportWidth(int w)
else
d->_flick->setWidth(w);
// Make sure that we're entirely in view.
- if (d->_moveX.value() > minXExtent() || maxXExtent() > 0) {
- d->_tl.clear();
- d->_moveX.setValue(minXExtent());
- } else if (d->_moveX.value() < maxXExtent()) {
- d->_tl.clear();
- d->_moveX.setValue(maxXExtent());
- }
+ if (!d->pressed)
+ d->fixupX();
emit viewportWidthChanged();
d->updateBeginningEnd();
}
@@ -919,13 +913,8 @@ void QFxFlickable::setViewportHeight(int h)
else
d->_flick->setHeight(h);
// Make sure that we're entirely in view.
- if (d->_moveY.value() > minYExtent() || maxYExtent() > 0) {
- d->_tl.clear();
- d->_moveY.setValue(minYExtent());
- } else if (d->_moveY.value() < maxYExtent()) {
- d->_tl.clear();
- d->_moveY.setValue(maxYExtent());
- }
+ if (!d->pressed)
+ d->fixupY();
emit viewportHeightChanged();
d->updateBeginningEnd();
}
diff --git a/src/declarative/fx/qfxflickable.h b/src/declarative/fx/qfxflickable.h
index e13fa9b..13d793f 100644
--- a/src/declarative/fx/qfxflickable.h
+++ b/src/declarative/fx/qfxflickable.h
@@ -70,7 +70,7 @@ class Q_DECLARATIVE_EXPORT QFxFlickable : public QFxItem
Q_PROPERTY(bool flicking READ isFlicking NOTIFY flickingChanged)
Q_PROPERTY(bool locked READ isLocked WRITE setLocked) //### interactive, ensure flicking is stopped, etc.
- Q_PROPERTY(DragMode dragMode READ dragMode WRITE setDragMode) //### remove. Consider a better way to implement different drag behaviour
+ Q_PROPERTY(DragMode dragMode READ dragMode WRITE setDragMode) //### remove. Consider a better way to implement different drag behavior
Q_PROPERTY(bool atXEnd READ isAtXEnd NOTIFY isAtBoundaryChanged)
Q_PROPERTY(bool atYEnd READ isAtYEnd NOTIFY isAtBoundaryChanged)
diff --git a/src/declarative/fx/qfxfocusscope.cpp b/src/declarative/fx/qfxfocusscope.cpp
index 8981256..9bcc17e 100644
--- a/src/declarative/fx/qfxfocusscope.cpp
+++ b/src/declarative/fx/qfxfocusscope.cpp
@@ -63,7 +63,7 @@ QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,FocusScope,QFxFocusScope)
QFxFocusScope::QFxFocusScope(QFxItem *parent) :
QFxItem(parent)
{
- setFlag(QGraphicsItem::ItemAutoDetectsFocusProxy);
+ setFlag(QGraphicsItem::ItemIsFocusScope);
}
QFxFocusScope::~QFxFocusScope()
diff --git a/src/declarative/fx/qfxgridview.cpp b/src/declarative/fx/qfxgridview.cpp
index e2c7fa3..bf6e863 100644
--- a/src/declarative/fx/qfxgridview.cpp
+++ b/src/declarative/fx/qfxgridview.cpp
@@ -325,7 +325,7 @@ public:
void QFxGridViewPrivate::init()
{
Q_Q(QFxGridView);
- q->setFlag(QGraphicsItem::ItemAutoDetectsFocusProxy);
+ q->setFlag(QGraphicsItem::ItemIsFocusScope);
QObject::connect(q, SIGNAL(widthChanged()), q, SLOT(sizeChange()));
QObject::connect(q, SIGNAL(heightChanged()), q, SLOT(sizeChange()));
}
@@ -1254,6 +1254,7 @@ void QFxGridView::itemsInserted(int modelIndex, int count)
void QFxGridView::itemsRemoved(int modelIndex, int count)
{
Q_D(QFxGridView);
+ bool currentRemoved = d->currentIndex >= modelIndex && d->currentIndex < modelIndex + count;
int index = d->mapFromModel(modelIndex);
if (index == -1) {
if (modelIndex + count - 1 < d->visibleIndex) {
@@ -1269,7 +1270,7 @@ void QFxGridView::itemsRemoved(int modelIndex, int count)
d->currentIndex -= count;
if (d->currentItem)
d->currentItem->index -= count;
- } else if (d->currentIndex >= modelIndex && d->currentIndex < modelIndex + count) {
+ } else if (currentRemoved) {
// current item has been removed.
d->releaseItem(d->currentItem);
d->currentItem = 0;
@@ -1311,7 +1312,7 @@ void QFxGridView::itemsRemoved(int modelIndex, int count)
d->currentIndex -= count;
if (d->currentItem)
d->currentItem->index -= count;
- } else if (d->currentIndex >= modelIndex && d->currentIndex < modelIndex + count) {
+ } else if (currentRemoved) {
// current item has been removed.
d->releaseItem(d->currentItem);
d->currentItem = 0;
diff --git a/src/declarative/fx/qfxitem.cpp b/src/declarative/fx/qfxitem.cpp
index 8bdc2de..9b9355e 100644
--- a/src/declarative/fx/qfxitem.cpp
+++ b/src/declarative/fx/qfxitem.cpp
@@ -1152,11 +1152,12 @@ QFxItem::~QFxItem()
QFxAnchors *anchor = d->dependantAnchors.at(ii);
anchor->d_func()->clearItem(this);
}
- for (int ii = 0; ii < d->dependantAnchors.count(); ++ii) {
- QFxAnchors *anchor = d->dependantAnchors.at(ii);
- if (anchor->d_func()->item && anchor->d_func()->item->parentItem() != this) //child will be deleted anyway
- anchor->d_func()->updateOnComplete();
- }
+ if (!d->parent || (parentItem() && !parentItem()->QGraphicsItem::d_ptr->inDestructor))
+ for (int ii = 0; ii < d->dependantAnchors.count(); ++ii) {
+ QFxAnchors *anchor = d->dependantAnchors.at(ii);
+ if (anchor->d_func()->item && anchor->d_func()->item->parentItem() != this) //child will be deleted anyway
+ anchor->d_func()->updateOnComplete();
+ }
delete d->_anchorLines; d->_anchorLines = 0;
delete d->_anchors; d->_anchors = 0;
}
@@ -2362,7 +2363,14 @@ QPointF QFxItemPrivate::computeTransformOrigin() const
*/
bool QFxItem::sceneEvent(QEvent *event)
{
- return QGraphicsItem::sceneEvent(event);
+ bool rv = QGraphicsItem::sceneEvent(event);
+
+ if (event->type() == QEvent::FocusIn ||
+ event->type() == QEvent::FocusOut) {
+ activeFocusChanged(hasActiveFocus());
+ }
+
+ return rv;
}
/*!
@@ -2547,49 +2555,20 @@ bool QFxItem::heightValid() const
bool QFxItem::hasFocus() const
{
- const QGraphicsItem *current = this->parentItem();
- while (current && !(current->flags() & ItemAutoDetectsFocusProxy))
- current = current->parentItem();
-
- if (current)
- return current->focusProxy() == this;
- else
- return QGraphicsItem::hasFocus();
+ Q_D(const QFxItem);
+ return d->itemIsFocusedInScope;
}
void QFxItem::setFocus(bool focus)
{
- QGraphicsScene *s = scene();
- if (!s) {
- if (focus) QGraphicsItem::setFocus(Qt::OtherFocusReason);
- else QGraphicsItem::clearFocus();
- focusChanged(focus);
- return;
- }
-
- QGraphicsItem *current = this->parentItem();
- while (current && !(current->flags() & ItemAutoDetectsFocusProxy))
- current = current->parentItem();
-
- if (!current) {
- if (focus) QGraphicsItem::setFocus(Qt::OtherFocusReason);
- else QGraphicsItem::clearFocus();
- focusChanged(focus);
- return;
- }
-
- if (current->focusProxy() && current->focusProxy() != this) {
- QFxItem *currentItem = qobject_cast<QFxItem *>(current->focusProxy());
- if (currentItem)
- currentItem->setFocus(false);
- }
-
- if (current->focusProxy() == this && !focus)
- current->setFocusProxy(0);
- else if (focus)
- current->setFocusProxy(this);
+ if (focus) QGraphicsItem::setFocus(Qt::OtherFocusReason);
+ else QGraphicsItem::clearFocus();
+}
- focusChanged(focus);
+void QFxItemPrivate::focusedInScopeChanged()
+{
+ Q_Q(QFxItem);
+ q->focusChanged(q->hasFocus());
}
/*!
diff --git a/src/declarative/fx/qfxitem_p.h b/src/declarative/fx/qfxitem_p.h
index d30e324..054bdc7 100644
--- a/src/declarative/fx/qfxitem_p.h
+++ b/src/declarative/fx/qfxitem_p.h
@@ -223,6 +223,9 @@ public:
QGraphicsItemPrivate::setPosHelper(pos);
q->geometryChanged(QRectF(this->pos.x(), this->pos.y(), width, height), oldGeometry);
}
+
+ // Inherited from QGraphcisItemPrivate
+ virtual void focusedInScopeChanged();
};
QT_END_NAMESPACE
diff --git a/src/declarative/fx/qfxlistview.cpp b/src/declarative/fx/qfxlistview.cpp
index 048cb0f..c1e03dd 100644
--- a/src/declarative/fx/qfxlistview.cpp
+++ b/src/declarative/fx/qfxlistview.cpp
@@ -396,7 +396,7 @@ public:
void QFxListViewPrivate::init()
{
Q_Q(QFxListView);
- q->setFlag(QGraphicsItem::ItemAutoDetectsFocusProxy);
+ q->setFlag(QGraphicsItem::ItemIsFocusScope);
QObject::connect(q, SIGNAL(heightChanged()), q, SLOT(refill()));
QObject::connect(q, SIGNAL(widthChanged()), q, SLOT(refill()));
}
@@ -894,7 +894,7 @@ QFxListView::~QFxListView()
provided by a C++ model object. The C++ model object must be a \l
{QAbstractItemModel} subclass, a VisualModel, or a simple list.
- Models can also be created directly in QML, using a \l{ListModel}.
+ Models can also be created directly in QML, using a \l{ListModel} or \l{XmlListModel}.
*/
QVariant QFxListView::model() const
{
@@ -1396,13 +1396,14 @@ void QFxListView::trackedPositionChanged()
case Free:
if (d->trackedItem->position() < d->position()) {
d->setPosition(d->trackedItem->position());
+ d->fixupPosition();
} else if (d->trackedItem->endPosition() > d->position() + d->size()) {
qreal pos = d->trackedItem->endPosition() - d->size();
if (d->trackedItem->size() > d->size())
pos = d->trackedItem->position();
d->setPosition(pos);
+ d->fixupPosition();
}
- d->fixupPosition();
break;
case Snap:
if (d->trackedItem->position() < d->startPosition() + d->snapPos)
@@ -1521,6 +1522,7 @@ void QFxListView::itemsRemoved(int modelIndex, int count)
{
Q_D(QFxListView);
d->updateUnrequestedIndexes();
+ bool currentRemoved = d->currentIndex >= modelIndex && d->currentIndex < modelIndex + count;
if (!d->mapRangeFromModel(modelIndex, count)) {
if (modelIndex + count - 1 < d->visibleIndex) {
// Items removed before our visible items.
@@ -1535,7 +1537,7 @@ void QFxListView::itemsRemoved(int modelIndex, int count)
d->currentIndex -= count;
if (d->currentItem)
d->currentItem->index -= count;
- } else if (d->currentIndex >= modelIndex && d->currentIndex < modelIndex + count) {
+ } else if (currentRemoved) {
// current item has been removed.
d->releaseItem(d->currentItem);
d->currentItem = 0;
@@ -1578,8 +1580,9 @@ void QFxListView::itemsRemoved(int modelIndex, int count)
d->currentIndex -= count;
if (d->currentItem)
d->currentItem->index -= count;
- } else if (d->currentIndex >= modelIndex && d->currentIndex < modelIndex + count) {
+ } else if (currentRemoved) {
// current item has been removed.
+ d->currentItem->attached->setIsCurrentItem(false);
d->releaseItem(d->currentItem);
d->currentItem = 0;
d->currentIndex = -1;
diff --git a/src/declarative/fx/qfxpathview_p.h b/src/declarative/fx/qfxpathview_p.h
index a69f75f..60bfdb3 100644
--- a/src/declarative/fx/qfxpathview_p.h
+++ b/src/declarative/fx/qfxpathview_p.h
@@ -87,7 +87,7 @@ public:
Q_Q(QFxPathView);
_offset = 0;
q->setAcceptedMouseButtons(Qt::LeftButton);
- q->setFlag(QGraphicsItem::ItemAutoDetectsFocusProxy);
+ q->setFlag(QGraphicsItem::ItemIsFocusScope);
q->setFiltersChildEvents(true);
q->connect(&tl, SIGNAL(updated()), q, SLOT(ticked()));
}
diff --git a/src/declarative/fx/qfxrepeater.cpp b/src/declarative/fx/qfxrepeater.cpp
index a9d9977..67d4d69 100644
--- a/src/declarative/fx/qfxrepeater.cpp
+++ b/src/declarative/fx/qfxrepeater.cpp
@@ -47,7 +47,7 @@
QT_BEGIN_NAMESPACE
QFxRepeaterPrivate::QFxRepeaterPrivate()
-: component(0)
+: component(0), count(0)
{
}
@@ -112,42 +112,8 @@ QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Repeater,QFxRepeater)
/*!
\internal
\class QFxRepeater
- \ingroup group_utility
\qmlclass Repeater
- \brief The QFxRepeater class allows you to repeat a component based on a
- data source.
-
- The QFxRepeater class is used when you want to create a large number of
- similar items. For each entry in the data source, an item is instantiated
- in a context seeded with data from the data source.
-
- The data source may be either an object list, a string list or a Qt model.
- In each case, the data element and the index is exposed to each instantiated
- component. The index is always exposed as an accessible \c index property.
- In the case of an object or string list, the data element (of type string
- or object) is available as the \c modelData property. In the case of a Qt model,
- all roles are available as named properties just like in the view classes.
-
- As a special case the data source can also be merely a number. In this case it will
- create that many instances of the component. They will also be assigned an index
- based on the order they are created.
-
- Items instantiated by the QFxRepeater class are inserted, in order, as
- children of the repeater's parent. The insertion starts immediately after
- the repeater's position in its parent stacking list. This is to allow
- you to use a repeater inside a layout. The following QML example shows how
- the instantiated items would visually appear stacked between the red and
- blue rectangles.
-
- \snippet doc/src/snippets/declarative/repeater.qml 0
-
- The QFxRepeater instance continues to own all items it instantiates, even
- if they are otherwise manipulated. It is illegal to manually delete an item
- created by the repeater. On destruction, the repeater will clean up any
- items it has instantiated.
-
-
XXX Repeater is very conservative in how it instatiates/deletes items. Also
new model entries will not be created and old ones will not be removed.
*/
@@ -177,27 +143,30 @@ QFxRepeater::~QFxRepeater()
}
/*!
- \qmlproperty any Repeater::dataSource
+ \qmlproperty any Repeater::model
- The Repeater's data source.
+ The model providing data for the repeater.
- The data source may be either an object list, a string list or a Qt model.
+ The model may be either an object list, a string list or a Qt model.
In each case, the data element and the index is exposed to each instantiated
component. The index is always exposed as an accessible \c index property.
In the case of an object or string list, the data element (of type string
or object) is available as the \c modelData property. In the case of a Qt model,
all roles are available as named properties just like in the view classes.
- As a special case the data source can also be merely a number. In this case it will
+ As a special case the model can also be merely a number. In this case it will
create that many instances of the component. They will also be assigned an index
based on the order they are created.
+
+ Models can also be created directly in QML, using a \l{ListModel} or \l{XmlListModel}.
*/
-QVariant QFxRepeater::dataSource() const
+QVariant QFxRepeater::model() const
{
- return QVariant();
+ Q_D(const QFxRepeater);
+ return d->dataSource;
}
-void QFxRepeater::setDataSource(const QVariant &v)
+void QFxRepeater::setModel(const QVariant &v)
{
Q_D(QFxRepeater);
d->dataSource = v;
@@ -205,18 +174,18 @@ void QFxRepeater::setDataSource(const QVariant &v)
}
/*!
- \qmlproperty Component Repeater::component
+ \qmlproperty Component Repeater::delegate
\default
- The component to repeat.
+ The delegate provides a template describing what each item instantiated by the repeater should look and act like.
*/
-QmlComponent *QFxRepeater::component() const
+QmlComponent *QFxRepeater::delegate() const
{
Q_D(const QFxRepeater);
return d->component;
}
-void QFxRepeater::setComponent(QmlComponent *_c)
+void QFxRepeater::setDelegate(QmlComponent *_c)
{
Q_D(QFxRepeater);
d->component = _c;
@@ -224,6 +193,18 @@ void QFxRepeater::setComponent(QmlComponent *_c)
}
/*!
+ \qmlproperty int Repeater::count
+
+ This property holds the number of items in the repeater.
+*/
+int QFxRepeater::count() const
+{
+ Q_D(const QFxRepeater);
+ return d->count;
+}
+
+
+/*!
\internal
*/
void QFxRepeater::componentComplete()
@@ -260,10 +241,13 @@ void QFxRepeater::regenerate()
QFxItem *lastItem = this;
+ int count = 0;
+
if (d->dataSource.type() == QVariant::StringList) {
QStringList sl = qvariant_cast<QStringList>(d->dataSource);
- for (int ii = 0; ii < sl.size(); ++ii) {
+ count = sl.size();
+ for (int ii = 0; ii < count; ++ii) {
QmlContext *ctxt = new QmlContext(qmlContext(this), this);
d->deletables << ctxt;
@@ -274,11 +258,11 @@ void QFxRepeater::regenerate()
lastItem = item;
}
} else if (QmlMetaType::isList(d->dataSource)) {
- int cnt = QmlMetaType::listCount(d->dataSource);
- if (cnt <= 0)
+ count = QmlMetaType::listCount(d->dataSource);
+ if (count <= 0)
return;
- for (int ii = 0; ii < cnt; ++ii) {
+ for (int ii = 0; ii < count; ++ii) {
QVariant v = QmlMetaType::listAt(d->dataSource, ii);
QObject *o = QmlMetaType::toQObject(v);
@@ -292,11 +276,11 @@ void QFxRepeater::regenerate()
lastItem = item;
}
} else if (QListModelInterface *model = qobject_cast<QListModelInterface*>(d->dataSource.value<QObject*>())) {
- int cnt = model->count();
- if (cnt <= 0)
+ count = model->count();
+ if (count <= 0)
return;
- for (int ii = 0; ii < cnt; ++ii) {
+ for (int ii = 0; ii < count; ++ii) {
QmlContext *ctxt = new QmlContext(qmlContext(this), this);
d->deletables << ctxt;
@@ -315,6 +299,38 @@ void QFxRepeater::regenerate()
if (QFxItem *item = d->addItem(ctxt, lastItem))
lastItem = item;
}
+ } else if (QAbstractItemModel *model = qobject_cast<QAbstractItemModel*>(d->dataSource.value<QObject*>())) {
+ count = model->rowCount();
+ if (count <= 0)
+ return;
+
+ for (int ii = 0; ii < count; ++ii) {
+ QmlContext *ctxt = new QmlContext(qmlContext(this), this);
+ d->deletables << ctxt;
+
+ ctxt->setContextProperty(QLatin1String("index"), ii);
+
+ QList<int> roles;
+ QStringList roleNames;
+ QHash<int,QVariant> data;
+ for (QHash<int,QByteArray>::const_iterator it = model->roleNames().begin();
+ it != model->roleNames().end(); ++it) {
+ roles.append(it.key());
+ roleNames.append(QLatin1String(*it));
+ }
+
+ QModelIndex index = model->index(ii, 0);
+ for (int j = 0; j < roles.size(); ++j) {
+ ctxt->setContextProperty(roleNames.at(j), model->data(index, roles.at(j)));
+ }
+
+ //for compatability with other lists, assign data if there is only a single role
+ if (roles.size() == 1)
+ ctxt->setContextProperty(QLatin1String("modelData"), data.value(roles.at(0)));
+
+ if (QFxItem *item = d->addItem(ctxt, lastItem))
+ lastItem = item;
+ }
} else if (QObject *object = d->dataSource.value<QObject*>()) {
// A single object (i.e. list of size 1).
// Properties are the roles (excluding objectName).
@@ -322,13 +338,14 @@ void QFxRepeater::regenerate()
d->deletables << ctxt;
ctxt->setContextProperty(QLatin1String("index"), QVariant(0));
- for (int ii = 1; ii < object->metaObject()->propertyCount(); ++ii) {
+ count = object->metaObject()->propertyCount();
+ for (int ii = 1; ii < count; ++ii) {
const QMetaProperty &prop = object->metaObject()->property(ii);
ctxt->setContextProperty(QLatin1String(prop.name()), prop.read(object));
}
//for compatability with other lists, assign data if there is only a single role (excluding objectName)
- if (object->metaObject()->propertyCount() == 2) {
+ if (count == 2) {
const QMetaProperty &prop = object->metaObject()->property(1);
ctxt->setContextProperty(QLatin1String("modelData"), prop.read(object));
}
@@ -337,7 +354,7 @@ void QFxRepeater::regenerate()
} else if (d->dataSource.canConvert(QVariant::Int)){
- int count = qvariant_cast<int>(d->dataSource);
+ count = qvariant_cast<int>(d->dataSource);
for (int ii = 0; ii < count; ++ii) {
QmlContext *ctxt = new QmlContext(qmlContext(this), this);
@@ -349,5 +366,6 @@ void QFxRepeater::regenerate()
lastItem = item;
}
}
+ d->count = count;
}
QT_END_NAMESPACE
diff --git a/src/declarative/fx/qfxrepeater.h b/src/declarative/fx/qfxrepeater.h
index 3013b61..43afd63 100644
--- a/src/declarative/fx/qfxrepeater.h
+++ b/src/declarative/fx/qfxrepeater.h
@@ -55,19 +55,22 @@ class Q_DECLARATIVE_EXPORT QFxRepeater : public QFxItem
{
Q_OBJECT
- Q_PROPERTY(QVariant dataSource READ dataSource WRITE setDataSource) //### model
- Q_PROPERTY(QmlComponent *component READ component WRITE setComponent) //### delegate
- Q_CLASSINFO("DefaultProperty", "component")
- //### count
+ Q_PROPERTY(QVariant model READ model WRITE setModel)
+ Q_PROPERTY(QmlComponent *delegate READ delegate WRITE setDelegate)
+ Q_PROPERTY(int count READ count NOTIFY countChanged)
+ Q_CLASSINFO("DefaultProperty", "delegate")
+
public:
QFxRepeater(QFxItem *parent=0);
virtual ~QFxRepeater();
- QVariant dataSource() const;
- void setDataSource(const QVariant &);
+ QVariant model() const;
+ void setModel(const QVariant &);
+
+ QmlComponent *delegate() const;
+ void setDelegate(QmlComponent *);
- QmlComponent *component() const;
- void setComponent(QmlComponent *);
+ int count() const;
private:
void regenerate();
diff --git a/src/declarative/fx/qfxrepeater_p.h b/src/declarative/fx/qfxrepeater_p.h
index ba69658..65b0973 100644
--- a/src/declarative/fx/qfxrepeater_p.h
+++ b/src/declarative/fx/qfxrepeater_p.h
@@ -73,6 +73,7 @@ public:
QVariant dataSource;
QmlComponent *component;
+ int count;
QList<QPointer<QObject> > deletables;
};
diff --git a/src/declarative/fx/qfxtextinput.cpp b/src/declarative/fx/qfxtextinput.cpp
index b9b33ab..f491d34 100644
--- a/src/declarative/fx/qfxtextinput.cpp
+++ b/src/declarative/fx/qfxtextinput.cpp
@@ -320,6 +320,20 @@ void QFxTextInput::setSelectionEnd(int s)
d->control->setSelection(d->lastSelectionStart, s - d->lastSelectionStart);
}
+/*!
+ \qmlproperty string TextInput::selectedText
+
+ This read-only property provides the text currently selected in the
+ text input.
+
+ It is equivalent to the following snippet, but is faster and easier
+ to use.
+
+ \qmlcode
+ myTextInput.text.toString().substring(myTextInput.selectionStart,
+ myTextInput.selectionEnd);
+ \endcode
+*/
QString QFxTextInput::selectedText() const
{
Q_D(const QFxTextInput);
diff --git a/src/declarative/qml/qml.h b/src/declarative/qml/qml.h
index bced8f2..23f2f1e 100644
--- a/src/declarative/qml/qml.h
+++ b/src/declarative/qml/qml.h
@@ -50,6 +50,7 @@
#include <QtDeclarative/qmlmetatype.h>
#include <QtDeclarative/qmlmetaproperty.h>
#include <QtDeclarative/qmlparserstatus.h>
+#include <QtDeclarative/qmlpropertyvaluesource.h>
#include <QtDeclarative/qmllist.h>
QT_BEGIN_HEADER
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index 05bdade..9a8d3f2 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -30,7 +30,8 @@ SOURCES += qml/qmlparser.cpp \
qml/qmlrewrite.cpp \
qml/qmlbasicscript.cpp \
qml/qmlvaluetype.cpp \
- qml/qmlbindingoptimizations.cpp
+ qml/qmlbindingoptimizations.cpp \
+ qml/qmlxmlhttprequest.cpp
HEADERS += qml/qmlparser_p.h \
qml/qmlinstruction_p.h \
@@ -77,7 +78,8 @@ HEADERS += qml/qmlparser_p.h \
qml/qmlrewrite_p.h \
qml/qpodvector_p.h \
qml/qmlvaluetype_p.h \
- qml/qmlbindingoptimizations_p.h
+ qml/qmlbindingoptimizations_p.h \
+ qml/qmlxmlhttprequest_p.h
# for qtscript debugger
contains(QT_CONFIG, scripttools):QT += scripttools
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index 4f96d12..070add7 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -1231,17 +1231,13 @@ bool QmlCompiler::buildProperty(QmlParser::Property *prop,
if (!prop->isDefault && prop->name == "id" && !ctxt.isSubContext()) {
- // The magic "id" behaviour doesn't apply when "id" is resolved as a
+ // The magic "id" behavior doesn't apply when "id" is resolved as a
// default property or to sub-objects (which are always in binding
// sub-contexts)
COMPILE_CHECK(buildIdProperty(prop, obj));
- if (prop->type == QVariant::String){
- if(!prop->values.at(0)->value.isString()){
- //Need to convert to string to assign to the QString id property
- prop->values.at(0)->value = Variant(prop->values.at(0)->value.asString());
- }
+ if (prop->type == QVariant::String &&
+ prop->values.at(0)->value.isString())
COMPILE_CHECK(buildPropertyAssignment(prop, obj, ctxt));
- }
} else if (isAttachedPropertyName(prop->name)) {
@@ -1411,7 +1407,6 @@ void QmlCompiler::genPropertyAssignment(QmlParser::Property *prop,
}
} else if (v->type == Value::ValueSource) {
-
genObject(v->object);
QmlInstruction store;
@@ -1425,6 +1420,8 @@ void QmlCompiler::genPropertyAssignment(QmlParser::Property *prop,
QmlMetaPropertyPrivate::saveProperty(prop->index);
store.assignValueSource.owner = 0;
}
+ QmlType *valueType = QmlMetaType::qmlType(v->object->metatype);
+ store.assignValueSource.castValue = valueType->propertyValueSourceCast();
output->bytecode << store;
} else if (v->type == Value::PropertyBinding) {
@@ -1584,15 +1581,7 @@ bool QmlCompiler::buildValueTypeProperty(QObject *type,
Value *value = prop->values.at(0);
if (value->object) {
- const QMetaObject *c =
- output->types.at(value->object->type).metaObject();
- bool isPropertyValue = false;
- while (c && !isPropertyValue) {
- isPropertyValue =
- (c == &QmlPropertyValueSource::staticMetaObject);
- c = c->superClass();
- }
-
+ bool isPropertyValue = output->types.at(value->object->type).type->propertyValueSourceCast() != -1;
if (!isPropertyValue) {
COMPILE_EXCEPTION(prop, "Invalid property use");
} else {
@@ -1709,7 +1698,7 @@ bool QmlCompiler::buildListProperty(QmlParser::Property *prop,
// children: [ Item {}, Item {} ]
// }
//
-// We allow assigning multiple values to single value properties
+// We allow assignming multiple values to single value properties
bool QmlCompiler::buildPropertyAssignment(QmlParser::Property *prop,
QmlParser::Object *obj,
const BindingContext &ctxt)
@@ -1762,30 +1751,26 @@ bool QmlCompiler::buildPropertyObjectAssignment(QmlParser::Property *prop,
v->object->metatype = output->types.at(v->object->type).metaObject();
Q_ASSERT(v->object->metaObject());
+ // Will be true if the assigned type inherits QmlPropertyValueSource
+ bool isPropertyValue = false;
+ if (QmlType *valueType = QmlMetaType::qmlType(v->object->metatype))
+ isPropertyValue = valueType->propertyValueSourceCast() != -1;
+
// We want to raw metaObject here as the raw metaobject is the
// actual property type before we applied any extensions that might
// effect the properties on the type, but don't effect assignability
const QMetaObject *propertyMetaObject =
QmlMetaType::rawMetaObjectForType(prop->type);
- // Will be true if the assigned type inherits QmlPropertyValueSource
- bool isPropertyValue = false;
// Will be true if the assgned type inherits propertyMetaObject
bool isAssignable = false;
- // Determine isPropertyValue and isAssignable values
+ // Determine isAssignable value
if (propertyMetaObject) {
const QMetaObject *c = v->object->metatype;
while(c) {
- isPropertyValue |= (c == &QmlPropertyValueSource::staticMetaObject);
isAssignable |= (c == propertyMetaObject);
c = c->superClass();
}
- } else {
- const QMetaObject *c = v->object->metatype;
- while(!isPropertyValue && c) {
- isPropertyValue |= (c == &QmlPropertyValueSource::staticMetaObject);
- c = c->superClass();
- }
}
if (isAssignable) {
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index ea00d65..d06376a 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -55,6 +55,7 @@
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QNetworkAccessManager>
+#include <QDesktopServices>
#include <QTimer>
#include <QList>
#include <QPair>
@@ -71,6 +72,7 @@
#include <QtCore/qthread.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qdir.h>
+#include <QtGui/qcolor.h>
#include <QtGui/qvector3d.h>
#include <qmlcomponent.h>
#include "private/qmlcomponentjs_p.h"
@@ -78,6 +80,7 @@
#include <private/qmlbinding_p.h>
#include <private/qmlvme_p.h>
#include <private/qmlenginedebug_p.h>
+#include <private/qmlxmlhttprequest_p.h>
Q_DECLARE_METATYPE(QmlMetaProperty)
Q_DECLARE_METATYPE(QList<QObject *>);
@@ -95,6 +98,14 @@ struct StaticQtMetaObject : public QObject
{ return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; }
};
+QScriptValue desktopOpenUrl(QScriptContext *ctxt, QScriptEngine *e)
+{
+ if(!ctxt->argumentCount())
+ return e->newVariant(QVariant(false));
+ bool ret = QDesktopServices::openUrl(QUrl(ctxt->argument(0).toString()));
+ return e->newVariant(QVariant(ret));
+}
+
QmlEnginePrivate::QmlEnginePrivate(QmlEngine *e)
: rootContext(0), currentBindContext(0), currentExpression(0),
isDebugging(false), contextClass(0), objectClass(0), valueTypeClass(0),
@@ -103,7 +114,19 @@ QmlEnginePrivate::QmlEnginePrivate(QmlEngine *e)
{
QScriptValue qtObject =
scriptEngine.newQMetaObject(StaticQtMetaObject::get());
+ QScriptValue desktopObject = scriptEngine.newObject();
+ desktopObject.setProperty(QLatin1String("openUrl"),scriptEngine.newFunction(desktopOpenUrl, 1));
+ qtObject.setProperty(QLatin1String("DesktopServices"), desktopObject);
scriptEngine.globalObject().setProperty(QLatin1String("Qt"), qtObject);
+
+ qt_add_qmlxmlhttprequest(&scriptEngine);
+
+ qtObject.setProperty(QLatin1String("rgba"), scriptEngine.newFunction(QmlEnginePrivate::rgba, 4));
+ qtObject.setProperty(QLatin1String("hsla"), scriptEngine.newFunction(QmlEnginePrivate::hsla, 4));
+ qtObject.setProperty(QLatin1String("rect"), scriptEngine.newFunction(QmlEnginePrivate::rect, 4));
+ qtObject.setProperty(QLatin1String("point"), scriptEngine.newFunction(QmlEnginePrivate::point, 2));
+ qtObject.setProperty(QLatin1String("size"), scriptEngine.newFunction(QmlEnginePrivate::size, 2));
+ qtObject.setProperty(QLatin1String("vector3d"), scriptEngine.newFunction(QmlEnginePrivate::vector, 3));
}
QmlEnginePrivate::~QmlEnginePrivate()
@@ -160,7 +183,7 @@ void QmlEnginePrivate::init()
scriptEngine.globalObject().setProperty(QLatin1String("createComponent"),
scriptEngine.newFunction(QmlEnginePrivate::createComponent, 1));
scriptEngine.globalObject().setProperty(QLatin1String("vector"),
- scriptEngine.newFunction(QmlEnginePrivate::vector, 1));
+ scriptEngine.newFunction(QmlEnginePrivate::vector, 3));
if (QCoreApplication::instance()->thread() == q->thread() &&
QmlEngineDebugServer::isDebuggingEnabled()) {
@@ -698,7 +721,7 @@ QScriptValue QmlEnginePrivate::createQmlObject(QScriptContext *ctxt, QScriptEngi
QVector3D as usual.
This function takes three numeric components and combines them into a
- QMLJS string that can be used with any property that takes a
+ QVector3D value that can be used with any property that takes a
QVector3D argument. The following QML code:
\code
@@ -729,6 +752,59 @@ QScriptValue QmlEnginePrivate::vector(QScriptContext *ctxt, QScriptEngine *engin
return engine->newVariant(qVariantFromValue(QVector3D(x, y, z)));
}
+QScriptValue QmlEnginePrivate::rgba(QScriptContext *ctxt, QScriptEngine *engine)
+{
+ int argCount = ctxt->argumentCount();
+ if(argCount < 3)
+ return engine->nullValue();
+ qsreal r = ctxt->argument(0).toNumber();
+ qsreal g = ctxt->argument(1).toNumber();
+ qsreal b = ctxt->argument(2).toNumber();
+ qsreal a = (argCount == 4) ? ctxt->argument(3).toNumber() : 1;
+ return qScriptValueFromValue(engine, qVariantFromValue(QColor::fromRgbF(r, g, b, a)));
+}
+
+QScriptValue QmlEnginePrivate::hsla(QScriptContext *ctxt, QScriptEngine *engine)
+{
+ int argCount = ctxt->argumentCount();
+ if(argCount < 3)
+ return engine->nullValue();
+ qsreal h = ctxt->argument(0).toNumber();
+ qsreal s = ctxt->argument(1).toNumber();
+ qsreal l = ctxt->argument(2).toNumber();
+ qsreal a = (argCount == 4) ? ctxt->argument(3).toNumber() : 1;
+ return qScriptValueFromValue(engine, qVariantFromValue(QColor::fromHslF(h, s, l, a)));
+}
+
+QScriptValue QmlEnginePrivate::rect(QScriptContext *ctxt, QScriptEngine *engine)
+{
+ if(ctxt->argumentCount() < 4)
+ return engine->nullValue();
+ qsreal x = ctxt->argument(0).toNumber();
+ qsreal y = ctxt->argument(1).toNumber();
+ qsreal w = ctxt->argument(2).toNumber();
+ qsreal h = ctxt->argument(3).toNumber();
+ return qScriptValueFromValue(engine, qVariantFromValue(QRectF(x, y, w, h)));
+}
+
+QScriptValue QmlEnginePrivate::point(QScriptContext *ctxt, QScriptEngine *engine)
+{
+ if(ctxt->argumentCount() < 2)
+ return engine->nullValue();
+ qsreal x = ctxt->argument(0).toNumber();
+ qsreal y = ctxt->argument(1).toNumber();
+ return qScriptValueFromValue(engine, qVariantFromValue(QPointF(x, y)));
+}
+
+QScriptValue QmlEnginePrivate::size(QScriptContext *ctxt, QScriptEngine *engine)
+{
+ if(ctxt->argumentCount() < 2)
+ return engine->nullValue();
+ qsreal w = ctxt->argument(0).toNumber();
+ qsreal h = ctxt->argument(1).toNumber();
+ return qScriptValueFromValue(engine, qVariantFromValue(QSizeF(w, h)));
+}
+
QmlScriptClass::QmlScriptClass(QmlEngine *bindengine)
: QScriptClass(QmlEnginePrivate::getScriptEngine(bindengine)),
engine(bindengine)
@@ -971,7 +1047,7 @@ QScriptValue QmlObjectToString(QScriptContext *context, QScriptEngine *engine)
ret += QString::number((quintptr)obj,16);
ret += QLatin1String(")");
}else{
- ret += "null";
+ ret += QLatin1String("null");
}
return engine->newVariant(ret);
}
diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h
index 53b2967..aeee355 100644
--- a/src/declarative/qml/qmlengine_p.h
+++ b/src/declarative/qml/qmlengine_p.h
@@ -214,9 +214,16 @@ public:
static QScriptValue createComponent(QScriptContext*, QScriptEngine*);
static QScriptValue createQmlObject(QScriptContext*, QScriptEngine*);
static QScriptValue vector(QScriptContext*, QScriptEngine*);
+ static QScriptValue rgba(QScriptContext*, QScriptEngine*);
+ static QScriptValue hsla(QScriptContext*, QScriptEngine*);
+ static QScriptValue point(QScriptContext*, QScriptEngine*);
+ static QScriptValue size(QScriptContext*, QScriptEngine*);
+ static QScriptValue rect(QScriptContext*, QScriptEngine*);
static QScriptEngine *getScriptEngine(QmlEngine *e) { return &e->d_func()->scriptEngine; }
+ static QmlEngine *getEngine(QScriptEngine *e) { return static_cast<QmlScriptEngine*>(e)->p->q_func(); }
static QmlEnginePrivate *get(QmlEngine *e) { return e->d_func(); }
+ static QmlEnginePrivate *get(QScriptEngine *e) { return static_cast<QmlScriptEngine*>(e)->p; }
};
diff --git a/src/declarative/qml/qmlexpression.cpp b/src/declarative/qml/qmlexpression.cpp
index 77463cd..845dcf6 100644
--- a/src/declarative/qml/qmlexpression.cpp
+++ b/src/declarative/qml/qmlexpression.cpp
@@ -315,7 +315,7 @@ QVariant QmlExpression::value()
Q_D(QmlExpression);
QVariant rv;
- if (!d->context() || (!d->sse.isValid() && d->expression.isEmpty()))
+ if (!engine() || (!d->sse.isValid() && d->expression.isEmpty()))
return rv;
#ifdef Q_ENABLE_PERFORMANCE_LOG
diff --git a/src/declarative/qml/qmlinstruction.cpp b/src/declarative/qml/qmlinstruction.cpp
index 02e4883..b71c6e3 100644
--- a/src/declarative/qml/qmlinstruction.cpp
+++ b/src/declarative/qml/qmlinstruction.cpp
@@ -147,7 +147,7 @@ void QmlCompiledData::dump(QmlInstruction *instr, int idx)
qWarning() << idx << "\t" << line << "\t" << "STORE_COMPILED_BINDING\t" << instr->assignBinding.property << "\t" << instr->assignBinding.value << "\t\t" << instr->assignBinding.context;
break;
case QmlInstruction::StoreValueSource:
- qWarning() << idx << "\t" << line << "\t" << "STORE_VALUE_SOURCE\t" << instr->assignValueSource.property;
+ qWarning() << idx << "\t" << line << "\t" << "STORE_VALUE_SOURCE\t" << instr->assignValueSource.property << "\t" << instr->assignValueSource.castValue;
break;
case QmlInstruction::BeginObject:
qWarning() << idx << "\t" << line << "\t" << "BEGIN\t\t\t" << instr->begin.castValue;
diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h
index 0f2995a..8861609a 100644
--- a/src/declarative/qml/qmlinstruction_p.h
+++ b/src/declarative/qml/qmlinstruction_p.h
@@ -183,6 +183,7 @@ public:
struct {
int property;
int owner;
+ int castValue;
} assignValueSource;
struct {
int property;
diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp
index cc5e4ee..1e8ce91 100644
--- a/src/declarative/qml/qmlmetaproperty.cpp
+++ b/src/declarative/qml/qmlmetaproperty.cpp
@@ -532,7 +532,7 @@ QmlAbstractBinding *QmlMetaProperty::binding() const
QmlAbstractBinding *binding = data->bindings;
while (binding) {
// ### This wont work for value types
- if (binding->propertyIndex() == d->coreIdx)
+ if (binding->propertyIndex() == d->coreIdx) //### should we check for enabled?
return binding;
binding = binding->m_nextBinding;
}
diff --git a/src/declarative/qml/qmlmetatype.cpp b/src/declarative/qml/qmlmetatype.cpp
index ab64079..c488c13 100644
--- a/src/declarative/qml/qmlmetatype.cpp
+++ b/src/declarative/qml/qmlmetatype.cpp
@@ -120,6 +120,7 @@ public:
QmlAttachedPropertiesFunc m_attachedPropertiesFunc;
const QMetaObject *m_attachedPropertiesType;
int m_parserStatusCast;
+ int m_propertyValueSourceCast;
QmlPrivate::CreateFunc m_extFunc;
const QMetaObject *m_extMetaObject;
int m_index;
@@ -132,8 +133,8 @@ public:
QmlTypePrivate::QmlTypePrivate()
: m_isInterface(false), m_iid(0), m_typeId(0), m_listId(0), m_qmlListId(0),
m_opFunc(0), m_baseMetaObject(0), m_attachedPropertiesFunc(0), m_attachedPropertiesType(0),
- m_parserStatusCast(-1), m_extFunc(0), m_extMetaObject(0), m_index(-1),
- m_customParser(0), m_isSetup(false)
+ m_parserStatusCast(-1), m_propertyValueSourceCast(-1), m_extFunc(0), m_extMetaObject(0),
+ m_index(-1), m_customParser(0), m_isSetup(false)
{
}
@@ -161,7 +162,7 @@ QmlType::QmlType(int type, int listType, int qmlListType,
const QMetaObject *metaObject,
QmlAttachedPropertiesFunc attachedPropertiesFunc,
const QMetaObject *attachedType,
- int parserStatusCast, QmlPrivate::CreateFunc extFunc,
+ int parserStatusCast, int propertyValueSourceCast, QmlPrivate::CreateFunc extFunc,
const QMetaObject *extMetaObject, int index,
QmlCustomParser *customParser)
: d(new QmlTypePrivate)
@@ -178,6 +179,7 @@ QmlType::QmlType(int type, int listType, int qmlListType,
d->m_attachedPropertiesFunc = attachedPropertiesFunc;
d->m_attachedPropertiesType = attachedType;
d->m_parserStatusCast = parserStatusCast;
+ d->m_propertyValueSourceCast = propertyValueSourceCast;
d->m_extFunc = extFunc;
d->m_index = index;
d->m_customParser = customParser;
@@ -397,6 +399,11 @@ int QmlType::parserStatusCast() const
return d->m_parserStatusCast;
}
+int QmlType::propertyValueSourceCast() const
+{
+ return d->m_propertyValueSourceCast;
+}
+
QVariant QmlType::fromObject(QObject *obj) const
{
QVariant rv;
@@ -452,7 +459,7 @@ int QmlMetaType::registerInterface(const QmlPrivate::MetaTypeIds &id,
int QmlMetaType::registerType(const QmlPrivate::MetaTypeIds &id, QmlPrivate::Func func,
const char *uri, int version_maj, int version_min_from, int version_min_to, const char *cname,
const QMetaObject *mo, QmlAttachedPropertiesFunc attach, const QMetaObject *attachMo,
- int pStatus, int object, QmlPrivate::CreateFunc extFunc, const QMetaObject *extmo, QmlCustomParser *parser)
+ int pStatus, int object, int valueSource, QmlPrivate::CreateFunc extFunc, const QMetaObject *extmo, QmlCustomParser *parser)
{
Q_UNUSED(object);
@@ -476,8 +483,8 @@ int QmlMetaType::registerType(const QmlPrivate::MetaTypeIds &id, QmlPrivate::Fun
name.replace('.','/');
QmlType *type = new QmlType(id.typeId, id.listId, id.qmlListId,
- func, name, version_maj, version_min_from, version_min_to, mo, attach, attachMo, pStatus, extFunc,
- extmo, index, parser);
+ func, name, version_maj, version_min_from, version_min_to, mo, attach, attachMo, pStatus,
+ valueSource, extFunc, extmo, index, parser);
data->types.append(type);
data->idToType.insert(type->typeId(), type);
@@ -513,6 +520,17 @@ int QmlMetaType::qmlParserStatusCast(int userType)
return -1;
}
+int QmlMetaType::qmlPropertyValueSourceCast(int userType)
+{
+ QReadLocker lock(metaTypeDataLock());
+ QmlMetaTypeData *data = metaTypeData();
+ QmlType *type = data->idToType.value(userType);
+ if (type && type->typeId() == userType)
+ return type->propertyValueSourceCast();
+ else
+ return -1;
+}
+
QObject *QmlMetaType::toQObject(const QVariant &v)
{
if (!isObject(v.userType()))
diff --git a/src/declarative/qml/qmlmetatype.h b/src/declarative/qml/qmlmetatype.h
index c388b1a..5ed9a5a 100644
--- a/src/declarative/qml/qmlmetatype.h
+++ b/src/declarative/qml/qmlmetatype.h
@@ -47,6 +47,7 @@
#include <QtCore/qbitarray.h>
#include <QtDeclarative/qmlprivate.h>
#include <QtDeclarative/qmlparserstatus.h>
+#include <QtDeclarative/qmlpropertyvaluesource.h>
QT_BEGIN_HEADER
@@ -59,7 +60,7 @@ class QmlCustomParser;
class Q_DECLARATIVE_EXPORT QmlMetaType
{
public:
- static int registerType(const QmlPrivate::MetaTypeIds &, QmlPrivate::Func, const char *, int vmaj, int vmin_from, int vmin_to, const char *qmlName, const QMetaObject *, QmlAttachedPropertiesFunc, const QMetaObject *, int pStatus, int object, QmlPrivate::CreateFunc extFunc, const QMetaObject *extmo, QmlCustomParser *);
+ static int registerType(const QmlPrivate::MetaTypeIds &, QmlPrivate::Func, const char *, int vmaj, int vmin_from, int vmin_to, const char *qmlName, const QMetaObject *, QmlAttachedPropertiesFunc, const QMetaObject *, int pStatus, int object, int valueSource, QmlPrivate::CreateFunc extFunc, const QMetaObject *extmo, QmlCustomParser *);
static int registerInterface(const QmlPrivate::MetaTypeIds &, QmlPrivate::Func, const char *);
static bool copy(int type, void *data, const void *copy = 0);
@@ -78,6 +79,7 @@ public:
static QMetaProperty property(QObject *, const char *);
static QObject *toQObject(const QVariant &);
static int qmlParserStatusCast(int);
+ static int qmlPropertyValueSourceCast(int);
static int listType(int);
static bool clear(const QVariant &);
static bool append(const QVariant &, const QVariant &);
@@ -143,13 +145,14 @@ public:
int parserStatusCast() const;
QVariant fromObject(QObject *) const;
const char *interfaceIId() const;
+ int propertyValueSourceCast() const;
int index() const;
private:
friend class QmlMetaType;
friend class QmlTypePrivate;
QmlType(int, int, int, QmlPrivate::Func, const char *, int);
- QmlType(int, int, int, QmlPrivate::Func, const char *, int, int, int, const QMetaObject *, QmlAttachedPropertiesFunc, const QMetaObject *, int, QmlPrivate::CreateFunc, const QMetaObject *, int, QmlCustomParser *);
+ QmlType(int, int, int, QmlPrivate::Func, const char *, int, int, int, const QMetaObject *, QmlAttachedPropertiesFunc, const QMetaObject *, int, int, QmlPrivate::CreateFunc, const QMetaObject *, int, QmlCustomParser *);
~QmlType();
QmlTypePrivate *d;
@@ -170,7 +173,8 @@ int qmlRegisterType(const char *typeName)
QmlPrivate::attachedPropertiesFunc<T>(),
QmlPrivate::attachedPropertiesMetaObject<T>(),
QmlPrivate::StaticCastSelector<T,QmlParserStatus>::cast(),
- QmlPrivate::StaticCastSelector<T,QObject>::cast(),
+ QmlPrivate::StaticCastSelector<T,QObject>::cast(),
+ QmlPrivate::StaticCastSelector<T,QmlPropertyValueSource>::cast(),
0, 0, 0);
}
@@ -191,6 +195,7 @@ int qmlRegisterType(const char *uri, int version_maj, int version_min_from, int
QmlPrivate::attachedPropertiesMetaObject<T>(),
QmlPrivate::StaticCastSelector<T,QmlParserStatus>::cast(),
QmlPrivate::StaticCastSelector<T,QObject>::cast(),
+ QmlPrivate::StaticCastSelector<T,QmlPropertyValueSource>::cast(),
0, 0, 0);
}
@@ -216,7 +221,8 @@ int qmlRegisterExtendedType(const char *typeName)
return QmlMetaType::registerType(ids, QmlPrivate::list_nocreate_op<T>, 0, 0, 0, 0, 0,
&T::staticMetaObject, attached, attachedMo,
QmlPrivate::StaticCastSelector<T,QmlParserStatus>::cast(),
- QmlPrivate::StaticCastSelector<T,QObject>::cast(),
+ QmlPrivate::StaticCastSelector<T,QObject>::cast(),
+ QmlPrivate::StaticCastSelector<T,QmlPropertyValueSource>::cast(),
&QmlPrivate::CreateParent<E>::create, &E::staticMetaObject, 0);
}
@@ -244,7 +250,8 @@ int qmlRegisterExtendedType(const char *uri, int version_maj, int version_min_fr
&T::staticMetaObject,
attached, attachedMo,
QmlPrivate::StaticCastSelector<T,QmlParserStatus>::cast(),
- QmlPrivate::StaticCastSelector<T,QObject>::cast(),
+ QmlPrivate::StaticCastSelector<T,QObject>::cast(),
+ QmlPrivate::StaticCastSelector<T,QmlPropertyValueSource>::cast(),
&QmlPrivate::CreateParent<E>::create,
&E::staticMetaObject, 0);
}
@@ -280,7 +287,8 @@ int qmlRegisterCustomType(const char *uri, int version_maj, int version_min_from
QmlPrivate::attachedPropertiesFunc<T>(),
QmlPrivate::attachedPropertiesMetaObject<T>(),
QmlPrivate::StaticCastSelector<T,QmlParserStatus>::cast(),
- QmlPrivate::StaticCastSelector<T,QObject>::cast(),
+ QmlPrivate::StaticCastSelector<T,QObject>::cast(),
+ QmlPrivate::StaticCastSelector<T,QmlPropertyValueSource>::cast(),
0, 0, parser);
}
diff --git a/src/declarative/qml/qmlpropertyvaluesource.cpp b/src/declarative/qml/qmlpropertyvaluesource.cpp
index c6ff596..429080b 100644
--- a/src/declarative/qml/qmlpropertyvaluesource.cpp
+++ b/src/declarative/qml/qmlpropertyvaluesource.cpp
@@ -48,34 +48,18 @@ QT_BEGIN_NAMESPACE
\class QmlPropertyValueSource
\brief The QmlPropertyValueSource class is inherited by property value sources such as animations and bindings.
*/
-QML_DEFINE_NOCREATE_TYPE(QmlPropertyValueSource)
/*!
- Constructs a QmlPropertyValueSource with parent \a parent.
+ Constructs a QmlPropertyValueSource.
*/
-QmlPropertyValueSource::QmlPropertyValueSource(QObject *parent)
- : QObject(parent)
-
-{
-}
-
-/*!
- \internal
- */
-QmlPropertyValueSource::QmlPropertyValueSource(QObjectPrivate &dd, QObject *parent)
- : QObject(dd, parent)
+QmlPropertyValueSource::QmlPropertyValueSource()
{
}
/*!
+ \fn void QmlPropertyValueSource::setTarget(const QmlMetaProperty &property)
Set the target \a property for the value source. This method will
be called by the QML engine when assigning a value source.
-
- The default implementation does nothing.
*/
-void QmlPropertyValueSource::setTarget(const QmlMetaProperty &property)
-{
- Q_UNUSED(property);
-}
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlpropertyvaluesource.h b/src/declarative/qml/qmlpropertyvaluesource.h
index 4e5f1c5..ee4ea2c 100644
--- a/src/declarative/qml/qmlpropertyvaluesource.h
+++ b/src/declarative/qml/qmlpropertyvaluesource.h
@@ -42,9 +42,7 @@
#ifndef QMLPROPERTYVALUESOURCE_H
#define QMLPROPERTYVALUESOURCE_H
-#include <QtDeclarative/qfxglobal.h>
-#include <QtDeclarative/qml.h>
-#include <QtCore/QObject>
+#include <QtCore/qobject.h>
QT_BEGIN_HEADER
@@ -52,28 +50,17 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
-class QObjectPrivate;
class QmlMetaProperty;
-class Q_DECLARATIVE_EXPORT QmlPropertyValueSource : public QObject
+class Q_DECLARATIVE_EXPORT QmlPropertyValueSource
{
- Q_OBJECT
- Q_DECLARE_PRIVATE(QObject)
-
public:
- QmlPropertyValueSource(QObject *parent);
- virtual void setTarget(const QmlMetaProperty &);
-
-protected:
- QmlPropertyValueSource(QObjectPrivate &dd, QObject *parent);
-
-private:
- Q_DISABLE_COPY(QmlPropertyValueSource)
+ QmlPropertyValueSource();
+ virtual void setTarget(const QmlMetaProperty &) = 0;
};
+Q_DECLARE_INTERFACE(QmlPropertyValueSource, "com.trolltech.qml.QmlPropertyValueSource")
QT_END_NAMESPACE
-QML_DECLARE_TYPE(QmlPropertyValueSource)
-
QT_END_HEADER
#endif // QMLPROPERTYVALUESOURCE_H
diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp
index 7455eb4..930e6e4 100644
--- a/src/declarative/qml/qmlvme.cpp
+++ b/src/declarative/qml/qmlvme.cpp
@@ -591,13 +591,12 @@ QObject *QmlVME::run(QStack<QObject *> &stack, QmlContext *ctxt, QmlCompiledData
case QmlInstruction::StoreValueSource:
{
- QmlPropertyValueSource *vs =
- static_cast<QmlPropertyValueSource *>(stack.pop());
- QObject *target =
- stack.at(stack.count() - 1 - instr.assignValueSource.owner);
+ QObject *obj = stack.pop();
+ QmlPropertyValueSource *vs = reinterpret_cast<QmlPropertyValueSource *>(reinterpret_cast<char *>(obj) + instr.assignValueSource.castValue);
+ QObject *target = stack.at(stack.count() - 1 - instr.assignValueSource.owner);
QmlMetaProperty prop;
prop.restore(instr.assignValueSource.property, target, ctxt);
- vs->setParent(target);
+ obj->setParent(target);
vs->setTarget(prop);
}
break;
diff --git a/src/declarative/qml/qmlxmlhttprequest.cpp b/src/declarative/qml/qmlxmlhttprequest.cpp
new file mode 100644
index 0000000..fb92c54
--- /dev/null
+++ b/src/declarative/qml/qmlxmlhttprequest.cpp
@@ -0,0 +1,535 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qobject.h>
+#include <QtDeclarative/qmlengine.h>
+#include <private/qmlengine_p.h>
+#include <QtScript/qscriptvalue.h>
+#include <QtScript/qscriptcontext.h>
+#include <QtScript/qscriptengine.h>
+#include <QtNetwork/qnetworkreply.h>
+#include "qmlxmlhttprequest_p.h"
+
+#include <QtCore/qdebug.h>
+
+// ### Find real values
+#define INVALID_STATE_ERR ((QScriptContext::Error)15)
+
+class QmlXMLHttpRequest : public QObject
+{
+Q_OBJECT
+public:
+ enum State { Unsent = 0,
+ Opened = 1, HeadersReceived = 2,
+ Loading = 3, Done = 4 };
+
+ QmlXMLHttpRequest(QmlEngine *engine);
+ virtual ~QmlXMLHttpRequest();
+
+ QScriptValue callback() const;
+ void setCallback(const QScriptValue &);
+
+ bool sendFlag() const;
+ bool errorFlag() const;
+ quint32 readyState() const;
+ int replyStatus() const;
+ QString replyStatusText() const;
+
+ void open(const QString &, const QUrl &);
+ void addHeader(const QString &, const QString &);
+ void send(const QByteArray &);
+ void abort();
+
+ QString responseBody() const;
+private slots:
+ void downloadProgress(qint64);
+ void error(QNetworkReply::NetworkError);
+ void finished();
+
+private:
+ QmlEngine *m_engine;
+
+ State m_state;
+ bool m_errorFlag;
+ bool m_sendFlag;
+ QString m_method;
+ QUrl m_url;
+ QByteArray m_responseEntityBody;
+
+ void dispatchCallback();
+ QScriptValue m_callback;
+
+ int m_status;
+ QString m_statusText;
+ QNetworkRequest m_request;
+ QNetworkReply *m_network;
+ void destroyNetwork();
+};
+
+QmlXMLHttpRequest::QmlXMLHttpRequest(QmlEngine *engine)
+: m_engine(engine), m_state(Unsent), m_errorFlag(false), m_sendFlag(false),
+ m_network(0)
+{
+ Q_ASSERT(m_engine);
+}
+
+QmlXMLHttpRequest::~QmlXMLHttpRequest()
+{
+ destroyNetwork();
+}
+
+QScriptValue QmlXMLHttpRequest::callback() const
+{
+ return m_callback;
+}
+
+void QmlXMLHttpRequest::setCallback(const QScriptValue &c)
+{
+ m_callback = c;
+}
+
+bool QmlXMLHttpRequest::sendFlag() const
+{
+ return m_sendFlag;
+}
+
+bool QmlXMLHttpRequest::errorFlag() const
+{
+ return m_errorFlag;
+}
+
+quint32 QmlXMLHttpRequest::readyState() const
+{
+ return m_state;
+}
+
+int QmlXMLHttpRequest::replyStatus() const
+{
+ return m_status;
+}
+
+QString QmlXMLHttpRequest::replyStatusText() const
+{
+ return m_statusText;
+}
+
+void QmlXMLHttpRequest::open(const QString &method, const QUrl &url)
+{
+ destroyNetwork();
+ m_sendFlag = false;
+ m_errorFlag = false;
+ m_responseEntityBody = QByteArray();
+ m_method = method;
+ m_url = url;
+ m_state = Opened;
+ dispatchCallback();
+}
+
+void QmlXMLHttpRequest::addHeader(const QString &name, const QString &value)
+{
+ QByteArray utfname = name.toUtf8();
+
+ if (m_request.hasRawHeader(utfname)) {
+ m_request.setRawHeader(utfname, m_request.rawHeader(utfname) + "," + value.toUtf8());
+ } else {
+ m_request.setRawHeader(utfname, value.toUtf8());
+ }
+}
+
+void QmlXMLHttpRequest::send(const QByteArray &data)
+{
+ m_errorFlag = false;
+ m_sendFlag = true;
+
+ dispatchCallback();
+
+ m_request.setUrl(m_url);
+
+ if (m_method == QLatin1String("GET"))
+ m_network = m_engine->networkAccessManager()->get(m_request);
+ else if (m_method == QLatin1String("HEAD"))
+ m_network = m_engine->networkAccessManager()->head(m_request);
+ else if(m_method == QLatin1String("POST"))
+ m_network = m_engine->networkAccessManager()->post(m_request, data);
+ else if(m_method == QLatin1String("PUT"))
+ m_network = m_engine->networkAccessManager()->put(m_request, data);
+
+ QObject::connect(m_network, SIGNAL(downloadProgress(qint64,qint64)),
+ this, SLOT(downloadProgress(qint64)));
+ QObject::connect(m_network, SIGNAL(error(QNetworkReply::NetworkError)),
+ this, SLOT(error(QNetworkReply::NetworkError)));
+ QObject::connect(m_network, SIGNAL(finished()),
+ this, SLOT(finished()));
+}
+
+void QmlXMLHttpRequest::abort()
+{
+ destroyNetwork();
+ m_responseEntityBody = QByteArray();
+ m_errorFlag = true;
+ m_request = QNetworkRequest();
+
+ if (!(m_state == Unsent ||
+ (m_state == Opened && !m_sendFlag) ||
+ m_state == Done)) {
+
+ m_state = Done;
+ m_sendFlag = false;
+ dispatchCallback();
+ }
+
+ m_state = Unsent;
+}
+
+void QmlXMLHttpRequest::downloadProgress(qint64 bytes)
+{
+ m_status =
+ m_network->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+ m_statusText =
+ QLatin1String(m_network->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toByteArray());
+
+ // ### We assume if this is called the headers are now available
+ if (m_state < HeadersReceived) {
+ m_state = HeadersReceived;
+ dispatchCallback();
+ }
+
+ bool wasEmpty = m_responseEntityBody.isEmpty();
+ m_responseEntityBody.append(m_network->readAll());
+ if (wasEmpty && !m_responseEntityBody.isEmpty()) {
+ m_state = Loading;
+ dispatchCallback();
+ }
+}
+
+void QmlXMLHttpRequest::error(QNetworkReply::NetworkError error)
+{
+ m_responseEntityBody = QByteArray();
+ m_errorFlag = true;
+ m_request = QNetworkRequest();
+
+ destroyNetwork();
+
+ m_state = Done;
+ dispatchCallback();
+}
+
+void QmlXMLHttpRequest::finished()
+{
+ // ### We need to transparently redirect as dictated by the spec
+
+ if (m_state < HeadersReceived) {
+ m_state = HeadersReceived;
+ dispatchCallback();
+ }
+ m_responseEntityBody.append(m_network->readAll());
+ destroyNetwork();
+ if (m_state < Loading) {
+ m_state = Loading;
+ dispatchCallback();
+ }
+ m_state = Done;
+ dispatchCallback();
+}
+
+
+QString QmlXMLHttpRequest::responseBody() const
+{
+ return QString::fromUtf8(m_responseEntityBody);
+}
+
+void QmlXMLHttpRequest::dispatchCallback()
+{
+ m_callback.call();
+}
+
+void QmlXMLHttpRequest::destroyNetwork()
+{
+ if (m_network) {
+ m_network->disconnect();
+ m_network->deleteLater();
+ m_network = 0;
+ }
+}
+
+// XMLHttpRequest methods
+static QScriptValue qmlxmlhttprequest_open(QScriptContext *context, QScriptEngine *engine)
+{
+ QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject());
+ if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object"));
+
+ if (context->argumentCount() < 2 || context->argumentCount() > 5)
+ return context->throwError(QScriptContext::SyntaxError, "Incorrect argument count");
+
+ // Argument 0 - Method
+ QString method = context->argument(0).toString().toUpper();
+ if (method != QLatin1String("GET") &&
+ method != QLatin1String("PUT") &&
+ method != QLatin1String("HEAD") &&
+ method != QLatin1String("POST"))
+ return context->throwError(QScriptContext::SyntaxError, "Unsupported method");
+
+
+ // Argument 1 - URL
+ QUrl url(context->argument(1).toString()); // ### Need to resolve correctly
+
+ if (url.isRelative()) // ### Fix me
+ return context->throwError(QScriptContext::SyntaxError, "Relative URLs not supported");
+
+ // Argument 2 - async (optional)
+ if (context->argumentCount() > 2 && !context->argument(2).toBoolean())
+ return context->throwError(QScriptContext::SyntaxError, "Synchronous call not supported");
+
+
+ // Argument 3/4 - user/pass (optional)
+ QString username, password;
+ if (context->argumentCount() > 3)
+ username = context->argument(3).toString();
+ if (context->argumentCount() > 4)
+ password = context->argument(4).toString();
+
+
+ // Clear the fragment (if any)
+ url.setFragment(QString());
+ // Set username/password
+ if (!username.isNull()) url.setUserName(username);
+ if (!password.isNull()) url.setPassword(password);
+
+ request->open(method, url);
+
+ return engine->undefinedValue();
+}
+
+static QScriptValue qmlxmlhttprequest_setRequestHeader(QScriptContext *context, QScriptEngine *engine)
+{
+ QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject());
+ if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object"));
+
+ if (context->argumentCount() != 2)
+ return context->throwError(QScriptContext::SyntaxError, "Incorrect argument count");
+
+
+ if (request->readyState() != QmlXMLHttpRequest::Opened ||
+ request->sendFlag())
+ return context->throwError(INVALID_STATE_ERR, "Invalid state");
+
+
+ QString name = context->argument(0).toString();
+ QString value = context->argument(1).toString();
+
+ // ### Check that name and value are well formed
+
+ QString nameUpper = name.toUpper();
+ if (nameUpper == QLatin1String("ACCEPT-CHARSET") ||
+ nameUpper == QLatin1String("ACCEPT-ENCODING") ||
+ nameUpper == QLatin1String("CONNECTION") ||
+ nameUpper == QLatin1String("CONTENT-LENGTH") ||
+ nameUpper == QLatin1String("COOKIE") ||
+ nameUpper == QLatin1String("COOKIE2") ||
+ nameUpper == QLatin1String("CONTENT-TRANSFER-ENCODING") ||
+ nameUpper == QLatin1String("DATE") ||
+ nameUpper == QLatin1String("EXPECT") ||
+ nameUpper == QLatin1String("HOST") ||
+ nameUpper == QLatin1String("KEEP-ALIVE") ||
+ nameUpper == QLatin1String("REFERER") ||
+ nameUpper == QLatin1String("TE") ||
+ nameUpper == QLatin1String("TRAILER") ||
+ nameUpper == QLatin1String("TRANSFER-ENCODING") ||
+ nameUpper == QLatin1String("UPGRADE") ||
+ nameUpper == QLatin1String("USER-AGENT") ||
+ nameUpper == QLatin1String("VIA") ||
+ nameUpper.startsWith(QLatin1String("PROXY-")) ||
+ nameUpper.startsWith(QLatin1String("SEC-")))
+ return engine->undefinedValue();
+
+ request->addHeader(nameUpper, value);
+
+ return engine->undefinedValue();
+}
+
+static QScriptValue qmlxmlhttprequest_send(QScriptContext *context, QScriptEngine *engine)
+{
+ QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject());
+ if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object"));
+
+ if (request->readyState() != QmlXMLHttpRequest::Opened)
+ return context->throwError(INVALID_STATE_ERR, "Invalid state");
+
+ if (request->sendFlag())
+ return context->throwError(INVALID_STATE_ERR, "Invalid state");
+
+ QByteArray data;
+ if (context->argumentCount() > 0)
+ data = context->argument(0).toString().toUtf8();
+
+ request->send(data);
+
+ return engine->undefinedValue();
+}
+
+static QScriptValue qmlxmlhttprequest_abort(QScriptContext *context, QScriptEngine *engine)
+{
+ QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject());
+ if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object"));
+
+ request->abort();
+
+ return engine->undefinedValue();
+}
+
+static QScriptValue qmlxmlhttprequest_getResponseHeader(QScriptContext *context, QScriptEngine *engine)
+{
+ // ### Implement
+
+ return engine->undefinedValue();
+}
+
+static QScriptValue qmlxmlhttprequest_getAllResponseHeaders(QScriptContext *context, QScriptEngine *engine)
+{
+ // ### Implement
+
+ return engine->undefinedValue();
+}
+
+// XMLHttpRequest properties
+static QScriptValue qmlxmlhttprequest_readyState(QScriptContext *context, QScriptEngine *engine)
+{
+ QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject());
+ if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object"));
+
+ return QScriptValue(request->readyState());
+}
+
+static QScriptValue qmlxmlhttprequest_status(QScriptContext *context, QScriptEngine *engine)
+{
+ QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject());
+ if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object"));
+
+ if (request->readyState() == QmlXMLHttpRequest::Unsent ||
+ request->readyState() == QmlXMLHttpRequest::Opened)
+ return context->throwError(INVALID_STATE_ERR, "Invalid state");
+
+ if (request->errorFlag())
+ return QScriptValue(0);
+ else
+ return QScriptValue(request->replyStatus());
+}
+
+static QScriptValue qmlxmlhttprequest_statusText(QScriptContext *context, QScriptEngine *engine)
+{
+ QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject());
+ if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object"));
+
+ if (request->readyState() == QmlXMLHttpRequest::Unsent ||
+ request->readyState() == QmlXMLHttpRequest::Opened)
+ return context->throwError(INVALID_STATE_ERR, "Invalid state");
+
+ if (request->errorFlag())
+ return QScriptValue(0);
+ else
+ return QScriptValue(request->replyStatusText());
+}
+
+static QScriptValue qmlxmlhttprequest_responseText(QScriptContext *context, QScriptEngine *engine)
+{
+ QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject());
+ if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object"));
+
+ if (request->readyState() != QmlXMLHttpRequest::Loading &&
+ request->readyState() != QmlXMLHttpRequest::Done)
+ return QScriptValue(QString());
+ else
+ return QScriptValue(request->responseBody());
+}
+
+static QScriptValue qmlxmlhttprequest_onreadystatechange(QScriptContext *context, QScriptEngine *engine)
+{
+ QmlXMLHttpRequest *request = qobject_cast<QmlXMLHttpRequest *>(context->thisObject().data().toQObject());
+ if (!request) return context->throwError(QScriptContext::ReferenceError, QLatin1String("Not an XMLHttpRequest object"));
+
+ if (context->argumentCount())
+ request->setCallback(context->argument(0));
+
+ return request->callback();
+}
+
+// Constructor
+static QScriptValue qmlxmlhttprequest_new(QScriptContext *context, QScriptEngine *engine)
+{
+ QScriptValue rv = engine->newObject();
+ rv.setPrototype(context->callee().data());
+ rv.setData(engine->newQObject(new QmlXMLHttpRequest(QmlEnginePrivate::getEngine(engine)), QScriptEngine::ScriptOwnership));
+ return rv;
+}
+
+void qt_add_qmlxmlhttprequest(QScriptEngine *engine)
+{
+ QScriptValue prototype = engine->newObject();
+
+ // Constants
+ prototype.setProperty(QLatin1String("UNSENT"), 0, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+ prototype.setProperty(QLatin1String("OPENED"), 1, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+ prototype.setProperty(QLatin1String("HEADERS_RECEIVED"), 2, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+ prototype.setProperty(QLatin1String("LOADING"), 3, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+ prototype.setProperty(QLatin1String("DONE"), 4, QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration);
+
+ // Methods
+ prototype.setProperty(QLatin1String("open"), engine->newFunction(qmlxmlhttprequest_open, 2));
+ prototype.setProperty(QLatin1String("setRequestHeader"), engine->newFunction(qmlxmlhttprequest_setRequestHeader, 2));
+ prototype.setProperty(QLatin1String("send"), engine->newFunction(qmlxmlhttprequest_send));
+ prototype.setProperty(QLatin1String("abort"), engine->newFunction(qmlxmlhttprequest_abort));
+ prototype.setProperty(QLatin1String("getResponseHeader"), engine->newFunction(qmlxmlhttprequest_getResponseHeader, 1));
+ prototype.setProperty(QLatin1String("getAllResponseHeaders"), engine->newFunction(qmlxmlhttprequest_getAllResponseHeaders));
+
+ // Read-only properties
+ prototype.setProperty(QLatin1String("readyState"), engine->newFunction(qmlxmlhttprequest_readyState), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);
+ prototype.setProperty(QLatin1String("status"), engine->newFunction(qmlxmlhttprequest_status), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);
+ prototype.setProperty(QLatin1String("statusText"), engine->newFunction(qmlxmlhttprequest_statusText), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);
+ prototype.setProperty(QLatin1String("responseText"), engine->newFunction(qmlxmlhttprequest_responseText), QScriptValue::ReadOnly | QScriptValue::PropertyGetter);
+ prototype.setProperty(QLatin1String("onreadystatechange"), engine->newFunction(qmlxmlhttprequest_onreadystatechange), QScriptValue::PropertyGetter | QScriptValue::PropertySetter);
+
+ // Constructor
+ QScriptValue constructor = engine->newFunction(qmlxmlhttprequest_new);
+ constructor.setData(prototype);
+ engine->globalObject().setProperty(QLatin1String("XMLHttpRequest"), constructor);
+}
+
+#include "qmlxmlhttprequest.moc"
diff --git a/src/declarative/qml/qmlxmlhttprequest_p.h b/src/declarative/qml/qmlxmlhttprequest_p.h
new file mode 100644
index 0000000..2142bc6
--- /dev/null
+++ b/src/declarative/qml/qmlxmlhttprequest_p.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLXMLHTTPREQUEST_P_H
+#define QMLXMLHTTPREQUEST_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.
+//
+
+class QScriptEngine;
+void qt_add_qmlxmlhttprequest(QScriptEngine *engine);
+
+#endif // QMLXMLHTTPREQUEST_P_H
+
diff --git a/src/declarative/util/qmlanimation.cpp b/src/declarative/util/qmlanimation.cpp
index 89b5660..c535045 100644
--- a/src/declarative/util/qmlanimation.cpp
+++ b/src/declarative/util/qmlanimation.cpp
@@ -47,7 +47,7 @@
#include "qml.h"
#include "qmlinfo.h"
#include "qmlanimation_p.h"
-#include "qmlbehaviour.h"
+#include "qmlbehavior.h"
#include <QParallelAnimationGroup>
#include <QSequentialAnimationGroup>
#include <QtCore/qset.h>
@@ -154,7 +154,7 @@ QML_DEFINE_NOCREATE_TYPE(QmlAbstractAnimation)
*/
QmlAbstractAnimation::QmlAbstractAnimation(QObject *parent)
-: QmlPropertyValueSource(*(new QmlAbstractAnimationPrivate), parent)
+: QObject(*(new QmlAbstractAnimationPrivate), parent)
{
}
@@ -163,7 +163,7 @@ QmlAbstractAnimation::~QmlAbstractAnimation()
}
QmlAbstractAnimation::QmlAbstractAnimation(QmlAbstractAnimationPrivate &dd, QObject *parent)
-: QmlPropertyValueSource(dd, parent)
+: QObject(dd, parent)
{
}
@@ -330,7 +330,7 @@ void QmlAbstractAnimation::componentComplete()
calling the \c stop() method. The \c complete() method is not effected
by this value.
- This behaviour is most useful when the \c repeat property is set, as the
+ This behavior is most useful when the \c repeat property is set, as the
animation will finish playing normally but not restart.
By default, the alwaysRunToEnd property is not set.
@@ -1007,9 +1007,9 @@ void QmlPropertyAction::transition(QmlStateActions &actions,
{
for (int ii = 0; ii < actions.count(); ++ii) {
const Action &action = actions.at(ii);
- QmlBehaviour::_ignore = true;
+ QmlBehavior::_ignore = true;
action.property.write(action.toValue);
- QmlBehaviour::_ignore = false;
+ QmlBehavior::_ignore = false;
}
}
};
@@ -1338,7 +1338,7 @@ void QmlSequentialAnimation::transition(QmlStateActions &actions,
inc = -1;
from = d->animations.count() - 1;
}
-
+
//needed for Behavior
if (d->userProperty.isValid() && d->propertyName.isEmpty() && !target()) {
for (int i = 0; i < d->animations.count(); ++i)
@@ -1760,7 +1760,7 @@ void QmlPropertyAnimation::transition(QmlStateActions &actions,
for (int ii = 0; ii < actions.count(); ++ii) {
Action &action = actions[ii];
- QmlBehaviour::_ignore = true;
+ QmlBehavior::_ignore = true;
if (v == 1.)
action.property.write(action.toValue);
else {
@@ -1779,7 +1779,7 @@ void QmlPropertyAnimation::transition(QmlStateActions &actions,
if (interpolator)
action.property.write(interpolator(action.fromValue.constData(), action.toValue.constData(), v));
}
- QmlBehaviour::_ignore = false;
+ QmlBehavior::_ignore = false;
}
}
};
diff --git a/src/declarative/util/qmlanimation.h b/src/declarative/util/qmlanimation.h
index ba1e430..a898be8 100644
--- a/src/declarative/util/qmlanimation.h
+++ b/src/declarative/util/qmlanimation.h
@@ -58,7 +58,7 @@ QT_MODULE(Declarative)
class QmlAbstractAnimationPrivate;
class QmlAnimationGroup;
-class QmlAbstractAnimation : public QmlPropertyValueSource, public QmlParserStatus
+class QmlAbstractAnimation : public QObject, public QmlPropertyValueSource, public QmlParserStatus
{
Q_OBJECT
Q_DECLARE_PRIVATE(QmlAbstractAnimation)
diff --git a/src/declarative/util/qmlfollow.cpp b/src/declarative/util/qmlfollow.cpp
index eec2480..fe5303f 100644
--- a/src/declarative/util/qmlfollow.cpp
+++ b/src/declarative/util/qmlfollow.cpp
@@ -239,7 +239,7 @@ void QmlFollowPrivate::stop()
*/
QmlFollow::QmlFollow(QObject *parent)
-: QmlPropertyValueSource(*(new QmlFollowPrivate),parent)
+: QObject(*(new QmlFollowPrivate),parent)
{
}
diff --git a/src/declarative/util/qmlfollow.h b/src/declarative/util/qmlfollow.h
index 07b2f49..1f6376a 100644
--- a/src/declarative/util/qmlfollow.h
+++ b/src/declarative/util/qmlfollow.h
@@ -52,11 +52,12 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
class QmlFollowPrivate;
-class Q_DECLARATIVE_EXPORT QmlFollow : public QmlPropertyValueSource,
+class Q_DECLARATIVE_EXPORT QmlFollow : public QObject, public QmlPropertyValueSource,
public QmlParserStatus
{
Q_OBJECT
Q_DECLARE_PRIVATE(QmlFollow)
+ Q_INTERFACES(QmlPropertyValueSource)
Q_INTERFACES(QmlParserStatus)
Q_PROPERTY(qreal source READ sourceValue WRITE setSourceValue)
diff --git a/src/declarative/util/qmlstate.cpp b/src/declarative/util/qmlstate.cpp
index a17d16e..508ef43 100644
--- a/src/declarative/util/qmlstate.cpp
+++ b/src/declarative/util/qmlstate.cpp
@@ -208,7 +208,7 @@ void QmlState::setWhen(QmlBinding *when)
}
/*!
- \qmlproperty string State::extends
+ \qmlproperty string State::extend
This property holds the state that this state extends
The state being extended is treated as the base state in regards to
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 620f6f4..ead5aee 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -331,10 +331,6 @@
\value ItemNegativeZStacksBehindParent The item automatically stacks behind
it's parent if it's z-value is negative. This flag enables setZValue() to
toggle ItemStacksBehindParent.
-
- \value ItemAutoDetectsFocusProxy The item will assign any child that
- gains input focus as its focus proxy. See also focusProxy().
- This flag was introduced in Qt 4.6.
*/
/*!
@@ -944,17 +940,6 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
parent->itemChange(QGraphicsItem::ItemChildRemovedChange, thisPointerVariant);
}
- // Auto-update focus proxy. Any ancestor that has this as focus proxy
- //needs to be nulled.
- QGraphicsItem *p = parent;
- while (p) {
- if ((p->d_ptr->flags & QGraphicsItem::ItemAutoDetectsFocusProxy) &&
- (p->focusProxy() == q)) {
- p->setFocusProxy(0);
- }
- p = p->d_ptr->parent;
- }
-
// Update toplevelitem list. If this item is being deleted, its parent
// will be 0 but we don't want to register/unregister it in the TLI list.
if (scene && !inDestructor) {
@@ -969,7 +954,11 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
bool implicitUpdate = false;
if (parent->d_func()->scene && parent->d_func()->scene != scene) {
// Move this item to its new parent's scene
- parent->d_func()->scene->addItem(q);
+
+ QGraphicsItem *focusScope = newParent;
+ while (focusScope && !(focusScope->d_ptr->flags & QGraphicsItem::ItemIsFocusScope))
+ focusScope = focusScope->d_ptr->parent;
+ parent->d_func()->scene->d_func()->addItem(q, focusScope);
implicitUpdate = true;
} else if (!parent->d_func()->scene && scene) {
// Remove this item from its former scene
@@ -1031,17 +1020,6 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent)
if (lastSubFocusItem)
lastSubFocusItem->d_ptr->setSubFocus();
- // Auto-update focus proxy. The closest parent that detects
- // focus proxies is updated as the proxy gains or loses focus.
- p = newParent;
- while (p) {
- if (p->d_ptr->flags & QGraphicsItem::ItemAutoDetectsFocusProxy) {
- p->setFocusProxy(q);
- break;
- }
- p = p->d_ptr->parent;
- }
-
// Deliver post-change notification
q->itemChange(QGraphicsItem::ItemParentHasChanged, newParentVariant);
@@ -2663,11 +2641,27 @@ void QGraphicsItem::setFocus(Qt::FocusReason focusReason)
// Update the scene's focus item.
if (d_ptr->scene) {
+ QGraphicsItem *s = d_ptr->focusScope();
+ if (s) {
+ bool scopeHasFocus =
+ s->d_ptr->hasActiveFocus(d_ptr->scene->focusItem());
+ if (s->d_ptr->focusScopeItem)
+ s->d_ptr->focusScopeItem->d_ptr->setItemFocusedInScope(false);
+ s->d_ptr->focusScopeItem = this;
+ d_ptr->setItemFocusedInScope(true);
+ if (scopeHasFocus)
+ d_ptr->scene->d_func()->setFocusItemHelper(s, focusReason);
+ return;
+ }
+ d_ptr->setItemFocusedInScope(false);
+
QGraphicsWidget *w = window();
if (!w || w->isActiveWindow()) {
// Visible items immediately gain focus from scene.
d_ptr->scene->d_func()->setFocusItemHelper(f, focusReason);
}
+ } else {
+ d_ptr->setItemFocusedInScope(true);
}
}
@@ -2684,12 +2678,31 @@ void QGraphicsItem::setFocus(Qt::FocusReason focusReason)
*/
void QGraphicsItem::clearFocus()
{
- if (!d_ptr->scene)
+ if (!d_ptr->scene) {
+ d_ptr->setItemFocusedInScope(false);
return;
+ }
// Invisible items with focus must explicitly clear subfocus.
d_ptr->clearSubFocus();
+
+ if (d_ptr->itemIsFocusedInScope) {
+ d_ptr->setItemFocusedInScope(false);
+ QGraphicsItem *s = d_ptr->focusScope();
+ if (s) {
+ if (s->d_ptr->focusScopeItem == this) {
+ bool scopeHasFocus =
+ s->d_ptr->hasActiveFocus(d_ptr->scene->focusItem());
+ s->d_ptr->focusScopeItem = 0;
+ if (scopeHasFocus)
+ d_ptr->scene->setFocusItem(s);
+ return;
+ }
+ }
+ }
+
if (hasFocus()) {
// If this item has the scene's input focus, clear it.
+ d_ptr->setItemFocusedInScope(false);
d_ptr->scene->setFocusItem(0);
}
}
@@ -2700,7 +2713,7 @@ void QGraphicsItem::clearFocus()
Returns this item's focus proxy, or 0 if this item has no
focus proxy.
- \sa setFocusProxy(), ItemAutoDetectsFocusProxy, setFocus(), hasFocus()
+ \sa setFocusProxy(), setFocus(), hasFocus()
*/
QGraphicsItem *QGraphicsItem::focusProxy() const
{
@@ -2724,7 +2737,7 @@ QGraphicsItem *QGraphicsItem::focusProxy() const
The focus proxy \a item must belong to the same scene as
this item.
- \sa focusProxy(), ItemAutoDetectsFocusProxy, setFocus(), hasFocus()
+ \sa focusProxy(), setFocus(), hasFocus()
*/
void QGraphicsItem::setFocusProxy(QGraphicsItem *item)
{
@@ -4770,7 +4783,7 @@ void QGraphicsItemPrivate::setSubFocus()
bool hidden = !visible;
do {
parent->d_func()->subFocusItem = item;
- } while (!parent->isWindow() && (parent = parent->d_ptr->parent) && (!hidden || !parent->d_func()->visible));
+ } while (!parent->isWindow() && (parent = parent->d_ptr->parent) && (!hidden || !parent->d_func()->visible) && !(parent->d_ptr->flags & QGraphicsItem::ItemIsFocusScope));
}
/*!
@@ -10437,8 +10450,8 @@ QDebug operator<<(QDebug debug, QGraphicsItem::GraphicsItemFlag flag)
case QGraphicsItem::ItemNegativeZStacksBehindParent:
str = "ItemNegativeZStacksBehindParent";
break;
- case QGraphicsItem::ItemAutoDetectsFocusProxy:
- str = "ItemAutoDetectsFocusProxy";
+ case QGraphicsItem::ItemIsFocusScope:
+ str = "ItemIsFocusScope";
break;
}
debug << str;
diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h
index 7af7c2f..b76f5ac 100644
--- a/src/gui/graphicsview/qgraphicsitem.h
+++ b/src/gui/graphicsview/qgraphicsitem.h
@@ -103,8 +103,8 @@ public:
ItemHasNoContents = 0x400,
ItemSendsGeometryChanges = 0x800,
ItemAcceptsInputMethod = 0x1000,
- ItemAutoDetectsFocusProxy = 0x2000,
- ItemNegativeZStacksBehindParent = 0x4000
+ ItemNegativeZStacksBehindParent = 0x4000,
+ ItemIsFocusScope = 0x8000
// NB! Don't forget to increase the d_ptr->flags bit field by 1 when adding a new flag.
};
Q_DECLARE_FLAGS(GraphicsItemFlags, GraphicsItemFlag)
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index 11f6f53..7abd7f5 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -97,6 +97,8 @@ public:
void purge();
};
+#include <QDebug>
+
class Q_GUI_EXPORT QGraphicsItemPrivate
{
Q_DECLARE_PUBLIC(QGraphicsItem)
@@ -128,6 +130,7 @@ public:
siblingIndex(-1),
itemDepth(-1),
focusProxy(0),
+ focusScopeItem(0),
subFocusItem(0),
imHints(Qt::ImhNone),
acceptedMouseButtons(0x1f),
@@ -171,6 +174,7 @@ public:
notifyBoundingRectChanged(0),
notifyInvalidated(0),
mouseSetsFocus(1),
+ itemIsFocusedInScope(0),
globalStackingOrder(-1),
q_ptr(0)
{
@@ -410,6 +414,38 @@ public:
void clearSubFocus();
void resetFocusProxy();
+ inline QGraphicsItem *rootLevelFocusItem() const {
+ QGraphicsItem *fi = q_ptr;
+ while(QGraphicsItem *i = fi->d_ptr->focusScope())
+ fi = i;
+ return fi;
+ }
+
+ inline QGraphicsItem *focusScope() const {
+ QGraphicsItem *item = parent;
+ while (item) {
+ if (item->isWindow())
+ return 0;
+ if (item->d_ptr->flags & QGraphicsItem::ItemIsFocusScope)
+ return item;
+ item = item->d_ptr->parent;
+ }
+ return 0;
+ }
+ inline bool hasActiveFocus(QGraphicsItem *focusItem) const {
+ if (!(flags & QGraphicsItem::ItemIsFocusScope) || !focusScopeItem)
+ return focusItem == q_ptr;
+ else
+ return focusScopeItem->d_ptr->hasActiveFocus(focusItem);
+ }
+ inline void setItemFocusedInScope(bool f) {
+ if (itemIsFocusedInScope != f) {
+ itemIsFocusedInScope = f;
+ if (!inDestructor) focusedInScopeChanged();
+ }
+ }
+ inline virtual void focusedInScopeChanged() {}
+
inline QTransform transformToParent() const;
inline void ensureSortedChildren();
@@ -431,6 +467,7 @@ public:
int siblingIndex;
int itemDepth; // Lazily calculated when calling depth().
QGraphicsItem *focusProxy;
+ QGraphicsItem *focusScopeItem; // Only used if this is a focus scope
QList<QGraphicsItem **> focusProxyRefs;
QGraphicsItem *subFocusItem;
Qt::InputMethodHints imHints;
@@ -463,7 +500,7 @@ public:
// New 32 bits
quint32 fullUpdatePending : 1;
- quint32 flags : 15;
+ quint32 flags : 16;
quint32 dirtyChildrenBoundingRect : 1;
quint32 paintedViewBoundingRectsNeedRepaint : 1;
quint32 dirtySceneTransform : 1;
@@ -479,6 +516,7 @@ public:
quint32 notifyBoundingRectChanged : 1;
quint32 notifyInvalidated : 1;
quint32 mouseSetsFocus : 1;
+ quint32 itemIsFocusedInScope : 1;
quint32 unused : 1; // feel free to use
// Optional stacking order
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index a819822..af137e7 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -572,6 +572,10 @@ void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item,
Qt::FocusReason focusReason)
{
Q_Q(QGraphicsScene);
+
+ while (item && item->d_ptr->focusScopeItem)
+ item = item->d_ptr->focusScopeItem;
+
if (item == focusItem)
return;
@@ -589,22 +593,18 @@ void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item,
return;
}
- // Auto-update focus proxy. The closest parent that detects
- // focus proxies is updated as the proxy gains or loses focus.
- if (item) {
- QGraphicsItem *p = item->d_ptr->parent;
- while (p) {
- if (p->d_ptr->flags & QGraphicsItem::ItemAutoDetectsFocusProxy) {
- p->setFocusProxy(item);
- break;
- }
- p = p->d_ptr->parent;
- }
- }
+ QGraphicsItem *itemRootLevelFocusItem =
+ item?item->d_ptr->rootLevelFocusItem():0;
if (focusItem) {
QFocusEvent event(QEvent::FocusOut, focusReason);
lastFocusItem = focusItem;
+
+ QGraphicsItem *oldRootLevelFocusItem =
+ focusItem->d_ptr->rootLevelFocusItem();
+ if (oldRootLevelFocusItem != itemRootLevelFocusItem)
+ oldRootLevelFocusItem->d_ptr->setItemFocusedInScope(false);
+
focusItem = 0;
sendEvent(lastFocusItem, &event);
@@ -622,6 +622,8 @@ void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item,
if (item) {
focusItem = item;
+ itemRootLevelFocusItem->d_ptr->setItemFocusedInScope(true);
+ item->d_ptr->setItemFocusedInScope(true);
QFocusEvent event(QEvent::FocusIn, focusReason);
sendEvent(item, &event);
}
@@ -2240,11 +2242,19 @@ void QGraphicsScene::destroyItemGroup(QGraphicsItemGroup *group)
void QGraphicsScene::addItem(QGraphicsItem *item)
{
Q_D(QGraphicsScene);
+ d->addItem(item);
+}
+
+void QGraphicsScenePrivate::addItem(QGraphicsItem *item,
+ QGraphicsItem *focusScope)
+{
+ Q_Q(QGraphicsScene);
+
if (!item) {
qWarning("QGraphicsScene::addItem: cannot add null item");
return;
}
- if (item->scene() == this) {
+ if (item->scene() == q) {
qWarning("QGraphicsScene::addItem: item has already been added to this scene");
return;
}
@@ -2255,9 +2265,9 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
// Notify the item that its scene is changing, and allow the item to
// react.
const QVariant newSceneVariant(item->itemChange(QGraphicsItem::ItemSceneChange,
- qVariantFromValue<QGraphicsScene *>(this)));
+ qVariantFromValue<QGraphicsScene *>(q)));
QGraphicsScene *targetScene = qVariantValue<QGraphicsScene *>(newSceneVariant);
- if (targetScene != this) {
+ if (targetScene != q) {
if (targetScene && item->scene() != targetScene)
targetScene->addItem(item);
return;
@@ -2266,7 +2276,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
// Detach this item from its parent if the parent's scene is different
// from this scene.
if (QGraphicsItem *itemParent = item->parentItem()) {
- if (itemParent->scene() != this)
+ if (itemParent->scene() != q)
item->setParentItem(0);
}
@@ -2274,98 +2284,101 @@ void QGraphicsScene::addItem(QGraphicsItem *item)
item->d_func()->scene = targetScene;
// Add the item in the index
- d->index->addItem(item);
+ index->addItem(item);
// Add to list of toplevels if this item is a toplevel.
if (!item->d_ptr->parent)
- d->registerTopLevelItem(item);
+ registerTopLevelItem(item);
// Add to list of items that require an update. We cannot assume that the
// item is fully constructed, so calling item->update() can lead to a pure
// virtual function call to boundingRect().
- d->markDirty(item);
- d->dirtyGrowingItemsBoundingRect = true;
+ markDirty(item);
+ dirtyGrowingItemsBoundingRect = true;
// Disable selectionChanged() for individual items
- ++d->selectionChanging;
- int oldSelectedItemSize = d->selectedItems.size();
+ ++selectionChanging;
+ int oldSelectedItemSize = selectedItems.size();
// Enable mouse tracking if the item accepts hover events or has a cursor set.
- if (d->allItemsIgnoreHoverEvents && d->itemAcceptsHoverEvents_helper(item)) {
- d->allItemsIgnoreHoverEvents = false;
- d->enableMouseTrackingOnViews();
+ if (allItemsIgnoreHoverEvents && itemAcceptsHoverEvents_helper(item)) {
+ allItemsIgnoreHoverEvents = false;
+ enableMouseTrackingOnViews();
}
#ifndef QT_NO_CURSOR
- if (d->allItemsUseDefaultCursor && item->hasCursor()) {
- d->allItemsUseDefaultCursor = false;
- if (d->allItemsIgnoreHoverEvents) // already enabled otherwise
- d->enableMouseTrackingOnViews();
+ if (allItemsUseDefaultCursor && item->hasCursor()) {
+ allItemsUseDefaultCursor = false;
+ if (allItemsIgnoreHoverEvents) // already enabled otherwise
+ enableMouseTrackingOnViews();
}
#endif //QT_NO_CURSOR
// Enable touch events if the item accepts touch events.
- if (d->allItemsIgnoreTouchEvents && item->acceptTouchEvents()) {
- d->allItemsIgnoreTouchEvents = false;
- d->enableTouchEventsOnViews();
+ if (allItemsIgnoreTouchEvents && item->acceptTouchEvents()) {
+ allItemsIgnoreTouchEvents = false;
+ enableTouchEventsOnViews();
}
// Update selection lists
if (item->isSelected())
- d->selectedItems << item;
+ selectedItems << item;
if (item->isWidget() && item->isVisible() && static_cast<QGraphicsWidget *>(item)->windowType() == Qt::Popup)
- d->addPopup(static_cast<QGraphicsWidget *>(item));
+ addPopup(static_cast<QGraphicsWidget *>(item));
// Update creation order focus chain. Make sure to leave the widget's
// internal tab order intact.
if (item->isWidget()) {
QGraphicsWidget *widget = static_cast<QGraphicsWidget *>(item);
- if (!d->tabFocusFirst) {
+ if (!tabFocusFirst) {
// No first tab focus widget - make this the first tab focus
// widget.
- d->tabFocusFirst = widget;
+ tabFocusFirst = widget;
} else if (!widget->parentWidget()) {
// Adding a widget that is not part of a tab focus chain.
- QGraphicsWidget *last = d->tabFocusFirst->d_func()->focusPrev;
+ QGraphicsWidget *last = tabFocusFirst->d_func()->focusPrev;
QGraphicsWidget *lastNew = widget->d_func()->focusPrev;
last->d_func()->focusNext = widget;
widget->d_func()->focusPrev = last;
- d->tabFocusFirst->d_func()->focusPrev = lastNew;
- lastNew->d_func()->focusNext = d->tabFocusFirst;
+ tabFocusFirst->d_func()->focusPrev = lastNew;
+ lastNew->d_func()->focusNext = tabFocusFirst;
}
}
// Add all children recursively
+ QGraphicsItem *subFocusScope =
+ (item->d_ptr->flags & QGraphicsItem::ItemIsFocusScope)?item:focusScope;
foreach (QGraphicsItem *child, item->children())
- addItem(child);
+ addItem(child, subFocusScope);
// Resolve font and palette.
- item->d_ptr->resolveFont(d->font.resolve());
- item->d_ptr->resolvePalette(d->palette.resolve());
+ item->d_ptr->resolveFont(font.resolve());
+ item->d_ptr->resolvePalette(palette.resolve());
if (!item->d_ptr->explicitlyHidden) {
- if (d->unpolishedItems.isEmpty())
- QMetaObject::invokeMethod(this, "_q_polishItems", Qt::QueuedConnection);
- d->unpolishedItems << item;
+ if (unpolishedItems.isEmpty())
+ QMetaObject::invokeMethod(q, "_q_polishItems", Qt::QueuedConnection);
+ unpolishedItems << item;
}
// Reenable selectionChanged() for individual items
- --d->selectionChanging;
- if (!d->selectionChanging && d->selectedItems.size() != oldSelectedItemSize)
- emit selectionChanged();
+ --selectionChanging;
+ if (!selectionChanging && selectedItems.size() != oldSelectedItemSize)
+ emit q->selectionChanged();
// Deliver post-change notification
item->itemChange(QGraphicsItem::ItemSceneHasChanged, newSceneVariant);
// Auto-activate the first inactive window if the scene is active.
- if (d->activationRefCount > 0 && !d->activeWindow && item->isWindow())
- setActiveWindow(static_cast<QGraphicsWidget *>(item));
+ if (activationRefCount > 0 && !activeWindow && item->isWindow())
+ q->setActiveWindow(static_cast<QGraphicsWidget *>(item));
// Ensure that newly added items that have subfocus set, gain
// focus automatically if there isn't a focus item already.
- if (!d->focusItem && item->focusItem())
+ if (!focusItem && item->focusItem() ||
+ focusScope && !focusScope->d_ptr->focusScopeItem && item->focusItem())
item->focusItem()->setFocus();
- d->updateInputMethodSensitivityInViews();
+ updateInputMethodSensitivityInViews();
}
/*!
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
index 4b8791e..9e62901 100644
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_p.h
@@ -124,6 +124,8 @@ public:
QBrush backgroundBrush;
QBrush foregroundBrush;
+ void addItem(QGraphicsItem *, QGraphicsItem *focusScope = 0);
+
bool stickyFocus;
bool hasFocus;
QGraphicsItem *focusItem;
diff --git a/tests/auto/declarative/qmlengine/functions.qml b/tests/auto/declarative/qmlengine/functions.qml
new file mode 100644
index 0000000..28e8ed4
--- /dev/null
+++ b/tests/auto/declarative/qmlengine/functions.qml
@@ -0,0 +1,6 @@
+import Test 1.0
+
+MyTypeObject {
+ rectProperty: Qt.rect(0,0,100,100)
+ rectFProperty: Qt.rect(0,0.5,100,99.5)
+}
diff --git a/tests/auto/declarative/qmlengine/tst_qmlengine.cpp b/tests/auto/declarative/qmlengine/tst_qmlengine.cpp
index 9a04c61..8c050cb 100644
--- a/tests/auto/declarative/qmlengine/tst_qmlengine.cpp
+++ b/tests/auto/declarative/qmlengine/tst_qmlengine.cpp
@@ -1,4 +1,6 @@
#include <qtest.h>
+#include <QtDeclarative/qml.h>
+#include <QtDeclarative/QmlComponent>
#include <QtDeclarative/QmlEngine>
#include <QtCore/QDebug>
@@ -12,30 +14,83 @@ public:
tst_qmlengine() {}
private slots:
- void componentSearchPath();
-};
+ void valueTypeFunctions();
+private:
+ QmlEngine engine;
+};
-void tst_qmlengine::componentSearchPath()
+class MyTypeObject : public QObject
{
- QFile file(SRCDIR "/imports.qml");
- QVERIFY(file.open(QIODevice::ReadOnly));
+ Q_OBJECT
+ Q_PROPERTY(QPoint pointProperty READ pointProperty WRITE setPointProperty);
+ Q_PROPERTY(QPointF pointFProperty READ pointFProperty WRITE setPointFProperty);
+ Q_PROPERTY(QSize sizeProperty READ sizeProperty WRITE setSizeProperty);
+ Q_PROPERTY(QSizeF sizeFProperty READ sizeFProperty WRITE setSizeFProperty);
+ Q_PROPERTY(QRect rectProperty READ rectProperty WRITE setRectProperty NOTIFY rectPropertyChanged);
+ Q_PROPERTY(QRectF rectFProperty READ rectFProperty WRITE setRectFProperty);
+
+public:
+ MyTypeObject() {}
- QmlEngine engine;
+ QPoint pointPropertyValue;
+ QPoint pointProperty() const {
+ return pointPropertyValue;
+ }
+ void setPointProperty(const QPoint &v) {
+ pointPropertyValue = v;
+ }
- QList<QUrl> searchPath = engine.componentSearchPath(file.readAll(),
- QUrl::fromLocalFile(file.fileName()));
+ QPointF pointFPropertyValue;
+ QPointF pointFProperty() const {
+ return pointFPropertyValue;
+ }
+ void setPointFProperty(const QPointF &v) {
+ pointFPropertyValue = v;
+ }
- QList<QUrl> expected;
- expected << QUrl::fromLocalFile(SRCDIR);
- expected << QUrl::fromLocalFile(file.fileName()).resolved(QUrl("import1"));
- expected << QUrl::fromLocalFile(file.fileName()).resolved(QUrl("import2"));
+ QSize sizePropertyValue;
+ QSize sizeProperty() const {
+ return sizePropertyValue;
+ }
+ void setSizeProperty(const QSize &v) {
+ sizePropertyValue = v;
+ }
- QCOMPARE(searchPath.size(), expected.size());
- for (int i = 0; i < expected.size(); ++i) {
- QCOMPARE(searchPath.at(i).toString(QUrl::StripTrailingSlash),
- expected.at(i).toString(QUrl::StripTrailingSlash));
+ QSizeF sizeFPropertyValue;
+ QSizeF sizeFProperty() const {
+ return sizeFPropertyValue;
}
+ void setSizeFProperty(const QSizeF &v) {
+ sizeFPropertyValue = v;
+ }
+
+ QRect rectPropertyValue;
+ QRect rectProperty() const {
+ return rectPropertyValue;
+ }
+ void setRectProperty(const QRect &v) {
+ rectPropertyValue = v;
+ }
+
+ QRectF rectFPropertyValue;
+ QRectF rectFProperty() const {
+ return rectFPropertyValue;
+ }
+ void setRectFProperty(const QRectF &v) {
+ rectFPropertyValue = v;
+ }
+
+};
+QML_DECLARE_TYPE(MyTypeObject);
+QML_DEFINE_TYPE(Test, 1, 0, 0, MyTypeObject, MyTypeObject);
+
+void tst_qmlengine::valueTypeFunctions()
+{
+ QmlComponent component(&engine, SRCDIR "/functions.qml");
+ MyTypeObject *obj = qobject_cast<MyTypeObject*>(component.create());
+ QCOMPARE(obj->rectProperty(), QRect(0,0,100,100));
+ QCOMPARE(obj->rectFProperty(), QRectF(0,0.5,100,99.5));
}
QTEST_MAIN(tst_qmlengine)
diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
index e9154d4..b1835c8 100644
--- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
+++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
@@ -161,7 +161,6 @@ public slots:
void init();
private slots:
- void explicitDeleteAutoFocusProxy();
void construction();
void constructionWithParent();
void destruction();
@@ -281,9 +280,7 @@ private slots:
void hitTestUntransformableItem();
void hitTestGraphicsEffectItem();
void focusProxy();
- void autoDetectFocusProxy();
void subFocus();
- void reverseCreateAutoFocusProxy();
void focusProxyDeletion();
void negativeZStacksBehindParent();
void setGraphicsEffect();
@@ -7540,31 +7537,6 @@ void tst_QGraphicsItem::focusProxy()
QCOMPARE(item3->focusProxy(), (QGraphicsItem *)0);
}
-void tst_QGraphicsItem::autoDetectFocusProxy()
-{
- QGraphicsScene scene;
- QGraphicsItem *item = scene.addRect(0, 0, 10, 10);
- item->setFlag(QGraphicsItem::ItemIsFocusable);
-
- QGraphicsItem *item2 = scene.addRect(0, 0, 10, 10);
- item2->setParentItem(item);
- item2->setFlag(QGraphicsItem::ItemIsFocusable);
-
- QGraphicsItem *item3 = scene.addRect(0, 0, 10, 10);
- item3->setParentItem(item2);
- item3->setFlag(QGraphicsItem::ItemIsFocusable);
-
- item->setFlag(QGraphicsItem::ItemAutoDetectsFocusProxy);
- QCOMPARE(item->focusProxy(), (QGraphicsItem *)0);
-
- item2->setFocus();
- QCOMPARE(item->focusProxy(), item2);
- item3->setFocus();
- QCOMPARE(item->focusProxy(), item3);
- item3->clearFocus();
- QCOMPARE(item->focusProxy(), item3);
-}
-
void tst_QGraphicsItem::subFocus()
{
// Construct a text item that's not part of a scene (yet)
@@ -7624,49 +7596,6 @@ void tst_QGraphicsItem::subFocus()
QVERIFY(text2->hasFocus());
}
-void tst_QGraphicsItem::reverseCreateAutoFocusProxy()
-{
- QGraphicsTextItem *text = new QGraphicsTextItem;
- text->setTextInteractionFlags(Qt::TextEditorInteraction);
- text->setFlag(QGraphicsItem::ItemAutoDetectsFocusProxy);
-
- QGraphicsTextItem *text2 = new QGraphicsTextItem;
- text2->setTextInteractionFlags(Qt::TextEditorInteraction);
- text2->setFocus();
- QVERIFY(!text2->hasFocus());
- QCOMPARE(text->focusProxy(), (QGraphicsItem *)0);
- text2->setParentItem(text);
- QCOMPARE(text->focusProxy(), (QGraphicsItem *)text2);
- QCOMPARE(text->focusItem(), (QGraphicsItem *)text2);
-
- QGraphicsScene scene;
- scene.addItem(text);
- QVERIFY(text2->hasFocus());
-}
-
-void tst_QGraphicsItem::explicitDeleteAutoFocusProxy()
-{
- QGraphicsTextItem *text = new QGraphicsTextItem;
- text->setTextInteractionFlags(Qt::TextEditorInteraction);
- text->setFlag(QGraphicsItem::ItemAutoDetectsFocusProxy);
-
- QGraphicsTextItem *text2 = new QGraphicsTextItem;
- text2->setTextInteractionFlags(Qt::TextEditorInteraction);
- text2->setFocus();
- QVERIFY(!text2->hasFocus());
- QCOMPARE(text->focusProxy(), (QGraphicsItem *)0);
- text2->setParentItem(text);
- QCOMPARE(text->focusProxy(), (QGraphicsItem *)text2);
- QCOMPARE(text->focusItem(), (QGraphicsItem *)text2);
-
- QGraphicsScene scene;
- scene.addItem(text);
- QVERIFY(text2->hasFocus());
-
- delete text2;
- QCOMPARE(text->focusProxy(), (QGraphicsItem *)0);
-}
-
void tst_QGraphicsItem::focusProxyDeletion()
{
QGraphicsRectItem *rect = new QGraphicsRectItem;
diff --git a/tools/qmlviewer/main.cpp b/tools/qmlviewer/main.cpp
index ca159f3..a4ed054 100644
--- a/tools/qmlviewer/main.cpp
+++ b/tools/qmlviewer/main.cpp
@@ -161,6 +161,7 @@ int main(int argc, char ** argv)
viewer.show();
viewer.open();
}
+ viewer.raise();
return app.exec();
}