diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2010-06-29 10:59:37 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2010-06-29 10:59:37 (GMT) |
commit | 66db2c2b9e4395dffbb073942c23bd737567cc28 (patch) | |
tree | db2f8afc412f8457110ce6bd9df112a2e5f5c88a /src | |
parent | 844171ae6d0a3a02cfb9a39ff18a27d7204a8755 (diff) | |
parent | 836140b72663aa6b520d7c40d01813c164a60f8e (diff) | |
download | Qt-66db2c2b9e4395dffbb073942c23bd737567cc28.zip Qt-66db2c2b9e4395dffbb073942c23bd737567cc28.tar.gz Qt-66db2c2b9e4395dffbb073942c23bd737567cc28.tar.bz2 |
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-qml into 4.7-integration
* '4.7' of scm.dev.nokia.troll.no:qt/qt-qml: (53 commits)
Undefined is undefined, and now qml warns about it
Fix so window will resize with the root object (broken by
Avoid duplicate code for testing initial sizes
Remove an unnecessary connect() in TextInput
Ensure micro focus is updated in TextEdit and TextInput
Fix flow layout not taking into account whether it's width and height are implicit or not.
Avoid binding loop.
Ensure Loader item change listener is removed when Loader is destroyed
Adapt all qmlviewer testcases to the code changes in the actual viewer.
Stop QMLLauncher from crashing on exit on Mac when quitting app via the
VisualDataModel hasModelChildren role shadowed user roles.
Allow positioning of ListView items width sub-pixel precision.
Examples clean up
Docs
Improve appearance when scaling
Tweak Qt Demo Behaviour
forget to rename the moc include when renaming deviceorientation_maemo.cpp
fix namespace macros
fix QML Viewer resize modes
forgot to cleanup the code a bit after adding Maemo5 support
...
Diffstat (limited to 'src')
39 files changed, 465 insertions, 161 deletions
diff --git a/src/3rdparty/webkit/WebKit/qt/declarative/qdeclarativewebview.cpp b/src/3rdparty/webkit/WebKit/qt/declarative/qdeclarativewebview.cpp index a349bec..0342c9f 100644 --- a/src/3rdparty/webkit/WebKit/qt/declarative/qdeclarativewebview.cpp +++ b/src/3rdparty/webkit/WebKit/qt/declarative/qdeclarativewebview.cpp @@ -180,6 +180,8 @@ void GraphicsWebView::mouseMoveEvent(QGraphicsSceneMouseEvent* event) When this item has keyboard focus, all keyboard input will be sent directly to the web page within. + + \sa {declarative/modelviews/webview}{WebView example}, {demos/declarative/webbrowser}{Web Browser demo} */ /*! diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp index 3f681b7..65bc233 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp @@ -122,7 +122,7 @@ void QDeclarativeFlickableVisibleArea::updateVisible() QDeclarativeFlickablePrivate::QDeclarativeFlickablePrivate() - : viewport(new QDeclarativeItem) + : contentItem(new QDeclarativeItem) , hData(this, &QDeclarativeFlickablePrivate::setRoundedViewportX) , vData(this, &QDeclarativeFlickablePrivate::setRoundedViewportY) , flickingHorizontally(false), flickingVertically(false) @@ -140,8 +140,8 @@ QDeclarativeFlickablePrivate::QDeclarativeFlickablePrivate() void QDeclarativeFlickablePrivate::init() { Q_Q(QDeclarativeFlickable); - QDeclarative_setParent_noEvent(viewport, q); - viewport->setParentItem(q); + QDeclarative_setParent_noEvent(contentItem, q); + contentItem->setParentItem(q); static int timelineUpdatedIdx = -1; static int timelineCompletedIdx = -1; static int flickableTickedIdx = -1; @@ -158,7 +158,7 @@ void QDeclarativeFlickablePrivate::init() q, flickableMovementEndingIdx, Qt::DirectConnection); q->setAcceptedMouseButtons(Qt::LeftButton); q->setFiltersChildEvents(true); - QDeclarativeItemPrivate *viewportPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(viewport)); + QDeclarativeItemPrivate *viewportPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(contentItem)); viewportPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); lastPosTime.invalidate(); } @@ -182,7 +182,7 @@ qreal QDeclarativeFlickablePrivate::overShootDistance(qreal velocity, qreal size void QDeclarativeFlickablePrivate::itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeom, const QRectF &oldGeom) { Q_Q(QDeclarativeFlickable); - if (item == viewport) { + if (item == contentItem) { if (newGeom.x() != oldGeom.x()) emit q->contentXChanged(); if (newGeom.y() != oldGeom.y()) @@ -579,10 +579,28 @@ void QDeclarativeFlickable::ticked() viewportMoved(); } -QDeclarativeItem *QDeclarativeFlickable::viewport() +/*! + \qmlproperty Item Flickable::contentItem + + The internal item that contains the Items to be moved in the Flickable. + + Items declared as children of a Flickable are automatically parented to the Flickable's contentItem. + + Items created dynamically need to be explicitly parented to the \e contentItem: + \code + Flickable { + id: myFlickable + function addItem(file) { + var component = Qt.createComponent(file) + component.createObject(myFlickable.contentItem); + } + } + \endcode +*/ +QDeclarativeItem *QDeclarativeFlickable::contentItem() { Q_D(QDeclarativeFlickable); - return d->viewport; + return d->contentItem; } QDeclarativeFlickableVisibleArea *QDeclarativeFlickable::visibleArea() @@ -899,12 +917,12 @@ void QDeclarativeFlickablePrivate::clearDelayedPress() void QDeclarativeFlickablePrivate::setRoundedViewportX(qreal x) { - viewport->setX(qRound(x)); + contentItem->setX(qRound(x)); } void QDeclarativeFlickablePrivate::setRoundedViewportY(qreal y) { - viewport->setY(qRound(y)); + contentItem->setY(qRound(y)); } void QDeclarativeFlickable::timerEvent(QTimerEvent *event) @@ -991,13 +1009,13 @@ void QDeclarativeFlickable::geometryChanged(const QRectF &newGeometry, bool changed = false; if (newGeometry.width() != oldGeometry.width()) { if (d->hData.viewSize < 0) { - d->viewport->setWidth(width()); + d->contentItem->setWidth(width()); emit contentWidthChanged(); } } if (newGeometry.height() != oldGeometry.height()) { if (d->vData.viewSize < 0) { - d->viewport->setHeight(height()); + d->contentItem->setHeight(height()); emit contentHeightChanged(); } } @@ -1018,7 +1036,7 @@ void QDeclarativeFlickablePrivate::data_append(QDeclarativeListProperty<QObject> { QDeclarativeItem *i = qobject_cast<QDeclarativeItem *>(o); if (i) - i->setParentItem(static_cast<QDeclarativeFlickablePrivate*>(prop->data)->viewport); + i->setParentItem(static_cast<QDeclarativeFlickablePrivate*>(prop->data)->contentItem); else o->setParent(prop->object); } @@ -1032,7 +1050,7 @@ QDeclarativeListProperty<QObject> QDeclarativeFlickable::flickableData() QDeclarativeListProperty<QGraphicsObject> QDeclarativeFlickable::flickableChildren() { Q_D(QDeclarativeFlickable); - return QGraphicsItemPrivate::get(d->viewport)->childrenList(); + return QGraphicsItemPrivate::get(d->contentItem)->childrenList(); } /*! @@ -1102,9 +1120,9 @@ void QDeclarativeFlickable::setContentWidth(qreal w) return; d->hData.viewSize = w; if (w < 0) - d->viewport->setWidth(width()); + d->contentItem->setWidth(width()); else - d->viewport->setWidth(w); + d->contentItem->setWidth(w); // Make sure that we're entirely in view. if (!d->pressed && !d->movingHorizontally && !d->movingVertically) { int oldDuration = d->fixupDuration; @@ -1129,9 +1147,9 @@ void QDeclarativeFlickable::setContentHeight(qreal h) return; d->vData.viewSize = h; if (h < 0) - d->viewport->setHeight(height()); + d->contentItem->setHeight(height()); else - d->viewport->setHeight(h); + d->contentItem->setHeight(h); // Make sure that we're entirely in view. if (!d->pressed && !d->movingHorizontally && !d->movingVertically) { int oldDuration = d->fixupDuration; diff --git a/src/declarative/graphicsitems/qdeclarativeflickable_p.h b/src/declarative/graphicsitems/qdeclarativeflickable_p.h index d40a0dc..eb738d9 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable_p.h +++ b/src/declarative/graphicsitems/qdeclarativeflickable_p.h @@ -60,6 +60,7 @@ class Q_DECLARATIVE_EXPORT QDeclarativeFlickable : public QDeclarativeItem Q_PROPERTY(qreal contentHeight READ contentHeight WRITE setContentHeight NOTIFY contentHeightChanged) Q_PROPERTY(qreal contentX READ contentX WRITE setContentX NOTIFY contentXChanged) Q_PROPERTY(qreal contentY READ contentY WRITE setContentY NOTIFY contentYChanged) + Q_PROPERTY(QDeclarativeItem *contentItem READ contentItem CONSTANT) Q_PROPERTY(qreal horizontalVelocity READ horizontalVelocity NOTIFY horizontalVelocityChanged) Q_PROPERTY(qreal verticalVelocity READ verticalVelocity NOTIFY verticalVelocityChanged) @@ -111,10 +112,10 @@ public: void setContentHeight(qreal); qreal contentX() const; - void setContentX(qreal pos); + virtual void setContentX(qreal pos); qreal contentY() const; - void setContentY(qreal pos); + virtual void setContentY(qreal pos); bool isMoving() const; bool isMovingHorizontally() const; @@ -143,7 +144,7 @@ public: bool isAtYEnd() const; bool isAtYBeginning() const; - QDeclarativeItem *viewport(); + QDeclarativeItem *contentItem(); enum FlickableDirection { AutoFlickDirection=0x00, HorizontalFlick=0x01, VerticalFlick=0x02, HorizontalAndVerticalFlick=0x03 }; FlickableDirection flickDirection() const; // deprecated diff --git a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h index 66d2678..b919e1b 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativeflickable_p_p.h @@ -125,7 +125,7 @@ public: void itemGeometryChanged(QDeclarativeItem *, const QRectF &, const QRectF &); public: - QDeclarativeItem *viewport; + QDeclarativeItem *contentItem; AxisData hData; AxisData vData; diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 3792595..dda1efb 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -151,9 +151,9 @@ public: void setPosition(qreal pos) { Q_Q(QDeclarativeGridView); if (flow == QDeclarativeGridView::LeftToRight) - q->setContentY(pos); + q->QDeclarativeFlickable::setContentY(pos); else - q->setContentX(pos); + q->QDeclarativeFlickable::setContentX(pos); } int size() const { Q_Q(const QDeclarativeGridView); @@ -421,10 +421,10 @@ FxGridItem *QDeclarativeGridViewPrivate::createItem(int modelIndex) if (model->completePending()) { // complete listItem->item->setZValue(1); - listItem->item->setParentItem(q->viewport()); + listItem->item->setParentItem(q->contentItem()); model->completeItem(); } else { - listItem->item->setParentItem(q->viewport()); + listItem->item->setParentItem(q->contentItem()); } unrequestedItems.remove(listItem->item); } @@ -716,12 +716,12 @@ void QDeclarativeGridViewPrivate::createHighlight() } } else { item = new QDeclarativeItem; - QDeclarative_setParent_noEvent(item, q->viewport()); - item->setParentItem(q->viewport()); + QDeclarative_setParent_noEvent(item, q->contentItem()); + item->setParentItem(q->contentItem()); } if (item) { - QDeclarative_setParent_noEvent(item, q->viewport()); - item->setParentItem(q->viewport()); + QDeclarative_setParent_noEvent(item, q->contentItem()); + item->setParentItem(q->contentItem()); highlight = new FxGridItem(item, q); highlightXAnimator = new QSmoothedAnimation(q); highlightXAnimator->target = QDeclarativeProperty(highlight->item, QLatin1String("x")); @@ -808,8 +808,8 @@ void QDeclarativeGridViewPrivate::updateFooter() delete context; } if (item) { - QDeclarative_setParent_noEvent(item, q->viewport()); - item->setParentItem(q->viewport()); + QDeclarative_setParent_noEvent(item, q->contentItem()); + item->setParentItem(q->contentItem()); item->setZValue(1); QDeclarativeItemPrivate *itemPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(item)); itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); @@ -854,8 +854,8 @@ void QDeclarativeGridViewPrivate::updateHeader() delete context; } if (item) { - QDeclarative_setParent_noEvent(item, q->viewport()); - item->setParentItem(q->viewport()); + QDeclarative_setParent_noEvent(item, q->contentItem()); + item->setParentItem(q->contentItem()); item->setZValue(1); QDeclarativeItemPrivate *itemPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(item)); itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); @@ -1742,6 +1742,22 @@ void QDeclarativeGridView::setHeader(QDeclarativeComponent *header) } } +void QDeclarativeGridView::setContentX(qreal pos) +{ + Q_D(QDeclarativeGridView); + // Positioning the view manually should override any current movement state + d->moveReason = QDeclarativeGridViewPrivate::Other; + QDeclarativeFlickable::setContentX(pos); +} + +void QDeclarativeGridView::setContentY(qreal pos) +{ + Q_D(QDeclarativeGridView); + // Positioning the view manually should override any current movement state + d->moveReason = QDeclarativeGridViewPrivate::Other; + QDeclarativeFlickable::setContentY(pos); +} + bool QDeclarativeGridView::event(QEvent *event) { Q_D(QDeclarativeGridView); @@ -1919,6 +1935,8 @@ void QDeclarativeGridView::keyPressEvent(QKeyEvent *event) Move the currentIndex up one item in the view. The current index will wrap if keyNavigationWraps is true and it is currently at the end. + + \bold Note: methods should only be called after the Component has completed. */ void QDeclarativeGridView::moveCurrentIndexUp() { @@ -1942,6 +1960,8 @@ void QDeclarativeGridView::moveCurrentIndexUp() Move the currentIndex down one item in the view. The current index will wrap if keyNavigationWraps is true and it is currently at the end. + + \bold Note: methods should only be called after the Component has completed. */ void QDeclarativeGridView::moveCurrentIndexDown() { @@ -1965,6 +1985,8 @@ void QDeclarativeGridView::moveCurrentIndexDown() Move the currentIndex left one item in the view. The current index will wrap if keyNavigationWraps is true and it is currently at the end. + + \bold Note: methods should only be called after the Component has completed. */ void QDeclarativeGridView::moveCurrentIndexLeft() { @@ -1988,6 +2010,8 @@ void QDeclarativeGridView::moveCurrentIndexLeft() Move the currentIndex right one item in the view. The current index will wrap if keyNavigationWraps is true and it is currently at the end. + + \bold Note: methods should only be called after the Component has completed. */ void QDeclarativeGridView::moveCurrentIndexRight() { @@ -2028,6 +2052,14 @@ void QDeclarativeGridView::moveCurrentIndexRight() at a particular index. This is unreliable since removing items from the start of the view does not cause all other items to be repositioned. The correct way to bring an item into view is with \c positionViewAtIndex. + + \bold Note: methods should only be called after the Component has completed. To position + the view at startup, this method should be called by Component.onCompleted. For + example, to position the view at the end: + + \code + Component.onCompleted: positionViewAtIndex(count - 1, GridView.Beginning) + \endcode */ void QDeclarativeGridView::positionViewAtIndex(int index, int mode) { @@ -2037,6 +2069,8 @@ void QDeclarativeGridView::positionViewAtIndex(int index, int mode) if (mode < Beginning || mode > Contain) return; + if (d->layoutScheduled) + d->layout(); qreal pos = d->position(); FxGridItem *item = d->visibleItem(index); if (!item) { @@ -2079,6 +2113,8 @@ void QDeclarativeGridView::positionViewAtIndex(int index, int mode) pos = qMin(pos, maxExtent); qreal minExtent = d->flow == QDeclarativeGridView::LeftToRight ? -minYExtent() : -minXExtent(); pos = qMax(pos, minExtent); + d->moveReason = QDeclarativeGridViewPrivate::Other; + cancelFlick(); d->setPosition(pos); } d->fixupPosition(); @@ -2093,6 +2129,8 @@ void QDeclarativeGridView::positionViewAtIndex(int index, int mode) If the item is outside the visible area, -1 is returned, regardless of whether an item will exist at that point when scrolled into view. + + \bold Note: methods should only be called after the Component has completed. */ int QDeclarativeGridView::indexAt(int x, int y) const { @@ -2113,10 +2151,16 @@ void QDeclarativeGridView::componentComplete() d->updateGrid(); if (d->isValid()) { refill(); + d->moveReason = QDeclarativeGridViewPrivate::SetIndex; if (d->currentIndex < 0) d->updateCurrent(0); else d->updateCurrent(d->currentIndex); + if (d->highlight) { + d->highlight->setPosition(d->currentItem->colPos(), d->currentItem->rowPos()); + d->updateTrackedItem(); + } + d->moveReason = QDeclarativeGridViewPrivate::Other; d->fixupPosition(); } } diff --git a/src/declarative/graphicsitems/qdeclarativegridview_p.h b/src/declarative/graphicsitems/qdeclarativegridview_p.h index 021aad9..64b91d8 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview_p.h +++ b/src/declarative/graphicsitems/qdeclarativegridview_p.h @@ -151,6 +151,9 @@ public: QDeclarativeComponent *header() const; void setHeader(QDeclarativeComponent *); + virtual void setContentX(qreal pos); + virtual void setContentY(qreal pos); + enum PositionMode { Beginning, Center, End, Visible, Contain }; Q_INVOKABLE void positionViewAtIndex(int index, int mode); diff --git a/src/declarative/graphicsitems/qdeclarativeimage.cpp b/src/declarative/graphicsitems/qdeclarativeimage.cpp index ec08517..ff61302 100644 --- a/src/declarative/graphicsitems/qdeclarativeimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeimage.cpp @@ -199,6 +199,7 @@ void QDeclarativeImagePrivate::setPixmap(const QPixmap &pixmap) fillMode: Image.PreserveAspectCrop smooth: true source: "qtlogo.png" + clip: true } \endqml @@ -220,6 +221,7 @@ void QDeclarativeImagePrivate::setPixmap(const QPixmap &pixmap) Image { width: 120; height: 120 fillMode: Image.TileVertically + smooth: true source: "qtlogo.png" } \endqml @@ -231,11 +233,14 @@ void QDeclarativeImagePrivate::setPixmap(const QPixmap &pixmap) Image { width: 120; height: 120 fillMode: Image.TileHorizontally + smooth: true source: "qtlogo.png" } \endqml \endtable + + \sa {declarative/imageelements/image}{Image example} */ QDeclarativeImage::FillMode QDeclarativeImage::fillMode() const { diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 06a3239..a69fc3f 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -105,7 +105,7 @@ public: else return (view->orientation() == QDeclarativeListView::Vertical ? item->y() : item->x()); } - int size() const { + qreal size() const { if (section) return (view->orientation() == QDeclarativeListView::Vertical ? item->height()+section->height() : item->width()+section->height()); else @@ -216,9 +216,9 @@ public: void setPosition(qreal pos) { Q_Q(QDeclarativeListView); if (orient == QDeclarativeListView::Vertical) - q->setContentY(pos); + q->QDeclarativeFlickable::setContentY(pos); else - q->setContentX(pos); + q->QDeclarativeFlickable::setContentX(pos); } qreal size() const { Q_Q(const QDeclarativeListView); @@ -421,7 +421,7 @@ public: void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) { Q_Q(QDeclarativeListView); QDeclarativeFlickablePrivate::itemGeometryChanged(item, newGeometry, oldGeometry); - if (item != viewport && (!highlight || item != highlight->item)) { + if (item != contentItem && (!highlight || item != highlight->item)) { if ((orient == QDeclarativeListView::Vertical && newGeometry.height() != oldGeometry.height()) || (orient == QDeclarativeListView::Horizontal && newGeometry.width() != oldGeometry.width())) { scheduleLayout(); @@ -476,7 +476,7 @@ public: QHash<QDeclarativeItem*,int> unrequestedItems; FxListItem *currentItem; QDeclarativeListView::Orientation orient; - int visiblePos; + qreal visiblePos; int visibleIndex; qreal averageSize; int currentIndex; @@ -580,10 +580,10 @@ FxListItem *QDeclarativeListViewPrivate::createItem(int modelIndex) if (model->completePending()) { // complete listItem->item->setZValue(1); - listItem->item->setParentItem(q->viewport()); + listItem->item->setParentItem(q->contentItem()); model->completeItem(); } else { - listItem->item->setParentItem(q->viewport()); + listItem->item->setParentItem(q->contentItem()); } QDeclarativeItemPrivate *itemPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(item)); itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); @@ -655,7 +655,7 @@ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer) bool changed = false; FxListItem *item = 0; - int pos = itemEnd + 1; + qreal pos = itemEnd + 1; while (modelIndex < model->count() && pos <= fillTo) { // qDebug() << "refill: append item" << modelIndex << "pos" << pos; if (!(item = createItem(modelIndex))) @@ -744,8 +744,8 @@ void QDeclarativeListViewPrivate::layout() } updateSections(); if (!visibleItems.isEmpty()) { - int oldEnd = visibleItems.last()->endPosition(); - int pos = visibleItems.first()->endPosition() + spacing + 1; + qreal oldEnd = visibleItems.last()->endPosition(); + qreal pos = visibleItems.first()->endPosition() + spacing + 1; for (int i=1; i < visibleItems.count(); ++i) { FxListItem *item = visibleItems.at(i); item->setPosition(pos); @@ -840,8 +840,8 @@ void QDeclarativeListViewPrivate::createHighlight() item = new QDeclarativeItem; } if (item) { - QDeclarative_setParent_noEvent(item, q->viewport()); - item->setParentItem(q->viewport()); + QDeclarative_setParent_noEvent(item, q->contentItem()); + item->setParentItem(q->contentItem()); highlight = new FxListItem(item, q); if (currentItem && autoHighlight) { if (orient == QDeclarativeListView::Vertical) { @@ -921,8 +921,8 @@ void QDeclarativeListViewPrivate::createSection(FxListItem *listItem) delete nobj; } else { listItem->section->setZValue(1); - QDeclarative_setParent_noEvent(listItem->section, q->viewport()); - listItem->section->setParentItem(q->viewport()); + QDeclarative_setParent_noEvent(listItem->section, q->contentItem()); + listItem->section->setParentItem(q->contentItem()); } } else { delete context; @@ -1027,7 +1027,7 @@ void QDeclarativeListViewPrivate::updateAverage() qreal sum = 0.0; for (int i = 0; i < visibleItems.count(); ++i) sum += visibleItems.at(i)->size(); - averageSize = sum / visibleItems.count(); + averageSize = qRound(sum / visibleItems.count()); } void QDeclarativeListViewPrivate::updateFooter() @@ -1046,8 +1046,8 @@ void QDeclarativeListViewPrivate::updateFooter() delete context; } if (item) { - QDeclarative_setParent_noEvent(item, q->viewport()); - item->setParentItem(q->viewport()); + QDeclarative_setParent_noEvent(item, q->contentItem()); + item->setParentItem(q->contentItem()); item->setZValue(1); QDeclarativeItemPrivate *itemPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(item)); itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); @@ -1086,8 +1086,8 @@ void QDeclarativeListViewPrivate::updateHeader() delete context; } if (item) { - QDeclarative_setParent_noEvent(item, q->viewport()); - item->setParentItem(q->viewport()); + QDeclarative_setParent_noEvent(item, q->contentItem()); + item->setParentItem(q->contentItem()); item->setZValue(1); QDeclarativeItemPrivate *itemPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(item)); itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); @@ -1547,9 +1547,12 @@ void QDeclarativeListView::setModel(const QVariant &model) that is not needed for the normal display of the delegate in a \l Loader which can load additional elements when needed. - Tthe ListView will lay out the items based on the size of the root item + The ListView will lay out the items based on the size of the root item in the delegate. + It is recommended that the delagate's size be a whole number to avoid sub-pixel + alignment of items. + \note Delegates are instantiated as needed and may be destroyed at any time. State should \e never be stored in a delegate. */ @@ -2182,6 +2185,22 @@ void QDeclarativeListView::setHeader(QDeclarativeComponent *header) } } +void QDeclarativeListView::setContentX(qreal pos) +{ + Q_D(QDeclarativeListView); + // Positioning the view manually should override any current movement state + d->moveReason = QDeclarativeListViewPrivate::Other; + QDeclarativeFlickable::setContentX(pos); +} + +void QDeclarativeListView::setContentY(qreal pos) +{ + Q_D(QDeclarativeListView); + // Positioning the view manually should override any current movement state + d->moveReason = QDeclarativeListViewPrivate::Other; + QDeclarativeFlickable::setContentY(pos); +} + bool QDeclarativeListView::event(QEvent *event) { Q_D(QDeclarativeListView); @@ -2386,6 +2405,8 @@ void QDeclarativeListView::keyPressEvent(QKeyEvent *event) Increments the current index. The current index will wrap if keyNavigationWraps is true and it is currently at the end. + + \bold Note: methods should only be called after the Component has completed. */ void QDeclarativeListView::incrementCurrentIndex() { @@ -2403,6 +2424,8 @@ void QDeclarativeListView::incrementCurrentIndex() Decrements the current index. The current index will wrap if keyNavigationWraps is true and it is currently at the beginning. + + \bold Note: methods should only be called after the Component has completed. */ void QDeclarativeListView::decrementCurrentIndex() { @@ -2439,6 +2462,14 @@ void QDeclarativeListView::decrementCurrentIndex() of the list does not cause all other items to be repositioned, and because the actual start of the view can vary based on the size of the delegates. The correct way to bring an item into view is with \c positionViewAtIndex. + + \bold Note: methods should only be called after the Component has completed. To position + the view at startup, this method should be called by Component.onCompleted. For + example, to position the view at the end: + + \code + Component.onCompleted: positionViewAtIndex(count - 1, ListView.Beginning) + \endcode */ void QDeclarativeListView::positionViewAtIndex(int index, int mode) { @@ -2448,6 +2479,8 @@ void QDeclarativeListView::positionViewAtIndex(int index, int mode) if (mode < Beginning || mode > Contain) return; + if (d->layoutScheduled) + d->layout(); qreal pos = d->position(); FxListItem *item = d->visibleItem(index); if (!item) { @@ -2491,6 +2524,8 @@ void QDeclarativeListView::positionViewAtIndex(int index, int mode) pos = qMin(pos, maxExtent); qreal minExtent = d->orient == QDeclarativeListView::Vertical ? -minYExtent() : -minXExtent(); pos = qMax(pos, minExtent); + d->moveReason = QDeclarativeListViewPrivate::Other; + cancelFlick(); d->setPosition(pos); } d->fixupPosition(); @@ -2505,6 +2540,8 @@ void QDeclarativeListView::positionViewAtIndex(int index, int mode) If the item is outside the visible area, -1 is returned, regardless of whether an item will exist at that point when scrolled into view. + + \bold Note: methods should only be called after the Component has completed. */ int QDeclarativeListView::indexAt(int x, int y) const { @@ -2529,6 +2566,11 @@ void QDeclarativeListView::componentComplete() d->updateCurrent(0); else d->updateCurrent(d->currentIndex); + if (d->highlight) { + d->highlight->setPosition(d->currentItem->position()); + d->updateTrackedItem(); + } + d->moveReason = QDeclarativeListViewPrivate::Other; d->fixupPosition(); } } @@ -2961,7 +3003,7 @@ void QDeclarativeListView::createdItem(int index, QDeclarativeItem *item) { Q_D(QDeclarativeListView); if (d->requestedIndex != index) { - item->setParentItem(viewport()); + item->setParentItem(contentItem()); d->unrequestedItems.insert(item, index); if (d->orient == QDeclarativeListView::Vertical) item->setY(d->positionAt(index)); diff --git a/src/declarative/graphicsitems/qdeclarativelistview_p.h b/src/declarative/graphicsitems/qdeclarativelistview_p.h index d6e8023..505f659 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview_p.h +++ b/src/declarative/graphicsitems/qdeclarativelistview_p.h @@ -198,6 +198,9 @@ public: QDeclarativeComponent *header() const; void setHeader(QDeclarativeComponent *); + virtual void setContentX(qreal pos); + virtual void setContentY(qreal pos); + static QDeclarativeListViewAttached *qmlAttachedProperties(QObject *); enum PositionMode { Beginning, Center, End, Visible, Contain }; diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp index 25b1119..c8c9e44 100644 --- a/src/declarative/graphicsitems/qdeclarativeloader.cpp +++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp @@ -174,7 +174,7 @@ void QDeclarativeLoaderPrivate::initResize() QDeclarativeLoader::QDeclarativeLoader(QDeclarativeItem *parent) : QDeclarativeItem(*(new QDeclarativeLoaderPrivate), parent) { - Q_D(QDeclarativeItem); + Q_D(QDeclarativeLoader); d->flags |= QGraphicsItem::ItemIsFocusScope; } @@ -183,6 +183,14 @@ QDeclarativeLoader::QDeclarativeLoader(QDeclarativeItem *parent) */ QDeclarativeLoader::~QDeclarativeLoader() { + Q_D(QDeclarativeLoader); + if (d->item) { + if (QDeclarativeItem *qmlItem = qobject_cast<QDeclarativeItem*>(d->item)) { + QDeclarativeItemPrivate *p = + static_cast<QDeclarativeItemPrivate *>(QGraphicsItemPrivate::get(qmlItem)); + p->removeItemChangeListener(d, QDeclarativeItemPrivate::Geometry); + } + } } /*! diff --git a/src/declarative/graphicsitems/qdeclarativepainteditem.cpp b/src/declarative/graphicsitems/qdeclarativepainteditem.cpp index 13d1b61..3b9b8df 100644 --- a/src/declarative/graphicsitems/qdeclarativepainteditem.cpp +++ b/src/declarative/graphicsitems/qdeclarativepainteditem.cpp @@ -151,6 +151,7 @@ void QDeclarativePaintedItem::setContentsSize(const QSize &size) { Q_D(QDeclarativePaintedItem); if (d->contentsSize == size) return; + prepareGeometryChange(); d->contentsSize = size; clearCache(); update(); @@ -247,8 +248,7 @@ QRectF QDeclarativePaintedItem::boundingRect() const void QDeclarativePaintedItem::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) { Q_D(QDeclarativePaintedItem); - const QRect content(0,0,qCeil(d->contentsSize.width()*d->contentsScale), - qCeil(d->contentsSize.height()*d->contentsScale)); + const QRect content = boundingRect().toRect(); if (content.width() <= 0 || content.height() <= 0) return; diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp index 0c2d249..0e980b3 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview.cpp +++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp @@ -552,6 +552,8 @@ void QDeclarativePathView::setCurrentIndex(int idx) \qmlmethod PathView::incrementCurrentIndex() Increments the current index. + + \bold Note: methods should only be called after the Component has completed. */ void QDeclarativePathView::incrementCurrentIndex() { @@ -563,6 +565,8 @@ void QDeclarativePathView::incrementCurrentIndex() \qmlmethod PathView::decrementCurrentIndex() Decrements the current index. + + \bold Note: methods should only be called after the Component has completed. */ void QDeclarativePathView::decrementCurrentIndex() { diff --git a/src/declarative/graphicsitems/qdeclarativepositioners.cpp b/src/declarative/graphicsitems/qdeclarativepositioners.cpp index b9231a1..179f13d 100644 --- a/src/declarative/graphicsitems/qdeclarativepositioners.cpp +++ b/src/declarative/graphicsitems/qdeclarativepositioners.cpp @@ -1027,13 +1027,13 @@ void QDeclarativeFlow::doPositioning(QSizeF *contentSize) continue; if (d->flow == LeftToRight) { - if (hoffset && hoffset + child.item->width() > width()) { + if (widthValid() && hoffset && hoffset + child.item->width() > width()) { hoffset = 0; voffset += linemax + spacing(); linemax = 0; } } else { - if (voffset && voffset + child.item->height() > height()) { + if (heightValid() && voffset && voffset + child.item->height() > height()) { voffset = 0; hoffset += linemax + spacing(); linemax = 0; diff --git a/src/declarative/graphicsitems/qdeclarativerectangle.cpp b/src/declarative/graphicsitems/qdeclarativerectangle.cpp index 2756877..c49be46 100644 --- a/src/declarative/graphicsitems/qdeclarativerectangle.cpp +++ b/src/declarative/graphicsitems/qdeclarativerectangle.cpp @@ -446,6 +446,7 @@ void QDeclarativeRectangle::drawRect(QPainter &p) p.setRenderHint(QPainter::Antialiasing); if (d->pen && d->pen->isValid()) { QPen pn(QColor(d->pen->color()), d->pen->width()); + pn.setJoinStyle(Qt::MiterJoin); p.setPen(pn); } else { p.setPen(Qt::NoPen); diff --git a/src/declarative/graphicsitems/qdeclarativetext.cpp b/src/declarative/graphicsitems/qdeclarativetext.cpp index c2e0d67..2ba680d 100644 --- a/src/declarative/graphicsitems/qdeclarativetext.cpp +++ b/src/declarative/graphicsitems/qdeclarativetext.cpp @@ -663,6 +663,71 @@ void QDeclarativeText::setElideMode(QDeclarativeText::TextElideMode mode) emit elideModeChanged(d->elideMode); } +QRectF QDeclarativeText::boundingRect() const +{ + Q_D(const QDeclarativeText); + + int w = width(); + int h = height(); + + int x = 0; + int y = 0; + + if (d->cache || d->style != Normal) { + switch (d->hAlign) { + case AlignLeft: + x = 0; + break; + case AlignRight: + x = w - d->imgCache.width(); + break; + case AlignHCenter: + x = (w - d->imgCache.width()) / 2; + break; + } + + switch (d->vAlign) { + case AlignTop: + y = 0; + break; + case AlignBottom: + y = h - d->imgCache.height(); + break; + case AlignVCenter: + y = (h - d->imgCache.height()) / 2; + break; + } + + return QRectF(x,y,d->imgCache.width(),d->imgCache.height()); + } else { + switch (d->hAlign) { + case AlignLeft: + x = 0; + break; + case AlignRight: + x = w - d->cachedLayoutSize.width(); + break; + case AlignHCenter: + x = (w - d->cachedLayoutSize.width()) / 2; + break; + } + + switch (d->vAlign) { + case AlignTop: + y = 0; + break; + case AlignBottom: + y = h - d->cachedLayoutSize.height(); + break; + case AlignVCenter: + y = (h - d->cachedLayoutSize.height()) / 2; + break; + } + + return QRectF(x,y,d->cachedLayoutSize.width(),d->cachedLayoutSize.height()); + } +} + void QDeclarativeText::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) { @@ -713,6 +778,7 @@ void QDeclarativeTextPrivate::updateLayout() } } + void QDeclarativeTextPrivate::updateSize() { Q_Q(QDeclarativeText); @@ -730,7 +796,10 @@ void QDeclarativeTextPrivate::updateSize() //setup instance of QTextLayout for all cases other than richtext if (!richText) { size = setupTextLayout(&layout); - cachedLayoutSize = size; + if (cachedLayoutSize != size) { + q->prepareGeometryChange(); + cachedLayoutSize = size; + } dy -= size.height(); } else { singleline = false; // richtext can't elide or be optimized for single-line case @@ -744,7 +813,13 @@ void QDeclarativeTextPrivate::updateSize() else doc->setTextWidth(doc->idealWidth()); // ### Text does not align if width is not set (QTextDoc bug) dy -= (int)doc->size().height(); - cachedLayoutSize = doc->size().toSize(); + q->prepareGeometryChange(); + QSize dsize = doc->size().toSize(); + if (dsize != cachedLayoutSize) { + q->prepareGeometryChange(); + cachedLayoutSize = dsize; + } + size = QSize(int(doc->idealWidth()),dsize.height()); } int yoff = 0; @@ -757,8 +832,8 @@ void QDeclarativeTextPrivate::updateSize() q->setBaselineOffset(fm.ascent() + yoff); //### need to comfirm cost of always setting these for richText - q->setImplicitWidth(richText ? (int)doc->idealWidth() : size.width()); - q->setImplicitHeight(richText ? (int)doc->size().height() : size.height()); + q->setImplicitWidth(size.width()); + q->setImplicitHeight(size.height()); emit q->paintedSizeChanged(); } else { dirty = true; @@ -813,6 +888,8 @@ void QDeclarativeTextPrivate::drawOutline() ppm.drawPixmap(pos, imgCache); ppm.end(); + if (imgCache.size() != img.size()) + q_func()->prepareGeometryChange(); imgCache = img; } @@ -831,6 +908,8 @@ void QDeclarativeTextPrivate::drawOutline(int yOffset) ppm.drawPixmap(pos, imgCache); ppm.end(); + if (imgCache.size() != img.size()) + q_func()->prepareGeometryChange(); imgCache = img; } @@ -955,18 +1034,21 @@ void QDeclarativeTextPrivate::checkImgCache() return; bool empty = text.isEmpty(); + QPixmap newImgCache; if (empty) { - imgCache = QPixmap(); imgStyleCache = QPixmap(); } else if (richText) { - imgCache = richTextImage(false); + newImgCache = richTextImage(false); if (style != QDeclarativeText::Normal) imgStyleCache = richTextImage(true); //### should use styleColor } else { - imgCache = wrappedTextImage(false); + newImgCache = wrappedTextImage(false); if (style != QDeclarativeText::Normal) imgStyleCache = wrappedTextImage(true); //### should use styleColor } + if (imgCache.size() != newImgCache.size()) + q_func()->prepareGeometryChange(); + imgCache = newImgCache; if (!empty) switch (style) { case QDeclarativeText::Outline: @@ -1031,35 +1113,7 @@ void QDeclarativeText::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWid if (d->smooth) p->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, d->smooth); - int w = width(); - int h = height(); - - int x = 0; - int y = 0; - - switch (d->hAlign) { - case AlignLeft: - x = 0; - break; - case AlignRight: - x = w - d->imgCache.width(); - break; - case AlignHCenter: - x = (w - d->imgCache.width()) / 2; - break; - } - - switch (d->vAlign) { - case AlignTop: - y = 0; - break; - case AlignBottom: - y = h - d->imgCache.height(); - break; - case AlignVCenter: - y = (h - d->imgCache.height()) / 2; - break; - } + QRect br = boundingRect().toRect(); bool needClip = clip() && (d->imgCache.width() > width() || d->imgCache.height() > height()); @@ -1068,7 +1122,7 @@ void QDeclarativeText::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWid p->save(); p->setClipRect(boundingRect(), Qt::IntersectClip); } - p->drawPixmap(x, y, d->imgCache); + p->drawPixmap(br.x(), br.y(), d->imgCache); if (needClip) p->restore(); @@ -1077,20 +1131,8 @@ void QDeclarativeText::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWid p->setRenderHint(QPainter::SmoothPixmapTransform, oldSmooth); } } else { - int h = height(); - int y = 0; + qreal y = boundingRect().y(); - switch (d->vAlign) { - case AlignTop: - y = 0; - break; - case AlignBottom: - y = h - d->cachedLayoutSize.height(); - break; - case AlignVCenter: - y = (h - d->cachedLayoutSize.height()) / 2; - break; - } bool needClip = !clip() && (d->cachedLayoutSize.width() > width() || d->cachedLayoutSize.height() > height()); diff --git a/src/declarative/graphicsitems/qdeclarativetext_p.h b/src/declarative/graphicsitems/qdeclarativetext_p.h index db21140..cd97df3 100644 --- a/src/declarative/graphicsitems/qdeclarativetext_p.h +++ b/src/declarative/graphicsitems/qdeclarativetext_p.h @@ -143,6 +143,8 @@ public: qreal paintedWidth() const; qreal paintedHeight() const; + QRectF boundingRect() const; + Q_SIGNALS: void textChanged(const QString &text); void linkActivated(const QString &link); diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp index 3106daf..bafa10c 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp @@ -1231,8 +1231,13 @@ void QDeclarativeTextEdit::updateImgCache(const QRectF &rf) r = QRect(0,0,INT_MAX,INT_MAX); } else { r = rf.toRect(); - if (r != QRect(0,0,INT_MAX,INT_MAX)) // Don't translate "everything" + if (r.height() > INT_MAX/2) { + // Take care of overflow when translating "everything" + r.setTop(r.y() + d->yoff); + r.setBottom(INT_MAX/2); + } else { r = r.translated(0,d->yoff); + } } dirtyCache(r); emit update(); @@ -1284,6 +1289,7 @@ void QDeclarativeTextEditPrivate::init() void QDeclarativeTextEdit::q_textChanged() { updateSize(); + updateMicroFocus(); emit textChanged(text()); } @@ -1325,8 +1331,17 @@ void QDeclarativeTextEdit::updateSelectionMarkers() d->lastSelectionEnd = d->control->textCursor().selectionEnd(); emit selectionEndChanged(); } + updateMicroFocus(); +} + +QRectF QDeclarativeTextEdit::boundingRect() const +{ + Q_D(const QDeclarativeTextEdit); + QRectF r = QDeclarativePaintedItem::boundingRect(); + return r.translated(0,d->yoff); } + //### we should perhaps be a bit smarter here -- depending on what has changed, we shouldn't // need to do all the calculations each time void QDeclarativeTextEdit::updateSize() @@ -1341,13 +1356,20 @@ void QDeclarativeTextEdit::updateSize() d->document->setTextWidth(width()); dy -= (int)d->document->size().height(); + int nyoff; if (heightValid()) { if (d->vAlign == AlignBottom) - d->yoff = dy; + nyoff = dy; else if (d->vAlign == AlignVCenter) - d->yoff = dy/2; + nyoff = dy/2; + else + nyoff = 0; } else { - d->yoff = 0; + nyoff = 0; + } + if (nyoff != d->yoff) { + prepareGeometryChange(); + d->yoff = nyoff; } setBaselineOffset(fm.ascent() + d->yoff + d->textMargin); diff --git a/src/declarative/graphicsitems/qdeclarativetextedit_p.h b/src/declarative/graphicsitems/qdeclarativetextedit_p.h index d08f607..a6dd4a4 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextedit_p.h @@ -195,6 +195,8 @@ public: Q_INVOKABLE int positionAt(int x, int y) const; Q_INVOKABLE void moveCursorSelection(int pos); + QRectF boundingRect() const; + Q_SIGNALS: void textChanged(const QString &); void paintedSizeChanged(); diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index ec14c78..ef40f98 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -1398,18 +1398,11 @@ void QDeclarativeTextInputPrivate::init() q->connect(control, SIGNAL(selectionChanged()), q, SLOT(selectionChanged())); q->connect(control, SIGNAL(textChanged(const QString &)), - q, SIGNAL(displayTextChanged(const QString &))); - q->connect(control, SIGNAL(textChanged(const QString &)), q, SLOT(q_textChanged())); q->connect(control, SIGNAL(accepted()), q, SIGNAL(accepted())); q->connect(control, SIGNAL(updateNeeded(QRect)), q, SLOT(updateRect(QRect))); - q->connect(control, SIGNAL(cursorPositionChanged(int,int)), - q, SLOT(updateRect()));//TODO: Only update rect between pos's - q->connect(control, SIGNAL(selectionChanged()), - q, SLOT(updateRect()));//TODO: Only update rect in selection - //Note that above TODOs probably aren't that big a savings q->updateSize(); oldValidity = control->hasAcceptableInput(); lastSelectionStart = 0; @@ -1422,6 +1415,8 @@ void QDeclarativeTextInputPrivate::init() void QDeclarativeTextInput::cursorPosChanged() { Q_D(QDeclarativeTextInput); + updateRect();//TODO: Only update rect between pos's + updateMicroFocus(); emit cursorPositionChanged(); if(!d->control->hasSelectedText()){ @@ -1439,6 +1434,7 @@ void QDeclarativeTextInput::cursorPosChanged() void QDeclarativeTextInput::selectionChanged() { Q_D(QDeclarativeTextInput); + updateRect();//TODO: Only update rect in selection emit selectedTextChanged(); if(d->lastSelectionStart != d->control->selectionStart()){ @@ -1460,7 +1456,9 @@ void QDeclarativeTextInput::q_textChanged() Q_D(QDeclarativeTextInput); d->updateHorizontalScroll(); updateSize(); + updateMicroFocus(); emit textChanged(); + emit displayTextChanged(); if(hasAcceptableInput() != d->oldValidity){ d->oldValidity = hasAcceptableInput(); emit acceptableInputChanged(); diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p.h index 6934da4..52dd57d 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextinput_p.h @@ -208,7 +208,7 @@ Q_SIGNALS: void inputMaskChanged(const QString &inputMask); void echoModeChanged(EchoMode echoMode); void passwordCharacterChanged(); - void displayTextChanged(const QString &text); + void displayTextChanged(); void focusOnPressChanged(bool focusOnPress); void autoScrollChanged(bool autoScroll); void selectByMouseChanged(bool selectByMouse); diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp index 5092349..8071d7a 100644 --- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp +++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp @@ -283,7 +283,7 @@ public: if (m_roles.count() == 1) m_roleNames.insert("modelData", m_roles.at(0)); if (m_roles.count()) - m_roleNames.insert("hasModelChildren", 0); + m_roleNames.insert("hasModelChildren", -1); } else if (m_listAccessor) { m_roleNames.insert("modelData", 0); if (m_listAccessor->type() == QDeclarativeListAccessor::Instance) { diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 80a1093..623e3df 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -815,6 +815,10 @@ bool QDeclarativeCompiler::buildObject(Object *obj, const BindingContext &ctxt) } } + QDeclarativeCustomParser *cp = 0; + if (isCustomParser) + cp = output->types.at(obj->type).type->customParser(); + // Build all explicit properties specified foreach(Property *prop, obj->properties) { @@ -825,7 +829,9 @@ bool QDeclarativeCompiler::buildObject(Object *obj, const BindingContext &ctxt) bool canDefer = false; if (isCustomParser) { - if (doesPropertyExist(prop, obj)) { + if (doesPropertyExist(prop, obj) && + (!(cp->flags() & QDeclarativeCustomParser::AcceptsAttachedProperties) || + !isAttachedPropertyName(prop->name))) { int ids = compileState.ids.count(); COMPILE_CHECK(buildProperty(prop, obj, objCtxt)); canDefer = ids == compileState.ids.count(); @@ -876,8 +882,7 @@ bool QDeclarativeCompiler::buildObject(Object *obj, const BindingContext &ctxt) defaultProperty->release(); // Compile custom parser parts - if (isCustomParser/* && !customProps.isEmpty()*/) { - QDeclarativeCustomParser *cp = output->types.at(obj->type).type->customParser(); + if (isCustomParser && !customProps.isEmpty()) { cp->clearErrors(); cp->compiler = this; cp->object = obj; @@ -1356,7 +1361,7 @@ bool QDeclarativeCompiler::buildSignal(QDeclarativeParser::Property *prop, QDecl Returns true if (value) property \a prop exists on obj, false otherwise. */ bool QDeclarativeCompiler::doesPropertyExist(QDeclarativeParser::Property *prop, - QDeclarativeParser::Object *obj) + QDeclarativeParser::Object *obj) { if(isAttachedPropertyName(prop->name) || prop->name == "id") return true; @@ -2176,6 +2181,18 @@ int QDeclarativeCompiler::evaluateEnum(const QByteArray& script) const return -1; } +const QMetaObject *QDeclarativeCompiler::resolveType(const QByteArray& name) const +{ + QDeclarativeType *qmltype = 0; + if (!enginePrivate->importDatabase.resolveType(unit->imports, name, &qmltype, + 0, 0, 0, 0)) + return 0; + if (!qmltype) + return 0; + return qmltype->metaObject(); +} + + // Ensures that the dynamic meta specification on obj is valid bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj) { @@ -2199,6 +2216,10 @@ bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj) if (QString::fromUtf8(prop.name).at(0).isUpper()) COMPILE_EXCEPTION(&prop, tr("Property names cannot begin with an upper case letter")); + + if (QDeclarativeEnginePrivate::get(engine)->globalClass->illegalNames().contains(prop.name)) + COMPILE_EXCEPTION(&prop, tr("Illegal property name")); + propNames.insert(prop.name); } @@ -2208,6 +2229,8 @@ bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj) COMPILE_EXCEPTION(obj, tr("Duplicate signal name")); if (QString::fromUtf8(name).at(0).isUpper()) COMPILE_EXCEPTION(obj, tr("Signal names cannot begin with an upper case letter")); + if (QDeclarativeEnginePrivate::get(engine)->globalClass->illegalNames().contains(name)) + COMPILE_EXCEPTION(obj, tr("Illegal signal name")); methodNames.insert(name); } for (int ii = 0; ii < obj->dynamicSlots.count(); ++ii) { @@ -2216,6 +2239,8 @@ bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj) COMPILE_EXCEPTION(obj, tr("Duplicate method name")); if (QString::fromUtf8(name).at(0).isUpper()) COMPILE_EXCEPTION(obj, tr("Method names cannot begin with an upper case letter")); + if (QDeclarativeEnginePrivate::get(engine)->globalClass->illegalNames().contains(name)) + COMPILE_EXCEPTION(obj, tr("Illegal method name")); methodNames.insert(name); } diff --git a/src/declarative/qml/qdeclarativecompiler_p.h b/src/declarative/qml/qdeclarativecompiler_p.h index 908c703..caad376 100644 --- a/src/declarative/qml/qdeclarativecompiler_p.h +++ b/src/declarative/qml/qdeclarativecompiler_p.h @@ -161,6 +161,7 @@ public: static bool isSignalPropertyName(const QByteArray &); int evaluateEnum(const QByteArray& script) const; // for QDeclarativeCustomParser::evaluateEnum + const QMetaObject *resolveType(const QByteArray& name) const; // for QDeclarativeCustomParser::resolveType private: static void reset(QDeclarativeCompiledData *); diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index b4919ff..9d3032c 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -572,7 +572,9 @@ QScriptValue QDeclarativeComponent::createObject(QObject* parent) { Q_D(QDeclarativeComponent); QDeclarativeContext* ctxt = creationContext(); - if(!ctxt) + if(!ctxt && d->engine) + ctxt = d->engine->rootContext(); + if (!ctxt) return QScriptValue(QScriptValue::NullValue); QObject* ret = create(ctxt); if (!ret) diff --git a/src/declarative/qml/qdeclarativecustomparser.cpp b/src/declarative/qml/qdeclarativecustomparser.cpp index 472a883..97a6a00 100644 --- a/src/declarative/qml/qdeclarativecustomparser.cpp +++ b/src/declarative/qml/qdeclarativecustomparser.cpp @@ -295,4 +295,14 @@ int QDeclarativeCustomParser::evaluateEnum(const QByteArray& script) const return compiler->evaluateEnum(script); } +/*! + Resolves \a name to a type, or 0 if it is not a type. This can be used + to type-check object nodes. +*/ +const QMetaObject *QDeclarativeCustomParser::resolveType(const QByteArray& name) const +{ + return compiler->resolveType(name); +} + + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativecustomparser_p.h b/src/declarative/qml/qdeclarativecustomparser_p.h index 0e397c5..509e30a 100644 --- a/src/declarative/qml/qdeclarativecustomparser_p.h +++ b/src/declarative/qml/qdeclarativecustomparser_p.h @@ -113,10 +113,18 @@ private: class Q_DECLARATIVE_EXPORT QDeclarativeCustomParser { public: - QDeclarativeCustomParser() : compiler(0), object(0) {} + enum Flag { + NoFlag = 0x00000000, + AcceptsAttachedProperties = 0x00000001 + }; + Q_DECLARE_FLAGS(Flags, Flag); + + QDeclarativeCustomParser() : compiler(0), object(0), m_flags(NoFlag) {} + QDeclarativeCustomParser(Flags f) : compiler(0), object(0), m_flags(f) {} virtual ~QDeclarativeCustomParser() {} void clearErrors(); + Flags flags() const { return m_flags; } virtual QByteArray compile(const QList<QDeclarativeCustomParserProperty> &)=0; virtual void setCustomData(QObject *, const QByteArray &)=0; @@ -130,12 +138,16 @@ protected: int evaluateEnum(const QByteArray&) const; + const QMetaObject *resolveType(const QByteArray&) const; + private: QList<QDeclarativeError> exceptions; QDeclarativeCompiler *compiler; QDeclarativeParser::Object *object; + Flags m_flags; friend class QDeclarativeCompiler; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeCustomParser::Flags); #if 0 #define QML_REGISTER_CUSTOM_TYPE(URI, VERSION_MAJ, VERSION_MIN, NAME, TYPE, CUSTOMTYPE) \ diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 86053c4..8b15ae9 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -1033,6 +1033,17 @@ QDeclarativeContextData *QDeclarativeEnginePrivate::getContext(QScriptContext *c return contextClass->contextFromValue(scopeNode); } +/*! + Returns the QUrl associated with the script \a ctxt for the case that there is + no QDeclarativeContext. +*/ +QUrl QDeclarativeEnginePrivate::getUrl(QScriptContext *ctxt) +{ + QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(ctxt, -3); + Q_ASSERT(scopeNode.isValid()); + Q_ASSERT(QScriptDeclarativeClass::scriptClass(scopeNode) == contextClass); + return contextClass->urlFromValue(scopeNode); +} QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QUrl& url) { @@ -1075,16 +1086,19 @@ QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, QS static_cast<QDeclarativeScriptEngine*>(engine)->p; QDeclarativeEngine* activeEngine = activeEnginePriv->q_func(); - QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt); - Q_ASSERT(context); - if(ctxt->argumentCount() != 1) { return ctxt->throwError(QLatin1String("Qt.createComponent(): Invalid arguments")); - }else{ + } else { + QString arg = ctxt->argument(0).toString(); if (arg.isEmpty()) return engine->nullValue(); - QUrl url = QUrl(context->resolvedUrl(QUrl(arg))); + QUrl url; + QDeclarativeContextData* context = activeEnginePriv->getContext(ctxt); + if (context) + url = QUrl(context->resolvedUrl(QUrl(arg))); + else + url = activeEnginePriv->getUrl(ctxt).resolved(QUrl(arg)); QDeclarativeComponent *c = new QDeclarativeComponent(activeEngine, url, activeEngine); QDeclarativeComponentPrivate::get(c)->creationContext = context; QDeclarativeData::get(c, true)->setImplicitDestructible(); diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h index 3269e98..cfa9d73 100644 --- a/src/declarative/qml/qdeclarativeengine_p.h +++ b/src/declarative/qml/qdeclarativeengine_p.h @@ -315,6 +315,7 @@ public: static QDeclarativeEnginePrivate *get(QScriptEngine *e) { return static_cast<QDeclarativeScriptEngine*>(e)->p; } static QDeclarativeEngine *get(QDeclarativeEnginePrivate *p) { return p->q_func(); } QDeclarativeContextData *getContext(QScriptContext *); + QUrl getUrl(QScriptContext *); static QString urlToLocalFileOrQrc(const QUrl& url); diff --git a/src/declarative/qml/qdeclarativeglobalscriptclass.cpp b/src/declarative/qml/qdeclarativeglobalscriptclass.cpp index 39ea101..d43443d 100644 --- a/src/declarative/qml/qdeclarativeglobalscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeglobalscriptclass.cpp @@ -41,6 +41,7 @@ #include "private/qdeclarativeglobalscriptclass_p.h" +#include <QtCore/qstringlist.h> #include <QtCore/qvector.h> #include <QtScript/qscriptstring.h> #include <QtScript/qscriptengine.h> @@ -57,6 +58,7 @@ QDeclarativeGlobalScriptClass::QDeclarativeGlobalScriptClass(QScriptEngine *engi : QScriptClass(engine) { QString eval = QLatin1String("eval"); + QString version = QLatin1String("version"); QScriptValue originalGlobalObject = engine->globalObject(); @@ -72,6 +74,9 @@ QDeclarativeGlobalScriptClass::QDeclarativeGlobalScriptClass(QScriptEngine *engi QString name = iter.name(); + if (name == version) + continue; + if (name != eval) { names.append(name); values.append(iter.value()); @@ -98,18 +103,7 @@ QDeclarativeGlobalScriptClass::queryProperty(const QScriptValue &object, Q_UNUSED(name); Q_UNUSED(flags); Q_UNUSED(id); - return HandlesReadAccess | HandlesWriteAccess; -} - -QScriptValue -QDeclarativeGlobalScriptClass::property(const QScriptValue &object, - const QScriptString &name, - uint id) -{ - Q_UNUSED(object); - Q_UNUSED(name); - Q_UNUSED(id); - return engine()->undefinedValue(); + return HandlesWriteAccess; } void QDeclarativeGlobalScriptClass::setProperty(QScriptValue &object, @@ -125,8 +119,9 @@ void QDeclarativeGlobalScriptClass::setProperty(QScriptValue &object, } /* This method is for the use of tst_qdeclarativeecmascript::callQtInvokables() only */ -void QDeclarativeGlobalScriptClass::explicitSetProperty(const QString &name, const QScriptValue &value) +void QDeclarativeGlobalScriptClass::explicitSetProperty(const QStringList &names, const QList<QScriptValue> &values) { + Q_ASSERT(names.count() == values.count()); QScriptValue globalObject = engine()->globalObject(); QScriptValue v = engine()->newObject(); @@ -137,7 +132,12 @@ void QDeclarativeGlobalScriptClass::explicitSetProperty(const QString &name, con v.setProperty(iter.scriptName(), iter.value()); } - v.setProperty(name, value); + for (int ii = 0; ii < names.count(); ++ii) { + const QString &name = names.at(ii); + const QScriptValue &value = values.at(ii); + v.setProperty(name, value); + } + v.setScriptClass(this); engine()->setGlobalObject(v); diff --git a/src/declarative/qml/qdeclarativeglobalscriptclass_p.h b/src/declarative/qml/qdeclarativeglobalscriptclass_p.h index 414bf02..b42b7bd 100644 --- a/src/declarative/qml/qdeclarativeglobalscriptclass_p.h +++ b/src/declarative/qml/qdeclarativeglobalscriptclass_p.h @@ -67,13 +67,10 @@ public: const QScriptString &name, QueryFlags flags, uint *id); - virtual QScriptValue property(const QScriptValue &object, - const QScriptString &name, uint id); - virtual void setProperty(QScriptValue &object, const QScriptString &name, uint id, const QScriptValue &value); - void explicitSetProperty(const QString &, const QScriptValue &); + void explicitSetProperty(const QStringList &, const QList<QScriptValue> &); const QScriptValue &staticGlobalObject() const { return m_staticGlobalObject; } diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index aca01b2..3af892d 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -797,6 +797,26 @@ QScriptDeclarativeClass::Value MetaCallArgument::toValue(QDeclarativeEngine *e) } } +int QDeclarativeObjectMethodScriptClass::enumType(const QMetaObject *meta, const QString &strname) +{ + QByteArray str = strname.toUtf8(); + QByteArray scope; + QByteArray name; + int scopeIdx = str.lastIndexOf("::"); + if (scopeIdx != -1) { + scope = str.left(scopeIdx); + name = str.mid(scopeIdx + 2); + } else { + name = str; + } + for (int i = meta->enumeratorCount() - 1; i >= 0; --i) { + QMetaEnum m = meta->enumerator(i); + if ((m.name() == name) && (scope.isEmpty() || (m.scope() == scope))) + return QVariant::Int; + } + return QVariant::Invalid; +} + QDeclarativeObjectMethodScriptClass::Value QDeclarativeObjectMethodScriptClass::call(Object *o, QScriptContext *ctxt) { MethodData *method = static_cast<MethodData *>(o); @@ -810,7 +830,9 @@ QDeclarativeObjectMethodScriptClass::Value QDeclarativeObjectMethodScriptClass:: // ### Cache for (int ii = 0; ii < argTypeNames.count(); ++ii) { argTypes[ii] = QMetaType::type(argTypeNames.at(ii)); - if (argTypes[ii] == QVariant::Invalid) + if (argTypes[ii] == QVariant::Invalid) + argTypes[ii] = enumType(method->object->metaObject(), argTypeNames.at(ii)); + if (argTypes[ii] == QVariant::Invalid) return Value(ctxt, ctxt->throwError(QString::fromLatin1("Unknown method parameter type: %1").arg(QLatin1String(argTypeNames.at(ii))))); } diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass_p.h b/src/declarative/qml/qdeclarativeobjectscriptclass_p.h index 4b27e53..75e384c 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass_p.h +++ b/src/declarative/qml/qdeclarativeobjectscriptclass_p.h @@ -80,6 +80,8 @@ protected: virtual Value property(Object *, const Identifier &); private: + int enumType(const QMetaObject *, const QString &); + PersistentIdentifier m_connectId; PersistentIdentifier m_disconnectId; QScriptValue m_connect; diff --git a/src/declarative/qml/qdeclarativetypenamescriptclass.cpp b/src/declarative/qml/qdeclarativetypenamescriptclass.cpp index 2a3417a..764a8db 100644 --- a/src/declarative/qml/qdeclarativetypenamescriptclass.cpp +++ b/src/declarative/qml/qdeclarativetypenamescriptclass.cpp @@ -107,8 +107,7 @@ QDeclarativeTypeNameScriptClass::queryProperty(Object *obj, const Identifier &na return 0; } - } else { - Q_ASSERT(data->type); + } else if (data->type) { QString strName = toString(name); @@ -134,6 +133,7 @@ QDeclarativeTypeNameScriptClass::queryProperty(Object *obj, const Identifier &na if (!object) return 0; return ep->objectClass->queryProperty(object, name, flags, 0); } + } return 0; diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index f807866..add27f3 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -176,6 +176,8 @@ void QDeclarativeAbstractAnimation::setRunning(bool r) { Q_D(QDeclarativeAbstractAnimation); if (!d->componentComplete) { + if (d->running && r == d->running) //don't re-register + return; d->running = r; if (r == false) d->avoidPropertyValueSourceStart = true; diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp index 9ed21a6..deb835d 100644 --- a/src/declarative/util/qdeclarativelistmodel.cpp +++ b/src/declarative/util/qdeclarativelistmodel.cpp @@ -551,9 +551,13 @@ bool QDeclarativeListModelParser::compileProperty(const QDeclarativeCustomParser QDeclarativeCustomParserNode node = qvariant_cast<QDeclarativeCustomParserNode>(value); - if (node.name() != "ListElement") { - error(node, QDeclarativeListModel::tr("ListElement: cannot contain nested elements")); - return false; + if (node.name() != listElementTypeName) { + const QMetaObject *mo = resolveType(node.name()); + if (mo != &QDeclarativeListElement::staticMetaObject) { + error(node, QDeclarativeListModel::tr("ListElement: cannot contain nested elements")); + return false; + } + listElementTypeName = node.name(); // cache right name for next time } { @@ -650,6 +654,7 @@ QByteArray QDeclarativeListModelParser::compile(const QList<QDeclarativeCustomPa { QList<ListInstruction> instr; QByteArray data; + listElementTypeName = QByteArray(); // unknown for(int ii = 0; ii < customProps.count(); ++ii) { const QDeclarativeCustomParserProperty &prop = customProps.at(ii); diff --git a/src/declarative/util/qdeclarativelistmodel_p.h b/src/declarative/util/qdeclarativelistmodel_p.h index d09062e..6aff9c6 100644 --- a/src/declarative/util/qdeclarativelistmodel_p.h +++ b/src/declarative/util/qdeclarativelistmodel_p.h @@ -135,6 +135,8 @@ private: bool compileProperty(const QDeclarativeCustomParserProperty &prop, QList<ListInstruction> &instr, QByteArray &data); bool definesEmptyList(const QString &); + + QByteArray listElementTypeName; }; diff --git a/src/declarative/util/qdeclarativepixmapcache.cpp b/src/declarative/util/qdeclarativepixmapcache.cpp index a4ddf46..0a14462 100644 --- a/src/declarative/util/qdeclarativepixmapcache.cpp +++ b/src/declarative/util/qdeclarativepixmapcache.cpp @@ -510,6 +510,12 @@ bool QDeclarativePixmapReply::event(QEvent *event) else d->errorString = de->errorString; QByteArray key = d->url.toEncoded(QUrl::FormattingOption(0x100)); + if (d->forced_width > 0 || d->forced_height > 0) { + key += ':'; + key += QByteArray::number(d->forced_width); + key += 'x'; + key += QByteArray::number(d->forced_height); + } QString strKey = QString::fromLatin1(key.constData(), key.count()); QPixmapCache::insert(strKey, d->pixmap); // note: may fail (returns false) emit finished(); diff --git a/src/declarative/util/qdeclarativepropertychanges_p.h b/src/declarative/util/qdeclarativepropertychanges_p.h index c2ed466..bb0f944 100644 --- a/src/declarative/util/qdeclarativepropertychanges_p.h +++ b/src/declarative/util/qdeclarativepropertychanges_p.h @@ -79,6 +79,9 @@ public: class QDeclarativePropertyChangesParser : public QDeclarativeCustomParser { public: + QDeclarativePropertyChangesParser() + : QDeclarativeCustomParser(AcceptsAttachedProperties) {} + void compileList(QList<QPair<QByteArray, QVariant> > &list, const QByteArray &pre, const QDeclarativeCustomParserProperty &prop); virtual QByteArray compile(const QList<QDeclarativeCustomParserProperty> &); diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 2de3638..8a419b4 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -7312,10 +7312,13 @@ void QGraphicsItem::updateMicroFocus() { #if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)) if (QWidget *fw = QApplication::focusWidget()) { - for (int i = 0 ; i < scene()->views().count() ; ++i) - if (scene()->views().at(i) == fw) - if (QInputContext *inputContext = fw->inputContext()) - inputContext->update(); + if (scene()) { + for (int i = 0 ; i < scene()->views().count() ; ++i) { + if (scene()->views().at(i) == fw) + if (QInputContext *inputContext = fw->inputContext()) + inputContext->update(); + } + } #ifndef QT_NO_ACCESSIBILITY // ##### is this correct QAccessible::updateAccessibility(fw, 0, QAccessible::StateChanged); |