From 792ce37abd5c48e6e1811287eb23e35e32303bca Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Fri, 8 May 2009 09:45:18 +1000 Subject: Fixes for the slider. --- demos/declarative/flickr/content/ImageDetails.qml | 3 ++- demos/declarative/flickr/content/Slider.qml | 1 + demos/declarative/flickr/flickr.qml | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/demos/declarative/flickr/content/ImageDetails.qml b/demos/declarative/flickr/content/ImageDetails.qml index 6c354f6..1e52235 100644 --- a/demos/declarative/flickr/content/ImageDetails.qml +++ b/demos/declarative/flickr/content/ImageDetails.qml @@ -3,6 +3,7 @@ Flipable { property var frontContainer: ContainerFront property var flickableArea: Flickable + property var slider: Slider property string photoTitle: "" property string photoDescription: "" property string photoTags: "" @@ -96,7 +97,7 @@ Flipable { anchors.centeredIn: parent; color: "white"; font.bold: true } - Slider { id: Slider; x: 25; y: 374; imageWidth: Container.photoWidth; imageHeight: Container.photoHeight } + Slider { id: Slider; x: 25; y: 374; visible: BigImage.status == 0; imageWidth: Container.photoWidth; imageHeight: Container.photoHeight } } states: [ diff --git a/demos/declarative/flickr/content/Slider.qml b/demos/declarative/flickr/content/Slider.qml index ba9d842..c6a3e5e 100644 --- a/demos/declarative/flickr/content/Slider.qml +++ b/demos/declarative/flickr/content/Slider.qml @@ -3,6 +3,7 @@ Item { property var value: Handle.x / Slider.xMax property int xMax: Slider.width - Handle.width - 2 + property var handle: Handle property int imageWidth property int imageHeight diff --git a/demos/declarative/flickr/flickr.qml b/demos/declarative/flickr/flickr.qml index 85af8e3..dc150cb 100644 --- a/demos/declarative/flickr/flickr.qml +++ b/demos/declarative/flickr/flickr.qml @@ -58,6 +58,7 @@ Item { ImageDetails.photoDate = photoDate; ImageDetails.photoUrl = url; ImageDetails.rating = 0; + ImageDetails.slider.handle.x = ImageDetails.slider.xMax; Wrapper.state = "Details"; } } @@ -121,7 +122,7 @@ Item { Image { source: "content/pics/background.png"; opaque: true } GridView { - id: PhotoGridView; model: FeedModel; delegate: PhotoDelegate + id: PhotoGridView; model: FeedModel; delegate: PhotoDelegate; cacheBuffer: 100 cellWidth: 105; cellHeight: 105; x:32; y: 80; width: 800; height: 330; z: 1 } -- cgit v0.12 From 6cfefeac5db91186027fc203cf9f8f354a0eedac Mon Sep 17 00:00:00 2001 From: Ian Walters Date: Fri, 8 May 2009 10:43:56 +1000 Subject: Don't assume will get non-0 item to send key to. Before this change was getting crashes when the window lost focus. This is because the target was non-0, but the focusItem stored for that target was 0. --- src/declarative/fx/qfxkeyproxy.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/declarative/fx/qfxkeyproxy.cpp b/src/declarative/fx/qfxkeyproxy.cpp index 1bb54ec..848b2d9 100644 --- a/src/declarative/fx/qfxkeyproxy.cpp +++ b/src/declarative/fx/qfxkeyproxy.cpp @@ -94,9 +94,9 @@ QList *QFxKeyProxy::targets() const void QFxKeyProxy::keyPressEvent(QKeyEvent *e) { for (int ii = 0; ii < d->targets.count(); ++ii) { - QSimpleCanvasItem *i = d->targets.at(ii); + QSimpleCanvasItem *i = canvas()->focusItem(d->targets.at(ii)); if (i) - canvas()->focusItem(i)->keyPressEvent(e); + i->keyPressEvent(e); if (e->isAccepted()) return; } @@ -105,9 +105,9 @@ void QFxKeyProxy::keyPressEvent(QKeyEvent *e) void QFxKeyProxy::keyReleaseEvent(QKeyEvent *e) { for (int ii = 0; ii < d->targets.count(); ++ii) { - QSimpleCanvasItem *i = d->targets.at(ii); + QSimpleCanvasItem *i = canvas()->focusItem(d->targets.at(ii)); if (i) - canvas()->focusItem(i)->keyReleaseEvent(e); + i->keyReleaseEvent(e); if (e->isAccepted()) return; } -- cgit v0.12 From bbf6d8ecaa896881f111be731a0718a124b6d21b Mon Sep 17 00:00:00 2001 From: Ian Walters Date: Fri, 8 May 2009 10:45:30 +1000 Subject: Add the ability to remove whole contacts. --- demos/declarative/contacts/Contact.qml | 69 ++++++++++++++++++----------- demos/declarative/contacts/ContactField.qml | 2 +- demos/declarative/contacts/RemoveButton.qml | 6 +++ demos/declarative/contacts/contacts.qml | 22 ++++++++- 4 files changed, 70 insertions(+), 29 deletions(-) diff --git a/demos/declarative/contacts/Contact.qml b/demos/declarative/contacts/Contact.qml index 7297fa6..50c9d1c 100644 --- a/demos/declarative/contacts/Contact.qml +++ b/demos/declarative/contacts/Contact.qml @@ -16,41 +16,53 @@ Item { id: updateContactQuery connection: contactDatabase query: "UPDATE contacts SET label = :l, email = :e, phone = :p WHERE recid = :r" - bindings: SqlBind { - name: ":r" - value: contactId - } - bindings: SqlBind { - name: ":l" - value: labelField.value - } - bindings: SqlBind { - name: ":e" - value: emailField.value - } - bindings: SqlBind { - name: ":p" - value: phoneField.value - } + bindings: [ + SqlBind { + name: ":r" + value: contactId + }, + SqlBind { + name: ":l" + value: labelField.value + }, + SqlBind { + name: ":e" + value: emailField.value + }, + SqlBind { + name: ":p" + value: phoneField.value + } + ] }, SqlQuery { id: insertContactQuery connection: contactDatabase query: "INSERT INTO contacts (label, email, phone) VALUES(:l, :e, :p)" + bindings: [ + SqlBind { + name: ":l" + value: labelField.value + }, + SqlBind { + name: ":e" + value: emailField.value + }, + SqlBind { + name: ":p" + value: phoneField.value + } + ] + }, + SqlQuery { + id: removeContactQuery + connection: contactDatabase + query: "DELETE FROM contacts WHERE recid = :r" bindings: SqlBind { - name: ":l" - value: labelField.value - } - bindings: SqlBind { - name: ":e" - value: emailField.value - } - bindings: SqlBind { - name: ":p" - value: phoneField.value + name: ":r" + value: contactId } } - ] function refresh() { labelField.value = label; @@ -63,6 +75,9 @@ Item { function insert() { insertContactQuery.exec(); } + function remove() { + removeContactQuery.exec(); + } VerticalLayout { id: layout anchors.fill: parent diff --git a/demos/declarative/contacts/ContactField.qml b/demos/declarative/contacts/ContactField.qml index cb319ae..003e723 100644 --- a/demos/declarative/contacts/ContactField.qml +++ b/demos/declarative/contacts/ContactField.qml @@ -3,7 +3,7 @@ Item { clip: true height: 30 property var label: "Name" - property var icon: "pics/phone.png" + property var icon: "" property var value: "" onValueChanged: { fieldText.text = contactField.value } RemoveButton { diff --git a/demos/declarative/contacts/RemoveButton.qml b/demos/declarative/contacts/RemoveButton.qml index 114db2e..59e3fcb 100644 --- a/demos/declarative/contacts/RemoveButton.qml +++ b/demos/declarative/contacts/RemoveButton.qml @@ -76,6 +76,12 @@ Rect { text: "Remove" opacity: 0 } + opacity: Behaviour { + NumericAnimation { + property: "opacity" + duration: 250 + } + } states: [ State { name: "opened" diff --git a/demos/declarative/contacts/contacts.qml b/demos/declarative/contacts/contacts.qml index 4582bd1..b38e02e 100644 --- a/demos/declarative/contacts/contacts.qml +++ b/demos/declarative/contacts/contacts.qml @@ -127,13 +127,26 @@ Rect { sender: cancelEditButton signal: "clicked()" script: { - if (wrapper.state == 'opened' && !contacts.mouseGrabbed) { + if (wrapper.state == 'opened' && !contacts.mouseGrabbed) { wrapper.state = ''; contacts.mode = 'list'; } } } + Connection { + sender: removeContactButton + signal: "confirmed()" + script: { + if (wrapper.state == 'opened' && !contacts.mouseGrabbed) { + Details.qmlItem.remove(); + wrapper.state = ''; + contacts.mode = 'list'; + contactList.exec(); + } + + } + } } } ] @@ -165,6 +178,13 @@ Rect { icon: "pics/cancel.png" opacity: contacts.mode == 'list' || contacts.mouseGrabbed ? 0 : 1 } + RemoveButton { + id: removeContactButton + anchors.top: parent.top + anchors.topMargin: 5 + anchors.horizontalCenter: parent.horizontalCenter + opacity: (contacts.mode == 'edit' && (!contacts.mouseGrabbed || removeContactButton.state =='opened')) ? 1 : 0 + } ListView { id: contactListView anchors.left: parent.left -- cgit v0.12 From 93b289cb9d2ff48e5b894a0b91fa5372df399004 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Fri, 8 May 2009 10:47:03 +1000 Subject: Warn when dereferencing a non-existant name --- src/declarative/qml/script/qmlbasicscript.cpp | 1 + src/declarative/qml/script/qmlbasicscript_p.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/declarative/qml/script/qmlbasicscript.cpp b/src/declarative/qml/script/qmlbasicscript.cpp index 603e6ba..ee537e4 100644 --- a/src/declarative/qml/script/qmlbasicscript.cpp +++ b/src/declarative/qml/script/qmlbasicscript.cpp @@ -789,6 +789,7 @@ QVariant QmlBasicScript::run(QmlContext *context, void *voidCache, CacheState *c state = Incremental; } + qWarning("ReferenceError: %s is not defined", id); } else { // instr.type == ScriptInstruction::Fetch QVariant o = stack.pop(); diff --git a/src/declarative/qml/script/qmlbasicscript_p.h b/src/declarative/qml/script/qmlbasicscript_p.h index bcb7d00..fb9951e 100644 --- a/src/declarative/qml/script/qmlbasicscript_p.h +++ b/src/declarative/qml/script/qmlbasicscript_p.h @@ -39,6 +39,7 @@ public: }; int coreType; + bool isValid() const { return type != Invalid; } bool isCore() const { return type == Core; } bool isExplicit() const { return type == Explicit; } void clear(); -- cgit v0.12 From 6b1da53ad4ee4fa9bd60c8c039ba18d386c5e1ad Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Fri, 8 May 2009 11:05:24 +1000 Subject: More path to path fixing. --- demos/declarative/flickr/flickr2.qml | 124 ++++++++++++++++------------------- src/declarative/fx/qfxpathview.cpp | 12 ++-- 2 files changed, 61 insertions(+), 75 deletions(-) diff --git a/demos/declarative/flickr/flickr2.qml b/demos/declarative/flickr/flickr2.qml index 3b1208c..41d7d88 100644 --- a/demos/declarative/flickr/flickr2.qml +++ b/demos/declarative/flickr/flickr2.qml @@ -29,11 +29,15 @@ Item { delegate: Package { Item { - id: Wrapper; width: 85; height: 85 - scale: Wrapper.PathView.scale; z: Wrapper.PathView.z + id: Wrapper; width: 85; height: 85; scale: {1.0} + z: RightBox.PathView.z + property real angle: 0 * 0 transform: [ - Rotation3D { id: Rotation; axis.startX: 30; axis.endX: 30; axis.endY: 60; angle: Wrapper.PathView.angle } + Rotation3D { + id: Rotation; axis.startX: 30; axis.endX: 30; axis.endY: 60 + angle: Wrapper.angle + } ] Connection { @@ -111,7 +115,7 @@ Item { Item { Package.name: "rightBox" - id: RightBox; x: 200; width: 85; height: 85 + id: RightBox; width: 85; height: 85 } Item { @@ -120,73 +124,58 @@ Item { } Item { - id: MyItem - states: [ - State { - name: "left" - when: MainWindow.showPathView == true - SetProperty { - target: Wrapper - property: "moveToParent" - value: LeftBox - } - }, - State { - name: "right" - when: MainWindow.showPathView == false - SetProperty { - target: Wrapper - property: "moveToParent" - value: RightBox + id: MyItem + state: MainWindow.showPathView ? "right" : "left" + states: [ + State { + name: "left" + SetProperty { target: Wrapper; property: "moveToParent"; value: LeftBox } + }, + State { + name: "right" + SetProperty { target: Wrapper; property: "scale"; value: RightBox.PathView.scale } + SetProperty { target: Wrapper; property: "scale"; binding: "RightBox.PathView.scale" } + SetProperty { target: Wrapper; property: "angle"; value: RightBox.PathView.angle } + SetProperty { target: Wrapper; property: "angle"; binding: "RightBox.PathView.angle" } + SetProperty { target: Wrapper; property: "moveToParent"; value: RightBox } } - } - ] - transitions: [ - Transition { - fromState: "left" - toState: "right" - SequentialAnimation { - SetPropertyAction { - target: Wrapper - property: "moveToParent" - } - ParallelAnimation { - NumericAnimation { - target: Wrapper - properties: "x,y" - to: 0 - easing: "easeOutQuad" - duration: 350 + ] + transitions: [ + Transition { + toState: "right" + SequentialAnimation { + SetPropertyAction { target: Wrapper; property: "moveToParent" } + ParallelAnimation { + NumericAnimation { + target: Wrapper + properties: "x,y" + to: 0 + easing: "easeOutQuad" + duration: 350 + } + NumericAnimation { target: Wrapper; properties: "scale,angle"; duration: 350 } } } - } - }, - Transition { - fromState: "right" - toState: "left" - SequentialAnimation { - PauseAnimation { - duration: Math.floor(index/7)*100 - } - SetPropertyAction { - target: Wrapper - property: "moveToParent" - } - ParallelAnimation { - NumericAnimation { - target: Wrapper - properties: "x,y" - to: 0 - easing: "easeOutQuad" - duration: 250 + }, + Transition { + toState: "left" + SequentialAnimation { + PauseAnimation { duration: Math.floor(index/7)*100 } + SetPropertyAction { target: Wrapper; property: "moveToParent" } + ParallelAnimation { + NumericAnimation { + target: Wrapper + properties: "x,y" + to: 0 + easing: "easeOutQuad" + duration: 250 + } + NumericAnimation { target: Wrapper; properties: "scale,angle"; duration: 250 } } } } - } - ] - state: "right" - } - + ] + } } } @@ -213,7 +202,7 @@ Item { PathLine { x: -50; y: 40 } PathPercent { value: 0.001 } - PathAttribute { name: "scale"; value: 1 } + PathAttribute { name: "scale"; value: 0.9 } PathAttribute { name: "angle"; value: -45 } PathCubic { @@ -232,14 +221,13 @@ Item { control1X: 590; control1Y: 220 } - PathAttribute { name: "scale"; value: 1 } + PathAttribute { name: "scale"; value: 0.9 } PathAttribute { name: "angle"; value: -45 } PathPercent { value: 0.999 } PathLine { x: 950; y: 40 } PathPercent { value: 1.0 } } - } ImageDetails { id: ImageDetails; width: 750; x: 25; y: 500; height: 410 } diff --git a/src/declarative/fx/qfxpathview.cpp b/src/declarative/fx/qfxpathview.cpp index 2b39d6e..77d5fa2 100644 --- a/src/declarative/fx/qfxpathview.cpp +++ b/src/declarative/fx/qfxpathview.cpp @@ -157,7 +157,6 @@ void QFxPathView::setModel(const QVariant &model) disconnect(d->model, SIGNAL(itemCreated(int, QFxItem*)), this, SLOT(itemCreated(int,QFxItem*))); for (int i=0; iitems.count(); i++){ QFxItem *p = d->items[i]; - attachedProperties.remove(p); d->model->release(p); } d->items.clear(); @@ -557,7 +556,6 @@ void QFxPathViewPrivate::regenerate() Q_Q(QFxPathView); for (int i=0; iattachedProperties.remove(p); model->release(p); } items.clear(); @@ -631,7 +629,6 @@ void QFxPathView::refill() while(wrapIndex-- >= 0){ QFxItem* p = d->items.takeFirst(); d->updateItem(p, 0.0); - attachedProperties.remove(p); d->model->release(p); d->firstIndex++; d->firstIndex %= d->model->count(); @@ -645,7 +642,6 @@ void QFxPathView::refill() while(wrapIndex++ < d->items.count()-1){ QFxItem* p = d->items.takeLast(); d->updateItem(p, 1.0); - attachedProperties.remove(p); d->model->release(p); d->firstIndex--; if (d->firstIndex < 0) @@ -704,7 +700,6 @@ void QFxPathView::itemsRemoved(int modelIndex, int count) if (d->pathItems == -1) { for (int i = 0; i < count; ++i) { QFxItem* p = d->items.takeAt(modelIndex); - attachedProperties.remove(p); d->model->release(p); } d->snapToCurrent(); @@ -876,8 +871,11 @@ void QFxPathViewPrivate::snapToCurrent() QHash QFxPathView::attachedProperties; QObject *QFxPathView::qmlAttachedProperties(QObject *obj) { - QFxPathViewAttached *rv = new QFxPathViewAttached(obj); - attachedProperties.insert(obj, rv); + QObject *rv = attachedProperties.value(obj); + if (!rv) { + rv = new QFxPathViewAttached(obj); + attachedProperties.insert(obj, rv); + } return rv; } -- cgit v0.12 From 3a2b763f7e74f1ee7617e539ca42372c57debbc2 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Fri, 8 May 2009 11:07:44 +1000 Subject: Get the delegate scale correct at the ends of the path. --- demos/declarative/flickr/flickr2.qml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/demos/declarative/flickr/flickr2.qml b/demos/declarative/flickr/flickr2.qml index 41d7d88..f5f569e 100644 --- a/demos/declarative/flickr/flickr2.qml +++ b/demos/declarative/flickr/flickr2.qml @@ -198,12 +198,12 @@ Item { path: Path { startX: -150; startY: 40; + PathAttribute { name: "scale"; value: 0.9 } + PathAttribute { name: "angle"; value: -45 } PathPercent { value: 0 } PathLine { x: -50; y: 40 } PathPercent { value: 0.001 } - PathAttribute { name: "scale"; value: 0.9 } - PathAttribute { name: "angle"; value: -45 } PathCubic { x: 400; y: 220 @@ -221,12 +221,11 @@ Item { control1X: 590; control1Y: 220 } - PathAttribute { name: "scale"; value: 0.9 } - PathAttribute { name: "angle"; value: -45 } - PathPercent { value: 0.999 } PathLine { x: 950; y: 40 } PathPercent { value: 1.0 } + PathAttribute { name: "scale"; value: 0.9 } + PathAttribute { name: "angle"; value: -45 } } } -- cgit v0.12 From cce83e2985bbdfe33d04162c3e20243e10ece46a Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Fri, 8 May 2009 12:06:19 +1000 Subject: setWidth() and setHeight() lost their virtual at some point :-/ --- src/declarative/fx/qfxflickable.cpp | 12 ++++++------ src/declarative/fx/qfxflickable.h | 4 ++-- src/declarative/fx/qfxgridview.cpp | 21 +++------------------ src/declarative/fx/qfxgridview.h | 4 +--- src/declarative/fx/qfxlistview.cpp | 24 ++---------------------- src/declarative/fx/qfxlistview.h | 7 +------ 6 files changed, 15 insertions(+), 57 deletions(-) diff --git a/src/declarative/fx/qfxflickable.cpp b/src/declarative/fx/qfxflickable.cpp index 52b142b..890bb31 100644 --- a/src/declarative/fx/qfxflickable.cpp +++ b/src/declarative/fx/qfxflickable.cpp @@ -116,6 +116,8 @@ void QFxFlickablePrivate::init() QObject::connect(_flick, SIGNAL(topChanged()), q, SIGNAL(positionChanged())); QObject::connect(&elasticX, SIGNAL(updated()), q, SLOT(ticked())); QObject::connect(&elasticY, SIGNAL(updated()), q, SLOT(ticked())); + QObject::connect(q, SIGNAL(heightChanged()), q, SLOT(heightChange())); + QObject::connect(q, SIGNAL(widthChanged()), q, SLOT(widthChange())); } void QFxFlickablePrivate::fixupX() @@ -914,23 +916,21 @@ void QFxFlickable::setViewportWidth(int w) d->updateBeginningEnd(); } -void QFxFlickable::setWidth(int w) +void QFxFlickable::widthChange() { Q_D(QFxFlickable); - QFxItem::setWidth(w); if (d->vWidth < 0) { - d->_flick->setWidth(w); + d->_flick->setWidth(width()); emit viewportWidthChanged(); d->updateBeginningEnd(); } } -void QFxFlickable::setHeight(int h) +void QFxFlickable::heightChange() { Q_D(QFxFlickable); - QFxItem::setHeight(h); if (d->vHeight < 0) { - d->_flick->setHeight(h); + d->_flick->setHeight(height()); emit viewportHeightChanged(); d->updateBeginningEnd(); } diff --git a/src/declarative/fx/qfxflickable.h b/src/declarative/fx/qfxflickable.h index 1281788..c5a0593 100644 --- a/src/declarative/fx/qfxflickable.h +++ b/src/declarative/fx/qfxflickable.h @@ -133,8 +133,6 @@ public: qreal pageYPosition() const; qreal pageHeight() const; - virtual void setWidth(int); - virtual void setHeight(int); QFxItem *viewport(); Q_SIGNALS: @@ -165,6 +163,8 @@ protected Q_SLOTS: virtual void ticked(); void movementStarting(); void movementEnding(); + void heightChange(); + void widthChange(); protected: virtual qreal minXExtent() const; diff --git a/src/declarative/fx/qfxgridview.cpp b/src/declarative/fx/qfxgridview.cpp index acfb57e..9e6f2c9 100644 --- a/src/declarative/fx/qfxgridview.cpp +++ b/src/declarative/fx/qfxgridview.cpp @@ -319,6 +319,8 @@ void QFxGridViewPrivate::init() { Q_Q(QFxGridView); q->setOptions(QFxGridView::IsFocusRealm); + QObject::connect(q, SIGNAL(widthChanged()), q, SLOT(sizeChange())); + QObject::connect(q, SIGNAL(heightChanged()), q, SLOT(sizeChange())); } void QFxGridViewPrivate::clear() @@ -996,26 +998,9 @@ void QFxGridView::setCellHeight(int cellHeight) } } -/*! - \reimp -*/ -void QFxGridView::setHeight(int height) -{ - Q_D(QFxGridView); - QFxFlickable::setHeight(height); - if (isComponentComplete()) { - d->updateGrid(); - d->layout(); - } -} - -/*! - \reimp -*/ -void QFxGridView::setWidth(int width) +void QFxGridView::sizeChange() { Q_D(QFxGridView); - QFxFlickable::setWidth(width); if (isComponentComplete()) { d->updateGrid(); d->layout(); diff --git a/src/declarative/fx/qfxgridview.h b/src/declarative/fx/qfxgridview.h index c612804..2bbfc40 100644 --- a/src/declarative/fx/qfxgridview.h +++ b/src/declarative/fx/qfxgridview.h @@ -109,9 +109,6 @@ public: int cellHeight() const; void setCellHeight(int); - virtual void setHeight(int height); - virtual void setWidth(int width); - static QObject *qmlAttachedProperties(QObject *); Q_SIGNALS: @@ -134,6 +131,7 @@ private Q_SLOTS: void itemsInserted(int index, int count); void itemsRemoved(int index, int count); void destroyRemoved(); + void sizeChange(); private: void refill(); diff --git a/src/declarative/fx/qfxlistview.cpp b/src/declarative/fx/qfxlistview.cpp index b256c4a..ad752a7 100644 --- a/src/declarative/fx/qfxlistview.cpp +++ b/src/declarative/fx/qfxlistview.cpp @@ -356,6 +356,8 @@ void QFxListViewPrivate::init() { Q_Q(QFxListView); q->setOptions(QFxListView::IsFocusRealm); + QObject::connect(q, SIGNAL(heightChanged()), q, SLOT(refill())); + QObject::connect(q, SIGNAL(widthChanged()), q, SLOT(refill())); } void QFxListViewPrivate::clear() @@ -1190,28 +1192,6 @@ QString QFxListView::currentSection() const return d->currentSection; } -/*! - \reimp -*/ -void QFxListView::setHeight(int height) -{ - Q_D(QFxListView); - QFxFlickable::setHeight(height); - if (d->orient == Qt::Vertical && isComponentComplete()) - refill(); -} - -/*! - \reimp -*/ -void QFxListView::setWidth(int width) -{ - Q_D(QFxListView); - QFxFlickable::setWidth(width); - if (d->orient == Qt::Horizontal && isComponentComplete()) - refill(); -} - void QFxListView::viewportMoved() { Q_D(QFxListView); diff --git a/src/declarative/fx/qfxlistview.h b/src/declarative/fx/qfxlistview.h index f15db0c..40c2496 100644 --- a/src/declarative/fx/qfxlistview.h +++ b/src/declarative/fx/qfxlistview.h @@ -116,9 +116,6 @@ public: void setSectionExpression(const QString &); QString currentSection() const; - virtual void setHeight(int height); - virtual void setWidth(int width); - static QObject *qmlAttachedProperties(QObject *); Q_SIGNALS: @@ -137,10 +134,8 @@ protected: virtual void keyReleaseEvent(QKeyEvent *); virtual void componentComplete(); -private: - void refill(); - private Q_SLOTS: + void refill(); void trackedPositionChanged(); void itemResized(); void itemsInserted(int index, int count); -- cgit v0.12 From 242410e288280b9bcf8f3b68fa362be44e4c8813 Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Fri, 8 May 2009 12:22:17 +1000 Subject: Tweak debugger watches --- src/declarative/debugger/debugger.pri | 6 +- src/declarative/debugger/qmldebugger.cpp | 84 ++------- src/declarative/debugger/qmldebugger.h | 8 +- src/declarative/debugger/qmlpropertyview.cpp | 97 +++++++++- src/declarative/debugger/qmlpropertyview_p.h | 6 +- src/declarative/debugger/qmlwatches.cpp | 267 +++++++++++++++++++++++++++ src/declarative/debugger/qmlwatches_p.h | 99 ++++++++++ src/declarative/qml/qmlengine.cpp | 11 ++ src/declarative/qml/qmlexpression.h | 1 + 9 files changed, 499 insertions(+), 80 deletions(-) create mode 100644 src/declarative/debugger/qmlwatches.cpp create mode 100644 src/declarative/debugger/qmlwatches_p.h diff --git a/src/declarative/debugger/debugger.pri b/src/declarative/debugger/debugger.pri index 31a1d5b..bf693d9 100644 --- a/src/declarative/debugger/debugger.pri +++ b/src/declarative/debugger/debugger.pri @@ -1,7 +1,9 @@ SOURCES += debugger/qmldebugger.cpp \ debugger/qmldebuggerstatus.cpp \ - debugger/qmlpropertyview.cpp + debugger/qmlpropertyview.cpp \ + debugger/qmlwatches.cpp HEADERS += debugger/qmldebugger.h \ debugger/qmldebuggerstatus.h \ - debugger/qmlpropertyview_p.h + debugger/qmlpropertyview_p.h \ + debugger/qmlwatches_p.h diff --git a/src/declarative/debugger/qmldebugger.cpp b/src/declarative/debugger/qmldebugger.cpp index 634385b..250f451 100644 --- a/src/declarative/debugger/qmldebugger.cpp +++ b/src/declarative/debugger/qmldebugger.cpp @@ -58,10 +58,11 @@ #include #include #include +#include QmlDebugger::QmlDebugger(QWidget *parent) -: QWidget(parent), m_tree(0), m_warnings(0), m_watchers(0), m_properties(0), - m_text(0) +: QWidget(parent), m_tree(0), m_warnings(0), m_watchTable(0), m_watches(0), + m_properties(0), m_text(0) { QHBoxLayout *layout = new QHBoxLayout; setLayout(layout); @@ -75,7 +76,6 @@ QmlDebugger::QmlDebugger(QWidget *parent) splitter->addWidget(treeWid); m_tree = new QTreeWidget(treeWid); - m_tree->setSelectionMode(QTreeWidget::NoSelection); m_tree->setHeaderHidden(true); QObject::connect(m_tree, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(itemClicked(QTreeWidgetItem *))); QObject::connect(m_tree, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(itemDoubleClicked(QTreeWidgetItem *))); @@ -95,11 +95,13 @@ QmlDebugger::QmlDebugger(QWidget *parent) m_warnings->setHeaderHidden(true); tabs->addTab(m_warnings, "Warnings"); - m_watchers = new QTableWidget(this); - m_watchers->setSelectionMode(QTableWidget::NoSelection); - tabs->addTab(m_watchers, "Watchers"); + m_watches = new QmlWatches(this); + m_watchTable = new QTableView(this); + m_watchTable->setSelectionMode(QTableWidget::NoSelection); + m_watchTable->setModel(m_watches); + tabs->addTab(m_watchTable, "Watches"); - m_properties = new QmlPropertyView(this); + m_properties = new QmlPropertyView(m_watches, this); tabs->addTab(m_properties, "Properties"); splitter->addWidget(tabs); @@ -131,21 +133,6 @@ public: void QmlDebugger::itemDoubleClicked(QTreeWidgetItem *i) { - QmlDebuggerItem *item = static_cast(i); - - if(item->bindableValue) { - - QmlExpressionPrivate *p = item->bindableValue->d; - - if(m_watchedIds.contains(p->id)) { - m_watchedIds.remove(p->id); - item->setForeground(0, Qt::green); - } else { - m_watchedIds.insert(p->id); - item->setForeground(0, QColor("purple")); - } - - } } void QmlDebugger::itemClicked(QTreeWidgetItem *i) @@ -227,36 +214,16 @@ bool QmlDebugger::makeItem(QObject *obj, QmlDebuggerItem *item) QmlExpressionPrivate *p = bv->d; text = bv->property().name() + ": " + bv->expression(); - bool watched = m_watchedIds.contains(p->id); - if(watched) - item->setForeground(0, QColor("purple")); - else - item->setForeground(0, Qt::green); + item->setForeground(0, Qt::green); item->bindableValue = bv; if(p->log) { QTreeWidgetItem *warningItem = 0; - int column = m_watchers->columnCount(); - - if(watched) { - m_watchers->insertColumn(column); - QTableWidgetItem *tableheader = new QTableWidgetItem; - tableheader->setText(bv->expression()); - tableheader->setToolTip(bv->expression()); - m_watchers->setHorizontalHeaderItem(column, tableheader); - } - for(int ii = 0; ii < p->log->count(); ++ii) { const QmlExpressionLog &log = p->log->at(ii); QString variant; QDebug d(&variant); d << log.result(); - if(watched) { - QString str = log.result().toString(); - if(str.isEmpty()) - str = variant; - m_expressions << qMakePair(log.time(), qMakePair(column, str)); - } if(!log.warnings().isEmpty()) { @@ -280,14 +247,12 @@ bool QmlDebugger::makeItem(QObject *obj, QmlDebuggerItem *item) } + delete item; + return false; + } else if(QmlBoundSignal *bs = qobject_cast(obj)) { - QMetaMethod method = obj->parent()->metaObject()->method(bs->index()); - QByteArray sig = method.signature(); - if(!sig.isEmpty()) - text = sig + ": "; - text += bs->expression(); - item->setForeground(0, Qt::blue); - rv = false; + delete item; + return false; } else { QmlContext *context = qmlContext(obj); QmlContext *parentContext = qmlContext(obj->parent()); @@ -359,10 +324,6 @@ void QmlDebugger::setDebugObject(QObject *obj) { m_tree->clear(); m_warnings->clear(); - m_watchers->clear(); - m_watchers->setColumnCount(0); - m_watchers->setRowCount(0); - m_expressions.clear(); m_object = obj; if(!obj) @@ -372,20 +333,5 @@ void QmlDebugger::setDebugObject(QObject *obj) makeItem(obj, item); buildTree(obj, item); item->setExpanded(true); - - m_watchers->setRowCount(m_expressions.count()); - - qSort(m_expressions.begin(), m_expressions.end()); - - for(int ii = 0; ii < m_expressions.count(); ++ii) { - - const QPair > &expr = m_expressions.at(ii); - QTableWidgetItem *item = new QTableWidgetItem; - item->setText(expr.second.second); - m_watchers->setItem(ii, expr.second.first, item); - - } - - } diff --git a/src/declarative/debugger/qmldebugger.h b/src/declarative/debugger/qmldebugger.h index 35ff92c..776ded3 100644 --- a/src/declarative/debugger/qmldebugger.h +++ b/src/declarative/debugger/qmldebugger.h @@ -56,8 +56,9 @@ class QTreeWidget; class QTreeWidgetItem; class QPlainTextEdit; class QmlDebuggerItem; -class QTableWidget; +class QTableView; class QmlPropertyView; +class QmlWatches; class QmlDebugger : public QWidget { Q_OBJECT @@ -78,12 +79,11 @@ private: bool makeItem(QObject *obj, QmlDebuggerItem *item); QTreeWidget *m_tree; QTreeWidget *m_warnings; - QTableWidget *m_watchers; + QTableView *m_watchTable; + QmlWatches *m_watches; QmlPropertyView *m_properties; QPlainTextEdit *m_text; QPointer m_object; - QList > > m_expressions; - QSet m_watchedIds; QPointer m_selectedItem; }; diff --git a/src/declarative/debugger/qmlpropertyview.cpp b/src/declarative/debugger/qmlpropertyview.cpp index 2434c58..b46a1bf 100644 --- a/src/declarative/debugger/qmlpropertyview.cpp +++ b/src/declarative/debugger/qmlpropertyview.cpp @@ -43,9 +43,12 @@ #include #include #include +#include +#include +#include -QmlPropertyView::QmlPropertyView(QWidget *parent) -: QWidget(parent), m_tree(0) +QmlPropertyView::QmlPropertyView(QmlWatches *watches, QWidget *parent) +: QWidget(parent), m_tree(0), m_watches(watches) { QVBoxLayout *layout = new QVBoxLayout; layout->setContentsMargins(0, 0, 0, 0); @@ -54,6 +57,8 @@ QmlPropertyView::QmlPropertyView(QWidget *parent) m_tree = new QTreeWidget(this); m_tree->setHeaderLabels(QStringList() << "Property" << "Value"); + QObject::connect(m_tree, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), + this, SLOT(itemDoubleClicked(QTreeWidgetItem *))); m_tree->setColumnCount(2); @@ -65,16 +70,24 @@ class QmlPropertyViewItem : public QObject, public QTreeWidgetItem Q_OBJECT public: QmlPropertyViewItem(QTreeWidget *widget); + QmlPropertyViewItem(QTreeWidgetItem *parent); QObject *object; QMetaProperty property; + quint32 exprId; + public slots: void refresh(); }; QmlPropertyViewItem::QmlPropertyViewItem(QTreeWidget *widget) -: QTreeWidgetItem(widget) +: QTreeWidgetItem(widget), object(0), exprId(0) +{ +} + +QmlPropertyViewItem::QmlPropertyViewItem(QTreeWidgetItem *parent) +: QTreeWidgetItem(parent), object(0), exprId(0) { } @@ -83,6 +96,33 @@ void QmlPropertyViewItem::refresh() setText(1, property.read(object).toString()); } +void QmlPropertyView::itemDoubleClicked(QTreeWidgetItem *i) +{ + QmlPropertyViewItem *item = static_cast(i); + + if(item->object) { + quint32 objectId = m_watches->objectId(item->object); + + if(m_watches->hasWatch(objectId, item->property.name())) { + m_watches->remWatch(objectId, item->property.name()); + item->setForeground(0, Qt::black); + } else { + m_watches->addWatch(objectId, item->property.name()); + item->setForeground(0, Qt::red); + } + } else if(item->exprId) { + + if(m_watches->hasWatch(item->exprId)) { + m_watches->remWatch(item->exprId); + item->setForeground(1, Qt::green); + } else { + m_watches->addWatch(item->exprId); + item->setForeground(1, Qt::darkGreen); + } + + } +} + void QmlPropertyView::setObject(QObject *object) { m_object = object; @@ -91,15 +131,38 @@ void QmlPropertyView::setObject(QObject *object) if(!m_object) return; + QMultiHash > bindings; + QHash sigs; + QObjectList children = object->children(); + + foreach(QObject *child, children) { + if(QmlBindableValue *value = qobject_cast(child)) { + bindings.insert(value->property().name().toUtf8(), qMakePair(value->expression(), value->id())); + } else if(QmlBoundSignal *signal = qobject_cast(child)) { + QMetaMethod method = object->metaObject()->method(signal->index()); + QByteArray sig = method.signature(); + sigs.insert(sig, signal->expression()); + } + } + + quint32 objectId = m_watches->objectId(object); + const QMetaObject *mo = object->metaObject(); for(int ii = 0; ii < mo->propertyCount(); ++ii) { + QMetaProperty p = mo->property(ii); + + if(QmlMetaType::isList(p.userType()) || + QmlMetaType::isQmlList(p.userType())) + continue; + QmlPropertyViewItem *item = new QmlPropertyViewItem(m_tree); - QMetaProperty p = mo->property(ii); item->object = object; item->property = p; item->setText(0, QLatin1String(p.name())); + if(m_watches->hasWatch(objectId, p.name())) + item->setForeground(0, Qt::red); static int refreshIdx = -1; if(refreshIdx == -1) @@ -109,8 +172,34 @@ void QmlPropertyView::setObject(QObject *object) QMetaObject::connect(object, p.notifySignalIndex(), item, refreshIdx); + + QMultiHash >::Iterator iter = + bindings.find(p.name()); + + while(iter != bindings.end() && iter.key() == p.name()) { + QmlPropertyViewItem *binding = new QmlPropertyViewItem(item); + binding->exprId = iter.value().second; + binding->setText(1, iter.value().first); + if (m_watches->hasWatch(binding->exprId)) + binding->setForeground(1, Qt::darkGreen); + else + binding->setForeground(1, Qt::green); + ++iter; + } + + item->setExpanded(true); item->refresh(); } + + for(QHash::ConstIterator iter = sigs.begin(); + iter != sigs.end(); + ++iter) { + + QTreeWidgetItem *item = new QTreeWidgetItem(m_tree); + item->setText(0, iter.key()); + item->setForeground(0, Qt::blue); + item->setText(1, iter.value()); + } } void QmlPropertyView::refresh() diff --git a/src/declarative/debugger/qmlpropertyview_p.h b/src/declarative/debugger/qmlpropertyview_p.h index fce9941..a671ea1 100644 --- a/src/declarative/debugger/qmlpropertyview_p.h +++ b/src/declarative/debugger/qmlpropertyview_p.h @@ -44,24 +44,28 @@ #include #include +#include QT_BEGIN_NAMESPACE class QTreeWidget; +class QTreeWidgetItem; class QmlPropertyView : public QWidget { Q_OBJECT public: - QmlPropertyView(QWidget *parent = 0); + QmlPropertyView(QmlWatches *watches, QWidget *parent = 0); void setObject(QObject *); public slots: void refresh(); + void itemDoubleClicked(QTreeWidgetItem *); private: QPointer m_object; QTreeWidget *m_tree; + QmlWatches *m_watches; }; QT_END_NAMESPACE diff --git a/src/declarative/debugger/qmlwatches.cpp b/src/declarative/debugger/qmlwatches.cpp new file mode 100644 index 0000000..1b9befd --- /dev/null +++ b/src/declarative/debugger/qmlwatches.cpp @@ -0,0 +1,267 @@ +/**************************************************************************** +** +** 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 "qmlwatches_p.h" +#include +#include +#include +#include + +static QString objectToString(QObject *obj) +{ + if(!obj) + return QString(); + + QString objectName = obj->objectName(); + if(objectName.isEmpty()) + objectName = QLatin1String(""); + + QString rv = QLatin1String(obj->metaObject()->className()) + + QLatin1String(": ") + objectName; + + return rv; +} + +class QmlWatchesProxy : public QObject +{ + Q_OBJECT +public: + QmlWatchesProxy(QObject *object, + const QMetaProperty &prop, + int column, + QmlWatches *parent = 0); + +public slots: + void refresh(); + +private: + QmlWatches *m_watches; + QObject *m_object; + QMetaProperty m_property; + int m_column; +}; + +QmlWatchesProxy::QmlWatchesProxy(QObject *object, + const QMetaProperty &prop, + int column, + QmlWatches *parent) +: QObject(parent), m_watches(parent), m_object(object), m_property(prop), + m_column(column) +{ + static int refreshIdx = -1; + if(refreshIdx == -1) + refreshIdx = QmlWatchesProxy::staticMetaObject.indexOfMethod("refresh()"); + + QMetaObject::connect(m_object, prop.notifySignalIndex(), + this, refreshIdx); +} + +void QmlWatchesProxy::refresh() +{ + QVariant v = m_property.read(m_object); + m_watches->addValue(m_column, v); +} + +QmlWatches::QmlWatches(QObject *parent) +: QAbstractTableModel(parent), m_uniqueId(0) +{ +} + +bool QmlWatches::hasWatch(quint32 objectId, const QByteArray &property) +{ + return m_watches.contains(qMakePair(objectId, property)); +} + +void QmlWatches::addWatch(quint32 objectId, const QByteArray &property) +{ + if(hasWatch(objectId, property)) + return; + + int oldColumn = columnCount(QModelIndex()); + + + m_watches.append(qMakePair(objectId, property)); + + beginInsertColumns(QModelIndex(), oldColumn, oldColumn); + endInsertColumns(); + + QObject *obj = object(objectId); + m_columnNames.append(QLatin1String(property) + QLatin1String(" on ") + objectToString(obj)); + QMetaProperty prop = + obj->metaObject()->property(obj->metaObject()->indexOfProperty(property.constData())); + QmlWatchesProxy *proxy = new QmlWatchesProxy(obj, prop, oldColumn, this); + proxy->refresh(); + m_values[m_values.count() - 1].first = true; +} + +void QmlWatches::remWatch(quint32 objectId, const QByteArray &property) +{ + m_watches.removeAll(qMakePair(objectId, property)); +} + +bool QmlWatches::hasWatch(quint32 exprId) +{ + return m_exprWatches.contains(exprId); +} + +void QmlWatches::remWatch(quint32 exprId) +{ + m_exprWatches.removeAll(exprId); +} + +void QmlWatches::addWatch(quint32 exprId) +{ + if (hasWatch(exprId)) + return; + + int oldColumn = columnCount(QModelIndex()); + + m_exprWatches.append(exprId); + + beginInsertColumns(QModelIndex(), oldColumn, oldColumn); + endInsertColumns(); +} + +quint32 QmlWatches::objectId(QObject *object) +{ + Q_ASSERT(object); + + QHash, quint32> *>::Iterator iter = + m_objects.find(object); + if(iter == m_objects.end()) { + iter = m_objects.insert(object, new QPair, quint32>(QPointer(object), m_uniqueId++)); + m_objectIds.insert(iter.value()->second, iter.value()); + } + + if(iter.value()->first != object) { + iter.value()->first = object; + iter.value()->second = m_uniqueId++; + + m_objectIds.insert(iter.value()->second, iter.value()); + } + return iter.value()->second; +} + +QObject *QmlWatches::object(quint32 id) +{ + QHash, quint32> *>::Iterator iter = + m_objectIds.find(id); + if(iter == m_objectIds.end()) + return 0; + + if(!iter.value()->first) { + m_objectIds.erase(iter); + return 0; + } + + return iter.value()->first; +} + +void QmlWatches::addValue(int column, const QVariant &value) +{ + int row = m_values.count(); + + beginInsertRows(QModelIndex(), row, row); + Value v; + v.column = column; + v.variant = value; + v.first = false; + m_values.append(v); + endInsertRows(); +} + +int QmlWatches::columnCount(const QModelIndex &) const +{ + return m_watches.count() + m_exprWatches.count(); +} + +int QmlWatches::rowCount(const QModelIndex &) const +{ + return m_values.count(); +} + +QVariant QmlWatches::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation == Qt::Horizontal && section < m_columnNames.count() && + role == Qt::DisplayRole) + return m_columnNames.at(section); + else + return QVariant(); +} + +QVariant QmlWatches::data(const QModelIndex &idx, int role) const +{ + if(m_values.at(idx.row()).column == idx.column()) { + if(role == Qt::DisplayRole) { + const QVariant &value = m_values.at(idx.row()).variant; + + QString str = value.toString(); + + if(str.isEmpty() && QmlMetaType::isObject(value.userType())) { + QObject *o = QmlMetaType::toQObject(value); + if(o) { + QString objectName = o->objectName(); + if(objectName.isEmpty()) + objectName = QLatin1String(""); + str = QLatin1String(o->metaObject()->className()) + + QLatin1String(": ") + objectName; + } + } + + if(str.isEmpty()) { + QDebug d(&str); + d << value; + } + return QVariant(str); + } else if(role == Qt::BackgroundRole) { + if(m_values.at(idx.row()).first) + return QColor(Qt::green); + else + return QVariant(); + } else { + return QVariant(); + } + } else { + return QVariant(); + } +} + +#include "qmlwatches.moc" diff --git a/src/declarative/debugger/qmlwatches_p.h b/src/declarative/debugger/qmlwatches_p.h new file mode 100644 index 0000000..12a6468 --- /dev/null +++ b/src/declarative/debugger/qmlwatches_p.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** 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 QMLWATCHES_P_H +#define QMLWATCHES_P_H + +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QmlWatchesProxy; +class QmlWatches : public QAbstractTableModel +{ + Q_OBJECT +public: + QmlWatches(QObject *parent = 0); + + bool hasWatch(quint32 objectId, const QByteArray &property); + void addWatch(quint32 objectId, const QByteArray &property); + void remWatch(quint32 objectId, const QByteArray &property); + + bool hasWatch(quint32 exprId); + void remWatch(quint32 exprId); + void addWatch(quint32 exprId); + + quint32 objectId(QObject *); + QObject *object(quint32); + +protected: + int columnCount(const QModelIndex &) const; + int rowCount(const QModelIndex &) const; + QVariant data(const QModelIndex &, int) const; + QVariant headerData(int, Qt::Orientation, int) const; + +private: + friend class QmlWatchesProxy; + QList > m_watches; + QList m_exprWatches; + + void addValue(int, const QVariant &); + struct Value { + int column; + QVariant variant; + bool first; + }; + QList m_values; + QStringList m_columnNames; + + quint32 m_uniqueId; + QHash, quint32> *> m_objects; + QHash, quint32> *> m_objectIds; +}; + +QT_END_NAMESPACE + +#endif // QMLWATCHES_P_H diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index 15b5879..50c0981 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -597,6 +597,9 @@ QNetworkAccessManager *QmlEngine::networkAccessManager() const */ QmlContext *QmlEngine::contextForObject(const QObject *object) { + if(!object) + return 0; + QObjectPrivate *priv = QObjectPrivate::get(const_cast(object)); QmlSimpleDeclarativeData *data = @@ -1093,6 +1096,14 @@ QObject *QmlExpression::scopeObject() const } /*! + \internal +*/ +quint32 QmlExpression::id() const +{ + return d->id; +} + +/*! \class QmlExpression \brief The QmlExpression class evaluates ECMAScript in a QML context. */ diff --git a/src/declarative/qml/qmlexpression.h b/src/declarative/qml/qmlexpression.h index 0ab5d9c..bb6980a 100644 --- a/src/declarative/qml/qmlexpression.h +++ b/src/declarative/qml/qmlexpression.h @@ -80,6 +80,7 @@ public: QObject *scopeObject() const; + quint32 id() const; protected: virtual void valueChanged(); -- cgit v0.12