diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2010-06-10 07:21:59 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2010-06-10 07:21:59 (GMT) |
commit | cc3ab4e2aabf719656398d16bd40a1edf70c169f (patch) | |
tree | e2de8b7b1fa7eed9a467b2a10807c1aaac9e371a /src | |
parent | 2e69bd4457c8cbe8b54af237451ba33b2a73a89b (diff) | |
parent | 7f06f14d01547ca115bc7d06c04bbaf924148910 (diff) | |
download | Qt-cc3ab4e2aabf719656398d16bd40a1edf70c169f.zip Qt-cc3ab4e2aabf719656398d16bd40a1edf70c169f.tar.gz Qt-cc3ab4e2aabf719656398d16bd40a1edf70c169f.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: (42 commits)
Update on color change.
Update on color change.
Add go button to webbrowser example.
Remove 'XXX Experimental' from VisualItemModel/VisualDataModel and
Document attached properties
Add 'on' prefix to documentation of signals
Stablize qmlviewer test
Improve test stability.
qmlviewer: ensure that only clicks on the current file list are handled.
Doc improvements: move some example code to snippets, add screenshots,
Move some example code into snippets/ and add other doc fixes
Fix crash when changing ListView model with highlightRangeMode: ListView.StrictlyEnforceRange
Fix GridView bounds behavior with snapping enabled.
Small optimization when checking if MouseArea's onPressAndHold is
Fix autotest.
Fixed `nmake clean' breaking declarative imports on Windows.
Fix drawing flicker on Qml Viewer startup
Fix snake demo
Add qmlmethod Item::childAt() to delarative item
Cursor positioning in QTextDocument after undo()
...
Diffstat (limited to 'src')
51 files changed, 668 insertions, 435 deletions
diff --git a/src/declarative/3rdparty/3rdparty.pri b/src/declarative/3rdparty/3rdparty.pri deleted file mode 100644 index fbdcc11..0000000 --- a/src/declarative/3rdparty/3rdparty.pri +++ /dev/null @@ -1,7 +0,0 @@ -INCLUDEPATH += $$PWD - -HEADERS += \ - $$PWD/qlistmodelinterface_p.h\ - -SOURCES += \ - $$PWD/qlistmodelinterface.cpp \ diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index 5735b1e..8b6b83f 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -1,6 +1,8 @@ ============================================================================= The changes below are pre Qt 4.7.0 RC +QDeclarativeView + - initialSize() function added TextInput and TextEdit: - openSoftwareInputPanel() and closeSoftwareInputPanel() functions added Flickable: diff --git a/src/declarative/declarative.pro b/src/declarative/declarative.pro index 8037a16..510e7a5 100644 --- a/src/declarative/declarative.pro +++ b/src/declarative/declarative.pro @@ -20,7 +20,6 @@ include(../qbase.pri) #DESTDIR=. #modules -include(3rdparty/3rdparty.pri) include(util/util.pri) include(graphicsitems/graphicsitems.pri) include(qml/qml.pri) diff --git a/src/declarative/graphicsitems/qdeclarativeanchors.cpp b/src/declarative/graphicsitems/qdeclarativeanchors.cpp index aa53aba..6796977 100644 --- a/src/declarative/graphicsitems/qdeclarativeanchors.cpp +++ b/src/declarative/graphicsitems/qdeclarativeanchors.cpp @@ -53,6 +53,30 @@ QT_BEGIN_NAMESPACE //TODO: should we cache relationships, so we don't have to check each time (parent-child or sibling)? //TODO: support non-parent, non-sibling (need to find lowest common ancestor) +static qreal hcenter(QGraphicsItem *i) +{ + QGraphicsItemPrivate *item = QGraphicsItemPrivate::get(i); + + qreal width = item->width(); + int iw = width; + if (iw % 2) + return (width + 1) / 2; + else + return width / 2; +} + +static qreal vcenter(QGraphicsItem *i) +{ + QGraphicsItemPrivate *item = QGraphicsItemPrivate::get(i); + + qreal height = item->height(); + int ih = height; + if (ih % 2) + return (height + 1) / 2; + else + return height / 2; +} + //### const item? //local position static qreal position(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine) @@ -73,10 +97,10 @@ static qreal position(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine ret = item->y() + d->height(); break; case QDeclarativeAnchorLine::HCenter: - ret = item->x() + d->width()/2; + ret = item->x() + hcenter(item); break; case QDeclarativeAnchorLine::VCenter: - ret = item->y() + d->height()/2; + ret = item->y() + vcenter(item); break; case QDeclarativeAnchorLine::Baseline: if (d->isDeclarativeItem) @@ -108,10 +132,10 @@ static qreal adjustedPosition(QGraphicsObject *item, QDeclarativeAnchorLine::Anc ret = d->height(); break; case QDeclarativeAnchorLine::HCenter: - ret = d->width()/2; + ret = hcenter(item); break; case QDeclarativeAnchorLine::VCenter: - ret = d->height()/2; + ret = vcenter(item); break; case QDeclarativeAnchorLine::Baseline: if (d->isDeclarativeItem) @@ -192,14 +216,14 @@ void QDeclarativeAnchorsPrivate::centerInChanged() QGraphicsItemPrivate *itemPrivate = QGraphicsItemPrivate::get(item); if (centerIn == item->parentItem()) { QGraphicsItemPrivate *parentPrivate = QGraphicsItemPrivate::get(item->parentItem()); - QPointF p((parentPrivate->width() - itemPrivate->width()) / 2. + hCenterOffset, - (parentPrivate->height() - itemPrivate->height()) / 2. + vCenterOffset); + QPointF p(hcenter(item->parentItem()) - hcenter(item) + hCenterOffset, + vcenter(item->parentItem()) - vcenter(item) + vCenterOffset); setItemPos(p); } else if (centerIn->parentItem() == item->parentItem()) { QGraphicsItemPrivate *centerPrivate = QGraphicsItemPrivate::get(centerIn); - QPointF p(centerIn->x() + (centerPrivate->width() - itemPrivate->width()) / 2. + hCenterOffset, - centerIn->y() + (centerPrivate->height() - itemPrivate->height()) / 2. + vCenterOffset); + QPointF p(centerIn->x() + hcenter(centerIn) - hcenter(item) + hCenterOffset, + centerIn->y() + vcenter(centerIn) - vcenter(item) + vCenterOffset); setItemPos(p); } @@ -535,9 +559,9 @@ void QDeclarativeAnchorsPrivate::updateVerticalAnchors() //Handle vCenter if (vCenter.item == item->parentItem()) { setItemY(adjustedPosition(vCenter.item, vCenter.anchorLine) - - itemPrivate->height()/2 + vCenterOffset); + - vcenter(item) + vCenterOffset); } else if (vCenter.item->parentItem() == item->parentItem()) { - setItemY(position(vCenter.item, vCenter.anchorLine) - itemPrivate->height()/2 + vCenterOffset); + setItemY(position(vCenter.item, vCenter.anchorLine) - vcenter(item) + vCenterOffset); } } else if (usedAnchors & QDeclarativeAnchors::BaselineAnchor) { //Handle baseline @@ -604,9 +628,9 @@ void QDeclarativeAnchorsPrivate::updateHorizontalAnchors() } else if (usedAnchors & QDeclarativeAnchors::HCenterAnchor) { //Handle hCenter if (hCenter.item == item->parentItem()) { - setItemX(adjustedPosition(hCenter.item, hCenter.anchorLine) - itemPrivate->width()/2 + hCenterOffset); + setItemX(adjustedPosition(hCenter.item, hCenter.anchorLine) - hcenter(item) + hCenterOffset); } else if (hCenter.item->parentItem() == item->parentItem()) { - setItemX(position(hCenter.item, hCenter.anchorLine) - itemPrivate->width()/2 + hCenterOffset); + setItemX(position(hCenter.item, hCenter.anchorLine) - hcenter(item) + hCenterOffset); } } diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index ffffc2f..ed1d271 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -108,6 +108,7 @@ public: , highlightComponent(0), highlight(0), trackedItem(0) , moveReason(Other), buffer(0), highlightXAnimator(0), highlightYAnimator(0) , highlightMoveDuration(150) + , footerComponent(0), footer(0), headerComponent(0), header(0) , bufferMode(BufferBefore | BufferAfter), snapMode(QDeclarativeGridView::NoSnap) , ownModel(false), wrap(false), autoHighlight(true) , fixCurrentVisibility(false), lazyRelease(false), layoutScheduled(false) @@ -128,6 +129,8 @@ public: void createHighlight(); void updateHighlight(); void updateCurrent(int modelIndex); + void updateHeader(); + void updateFooter(); void fixupPosition(); FxGridItem *visibleItem(int modelIndex) const { @@ -230,6 +233,18 @@ public: return visibleItems.count() ? visibleItems.first() : 0; } + int lastVisibleIndex() const { + int lastIndex = -1; + for (int i = visibleItems.count()-1; i >= 0; --i) { + FxGridItem *gridItem = visibleItems.at(i); + if (gridItem->index != -1) { + lastIndex = gridItem->index; + break; + } + } + return lastIndex; + } + // Map a model index to visibleItems list index. // These may differ if removed items are still present in the visible list, // e.g. doing a removal animation @@ -246,12 +261,19 @@ public: return -1; // Not in visibleList } - qreal snapPosAt(qreal pos) { + qreal snapPosAt(qreal pos) const { + Q_Q(const QDeclarativeGridView); qreal snapPos = 0; if (!visibleItems.isEmpty()) { pos += rowSize()/2; snapPos = visibleItems.first()->rowPos() - visibleIndex / columns * rowSize(); snapPos = pos - fmodf(pos - snapPos, qreal(rowSize())); + qreal maxExtent = flow == QDeclarativeGridView::LeftToRight ? -q->maxYExtent() : -q->maxXExtent(); + qreal minExtent = flow == QDeclarativeGridView::LeftToRight ? -q->minYExtent() : -q->minXExtent(); + if (snapPos > maxExtent) + snapPos = maxExtent; + if (snapPos < minExtent) + snapPos = minExtent; } return snapPos; } @@ -283,6 +305,9 @@ public: scheduleLayout(); } } + } else if ((header && header->item == item) || (footer && footer->item == item)) { + updateHeader(); + updateFooter(); } } @@ -330,6 +355,10 @@ public: QSmoothedAnimation *highlightXAnimator; QSmoothedAnimation *highlightYAnimator; int highlightMoveDuration; + QDeclarativeComponent *footerComponent; + FxGridItem *footer; + QDeclarativeComponent *headerComponent; + FxGridItem *header; enum BufferMode { NoBuffer = 0x00, BufferBefore = 0x01, BufferAfter = 0x02 }; int bufferMode; QDeclarativeGridView::SnapMode snapMode; @@ -412,7 +441,6 @@ void QDeclarativeGridViewPrivate::refill(qreal from, qreal to, bool doBuffer) Q_Q(QDeclarativeGridView); if (!isValid() || !q->isComponentComplete()) return; - itemCount = model->count(); qreal bufferFrom = from - buffer; qreal bufferTo = to + buffer; @@ -522,6 +550,10 @@ void QDeclarativeGridViewPrivate::refill(qreal from, qreal to, bool doBuffer) deferredRelease = true; } if (changed) { + if (header) + updateHeader(); + if (footer) + updateFooter(); if (flow == QDeclarativeGridView::LeftToRight) q->setContentHeight(endPosition() - startPosition()); else @@ -579,6 +611,10 @@ void QDeclarativeGridViewPrivate::layout() item->setPosition(colPos, rowPos); } } + if (header) + updateHeader(); + if (footer) + updateFooter(); q->refill(); updateHighlight(); moveReason = Other; @@ -742,6 +778,94 @@ void QDeclarativeGridViewPrivate::updateCurrent(int modelIndex) releaseItem(oldCurrentItem); } +void QDeclarativeGridViewPrivate::updateFooter() +{ + Q_Q(QDeclarativeGridView); + if (!footer && footerComponent) { + QDeclarativeItem *item = 0; + QDeclarativeContext *context = new QDeclarativeContext(qmlContext(q)); + QObject *nobj = footerComponent->create(context); + if (nobj) { + QDeclarative_setParent_noEvent(context, nobj); + item = qobject_cast<QDeclarativeItem *>(nobj); + if (!item) + delete nobj; + } else { + delete context; + } + if (item) { + QDeclarative_setParent_noEvent(item, q->viewport()); + item->setParentItem(q->viewport()); + item->setZValue(1); + QDeclarativeItemPrivate *itemPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(item)); + itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); + footer = new FxGridItem(item, q); + } + } + if (footer) { + if (visibleItems.count()) { + qreal endPos = endPosition(); + if (lastVisibleIndex() == model->count()-1) { + footer->setPosition(0, endPos); + } else { + qreal visiblePos = position() + q->height(); + if (endPos <= visiblePos || footer->endRowPos() < endPos) + footer->setPosition(0, endPos); + } + } else { + qreal endPos = 0; + if (header) { + endPos += flow == QDeclarativeGridView::LeftToRight + ? header->item->height() + : header->item->width(); + } + footer->setPosition(0, endPos); + } + } +} + +void QDeclarativeGridViewPrivate::updateHeader() +{ + Q_Q(QDeclarativeGridView); + if (!header && headerComponent) { + QDeclarativeItem *item = 0; + QDeclarativeContext *context = new QDeclarativeContext(qmlContext(q)); + QObject *nobj = headerComponent->create(context); + if (nobj) { + QDeclarative_setParent_noEvent(context, nobj); + item = qobject_cast<QDeclarativeItem *>(nobj); + if (!item) + delete nobj; + } else { + delete context; + } + if (item) { + QDeclarative_setParent_noEvent(item, q->viewport()); + item->setParentItem(q->viewport()); + item->setZValue(1); + QDeclarativeItemPrivate *itemPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(item)); + itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); + header = new FxGridItem(item, q); + } + } + if (header) { + if (visibleItems.count()) { + qreal startPos = startPosition(); + qreal headerSize = flow == QDeclarativeGridView::LeftToRight + ? header->item->height() + : header->item->width(); + if (visibleIndex == 0) { + header->setPosition(0, startPos - headerSize); + } else { + if (position() <= startPos || header->rowPos() > startPos - headerSize) + header->setPosition(0, startPos - headerSize); + } + } else { + header->setPosition(0, 0); + } + } +} + void QDeclarativeGridViewPrivate::fixupPosition() { moveReason = Other; @@ -784,7 +908,6 @@ void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m } } else if (snapMode != QDeclarativeGridView::NoSnap) { qreal pos = -snapPosAt(-(data.move.value() - highlightRangeStart)) + highlightRangeStart; - pos = qMin(qMax(pos, maxExtent), minExtent); qreal dist = qAbs(data.move.value() - pos); if (dist > 0) { timeline.reset(data.move); @@ -806,7 +929,6 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity) { Q_Q(QDeclarativeGridView); - moveReason = Mouse; if ((!haveHighlightRange || highlightRange != QDeclarativeGridView::StrictlyEnforceRange) && snapMode == QDeclarativeGridView::NoSnap) { @@ -851,9 +973,10 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m qreal accel = deceleration; qreal v2 = v * v; qreal overshootDist = 0.0; - if (maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) { + if ((maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) || snapMode == QDeclarativeGridView::SnapOneRow) { // + rowSize()/4 to encourage moving at least one item in the flick direction qreal dist = v2 / (accel * 2.0) + rowSize()/4; + dist = qMin(dist, maxDistance); if (v > 0) dist = -dist; data.flickTarget = -snapPosAt(-(data.move.value() - highlightRangeStart) + dist) + highlightRangeStart; @@ -958,11 +1081,13 @@ QDeclarativeGridView::~QDeclarativeGridView() d->clear(); if (d->ownModel) delete d->model; + delete d->header; + delete d->footer; } /*! \qmlattachedproperty bool GridView::isCurrentItem - This attched property is true if this delegate is the current item; otherwise false. + This attached property is true if this delegate is the current item; otherwise false. It is attached to each instance of the delegate. */ @@ -1524,6 +1649,67 @@ void QDeclarativeGridView::setSnapMode(SnapMode mode) } } +/*! + \qmlproperty Component GridView::footer + This property holds the component to use as the footer. + + An instance of the footer component is created for each view. The + footer is positioned at the end of the view, after any items. + + \sa header +*/ +QDeclarativeComponent *QDeclarativeGridView::footer() const +{ + Q_D(const QDeclarativeGridView); + return d->footerComponent; +} + +void QDeclarativeGridView::setFooter(QDeclarativeComponent *footer) +{ + Q_D(QDeclarativeGridView); + if (d->footerComponent != footer) { + if (d->footer) { + delete d->footer; + d->footer = 0; + } + d->footerComponent = footer; + d->updateFooter(); + d->updateGrid(); + emit footerChanged(); + } +} + +/*! + \qmlproperty Component GridView::header + This property holds the component to use as the header. + + An instance of the header component is created for each view. The + header is positioned at the beginning of the view, before any items. + + \sa footer +*/ +QDeclarativeComponent *QDeclarativeGridView::header() const +{ + Q_D(const QDeclarativeGridView); + return d->headerComponent; +} + +void QDeclarativeGridView::setHeader(QDeclarativeComponent *header) +{ + Q_D(QDeclarativeGridView); + if (d->headerComponent != header) { + if (d->header) { + delete d->header; + d->header = 0; + } + d->headerComponent = header; + d->updateHeader(); + d->updateFooter(); + d->updateGrid(); + emit headerChanged(); + } +} + bool QDeclarativeGridView::event(QEvent *event) { Q_D(QDeclarativeGridView); @@ -1590,6 +1776,8 @@ qreal QDeclarativeGridView::minYExtent() const if (d->flow == QDeclarativeGridView::TopToBottom) return QDeclarativeFlickable::minYExtent(); qreal extent = -d->startPosition(); + if (d->header && d->visibleItems.count()) + extent += d->header->item->height(); if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { extent += d->highlightRangeStart; extent = qMax(extent, -(d->rowPosAt(0) + d->rowSize() - d->highlightRangeEnd)); @@ -1603,13 +1791,17 @@ qreal QDeclarativeGridView::maxYExtent() const if (d->flow == QDeclarativeGridView::TopToBottom) return QDeclarativeFlickable::maxYExtent(); qreal extent; - if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { + if (!d->model || !d->model->count()) { + extent = 0; + } else if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { extent = -(d->rowPosAt(d->model->count()-1) - d->highlightRangeStart); if (d->highlightRangeEnd != d->highlightRangeStart) extent = qMin(extent, -(d->endPosition() - d->highlightRangeEnd + 1)); } else { extent = -(d->endPosition() - height()); } + if (d->footer) + extent -= d->footer->item->height(); const qreal minY = minYExtent(); if (extent > minY) extent = minY; @@ -1622,6 +1814,8 @@ qreal QDeclarativeGridView::minXExtent() const if (d->flow == QDeclarativeGridView::LeftToRight) return QDeclarativeFlickable::minXExtent(); qreal extent = -d->startPosition(); + if (d->header && d->visibleItems.count()) + extent += d->header->item->width(); if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { extent += d->highlightRangeStart; extent = qMax(extent, -(d->rowPosAt(0) + d->rowSize() - d->highlightRangeEnd)); @@ -1635,13 +1829,17 @@ qreal QDeclarativeGridView::maxXExtent() const if (d->flow == QDeclarativeGridView::LeftToRight) return QDeclarativeFlickable::maxXExtent(); qreal extent; - if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { + if (!d->model || !d->model->count()) { + extent = 0; + } if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { extent = -(d->rowPosAt(d->model->count()-1) - d->highlightRangeStart); if (d->highlightRangeEnd != d->highlightRangeStart) extent = qMin(extent, -(d->endPosition() - d->highlightRangeEnd + 1)); } else { - extent = -(d->endPosition() - height()); + extent = -(d->endPosition() - width()); } + if (d->footer) + extent -= d->footer->item->width(); const qreal minX = minXExtent(); if (extent > minX) extent = minX; diff --git a/src/declarative/graphicsitems/qdeclarativegridview_p.h b/src/declarative/graphicsitems/qdeclarativegridview_p.h index 2bf154c..021aad9 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview_p.h +++ b/src/declarative/graphicsitems/qdeclarativegridview_p.h @@ -80,6 +80,9 @@ class Q_DECLARATIVE_EXPORT QDeclarativeGridView : public QDeclarativeFlickable Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged) + Q_PROPERTY(QDeclarativeComponent *header READ header WRITE setHeader NOTIFY headerChanged) + Q_PROPERTY(QDeclarativeComponent *footer READ footer WRITE setFooter NOTIFY footerChanged) + Q_ENUMS(HighlightRangeMode) Q_ENUMS(SnapMode) Q_ENUMS(Flow) @@ -142,6 +145,12 @@ public: SnapMode snapMode() const; void setSnapMode(SnapMode mode); + QDeclarativeComponent *footer() const; + void setFooter(QDeclarativeComponent *); + + QDeclarativeComponent *header() const; + void setHeader(QDeclarativeComponent *); + enum PositionMode { Beginning, Center, End, Visible, Contain }; Q_INVOKABLE void positionViewAtIndex(int index, int mode); @@ -172,6 +181,8 @@ Q_SIGNALS: void keyNavigationWrapsChanged(); void cacheBufferChanged(); void snapModeChanged(); + void headerChanged(); + void footerChanged(); protected: virtual bool event(QEvent *event); diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp index 9949e65..7ab280e 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp @@ -726,7 +726,7 @@ void QDeclarativeKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post) The signal properties have a \l KeyEvent parameter, named \e event which contains details of the event. If a key is handled \e event.accepted should be set to true to prevent the - event from propagating up the item heirarchy. + event from propagating up the item hierarchy. \code Item { @@ -1633,7 +1633,7 @@ void QDeclarativeItemPrivate::data_append(QDeclarativeListProperty<QObject> *pro QObject *QDeclarativeItemPrivate::resources_at(QDeclarativeListProperty<QObject> *prop, int index) { - QObjectList children = prop->object->children(); + const QObjectList children = prop->object->children(); if (index < children.count()) return children.at(index); else @@ -2391,6 +2391,28 @@ void QDeclarativeItem::forceFocus() } } + +/*! + \qmlmethod Item::childAt(real x, real y) + + Returns the visible child item at point (\a x, \a y), which is in this + item's coordinate system, or \c null if there is no such item. + */ +QDeclarativeItem *QDeclarativeItem::childAt(qreal x, qreal y) const +{ + const QList<QGraphicsItem *> children = childItems(); + for (int i = children.count()-1; i >= 0; --i) { + if (QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i))) { + if (child->isVisible() && child->x() <= x + && child->x() + child->width() >= x + && child->y() <= y + && child->y() + child->height() >= y) + return child; + } + } + return 0; +} + void QDeclarativeItemPrivate::focusChanged(bool flag) { Q_Q(QDeclarativeItem); diff --git a/src/declarative/graphicsitems/qdeclarativeitem.h b/src/declarative/graphicsitems/qdeclarativeitem.h index 77e316b..4f420f8 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.h +++ b/src/declarative/graphicsitems/qdeclarativeitem.h @@ -148,6 +148,7 @@ public: Q_INVOKABLE QScriptValue mapFromItem(const QScriptValue &item, qreal x, qreal y) const; Q_INVOKABLE QScriptValue mapToItem(const QScriptValue &item, qreal x, qreal y) const; Q_INVOKABLE void forceFocus(); + Q_INVOKABLE QDeclarativeItem *childAt(qreal x, qreal y) const; Q_SIGNALS: void childrenChanged(); diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index dbd1976..3f2b4ce 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -427,6 +427,10 @@ public: scheduleLayout(); } } + if ((header && header->item == item) || (footer && footer->item == item)) { + updateHeader(); + updateFooter(); + } if (currentItem && currentItem->item == item) updateHighlight(); if (trackedItem && trackedItem->item == item) @@ -1045,6 +1049,8 @@ void QDeclarativeListViewPrivate::updateFooter() QDeclarative_setParent_noEvent(item, q->viewport()); item->setParentItem(q->viewport()); item->setZValue(1); + QDeclarativeItemPrivate *itemPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(item)); + itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); footer = new FxListItem(item, q); } } @@ -1083,6 +1089,8 @@ void QDeclarativeListViewPrivate::updateHeader() QDeclarative_setParent_noEvent(item, q->viewport()); item->setParentItem(q->viewport()); item->setZValue(1); + QDeclarativeItemPrivate *itemPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(item)); + itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); header = new FxListItem(item, q); if (visibleItems.isEmpty()) visiblePos = header->size(); @@ -2074,6 +2082,15 @@ void QDeclarativeListView::setSnapMode(SnapMode mode) } } +/*! + \qmlproperty Component ListView::footer + This property holds the component to use as the footer. + + An instance of the footer component is created for each view. The + footer is positioned at the end of the view, after any items. + + \sa header +*/ QDeclarativeComponent *QDeclarativeListView::footer() const { Q_D(const QDeclarativeListView); @@ -2097,6 +2114,15 @@ void QDeclarativeListView::setFooter(QDeclarativeComponent *footer) } } +/*! + \qmlproperty Component ListView::header + This property holds the component to use as the header. + + An instance of the header component is created for each view. The + header is positioned at the beginning of the view, before any items. + + \sa footer +*/ QDeclarativeComponent *QDeclarativeListView::header() const { Q_D(const QDeclarativeListView); @@ -2222,7 +2248,9 @@ qreal QDeclarativeListView::maxYExtent() const if (d->orient == QDeclarativeListView::Horizontal) return height(); if (d->maxExtentDirty) { - if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { + if (!d->model || !d->model->count()) { + d->maxExtent = 0; + } else if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { d->maxExtent = -(d->positionAt(d->model->count()-1) - d->highlightRangeStart); if (d->highlightRangeEnd != d->highlightRangeStart) d->maxExtent = qMin(d->maxExtent, -(d->endPosition() - d->highlightRangeEnd + 1)); @@ -2264,7 +2292,9 @@ qreal QDeclarativeListView::maxXExtent() const if (d->orient == QDeclarativeListView::Vertical) return width(); if (d->maxExtentDirty) { - if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { + if (!d->model || !d->model->count()) { + d->maxExtent = 0; + } else if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { d->maxExtent = -(d->positionAt(d->model->count()-1) - d->highlightRangeStart); if (d->highlightRangeEnd != d->highlightRangeStart) d->maxExtent = qMin(d->maxExtent, -(d->endPosition() - d->highlightRangeEnd + 1)); diff --git a/src/declarative/graphicsitems/qdeclarativemousearea.cpp b/src/declarative/graphicsitems/qdeclarativemousearea.cpp index 6fca283..a68e664 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea.cpp +++ b/src/declarative/graphicsitems/qdeclarativemousearea.cpp @@ -410,7 +410,7 @@ void QDeclarativeMouseArea::mousePressEvent(QGraphicsSceneMouseEvent *event) setHovered(true); d->startScene = event->scenePos(); // we should only start timer if pressAndHold is connected to. - if (d->isConnected("pressAndHold(QDeclarativeMouseEvent*)")) + if (d->isPressAndHoldConnected()) d->pressAndHoldTimer.start(PressAndHoldDelay, this); setKeepMouseGrab(false); event->setAccepted(setPressed(true)); diff --git a/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h b/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h index 4e909ff..3d7bd1e 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h @@ -88,9 +88,9 @@ public: lastModifiers = event->modifiers(); } - bool isConnected(const char *signal) { + bool isPressAndHoldConnected() { Q_Q(QDeclarativeMouseArea); - int idx = QObjectPrivate::get(q)->signalIndex(signal); + static int idx = QObjectPrivate::get(q)->signalIndex("pressAndHold(QDeclarativeMouseEvent*)"); return QObjectPrivate::get(q)->isSignalConnected(idx); } diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp index f58b054..0c2d249 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview.cpp +++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp @@ -358,6 +358,13 @@ QDeclarativePathView::~QDeclarativePathView() } /*! + \qmlattachedproperty PathView PathView::view + This attached property holds the view that manages this delegate instance. + + It is attached to each instance of the delegate. +*/ + +/*! \qmlattachedproperty bool PathView::onPath This attached property holds whether the item is currently on the path. diff --git a/src/declarative/graphicsitems/qdeclarativepositioners.cpp b/src/declarative/graphicsitems/qdeclarativepositioners.cpp index 20cc46b..18618ab 100644 --- a/src/declarative/graphicsitems/qdeclarativepositioners.cpp +++ b/src/declarative/graphicsitems/qdeclarativepositioners.cpp @@ -219,6 +219,7 @@ void QDeclarativeBasePositioner::prePositioning() QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(ii)); if (!child) continue; + QDeclarativeItemPrivate *childPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(child)); PositionedItem *item = 0; PositionedItem posItem(child); int wIdx = oldItems.find(posItem); @@ -227,11 +228,13 @@ void QDeclarativeBasePositioner::prePositioning() positionedItems.append(posItem); item = &positionedItems[positionedItems.count()-1]; item->isNew = true; - if (child->opacity() <= 0.0 || !child->isVisible()) + if (child->opacity() <= 0.0 || childPrivate->explicitlyHidden) item->isVisible = false; } else { item = &oldItems[wIdx]; - if (child->opacity() <= 0.0 || !child->isVisible()) { + // Items are only omitted from positioning if they are explicitly hidden + // i.e. their positioning is not affected if an ancestor is hidden. + if (child->opacity() <= 0.0 || childPrivate->explicitlyHidden) { item->isVisible = false; } else if (!item->isVisible) { item->isVisible = true; @@ -299,6 +302,12 @@ void QDeclarativeBasePositioner::finishApplyTransitions() d->moveActions.clear(); } +static inline bool isInvisible(QDeclarativeItem *child) +{ + QDeclarativeItemPrivate *childPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(child)); + return child->opacity() == 0.0 || childPrivate->explicitlyHidden || !child->width() || !child->height(); +} + /*! \qmlclass Column QDeclarativeColumn \since 4.7 @@ -416,11 +425,6 @@ QDeclarativeColumn::QDeclarativeColumn(QDeclarativeItem *parent) { } -static inline bool isInvisible(QDeclarativeItem *child) -{ - return child->opacity() == 0.0 || !child->isVisible() || !child->width() || !child->height(); -} - void QDeclarativeColumn::doPositioning(QSizeF *contentSize) { int voffset = 0; diff --git a/src/declarative/graphicsitems/qdeclarativepositioners_p_p.h b/src/declarative/graphicsitems/qdeclarativepositioners_p_p.h index 04f0181..822079b 100644 --- a/src/declarative/graphicsitems/qdeclarativepositioners_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativepositioners_p_p.h @@ -100,18 +100,23 @@ public: bool doingPositioning : 1; bool anchorConflict : 1; - virtual void itemSiblingOrderChanged(QDeclarativeItem* other) + void schedulePositioning() { Q_Q(QDeclarativeBasePositioner); - Q_UNUSED(other); if(!queuedPositioning){ - //Delay is due to many children often being reordered at once - //And we only want to reposition them all once QTimer::singleShot(0,q,SLOT(prePositioning())); queuedPositioning = true; } } + virtual void itemSiblingOrderChanged(QDeclarativeItem* other) + { + Q_UNUSED(other); + //Delay is due to many children often being reordered at once + //And we only want to reposition them all once + schedulePositioning(); + } + void itemGeometryChanged(QDeclarativeItem *, const QRectF &newGeometry, const QRectF &oldGeometry) { Q_Q(QDeclarativeBasePositioner); @@ -120,8 +125,7 @@ public: } virtual void itemVisibilityChanged(QDeclarativeItem *) { - Q_Q(QDeclarativeBasePositioner); - q->prePositioning(); + schedulePositioning(); } virtual void itemOpacityChanged(QDeclarativeItem *) { diff --git a/src/declarative/graphicsitems/qdeclarativetext.cpp b/src/declarative/graphicsitems/qdeclarativetext.cpp index f4722c3..3b89ad9 100644 --- a/src/declarative/graphicsitems/qdeclarativetext.cpp +++ b/src/declarative/graphicsitems/qdeclarativetext.cpp @@ -1171,7 +1171,7 @@ void QDeclarativeText::mousePressEvent(QGraphicsSceneMouseEvent *event) } /*! - \qmlsignal Text::linkActivated(link) + \qmlsignal Text::onLinkActivated(link) This handler is called when the user clicks on a link embedded in the text. */ diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp index 94973f2..c086851 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp @@ -1391,9 +1391,9 @@ void QDeclarativeTextEditPrivate::updateDefaultTextOption() your application. By default the opening of input panels follows the platform style. On Symbian^1 and - Symbian^3 -based devices the panels are opened by clicking TextEdit and need to be - manually closed by the user. On other platforms the panels are automatically opened - when TextEdit element gains focus and closed when the focus is lost. + Symbian^3 -based devices the panels are opened by clicking TextEdit. On other platforms + the panels are automatically opened when TextEdit element gains focus. Input panels are + always closed if no editor owns focus. . You can disable the automatic behavior by setting the property \c focusOnPress to false and use functions openSoftwareInputPanel() and closeSoftwareInputPanel() to implement @@ -1415,9 +1415,9 @@ void QDeclarativeTextEditPrivate::updateDefaultTextOption() textEdit.openSoftwareInputPanel(); } else { textEdit.focus = false; - textEdit.closeSoftwareInputPanel(); } } + onPressAndHold: textEdit.closeSoftwareInputPanel(); } } \endcode @@ -1442,9 +1442,9 @@ void QDeclarativeTextEdit::openSoftwareInputPanel() your application. By default the opening of input panels follows the platform style. On Symbian^1 and - Symbian^3 -based devices the panels are opened by clicking TextEdit and need to be - manually closed by the user. On other platforms the panels are automatically opened - when TextEdit element gains focus and closed when the focus is lost. + Symbian^3 -based devices the panels are opened by clicking TextEdit. On other platforms + the panels are automatically opened when TextEdit element gains focus. Input panels are + always closed if no editor owns focus. . You can disable the automatic behavior by setting the property \c focusOnPress to false and use functions openSoftwareInputPanel() and closeSoftwareInputPanel() to implement @@ -1466,9 +1466,9 @@ void QDeclarativeTextEdit::openSoftwareInputPanel() textEdit.openSoftwareInputPanel(); } else { textEdit.focus = false; - textEdit.closeSoftwareInputPanel(); } } + onPressAndHold: textEdit.closeSoftwareInputPanel(); } } \endcode @@ -1489,22 +1489,11 @@ void QDeclarativeTextEdit::focusInEvent(QFocusEvent *event) { Q_D(const QDeclarativeTextEdit); if (d->showInputPanelOnFocus) { - if (d->focusOnPress && !isReadOnly() && event->reason() != Qt::ActiveWindowFocusReason) { + if (d->focusOnPress && !isReadOnly()) { openSoftwareInputPanel(); } } QDeclarativePaintedItem::focusInEvent(event); } -void QDeclarativeTextEdit::focusOutEvent(QFocusEvent *event) -{ - Q_D(const QDeclarativeTextEdit); - if (d->showInputPanelOnFocus) { - if (d->focusOnPress && !isReadOnly()) { - closeSoftwareInputPanel(); - } - } - QDeclarativePaintedItem::focusOutEvent(event); -} - QT_END_NAMESPACE diff --git a/src/declarative/graphicsitems/qdeclarativetextedit_p.h b/src/declarative/graphicsitems/qdeclarativetextedit_p.h index 0ecb2f3..d08f607 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextedit_p.h @@ -247,7 +247,6 @@ protected: void keyPressEvent(QKeyEvent *); void keyReleaseEvent(QKeyEvent *); void focusInEvent(QFocusEvent *event); - void focusOutEvent(QFocusEvent *event); // mouse filter? void mousePressEvent(QGraphicsSceneMouseEvent *event); diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index 1202101..01b1447 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -249,7 +249,12 @@ QColor QDeclarativeTextInput::color() const void QDeclarativeTextInput::setColor(const QColor &c) { Q_D(QDeclarativeTextInput); - d->color = c; + if (c != d->color) { + d->color = c; + clearCache(); + update(); + emit colorChanged(c); + } } @@ -1234,9 +1239,9 @@ void QDeclarativeTextInput::moveCursorSelection(int position) your application. By default the opening of input panels follows the platform style. On Symbian^1 and - Symbian^3 -based devices the panels are opened by clicking TextInput and need to be - manually closed by the user. On other platforms the panels are automatically opened - when TextInput element gains focus and closed when the focus is lost. + Symbian^3 -based devices the panels are opened by clicking TextInput. On other platforms + the panels are automatically opened when TextInput element gains focus. Input panels are + always closed if no editor owns focus. . You can disable the automatic behavior by setting the property \c focusOnPress to false and use functions openSoftwareInputPanel() and closeSoftwareInputPanel() to implement @@ -1258,9 +1263,9 @@ void QDeclarativeTextInput::moveCursorSelection(int position) textInput.openSoftwareInputPanel(); } else { textInput.focus = false; - textInput.closeSoftwareInputPanel(); } } + onPressAndHold: textInput.closeSoftwareInputPanel(); } } \endqml @@ -1285,9 +1290,9 @@ void QDeclarativeTextInput::openSoftwareInputPanel() your application. By default the opening of input panels follows the platform style. On Symbian^1 and - Symbian^3 -based devices the panels are opened by clicking TextInput and need to be - manually closed by the user. On other platforms the panels are automatically opened - when TextInput element gains focus and closed when the focus is lost. + Symbian^3 -based devices the panels are opened by clicking TextInput. On other platforms + the panels are automatically opened when TextInput element gains focus. Input panels are + always closed if no editor owns focus. . You can disable the automatic behavior by setting the property \c focusOnPress to false and use functions openSoftwareInputPanel() and closeSoftwareInputPanel() to implement @@ -1309,9 +1314,9 @@ void QDeclarativeTextInput::openSoftwareInputPanel() textInput.openSoftwareInputPanel(); } else { textInput.focus = false; - textInput.closeSoftwareInputPanel(); } } + onPressAndHold: textInput.closeSoftwareInputPanel(); } } \endqml @@ -1333,24 +1338,13 @@ void QDeclarativeTextInput::focusInEvent(QFocusEvent *event) { Q_D(const QDeclarativeTextInput); if (d->showInputPanelOnFocus) { - if (d->focusOnPress && !isReadOnly() && event->reason() != Qt::ActiveWindowFocusReason) { + if (d->focusOnPress && !isReadOnly()) { openSoftwareInputPanel(); } } QDeclarativePaintedItem::focusInEvent(event); } -void QDeclarativeTextInput::focusOutEvent(QFocusEvent *event) -{ - Q_D(const QDeclarativeTextInput); - if (d->showInputPanelOnFocus) { - if (d->focusOnPress && !isReadOnly()) { - closeSoftwareInputPanel(); - } - } - QDeclarativePaintedItem::focusOutEvent(event); -} - void QDeclarativeTextInputPrivate::init() { Q_Q(QDeclarativeTextInput); diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p.h index e34634a..c539bd3 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextinput_p.h @@ -224,7 +224,6 @@ protected: void keyPressEvent(QKeyEvent* ev); bool event(QEvent *e); void focusInEvent(QFocusEvent *event); - void focusOutEvent(QFocusEvent *event); public Q_SLOTS: void selectAll(); diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp index 2a88a80..410f526 100644 --- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp +++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp @@ -113,16 +113,18 @@ public: \since 4.7 \brief The VisualItemModel allows items to be provided to a view. - The children of the VisualItemModel are provided in a model which - can be used in a view. Note that no delegate should be - provided to a view since the VisualItemModel contains the - visual delegate (items). + A VisualItemModel contains the visual items to be used in a view. + When a VisualItemModel is used in a view, the view does not require + a delegate since the VisualItemModel already contains the visual + delegate (items). An item can determine its index within the - model via the \c VisualItemModel.index attached property. + model via the \l{VisualItemModel::index}{index} attached property. The example below places three colored rectangles in a ListView. \code + import Qt 4.7 + Rectangle { VisualItemModel { id: itemModel @@ -145,6 +147,13 @@ QDeclarativeVisualItemModel::QDeclarativeVisualItemModel(QObject *parent) { } +/*! + \qmlattachedproperty int VisualItemModel::index + This attached property holds the index of this delegate's item within the model. + + It is attached to each instance of the delegate. +*/ + QDeclarativeListProperty<QDeclarativeItem> QDeclarativeVisualItemModel::children() { Q_D(QDeclarativeVisualItemModel); @@ -607,30 +616,15 @@ QDeclarativeVisualDataModelData *QDeclarativeVisualDataModelPrivate::data(QObjec A VisualDataModel encapsulates a model and the delegate that will be instantiated for items in the model. - It is usually not necessary to create a VisualDataModel directly, - since the QML views will create one internally. + It is usually not necessary to create VisualDataModel elements. + However, it can be useful for manipulating and accessing the \l modelIndex + when a QAbstractItemModel subclass is used as the + model. Also, VisualDataModel is used together with \l Package to + provide delegates to multiple views. The example below illustrates using a VisualDataModel with a ListView. - \code - VisualDataModel { - id: visualModel - model: myModel - delegate: Component { - Rectangle { - height: 25 - width: 100 - Text { text: "Name:" + name} - } - } - } - ListView { - width: 100 - height: 100 - anchors.fill: parent - model: visualModel - } - \endcode + \snippet doc/src/snippets/declarative/visualdatamodel.qml 0 */ QDeclarativeVisualDataModel::QDeclarativeVisualDataModel() @@ -805,56 +799,22 @@ void QDeclarativeVisualDataModel::setDelegate(QDeclarativeComponent *delegate) /*! \qmlproperty QModelIndex VisualDataModel::rootIndex - QAbstractItemModel provides a heirachical tree of data, whereas + QAbstractItemModel provides a hierarchical tree of data, whereas QML only operates on list data. \c rootIndex allows the children of any node in a QAbstractItemModel to be provided by this model. This property only affects models of type QAbstractItemModel. - \code - // main.cpp - - int main(int argc, char ** argv) - { - QApplication app(argc, argv); + For example, here is a simple interactive file system browser. + When a directory name is clicked, the view's \c rootIndex is set to the + QModelIndex node of the clicked directory, thus updating the view to show + the new directory's contents. - QDeclarativeView view; - - QDirModel model; - view.rootContext()->setContextProperty("myModel", &model); - - view.setSource(QUrl("qrc:view.qml")); - view.show(); - - return app.exec(); - } - - #include "main.moc" - \endcode - - \code - // view.qml - import Qt 4.7 - - ListView { - id: view - width: 200 - height: 200 - model: VisualDataModel { - model: myModel - delegate: Component { - Rectangle { - height: 25; width: 200 - Text { text: filePath } - MouseArea { - anchors.fill: parent; - onClicked: if (hasModelChildren) view.model.rootIndex = view.model.modelIndex(index) - } - } - } - } - } - \endcode + \c main.cpp: + \snippet doc/src/snippets/declarative/visualdatamodel_rootindex/main.cpp 0 + + \c view.qml: + \snippet doc/src/snippets/declarative/visualdatamodel_rootindex/view.qml 0 \sa modelIndex(), parentModelIndex() */ @@ -886,7 +846,7 @@ void QDeclarativeVisualDataModel::setRootIndex(const QVariant &root) /*! \qmlmethod QModelIndex VisualDataModel::modelIndex(int index) - QAbstractItemModel provides a heirachical tree of data, whereas + QAbstractItemModel provides a hierarchical tree of data, whereas QML only operates on list data. This function assists in using tree models in QML. @@ -906,7 +866,7 @@ QVariant QDeclarativeVisualDataModel::modelIndex(int idx) const /*! \qmlmethod QModelIndex VisualDataModel::parentModelIndex() - QAbstractItemModel provides a heirachical tree of data, whereas + QAbstractItemModel provides a hierarchical tree of data, whereas QML only operates on list data. This function assists in using tree models in QML. @@ -1000,10 +960,10 @@ QDeclarativeVisualDataModel::ReleaseFlags QDeclarativeVisualDataModel::release(Q The \a parts property selects a VisualDataModel which creates delegates from the part named. This is used in conjunction with - the Package element. + the \l Package element. For example, the code below selects a model which creates - delegates named \e list from a Package: + delegates named \e list from a \l Package: \code VisualDataModel { diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel_p.h b/src/declarative/graphicsitems/qdeclarativevisualitemmodel_p.h index 0bdbbcf..079c9e6 100644 --- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel_p.h +++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel_p.h @@ -54,11 +54,6 @@ Q_DECLARE_METATYPE(QModelIndex) QT_BEGIN_NAMESPACE QT_MODULE(Declarative) -/***************************************************************************** - ***************************************************************************** - XXX Experimental - ***************************************************************************** -*****************************************************************************/ class QDeclarativeItem; class QDeclarativeComponent; diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index 9847079..55ee783 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -78,7 +78,7 @@ class QByteArray; \since 4.7 \brief The Component element encapsulates a QML component description. - Components are reusable, encapsulated Qml element with a well-defined interface. + Components are reusable, encapsulated QML elements with well-defined interfaces. They are often defined in \l {qdeclarativedocuments.html}{Component Files}. The \e Component element allows defining components within a QML file. @@ -547,16 +547,18 @@ QDeclarativeComponent::QDeclarativeComponent(QDeclarativeComponentPrivate &dd, Q /*! \qmlmethod object Component::createObject(parent) - Returns an object instance from this component, or null if object creation fails. + + Creates and returns an object instance of this component that will have the given + \a parent. Returns null if object creation fails. The object will be created in the same context as the one in which the component was created. This function will always return null when called on components which were not created in QML. - Note that if the returned object is to be displayed, its \c parent must be set to - an existing item in a scene, or else the object will not be visible. The parent - argument is required to help you avoid this, you must explicitly pass in null if - you wish to create an object without setting a parent. + If you wish to create an object without setting a parent, specify \c null for + the \a parent value. Note that if the returned object is to be displayed, you + must provide a valid \a parent value or set the returned object's \l{Item::parent}{parent} + property, or else the object will not be visible. */ /*! diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index 6a13f15..2221d78 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -116,7 +116,7 @@ QDeclarativeContextPrivate::QDeclarativeContextPrivate() All properties added explicitly by QDeclarativeContext::setContextProperty() take precedence over the context object's properties. - Contexts form a hierarchy. The root of this heirarchy is the QDeclarativeEngine's + Contexts form a hierarchy. The root of this hierarchy is the QDeclarativeEngine's \l {QDeclarativeEngine::rootContext()}{root context}. A component instance can access the data in its own context, as well as all its ancestor contexts. Data can be made available to all instances by modifying the diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 39b0802..0715624 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -191,7 +191,7 @@ when the property has one of the following types: \o \c vector3d - use \l{Qt::vector3d()}{Qt.vector3d()} \endlist -There are also string based constructors for these types, see \l{qdeclarativebasictypes.html}{QML Basic Types}. +There are also string based constructors for these types. See \l{qdeclarativebasictypes.html}{QML Basic Types} for more information. \section1 Date/Time Formatters @@ -1054,8 +1054,9 @@ or \c null if there was an error in creating the component. Call \l {Component::createObject()}{Component.createObject()} on the returned component to create an object instance of the component. -Here is an example. Remember that QML files that might be loaded -over the network cannot be expected to be ready immediately. +Here is an example. Notice it checks whether the component \l{Component::status}{status} is +\c Component.Ready before calling \l {Component::createObject()}{createObject()} +in case the QML file is loaded over a network and thus is not ready immediately. \snippet doc/src/snippets/declarative/componentCreation.js 0 \codeline @@ -1095,12 +1096,12 @@ QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, QS /*! \qmlmethod object Qt::createQmlObject(string qml, object parent, string filepath) -Returns a new object created from the given \a string of QML with the specified \a parent, +Returns a new object created from the given \a string of QML which will have the specified \a parent, or \c null if there was an error in creating the object. If \a filepath is specified, it will be used for error reporting for the created object. -Example (where \c targetItem is the id of an existing QML item): +Example (where \c parentItem is the id of an existing QML item): \snippet doc/src/snippets/declarative/createQmlObject.qml 0 diff --git a/src/declarative/qml/qdeclarativevaluetype.cpp b/src/declarative/qml/qdeclarativevaluetype.cpp index dbc25bb..c17ec95 100644 --- a/src/declarative/qml/qdeclarativevaluetype.cpp +++ b/src/declarative/qml/qdeclarativevaluetype.cpp @@ -47,6 +47,8 @@ QT_BEGIN_NAMESPACE +Q_DECL_IMPORT extern int qt_defaultDpi(); + template<typename T> int qmlRegisterValueTypeEnums(const char *qmlName) { @@ -909,6 +911,11 @@ void QDeclarativeFontValueType::setStrikeout(bool b) qreal QDeclarativeFontValueType::pointSize() const { + if (font.pointSizeF() == -1) { + if (dpi.isNull) + dpi = qt_defaultDpi(); + return font.pixelSize() * qreal(72.) / qreal(dpi); + } return font.pointSizeF(); } @@ -929,6 +936,11 @@ void QDeclarativeFontValueType::setPointSize(qreal size) int QDeclarativeFontValueType::pixelSize() const { + if (font.pixelSize() == -1) { + if (dpi.isNull) + dpi = qt_defaultDpi(); + return (font.pointSizeF() * dpi) / qreal(72.); + } return font.pixelSize(); } diff --git a/src/declarative/qml/qdeclarativevaluetype_p.h b/src/declarative/qml/qdeclarativevaluetype_p.h index 3eaecc1..4b1bbd6 100644 --- a/src/declarative/qml/qdeclarativevaluetype_p.h +++ b/src/declarative/qml/qdeclarativevaluetype_p.h @@ -55,6 +55,7 @@ #include "qdeclarativeproperty.h" #include "private/qdeclarativeproperty_p.h" +#include "private/qdeclarativenullablevalue_p_p.h" #include <QtCore/qobject.h> #include <QtCore/qrect.h> @@ -547,6 +548,7 @@ private: QFont font; bool pixelSizeSet; bool pointSizeSet; + mutable QDeclarativeNullableValue<int> dpi; }; QT_END_NAMESPACE diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index 0eae136..25cf133 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -1774,7 +1774,7 @@ void QDeclarativePropertyAnimation::setTo(const QVariant &t) To specify an easing curve you need to specify at least the type. For some curves you can also specify amplitude, period and/or overshoot (more details provided after the table). The default easing curve is - Linear. + \c Easing.Linear. \qml PropertyAnimation { properties: "y"; easing.type: Easing.InOutElastic; easing.amplitude: 2.0; easing.period: 1.5 } @@ -1951,15 +1951,15 @@ void QDeclarativePropertyAnimation::setTo(const QVariant &t) \o \inlineimage qeasingcurve-outinbounce.png \endtable - easing.amplitude is only applicable for bounce and elastic curves (curves of type - Easing.InBounce, Easing.OutBounce, Easing.InOutBounce, Easing.OutInBounce, Easing.InElastic, - Easing.OutElastic, Easing.InOutElastic or Easing.OutInElastic). + \c easing.amplitude is only applicable for bounce and elastic curves (curves of type + \c Easing.InBounce, \c Easing.OutBounce, \c Easing.InOutBounce, \c Easing.OutInBounce, \c Easing.InElastic, + \c Easing.OutElastic, \c Easing.InOutElastic or \c Easing.OutInElastic). - easing.overshoot is only applicable if type is: Easing.InBack, Easing.OutBack, - Easing.InOutBack or Easing.OutInBack. + \c easing.overshoot is only applicable if \c easing.type is: \c Easing.InBack, \c Easing.OutBack, + \c Easing.InOutBack or \c Easing.OutInBack. - easing.period is only applicable if type is: Easing.InElastic, Easing.OutElastic, - Easing.InOutElastic or Easing.OutInElastic. + \c easing.period is only applicable if easing.type is: \c Easing.InElastic, \c Easing.OutElastic, + \c Easing.InOutElastic or \c Easing.OutInElastic. See the \l {declarative/animation/easing}{easing} example for a demonstration of the different easing settings. @@ -2045,8 +2045,9 @@ void QDeclarativePropertyAnimation::setProperties(const QString &prop) The singular forms are slightly optimized, so if you do have only a single target/property to animate you should try to use them. - In many cases these properties do not need to be explicitly specified -- they can be - inferred from the animation framework. + In many cases these properties do not need to be explicitly specified, as they can be + inferred from the animation framework: + \table 80% \row \o Value Source / Behavior @@ -2132,52 +2133,39 @@ QAbstractAnimation *QDeclarativePropertyAnimation::qtAnimation() return d->va; } -struct PropertyUpdater : public QDeclarativeBulkValueUpdater +void QDeclarativeAnimationPropertyUpdater::setValue(qreal v) { - QDeclarativeStateActions actions; - int interpolatorType; //for Number/ColorAnimation - int prevInterpolatorType; //for generic - QVariantAnimation::Interpolator interpolator; - bool reverse; - bool fromSourced; - bool fromDefined; - bool *wasDeleted; - PropertyUpdater() : prevInterpolatorType(0), wasDeleted(0) {} - ~PropertyUpdater() { if (wasDeleted) *wasDeleted = true; } - void setValue(qreal v) - { - bool deleted = false; - wasDeleted = &deleted; - if (reverse) //QVariantAnimation sends us 1->0 when reversed, but we are expecting 0->1 - v = 1 - v; - for (int ii = 0; ii < actions.count(); ++ii) { - QDeclarativeAction &action = actions[ii]; - - if (v == 1.) - QDeclarativePropertyPrivate::write(action.property, action.toValue, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding); - else { - if (!fromSourced && !fromDefined) { - action.fromValue = action.property.read(); - if (interpolatorType) - QDeclarativePropertyAnimationPrivate::convertVariant(action.fromValue, interpolatorType); - } - if (!interpolatorType) { - int propType = action.property.propertyType(); - if (!prevInterpolatorType || prevInterpolatorType != propType) { - prevInterpolatorType = propType; - interpolator = QVariantAnimationPrivate::getInterpolator(prevInterpolatorType); - } + bool deleted = false; + wasDeleted = &deleted; + if (reverse) //QVariantAnimation sends us 1->0 when reversed, but we are expecting 0->1 + v = 1 - v; + for (int ii = 0; ii < actions.count(); ++ii) { + QDeclarativeAction &action = actions[ii]; + + if (v == 1.) + QDeclarativePropertyPrivate::write(action.property, action.toValue, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding); + else { + if (!fromSourced && !fromDefined) { + action.fromValue = action.property.read(); + if (interpolatorType) + QDeclarativePropertyAnimationPrivate::convertVariant(action.fromValue, interpolatorType); + } + if (!interpolatorType) { + int propType = action.property.propertyType(); + if (!prevInterpolatorType || prevInterpolatorType != propType) { + prevInterpolatorType = propType; + interpolator = QVariantAnimationPrivate::getInterpolator(prevInterpolatorType); } - if (interpolator) - QDeclarativePropertyPrivate::write(action.property, interpolator(action.fromValue.constData(), action.toValue.constData(), v), QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding); } - if (deleted) - return; + if (interpolator) + QDeclarativePropertyPrivate::write(action.property, interpolator(action.fromValue.constData(), action.toValue.constData(), v), QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding); } - wasDeleted = 0; - fromSourced = true; + if (deleted) + return; } -}; + wasDeleted = 0; + fromSourced = true; +} void QDeclarativePropertyAnimation::transition(QDeclarativeStateActions &actions, QDeclarativeProperties &modified, @@ -2207,7 +2195,7 @@ void QDeclarativePropertyAnimation::transition(QDeclarativeStateActions &actions props << d->defaultProperties.split(QLatin1Char(',')); } - PropertyUpdater *data = new PropertyUpdater; + QDeclarativeAnimationPropertyUpdater *data = new QDeclarativeAnimationPropertyUpdater; data->interpolatorType = d->interpolatorType; data->interpolator = d->interpolator; data->reverse = direction == Backward ? true : false; @@ -2786,7 +2774,7 @@ void QDeclarativeAnchorAnimation::transition(QDeclarativeStateActions &actions, { Q_UNUSED(modified); Q_D(QDeclarativeAnchorAnimation); - PropertyUpdater *data = new PropertyUpdater; + QDeclarativeAnimationPropertyUpdater *data = new QDeclarativeAnimationPropertyUpdater; data->interpolatorType = QMetaType::QReal; data->interpolator = d->interpolator; diff --git a/src/declarative/util/qdeclarativeanimation_p.h b/src/declarative/util/qdeclarativeanimation_p.h index e7cd8a8..3f8fbdd 100644 --- a/src/declarative/util/qdeclarativeanimation_p.h +++ b/src/declarative/util/qdeclarativeanimation_p.h @@ -384,7 +384,7 @@ Q_SIGNALS: }; class QDeclarativeAnimationGroupPrivate; -class QDeclarativeAnimationGroup : public QDeclarativeAbstractAnimation +class Q_AUTOTEST_EXPORT QDeclarativeAnimationGroup : public QDeclarativeAbstractAnimation { Q_OBJECT Q_DECLARE_PRIVATE(QDeclarativeAnimationGroup) diff --git a/src/declarative/util/qdeclarativeanimation_p_p.h b/src/declarative/util/qdeclarativeanimation_p_p.h index 3b0f52e..b6d6bbb 100644 --- a/src/declarative/util/qdeclarativeanimation_p_p.h +++ b/src/declarative/util/qdeclarativeanimation_p_p.h @@ -96,7 +96,7 @@ private: }; //performs an action of type QAbstractAnimationAction -class QActionAnimation : public QAbstractAnimation +class Q_AUTOTEST_EXPORT QActionAnimation : public QAbstractAnimation { Q_OBJECT public: @@ -143,7 +143,7 @@ public: }; //animates QDeclarativeBulkValueUpdater (assumes start and end values will be reals or compatible) -class QDeclarativeBulkValueAnimator : public QVariantAnimation +class Q_AUTOTEST_EXPORT QDeclarativeBulkValueAnimator : public QVariantAnimation { Q_OBJECT public: @@ -378,6 +378,22 @@ public: QList<QDeclarativeItem*> targets; }; +class Q_AUTOTEST_EXPORT QDeclarativeAnimationPropertyUpdater : public QDeclarativeBulkValueUpdater +{ +public: + QDeclarativeStateActions actions; + int interpolatorType; //for Number/ColorAnimation + int prevInterpolatorType; //for generic + QVariantAnimation::Interpolator interpolator; + bool reverse; + bool fromSourced; + bool fromDefined; + bool *wasDeleted; + QDeclarativeAnimationPropertyUpdater() : prevInterpolatorType(0), wasDeleted(0) {} + ~QDeclarativeAnimationPropertyUpdater() { if (wasDeleted) *wasDeleted = true; } + void setValue(qreal v); +}; + QT_END_NAMESPACE #endif // QDECLARATIVEANIMATION_P_H diff --git a/src/declarative/util/qdeclarativeconnections.cpp b/src/declarative/util/qdeclarativeconnections.cpp index 808d196..b364821 100644 --- a/src/declarative/util/qdeclarativeconnections.cpp +++ b/src/declarative/util/qdeclarativeconnections.cpp @@ -72,7 +72,9 @@ public: /*! \qmlclass Connections QDeclarativeConnections \since 4.7 - \brief A Connections object describes generalized connections to signals. + \brief A Connections element describes generalized connections to signals. + + A Connections object creates a connection to a QML signal. When connecting to signals in QML, the usual way is to create an "on<Signal>" handler that reacts when a signal is received, like this: @@ -83,16 +85,16 @@ public: } \endqml - However, in some cases, it is not possible to connect to a signal in this - way, such as: + However, it is not possible to connect to a signal in this way in some + cases, such as when: \list - \i multiple connections to the same signal - \i connections outside the scope of the signal sender - \i connections to targets not defined in QML + \i Multiple connections to the same signal are required + \i Creating connections outside the scope of the signal sender + \i Connecting to targets not defined in QML \endlist - When any of these are needed, the Connections object can be used instead. + When any of these are needed, the Connections element can be used instead. For example, the above code can be changed to use a Connections object, like this: @@ -105,7 +107,7 @@ public: } \endqml - More generally, the Connections object can be a child of some other object than + More generally, the Connections object can be a child of some object other than the sender of the signal: \qml @@ -141,7 +143,7 @@ QDeclarativeConnections::~QDeclarativeConnections() \qmlproperty Object Connections::target This property holds the object that sends the signal. - If not set at all, the target defaults to be the parent of the Connections. + If this property is not set, the \c target defaults to the parent of the Connection. If set to null, no connection is made and any signal handlers are ignored until the target is not null. @@ -175,12 +177,11 @@ void QDeclarativeConnections::setTarget(QObject *obj) /*! \qmlproperty bool Connections::ignoreUnknownSignals - Normally, you will get a runtime error if you try to connect - to signals on an object which the object does not have. + Normally, a connection to a non-existent signal produces runtime errors. - By setting this flag to true, such errors are ignored. This is - useful if you intend to connect to different types of object, handling - a different set of signals for each. + If this property is set to \c true, such errors are ignored. + This is useful if you intend to connect to different types of objects, handling + a different set of signals for each object. */ bool QDeclarativeConnections::ignoreUnknownSignals() const { diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp index 7518eb7..78a3207 100644 --- a/src/declarative/util/qdeclarativelistmodel.cpp +++ b/src/declarative/util/qdeclarativelistmodel.cpp @@ -76,125 +76,41 @@ QDeclarativeListModelParser::ListInstruction *QDeclarativeListModelParser::ListM For example: - \code - ListModel { - id: fruitModel - ListElement { - name: "Apple" - cost: 2.45 - } - ListElement { - name: "Orange" - cost: 3.25 - } - ListElement { - name: "Banana" - cost: 1.95 - } - } - \endcode + \snippet doc/src/snippets/declarative/listmodel.qml 0 - Roles (properties) must begin with a lower-case letter.The above example defines a + Roles (properties) must begin with a lower-case letter. The above example defines a ListModel containing three elements, with the roles "name" and "cost". Values must be simple constants - either strings (quoted), bools (true, false), numbers, or enum values (like Text.AlignHCenter). The defined model can be used in views such as ListView: - \code - Component { - id: fruitDelegate - Item { - width: 200; height: 50 - Text { text: name } - Text { text: '$'+cost; anchors.right: parent.right } - } - } - ListView { - model: fruitModel - delegate: fruitDelegate - anchors.fill: parent - } - \endcode + \snippet doc/src/snippets/declarative/listmodel-simple.qml 0 + \dots 8 + \snippet doc/src/snippets/declarative/listmodel-simple.qml 1 + \image listmodel.png It is possible for roles to contain list data. In the example below we create a list of fruit attributes: - \code - ListModel { - id: fruitModel - ListElement { - name: "Apple" - cost: 2.45 - attributes: [ - ListElement { description: "Core" }, - ListElement { description: "Deciduous" } - ] - } - ListElement { - name: "Orange" - cost: 3.25 - attributes: [ - ListElement { description: "Citrus" } - ] - } - ListElement { - name: "Banana" - cost: 1.95 - attributes: [ - ListElement { description: "Tropical" }, - ListElement { description: "Seedless" } - ] - } - } - \endcode + \snippet doc/src/snippets/declarative/listmodel-nested.qml model + + The delegate below displays all the fruit attributes: + + \snippet doc/src/snippets/declarative/listmodel-nested.qml delegate + \image listmodel-nested.png - The delegate below will list all the fruit attributes: - \code - Component { - id: fruitDelegate - Item { - width: 200; height: 50 - Text { id: name; text: name } - Text { text: '$'+cost; anchors.right: parent.right } - Row { - anchors.top: name.bottom - spacing: 5 - Text { text: "Attributes:" } - Repeater { - model: attributes - Component { Text { text: description } } - } - } - } - } - \endcode \section2 Modifying list models The content of a ListModel may be created and modified using the clear(), - append(), and set() methods. For example: - - \code - Component { - id: fruitDelegate - Item { - width: 200; height: 50 - Text { text: name } - Text { text: '$'+cost; anchors.right: parent.right } - - // Double the price when clicked. - MouseArea { - anchors.fill: parent - onClicked: fruitModel.set(index, "cost", cost*2) - } - } - } - \endcode + append(), set() and setProperty() methods. For example: + + \snippet doc/src/snippets/declarative/listmodel-modify.qml delegate When creating content dynamically, note that the set of available properties cannot be changed - except by first clearing the model - whatever properties are first added are then the - only permitted properties in the model. + except by first clearing the model. Whatever properties are first added to the model are then the + only permitted properties in the model until it is cleared. \section2 Using threaded list models with WorkerScript @@ -214,11 +130,11 @@ QDeclarativeListModelParser::ListInstruction *QDeclarativeListModelParser::ListM \snippet examples/declarative/threading/threadedlistmodel/dataloader.js 0 The application's \tt Timer object periodically sends a message to the - worker script by calling \tt WorkerScript::sendMessage(). When this message - is received, \tt WorkerScript.onMessage() is invoked in + worker script by calling \l WorkerScript::sendMessage(). When this message + is received, \l {WorkerScript::onMessage}{WorkerScript.onMessage()} is invoked in \tt dataloader.js, which appends the current time to the list model. - Note the call to sync() from the \c WorkerScript.onMessage() handler. + Note the call to sync() from the \l {WorkerScript::onMessage}{WorkerScript.onMessage()} handler. You must call sync() or else the changes made to the list from the external thread will not be reflected in the list model in the main thread. @@ -454,7 +370,7 @@ void QDeclarativeListModel::insert(int index, const QScriptValue& valuemap) to the end of the list: \code - fruitModel.move(0,fruitModel.count-3,3) + fruitModel.move(0, fruitModel.count - 3, 3) \endcode \sa append() diff --git a/src/declarative/util/qdeclarativepackage.cpp b/src/declarative/util/qdeclarativepackage.cpp index 9617b86..b149120 100644 --- a/src/declarative/util/qdeclarativepackage.cpp +++ b/src/declarative/util/qdeclarativepackage.cpp @@ -48,17 +48,17 @@ QT_BEGIN_NAMESPACE /*! \qmlclass Package QDeclarativePackage - \brief Package provides a collection of named items + \brief Package provides a collection of named items. - The Package class is currently used in conjunction with + The Package class is used in conjunction with VisualDataModel to enable delegates with a shared context to be provided to multiple views. Any item within a Package may be assigned a name via the - \e {Package.name} attached property. + \l{Package::name}{Package.name} attached property. The example below creates a Package containing two named items; - \e list and \e grid. The third element in the package is parented to whichever + \e list and \e grid. The third element in the package (the \l Rectangle) is parented to whichever delegate it should appear in. This allows an item to move between views. @@ -70,7 +70,12 @@ QT_BEGIN_NAMESPACE \snippet examples/declarative/modelviews/package/view.qml 0 - \sa QtDeclarative + \sa {declarative/modelviews/package}{Package example}, QtDeclarative +*/ + +/*! + \qmlattachedproperty bool Package::name + This attached property holds the name of an item within a Package. */ diff --git a/src/declarative/util/qdeclarativepackage_p.h b/src/declarative/util/qdeclarativepackage_p.h index 57d9c22..6b12ef7 100644 --- a/src/declarative/util/qdeclarativepackage_p.h +++ b/src/declarative/util/qdeclarativepackage_p.h @@ -50,12 +50,6 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) -/***************************************************************************** - ***************************************************************************** - XXX Experimental - ***************************************************************************** -*****************************************************************************/ - class QDeclarativePackagePrivate; class QDeclarativePackageAttached; class Q_AUTOTEST_EXPORT QDeclarativePackage : public QObject diff --git a/src/declarative/util/qdeclarativepropertychanges.cpp b/src/declarative/util/qdeclarativepropertychanges.cpp index e98afeb..8e3ec82 100644 --- a/src/declarative/util/qdeclarativepropertychanges.cpp +++ b/src/declarative/util/qdeclarativepropertychanges.cpp @@ -91,7 +91,7 @@ QT_BEGIN_NAMESPACE \endqml By default, PropertyChanges will establish new bindings where appropriate. - For example, the following creates a new binding for myItem's height property. + For example, the following creates a new binding for myItem's \c height property. \qml PropertyChanges { @@ -500,8 +500,8 @@ QDeclarativePropertyChanges::ActionList QDeclarativePropertyChanges::actions() If explicit is set to true, any potential bindings will be interpreted as once-off assignments that occur when the state is entered. - In the following example, the addition of explicit prevents myItem.width from - being bound to parent.width. Instead, it is assigned the value of parent.width + In the following example, the addition of explicit prevents \c myItem.width from + being bound to \c parent.width. Instead, it is assigned the value of \c parent.width at the time of the state change. \qml PropertyChanges { diff --git a/src/declarative/util/qdeclarativestate.cpp b/src/declarative/util/qdeclarativestate.cpp index dc2b2cc..ae19a9c 100644 --- a/src/declarative/util/qdeclarativestate.cpp +++ b/src/declarative/util/qdeclarativestate.cpp @@ -136,12 +136,31 @@ QDeclarativeStateOperation::QDeclarativeStateOperation(QObjectPrivate &dd, QObje \since 4.7 \brief The State element defines configurations of objects and properties. - A state is specified as a set of batched changes from the default configuration. + A \e state is a set of batched changes from the default configuration. + + All items have a default state that defines the default configuration of objects + and property values. New states can be defined by adding State items to the \l {Item::states}{states} property to + allow items to switch between different configurations. These configurations + can, for example, be used to apply different sets of property values or execute + different scripts. + + The following example displays a single Rectangle. In the default state, the rectangle + is colored black. In the "clicked" state, a PropertyChanges element changes the + rectangle's color to red. Clicking within the MouseArea toggles the rectangle's state + between the default state and the "clicked" state, thus toggling the color of the + rectangle between black and red. + + \snippet doc/src/snippets/declarative/state.qml 0 + + Notice the default state is referred to using an empty string (""). + + States are commonly used together with \l {state-transitions}{Transitions} to provide + animations when state changes occur. \note setting the state of an object from within another state of the same object is not allowed. - \sa {qmlstates}{States}, {state-transitions}{Transitions}, QtDeclarative + \sa {declarative/animation/states}{states example}, {qmlstates}{States}, {state-transitions}{Transitions}, QtDeclarative */ /*! @@ -173,7 +192,7 @@ QDeclarativeState::~QDeclarativeState() /*! \qmlproperty string State::name - This property holds the name of the state + This property holds the name of the state. Each state should have a unique name. */ @@ -187,6 +206,13 @@ void QDeclarativeState::setName(const QString &n) { Q_D(QDeclarativeState); d->name = n; + d->named = true; +} + +bool QDeclarativeState::isNamed() const +{ + Q_D(const QDeclarativeState); + return d->named; } bool QDeclarativeState::isWhenKnown() const @@ -197,12 +223,12 @@ bool QDeclarativeState::isWhenKnown() const /*! \qmlproperty bool State::when - This property holds when the state should be applied + This property holds when the state should be applied. - This should be set to an expression that evaluates to true when you want the state to + This should be set to an expression that evaluates to \c true when you want the state to be applied. - If multiple states in a group have \c when clauses that evaluate to true at the same time, + If multiple states in a group have \c when clauses that evaluate to \c true at the same time, the first matching state will be applied. For example, in the following snippet \c state1 will always be selected rather than \c state2 when sharedCondition becomes \c true. @@ -229,7 +255,9 @@ void QDeclarativeState::setWhen(QDeclarativeBinding *when) /*! \qmlproperty string State::extend - This property holds the state that this state extends + This property holds the state that this state extends. + + When a state extends another state, it inherits all the changes of that state. The state being extended is treated as the base state in regards to the changes specified by the extending state. diff --git a/src/declarative/util/qdeclarativestate_p.h b/src/declarative/util/qdeclarativestate_p.h index 37b24cb..2e2ce7b 100644 --- a/src/declarative/util/qdeclarativestate_p.h +++ b/src/declarative/util/qdeclarativestate_p.h @@ -146,6 +146,7 @@ public: QString name() const; void setName(const QString &); + bool isNamed() const; /*'when' is a QDeclarativeBinding to limit state changes oscillation due to the unpredictable order of evaluation of bound expressions*/ diff --git a/src/declarative/util/qdeclarativestate_p_p.h b/src/declarative/util/qdeclarativestate_p_p.h index 4a2af0f..2ef9bb0 100644 --- a/src/declarative/util/qdeclarativestate_p_p.h +++ b/src/declarative/util/qdeclarativestate_p_p.h @@ -101,12 +101,13 @@ class QDeclarativeStatePrivate : public QObjectPrivate public: QDeclarativeStatePrivate() - : when(0), inState(false), group(0) {} + : when(0), named(false), inState(false), group(0) {} typedef QList<QDeclarativeSimpleAction> SimpleActionList; QString name; QDeclarativeBinding *when; + bool named; struct OperationGuard : public QDeclarativeGuard<QDeclarativeStateOperation> { diff --git a/src/declarative/util/qdeclarativestategroup.cpp b/src/declarative/util/qdeclarativestategroup.cpp index 9b042d7..67cd12e 100644 --- a/src/declarative/util/qdeclarativestategroup.cpp +++ b/src/declarative/util/qdeclarativestategroup.cpp @@ -91,8 +91,8 @@ public: \since 4.7 \brief The StateGroup element provides state support for non-Item elements. - Item (and all dervied elements) provides built in support for states and transitions - via its state, states and transitions properties. StateGroup provides an easy way to + Item (and all derived elements) provides built in support for states and transitions + via its \l{Item::state}{state}, \l{Item::states}{states} and \l{Item::transitions}{transitions} properties. StateGroup provides an easy way to use this support in other (non-Item-derived) elements. \qml @@ -263,7 +263,7 @@ void QDeclarativeStateGroup::componentComplete() for (int ii = 0; ii < d->states.count(); ++ii) { QDeclarativeState *state = d->states.at(ii); - if (state->name().isEmpty()) + if (!state->isNamed()) state->setName(QLatin1String("anonymousState") % QString::number(++d->unnamedCount)); } @@ -295,7 +295,7 @@ bool QDeclarativeStateGroupPrivate::updateAutoState() for (int ii = 0; ii < states.count(); ++ii) { QDeclarativeState *state = states.at(ii); if (state->isWhenKnown()) { - if (!state->name().isEmpty()) { + if (state->isNamed()) { if (state->when() && state->when()->evaluate().toBool()) { if (stateChangeDebug()) qWarning() << "Setting auto state due to:" diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp index 99f163e..51e6f99 100644 --- a/src/declarative/util/qdeclarativestateoperations.cpp +++ b/src/declarative/util/qdeclarativestateoperations.cpp @@ -172,6 +172,14 @@ void QDeclarativeParentChangePrivate::doChange(QDeclarativeItem *targetParent, Q items involved in the reparenting (i.e. items in the common ancestor tree for the original and new parent). + The example below displays a large red rectangle and a small blue rectangle, side by side. + When the \c blueRect is clicked, it changes to the "reparented" state: its parent is changed to \c redRect and it is + positioned at (10, 10) within the red rectangle, as specified in the ParentChange. + + \snippet doc/src/snippets/declarative/parentchange.qml 0 + + \image parentchange.png + You can specify at which point in a transition you want a ParentChange to occur by using a ParentAnimation. */ @@ -583,9 +591,9 @@ public: \qmlclass StateChangeScript QDeclarativeStateChangeScript \brief The StateChangeScript element allows you to run a script in a state. - StateChangeScripts are run when entering the state. You can use - ScriptAction to specify at which point in the transition - you want the StateChangeScript to be run. + A StateChangeScript is run upon entering a state. You can optionally use + ScriptAction to specify the point in the transition at which + the StateChangeScript should to be run. \qml State { @@ -687,22 +695,18 @@ QString QDeclarativeStateChangeScript::typeName() const \qmlclass AnchorChanges QDeclarativeAnchorChanges \brief The AnchorChanges element allows you to change the anchors of an item in a state. - In the following example we change the top and bottom anchors of an item: - \qml - State { - name: "reanchored" - AnchorChanges { - target: content; - anchors.top: window.top; - anchors.bottom: window.bottom - } - PropertyChanges { - target: content; - anchors.topMargin: 3 - anchors.bottomMargin: 3; - } - } - \endqml + The AnchorChanges element is used to modify the anchors of an item in a \l State. + + AnchorChanges cannot be used to modify the margins on an item. For this, use + PropertyChanges intead. + + In the following example we change the top and bottom anchors of an item + using AnchorChanges, and the top and bottom anchor margins using + PropertyChanges: + + \snippet doc/src/snippets/declarative/anchorchanges.qml 0 + + \image anchorchanges.png AnchorChanges can be animated using AnchorAnimation. \qml diff --git a/src/declarative/util/qdeclarativeview.cpp b/src/declarative/util/qdeclarativeview.cpp index 6059ad6..0414e65 100644 --- a/src/declarative/util/qdeclarativeview.cpp +++ b/src/declarative/util/qdeclarativeview.cpp @@ -131,7 +131,7 @@ class QDeclarativeViewPrivate : public QGraphicsViewPrivate, public QDeclarative Q_DECLARE_PUBLIC(QDeclarativeView) public: QDeclarativeViewPrivate() - : root(0), declarativeItemRoot(0), graphicsWidgetRoot(0), component(0), resizeMode(QDeclarativeView::SizeViewToRootObject) {} + : root(0), declarativeItemRoot(0), graphicsWidgetRoot(0), component(0), resizeMode(QDeclarativeView::SizeViewToRootObject), initialSize(0,0) {} ~QDeclarativeViewPrivate() { delete root; } void execute(); void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry); @@ -150,6 +150,7 @@ public: QBasicTimer resizetimer; QDeclarativeView::ResizeMode resizeMode; + QSize initialSize; QElapsedTimer frameTimer; void init(); @@ -586,9 +587,11 @@ void QDeclarativeView::setRootObject(QObject *obj) } if (d->root) { - QSize initialSize = d->rootObjectSize(); - if (initialSize != size()) { - resize(initialSize); + d->initialSize = d->rootObjectSize(); + if (d->initialSize != size()) { + if (!(parentWidget() && parentWidget()->layout())) { + resize(d->initialSize); + } } d->initResize(); } @@ -638,6 +641,15 @@ QSize QDeclarativeView::sizeHint() const } /*! + Returns the initial size of the root object +*/ +QSize QDeclarativeView::initialSize() const +{ + Q_D(const QDeclarativeView); + return d->initialSize; +} + +/*! Returns the view's root \l {QGraphicsObject} {item}. */ QGraphicsObject *QDeclarativeView::rootObject() const diff --git a/src/declarative/util/qdeclarativeview.h b/src/declarative/util/qdeclarativeview.h index e9cff32..cdcf134 100644 --- a/src/declarative/util/qdeclarativeview.h +++ b/src/declarative/util/qdeclarativeview.h @@ -90,6 +90,7 @@ public: QList<QDeclarativeError> errors() const; QSize sizeHint() const; + QSize initialSize() const; Q_SIGNALS: void sceneResized(QSize size); // ??? diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp index 4f9355b..4adef25 100644 --- a/src/declarative/util/qdeclarativexmllistmodel.cpp +++ b/src/declarative/util/qdeclarativexmllistmodel.cpp @@ -523,10 +523,13 @@ void QDeclarativeXmlListModelPrivate::clear_role(QDeclarativeListProperty<QDecla A XmlListModel could create a model from this data, like this: \qml + import Qt 4.7 + XmlListModel { id: xmlModel source: "http://www.mysite.com/feed.xml" query: "/rss/channel/item" + XmlRole { name: "title"; query: "title/string()" } XmlRole { name: "pubDate"; query: "pubDate/string()" } } @@ -536,7 +539,7 @@ void QDeclarativeXmlListModelPrivate::clear_role(QDeclarativeListProperty<QDecla a model item for each \c <item> in the XML document. The XmlRole objects define the - model item attributes; here, each model item will have \c title and \c pubDate + model item attributes. Here, each model item will have \c title and \c pubDate attributes that match the \c title and \c pubDate values of its corresponding \c <item>. (See \l XmlRole::query for more examples of valid XPath expressions for XmlRole.) @@ -672,11 +675,11 @@ void QDeclarativeXmlListModel::setSource(const QUrl &src) /*! \qmlproperty string XmlListModel::xml - This property holds XML text set directly. + This property holds the XML data for this model, if set. The text is assumed to be UTF-8 encoded. - If both source and xml are set, xml will be used. + If both \l source and \c xml are set, \c xml will be used. */ QString QDeclarativeXmlListModel::xml() const { @@ -733,6 +736,7 @@ void QDeclarativeXmlListModel::setQuery(const QString &query) source: "http://mysite.com/feed.xml" query: "/feed/entry" namespaceDeclarations: "declare default element namespace 'http://www.w3.org/2005/Atom';" + XmlRole { name: "title"; query: "title/string()" } } \endqml diff --git a/src/declarative/3rdparty/qlistmodelinterface.cpp b/src/declarative/util/qlistmodelinterface.cpp index 98d6a5b..98d6a5b 100644 --- a/src/declarative/3rdparty/qlistmodelinterface.cpp +++ b/src/declarative/util/qlistmodelinterface.cpp diff --git a/src/declarative/3rdparty/qlistmodelinterface_p.h b/src/declarative/util/qlistmodelinterface_p.h index 07592ad..07592ad 100644 --- a/src/declarative/3rdparty/qlistmodelinterface_p.h +++ b/src/declarative/util/qlistmodelinterface_p.h diff --git a/src/declarative/util/util.pri b/src/declarative/util/util.pri index f20bba1..04cfc68 100644 --- a/src/declarative/util/util.pri +++ b/src/declarative/util/util.pri @@ -27,7 +27,8 @@ SOURCES += \ $$PWD/qdeclarativebehavior.cpp \ $$PWD/qdeclarativefontloader.cpp \ $$PWD/qdeclarativestyledtext.cpp \ - $$PWD/qdeclarativelistmodelworkeragent.cpp + $$PWD/qdeclarativelistmodelworkeragent.cpp \ + $$PWD/qlistmodelinterface.cpp HEADERS += \ $$PWD/qdeclarativeutilmodule_p.h\ @@ -61,7 +62,8 @@ HEADERS += \ $$PWD/qdeclarativebehavior_p.h \ $$PWD/qdeclarativefontloader_p.h \ $$PWD/qdeclarativestyledtext_p.h \ - $$PWD/qdeclarativelistmodelworkeragent_p.h + $$PWD/qdeclarativelistmodelworkeragent_p.h \ + $$PWD/qlistmodelinterface_p.h contains(QT_CONFIG, xmlpatterns) { QT+=xmlpatterns diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index d6ac3aa..3db66ce 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -2437,6 +2437,9 @@ void QTextCursor::beginEditBlock() if (!d || !d->priv) return; + if (d->priv->editBlock == 0) // we are the initial edit block, store current cursor position for undo + d->priv->editBlockCursorPosition = d->position; + d->priv->beginEditBlock(); } diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp index e2bca04..f3cd481 100644 --- a/src/gui/text/qtextdocument_p.cpp +++ b/src/gui/text/qtextdocument_p.cpp @@ -192,6 +192,7 @@ QTextDocumentPrivate::QTextDocumentPrivate() initialBlockCharFormatIndex(-1) // set correctly later in init() { editBlock = 0; + editBlockCursorPosition = -1; docChangeFrom = -1; undoState = 0; @@ -967,6 +968,10 @@ int QTextDocumentPrivate::undoRedo(bool undo) editPos = -1; break; } + case QTextUndoCommand::CursorMoved: + editPos = c.pos; + editLength = 0; + break; case QTextUndoCommand::Custom: resetBlockRevision = -1; // ## TODO if (undo) @@ -1046,6 +1051,18 @@ void QTextDocumentPrivate::appendUndoItem(const QTextUndoCommand &c) if (undoState < undoStack.size()) clearUndoRedoStacks(QTextDocument::RedoStack); + if (editBlock != 0 && editBlockCursorPosition >= 0) { // we had a beginEditBlock() with a cursor position + if (c.pos != (quint32) editBlockCursorPosition) { // and that cursor position is different from the command + // generate a CursorMoved undo item + QT_INIT_TEXTUNDOCOMMAND(cc, QTextUndoCommand::CursorMoved, true, QTextUndoCommand::MoveCursor, + 0, 0, editBlockCursorPosition, 0, 0); + undoStack.append(cc); + undoState++; + editBlockCursorPosition = -1; + } + } + + if (!undoStack.isEmpty() && modified) { QTextUndoCommand &last = undoStack[undoState - 1]; @@ -1167,6 +1184,8 @@ void QTextDocumentPrivate::endEditBlock() } } + editBlockCursorPosition = -1; + finishEdit(); } diff --git a/src/gui/text/qtextdocument_p.h b/src/gui/text/qtextdocument_p.h index ac5ed3c..d1bd698 100644 --- a/src/gui/text/qtextdocument_p.h +++ b/src/gui/text/qtextdocument_p.h @@ -132,6 +132,7 @@ public: BlockAdded = 6, BlockDeleted = 7, GroupFormatChange = 8, + CursorMoved = 9, Custom = 256 }; enum Operation { @@ -315,6 +316,7 @@ private: bool modified; int editBlock; + int editBlockCursorPosition; int docChangeFrom; int docChangeOldLength; int docChangeLength; diff --git a/src/imports/particles/qdeclarativeparticles.cpp b/src/imports/particles/qdeclarativeparticles.cpp index ecc6604..630c068 100644 --- a/src/imports/particles/qdeclarativeparticles.cpp +++ b/src/imports/particles/qdeclarativeparticles.cpp @@ -241,11 +241,13 @@ void QDeclarativeParticleMotionGravity::setAcceleration(qreal accel) void QDeclarativeParticleMotionGravity::advance(QDeclarativeParticle &p, int interval) { - qreal xdiff = p.x - _xAttr; - qreal ydiff = p.y - _yAttr; + qreal xdiff = _xAttr - p.x; + qreal ydiff = _yAttr - p.y; + qreal absXdiff = qAbs(xdiff); + qreal absYdiff = qAbs(ydiff); - qreal xcomp = xdiff / (xdiff + ydiff); - qreal ycomp = ydiff / (xdiff + ydiff); + qreal xcomp = xdiff / (absXdiff + absYdiff); + qreal ycomp = ydiff / (absXdiff + absYdiff); p.x_velocity += xcomp * _accel * interval; p.y_velocity += ycomp * _accel * interval; @@ -1284,11 +1286,7 @@ void QDeclarativeParticlesPainter::paint(QPainter *p, const QStyleOptionGraphics const int myX = x() + parentItem()->x(); const int myY = y() + parentItem()->y(); -#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) QVarLengthArray<QPainter::PixmapFragment, 256> pixmapData; -#else - QVarLengthArray<QDrawPixmaps::Data, 256> pixmapData; -#endif pixmapData.resize(d->particles.count()); const QRectF sourceRect = d->image.rect(); @@ -1296,32 +1294,20 @@ void QDeclarativeParticlesPainter::paint(QPainter *p, const QStyleOptionGraphics qreal halfPHeight = sourceRect.height()/2.; for (int i = 0; i < d->particles.count(); ++i) { const QDeclarativeParticle &particle = d->particles.at(i); -#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) pixmapData[i].x = particle.x - myX + halfPWidth; pixmapData[i].y = particle.y - myY + halfPHeight; -#else - pixmapData[i].point = QPointF(particle.x - myX + halfPWidth, particle.y - myY + halfPHeight); -#endif pixmapData[i].opacity = particle.opacity; //these never change pixmapData[i].rotation = 0; pixmapData[i].scaleX = 1; pixmapData[i].scaleY = 1; -#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) pixmapData[i].sourceLeft = sourceRect.left(); pixmapData[i].sourceTop = sourceRect.top(); pixmapData[i].width = sourceRect.width(); pixmapData[i].height = sourceRect.height(); -#else - pixmapData[i].source = sourceRect; -#endif } -#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) p->drawPixmapFragments(pixmapData.data(), d->particles.count(), d->image); -#else - qDrawPixmaps(p, pixmapData.data(), d->particles.count(), d->image); -#endif } void QDeclarativeParticles::componentComplete() diff --git a/src/imports/qimportbase.pri b/src/imports/qimportbase.pri index 612ff20..0f70030 100644 --- a/src/imports/qimportbase.pri +++ b/src/imports/qimportbase.pri @@ -18,6 +18,8 @@ copy2build.output = $$QT_BUILD_TREE/imports/$$TARGETPATH/qmldir copy2build.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT} copy2build.name = COPY ${QMAKE_FILE_IN} copy2build.CONFIG += no_link +# `clean' should leave the build in a runnable state, which means it shouldn't delete qmldir +copy2build.CONFIG += no_clean QMAKE_EXTRA_COMPILERS += copy2build TARGET = $$qtLibraryTarget($$TARGET) diff --git a/src/imports/webkit/qdeclarativewebview.cpp b/src/imports/webkit/qdeclarativewebview.cpp index 9e5647f..383f1ce 100644 --- a/src/imports/webkit/qdeclarativewebview.cpp +++ b/src/imports/webkit/qdeclarativewebview.cpp @@ -1163,9 +1163,9 @@ QString QDeclarativeWebPage::chooseFile(QWebFrame *originatingFrame, const QStri } /*! - \qmlsignal WebView::alert(message) + \qmlsignal WebView::onAlert(message) - This signal is emitted when the web engine sends a JavaScript alert. The \a message is the text + This handler is called when the web engine sends a JavaScript alert. The \a message is the text to be displayed in the alert to the user. */ |