diff options
Diffstat (limited to 'src/declarative')
80 files changed, 1628 insertions, 844 deletions
diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index 872f6cb..6e07330 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -1,9 +1,19 @@ ============================================================================= -The changes below are pre Qt 4.7.0 tech preview +The changes below are pre Qt 4.7.0 RC1 TextInput - copy(), cut() and paste() functions added +Font.letterSpacing + - was percentage based. Now specified in pixels. +Item + - wantsFocus renamed to activeFocus + - forceFocus() renamed to forceActiveFocus() + - focus now returns the scoped focus (i.e. focus read/write now manipulate + the same value) +TextInput and TextEdit: + - focusOnPress renamed to activeFocusOnPress +============================================================================= The changes below are pre Qt 4.7.0 beta 2 QDeclarativeView diff --git a/src/declarative/debugger/qdeclarativedebugtrace.cpp b/src/declarative/debugger/qdeclarativedebugtrace.cpp index 5e6d5e7..b2b0c8a 100644 --- a/src/declarative/debugger/qdeclarativedebugtrace.cpp +++ b/src/declarative/debugger/qdeclarativedebugtrace.cpp @@ -78,6 +78,9 @@ void QDeclarativeDebugTrace::endRange(RangeType t) void QDeclarativeDebugTrace::addEventImpl(EventType event) { + if (!isEnabled()) + return; + QByteArray data; QDataStream ds(&data, QIODevice::WriteOnly); ds << m_timer.elapsed() << (int)Event << (int)event; @@ -86,6 +89,9 @@ void QDeclarativeDebugTrace::addEventImpl(EventType event) void QDeclarativeDebugTrace::startRangeImpl(RangeType range) { + if (!isEnabled()) + return; + QByteArray data; QDataStream ds(&data, QIODevice::WriteOnly); ds << m_timer.elapsed() << (int)RangeStart << (int)range; @@ -94,6 +100,9 @@ void QDeclarativeDebugTrace::startRangeImpl(RangeType range) void QDeclarativeDebugTrace::rangeDataImpl(RangeType range, const QUrl &u) { + if (!isEnabled()) + return; + QByteArray data; QDataStream ds(&data, QIODevice::WriteOnly); ds << m_timer.elapsed() << (int)RangeData << (int)range << (QString)u.toString(); @@ -102,6 +111,9 @@ void QDeclarativeDebugTrace::rangeDataImpl(RangeType range, const QUrl &u) void QDeclarativeDebugTrace::endRangeImpl(RangeType range) { + if (!isEnabled()) + return; + QByteArray data; QDataStream ds(&data, QIODevice::WriteOnly); ds << m_timer.elapsed() << (int)RangeEnd << (int)range; diff --git a/src/declarative/debugger/qpacketprotocol.cpp b/src/declarative/debugger/qpacketprotocol.cpp index 6241922..878f42f 100644 --- a/src/declarative/debugger/qpacketprotocol.cpp +++ b/src/declarative/debugger/qpacketprotocol.cpp @@ -422,7 +422,7 @@ QPacket::~QPacket() /*! Creates a copy of \a other. The initial stream positions are shared, but the - two packets are otherwise independant. + two packets are otherwise independent. */ QPacket::QPacket(const QPacket & other) : QDataStream(), b(other.b), buf(0) diff --git a/src/declarative/graphicsitems/qdeclarativeanchors_p.h b/src/declarative/graphicsitems/qdeclarativeanchors_p.h index 1bd7608..c929797 100644 --- a/src/declarative/graphicsitems/qdeclarativeanchors_p.h +++ b/src/declarative/graphicsitems/qdeclarativeanchors_p.h @@ -70,11 +70,11 @@ class Q_DECLARATIVE_EXPORT QDeclarativeAnchors : public QObject Q_PROPERTY(qreal margins READ margins WRITE setMargins NOTIFY marginsChanged) Q_PROPERTY(qreal leftMargin READ leftMargin WRITE setLeftMargin NOTIFY leftMarginChanged) Q_PROPERTY(qreal rightMargin READ rightMargin WRITE setRightMargin NOTIFY rightMarginChanged) - Q_PROPERTY(qreal horizontalCenterOffset READ horizontalCenterOffset WRITE setHorizontalCenterOffset NOTIFY horizontalCenterOffsetChanged()) + Q_PROPERTY(qreal horizontalCenterOffset READ horizontalCenterOffset WRITE setHorizontalCenterOffset NOTIFY horizontalCenterOffsetChanged) Q_PROPERTY(qreal topMargin READ topMargin WRITE setTopMargin NOTIFY topMarginChanged) Q_PROPERTY(qreal bottomMargin READ bottomMargin WRITE setBottomMargin NOTIFY bottomMarginChanged) - Q_PROPERTY(qreal verticalCenterOffset READ verticalCenterOffset WRITE setVerticalCenterOffset NOTIFY verticalCenterOffsetChanged()) - Q_PROPERTY(qreal baselineOffset READ baselineOffset WRITE setBaselineOffset NOTIFY baselineOffsetChanged()) + Q_PROPERTY(qreal verticalCenterOffset READ verticalCenterOffset WRITE setVerticalCenterOffset NOTIFY verticalCenterOffsetChanged) + Q_PROPERTY(qreal baselineOffset READ baselineOffset WRITE setBaselineOffset NOTIFY baselineOffsetChanged) Q_PROPERTY(QGraphicsObject *fill READ fill WRITE setFill RESET resetFill NOTIFY fillChanged) Q_PROPERTY(QGraphicsObject *centerIn READ centerIn WRITE setCenterIn RESET resetCenterIn NOTIFY centerInChanged) diff --git a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp index 44c206b..4881248 100644 --- a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp @@ -149,6 +149,8 @@ QDeclarativeBorderImage::~QDeclarativeBorderImage() \endqml The URL may be absolute, or relative to the URL of the component. + + \sa QDeclarativeImageProvider */ void QDeclarativeBorderImage::setSource(const QUrl &url) { diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp index 9af5f56..19cabdd 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp @@ -681,12 +681,15 @@ void QDeclarativeFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent if (newY < maxY && maxY - minY <= 0) newY = maxY + (newY - maxY) / 2; if (boundsBehavior == QDeclarativeFlickable::StopAtBounds && (newY > minY || newY < maxY)) { - if (newY > minY) - newY = minY; - else if (newY < maxY) + rejectY = true; + if (newY < maxY) { newY = maxY; - else - rejectY = true; + rejectY = false; + } + if (newY > minY) { + newY = minY; + rejectY = false; + } } if (!rejectY && stealMouse) { vData.move.setValue(qRound(newY)); @@ -708,12 +711,15 @@ void QDeclarativeFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent if (newX < maxX && maxX - minX <= 0) newX = maxX + (newX - maxX) / 2; if (boundsBehavior == QDeclarativeFlickable::StopAtBounds && (newX > minX || newX < maxX)) { - if (newX > minX) - newX = minX; - else if (newX < maxX) + rejectX = true; + if (newX < maxX) { newX = maxX; - else - rejectX = true; + rejectX = false; + } + if (newX > minX) { + newX = minX; + rejectX = false; + } } if (!rejectX && stealMouse) { hData.move.setValue(qRound(newX)); @@ -1214,6 +1220,7 @@ bool QDeclarativeFlickable::sendMouseEvent(QGraphicsSceneMouseEvent *event) d->handleMousePressEvent(&mouseEvent); d->captureDelayedPress(event); + stealThisEvent = d->stealMouse; // Update stealThisEvent in case changed by function call above break; case QEvent::GraphicsSceneMouseRelease: if (d->delayedPressEvent) { @@ -1234,7 +1241,6 @@ bool QDeclarativeFlickable::sendMouseEvent(QGraphicsSceneMouseEvent *event) default: break; } - stealThisEvent = d->stealMouse; // Update stealThisEvent and grabber in case changed by function calls above grabber = qobject_cast<QDeclarativeItem*>(s->mouseGrabberItem()); if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this) { d->clearDelayedPress(); @@ -1426,21 +1432,23 @@ void QDeclarativeFlickable::movementEnding() if (!d->flickingHorizontally) emit flickEnded(); } - if (d->movingHorizontally) { - d->movingHorizontally = false; - d->hMoved = false; - emit movingChanged(); - emit movingHorizontallyChanged(); - if (!d->movingVertically) - emit movementEnded(); - } - if (d->movingVertically) { - d->movingVertically = false; - d->vMoved = false; - emit movingChanged(); - emit movingVerticallyChanged(); - if (!d->movingHorizontally) - emit movementEnded(); + if (!d->pressed && !d->stealMouse) { + if (d->movingHorizontally) { + d->movingHorizontally = false; + d->hMoved = false; + emit movingChanged(); + emit movingHorizontallyChanged(); + if (!d->movingVertically) + emit movementEnded(); + } + if (d->movingVertically) { + d->movingVertically = false; + d->vMoved = false; + emit movingChanged(); + emit movingVerticallyChanged(); + if (!d->movingHorizontally) + emit movementEnded(); + } } d->hData.smoothVelocity.setValue(0); d->vData.smoothVelocity.setValue(0); diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 14a4f08..68a4c64 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -1085,13 +1085,15 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m \c portrait data directly. An improved grid view is shown below. The delegate is visually improved and is moved - into a separate \c contactDelegate component. Also, the currently selected item is highlighted - with a blue \l Rectangle using the \l highlight property, and \c focus is set to \c true - to enable keyboard navigation for the grid view. + into a separate \c contactDelegate component. \snippet doc/src/snippets/declarative/gridview/gridview.qml classdocs advanced \image gridview-highlight.png + The currently selected item is highlighted with a blue \l Rectangle using the \l highlight property, + and \c focus is set to \c true to enable keyboard navigation for the grid view. + The grid view itself is a focus scope (see \l{qmlfocus#Acquiring Focus and Focus Scopes}{the focus documentation page} for more details). + Delegates are instantiated as needed and may be destroyed at any time. State should \e never be stored in a delegate. @@ -1276,6 +1278,11 @@ void QDeclarativeGridView::setDelegate(QDeclarativeComponent *delegate) if (QDeclarativeVisualDataModel *dataModel = qobject_cast<QDeclarativeVisualDataModel*>(d->model)) { dataModel->setDelegate(delegate); if (isComponentComplete()) { + for (int i = 0; i < d->visibleItems.count(); ++i) + d->releaseItem(d->visibleItems.at(i)); + d->visibleItems.clear(); + d->releaseItem(d->currentItem); + d->currentItem = 0; refill(); d->moveReason = QDeclarativeGridViewPrivate::SetIndex; d->updateCurrent(d->currentIndex); @@ -1293,9 +1300,15 @@ void QDeclarativeGridView::setDelegate(QDeclarativeComponent *delegate) \qmlproperty int GridView::currentIndex \qmlproperty Item GridView::currentItem - \c currentIndex holds the index of the current item. - \c currentItem is the current item. Note that the position of the current item - may only be approximate until it becomes visible in the view. + The \c currentIndex property holds the index of the current item, and + \c currentItem holds the current item. + + If highlightFollowsCurrentItem is \c true, setting either of these + properties will smoothly scroll the GridView so that the current + item becomes visible. + + Note that the position of the current item + may only be approximate until it becomes visible in the view. */ int QDeclarativeGridView::currentIndex() const { @@ -1385,7 +1398,7 @@ void QDeclarativeGridView::setHighlight(QDeclarativeComponent *highlight) \qmlproperty bool GridView::highlightFollowsCurrentItem This property sets whether the highlight is managed by the view. - If this property is true, the highlight is moved smoothly + If this property is true (the default value), the highlight is moved smoothly to follow the current item. Otherwise, the highlight is not moved by the view, and any movement must be implemented by the highlight. @@ -1568,6 +1581,8 @@ void QDeclarativeGridView::setFlow(Flow flow) If this is true, key navigation that would move the current item selection past one end of the view instead wraps around and moves the selection to the other end of the view. + + By default, key navigation is not wrapped. */ bool QDeclarativeGridView::isWrapEnabled() const { diff --git a/src/declarative/graphicsitems/qdeclarativeimage.cpp b/src/declarative/graphicsitems/qdeclarativeimage.cpp index 90738c8..37736cc 100644 --- a/src/declarative/graphicsitems/qdeclarativeimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeimage.cpp @@ -66,7 +66,7 @@ QT_BEGIN_NAMESPACE \endqml \endtable - If the \l {Image::width}{width} and \l{Image::height}{height} properties are not specified, + If the \l {Item::width}{width} and \l{Item::height}{height} properties are not specified, the Image element is automatically sized to the loaded image. Image elements can be stretched and tiled using the \l fillMode property. diff --git a/src/declarative/graphicsitems/qdeclarativeimagebase.cpp b/src/declarative/graphicsitems/qdeclarativeimagebase.cpp index 67f2327..ba40443 100644 --- a/src/declarative/graphicsitems/qdeclarativeimagebase.cpp +++ b/src/declarative/graphicsitems/qdeclarativeimagebase.cpp @@ -50,6 +50,13 @@ QT_BEGIN_NAMESPACE + +/*! + \class QDeclarativeImageBase + \internal + \brief The base class for declarative images. + */ + QDeclarativeImageBase::QDeclarativeImageBase(QDeclarativeImageBasePrivate &dd, QDeclarativeItem *parent) : QDeclarativeItem(dd, parent) { diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp index 190b22c..2c295cd 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp @@ -63,11 +63,9 @@ #include <QtGui/qgraphicstransform.h> #include <qlistmodelinterface_p.h> -QT_BEGIN_NAMESPACE +#include <float.h> -#ifndef FLT_MAX -#define FLT_MAX 1E+37 -#endif +QT_BEGIN_NAMESPACE /*! \qmlclass Transform QGraphicsTransform @@ -91,7 +89,7 @@ QT_BEGIN_NAMESPACE */ /*! - \qmlclass Translate QGraphicsTranslate + \qmlclass Translate QDeclarativeTranslate \since 4.7 \brief The Translate object provides a way to move an Item without changing its x or y properties. @@ -420,12 +418,12 @@ void QDeclarativeItemKeyFilter::componentComplete() /*! - \qmlclass KeyNavigation + \qmlclass KeyNavigation QDeclarativeKeyNavigationAttached \since 4.7 \brief The KeyNavigation attached property supports key navigation by arrow keys. It is common in key-based UIs to use arrow keys to navigate - between focussed items. The KeyNavigation property provides a + between focused items. The KeyNavigation property provides a convenient way of specifying which item will gain focus when an arrow key is pressed. The following example provides key navigation for a 2x2 grid of items. @@ -513,8 +511,10 @@ QDeclarativeItem *QDeclarativeKeyNavigationAttached::left() const void QDeclarativeKeyNavigationAttached::setLeft(QDeclarativeItem *i) { Q_D(QDeclarativeKeyNavigationAttached); + if (d->left == i) + return; d->left = i; - emit changed(); + emit leftChanged(); } QDeclarativeItem *QDeclarativeKeyNavigationAttached::right() const @@ -526,8 +526,10 @@ QDeclarativeItem *QDeclarativeKeyNavigationAttached::right() const void QDeclarativeKeyNavigationAttached::setRight(QDeclarativeItem *i) { Q_D(QDeclarativeKeyNavigationAttached); + if (d->right == i) + return; d->right = i; - emit changed(); + emit rightChanged(); } QDeclarativeItem *QDeclarativeKeyNavigationAttached::up() const @@ -539,8 +541,10 @@ QDeclarativeItem *QDeclarativeKeyNavigationAttached::up() const void QDeclarativeKeyNavigationAttached::setUp(QDeclarativeItem *i) { Q_D(QDeclarativeKeyNavigationAttached); + if (d->up == i) + return; d->up = i; - emit changed(); + emit upChanged(); } QDeclarativeItem *QDeclarativeKeyNavigationAttached::down() const @@ -552,8 +556,10 @@ QDeclarativeItem *QDeclarativeKeyNavigationAttached::down() const void QDeclarativeKeyNavigationAttached::setDown(QDeclarativeItem *i) { Q_D(QDeclarativeKeyNavigationAttached); + if (d->down == i) + return; d->down = i; - emit changed(); + emit downChanged(); } QDeclarativeItem *QDeclarativeKeyNavigationAttached::tab() const @@ -565,8 +571,10 @@ QDeclarativeItem *QDeclarativeKeyNavigationAttached::tab() const void QDeclarativeKeyNavigationAttached::setTab(QDeclarativeItem *i) { Q_D(QDeclarativeKeyNavigationAttached); + if (d->tab == i) + return; d->tab = i; - emit changed(); + emit tabChanged(); } QDeclarativeItem *QDeclarativeKeyNavigationAttached::backtab() const @@ -578,8 +586,10 @@ QDeclarativeItem *QDeclarativeKeyNavigationAttached::backtab() const void QDeclarativeKeyNavigationAttached::setBacktab(QDeclarativeItem *i) { Q_D(QDeclarativeKeyNavigationAttached); + if (d->backtab == i) + return; d->backtab = i; - emit changed(); + emit backtabChanged(); } /*! @@ -714,7 +724,7 @@ void QDeclarativeKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post) } /*! - \qmlclass Keys + \qmlclass Keys QDeclarativeKeysAttached \since 4.7 \brief The Keys attached property provides key handling to Items. @@ -1388,26 +1398,6 @@ QDeclarativeKeysAttached *QDeclarativeKeysAttached::qmlAttachedProperties(QObjec */ /*! - \property QDeclarativeItem::baseline - \internal -*/ - -/*! - \property QDeclarativeItem::focus - \internal -*/ - -/*! - \property QDeclarativeItem::wantsFocus - \internal -*/ - -/*! - \property QDeclarativeItem::transformOrigin - \internal -*/ - -/*! \fn void QDeclarativeItem::childrenRectChanged(const QRectF &) \internal */ @@ -1452,7 +1442,7 @@ QDeclarativeKeysAttached *QDeclarativeKeysAttached::qmlAttachedProperties(QObjec */ /*! - \fn void QDeclarativeItem::wantsFocusChanged(bool) + \fn void QDeclarativeItem::activeFocusChanged(bool) \internal */ @@ -1534,6 +1524,9 @@ QDeclarativeItem::~QDeclarativeItem() \endqml The default transform origin is \c Item.Center. + + To set an arbitrary transform origin point use the \l Scale or \l Rotation + transform elements. */ /*! @@ -1970,6 +1963,9 @@ QVariant QDeclarativeItem::inputMethodQuery(Qt::InputMethodQuery query) const return v; } +/*! + \internal + */ void QDeclarativeItem::keyPressPreHandler(QKeyEvent *event) { Q_D(QDeclarativeItem); @@ -1980,6 +1976,9 @@ void QDeclarativeItem::keyPressPreHandler(QKeyEvent *event) d->doneEventPreHandler = true; } +/*! + \internal + */ void QDeclarativeItem::keyReleasePreHandler(QKeyEvent *event) { Q_D(QDeclarativeItem); @@ -1990,6 +1989,9 @@ void QDeclarativeItem::keyReleasePreHandler(QKeyEvent *event) d->doneEventPreHandler = true; } +/*! + \internal + */ void QDeclarativeItem::inputMethodPreHandler(QInputMethodEvent *event) { Q_D(QDeclarativeItem); @@ -2000,7 +2002,6 @@ void QDeclarativeItem::inputMethodPreHandler(QInputMethodEvent *event) d->doneEventPreHandler = true; } - /*! \internal */ @@ -2059,20 +2060,6 @@ QDeclarativeAnchorLine QDeclarativeItemPrivate::baseline() const } /*! - \qmlproperty AnchorLine Item::top - \qmlproperty AnchorLine Item::bottom - \qmlproperty AnchorLine Item::left - \qmlproperty AnchorLine Item::right - \qmlproperty AnchorLine Item::horizontalCenter - \qmlproperty AnchorLine Item::verticalCenter - \qmlproperty AnchorLine Item::baseline - - The anchor lines of the item. - - For more information see \l {anchor-layout}{Anchor Layouts}. -*/ - -/*! \qmlproperty AnchorLine Item::anchors.top \qmlproperty AnchorLine Item::anchors.bottom \qmlproperty AnchorLine Item::anchors.left @@ -2204,6 +2191,8 @@ void QDeclarativeItem::setBaselineOffset(qreal offset) } \endqml \endtable + + \sa transform, Rotation */ /*! @@ -2240,6 +2229,8 @@ void QDeclarativeItem::setBaselineOffset(qreal offset) } \endqml \endtable + + \sa transform, Scale */ /*! @@ -2377,12 +2368,12 @@ QScriptValue QDeclarativeItem::mapToItem(const QScriptValue &item, qreal x, qrea } /*! - \qmlmethod Item::forceFocus() + \qmlmethod Item::forceActiveFocus() - Force the focus on the item. - This method sets the focus on the item and makes sure that all the focus scopes higher in the object hierarchy are given focus. + Force active focus on the item. + This method sets focus on the item and makes sure that all the focus scopes higher in the object hierarchy are also given focus. */ -void QDeclarativeItem::forceFocus() +void QDeclarativeItem::forceActiveFocus() { setFocus(true); QGraphicsItem *parent = parentItem(); @@ -2419,8 +2410,19 @@ void QDeclarativeItemPrivate::focusChanged(bool flag) { Q_Q(QDeclarativeItem); if (!(flags & QGraphicsItem::ItemIsFocusScope) && parent) - emit q->wantsFocusChanged(flag); //see also QDeclarativeItemPrivate::subFocusItemChange() - emit q->focusChanged(flag); + emit q->activeFocusChanged(flag); //see also QDeclarativeItemPrivate::subFocusItemChange() + + bool inScope = false; + QGraphicsItem *p = parent; + while (p) { + if (p->flags() & QGraphicsItem::ItemIsFocusScope) { + inScope = true; + break; + } + p = p->parentItem(); + } + if (!inScope) + emit q->focusChanged(flag); } /*! \internal */ @@ -2492,7 +2494,7 @@ QDeclarativeListProperty<QDeclarativeTransition> QDeclarativeItemPrivate::transi Item { filter: [ Blur { ... }, - Relection { ... } + Reflection { ... } ... ] } @@ -2503,7 +2505,7 @@ QDeclarativeListProperty<QDeclarativeTransition> QDeclarativeItemPrivate::transi \qmlproperty bool Item::clip This property holds whether clipping is enabled. - if clipping is enabled, an item will clip its own painting, as well + If clipping is enabled, an item will clip its own painting, as well as the painting of its children, to its bounding rectangle. Non-rectangular clipping regions are not supported for performance reasons. @@ -2543,11 +2545,6 @@ QDeclarativeListProperty<QDeclarativeTransition> QDeclarativeItemPrivate::transi \sa {qmlstates}{States} */ -/*! - \property QDeclarativeItem::state - \internal -*/ - /*! \internal */ QString QDeclarativeItemPrivate::state() const { @@ -2570,11 +2567,6 @@ void QDeclarativeItemPrivate::setState(const QString &state) For more information see \l Transform. */ -/*! - \property QDeclarativeItem::transform - \internal -*/ - /*! \internal */ QDeclarativeListProperty<QGraphicsTransform> QDeclarativeItem::transform() { @@ -2707,14 +2699,14 @@ bool QDeclarativeItem::sceneEvent(QEvent *event) if (event->type() == QEvent::FocusIn || event->type() == QEvent::FocusOut) { - d->focusChanged(hasFocus()); + d->focusChanged(hasActiveFocus()); } return rv; } } /*! - \reimp + \internal Note that unlike QGraphicsItems, QDeclarativeItem::itemChange() is \e not called during initial widget polishing. Items wishing to optimize start-up construction @@ -2863,6 +2855,26 @@ void QDeclarativeItem::setSmooth(bool smooth) } /*! + \property QDeclarativeItem::focus + \internal +*/ + +/*! + \property QDeclarativeItem::transform + \internal +*/ + +/*! + \property QDeclarativeItem::transformOrigin + \internal +*/ + +/*! + \property QDeclarativeItem::activeFocus + \internal +*/ + +/*! \internal Return the width of the item */ @@ -3101,15 +3113,32 @@ void QDeclarativeItem::setSize(const QSizeF &size) } /*! - \qmlproperty bool Item::wantsFocus + \qmlproperty bool Item::activeFocus + + This property indicates whether the item has active focus. - This property indicates whether the item has has an active focus request. + An item with active focus will receive keyboard input, + or is a FocusScope ancestor of the item that will receive keyboard input. - \sa {qmlfocus}{Keyboard Focus} + Usually, activeFocus is gained by setting focus on an item and its enclosing + FocusScopes. In the following example \c input will have activeFocus. + \qml + Rectangle { + FocusScope { + focus: true + TextInput { + id: input + focus: true + } + } + } + \endqml + + \sa focus, {qmlfocus}{Keyboard Focus} */ /*! \internal */ -bool QDeclarativeItem::wantsFocus() const +bool QDeclarativeItem::hasActiveFocus() const { Q_D(const QDeclarativeItem); return focusItem() == this || @@ -3119,16 +3148,51 @@ bool QDeclarativeItem::wantsFocus() const /*! \qmlproperty bool Item::focus - This property indicates whether the item has keyboard input focus. Set this - property to true to request focus. + This property indicates whether the item has focus within the enclosing focus scope. If true, this item + will gain active focus when the enclosing focus scope gains active focus. + In the following example, \c input will be given active focus when \c scope gains active focus. + \qml + Rectangle { + FocusScope { + id: scope + TextInput { + id: input + focus: true + } + } + } + \endqml + + For the purposes of this property, the top level item in the scene + is assumed to act like a focus scope, and to always have active focus + when the scene has focus. On a practical level, that means the following + QML will give active focus to \c input on startup. + + \qml + Rectangle { + TextInput { + id: input + focus: true + } + } + \endqml - \sa {qmlfocus}{Keyboard Focus} + \sa activeFocus, {qmlfocus}{Keyboard Focus} */ /*! \internal */ bool QDeclarativeItem::hasFocus() const { - return QGraphicsItem::hasFocus(); + Q_D(const QDeclarativeItem); + QGraphicsItem *p = d->parent; + while (p) { + if (p->flags() & QGraphicsItem::ItemIsFocusScope) { + return p->focusScopeItem() == this; + } + p = p->parentItem(); + } + + return hasActiveFocus() ? true : (!QGraphicsItem::parentItem() ? true : false); } /*! \internal */ diff --git a/src/declarative/graphicsitems/qdeclarativeitem.h b/src/declarative/graphicsitems/qdeclarativeitem.h index 4f420f8..afb1f2e 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.h +++ b/src/declarative/graphicsitems/qdeclarativeitem.h @@ -87,9 +87,10 @@ class Q_DECLARATIVE_EXPORT QDeclarativeItem : public QGraphicsObject, public QDe Q_PROPERTY(qreal baselineOffset READ baselineOffset WRITE setBaselineOffset NOTIFY baselineOffsetChanged) Q_PROPERTY(bool clip READ clip WRITE setClip NOTIFY clipChanged) // ### move to QGI/QGO, NOTIFY Q_PROPERTY(bool focus READ hasFocus WRITE setFocus NOTIFY focusChanged FINAL) - Q_PROPERTY(bool wantsFocus READ wantsFocus NOTIFY wantsFocusChanged) + Q_PROPERTY(bool activeFocus READ hasActiveFocus NOTIFY activeFocusChanged) Q_PROPERTY(QDeclarativeListProperty<QGraphicsTransform> transform READ transform DESIGNABLE false FINAL) Q_PROPERTY(TransformOrigin transformOrigin READ transformOrigin WRITE setTransformOrigin NOTIFY transformOriginChanged) + Q_PROPERTY(QPointF transformOriginPoint READ transformOriginPoint) // transformOriginPoint is read-only for Item Q_PROPERTY(bool smooth READ smooth WRITE setSmooth NOTIFY smoothChanged) Q_ENUMS(TransformOrigin) Q_CLASSINFO("DefaultProperty", "data") @@ -138,7 +139,7 @@ public: QRectF boundingRect() const; virtual void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *); - bool wantsFocus() const; + bool hasActiveFocus() const; bool hasFocus() const; void setFocus(bool); @@ -147,16 +148,15 @@ 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 void forceActiveFocus(); Q_INVOKABLE QDeclarativeItem *childAt(qreal x, qreal y) const; Q_SIGNALS: - void childrenChanged(); void childrenRectChanged(const QRectF &); void baselineOffsetChanged(qreal); void stateChanged(const QString &); void focusChanged(bool); - void wantsFocusChanged(bool); + void activeFocusChanged(bool); void parentChanged(QDeclarativeItem *); void transformOriginChanged(TransformOrigin); void smoothChanged(bool); diff --git a/src/declarative/graphicsitems/qdeclarativeitem_p.h b/src/declarative/graphicsitems/qdeclarativeitem_p.h index bc5d809..fffb4f7 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem_p.h +++ b/src/declarative/graphicsitems/qdeclarativeitem_p.h @@ -285,11 +285,18 @@ public: virtual void subFocusItemChange() { if (flags & QGraphicsItem::ItemIsFocusScope || !parent) - emit q_func()->wantsFocusChanged(subFocusItem != 0); + emit q_func()->activeFocusChanged(subFocusItem != 0); //see also QDeclarativeItemPrivate::focusChanged } // Reimplemented from QGraphicsItemPrivate + virtual void focusScopeItemChange(bool isSubFocusItem) + { + emit q_func()->focusChanged(isSubFocusItem); + } + + + // Reimplemented from QGraphicsItemPrivate virtual void siblingOrderChange() { Q_Q(QDeclarativeItem); @@ -356,12 +363,12 @@ class QDeclarativeKeyNavigationAttached : public QObject, public QDeclarativeIte Q_OBJECT Q_DECLARE_PRIVATE(QDeclarativeKeyNavigationAttached) - Q_PROPERTY(QDeclarativeItem *left READ left WRITE setLeft NOTIFY changed) - Q_PROPERTY(QDeclarativeItem *right READ right WRITE setRight NOTIFY changed) - Q_PROPERTY(QDeclarativeItem *up READ up WRITE setUp NOTIFY changed) - Q_PROPERTY(QDeclarativeItem *down READ down WRITE setDown NOTIFY changed) - Q_PROPERTY(QDeclarativeItem *tab READ tab WRITE setTab NOTIFY changed) - Q_PROPERTY(QDeclarativeItem *backtab READ backtab WRITE setBacktab NOTIFY changed) + Q_PROPERTY(QDeclarativeItem *left READ left WRITE setLeft NOTIFY leftChanged) + Q_PROPERTY(QDeclarativeItem *right READ right WRITE setRight NOTIFY rightChanged) + Q_PROPERTY(QDeclarativeItem *up READ up WRITE setUp NOTIFY upChanged) + Q_PROPERTY(QDeclarativeItem *down READ down WRITE setDown NOTIFY downChanged) + Q_PROPERTY(QDeclarativeItem *tab READ tab WRITE setTab NOTIFY tabChanged) + Q_PROPERTY(QDeclarativeItem *backtab READ backtab WRITE setBacktab NOTIFY backtabChanged) Q_PROPERTY(Priority priority READ priority WRITE setPriority NOTIFY priorityChanged) Q_ENUMS(Priority) @@ -389,7 +396,12 @@ public: static QDeclarativeKeyNavigationAttached *qmlAttachedProperties(QObject *); Q_SIGNALS: - void changed(); + void leftChanged(); + void rightChanged(); + void upChanged(); + void downChanged(); + void tabChanged(); + void backtabChanged(); void priorityChanged(); private: diff --git a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp index b198077..783eff1 100644 --- a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp @@ -95,7 +95,8 @@ static QDeclarativePrivate::AutoParentResult qgraphicsobject_autoParent(QObject void QDeclarativeItemModule::defineModule() { - QDeclarativePrivate::registerAutoParentFunction(qgraphicsobject_autoParent); + QDeclarativePrivate::RegisterAutoParent autoparent = { 0, &qgraphicsobject_autoParent }; + QDeclarativePrivate::qmlregister(QDeclarativePrivate::AutoParentRegistration, &autoparent); #ifdef QT_NO_MOVIE qmlRegisterTypeNotAvailable("Qt",4,7,"AnimatedImage", @@ -141,7 +142,9 @@ void QDeclarativeItemModule::defineModule() qmlRegisterType<QGraphicsScale>("Qt",4,7,"Scale"); qmlRegisterType<QDeclarativeText>("Qt",4,7,"Text"); qmlRegisterType<QDeclarativeTextEdit>("Qt",4,7,"TextEdit"); +#ifndef QT_NO_LINEEDIT qmlRegisterType<QDeclarativeTextInput>("Qt",4,7,"TextInput"); +#endif qmlRegisterType<QDeclarativeViewSection>("Qt",4,7,"ViewSection"); qmlRegisterType<QDeclarativeVisualDataModel>("Qt",4,7,"VisualDataModel"); qmlRegisterType<QDeclarativeVisualItemModel>("Qt",4,7,"VisualItemModel"); diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 110c970..82b3e1c 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -60,7 +60,7 @@ void QDeclarativeViewSection::setProperty(const QString &property) { if (property != m_property) { m_property = property; - emit changed(); + emit propertyChanged(); } } @@ -68,7 +68,7 @@ void QDeclarativeViewSection::setCriteria(QDeclarativeViewSection::SectionCriter { if (criteria != m_criteria) { m_criteria = criteria; - emit changed(); + emit criteriaChanged(); } } @@ -575,6 +575,8 @@ FxListItem *QDeclarativeListViewPrivate::createItem(int modelIndex) listItem->attached->m_prevSection = item->attached->section(); else listItem->attached->m_prevSection = sectionAt(modelIndex-1); + } + if (modelIndex < model->count()-1) { if (FxListItem *item = visibleItem(modelIndex+1)) listItem->attached->m_nextSection = item->attached->section(); else @@ -1385,14 +1387,16 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m the delegate is able to access the model's \c name and \c number data directly. An improved list view is shown below. The delegate is visually improved and is moved - into a separate \c contactDelegate component. Also, the currently selected item is highlighted - with a blue \l Rectangle using the \l highlight property, and \c focus is set to \c true - to enable keyboard navigation for the list view. + into a separate \c contactDelegate component. \snippet doc/src/snippets/declarative/listview/listview.qml classdocs advanced \image listview-highlight.png - In a GridView, delegates are instantiated as needed and may be destroyed at any time. + The currently selected item is highlighted with a blue \l Rectangle using the \l highlight property, + and \c focus is set to \c true to enable keyboard navigation for the list view. + The list view itself is a focus scope (see \l{qmlfocus#Acquiring Focus and Focus Scopes}{the focus documentation page} for more details). + + Delegates are instantiated as needed and may be destroyed at any time. State should \e never be stored in a delegate. \note Views do not enable \e clip automatically. If the view @@ -1616,6 +1620,8 @@ void QDeclarativeListView::setDelegate(QDeclarativeComponent *delegate) for (int i = 0; i < d->visibleItems.count(); ++i) d->releaseItem(d->visibleItems.at(i)); d->visibleItems.clear(); + d->releaseItem(d->currentItem); + d->currentItem = 0; refill(); d->moveReason = QDeclarativeListViewPrivate::SetIndex; d->updateCurrent(d->currentIndex); @@ -1632,8 +1638,14 @@ void QDeclarativeListView::setDelegate(QDeclarativeComponent *delegate) \qmlproperty int ListView::currentIndex \qmlproperty Item ListView::currentItem - \c currentIndex holds the index of the current item. - \c currentItem is the current item. Note that the position of the current item + The \c currentIndex property holds the index of the current item, and + \c currentItem holds the current item. + + If highlightFollowsCurrentItem is \c true, setting either of these + properties will smoothly scroll the ListView so that the current + item becomes visible. + + Note that the position of the current item may only be approximate until it becomes visible in the view. */ int QDeclarativeListView::currentIndex() const @@ -1727,12 +1739,12 @@ void QDeclarativeListView::setHighlight(QDeclarativeComponent *highlight) \qmlproperty bool ListView::highlightFollowsCurrentItem This property holds whether the highlight is managed by the view. - If this property is true, the highlight is moved smoothly + If this property is true (the default value), the highlight is moved smoothly to follow the current item. Otherwise, the highlight is not moved by the view, and any movement must be implemented by the highlight. - Here is a highlight with its motion defined by a \l {SpringAniamtion} item: + Here is a highlight with its motion defined by a \l {SpringAnimation} item: \snippet doc/src/snippets/declarative/listview/listview.qml highlightFollowsCurrentItem @@ -1848,6 +1860,8 @@ void QDeclarativeListView::setHighlightRangeMode(HighlightRangeMode mode) \qmlproperty real ListView::spacing This property holds the spacing between items. + + The default value is 0. */ qreal QDeclarativeListView::spacing() const { @@ -1914,11 +1928,13 @@ void QDeclarativeListView::setOrientation(QDeclarativeListView::Orientation orie /*! \qmlproperty bool ListView::keyNavigationWraps - This property holds whether the list wraps key navigation. + This property holds whether the list wraps key navigation. If this is true, key navigation that would move the current item selection past the end of the list instead wraps around and moves the selection to the start of the list, and vice-versa. + + By default, key navigation is not wrapped. */ bool QDeclarativeListView::isWrapEnabled() const { diff --git a/src/declarative/graphicsitems/qdeclarativelistview_p.h b/src/declarative/graphicsitems/qdeclarativelistview_p.h index 9941040..b264861 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview_p.h +++ b/src/declarative/graphicsitems/qdeclarativelistview_p.h @@ -53,8 +53,8 @@ QT_MODULE(Declarative) class Q_AUTOTEST_EXPORT QDeclarativeViewSection : public QObject { Q_OBJECT - Q_PROPERTY(QString property READ property WRITE setProperty NOTIFY changed) - Q_PROPERTY(SectionCriteria criteria READ criteria WRITE setCriteria NOTIFY changed) + Q_PROPERTY(QString property READ property WRITE setProperty NOTIFY propertyChanged) + Q_PROPERTY(SectionCriteria criteria READ criteria WRITE setCriteria NOTIFY criteriaChanged) Q_PROPERTY(QDeclarativeComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) Q_ENUMS(SectionCriteria) public: @@ -73,7 +73,8 @@ public: QString sectionString(const QString &value); Q_SIGNALS: - void changed(); + void propertyChanged(); + void criteriaChanged(); void delegateChanged(); private: diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp index e745ca6..d28181e 100644 --- a/src/declarative/graphicsitems/qdeclarativeloader.cpp +++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp @@ -118,9 +118,9 @@ void QDeclarativeLoaderPrivate::initResize() be instantiated may be specified directly by the \l sourceComponent property, or loaded from a URL via the \l source property. - Loader can be used to delay the creation of a component until it is required. - For example, this loads "Page1.qml" as a component into the Loader element - when the \l MouseArea is clicked: + Loader can be used to delay the creation of a component until it + is required. For example, this loads "Page1.qml" as a component + into the Loader element, when the \l MouseArea is clicked: \code import Qt 4.7 @@ -159,13 +159,15 @@ void QDeclarativeLoaderPrivate::initResize() unloads "Page1.qml" and frees resources consumed by it. + Note that Loader is a focus scope. Its \c focus property must be set to \c true for any of its children + to get the \e {active focus} (see \l{qmlfocus#Acquiring Focus and Focus Scopes}{the focus documentation page} for more details). + \sa {dynamic-object-creation}{Dynamic Object Creation} */ /*! \internal \class QDeclarativeLoader - \qmlclass Loader */ /*! diff --git a/src/declarative/graphicsitems/qdeclarativemousearea.cpp b/src/declarative/graphicsitems/qdeclarativemousearea.cpp index b7b0c9e..dcdb9f6 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea.cpp +++ b/src/declarative/graphicsitems/qdeclarativemousearea.cpp @@ -46,12 +46,14 @@ #include <QGraphicsSceneMouseEvent> +#include <float.h> + QT_BEGIN_NAMESPACE static const int PressAndHoldDelay = 800; QDeclarativeDrag::QDeclarativeDrag(QObject *parent) -: QObject(parent), _target(0), _axis(XandYAxis), _xmin(0), _xmax(0), _ymin(0), _ymax(0), -_active(false) +: QObject(parent), _target(0), _axis(XandYAxis), _xmin(-FLT_MAX), _xmax(FLT_MAX), _ymin(-FLT_MAX), _ymax(FLT_MAX), +_active(false), _filterChildren(false) { } @@ -158,12 +160,24 @@ void QDeclarativeDrag::setActive(bool drag) emit activeChanged(); } +bool QDeclarativeDrag::filterChildren() const +{ + return _filterChildren; +} + +void QDeclarativeDrag::setFilterChildren(bool filter) +{ + if (_filterChildren == filter) + return; + _filterChildren = filter; + emit filterChildrenChanged(); +} + QDeclarativeMouseAreaPrivate::~QDeclarativeMouseAreaPrivate() { delete drag; } - /*! \qmlclass MouseArea QDeclarativeMouseArea \since 4.7 @@ -396,6 +410,7 @@ void QDeclarativeMouseArea::mousePressEvent(QGraphicsSceneMouseEvent *event) { Q_D(QDeclarativeMouseArea); d->moved = false; + d->stealMouse = false; if (!d->absorb) QDeclarativeItem::mousePressEvent(event); else { @@ -454,8 +469,10 @@ void QDeclarativeMouseArea::mouseMoveEvent(QGraphicsSceneMouseEvent *event) const int dragThreshold = QApplication::startDragDistance(); qreal dx = qAbs(curLocalPos.x() - startLocalPos.x()); qreal dy = qAbs(curLocalPos.y() - startLocalPos.y()); - if ((d->dragX && !(dx < dragThreshold)) || (d->dragY && !(dy < dragThreshold))) + if ((d->dragX && !(dx < dragThreshold)) || (d->dragY && !(dy < dragThreshold))) { d->drag->setActive(true); + d->stealMouse = true; + } if (!keepMouseGrab()) { if ((!d->dragY && dy < dragThreshold && d->dragX && dx > dragThreshold) || (!d->dragX && dx < dragThreshold && d->dragY && dy > dragThreshold) @@ -493,6 +510,7 @@ void QDeclarativeMouseArea::mouseMoveEvent(QGraphicsSceneMouseEvent *event) void QDeclarativeMouseArea::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { Q_D(QDeclarativeMouseArea); + d->stealMouse = false; if (!d->absorb) { QDeclarativeItem::mouseReleaseEvent(event); } else { @@ -503,6 +521,9 @@ void QDeclarativeMouseArea::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) // If we don't accept hover, we need to reset containsMouse. if (!acceptHoverEvents()) setHovered(false); + QGraphicsScene *s = scene(); + if (s && s->mouseGrabberItem() == this) + ungrabMouse(); setKeepMouseGrab(false); } } @@ -577,6 +598,71 @@ bool QDeclarativeMouseArea::sceneEvent(QEvent *event) return rv; } +bool QDeclarativeMouseArea::sendMouseEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(QDeclarativeMouseArea); + QGraphicsSceneMouseEvent mouseEvent(event->type()); + QRectF myRect = mapToScene(QRectF(0, 0, width(), height())).boundingRect(); + + QGraphicsScene *s = scene(); + QDeclarativeItem *grabber = s ? qobject_cast<QDeclarativeItem*>(s->mouseGrabberItem()) : 0; + bool stealThisEvent = d->stealMouse; + if ((stealThisEvent || myRect.contains(event->scenePos().toPoint())) && (!grabber || !grabber->keepMouseGrab())) { + mouseEvent.setAccepted(false); + for (int i = 0x1; i <= 0x10; i <<= 1) { + if (event->buttons() & i) { + Qt::MouseButton button = Qt::MouseButton(i); + mouseEvent.setButtonDownPos(button, mapFromScene(event->buttonDownPos(button))); + } + } + mouseEvent.setScenePos(event->scenePos()); + mouseEvent.setLastScenePos(event->lastScenePos()); + mouseEvent.setPos(mapFromScene(event->scenePos())); + mouseEvent.setLastPos(mapFromScene(event->lastScenePos())); + + switch(mouseEvent.type()) { + case QEvent::GraphicsSceneMouseMove: + mouseMoveEvent(&mouseEvent); + break; + case QEvent::GraphicsSceneMousePress: + mousePressEvent(&mouseEvent); + break; + case QEvent::GraphicsSceneMouseRelease: + mouseReleaseEvent(&mouseEvent); + break; + default: + break; + } + grabber = qobject_cast<QDeclarativeItem*>(s->mouseGrabberItem()); + if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this) + grabMouse(); + + return stealThisEvent; + } + if (mouseEvent.type() == QEvent::GraphicsSceneMouseRelease) { + d->stealMouse = false; + ungrabMouse(); + } + return false; +} + +bool QDeclarativeMouseArea::sceneEventFilter(QGraphicsItem *i, QEvent *e) +{ + Q_D(QDeclarativeMouseArea); + if (!d->absorb || !isVisible() || !d->drag || !d->drag->filterChildren()) + return QDeclarativeItem::sceneEventFilter(i, e); + switch (e->type()) { + case QEvent::GraphicsSceneMousePress: + case QEvent::GraphicsSceneMouseMove: + case QEvent::GraphicsSceneMouseRelease: + return sendMouseEvent(static_cast<QGraphicsSceneMouseEvent *>(e)); + default: + break; + } + + return QDeclarativeItem::sceneEventFilter(i, e); +} + void QDeclarativeMouseArea::timerEvent(QTimerEvent *event) { Q_D(QDeclarativeMouseArea); @@ -757,6 +843,7 @@ QDeclarativeDrag *QDeclarativeMouseArea::drag() \qmlproperty real MouseArea::drag.maximumX \qmlproperty real MouseArea::drag.minimumY \qmlproperty real MouseArea::drag.maximumY + \qmlproperty bool MouseArea::drag.filterChildren \c drag provides a convenient way to make an item draggable. @@ -777,6 +864,12 @@ QDeclarativeDrag *QDeclarativeMouseArea::drag() for \c rect in the above example, it cannot be dragged along the X-axis. This can be avoided by settng the anchor value to \c undefined in an \l onPressed handler. + + If \c drag.filterChildren is set to true, a drag can override descendant MouseAreas. This + enables a parent MouseArea to handle drags, for example, while descendants handle clicks: + + \snippet doc/src/snippets/declarative/mouseareadragfilter.qml dragfilter + */ QT_END_NAMESPACE diff --git a/src/declarative/graphicsitems/qdeclarativemousearea_p.h b/src/declarative/graphicsitems/qdeclarativemousearea_p.h index 4fe3fcb..0da7515 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea_p.h +++ b/src/declarative/graphicsitems/qdeclarativemousearea_p.h @@ -62,6 +62,7 @@ class Q_AUTOTEST_EXPORT QDeclarativeDrag : public QObject Q_PROPERTY(qreal minimumY READ ymin WRITE setYmin NOTIFY minimumYChanged) Q_PROPERTY(qreal maximumY READ ymax WRITE setYmax NOTIFY maximumYChanged) Q_PROPERTY(bool active READ active NOTIFY activeChanged) + Q_PROPERTY(bool filterChildren READ filterChildren WRITE setFilterChildren NOTIFY filterChildrenChanged) //### consider drag and drop public: @@ -88,6 +89,9 @@ public: bool active() const; void setActive(bool); + bool filterChildren() const; + void setFilterChildren(bool); + Q_SIGNALS: void targetChanged(); void axisChanged(); @@ -96,6 +100,7 @@ Q_SIGNALS: void minimumYChanged(); void maximumYChanged(); void activeChanged(); + void filterChildrenChanged(); private: QGraphicsObject *_target; @@ -104,7 +109,8 @@ private: qreal _xmax; qreal _ymin; qreal _ymax; - bool _active; + bool _active : 1; + bool _filterChildren: 1; Q_DISABLE_COPY(QDeclarativeDrag) }; @@ -177,6 +183,8 @@ protected: void hoverMoveEvent(QGraphicsSceneHoverEvent *event); void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); bool sceneEvent(QEvent *); + bool sendMouseEvent(QGraphicsSceneMouseEvent *event); + bool sceneEventFilter(QGraphicsItem *i, QEvent *e); void timerEvent(QTimerEvent *event); virtual void geometryChanged(const QRectF &newGeometry, diff --git a/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h b/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h index 3d7bd1e..cf9dc18 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h @@ -68,7 +68,7 @@ class QDeclarativeMouseAreaPrivate : public QDeclarativeItemPrivate public: QDeclarativeMouseAreaPrivate() : absorb(true), hovered(false), pressed(false), longPress(false), - moved(false), drag(0) + moved(false), stealMouse(false), drag(0) { } @@ -78,6 +78,7 @@ public: { Q_Q(QDeclarativeMouseArea); q->setAcceptedMouseButtons(Qt::LeftButton); + q->setFiltersChildEvents(true); } void saveEvent(QGraphicsSceneMouseEvent *event) { @@ -101,6 +102,7 @@ public: bool moved : 1; bool dragX : 1; bool dragY : 1; + bool stealMouse : 1; QDeclarativeDrag *drag; QPointF startScene; qreal startX; diff --git a/src/declarative/graphicsitems/qdeclarativepainteditem.cpp b/src/declarative/graphicsitems/qdeclarativepainteditem.cpp index 3b9b8df..a6db1fa 100644 --- a/src/declarative/graphicsitems/qdeclarativepainteditem.cpp +++ b/src/declarative/graphicsitems/qdeclarativepainteditem.cpp @@ -90,6 +90,8 @@ QT_BEGIN_NAMESPACE static int inpaint=0; static int inpaint_clearcache=0; +extern Q_GUI_EXPORT bool qt_applefontsmoothing_enabled; + /*! Marks areas of the cache that intersect with the given \a rect as dirty and in need of being refreshed. @@ -287,7 +289,14 @@ void QDeclarativePaintedItem::paint(QPainter *p, const QStyleOptionGraphicsItem QRectF target(area.x(), area.y(), area.width(), area.height()); if (!d->cachefrozen) { if (!d->imagecache[i]->dirty.isNull() && topaint.contains(d->imagecache[i]->dirty)) { +#ifdef Q_WS_MAC + bool oldSmooth = qt_applefontsmoothing_enabled; + qt_applefontsmoothing_enabled = false; +#endif QPainter qp(&d->imagecache[i]->image); +#ifdef Q_WS_MAC + qt_applefontsmoothing_enabled = oldSmooth; +#endif qp.setRenderHints(QPainter::HighQualityAntialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform, d->smoothCache); qp.translate(-area.x(), -area.y()); qp.scale(d->contentsScale,d->contentsScale); @@ -349,7 +358,14 @@ void QDeclarativePaintedItem::paint(QPainter *p, const QStyleOptionGraphicsItem if (d->fillColor.isValid()) img.fill(d->fillColor); { +#ifdef Q_WS_MAC + bool oldSmooth = qt_applefontsmoothing_enabled; + qt_applefontsmoothing_enabled = false; +#endif QPainter qp(&img); +#ifdef Q_WS_MAC + qt_applefontsmoothing_enabled = oldSmooth; +#endif qp.setRenderHints(QPainter::HighQualityAntialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform, d->smoothCache); qp.translate(-r.x(),-r.y()); diff --git a/src/declarative/graphicsitems/qdeclarativepath.cpp b/src/declarative/graphicsitems/qdeclarativepath.cpp index a904869..c48011d3 100644 --- a/src/declarative/graphicsitems/qdeclarativepath.cpp +++ b/src/declarative/graphicsitems/qdeclarativepath.cpp @@ -474,6 +474,7 @@ void QDeclarativeCurve::setX(qreal x) { if (_x != x) { _x = x; + emit xChanged(); emit changed(); } } @@ -487,6 +488,7 @@ void QDeclarativeCurve::setY(qreal y) { if (_y != y) { _y = y; + emit yChanged(); emit changed(); } } @@ -533,6 +535,13 @@ void QDeclarativeCurve::setY(qreal y) /*! \qmlproperty string PathAttribute::name the name of the attribute to change. + + This attribute will be available to the delegate as PathView.<name> + + Note that using an existing Item property name such as "opacity" as an + attribute is allowed. This is because path attributes add a new + \l{qdeclarativeintroduction.html#attached-properties} {Attached Property} + which in no way clashes with existing properties. */ /*! @@ -569,6 +578,7 @@ void QDeclarativePathAttribute::setValue(qreal value) { if (_value != value) { _value = value; + emit valueChanged(); emit changed(); } } @@ -671,6 +681,7 @@ void QDeclarativePathQuad::setControlX(qreal x) { if (_controlX != x) { _controlX = x; + emit controlXChanged(); emit changed(); } } @@ -688,6 +699,7 @@ void QDeclarativePathQuad::setControlY(qreal y) { if (_controlY != y) { _controlY = y; + emit controlYChanged(); emit changed(); } } @@ -754,6 +766,7 @@ void QDeclarativePathCubic::setControl1X(qreal x) { if (_control1X != x) { _control1X = x; + emit control1XChanged(); emit changed(); } } @@ -767,6 +780,7 @@ void QDeclarativePathCubic::setControl1Y(qreal y) { if (_control1Y != y) { _control1Y = y; + emit control1YChanged(); emit changed(); } } @@ -786,6 +800,7 @@ void QDeclarativePathCubic::setControl2X(qreal x) { if (_control2X != x) { _control2X = x; + emit control2XChanged(); emit changed(); } } @@ -799,6 +814,7 @@ void QDeclarativePathCubic::setControl2Y(qreal y) { if (_control2Y != y) { _control2Y = y; + emit control2YChanged(); emit changed(); } } diff --git a/src/declarative/graphicsitems/qdeclarativepath_p.h b/src/declarative/graphicsitems/qdeclarativepath_p.h index 001bcdf..5ab5cfd 100644 --- a/src/declarative/graphicsitems/qdeclarativepath_p.h +++ b/src/declarative/graphicsitems/qdeclarativepath_p.h @@ -68,7 +68,7 @@ class Q_AUTOTEST_EXPORT QDeclarativePathAttribute : public QDeclarativePathEleme Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) - Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY changed) + Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged) public: QDeclarativePathAttribute(QObject *parent=0) : QDeclarativePathElement(parent), _value(0) {} @@ -81,6 +81,7 @@ public: Q_SIGNALS: void nameChanged(); + void valueChanged(); private: QString _name; @@ -91,8 +92,8 @@ class Q_AUTOTEST_EXPORT QDeclarativeCurve : public QDeclarativePathElement { Q_OBJECT - Q_PROPERTY(qreal x READ x WRITE setX NOTIFY changed) - Q_PROPERTY(qreal y READ y WRITE setY NOTIFY changed) + Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged) + Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged) public: QDeclarativeCurve(QObject *parent=0) : QDeclarativePathElement(parent), _x(0), _y(0) {} @@ -104,6 +105,10 @@ public: virtual void addToPath(QPainterPath &) {} +Q_SIGNALS: + void xChanged(); + void yChanged(); + private: qreal _x; qreal _y; @@ -122,8 +127,8 @@ class Q_AUTOTEST_EXPORT QDeclarativePathQuad : public QDeclarativeCurve { Q_OBJECT - Q_PROPERTY(qreal controlX READ controlX WRITE setControlX NOTIFY changed) - Q_PROPERTY(qreal controlY READ controlY WRITE setControlY NOTIFY changed) + Q_PROPERTY(qreal controlX READ controlX WRITE setControlX NOTIFY controlXChanged) + Q_PROPERTY(qreal controlY READ controlY WRITE setControlY NOTIFY controlYChanged) public: QDeclarativePathQuad(QObject *parent=0) : QDeclarativeCurve(parent), _controlX(0), _controlY(0) {} @@ -135,6 +140,10 @@ public: void addToPath(QPainterPath &path); +Q_SIGNALS: + void controlXChanged(); + void controlYChanged(); + private: qreal _controlX; qreal _controlY; @@ -144,10 +153,10 @@ class Q_AUTOTEST_EXPORT QDeclarativePathCubic : public QDeclarativeCurve { Q_OBJECT - Q_PROPERTY(qreal control1X READ control1X WRITE setControl1X NOTIFY changed) - Q_PROPERTY(qreal control1Y READ control1Y WRITE setControl1Y NOTIFY changed) - Q_PROPERTY(qreal control2X READ control2X WRITE setControl2X NOTIFY changed) - Q_PROPERTY(qreal control2Y READ control2Y WRITE setControl2Y NOTIFY changed) + Q_PROPERTY(qreal control1X READ control1X WRITE setControl1X NOTIFY control1XChanged) + Q_PROPERTY(qreal control1Y READ control1Y WRITE setControl1Y NOTIFY control1YChanged) + Q_PROPERTY(qreal control2X READ control2X WRITE setControl2X NOTIFY control2XChanged) + Q_PROPERTY(qreal control2Y READ control2Y WRITE setControl2Y NOTIFY control2YChanged) public: QDeclarativePathCubic(QObject *parent=0) : QDeclarativeCurve(parent), _control1X(0), _control1Y(0), _control2X(0), _control2Y(0) {} @@ -165,11 +174,17 @@ public: void addToPath(QPainterPath &path); +Q_SIGNALS: + void control1XChanged(); + void control1YChanged(); + void control2XChanged(); + void control2YChanged(); + private: - int _control1X; - int _control1Y; - int _control2X; - int _control2Y; + qreal _control1X; + qreal _control1Y; + qreal _control2X; + qreal _control2Y; }; class Q_AUTOTEST_EXPORT QDeclarativePathPercent : public QDeclarativePathElement diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp index f4ebd13..06ac275 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview.cpp +++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp @@ -90,6 +90,26 @@ void QDeclarativePathViewAttached::setValue(const QByteArray &name, const QVaria m_metaobject->setValue(name, val); } + +void QDeclarativePathViewPrivate::init() +{ + Q_Q(QDeclarativePathView); + offset = 0; + q->setAcceptedMouseButtons(Qt::LeftButton); + q->setFlag(QGraphicsItem::ItemIsFocusScope); + q->setFiltersChildEvents(true); + q->connect(&tl, SIGNAL(updated()), q, SLOT(ticked())); + lastPosTime.invalidate(); + static int timelineCompletedIdx = -1; + static int movementEndingIdx = -1; + if (timelineCompletedIdx == -1) { + timelineCompletedIdx = QDeclarativeTimeLine::staticMetaObject.indexOfSignal("completed()"); + movementEndingIdx = QDeclarativePathView::staticMetaObject.indexOfSlot("movementEnding()"); + } + QMetaObject::connect(&tl, timelineCompletedIdx, + q, movementEndingIdx, Qt::DirectConnection); +} + QDeclarativeItem *QDeclarativePathViewPrivate::getItem(int modelIndex) { Q_Q(QDeclarativePathView); @@ -284,8 +304,8 @@ void QDeclarativePathViewPrivate::updateItem(QDeclarativeItem *item, qreal perce att->setValue(attr.toUtf8(), path->attributeAt(attr, percent)); } QPointF pf = path->pointAt(percent); - item->setX(qRound(pf.x() - item->width()*item->scale()/2)); - item->setY(qRound(pf.y() - item->height()*item->scale()/2)); + item->setX(qRound(pf.x() - item->width()/2)); + item->setY(qRound(pf.y() - item->height()/2)); } void QDeclarativePathViewPrivate::regenerate() @@ -314,7 +334,7 @@ void QDeclarativePathViewPrivate::regenerate() and XmlListModel, or custom model classes defined in C++ that inherit from QAbstractListModel. - A ListView has a \l model, which defines the data to be displayed, and + The view has a \l model, which defines the data to be displayed, and a \l delegate, which defines how the data should be displayed. The \l delegate is instantiated for each item on the \l path. The items may be flicked to move them along the path. @@ -333,6 +353,9 @@ void QDeclarativePathViewPrivate::regenerate() opacity of the items as they rotate. This additional code can be seen in the PathAttribute documentation.) + The \c focus can be set to \c true to enable keyboard navigation. + The path view itself is a focus scope (see \l{qmlfocus#Acquiring Focus and Focus Scopes}{the focus documentation page} for more details). + Delegates are instantiated as needed and may be destroyed at any time. State should \e never be stored in a delegate. @@ -341,7 +364,7 @@ void QDeclarativePathViewPrivate::regenerate() to set \e {clip: true} in order to have the out of view items clipped nicely. - \sa Path + \sa Path, {declarative/modelviews/pathview}{PathView example} */ QDeclarativePathView::QDeclarativePathView(QDeclarativeItem *parent) @@ -848,6 +871,61 @@ void QDeclarativePathView::setInteractive(bool interactive) } /*! + \qmlproperty bool PathView::moving + + This property holds whether the view is currently moving + due to the user either dragging or flicking the view. +*/ +bool QDeclarativePathView::isMoving() const +{ + Q_D(const QDeclarativePathView); + return d->moving; +} + +/*! + \qmlproperty bool PathView::flicking + + This property holds whether the view is currently moving + due to the user flicking the view. +*/ +bool QDeclarativePathView::isFlicking() const +{ + Q_D(const QDeclarativePathView); + return d->flicking; +} + +/*! + \qmlsignal PathView::onMovementStarted() + + This handler is called when the view begins moving due to user + interaction. +*/ + +/*! + \qmlsignal PathView::onMovementEnded() + + This handler is called when the view stops moving due to user + interaction. If a flick was generated, this handler will + be triggered once the flick stops. If a flick was not + generated, the handler will be triggered when the + user stops dragging - i.e. a mouse or touch release. +*/ + +/*! + \qmlsignal PathView::onFlickStarted() + + This handler is called when the view is flicked. A flick + starts from the point that the mouse or touch is released, + while still in motion. +*/ + +/*! + \qmlsignal PathView::onFlickEnded() + + This handler is called when the view stops moving due to a flick. +*/ + +/*! \qmlproperty Component PathView::delegate The delegate provides a template defining each item instantiated by the view. @@ -964,7 +1042,11 @@ void QDeclarativePathView::mousePressEvent(QGraphicsSceneMouseEvent *event) return; } - d->stealMouse = false; + if (d->tl.isActive() && d->flicking) + d->stealMouse = true; // If we've been flicked then steal the click. + else + d->stealMouse = false; + d->lastElapsed = 0; d->lastDist = 0; QDeclarativeItemPrivate::start(d->lastPosTime); @@ -1000,6 +1082,11 @@ void QDeclarativePathView::mouseMoveEvent(QGraphicsSceneMouseEvent *event) d->lastDist = diff; d->startPc = newPc; } + if (!d->moving) { + d->moving = true; + emit movingChanged(); + emit movementStarted(); + } } } @@ -1039,12 +1126,19 @@ void QDeclarativePathView::mouseReleaseEvent(QGraphicsSceneMouseEvent *) d->moveOffset.setValue(d->offset); d->tl.accel(d->moveOffset, velocity, accel, dist); d->tl.callback(QDeclarativeTimeLineCallback(&d->moveOffset, d->fixOffsetCallback, d)); + if (!d->flicking) { + d->flicking = true; + emit flickingChanged(); + emit flickStarted(); + } } else { d->fixOffset(); } d->lastPosTime.invalidate(); ungrabMouse(); + if (!d->tl.isActive()) + movementEnding(); } bool QDeclarativePathView::sendMouseEvent(QGraphicsSceneMouseEvent *event) @@ -1372,6 +1466,21 @@ void QDeclarativePathView::ticked() d->updateCurrent(); } +void QDeclarativePathView::movementEnding() +{ + Q_D(QDeclarativePathView); + if (d->flicking) { + d->flicking = false; + emit flickingChanged(); + emit flickEnded(); + } + if (d->moving && !d->stealMouse) { + d->moving = false; + emit movingChanged(); + emit movementEnded(); + } +} + // find the item closest to the snap position int QDeclarativePathViewPrivate::calcCurrentIndex() { diff --git a/src/declarative/graphicsitems/qdeclarativepathview_p.h b/src/declarative/graphicsitems/qdeclarativepathview_p.h index d2980c6..035a64b 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview_p.h +++ b/src/declarative/graphicsitems/qdeclarativepathview_p.h @@ -74,6 +74,9 @@ class Q_AUTOTEST_EXPORT QDeclarativePathView : public QDeclarativeItem Q_PROPERTY(qreal flickDeceleration READ flickDeceleration WRITE setFlickDeceleration NOTIFY flickDecelerationChanged) Q_PROPERTY(bool interactive READ isInteractive WRITE setInteractive NOTIFY interactiveChanged) + Q_PROPERTY(bool moving READ isMoving NOTIFY movingChanged) + Q_PROPERTY(bool flicking READ isFlicking NOTIFY flickingChanged) + Q_PROPERTY(int count READ count NOTIFY countChanged) Q_PROPERTY(QDeclarativeComponent *delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) Q_PROPERTY(int pathItemCount READ pathItemCount WRITE setPathItemCount NOTIFY pathItemCountChanged) @@ -122,6 +125,9 @@ public: bool isInteractive() const; void setInteractive(bool); + bool isMoving() const; + bool isFlicking() const; + int count() const; QDeclarativeComponent *delegate() const; @@ -151,9 +157,15 @@ Q_SIGNALS: void pathItemCountChanged(); void flickDecelerationChanged(); void interactiveChanged(); + void movingChanged(); + void flickingChanged(); void highlightChanged(); void highlightItemChanged(); void highlightMoveDurationChanged(); + void movementStarted(); + void movementEnded(); + void flickStarted(); + void flickEnded(); protected: void mousePressEvent(QGraphicsSceneMouseEvent *event); @@ -167,6 +179,7 @@ protected: private Q_SLOTS: void refill(); void ticked(); + void movementEnding(); void itemsInserted(int index, int count); void itemsRemoved(int index, int count); void itemsMoved(int,int,int); diff --git a/src/declarative/graphicsitems/qdeclarativepathview_p_p.h b/src/declarative/graphicsitems/qdeclarativepathview_p_p.h index a0d2610..9abec2e 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativepathview_p_p.h @@ -78,6 +78,7 @@ public: , lastElapsed(0), mappedRange(1.0) , stealMouse(false), ownModel(false), interactive(true), haveHighlightRange(true) , autoHighlight(true), highlightUp(false), layoutScheduled(false) + , moving(false), flicking(false) , dragMargin(0), deceleration(100) , moveOffset(this, &QDeclarativePathViewPrivate::setOffset) , firstIndex(-1), pathItems(-1), requestedIndex(-1) @@ -90,15 +91,7 @@ public: { } - void init() { - Q_Q(QDeclarativePathView); - offset = 0; - q->setAcceptedMouseButtons(Qt::LeftButton); - q->setFlag(QGraphicsItem::ItemIsFocusScope); - q->setFiltersChildEvents(true); - q->connect(&tl, SIGNAL(updated()), q, SLOT(ticked())); - lastPosTime.invalidate(); - } + void init(); void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry) { if ((newGeometry.size() != oldGeometry.size()) @@ -155,6 +148,8 @@ public: bool autoHighlight : 1; bool highlightUp : 1; bool layoutScheduled : 1; + bool moving : 1; + bool flicking : 1; QElapsedTimer lastPosTime; QPointF lastPos; qreal dragMargin; diff --git a/src/declarative/graphicsitems/qdeclarativerepeater.cpp b/src/declarative/graphicsitems/qdeclarativerepeater.cpp index 3be4014..2b268fb 100644 --- a/src/declarative/graphicsitems/qdeclarativerepeater.cpp +++ b/src/declarative/graphicsitems/qdeclarativerepeater.cpp @@ -148,7 +148,6 @@ QDeclarativeRepeaterPrivate::~QDeclarativeRepeaterPrivate() /*! \internal \class QDeclarativeRepeater - \qmlclass Repeater */ /*! diff --git a/src/declarative/graphicsitems/qdeclarativetext.cpp b/src/declarative/graphicsitems/qdeclarativetext.cpp index 9a281e5..ab2be9c 100644 --- a/src/declarative/graphicsitems/qdeclarativetext.cpp +++ b/src/declarative/graphicsitems/qdeclarativetext.cpp @@ -57,6 +57,8 @@ QT_BEGIN_NAMESPACE +extern Q_GUI_EXPORT bool qt_applefontsmoothing_enabled; + class QTextDocumentWithImageResources : public QTextDocument { Q_OBJECT @@ -301,8 +303,7 @@ QDeclarativeTextPrivate::~QDeclarativeTextPrivate() Sets the letter spacing for the font. Letter spacing changes the default spacing between individual letters in the font. - A value of 100 will keep the spacing unchanged; a value of 200 will enlarge the spacing after a character by - the width of the character itself. + A positive value increases the letter spacing by the corresponding pixels; a negative value decreases the spacing. */ /*! @@ -711,61 +712,37 @@ QRectF QDeclarativeText::boundingRect() const int x = 0; int y = 0; - // Could include font max left/right bearings to either side of rectangle. - - if (d->cache || d->style != Normal) { - switch (d->hAlign) { - case AlignLeft: - x = 0; - break; - case AlignRight: - x = w - d->imgCache.width(); - break; - case AlignHCenter: - x = (w - d->imgCache.width()) / 2; - break; - } - - switch (d->vAlign) { - case AlignTop: - y = 0; - break; - case AlignBottom: - y = h - d->imgCache.height(); - break; - case AlignVCenter: - y = (h - d->imgCache.height()) / 2; - break; - } + QSize size = d->cachedLayoutSize; + if (d->style != Normal) + size += QSize(2,2); - return QRectF(x,y,d->imgCache.width(),d->imgCache.height()); - } else { - switch (d->hAlign) { - case AlignLeft: - x = 0; - break; - case AlignRight: - x = w - d->cachedLayoutSize.width(); - break; - case AlignHCenter: - x = (w - d->cachedLayoutSize.width()) / 2; - break; - } + // Could include font max left/right bearings to either side of rectangle. - switch (d->vAlign) { - case AlignTop: - y = 0; - break; - case AlignBottom: - y = h - d->cachedLayoutSize.height(); - break; - case AlignVCenter: - y = (h - d->cachedLayoutSize.height()) / 2; - break; - } + switch (d->hAlign) { + case AlignLeft: + x = 0; + break; + case AlignRight: + x = w - size.width(); + break; + case AlignHCenter: + x = (w - size.width()) / 2; + break; + } - return QRectF(x,y,d->cachedLayoutSize.width(),d->cachedLayoutSize.height()); + switch (d->vAlign) { + case AlignTop: + y = 0; + break; + case AlignBottom: + y = h - size.height(); + break; + case AlignVCenter: + y = (h - size.height()) / 2; + break; } + + return QRectF(x,y,size.width(),size.height()); } void QDeclarativeText::geometryChanged(const QRectF &newGeometry, @@ -1028,7 +1005,14 @@ QPixmap QDeclarativeTextPrivate::wrappedTextImage(bool drawStyle) QPixmap img(size); if (!size.isEmpty()) { img.fill(Qt::transparent); +#ifdef Q_WS_MAC + bool oldSmooth = qt_applefontsmoothing_enabled; + qt_applefontsmoothing_enabled = false; +#endif QPainter p(&img); +#ifdef Q_WS_MAC + qt_applefontsmoothing_enabled = oldSmooth; +#endif drawWrappedText(&p, QPointF(0,0), drawStyle); } return img; @@ -1051,7 +1035,14 @@ QPixmap QDeclarativeTextPrivate::richTextImage(bool drawStyle) //paint text QPixmap img(size); img.fill(Qt::transparent); +#ifdef Q_WS_MAC + bool oldSmooth = qt_applefontsmoothing_enabled; + qt_applefontsmoothing_enabled = false; +#endif QPainter p(&img); +#ifdef Q_WS_MAC + qt_applefontsmoothing_enabled = oldSmooth; +#endif QAbstractTextDocumentLayout::PaintContext context; @@ -1127,6 +1118,15 @@ int QDeclarativeText::resourcesLoading() const return d->doc ? d->doc->resourcesLoading() : 0; } +/*! + \qmlproperty bool Text::clip + This property holds whether the text is clipped. + + Note that if the text does not fit in the bounding rectangle it will be abruptly chopped. + + If you want to display potentially long text in a limited space, you probably want to use \c elide instead. +*/ + void QDeclarativeText::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) { Q_D(QDeclarativeText); @@ -1146,13 +1146,10 @@ void QDeclarativeText::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWid bool needClip = clip() && (d->imgCache.width() > width() || d->imgCache.height() > height()); - if (needClip) { - p->save(); - p->setClipRect(boundingRect(), Qt::IntersectClip); - } - p->drawPixmap(br.x(), br.y(), d->imgCache); if (needClip) - p->restore(); + p->drawPixmap(0, 0, width(), height(), d->imgCache, -br.x(), -br.y(), width(), height()); + else + p->drawPixmap(br.x(), br.y(), d->imgCache); if (d->smooth) { p->setRenderHint(QPainter::Antialiasing, oldAA); @@ -1166,7 +1163,7 @@ void QDeclarativeText::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWid if (needClip) { p->save(); - p->setClipRect(boundingRect(), Qt::IntersectClip); + p->setClipRect(0, 0, width(), height(), Qt::IntersectClip); } if (d->richText) { QAbstractTextDocumentLayout::PaintContext context; diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp index f3eef23..8117676 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp @@ -202,8 +202,9 @@ QString QDeclarativeTextEdit::text() const Sets the font size in pixels. - Using this function makes the font device dependent. - Use \l font.pointSize to set the size of the font in a device independent manner. + Using this function makes the font device dependent. Use + \l{TextEdit::font.pointSize} to set the size of the font in a + device independent manner. */ /*! @@ -212,8 +213,7 @@ QString QDeclarativeTextEdit::text() const Sets the letter spacing for the font. Letter spacing changes the default spacing between individual letters in the font. - A value of 100 will keep the spacing unchanged; a value of 200 will enlarge the spacing after a character by - the width of the character itself. + A positive value increases the letter spacing by the corresponding pixels; a negative value decreases the spacing. */ /*! @@ -256,7 +256,6 @@ void QDeclarativeTextEdit::setText(const QString &text) Q_D(QDeclarativeTextEdit); if (QDeclarativeTextEdit::text() == text) return; - d->text = text; d->richText = d->format == RichText || (d->format == AutoText && Qt::mightBeRichText(text)); if (d->richText) { #ifndef QT_NO_TEXTHTMLPARSER @@ -624,7 +623,7 @@ void QDeclarativeTextEdit::moveCursorSelection(int pos) \qmlproperty bool TextEdit::cursorVisible If true the text edit shows a cursor. - This property is set and unset when the text edit gets focus, but it can also + This property is set and unset when the text edit gets active focus, but it can also be set directly (useful, for example, if a KeyProxy might forward keys to it). */ bool QDeclarativeTextEdit::isCursorVisible() const @@ -783,9 +782,9 @@ QString QDeclarativeTextEdit::selectedText() const } /*! - \qmlproperty bool TextEdit::focusOnPress + \qmlproperty bool TextEdit::activeFocusOnPress - Whether the TextEdit should gain focus on a mouse press. By default this is + Whether the TextEdit should gain active focus on a mouse press. By default this is set to true. */ bool QDeclarativeTextEdit::focusOnPress() const @@ -800,13 +799,13 @@ void QDeclarativeTextEdit::setFocusOnPress(bool on) if (d->focusOnPress == on) return; d->focusOnPress = on; - emit focusOnPressChanged(d->focusOnPress); + emit activeFocusOnPressChanged(d->focusOnPress); } /*! \qmlproperty bool TextEdit::persistentSelection - Whether the TextEdit should keep the selection visible when it loses focus to another + Whether the TextEdit should keep the selection visible when it loses active focus to another item in the scene. By default this is set to true; */ bool QDeclarativeTextEdit::persistentSelection() const @@ -1106,15 +1105,15 @@ void QDeclarativeTextEdit::mousePressEvent(QGraphicsSceneMouseEvent *event) { Q_D(QDeclarativeTextEdit); if (d->focusOnPress){ - bool hadFocus = hasFocus(); - forceFocus(); + bool hadActiveFocus = hasActiveFocus(); + forceActiveFocus(); if (d->showInputPanelOnFocus) { - if (hasFocus() && hadFocus && !isReadOnly()) { + if (hasActiveFocus() && hadActiveFocus && !isReadOnly()) { // re-open input panel on press if already focused openSoftwareInputPanel(); } } else { // show input panel on click - if (hasFocus() && !hadFocus) { + if (hasActiveFocus() && !hadActiveFocus) { d->clickCausedFocus = true; } } @@ -1291,9 +1290,11 @@ void QDeclarativeTextEditPrivate::init() void QDeclarativeTextEdit::q_textChanged() { + Q_D(QDeclarativeTextEdit); + d->text = text(); updateSize(); updateMicroFocus(); - emit textChanged(text()); + emit textChanged(d->text); } void QDeclarativeTextEdit::moveCursorDelegate() @@ -1427,10 +1428,10 @@ void QDeclarativeTextEditPrivate::updateDefaultTextOption() 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. On other platforms - the panels are automatically opened when TextEdit element gains focus. Input panels are - always closed if no editor owns focus. + the panels are automatically opened when TextEdit element gains active focus. Input panels are + always closed if no editor has active focus. - You can disable the automatic behavior by setting the property \c focusOnPress to false + You can disable the automatic behavior by setting the property \c activeFocusOnPress to false and use functions openSoftwareInputPanel() and closeSoftwareInputPanel() to implement the behavior you want. @@ -1441,12 +1442,12 @@ void QDeclarativeTextEditPrivate::updateDefaultTextOption() TextEdit { id: textEdit text: "Hello world!" - focusOnPress: false + activeFocusOnPress: false MouseArea { anchors.fill: parent onClicked: { - if (!textEdit.focus) { - textEdit.focus = true; + if (!textEdit.activeFocus) { + textEdit.forceActiveFocus(); textEdit.openSoftwareInputPanel(); } else { textEdit.focus = false; @@ -1478,10 +1479,10 @@ void QDeclarativeTextEdit::openSoftwareInputPanel() 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. On other platforms - the panels are automatically opened when TextEdit element gains focus. Input panels are - always closed if no editor owns focus. + the panels are automatically opened when TextEdit element gains active focus. Input panels are + always closed if no editor has active focus. - You can disable the automatic behavior by setting the property \c focusOnPress to false + You can disable the automatic behavior by setting the property \c activeFocusOnPress to false and use functions openSoftwareInputPanel() and closeSoftwareInputPanel() to implement the behavior you want. @@ -1492,12 +1493,12 @@ void QDeclarativeTextEdit::openSoftwareInputPanel() TextEdit { id: textEdit text: "Hello world!" - focusOnPress: false + activeFocusOnPress: false MouseArea { anchors.fill: parent onClicked: { - if (!textEdit.focus) { - textEdit.focus = true; + if (!textEdit.activeFocus) { + textEdit.forceActiveFocus(); textEdit.openSoftwareInputPanel(); } else { textEdit.focus = false; diff --git a/src/declarative/graphicsitems/qdeclarativetextedit_p.h b/src/declarative/graphicsitems/qdeclarativetextedit_p.h index 279af78..68fde3d 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextedit_p.h @@ -85,7 +85,7 @@ class Q_AUTOTEST_EXPORT QDeclarativeTextEdit : public QDeclarativePaintedItem Q_PROPERTY(int selectionStart READ selectionStart NOTIFY selectionStartChanged) Q_PROPERTY(int selectionEnd READ selectionEnd NOTIFY selectionEndChanged) Q_PROPERTY(QString selectedText READ selectedText NOTIFY selectionChanged) - Q_PROPERTY(bool focusOnPress READ focusOnPress WRITE setFocusOnPress NOTIFY focusOnPressChanged) + Q_PROPERTY(bool activeFocusOnPress READ focusOnPress WRITE setFocusOnPress NOTIFY activeFocusOnPressChanged) Q_PROPERTY(bool persistentSelection READ persistentSelection WRITE setPersistentSelection NOTIFY persistentSelectionChanged) Q_PROPERTY(qreal textMargin READ textMargin WRITE setTextMargin NOTIFY textMarginChanged) Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ inputMethodHints WRITE setInputMethodHints) @@ -216,7 +216,7 @@ Q_SIGNALS: void readOnlyChanged(bool isReadOnly); void cursorVisibleChanged(bool isCursorVisible); void cursorDelegateChanged(); - void focusOnPressChanged(bool focusIsPressed); + void activeFocusOnPressChanged(bool activeFocusOnPressed); void persistentSelectionChanged(bool isPersistentSelection); void textMarginChanged(qreal textMargin); void selectByMouseChanged(bool selectByMouse); diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index 2a5d73d..90f5a70 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -51,6 +51,8 @@ #include <QFontMetrics> #include <QPainter> +#ifndef QT_NO_LINEEDIT + QT_BEGIN_NAMESPACE /*! @@ -176,8 +178,7 @@ void QDeclarativeTextInput::setText(const QString &s) Sets the letter spacing for the font. Letter spacing changes the default spacing between individual letters in the font. - A value of 100 will keep the spacing unchanged; a value of 200 will enlarge the spacing after a character by - the width of the character itself. + A positive value increases the letter spacing by the corresponding pixels; a negative value decreases the spacing. */ /*! @@ -376,14 +377,14 @@ void QDeclarativeTextInput::setMaxLength(int ml) \qmlproperty bool TextInput::cursorVisible Set to true when the TextInput shows a cursor. - This property is set and unset when the TextInput gets focus, so that other + This property is set and unset when the TextInput gets active focus, so that other properties can be bound to whether the cursor is currently showing. As it gets set and unset automatically, when you set the value yourself you must keep in mind that your value may be overwritten. It can be set directly in script, for example if a KeyProxy might forward keys to it and you desire it to look active when this happens - (but without actually giving it the focus). + (but without actually giving it active focus). It should not be set directly on the element, like in the below QML, as the specified value will be overridden an lost on focus changes. @@ -396,7 +397,7 @@ void QDeclarativeTextInput::setMaxLength(int ml) \endcode In the above snippet the cursor will still become visible when the - TextInput gains focus. + TextInput gains active focus. */ bool QDeclarativeTextInput::isCursorVisible() const { @@ -511,9 +512,9 @@ QString QDeclarativeTextInput::selectedText() const } /*! - \qmlproperty bool TextInput::focusOnPress + \qmlproperty bool TextInput::activeFocusOnPress - Whether the TextInput should gain focus on a mouse press. By default this is + Whether the TextInput should gain active focus on a mouse press. By default this is set to true. */ bool QDeclarativeTextInput::focusOnPress() const @@ -530,7 +531,7 @@ void QDeclarativeTextInput::setFocusOnPress(bool b) d->focusOnPress = b; - emit focusOnPressChanged(d->focusOnPress); + emit activeFocusOnPressChanged(d->focusOnPress); } /*! @@ -946,15 +947,15 @@ void QDeclarativeTextInput::mousePressEvent(QGraphicsSceneMouseEvent *event) { Q_D(QDeclarativeTextInput); if(d->focusOnPress){ - bool hadFocus = hasFocus(); - forceFocus(); + bool hadActiveFocus = hasActiveFocus(); + forceActiveFocus(); if (d->showInputPanelOnFocus) { - if (hasFocus() && hadFocus && !isReadOnly()) { + if (hasActiveFocus() && hadActiveFocus && !isReadOnly()) { // re-open input panel on press if already focused openSoftwareInputPanel(); } } else { // show input panel on click - if (hasFocus() && !hadFocus) { + if (hasActiveFocus() && !hadActiveFocus) { d->clickCausedFocus = true; } } @@ -1313,10 +1314,10 @@ void QDeclarativeTextInput::moveCursorSelection(int position) 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. On other platforms - the panels are automatically opened when TextInput element gains focus. Input panels are - always closed if no editor owns focus. + the panels are automatically opened when TextInput element gains active focus. Input panels are + always closed if no editor has active focus. - . You can disable the automatic behavior by setting the property \c focusOnPress to false + . You can disable the automatic behavior by setting the property \c activeFocusOnPress to false and use functions openSoftwareInputPanel() and closeSoftwareInputPanel() to implement the behavior you want. @@ -1327,12 +1328,12 @@ void QDeclarativeTextInput::moveCursorSelection(int position) TextInput { id: textInput text: "Hello world!" - focusOnPress: false + activeFocusOnPress: false MouseArea { anchors.fill: parent onClicked: { - if (!textInput.focus) { - textInput.focus = true; + if (!textInput.activeFocus) { + textInput.forceActiveFocus() textInput.openSoftwareInputPanel(); } else { textInput.focus = false; @@ -1364,10 +1365,10 @@ void QDeclarativeTextInput::openSoftwareInputPanel() 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. On other platforms - the panels are automatically opened when TextInput element gains focus. Input panels are - always closed if no editor owns focus. + the panels are automatically opened when TextInput element gains active focus. Input panels are + always closed if no editor has active focus. - . You can disable the automatic behavior by setting the property \c focusOnPress to false + . You can disable the automatic behavior by setting the property \c activeFocusOnPress to false and use functions openSoftwareInputPanel() and closeSoftwareInputPanel() to implement the behavior you want. @@ -1378,12 +1379,12 @@ void QDeclarativeTextInput::openSoftwareInputPanel() TextInput { id: textInput text: "Hello world!" - focusOnPress: false + activeFocusOnPress: false MouseArea { anchors.fill: parent onClicked: { - if (!textInput.focus) { - textInput.focus = true; + if (!textInput.activeFocus) { + textInput.forceActiveFocus(); textInput.openSoftwareInputPanel(); } else { textInput.focus = false; @@ -1538,3 +1539,5 @@ void QDeclarativeTextInput::updateSize(bool needsRedraw) QT_END_NAMESPACE +#endif // QT_NO_LINEEDIT + diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p.h index b1862c6..06f77e5 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextinput_p.h @@ -48,6 +48,8 @@ #include <QGraphicsSceneMouseEvent> #include <QIntValidator> +#ifndef QT_NO_LINEEDIT + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -87,7 +89,7 @@ class Q_AUTOTEST_EXPORT QDeclarativeTextInput : public QDeclarativePaintedItem Q_PROPERTY(bool acceptableInput READ hasAcceptableInput NOTIFY acceptableInputChanged) Q_PROPERTY(EchoMode echoMode READ echoMode WRITE setEchoMode NOTIFY echoModeChanged) - Q_PROPERTY(bool focusOnPress READ focusOnPress WRITE setFocusOnPress NOTIFY focusOnPressChanged) + Q_PROPERTY(bool activeFocusOnPress READ focusOnPress WRITE setFocusOnPress NOTIFY activeFocusOnPressChanged) Q_PROPERTY(QString passwordCharacter READ passwordCharacter WRITE setPasswordCharacter NOTIFY passwordCharacterChanged) Q_PROPERTY(QString displayText READ displayText NOTIFY displayTextChanged) Q_PROPERTY(bool autoScroll READ autoScroll WRITE setAutoScroll NOTIFY autoScrollChanged) @@ -211,7 +213,7 @@ Q_SIGNALS: void echoModeChanged(EchoMode echoMode); void passwordCharacterChanged(); void displayTextChanged(); - void focusOnPressChanged(bool focusOnPress); + void activeFocusOnPressChanged(bool activeFocusOnPress); void autoScrollChanged(bool autoScroll); void selectByMouseChanged(bool selectByMouse); @@ -263,4 +265,6 @@ QML_DECLARE_TYPE(QRegExpValidator) QT_END_HEADER +#endif // QT_NO_LINEEDIT + #endif // QDECLARATIVETEXTINPUT_H diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h index 4ac5134..5ad6a3b 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h @@ -62,6 +62,8 @@ // // We mean it. +#ifndef QT_NO_LINEEDIT + QT_BEGIN_NAMESPACE class QDeclarativeTextInputPrivate : public QDeclarativePaintedItemPrivate @@ -132,5 +134,7 @@ public: QT_END_NAMESPACE +#endif // QT_NO_LINEEDIT + #endif diff --git a/src/declarative/graphicsitems/qdeclarativetranslate.cpp b/src/declarative/graphicsitems/qdeclarativetranslate.cpp index 17daac7..be9b3f3 100644 --- a/src/declarative/graphicsitems/qdeclarativetranslate.cpp +++ b/src/declarative/graphicsitems/qdeclarativetranslate.cpp @@ -90,7 +90,7 @@ void QDeclarativeTranslate::setX(qreal x) return; d->x = x; update(); - emit positionChanged(); + emit xChanged(); } /*! @@ -113,11 +113,11 @@ void QDeclarativeTranslate::setY(qreal y) return; d->y = y; update(); - emit positionChanged(); + emit yChanged(); } /*! - \reimp + \internal */ void QDeclarativeTranslate::applyTo(QMatrix4x4 *matrix) const { diff --git a/src/declarative/graphicsitems/qdeclarativetranslate_p.h b/src/declarative/graphicsitems/qdeclarativetranslate_p.h index 0207dce..b871518 100644 --- a/src/declarative/graphicsitems/qdeclarativetranslate_p.h +++ b/src/declarative/graphicsitems/qdeclarativetranslate_p.h @@ -56,8 +56,8 @@ class Q_AUTOTEST_EXPORT QDeclarativeTranslate : public QGraphicsTransform { Q_OBJECT - Q_PROPERTY(qreal x READ x WRITE setX NOTIFY positionChanged) - Q_PROPERTY(qreal y READ y WRITE setY NOTIFY positionChanged) + Q_PROPERTY(qreal x READ x WRITE setX NOTIFY xChanged) + Q_PROPERTY(qreal y READ y WRITE setY NOTIFY yChanged) public: QDeclarativeTranslate(QObject *parent = 0); @@ -72,7 +72,8 @@ public: void applyTo(QMatrix4x4 *matrix) const; Q_SIGNALS: - void positionChanged(); + void xChanged(); + void yChanged(); private: Q_DECLARE_PRIVATE(QDeclarativeTranslate) diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp index 786d6f9..ceb1961 100644 --- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp +++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp @@ -77,8 +77,8 @@ public: QDeclarativeVisualItemModelPrivate() : QObjectPrivate() {} static void children_append(QDeclarativeListProperty<QDeclarativeItem> *prop, QDeclarativeItem *item) { - item->QObject::setParent(prop->object); - static_cast<QDeclarativeVisualItemModelPrivate *>(prop->data)->children.append(item); + QDeclarative_setParent_noEvent(item, prop->object); + static_cast<QDeclarativeVisualItemModelPrivate *>(prop->data)->children.append(Item(item)); static_cast<QDeclarativeVisualItemModelPrivate *>(prop->data)->itemAppended(); static_cast<QDeclarativeVisualItemModelPrivate *>(prop->data)->emitChildrenChanged(); } @@ -88,12 +88,12 @@ public: } static QDeclarativeItem *children_at(QDeclarativeListProperty<QDeclarativeItem> *prop, int index) { - return static_cast<QDeclarativeVisualItemModelPrivate *>(prop->data)->children.at(index); + return static_cast<QDeclarativeVisualItemModelPrivate *>(prop->data)->children.at(index).item; } void itemAppended() { Q_Q(QDeclarativeVisualItemModel); - QDeclarativeVisualItemModelAttached *attached = QDeclarativeVisualItemModelAttached::properties(children.last()); + QDeclarativeVisualItemModelAttached *attached = QDeclarativeVisualItemModelAttached::properties(children.last().item); attached->setIndex(children.count()-1); emit q->itemsInserted(children.count()-1, 1); emit q->countChanged(); @@ -104,7 +104,25 @@ public: emit q->childrenChanged(); } - QList<QDeclarativeItem *> children; + int indexOf(QDeclarativeItem *item) const { + for (int i = 0; i < children.count(); ++i) + if (children.at(i).item == item) + return i; + return -1; + } + + class Item { + public: + Item(QDeclarativeItem *i) : item(i), ref(0) {} + + void addRef() { ++ref; } + bool deref() { return --ref == 0; } + + QDeclarativeItem *item; + int ref; + }; + + QList<Item> children; }; @@ -182,12 +200,22 @@ bool QDeclarativeVisualItemModel::isValid() const QDeclarativeItem *QDeclarativeVisualItemModel::item(int index, bool) { Q_D(QDeclarativeVisualItemModel); - return d->children.at(index); + QDeclarativeVisualItemModelPrivate::Item &item = d->children[index]; + item.addRef(); + return item.item; } -QDeclarativeVisualModel::ReleaseFlags QDeclarativeVisualItemModel::release(QDeclarativeItem *) +QDeclarativeVisualModel::ReleaseFlags QDeclarativeVisualItemModel::release(QDeclarativeItem *item) { - // Nothing to do + Q_D(QDeclarativeVisualItemModel); + int idx = d->indexOf(item); + if (idx >= 0) { + if (d->children[idx].deref()) { + if (item->scene()) + item->scene()->removeItem(item); + QDeclarative_setParent_noEvent(item, this); + } + } return 0; } @@ -206,7 +234,7 @@ QString QDeclarativeVisualItemModel::stringValue(int index, const QString &name) Q_D(QDeclarativeVisualItemModel); if (index < 0 || index >= d->children.count()) return QString(); - return QDeclarativeEngine::contextForObject(d->children.at(index))->contextProperty(name).toString(); + return QDeclarativeEngine::contextForObject(d->children.at(index).item)->contextProperty(name).toString(); } QVariant QDeclarativeVisualItemModel::evaluate(int index, const QString &expression, QObject *objectContext) @@ -216,7 +244,7 @@ QVariant QDeclarativeVisualItemModel::evaluate(int index, const QString &express return QVariant(); QDeclarativeContext *ccontext = qmlContext(this); QDeclarativeContext *ctxt = new QDeclarativeContext(ccontext); - ctxt->setContextObject(d->children.at(index)); + ctxt->setContextObject(d->children.at(index).item); QDeclarativeExpression e(ctxt, objectContext, expression); QVariant value = e.evaluate(); delete ctxt; @@ -226,7 +254,7 @@ QVariant QDeclarativeVisualItemModel::evaluate(int index, const QString &express int QDeclarativeVisualItemModel::indexOf(QDeclarativeItem *item, QObject *) const { Q_D(const QDeclarativeVisualItemModel); - return d->children.indexOf(item); + return d->indexOf(item); } QDeclarativeVisualItemModelAttached *QDeclarativeVisualItemModel::qmlAttachedProperties(QObject *obj) @@ -416,6 +444,9 @@ public: int propForRole(int) const; void setValue(int, const QVariant &); + bool hasValue(int id) const { + return m_meta->hasValue(id); + } void ensureProperties(); @@ -1089,6 +1120,11 @@ QString QDeclarativeVisualDataModel::stringValue(int index, const QString &name) if (d->m_visualItemModel) return d->m_visualItemModel->stringValue(index, name); + if ((!d->m_listModelInterface || !d->m_abstractItemModel) && d->m_listAccessor) { + if (QObject *object = d->m_listAccessor->at(index).value<QObject*>()) + return object->property(name.toUtf8()).toString(); + } + if ((!d->m_listModelInterface && !d->m_abstractItemModel) || !d->m_delegate) return QString(); @@ -1183,11 +1219,13 @@ void QDeclarativeVisualDataModel::_q_itemsChanged(int index, int count, int role = roles.at(roleIdx); int propId = data->propForRole(role); if (propId != -1) { - if (d->m_listModelInterface) { - data->setValue(propId, d->m_listModelInterface->data(idx, QList<int>() << role).value(role)); - } else if (d->m_abstractItemModel) { - QModelIndex index = d->m_abstractItemModel->index(idx, 0, d->m_root); - data->setValue(propId, d->m_abstractItemModel->data(index, role)); + if (data->hasValue(propId)) { + if (d->m_listModelInterface) { + data->setValue(propId, d->m_listModelInterface->data(idx, QList<int>() << role).value(role)); + } else if (d->m_abstractItemModel) { + QModelIndex index = d->m_abstractItemModel->index(idx, 0, d->m_root); + data->setValue(propId, d->m_abstractItemModel->data(index, role)); + } } } else { QString roleName; diff --git a/src/declarative/qml/parser/qdeclarativejslexer.cpp b/src/declarative/qml/parser/qdeclarativejslexer.cpp index fcaaece..65a6af2 100644 --- a/src/declarative/qml/parser/qdeclarativejslexer.cpp +++ b/src/declarative/qml/parser/qdeclarativejslexer.cpp @@ -103,7 +103,7 @@ Lexer::Lexer(Engine *eng, bool tokenizeComments) prohibitAutomaticSemicolon(false), tokenizeComments(tokenizeComments) { - driver->setLexer(this); + if (driver) driver->setLexer(this); // allocate space for read buffers buffer8 = new char[size8]; buffer16 = new QChar[size16]; @@ -677,9 +677,9 @@ int Lexer::lex() setDone(Other); } else state = Start; - driver->addComment(startpos, tokenLength(), startlineno, startcolumn); + if (driver) driver->addComment(startpos, tokenLength(), startlineno, startcolumn); } else if (current == 0) { - driver->addComment(startpos, tokenLength(), startlineno, startcolumn); + if (driver) driver->addComment(startpos, tokenLength(), startlineno, startcolumn); setDone(Eof); } @@ -689,14 +689,14 @@ int Lexer::lex() setDone(Bad); err = UnclosedComment; errmsg = QCoreApplication::translate("QDeclarativeParser", "Unclosed comment at end of file"); - driver->addComment(startpos, tokenLength(), startlineno, startcolumn); + if (driver) driver->addComment(startpos, tokenLength(), startlineno, startcolumn); } else if (isLineTerminator()) { shiftWindowsLineBreak(); yylineno++; } else if (current == '*' && next1 == '/') { state = Start; shift(1); - driver->addComment(startpos, tokenLength(), startlineno, startcolumn); + if (driver) driver->addComment(startpos, tokenLength(), startlineno, startcolumn); } break; diff --git a/src/declarative/qml/qdeclarative.h b/src/declarative/qml/qdeclarative.h index 53ff51c..c6b64ae 100644 --- a/src/declarative/qml/qdeclarative.h +++ b/src/declarative/qml/qdeclarative.h @@ -116,7 +116,7 @@ int qmlRegisterType() 0 }; - return QDeclarativePrivate::registerType(type); + return QDeclarativePrivate::qmlregister(QDeclarativePrivate::TypeRegistration, &type); } int qmlRegisterTypeNotAvailable(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& message); @@ -151,7 +151,7 @@ int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMin 0 }; - return QDeclarativePrivate::registerType(type); + return QDeclarativePrivate::qmlregister(QDeclarativePrivate::TypeRegistration, &type); } template<typename T> @@ -184,7 +184,7 @@ int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const c 0 }; - return QDeclarativePrivate::registerType(type); + return QDeclarativePrivate::qmlregister(QDeclarativePrivate::TypeRegistration, &type); } template<typename T, typename E> @@ -217,7 +217,7 @@ int qmlRegisterExtendedType() 0 }; - return QDeclarativePrivate::registerType(type); + return QDeclarativePrivate::qmlregister(QDeclarativePrivate::TypeRegistration, &type); } template<typename T, typename E> @@ -258,7 +258,7 @@ int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor, 0 }; - return QDeclarativePrivate::registerType(type); + return QDeclarativePrivate::qmlregister(QDeclarativePrivate::TypeRegistration, &type); } template<typename T> @@ -278,7 +278,7 @@ int qmlRegisterInterface(const char *typeName) qobject_interface_iid<T *>() }; - return QDeclarativePrivate::registerType(interface); + return QDeclarativePrivate::qmlregister(QDeclarativePrivate::InterfaceRegistration, &interface); } template<typename T> @@ -312,7 +312,7 @@ int qmlRegisterCustomType(const char *uri, int versionMajor, int versionMinor, parser }; - return QDeclarativePrivate::registerType(type); + return QDeclarativePrivate::qmlregister(QDeclarativePrivate::TypeRegistration, &type); } class QDeclarativeContext; diff --git a/src/declarative/qml/qdeclarativecompiler.cpp b/src/declarative/qml/qdeclarativecompiler.cpp index 23307c9..ba757fc 100644 --- a/src/declarative/qml/qdeclarativecompiler.cpp +++ b/src/declarative/qml/qdeclarativecompiler.cpp @@ -240,7 +240,7 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop, if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: color expected")); } break; -#ifndef QT_NO_TEXTDATE +#ifndef QT_NO_DATESTRING case QVariant::Date: { bool ok; @@ -262,7 +262,7 @@ bool QDeclarativeCompiler::testLiteralAssignment(const QMetaProperty &prop, if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: datetime expected")); } break; -#endif // QT_NO_TEXTDATE +#endif // QT_NO_DATESTRING case QVariant::Point: case QVariant::PointF: { @@ -416,7 +416,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, instr.storeColor.value = c.rgba(); } break; -#ifndef QT_NO_TEXTDATE +#ifndef QT_NO_DATESTRING case QVariant::Date: { QDate d = QDeclarativeStringConverters::dateFromString(string); @@ -450,7 +450,7 @@ void QDeclarativeCompiler::genLiteralAssignment(const QMetaProperty &prop, instr.storeDateTime.valueIndex = index; } break; -#endif // QT_NO_TEXTDATE +#endif // QT_NO_DATESTRING case QVariant::Point: case QVariant::PointF: { @@ -1070,6 +1070,7 @@ void QDeclarativeCompiler::genObjectBody(QDeclarativeParser::Object *obj) store.storeSignal.value = output->indexForString(v->value.asScript().trimmed()); store.storeSignal.context = ctxt.stack; + store.storeSignal.name = output->indexForByteArray(prop->name); output->bytecode << store; } @@ -2765,6 +2766,7 @@ bool QDeclarativeCompiler::completeComponentBuild() bool isSharable = sharableTest.isSharable(expression); QDeclarativeRewrite::RewriteBinding rewriteBinding; + rewriteBinding.setName('$'+binding.property->name); expression = rewriteBinding(expression); quint32 length = expression.length(); diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index 36c4b49..1d48b1a 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -115,24 +115,10 @@ class QByteArray; a small component within a QML file, or for defining a component that logically belongs with other QML components within a file. - For example, here is a component that is used by multiple \l Loader objects: + For example, here is a component that is used by multiple \l Loader objects. + It contains a top level \l Rectangle item: - \qml - Item { - Component { - id: redSquare - - Rectangle { - color: "red" - width: 10 - height: 10 - } - } - - Loader { sourceComponent: redSquare } - Loader { sourceComponent: redSquare; x: 20 } - } - \endqml + \snippet doc/src/snippets/declarative/component.qml 0 Notice that while a \l Rectangle by itself would be automatically rendered and displayed, this is not the case for the above rectangle @@ -141,12 +127,16 @@ class QByteArray; file, and is not loaded until requested (in this case, by the two \l Loader objects). + A Component cannot contain anything other + than an \c id and a single top level item. While the \c id is optional, + the top level item is not; you cannot define an empty component. + The Component element is commonly used to provide graphical components for views. For example, the ListView::delegate property requires a Component to specify how each list item is to be displayed. - Component objects can also be dynamically generated using - \l{Qt::createComponent}{Qt.createComponent()}. + Component objects can also be dynamically created using + \l{QML:Qt::createComponent()}{Qt.createComponent()}. */ /*! @@ -607,6 +597,9 @@ QDeclarativeComponent::QDeclarativeComponent(QDeclarativeComponentPrivate &dd, Q 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. + + Dynamically created instances can be deleted with the \c destroy() method. + See \l {Dynamic Object Management} for more information. */ /*! diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 97ef99c..e8cb36e 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -115,22 +115,55 @@ QT_BEGIN_NAMESPACE /*! \qmlclass QtObject QObject \since 4.7 - \brief The QtObject element is the most basic element in QML + \brief The QtObject element is the most basic element in QML. The QtObject element is a non-visual element which contains only the - objectName property. It is useful for when you need an extremely - lightweight element to place your own custom properties in. + objectName property. + + It can be useful to create a QtObject if you need an extremely + lightweight element to enclose a set of custom properties: + + \snippet doc/src/snippets/declarative/qtobject.qml 0 It can also be useful for C++ integration, as it is just a plain QObject. See the QObject documentation for further details. */ /*! - \qmlproperty string QtObject::objectName - This property allows you to give a name to this specific object instance. + \qmlproperty string QML:QtObject::objectName + This property holds the QObject::objectName for this specific object instance. + + This allows a C++ application to locate an item within a QML component + using the QObject::findChild() method. For example, the following C++ + application locates the child \l Rectangle item and dynamically changes its + \c color value: + + \qml + // MyRect.qml + + import Qt 4.7 + + Item { + width: 200; height: 200 + + Rectangle { + anchors.fill: parent + color: "red" + objectName: "myRect" + } + } + \endqml + + \code + // main.cpp + + QDeclarativeView view; + view.setSource(QUrl::fromLocalFile("MyRect.qml")); + view.show(); - See \l{scripting.html#accessing-child-qobjects}{Accessing Child QObjects} - in the scripting documentation for details how objectName can be used from - scripts. + QDeclarativeItem *item = view.rootObject()->findChild<QDeclarativeItem*>("myRect"); + if (item) + item->setProperty("color", QColor(Qt::yellow)); + \endcode */ struct StaticQtMetaObject : public QObject @@ -195,7 +228,7 @@ There are also string based constructors for these types. See \l{qdeclarativebas \section1 Date/Time Formatters -The Qt object contains several functions for formatting dates and times. +The Qt object contains several functions for formatting QDateTime, QDate and QTime values. \list \o \l{QML:Qt::formatDateTime}{string Qt.formatDateTime(datetime date, variant format)} @@ -237,8 +270,8 @@ QDeclarativeEnginePrivate::QDeclarativeEnginePrivate(QDeclarativeEngine *e) } /*! -\qmlmethod url Qt::resolvedUrl(url) -Returns \c url resolved relative to the URL of the caller. + \qmlmethod url Qt::resolvedUrl(url) + Returns \c url resolved relative to the URL of the caller. */ QUrl QDeclarativeScriptEngine::resolvedUrl(QScriptContext *context, const QUrl& url) { @@ -268,7 +301,9 @@ QDeclarativeScriptEngine::QDeclarativeScriptEngine(QDeclarativeEnginePrivate *pr + QDir::separator() + QLatin1String("OfflineStorage"); #endif +#ifndef QT_NO_XMLSTREAMREADER qt_add_qmlxmlhttprequest(this); +#endif qt_add_qmlsqldatabase(this); // XXX A Multimedia "Qt.Sound" class also needs to be made available, // XXX but we don't want a dependency in that cirection. @@ -296,7 +331,7 @@ QDeclarativeScriptEngine::QDeclarativeScriptEngine(QDeclarativeEnginePrivate *pr qtObject.setProperty(QLatin1String("tint"), newFunction(QDeclarativeEnginePrivate::tint, 2)); } -#ifndef QT_NO_TEXTDATE +#ifndef QT_NO_DATESTRING //date/time formatting qtObject.setProperty(QLatin1String("formatDate"),newFunction(QDeclarativeEnginePrivate::formatDate, 2)); qtObject.setProperty(QLatin1String("formatTime"),newFunction(QDeclarativeEnginePrivate::formatTime, 2)); @@ -545,9 +580,9 @@ void QDeclarativeEngine::clearComponentCache() component instances should be added to sub-contexts parented to the root context. */ -QDeclarativeContext *QDeclarativeEngine::rootContext() +QDeclarativeContext *QDeclarativeEngine::rootContext() const { - Q_D(QDeclarativeEngine); + Q_D(const QDeclarativeEngine); return d->rootContext; } @@ -1071,27 +1106,23 @@ QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QUrl& url) \qmlmethod object Qt::createComponent(url) Returns a \l Component object created using the QML file at the specified \a url, -or \c null if there was an error in creating the component. +or \c null if an empty string was given. + +The returned component's \l Component::status property indicates whether the +component was successfully created. If the status is \c Component.Error, +see \l Component::errorString() for an error description. Call \l {Component::createObject()}{Component.createObject()} on the returned component to create an object instance of the component. -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 -\snippet doc/src/snippets/declarative/componentCreation.js 1 +For example: -If you are certain the files will be local, you could simplify to: +\snippet doc/src/snippets/declarative/createComponent-simple.qml 0 -\snippet doc/src/snippets/declarative/componentCreation.js 2 +See \l {Dynamic Object Management} for more information on using this function. To create a QML object from an arbitrary string of QML (instead of a file), use \l{QML:Qt::createQmlObject()}{Qt.createQmlObject()}. - -\sa {Dynamic Object Management} */ QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, QScriptEngine *engine) @@ -1140,7 +1171,7 @@ Note that this function returns immediately, and therefore may not work if the \a qml string loads new components (that is, external QML files that have not yet been loaded). If this is the case, consider using \l{QML:Qt::createComponent()}{Qt.createComponent()} instead. -\sa {Dynamic Object Management} +See \l {Dynamic Object Management} for more information on using this function. */ QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QScriptEngine *engine) @@ -1265,7 +1296,7 @@ QScriptValue QDeclarativeEnginePrivate::vector3d(QScriptContext *ctxt, QScriptEn \qmlmethod string Qt::formatDate(datetime date, variant format) Returns the string representation of \c date, formatted according to \c format. */ -#ifndef QT_NO_TEXTDATE +#ifndef QT_NO_DATESTRING QScriptValue QDeclarativeEnginePrivate::formatDate(QScriptContext*ctxt, QScriptEngine*engine) { int argCount = ctxt->argumentCount(); @@ -1406,7 +1437,7 @@ QScriptValue QDeclarativeEnginePrivate::formatDateTime(QScriptContext*ctxt, QScr } return engine->newVariant(qVariantFromValue(date.toString(enumFormat))); } -#endif // QT_NO_TEXTDATE +#endif // QT_NO_DATESTRING /*! \qmlmethod color Qt::rgba(real red, real green, real blue, real alpha) diff --git a/src/declarative/qml/qdeclarativeengine.h b/src/declarative/qml/qdeclarativeengine.h index 01487f5..d971d80 100644 --- a/src/declarative/qml/qdeclarativeengine.h +++ b/src/declarative/qml/qdeclarativeengine.h @@ -74,7 +74,7 @@ public: QDeclarativeEngine(QObject *p = 0); virtual ~QDeclarativeEngine(); - QDeclarativeContext *rootContext(); + QDeclarativeContext *rootContext() const; void clearComponentCache(); diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h index a5c8c38..3b5dd5a 100644 --- a/src/declarative/qml/qdeclarativeengine_p.h +++ b/src/declarative/qml/qdeclarativeengine_p.h @@ -304,7 +304,7 @@ public: static QScriptValue consoleLog(QScriptContext*, QScriptEngine*); static QScriptValue quit(QScriptContext*, QScriptEngine*); -#ifndef QT_NO_TEXTDATE +#ifndef QT_NO_DATESTRING static QScriptValue formatDate(QScriptContext*, QScriptEngine*); static QScriptValue formatTime(QScriptContext*, QScriptEngine*); static QScriptValue formatDateTime(QScriptContext*, QScriptEngine*); diff --git a/src/declarative/qml/qdeclarativeenginedebug.cpp b/src/declarative/qml/qdeclarativeenginedebug.cpp index 001da46..1837366 100644 --- a/src/declarative/qml/qdeclarativeenginedebug.cpp +++ b/src/declarative/qml/qdeclarativeenginedebug.cpp @@ -485,24 +485,22 @@ void QDeclarativeEngineDebugServer::setBinding(int objectId, if (object && context) { + QDeclarativeProperty property(object, propertyName, context); if (isLiteralValue) { - QDeclarativeProperty literalProperty(object, propertyName, context); - literalProperty.write(expression); + property.write(expression); + } else if (hasValidSignal(object, propertyName)) { + QDeclarativeExpression *declarativeExpression = new QDeclarativeExpression(context, object, expression.toString()); + QDeclarativePropertyPrivate::setSignalExpression(property, declarativeExpression); + } else if (property.isProperty()) { + QDeclarativeBinding *binding = new QDeclarativeBinding(expression.toString(), object, context); + binding->setTarget(property); + binding->setNotifyOnValueChanged(true); + QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::setBinding(property, binding); + if (oldBinding) + oldBinding->destroy(); + binding->update(); } else { - if (hasValidSignal(object, propertyName)) { - QDeclarativeProperty property(object, propertyName); - QDeclarativeExpression *declarativeExpression = new QDeclarativeExpression(context, object, expression.toString()); - QDeclarativePropertyPrivate::setSignalExpression(property, declarativeExpression); - } else { - QDeclarativeBinding *binding = new QDeclarativeBinding(expression.toString(), object, context); - QDeclarativeProperty property(object, propertyName); - binding->setTarget(property); - binding->setNotifyOnValueChanged(true); - QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::setBinding(property, binding); - if (oldBinding) - oldBinding->destroy(); - binding->update(); - } + qWarning() << "QDeclarativeEngineDebugServer::setBinding: unable to set property" << propertyName << "on object" << object; } } } diff --git a/src/declarative/qml/qdeclarativeerror.cpp b/src/declarative/qml/qdeclarativeerror.cpp index 8717f56..0ab5cd9 100644 --- a/src/declarative/qml/qdeclarativeerror.cpp +++ b/src/declarative/qml/qdeclarativeerror.cpp @@ -250,7 +250,9 @@ QDebug operator<<(QDebug debug, const QDeclarativeError &error) if (f.open(QIODevice::ReadOnly)) { QByteArray data = f.readAll(); QTextStream stream(data, QIODevice::ReadOnly); +#ifndef QT_NO_TEXTCODEC stream.setCodec("UTF-8"); +#endif const QString code = stream.readAll(); const QStringList lines = code.split(QLatin1Char('\n')); diff --git a/src/declarative/qml/qdeclarativeexpression.cpp b/src/declarative/qml/qdeclarativeexpression.cpp index 9935e38..585fb69 100644 --- a/src/declarative/qml/qdeclarativeexpression.cpp +++ b/src/declarative/qml/qdeclarativeexpression.cpp @@ -604,6 +604,7 @@ QScriptValue QDeclarativeExpressionPrivate::scriptValue(QObject *secondaryScope, scriptContext->pushScope(ep->globalClass->staticGlobalObject()); QDeclarativeRewrite::RewriteBinding rewriteBinding; + rewriteBinding.setName(name); bool ok = true; const QString code = rewriteBinding(expression, &ok); if (ok) diff --git a/src/declarative/qml/qdeclarativeexpression_p.h b/src/declarative/qml/qdeclarativeexpression_p.h index b629e20..1700335 100644 --- a/src/declarative/qml/qdeclarativeexpression_p.h +++ b/src/declarative/qml/qdeclarativeexpression_p.h @@ -194,6 +194,7 @@ public: QString url; // This is a QString for a reason. QUrls are slooooooow... int line; + QByteArray name; //function name, hint for the debugger }; QDeclarativeQtScriptExpression::DeleteWatcher::DeleteWatcher(QDeclarativeQtScriptExpression *data) diff --git a/src/declarative/qml/qdeclarativeextensionplugin.cpp b/src/declarative/qml/qdeclarativeextensionplugin.cpp index 0660599..9b5eb61 100644 --- a/src/declarative/qml/qdeclarativeextensionplugin.cpp +++ b/src/declarative/qml/qdeclarativeextensionplugin.cpp @@ -50,23 +50,76 @@ QT_BEGIN_NAMESPACE \ingroup plugins - QDeclarativeExtensionPlugin is a plugin interface that makes it - possible to offer extensions that can be loaded dynamically into - applications using the QDeclarativeEngine class. - - Writing a QML extension plugin is achieved by subclassing this - base class, reimplementing the pure virtual registerTypes() - function, and exporting the class using the Q_EXPORT_PLUGIN2() - macro. + QDeclarativeExtensionPlugin is a plugin interface that makes it possible to + create QML extensions that can be loaded dynamically into QML applications. + These extensions allow custom QML types to be made available to the QML engine. + + To write a QML extension plugin: + + \list + \o Subclass QDeclarativeExtensionPlugin, implement registerTypes() method + to register types using qmlRegisterType(), and export the class using the Q_EXPORT_PLUGIN2() macro + \o Write an appropriate project file for the plugin + \o Create a \l{Writing a qmldir file}{qmldir file} to describe the plugin + \endlist QML extension plugins can be used to provide either application-specific or library-like plugins. Library plugins should limit themselves to registering types, as any manipulation of the engine's root context may cause conflicts or other issues in the library user's code. - See \l {Tutorial: Writing QML extensions with C++} for details on creating - QML extensions, including how to build a plugin with with QDeclarativeExtensionPlugin. - For a simple overview, see the \l{declarative/cppextensions/plugins}{plugins} example. + + \section1 An example + + Suppose there is a new \c TimeModel C++ class that should be made available + as a new QML element. It provides the current time through \c hour and \c minute + properties, like this: + + \snippet examples/declarative/cppextensions/plugins/plugin.cpp 0 + \dots + + To make this class available as a QML type, create a plugin that registers + this type with a specific \l {QML Modules}{module} using qmlRegisterType(). For this example the plugin + module will be named \c com.nokia.TimeExample (as defined in the project + file further below). + + \snippet examples/declarative/cppextensions/plugins/plugin.cpp plugin + \codeline + \snippet examples/declarative/cppextensions/plugins/plugin.cpp export + + This registers the \c TimeModel class with the 1.0 version of this + plugin library, as a QML type called \c Time. The Q_ASSERT statement + ensures the module is imported correctly by any QML components that use this plugin. + + The project file defines the project as a plugin library and specifies + it should be built into the \c com/nokia/TimeExample directory: + + \code + TEMPLATE = lib + CONFIG += qt plugin + QT += declarative + + DESTDIR = com/nokia/TimeExample + TARGET = qmlqtimeexampleplugin + ... + \endcode + + Finally, a \l{Writing a qmldir file}{qmldir file} is required in the \c com/nokia/TimeExample directory + that describes the plugin. This directory includes a \c Clock.qml file that + should be bundled with the plugin, so it needs to be specified in the \c qmldir + file: + + \quotefile examples/declarative/cppextensions/plugins/com/nokia/TimeExample/qmldir + + Once the project is built and installed, the new \c Time element can be + used by any QML component that imports the \c com.nokia.TimeExample module: + + \snippet examples/declarative/cppextensions/plugins/plugins.qml 0 + + The full source code is available in the \l {declarative/cppextensions/plugins}{plugins example}. + + The \l {Tutorial: Writing QML extensions with C++} also contains a chapter + on creating QML plugins. \sa QDeclarativeEngine::importPlugin(), {How to Create Qt Plugins} */ @@ -95,7 +148,7 @@ QDeclarativeExtensionPlugin::QDeclarativeExtensionPlugin(QObject *parent) } /*! - Destroys the plugin. + \internal */ QDeclarativeExtensionPlugin::~QDeclarativeExtensionPlugin() { diff --git a/src/declarative/qml/qdeclarativeimageprovider.cpp b/src/declarative/qml/qdeclarativeimageprovider.cpp index a294c38..241df87 100644 --- a/src/declarative/qml/qdeclarativeimageprovider.cpp +++ b/src/declarative/qml/qdeclarativeimageprovider.cpp @@ -212,9 +212,6 @@ QImage QDeclarativeImageProvider::requestImage(const QString &id, QSize *size, c In all cases, \a size must be set to the original size of the image. This is used to set the \l {Item::}{width} and \l {Item::}{height} of image elements that should be automatically sized to the loaded image. - - \note this method may be called by multiple threads, so ensure the - implementation of this method is reentrant. */ QPixmap QDeclarativeImageProvider::requestPixmap(const QString &id, QSize *size, const QSize& requestedSize) { diff --git a/src/declarative/qml/qdeclarativeinstruction_p.h b/src/declarative/qml/qdeclarativeinstruction_p.h index d1a0a0a..f0b032c 100644 --- a/src/declarative/qml/qdeclarativeinstruction_p.h +++ b/src/declarative/qml/qdeclarativeinstruction_p.h @@ -292,7 +292,8 @@ public: struct StoreSignalInstruction { int signalIndex; int value; - int context; + short context; + int name; }; struct AssignSignalObjectInstruction { int signal; diff --git a/src/declarative/qml/qdeclarativelist.cpp b/src/declarative/qml/qdeclarativelist.cpp index 7c89672..9598d98 100644 --- a/src/declarative/qml/qdeclarativelist.cpp +++ b/src/declarative/qml/qdeclarativelist.cpp @@ -306,7 +306,7 @@ int QDeclarativeListReference::count() const /*! \class QDeclarativeListProperty \since 4.7 -\brief The QDeclarativeListProperty class allows applications to explose list-like +\brief The QDeclarativeListProperty class allows applications to expose list-like properties to QML. QML has many list properties, where more than one object value can be assigned. diff --git a/src/declarative/qml/qdeclarativemetatype.cpp b/src/declarative/qml/qdeclarativemetatype.cpp index 153e2be..a5c878f 100644 --- a/src/declarative/qml/qdeclarativemetatype.cpp +++ b/src/declarative/qml/qdeclarativemetatype.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include <QtDeclarative/qdeclarativeprivate.h> #include "private/qdeclarativemetatype_p.h" #include "private/qdeclarativeproxymetaobject_p.h" @@ -485,17 +486,17 @@ int QDeclarativeType::index() const return d->m_index; } -int QDeclarativePrivate::registerAutoParentFunction(AutoParentFunction function) +int registerAutoParentFunction(QDeclarativePrivate::RegisterAutoParent &autoparent) { QWriteLocker lock(metaTypeDataLock()); QDeclarativeMetaTypeData *data = metaTypeData(); - data->parentFunctions.append(function); + data->parentFunctions.append(autoparent.function); return data->parentFunctions.count() - 1; } -int QDeclarativePrivate::registerType(const QDeclarativePrivate::RegisterInterface &interface) +int registerInterface(const QDeclarativePrivate::RegisterInterface &interface) { if (interface.version > 0) qFatal("qmlRegisterType(): Cannot mix incompatible QML versions."); @@ -524,7 +525,7 @@ int QDeclarativePrivate::registerType(const QDeclarativePrivate::RegisterInterfa return index; } -int QDeclarativePrivate::registerType(const QDeclarativePrivate::RegisterType &type) +int registerType(const QDeclarativePrivate::RegisterType &type) { if (type.elementName) { for (int ii = 0; type.elementName[ii]; ++ii) { @@ -576,6 +577,22 @@ int QDeclarativePrivate::registerType(const QDeclarativePrivate::RegisterType &t } /* +This method is "over generalized" to allow us to (potentially) register more types of things in +the future without adding exported symbols. +*/ +int QDeclarativePrivate::qmlregister(RegistrationType type, void *data) +{ + if (type == TypeRegistration) { + return registerType(*reinterpret_cast<RegisterType *>(data)); + } else if (type == InterfaceRegistration) { + return registerInterface(*reinterpret_cast<RegisterInterface *>(data)); + } else if (type == AutoParentRegistration) { + return registerAutoParentFunction(*reinterpret_cast<RegisterAutoParent *>(data)); + } + return -1; +} + +/* Have any types been registered for \a module with at least versionMajor.versionMinor, and types for \a module with at most versionMajor.versionMinor. diff --git a/src/declarative/qml/qdeclarativemetatype_p.h b/src/declarative/qml/qdeclarativemetatype_p.h index 4c98b6f..f410547 100644 --- a/src/declarative/qml/qdeclarativemetatype_p.h +++ b/src/declarative/qml/qdeclarativemetatype_p.h @@ -63,6 +63,8 @@ QT_BEGIN_NAMESPACE class QDeclarativeType; class QDeclarativeCustomParser; +class QDeclarativeTypePrivate; + class Q_DECLARATIVE_EXPORT QDeclarativeMetaType { public: @@ -103,7 +105,6 @@ public: static QList<QDeclarativePrivate::AutoParentFunction> parentFunctions(); }; -class QDeclarativeTypePrivate; class Q_DECLARATIVE_EXPORT QDeclarativeType { public: @@ -144,11 +145,12 @@ public: int propertyValueInterceptorCast() const; int index() const; + private: friend class QDeclarativeTypePrivate; friend struct QDeclarativeMetaTypeData; - friend int QDeclarativePrivate::registerType(const QDeclarativePrivate::RegisterInterface &); - friend int QDeclarativePrivate::registerType(const QDeclarativePrivate::RegisterType &); + friend int registerType(const QDeclarativePrivate::RegisterType &); + friend int registerInterface(const QDeclarativePrivate::RegisterInterface &); QDeclarativeType(int, const QDeclarativePrivate::RegisterInterface &); QDeclarativeType(int, const QDeclarativePrivate::RegisterType &); ~QDeclarativeType(); diff --git a/src/declarative/qml/qdeclarativeprivate.h b/src/declarative/qml/qdeclarativeprivate.h index cd859fe..b2d7451 100644 --- a/src/declarative/qml/qdeclarativeprivate.h +++ b/src/declarative/qml/qdeclarativeprivate.h @@ -42,6 +42,17 @@ #ifndef QDECLARATIVEPRIVATE_H #define QDECLARATIVEPRIVATE_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include <QtCore/qglobal.h> #include <QtCore/qvariant.h> #ifndef Q_OS_WIN @@ -177,6 +188,9 @@ namespace QDeclarativePrivate return AttachedPropertySelector<T, has_attachedPropertiesMethod<T, has_attachedPropertiesMember<T>::value>::value>::metaObject(); } + enum AutoParentResult { Parented, IncompatibleObject, IncompatibleParent }; + typedef AutoParentResult (*AutoParentFunction)(QObject *object, QObject *parent); + struct RegisterType { int version; @@ -214,13 +228,19 @@ namespace QDeclarativePrivate const char *iid; }; - enum AutoParentResult { Parented, IncompatibleObject, IncompatibleParent }; - typedef AutoParentResult (*AutoParentFunction)(QObject *object, QObject *parent); + struct RegisterAutoParent { + int version; - int Q_DECLARATIVE_EXPORT registerAutoParentFunction(AutoParentFunction); - int Q_DECLARATIVE_EXPORT registerType(const RegisterType &); - int Q_DECLARATIVE_EXPORT registerType(const RegisterInterface &); + AutoParentFunction function; + }; + + enum RegistrationType { + TypeRegistration = 0, + InterfaceRegistration = 1, + AutoParentRegistration = 2 + }; + int Q_DECLARATIVE_EXPORT qmlregister(RegistrationType, void *); } QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativerewrite.cpp b/src/declarative/qml/qdeclarativerewrite.cpp index 3d40e77..bc9a114 100644 --- a/src/declarative/qml/qdeclarativerewrite.cpp +++ b/src/declarative/qml/qdeclarativerewrite.cpp @@ -102,7 +102,7 @@ QString RewriteBinding::rewrite(QString code, unsigned position, unsigned startOfStatement = node->firstSourceLocation().begin() - _position; unsigned endOfStatement = node->lastSourceLocation().end() - _position; - _writer->replace(startOfStatement, 0, QLatin1String("(function() { ")); + _writer->replace(startOfStatement, 0, QLatin1String("(function ") + QString::fromUtf8(_name) + QLatin1String("() { ")); _writer->replace(endOfStatement, 0, QLatin1String(" })")); if (rewriteDump()) { diff --git a/src/declarative/qml/qdeclarativerewrite_p.h b/src/declarative/qml/qdeclarativerewrite_p.h index 33b168c..6f3c46e 100644 --- a/src/declarative/qml/qdeclarativerewrite_p.h +++ b/src/declarative/qml/qdeclarativerewrite_p.h @@ -78,10 +78,14 @@ class RewriteBinding: protected AST::Visitor { unsigned _position; TextWriter *_writer; + QByteArray _name; public: QString operator()(const QString &code, bool *ok = 0); + //name of the function: used for the debugger + void setName(const QByteArray &name) { _name = name; } + protected: using AST::Visitor::visit; diff --git a/src/declarative/qml/qdeclarativescriptparser.cpp b/src/declarative/qml/qdeclarativescriptparser.cpp index 219d759..f703cf5 100644 --- a/src/declarative/qml/qdeclarativescriptparser.cpp +++ b/src/declarative/qml/qdeclarativescriptparser.cpp @@ -831,7 +831,9 @@ bool QDeclarativeScriptParser::parse(const QByteArray &qmldata, const QUrl &url) _scriptFile = fileName; QTextStream stream(qmldata, QIODevice::ReadOnly); +#ifndef QT_NO_TEXTCODEC stream.setCodec("UTF-8"); +#endif const QString code = stream.readAll(); data = new QDeclarativeScriptParserJsASTData(fileName); @@ -896,6 +898,14 @@ QList<QDeclarativeError> QDeclarativeScriptParser::errors() const return _errors; } +static void replaceWithSpace(QString &str, int idx, int n) +{ + QChar *data = str.data() + idx; + QChar space(' '); + for (int ii = 0; ii < n; ++ii) + *data++ = space; +} + /* Searches for ".pragma <value>" declarations within \a script. Currently supported pragmas are: @@ -905,83 +915,48 @@ QDeclarativeParser::Object::ScriptBlock::Pragmas QDeclarativeScriptParser::extra { QDeclarativeParser::Object::ScriptBlock::Pragmas rv = QDeclarativeParser::Object::ScriptBlock::None; - const QChar forwardSlash(QLatin1Char('/')); - const QChar star(QLatin1Char('*')); - const QChar newline(QLatin1Char('\n')); - const QChar dot(QLatin1Char('.')); - const QChar semicolon(QLatin1Char(';')); - const QChar space(QLatin1Char(' ')); - const QString pragma(QLatin1String(".pragma ")); - - const QChar *pragmaData = pragma.constData(); - - const QChar *data = script.constData(); - const int length = script.count(); - for (int ii = 0; ii < length; ++ii) { - const QChar &c = data[ii]; - - if (c.isSpace()) - continue; - - if (c == forwardSlash) { - ++ii; - if (ii >= length) - return rv; - - const QChar &c = data[ii]; - if (c == forwardSlash) { - // Find next newline - while (ii < length && data[++ii] != newline) {}; - } else if (c == star) { - // Find next star - while (true) { - while (ii < length && data[++ii] != star) {}; - if (ii + 1 >= length) - return rv; - - if (data[ii + 1] == forwardSlash) { - ++ii; - break; - } - } - } else { - return rv; - } - } else if (c == dot) { - // Could be a pragma! - if (ii + pragma.length() >= length || - 0 != ::memcmp(data + ii, pragmaData, sizeof(QChar) * pragma.length())) - return rv; + const QString pragma(QLatin1String("pragma")); + const QString library(QLatin1String("library")); - int pragmaStatementIdx = ii; + QDeclarativeJS::Lexer l(0); + l.setCode(script, 0); - ii += pragma.length(); + int token = l.lex(); - while (ii < length && data[ii].isSpace()) { ++ii; } + while (true) { + if (token != QDeclarativeJSGrammar::T_DOT) + return rv; - int startIdx = ii; + int startOffset = l.tokenOffset(); + int startLine = l.currentLineNo(); - while (ii < length && data[ii].isLetter()) { ++ii; } + token = l.lex(); - int endIdx = ii; + if (token != QDeclarativeJSGrammar::T_IDENTIFIER || + l.currentLineNo() != startLine || + script.mid(l.tokenOffset(), l.tokenLength()) != pragma) + return rv; - if (ii != length && data[ii] != forwardSlash && !data[ii].isSpace() && data[ii] != semicolon) - return rv; + token = l.lex(); - QString p(data + startIdx, endIdx - startIdx); + if (token != QDeclarativeJSGrammar::T_IDENTIFIER || + l.currentLineNo() != startLine) + return rv; - if (p == QLatin1String("library")) - rv |= QDeclarativeParser::Object::ScriptBlock::Shared; - else - return rv; + QString pragmaValue = script.mid(l.tokenOffset(), l.tokenLength()); + int endOffset = l.tokenLength() + l.tokenOffset(); - for (int jj = pragmaStatementIdx; jj < endIdx; ++jj) script[jj] = space; + token = l.lex(); + if (l.currentLineNo() == startLine) + return rv; + if (pragmaValue == QLatin1String("library")) { + rv |= QDeclarativeParser::Object::ScriptBlock::Shared; + replaceWithSpace(script, startOffset, endOffset - startOffset); } else { return rv; } } - return rv; } diff --git a/src/declarative/qml/qdeclarativestringconverters.cpp b/src/declarative/qml/qdeclarativestringconverters.cpp index 8bd2cf1..7534a2c 100644 --- a/src/declarative/qml/qdeclarativestringconverters.cpp +++ b/src/declarative/qml/qdeclarativestringconverters.cpp @@ -106,14 +106,14 @@ QVariant QDeclarativeStringConverters::variantFromString(const QString &s, int p return QVariant(uint(qRound(s.toDouble(ok)))); case QMetaType::QColor: return QVariant::fromValue(colorFromString(s, ok)); -#ifndef QT_NO_TEXTDATE +#ifndef QT_NO_DATESTRING case QMetaType::QDate: return QVariant::fromValue(dateFromString(s, ok)); case QMetaType::QTime: return QVariant::fromValue(timeFromString(s, ok)); case QMetaType::QDateTime: return QVariant::fromValue(dateTimeFromString(s, ok)); -#endif // QT_NO_TEXTDATE +#endif // QT_NO_DATESTRING case QMetaType::QPointF: return QVariant::fromValue(pointFFromString(s, ok)); case QMetaType::QPoint: @@ -152,7 +152,7 @@ QColor QDeclarativeStringConverters::colorFromString(const QString &s, bool *ok) } } -#ifndef QT_NO_TEXTDATE +#ifndef QT_NO_DATESTRING QDate QDeclarativeStringConverters::dateFromString(const QString &s, bool *ok) { QDate d = QDate::fromString(s, Qt::ISODate); @@ -173,7 +173,7 @@ QDateTime QDeclarativeStringConverters::dateTimeFromString(const QString &s, boo if (ok) *ok = d.isValid(); return d; } -#endif // QT_NO_TEXTDATE +#endif // QT_NO_DATESTRING //expects input of "x,y" QPointF QDeclarativeStringConverters::pointFFromString(const QString &s, bool *ok) diff --git a/src/declarative/qml/qdeclarativestringconverters_p.h b/src/declarative/qml/qdeclarativestringconverters_p.h index 842d1b3..e6b0abe 100644 --- a/src/declarative/qml/qdeclarativestringconverters_p.h +++ b/src/declarative/qml/qdeclarativestringconverters_p.h @@ -73,7 +73,7 @@ namespace QDeclarativeStringConverters QVariant Q_DECLARATIVE_EXPORT variantFromString(const QString &, int preferredType, bool *ok = 0); QColor Q_DECLARATIVE_EXPORT colorFromString(const QString &, bool *ok = 0); -#ifndef QT_NO_TEXTDATE +#ifndef QT_NO_DATESTRING QDate Q_DECLARATIVE_EXPORT dateFromString(const QString &, bool *ok = 0); QTime Q_DECLARATIVE_EXPORT timeFromString(const QString &, bool *ok = 0); QDateTime Q_DECLARATIVE_EXPORT dateTimeFromString(const QString &, bool *ok = 0); diff --git a/src/declarative/qml/qdeclarativevaluetype.cpp b/src/declarative/qml/qdeclarativevaluetype.cpp index c17ec95..98e9a58 100644 --- a/src/declarative/qml/qdeclarativevaluetype.cpp +++ b/src/declarative/qml/qdeclarativevaluetype.cpp @@ -74,7 +74,7 @@ int qmlRegisterValueTypeEnums(const char *qmlName) 0 }; - return QDeclarativePrivate::registerType(type); + return QDeclarativePrivate::qmlregister(QDeclarativePrivate::TypeRegistration, &type); } QDeclarativeValueTypeFactory::QDeclarativeValueTypeFactory() @@ -973,7 +973,7 @@ qreal QDeclarativeFontValueType::letterSpacing() const void QDeclarativeFontValueType::setLetterSpacing(qreal size) { - font.setLetterSpacing(QFont::PercentageSpacing, size); + font.setLetterSpacing(QFont::AbsoluteSpacing, size); } qreal QDeclarativeFontValueType::wordSpacing() const diff --git a/src/declarative/qml/qdeclarativevme.cpp b/src/declarative/qml/qdeclarativevme.cpp index 3247f85..4e41c22 100644 --- a/src/declarative/qml/qdeclarativevme.cpp +++ b/src/declarative/qml/qdeclarativevme.cpp @@ -621,14 +621,15 @@ QObject *QDeclarativeVME::run(QDeclarativeVMEStack<QObject *> &stack, case QDeclarativeInstruction::StoreSignal: { QObject *target = stack.top(); - QObject *context = stack.at(stack.count() - 1 - instr.assignBinding.context); - + QObject *context = stack.at(stack.count() - 1 - instr.storeSignal.context); + QMetaMethod signal = target->metaObject()->method(instr.storeSignal.signalIndex); QDeclarativeBoundSignal *bs = new QDeclarativeBoundSignal(target, signal, target); QDeclarativeExpression *expr = new QDeclarativeExpression(ctxt, context, primitives.at(instr.storeSignal.value)); expr->setSourceLocation(comp->name, instr.line); + static_cast<QDeclarativeExpressionPrivate *>(QObjectPrivate::get(expr))->name = datas.at(instr.storeSignal.name); bs->setExpression(expr); } break; diff --git a/src/declarative/qml/qdeclarativexmlhttprequest.cpp b/src/declarative/qml/qdeclarativexmlhttprequest.cpp index acd1f51..ff1a0e9 100644 --- a/src/declarative/qml/qdeclarativexmlhttprequest.cpp +++ b/src/declarative/qml/qdeclarativexmlhttprequest.cpp @@ -58,6 +58,8 @@ #include <QtCore/qstack.h> #include <QtCore/qdebug.h> +#ifndef QT_NO_XMLSTREAMREADER + // From DOM-Level-3-Core spec // http://www.w3.org/TR/DOM-Level-3-Core/core.html #define INDEX_SIZE_ERR 1 @@ -1304,10 +1306,11 @@ QString QDeclarativeXMLHttpRequest::responseBody() const { QXmlStreamReader reader(m_responseEntityBody); reader.readNext(); +#ifndef QT_NO_TEXTCODEC QTextCodec *codec = QTextCodec::codecForName(reader.documentEncoding().toString().toUtf8()); if (codec) return codec->toUnicode(m_responseEntityBody); - +#endif return QString::fromUtf8(m_responseEntityBody); } @@ -1662,4 +1665,6 @@ void qt_add_qmlxmlhttprequest(QScriptEngine *engine) QT_END_NAMESPACE +#endif // QT_NO_XMLSTREAMREADER + #include <qdeclarativexmlhttprequest.moc> diff --git a/src/declarative/qml/qdeclarativexmlhttprequest_p.h b/src/declarative/qml/qdeclarativexmlhttprequest_p.h index 068cd0f..f340c1c 100644 --- a/src/declarative/qml/qdeclarativexmlhttprequest_p.h +++ b/src/declarative/qml/qdeclarativexmlhttprequest_p.h @@ -56,6 +56,8 @@ #include <QtCore/qglobal.h> +#ifndef QT_NO_XMLSTREAMREADER + QT_BEGIN_NAMESPACE class QScriptEngine; @@ -63,5 +65,7 @@ void qt_add_qmlxmlhttprequest(QScriptEngine *engine); QT_END_NAMESPACE +#endif // QT_NO_XMLSTREAMREADER + #endif // QDECLARATIVEXMLHTTPREQUEST_P_H diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index bdb9510..6a9cf95 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -632,15 +632,26 @@ QAbstractAnimation *QDeclarativePauseAnimation::qtAnimation() \qmlclass ColorAnimation QDeclarativeColorAnimation \since 4.7 \inherits PropertyAnimation - \brief The ColorAnimation element allows you to animate color changes. + \brief The ColorAnimation element animates changes in color values. - \code - ColorAnimation { from: "white"; to: "#c0c0c0"; duration: 100 } - \endcode + ColorAnimation is a specialized PropertyAnimation that defines an + animation to be applied when a color value changes. + + Here is a ColorAnimation applied to the \c color property of a \l Rectangle + as a property value source. It animates the \c color property's value from + its current value to a value of "red", over 1000 milliseconds: + + \snippet doc/src/snippets/declarative/coloranimation.qml 0 + + Like any other animation element, a ColorAnimation can be applied in a + number of ways, including transitions, behaviors and property value + sources. The \l PropertyAnimation documentation shows a variety of methods + for creating animations. When used in a transition, ColorAnimation will by default animate - all properties of type color that are changing. If a property or properties - are explicitly set for the animation, then those will be used instead. + all properties of type color that have changed. If a \l{PropertyAnimation::}{property} + or \l{PropertyAnimation::}{properties} are explicitly set for the animation, + then those are used instead. \sa {QML Animation}, {declarative/animation/basics}{Animation basics example} */ @@ -664,7 +675,24 @@ QDeclarativeColorAnimation::~QDeclarativeColorAnimation() /*! \qmlproperty color ColorAnimation::from - This property holds the starting color. + This property holds the color value at which the animation should begin. + + For example, the following animation is not applied until a color value + has reached "#c0c0c0": + + \qml + Item { + states: [ ... ] + + transition: Transition { + NumberAnimation { from: "#c0c0c0"; duration: 2000 } + } + } + \endqml + + If this value is not set and the ColorAnimation is defined within + a \l Transition, it defaults to the value defined in the starting + state of the \l Transition. */ QColor QDeclarativeColorAnimation::from() const { @@ -679,7 +707,12 @@ void QDeclarativeColorAnimation::setFrom(const QColor &f) /*! \qmlproperty color ColorAnimation::to - This property holds the ending color. + + This property holds the color value at which the animation should end. + + If this value is not set and the ColorAnimation is defined within + a \l Transition or \l Behavior, it defaults to the value defined in the end + state of the \l Transition or \l Behavior. */ QColor QDeclarativeColorAnimation::to() const { @@ -848,18 +881,27 @@ QAbstractAnimation *QDeclarativeScriptAction::qtAnimation() \inherits Animation \brief The PropertyAction element allows immediate property changes during animation. - Explicitly set \c theimage.smooth=true during a transition: + PropertyAction is used to specify an immediate property change + during an animation. The property change is not animated. + + For example, to explicitly set \c {theImage.smooth = true} during a \l Transition: \code - PropertyAction { target: theimage; property: "smooth"; value: true } + transitions: Transition { + ... + PropertyAction { target: theImage; property: "smooth"; value: true } + ... + } \endcode - Set \c thewebview.url to the value set for the destination state: + Or, to set \c theWebView.url to the value set for the destination state: \code - PropertyAction { target: thewebview; property: "url" } + transitions: Transition { + ... + PropertyAction { target: theWebView; property: "url" } + ... + } \endcode - The PropertyAction is immediate - - the target property is not animated to the selected value in any way. \sa QtDeclarative */ @@ -885,14 +927,6 @@ void QDeclarativePropertyActionPrivate::init() QDeclarative_setParent_noEvent(spa, q); } -/*! - \qmlproperty Object PropertyAction::target - This property holds an explicit target object to animate. - - The exact effect of the \c target property depends on how the animation - is being used. Refer to the \l {QML Animation} documentation for details. -*/ - QObject *QDeclarativePropertyAction::target() const { Q_D(const QDeclarativePropertyAction); @@ -905,7 +939,7 @@ void QDeclarativePropertyAction::setTarget(QObject *o) if (d->target == o) return; d->target = o; - emit targetChanged(d->target, d->propertyName); + emit targetChanged(); } QString QDeclarativePropertyAction::property() const @@ -920,16 +954,16 @@ void QDeclarativePropertyAction::setProperty(const QString &n) if (d->propertyName == n) return; d->propertyName = n; - emit targetChanged(d->target, d->propertyName); + emit propertyChanged(); } /*! + \qmlproperty Object PropertyAction::target \qmlproperty list<Object> PropertyAction::targets \qmlproperty string PropertyAction::property \qmlproperty string PropertyAction::properties - \qmlproperty Object PropertyAction::target - These properties are used as a set to determine which properties should be + These properties determine the items and their properties that are affected by this action. The details of how these properties are interpreted in different situations @@ -961,7 +995,7 @@ QDeclarativeListProperty<QObject> QDeclarativePropertyAction::targets() /*! \qmlproperty list<Object> PropertyAction::exclude - This property holds the objects not to be affected by this animation. + This property holds the objects that should not be affected by this action. \sa targets */ @@ -1096,13 +1130,25 @@ void QDeclarativePropertyAction::transition(QDeclarativeStateActions &actions, \qmlclass NumberAnimation QDeclarativeNumberAnimation \since 4.7 \inherits PropertyAnimation - \brief The NumberAnimation element allows you to animate changes in properties of type qreal. + \brief The NumberAnimation element animates changes in qreal-type values. - For example, to animate a set of properties over 200ms, from their values in the start state to - their values in the end state of the transition: - \code - NumberAnimation { properties: "x,y,scale"; duration: 200 } - \endcode + NumberAnimation is a specialized PropertyAnimation that defines an + animation to be applied when a numerical value changes. + + Here is a NumberAnimation applied to the \c x property of a \l Rectangle + as a property value source. It animates the \c x value from its current + value to a value of 50, over 1000 milliseconds: + + \snippet doc/src/snippets/declarative/numberanimation.qml 0 + + Like any other animation element, a NumberAnimation can be applied in a + number of ways, including transitions, behaviors and property value + sources. The \l PropertyAnimation documentation shows a variety of methods + for creating animations. + + Note that NumberAnimation may not animate smoothly if there are irregular + changes in the number value that it is tracking. If this is the case, use + SmoothedAnimation instead. \sa {QML Animation}, {declarative/animation/basics}{Animation basics example} */ @@ -1137,9 +1183,26 @@ void QDeclarativeNumberAnimation::init() /*! \qmlproperty real NumberAnimation::from - This property holds the starting value. - If not set, then the value defined in the start state of the transition. + This property holds the starting number value. + + For example, the following animation is not applied until the \c x value + has reached 100: + + \qml + Item { + states: [ ... ] + + transition: Transition { + NumberAnimation { properties: "x"; from: 100; duration: 200 } + } + } + \endqml + + If this value is not set and the NumberAnimation is defined within + a \l Transition, it defaults to the value defined in the start + state of the \l Transition. */ + qreal QDeclarativeNumberAnimation::from() const { Q_D(const QDeclarativePropertyAnimation); @@ -1153,8 +1216,11 @@ void QDeclarativeNumberAnimation::setFrom(qreal f) /*! \qmlproperty real NumberAnimation::to - This property holds the ending value. - If not set, then the value defined in the end state of the transition or Behavior. + This property holds the ending number value. + + If this value is not set and the NumberAnimation is defined within + a \l Transition or \l Behavior, it defaults to the value defined in the end + state of the \l Transition or \l Behavior. */ qreal QDeclarativeNumberAnimation::to() const { @@ -1173,7 +1239,10 @@ void QDeclarativeNumberAnimation::setTo(qreal t) \qmlclass Vector3dAnimation QDeclarativeVector3dAnimation \since 4.7 \inherits PropertyAnimation - \brief The Vector3dAnimation element allows you to animate changes in properties of type QVector3d. + \brief The Vector3dAnimation element animates changes in QVector3d values. + + Vector3dAnimation is a specialized PropertyAnimation that defines an + animation to be applied when a Vector3d value changes. \sa {QML Animation}, {declarative/animation/basics}{Animation basics example} */ @@ -1199,7 +1268,9 @@ QDeclarativeVector3dAnimation::~QDeclarativeVector3dAnimation() /*! \qmlproperty real Vector3dAnimation::from This property holds the starting value. - If not set, then the value defined in the start state of the transition. + + If this value is not set, it defaults to the value defined in the start + state of the \l Transition. */ QVector3D QDeclarativeVector3dAnimation::from() const { @@ -1215,7 +1286,9 @@ void QDeclarativeVector3dAnimation::setFrom(QVector3D f) /*! \qmlproperty real Vector3dAnimation::to This property holds the ending value. - If not set, then the value defined in the end state of the transition or Behavior. + + If this value is not set, it defaults to the value defined in the end + state of the \l Transition or \l Behavior. */ QVector3D QDeclarativeVector3dAnimation::to() const { @@ -1234,31 +1307,32 @@ void QDeclarativeVector3dAnimation::setTo(QVector3D t) \qmlclass RotationAnimation QDeclarativeRotationAnimation \since 4.7 \inherits PropertyAnimation - \brief The RotationAnimation element allows you to animate rotations. + \brief The RotationAnimation element animates changes in rotation values. RotationAnimation is a specialized PropertyAnimation that gives control - over the direction of rotation. By default, it will rotate in the direction + over the direction of rotation during an animation. + + By default, it rotates in the direction of the numerical change; a rotation from 0 to 240 will rotate 220 degrees clockwise, while a rotation from 240 to 0 will rotate 220 degrees - counterclockwise. + counterclockwise. The \l direction property can be set to specify the + direction in which the rotation should occur. - When used in a transition RotationAnimation will rotate all + In the following example we use RotationAnimation to animate the rotation + between states via the shortest path: + + \snippet doc/src/snippets/declarative/rotationanimation.qml 0 + + Notice the RotationAnimation did not need to set a \l {RotationAnimation::}{target} + value. As a convenience, when used in a transition, RotationAnimation will rotate all properties named "rotation" or "angle". You can override this by providing your own properties via \l {PropertyAnimation::properties}{properties} or \l {PropertyAnimation::property}{property}. - In the following example we use RotationAnimation to animate the rotation - between states via the shortest path. - \qml - states: { - State { name: "180"; PropertyChanges { target: myItem; rotation: 180 } } - State { name: "90"; PropertyChanges { target: myItem; rotation: 90 } } - State { name: "-90"; PropertyChanges { target: myItem; rotation: -90 } } - } - transition: Transition { - RotationAnimation { direction: RotationAnimation.Shortest } - } - \endqml + Like any other animation element, a RotationAnimation can be applied in a + number of ways, including transitions, behaviors and property value + sources. The \l PropertyAnimation documentation shows a variety of methods + for creating animations. \sa {QML Animation}, {declarative/animation/basics}{Animation basics example} */ @@ -1320,8 +1394,23 @@ QDeclarativeRotationAnimation::~QDeclarativeRotationAnimation() /*! \qmlproperty real RotationAnimation::from - This property holds the starting value. - If not set, then the value defined in the start state of the transition. + This property holds the starting number value. + + For example, the following animation is not applied until the \c angle value + has reached 100: + + \qml + Item { + states: [ ... ] + + transition: Transition { + RotationAnimation { properties: "angle"; from: 100; duration: 2000 } + } + } + \endqml + + If this value is not set, it defaults to the value defined in the start + state of the \l Transition. */ qreal QDeclarativeRotationAnimation::from() const { @@ -1337,7 +1426,9 @@ void QDeclarativeRotationAnimation::setFrom(qreal f) /*! \qmlproperty real RotationAnimation::to This property holds the ending value. - If not set, then the value defined in the end state of the transition or Behavior. + + If this value is not set, it defaults to the value defined in the end + state of the \l Transition or \l Behavior. */ qreal QDeclarativeRotationAnimation::to() const { @@ -1352,7 +1443,7 @@ void QDeclarativeRotationAnimation::setTo(qreal t) /*! \qmlproperty enumeration RotationAnimation::direction - The direction in which to rotate. + This property holds the direction of the rotation. Possible values are: @@ -1445,20 +1536,31 @@ QDeclarativeListProperty<QDeclarativeAbstractAnimation> QDeclarativeAnimationGro \qmlclass SequentialAnimation QDeclarativeSequentialAnimation \since 4.7 \inherits Animation - \brief The SequentialAnimation element allows you to run animations sequentially. + \brief The SequentialAnimation element allows animations to be run sequentially. - Animations controlled in SequentialAnimation will be run one after the other. + The SequentialAnimation and ParallelAnimation elements allow multiple + animations to be run together. Animations defined in a SequentialAnimation + are run one after the other, while animations defined in a ParallelAnimation + are run at the same time. - The following example chains two numeric animations together. The \c MyItem - object will animate from its current x position to 100, and then back to 0. + The following example runs two number animations in a sequence. The \l Rectangle + animates to a \c x position of 50, then to a \c y position of 50. - \code - SequentialAnimation { - NumberAnimation { target: MyItem; property: "x"; to: 100 } - NumberAnimation { target: MyItem; property: "x"; to: 0 } - } - \endcode + \snippet doc/src/snippets/declarative/sequentialanimation.qml 0 + + Animations defined within a \l Transition are automatically run in parallel, + so SequentialAnimation can be used to enclose the animations in a \l Transition + if this is the preferred behavior. + Like any other animation element, a SequentialAnimation can be applied in a + number of ways, including transitions, behaviors and property value + sources. The \l PropertyAnimation documentation shows a variety of methods + for creating animations. + + \note Once an animation has been grouped into a SequentialAnimation or + ParallelAnimation, it cannot be individually started and stopped; the + SequentialAnimation or ParallelAnimation must be started and stopped as a group. + \sa ParallelAnimation, {QML Animation}, {declarative/animation/basics}{Animation basics example} */ @@ -1507,19 +1609,26 @@ void QDeclarativeSequentialAnimation::transition(QDeclarativeStateActions &actio \qmlclass ParallelAnimation QDeclarativeParallelAnimation \since 4.7 \inherits Animation - \brief The ParallelAnimation element allows you to run animations in parallel. + \brief The ParallelAnimation element allows animations to be run in parallel. - Animations contained in ParallelAnimation will be run at the same time. + The SequentialAnimation and ParallelAnimation elements allow multiple + animations to be run together. Animations defined in a SequentialAnimation + are run one after the other, while animations defined in a ParallelAnimation + are run at the same time. - The following animation demonstrates animating the \c MyItem item - to (100,100) by animating the x and y properties in parallel. + The following animation runs two number animations in parallel. The \l Rectangle + moves to (50,50) by animating its \c x and \c y properties at the same time. - \code - ParallelAnimation { - NumberAnimation { target: MyItem; property: "x"; to: 100 } - NumberAnimation { target: MyItem; property: "y"; to: 100 } - } - \endcode + \snippet doc/src/snippets/declarative/parallelanimation.qml 0 + + Like any other animation element, a ParallelAnimation can be applied in a + number of ways, including transitions, behaviors and property value + sources. The \l PropertyAnimation documentation shows a variety of methods + for creating animations. + + \note Once an animation has been grouped into a SequentialAnimation or + ParallelAnimation, it cannot be individually started and stopped; the + SequentialAnimation or ParallelAnimation must be started and stopped as a group. \sa SequentialAnimation, {QML Animation}, {declarative/animation/basics}{Animation basics example} */ @@ -1618,59 +1727,60 @@ void QDeclarativePropertyAnimationPrivate::convertVariant(QVariant &variant, int \qmlclass PropertyAnimation QDeclarativePropertyAnimation \since 4.7 \inherits Animation - \brief The PropertyAnimation element allows you to animate property changes. + \brief The PropertyAnimation element animates changes in property values. + + PropertyAnimation provides a way to animate changes to a property's value. - PropertyAnimation provides a way to animate changes to a property's value. It can - be used in many different situations: + It can be used to define animations in a number of ways: + \list - \o In a Transition + \o In a \l Transition + + For example, to animate any objects that have changed their \c x or \c y properties + as a result of a state change, using an \c InOutQuad easing curve: + + \snippet doc/src/snippets/declarative/propertyanimation.qml transition + + + \o In a \l Behavior + + For example, to animate all changes to a rectangle's \c x property: + + \snippet doc/src/snippets/declarative/propertyanimation.qml behavior - Animate any objects that have changed their x or y properties in the target state using - an InOutQuad easing curve: - \qml - Transition { PropertyAnimation { properties: "x,y"; easing.type: Easing.InOutQuad } } - \endqml - \o In a Behavior - Animate all changes to a rectangle's x property. - \qml - Rectangle { - Behavior on x { PropertyAnimation {} } - } - \endqml \o As a property value source - Repeatedly animate the rectangle's x property. - \qml - Rectangle { - SequentialAnimation on x { - loops: Animation.Infinite - PropertyAnimation { to: 50 } - PropertyAnimation { to: 0 } - } - } - \endqml + For example, to repeatedly animate the rectangle's \c x property: + + \snippet doc/src/snippets/declarative/propertyanimation.qml propertyvaluesource + + \o In a signal handler - Fade out \c theObject when clicked: + For example, to fade out \c theObject when clicked: \qml MouseArea { anchors.fill: theObject onClicked: PropertyAnimation { target: theObject; property: "opacity"; to: 0 } } \endqml + \o Standalone - Animate \c theObject's size property over 200ms, from its current size to 20-by-20: - \qml - PropertyAnimation { target: theObject; property: "size"; to: "20x20"; duration: 200 } - \endqml + For example, to animate \c rect's \c width property over 500ms, from its current width to 30: + + \snippet doc/src/snippets/declarative/propertyanimation.qml standalone + \endlist Depending on how the animation is used, the set of properties normally used will be different. For more information see the individual property documentation, as well as the \l{QML Animation} introduction. + Note that PropertyAnimation inherits the abstract \l Animation element. + This includes additional properties and methods for controlling the animation. + \sa {QML Animation}, {declarative/animation/basics}{Animation basics example} */ @@ -1827,15 +1937,15 @@ void QDeclarativePropertyAnimation::setTo(const QVariant &t) \o \inlineimage qeasingcurve-inquart.png \row \o \c Easing.OutQuart - \o Easing curve for a cubic (t^4) function: decelerating from zero velocity. + \o Easing curve for a quartic (t^4) function: decelerating from zero velocity. \o \inlineimage qeasingcurve-outquart.png \row \o \c Easing.InOutQuart - \o Easing curve for a cubic (t^4) function: acceleration until halfway, then deceleration. + \o Easing curve for a quartic (t^4) function: acceleration until halfway, then deceleration. \o \inlineimage qeasingcurve-inoutquart.png \row \o \c Easing.OutInQuart - \o Easing curve for a cubic (t^4) function: deceleration until halfway, then acceleration. + \o Easing curve for a quartic (t^4) function: deceleration until halfway, then acceleration. \o \inlineimage qeasingcurve-outinquart.png \row \o \c Easing.InQuint @@ -1843,15 +1953,15 @@ void QDeclarativePropertyAnimation::setTo(const QVariant &t) \o \inlineimage qeasingcurve-inquint.png \row \o \c Easing.OutQuint - \o Easing curve for a cubic (t^5) function: decelerating from zero velocity. + \o Easing curve for a quintic (t^5) function: decelerating from zero velocity. \o \inlineimage qeasingcurve-outquint.png \row \o \c Easing.InOutQuint - \o Easing curve for a cubic (t^5) function: acceleration until halfway, then deceleration. + \o Easing curve for a quintic (t^5) function: acceleration until halfway, then deceleration. \o \inlineimage qeasingcurve-inoutquint.png \row \o \c Easing.OutInQuint - \o Easing curve for a cubic (t^5) function: deceleration until halfway, then acceleration. + \o Easing curve for a quintic (t^5) function: deceleration until halfway, then acceleration. \o \inlineimage qeasingcurve-outinquint.png \row \o \c Easing.InSine @@ -1969,17 +2079,16 @@ void QDeclarativePropertyAnimation::setTo(const QVariant &t) QEasingCurve QDeclarativePropertyAnimation::easing() const { Q_D(const QDeclarativePropertyAnimation); - return d->easing; + return d->va->easingCurve(); } void QDeclarativePropertyAnimation::setEasing(const QEasingCurve &e) { Q_D(QDeclarativePropertyAnimation); - if (d->easing == e) + if (d->va->easingCurve() == e) return; - d->easing = e; - d->va->setEasingCurve(d->easing); + d->va->setEasingCurve(e); emit easingChanged(e); } @@ -1995,7 +2104,7 @@ void QDeclarativePropertyAnimation::setTarget(QObject *o) if (d->target == o) return; d->target = o; - emit targetChanged(d->target, d->propertyName); + emit targetChanged(); } QString QDeclarativePropertyAnimation::property() const @@ -2010,7 +2119,7 @@ void QDeclarativePropertyAnimation::setProperty(const QString &n) if (d->propertyName == n) return; d->propertyName = n; - emit targetChanged(d->target, d->propertyName); + emit propertyChanged(); } QString QDeclarativePropertyAnimation::properties() const @@ -2285,43 +2394,30 @@ void QDeclarativePropertyAnimation::transition(QDeclarativeStateActions &actions \qmlclass ParentAnimation QDeclarativeParentAnimation \since 4.7 \inherits Animation - \brief The ParentAnimation element allows you to animate parent changes. + \brief The ParentAnimation element animates changes in parent values. - ParentAnimation is used in conjunction with NumberAnimation to smoothly - animate changing an item's parent. In the following example, - ParentAnimation wraps a NumberAnimation which animates from the - current position in the old parent to the new position in the new - parent. + ParentAnimation defines an animation to applied when a ParentChange + occurs. This allows parent changes to be smoothly animated. - \qml - ... - State { - //reparent myItem to newParent. myItem's final location - //should be 10,10 in newParent. - ParentChange { - target: myItem - parent: newParent - x: 10; y: 10 - } - } - ... - Transition { - //smoothly reparent myItem and move into new position - ParentAnimation { - target: theItem - NumberAnimation { properties: "x,y" } - } - } - \endqml + For example, the following ParentChange changes \c blueRect to become + a child of \c redRect when it is clicked. The inclusion of the + ParentAnimation, which defines a NumberAnimation to be applied during + the transition, ensures the item animates smoothly as it moves to + its new parent: - ParentAnimation can wrap any number of animations -- those animations will - be run in parallel (like those in a ParallelAnimation group). + \snippet doc/src/snippets/declarative/parentanimation.qml 0 - In some cases, such as reparenting between items with clipping, it's useful - to animate the parent change via another item with no clipping. + A ParentAnimation can contain any number of animations. These animations will + be run in parallel; to run them sequentially, define them within a + SequentialAnimation. - When used in a transition, ParentAnimation will by default animate - all ParentChanges. + In some cases, such as when reparenting between items with clipping enabled, it is useful + to animate the parent change via another item that does not have clipping + enabled. Such an item can be set using the \l via property. + + By default, when used in a transition, ParentAnimation animates all parent + changes. This can be overridden by setting a specific target item using the + \l target property. \sa {QML Animation}, {declarative/animation/basics}{Animation basics example} */ @@ -2358,8 +2454,8 @@ QDeclarativeParentAnimation::~QDeclarativeParentAnimation() \qmlproperty Item ParentAnimation::target The item to reparent. - When used in a transition, if no target is specified all - ParentChanges will be animated by the ParentAnimation. + When used in a transition, if no target is specified, all + ParentChange occurrences are animated by the ParentAnimation. */ QDeclarativeItem *QDeclarativeParentAnimation::target() const { @@ -2402,7 +2498,7 @@ void QDeclarativeParentAnimation::setNewParent(QDeclarativeItem *newParent) /*! \qmlproperty Item ParentAnimation::via The item to reparent via. This provides a way to do an unclipped animation - when both the old parent and new parent are clipped + when both the old parent and new parent are clipped. \qml ParentAnimation { @@ -2652,28 +2748,14 @@ QAbstractAnimation *QDeclarativeParentAnimation::qtAnimation() \qmlclass AnchorAnimation QDeclarativeAnchorAnimation \since 4.7 \inherits Animation - \brief The AnchorAnimation element allows you to animate anchor changes. + \brief The AnchorAnimation element animates changes in anchor values. - AnchorAnimation will animated any changes specified by a state's AnchorChanges. - In the following snippet we animate the addition of a right anchor to our item. - \qml - Item { - id: myItem - width: 100 - } - ... - State { - AnchorChanges { - target: myItem - anchors.right: container.right - } - } - ... - Transition { - //smoothly reanchor myItem and move into new position - AnchorAnimation {} - } - \endqml + AnchorAnimation is used to animate an AnchorChange. It will anchor all + anchor changes specified in a \l State. + + In the following snippet we animate the addition of a right anchor to a \l Rectangle: + + \snippet doc/src/snippets/declarative/anchoranimation.qml 0 \sa AnchorChanges */ diff --git a/src/declarative/util/qdeclarativeanimation_p.h b/src/declarative/util/qdeclarativeanimation_p.h index 59bd465..481c36c 100644 --- a/src/declarative/util/qdeclarativeanimation_p.h +++ b/src/declarative/util/qdeclarativeanimation_p.h @@ -197,7 +197,7 @@ class QDeclarativePropertyAction : public QDeclarativeAbstractAnimation Q_DECLARE_PRIVATE(QDeclarativePropertyAction) Q_PROPERTY(QObject *target READ target WRITE setTarget NOTIFY targetChanged) - Q_PROPERTY(QString property READ property WRITE setProperty NOTIFY targetChanged) + Q_PROPERTY(QString property READ property WRITE setProperty NOTIFY propertyChanged) Q_PROPERTY(QString properties READ properties WRITE setProperties NOTIFY propertiesChanged) Q_PROPERTY(QDeclarativeListProperty<QObject> targets READ targets) Q_PROPERTY(QDeclarativeListProperty<QObject> exclude READ exclude) @@ -225,7 +225,8 @@ public: Q_SIGNALS: void valueChanged(const QVariant &); void propertiesChanged(const QString &); - void targetChanged(QObject *, const QString &); + void targetChanged(); + void propertyChanged(); protected: virtual void transition(QDeclarativeStateActions &actions, @@ -246,7 +247,7 @@ class Q_AUTOTEST_EXPORT QDeclarativePropertyAnimation : public QDeclarativeAbstr Q_PROPERTY(QVariant to READ to WRITE setTo NOTIFY toChanged) Q_PROPERTY(QEasingCurve easing READ easing WRITE setEasing NOTIFY easingChanged) Q_PROPERTY(QObject *target READ target WRITE setTarget NOTIFY targetChanged) - Q_PROPERTY(QString property READ property WRITE setProperty NOTIFY targetChanged) + Q_PROPERTY(QString property READ property WRITE setProperty NOTIFY propertyChanged) Q_PROPERTY(QString properties READ properties WRITE setProperties NOTIFY propertiesChanged) Q_PROPERTY(QDeclarativeListProperty<QObject> targets READ targets) Q_PROPERTY(QDeclarativeListProperty<QObject> exclude READ exclude) @@ -292,7 +293,8 @@ Q_SIGNALS: void toChanged(QVariant); void easingChanged(const QEasingCurve &); void propertiesChanged(const QString &); - void targetChanged(QObject *, const QString &); + void targetChanged(); + void propertyChanged(); }; class Q_AUTOTEST_EXPORT QDeclarativeColorAnimation : public QDeclarativePropertyAnimation diff --git a/src/declarative/util/qdeclarativeanimation_p_p.h b/src/declarative/util/qdeclarativeanimation_p_p.h index b6d6bbb..e38580c 100644 --- a/src/declarative/util/qdeclarativeanimation_p_p.h +++ b/src/declarative/util/qdeclarativeanimation_p_p.h @@ -311,8 +311,6 @@ public: QVariant from; QVariant to; - QEasingCurve easing; - QObject *target; QString propertyName; QString properties; diff --git a/src/declarative/util/qdeclarativebehavior.cpp b/src/declarative/util/qdeclarativebehavior.cpp index 2bb28c3..fadb2ae 100644 --- a/src/declarative/util/qdeclarativebehavior.cpp +++ b/src/declarative/util/qdeclarativebehavior.cpp @@ -75,28 +75,21 @@ public: \since 4.7 \brief The Behavior element allows you to specify a default animation for a property change. - Behaviors provide one way to specify \l{qdeclarativeanimation.html}{animations} in QML. - - In the example below, the rectangle will use a bounce easing curve over 200 millisecond for any changes to its y property: - \code - Rectangle { - width: 20; height: 20 - color: "#00ff00" - y: 200 // initial value - Behavior on y { - NumberAnimation { - easing.type: Easing.OutBounce - easing.amplitude: 100 - duration: 200 - } - } - } - \endcode + A Behavior defines the default animation to be applied whenever a + particular property value changes. + + For example, the following Behavior defines a NumberAnimation to be run + whenever the \l Rectangle's \c width value changes. When the MouseArea + is clicked, the \c width is changed, triggering the behavior's animation: + + \snippet doc/src/snippets/declarative/behavior.qml 0 - Currently only a single Behavior may be specified for a property; - this Behavior can be enabled and disabled via the \l{enabled} property. + To run multiple animations within a Behavior, use ParallelAnimation or + SequentialAnimation. - \sa {declarative/animation/behaviors}{Behavior example}, QtDeclarative + Note that a property cannot have more than one assigned Behavior. + + \sa {Property Behaviors}, {declarative/animation/behaviors}{Behavior example}, QtDeclarative */ @@ -113,7 +106,7 @@ QDeclarativeBehavior::~QDeclarativeBehavior() \qmlproperty Animation Behavior::animation \default - The animation to use when the behavior is triggered. + This property holds the animation to run when the behavior is triggered. */ QDeclarativeAbstractAnimation *QDeclarativeBehavior::animation() @@ -152,7 +145,9 @@ void QDeclarativeBehavior::qtAnimationStateChanged(QAbstractAnimation::State new /*! \qmlproperty bool Behavior::enabled - Whether the Behavior will be triggered when the property it is tracking changes. + + This property holds whether the behavior will be triggered when the tracked + property changes value. By default a Behavior is enabled. */ @@ -182,7 +177,7 @@ void QDeclarativeBehavior::write(const QVariant &value) return; } - if (value == d->targetValue) + if (d->animation->isRunning() && value == d->targetValue) return; d->currentValue = d->property.read(); diff --git a/src/declarative/util/qdeclarativeopenmetaobject.cpp b/src/declarative/util/qdeclarativeopenmetaobject.cpp index ba5d534..40485bd 100644 --- a/src/declarative/util/qdeclarativeopenmetaobject.cpp +++ b/src/declarative/util/qdeclarativeopenmetaobject.cpp @@ -161,6 +161,12 @@ public: prop.second = true; } + inline bool hasData(int idx) const { + if (idx >= data.count()) + return false; + return data[idx].second; + } + bool autoCreate; QDeclarativeOpenMetaObject *q; QAbstractDynamicMetaObject *parent; @@ -295,6 +301,12 @@ void QDeclarativeOpenMetaObject::setValue(const QByteArray &name, const QVariant activate(d->object, id + d->type->d->signalOffset, 0); } +// returns true if this value has been initialized by a call to either value() or setValue() +bool QDeclarativeOpenMetaObject::hasValue(int id) const +{ + return d->hasData(id); +} + void QDeclarativeOpenMetaObject::setCached(bool c) { if (c == d->cacheProperties || !d->type->d->engine) diff --git a/src/declarative/util/qdeclarativeopenmetaobject_p.h b/src/declarative/util/qdeclarativeopenmetaobject_p.h index 9bb4c34..c18fa3d 100644 --- a/src/declarative/util/qdeclarativeopenmetaobject_p.h +++ b/src/declarative/util/qdeclarativeopenmetaobject_p.h @@ -91,6 +91,7 @@ public: void setValue(int, const QVariant &); QVariant &operator[](const QByteArray &); QVariant &operator[](int); + bool hasValue(int) const; int count() const; QByteArray name(int) const; diff --git a/src/declarative/util/qdeclarativepixmapcache.cpp b/src/declarative/util/qdeclarativepixmapcache.cpp index 00dd922..9ced14f 100644 --- a/src/declarative/util/qdeclarativepixmapcache.cpp +++ b/src/declarative/util/qdeclarativepixmapcache.cpp @@ -70,6 +70,16 @@ QT_BEGIN_NAMESPACE +// The cache limit describes the maximum "junk" in the cache. +// These are the same defaults as QPixmapCache +#if defined(Q_OS_SYMBIAN) +static int cache_limit = 1024 * 1024; // 1048 KB cache limit for symbian +#elif defined(Q_WS_QWS) || defined(Q_WS_WINCE) +static int cache_limit = 2048 * 1024; // 2048 KB cache limit for embedded +#else +static int cache_limit = 10240 * 1024; // 10 MB cache limit for desktop +#endif + class QDeclarativePixmapReader; class QDeclarativePixmapData; class QDeclarativePixmapReply : public QObject @@ -114,6 +124,18 @@ public: static int downloadProgressIndex; }; +class QDeclarativePixmapReaderThreadObject : public QObject { + Q_OBJECT +public: + QDeclarativePixmapReaderThreadObject(QDeclarativePixmapReader *); + void processJobs(); + virtual bool event(QEvent *e); +private slots: + void networkRequestDone(); +private: + QDeclarativePixmapReader *reader; +}; + class QDeclarativePixmapData; class QDeclarativePixmapReader : public QThread { @@ -130,12 +152,11 @@ public: protected: void run(); -private slots: - void networkRequestDone(); - private: + friend class QDeclarativePixmapReaderThreadObject; void processJobs(); void processJob(QDeclarativePixmapReply *); + void networkRequestDone(QNetworkReply *); QList<QDeclarativePixmapReply*> jobs; QList<QDeclarativePixmapReply*> cancelled; @@ -143,14 +164,7 @@ private: QObject *eventLoopQuitHack; QMutex mutex; - class ThreadObject : public QObject { - public: - ThreadObject(QDeclarativePixmapReader *); - void processJobs(); - virtual bool event(QEvent *e); - private: - QDeclarativePixmapReader *reader; - } *threadObject; + QDeclarativePixmapReaderThreadObject *threadObject; QWaitCondition waitCondition; QNetworkAccessManager *networkAccessManager(); @@ -161,7 +175,7 @@ private: static int replyDownloadProgress; static int replyFinished; static int downloadProgress; - static int thisNetworkRequestDone; + static int threadNetworkRequestDone; static QHash<QDeclarativeEngine *,QDeclarativePixmapReader*> readers; static QMutex readerMutex; }; @@ -232,7 +246,7 @@ QMutex QDeclarativePixmapReader::readerMutex; int QDeclarativePixmapReader::replyDownloadProgress = -1; int QDeclarativePixmapReader::replyFinished = -1; int QDeclarativePixmapReader::downloadProgress = -1; -int QDeclarativePixmapReader::thisNetworkRequestDone = -1; +int QDeclarativePixmapReader::threadNetworkRequestDone = -1; void QDeclarativePixmapReply::postReply(ReadError error, const QString &errorString, @@ -317,9 +331,8 @@ QDeclarativePixmapReader::~QDeclarativePixmapReader() wait(); } -void QDeclarativePixmapReader::networkRequestDone() +void QDeclarativePixmapReader::networkRequestDone(QNetworkReply *reply) { - QNetworkReply *reply = static_cast<QNetworkReply *>(sender()); QDeclarativePixmapReply *job = replies.take(reply); if (job) { @@ -335,7 +348,7 @@ void QDeclarativePixmapReader::networkRequestDone() reply = networkAccessManager()->get(req); QMetaObject::connect(reply, replyDownloadProgress, job, downloadProgress); - QMetaObject::connect(reply, replyFinished, this, thisNetworkRequestDone); + QMetaObject::connect(reply, replyFinished, threadObject, threadNetworkRequestDone); replies.insert(reply, job); return; @@ -368,17 +381,17 @@ void QDeclarativePixmapReader::networkRequestDone() threadObject->processJobs(); } -QDeclarativePixmapReader::ThreadObject::ThreadObject(QDeclarativePixmapReader *i) +QDeclarativePixmapReaderThreadObject::QDeclarativePixmapReaderThreadObject(QDeclarativePixmapReader *i) : reader(i) { } -void QDeclarativePixmapReader::ThreadObject::processJobs() +void QDeclarativePixmapReaderThreadObject::processJobs() { QCoreApplication::postEvent(this, new QEvent(QEvent::User)); } -bool QDeclarativePixmapReader::ThreadObject::event(QEvent *e) +bool QDeclarativePixmapReaderThreadObject::event(QEvent *e) { if (e->type() == QEvent::User) { reader->processJobs(); @@ -388,6 +401,12 @@ bool QDeclarativePixmapReader::ThreadObject::event(QEvent *e) } } +void QDeclarativePixmapReaderThreadObject::networkRequestDone() +{ + QNetworkReply *reply = static_cast<QNetworkReply *>(sender()); + reader->networkRequestDone(reply); +} + void QDeclarativePixmapReader::processJobs() { QMutexLocker locker(&mutex); @@ -469,7 +488,7 @@ void QDeclarativePixmapReader::processJob(QDeclarativePixmapReply *runningJob) QNetworkReply *reply = networkAccessManager()->get(req); QMetaObject::connect(reply, replyDownloadProgress, runningJob, downloadProgress); - QMetaObject::connect(reply, replyFinished, this, thisNetworkRequestDone); + QMetaObject::connect(reply, replyFinished, threadObject, threadNetworkRequestDone); replies.insert(reply, runningJob); } @@ -520,15 +539,15 @@ void QDeclarativePixmapReader::run() if (replyDownloadProgress == -1) { const QMetaObject *nr = &QNetworkReply::staticMetaObject; const QMetaObject *pr = &QDeclarativePixmapReply::staticMetaObject; - const QMetaObject *ir = &QDeclarativePixmapReader::staticMetaObject; + const QMetaObject *ir = &QDeclarativePixmapReaderThreadObject::staticMetaObject; replyDownloadProgress = nr->indexOfSignal("downloadProgress(qint64,qint64)"); replyFinished = nr->indexOfSignal("finished()"); downloadProgress = pr->indexOfSignal("downloadProgress(qint64,qint64)"); - thisNetworkRequestDone = ir->indexOfSlot("networkRequestDone()"); + threadNetworkRequestDone = ir->indexOfSlot("networkRequestDone()"); } mutex.lock(); - threadObject = new ThreadObject(this); + threadObject = new QDeclarativePixmapReaderThreadObject(this); mutex.unlock(); processJobs(); @@ -571,6 +590,8 @@ public: QHash<QDeclarativePixmapKey, QDeclarativePixmapData *> m_cache; private: + void shrinkCache(int remove); + QDeclarativePixmapData *m_unreferencedPixmaps; QDeclarativePixmapData *m_lastUnreferencedPixmap; @@ -604,8 +625,10 @@ void QDeclarativePixmapStore::unreferencePixmap(QDeclarativePixmapData *data) m_unreferencedCost += data->cost(); - if (m_timerId == -1) - startTimer(CACHE_EXPIRE_TIME * 1000); + shrinkCache(-1); // Shrink the cache incase it has become larger than cache_limit + + if (m_timerId == -1 && m_unreferencedPixmaps) + m_timerId = startTimer(CACHE_EXPIRE_TIME * 1000); } void QDeclarativePixmapStore::referencePixmap(QDeclarativePixmapData *data) @@ -627,11 +650,9 @@ void QDeclarativePixmapStore::referencePixmap(QDeclarativePixmapData *data) m_unreferencedCost -= data->cost(); } -void QDeclarativePixmapStore::timerEvent(QTimerEvent *) +void QDeclarativePixmapStore::shrinkCache(int remove) { - int removalCost = m_unreferencedCost / CACHE_REMOVAL_FRACTION; - - while (removalCost > 0 && m_lastUnreferencedPixmap) { + while ((remove > 0 || m_unreferencedCost > cache_limit) && m_lastUnreferencedPixmap) { QDeclarativePixmapData *data = m_lastUnreferencedPixmap; Q_ASSERT(data->nextUnreferenced == 0); @@ -640,10 +661,17 @@ void QDeclarativePixmapStore::timerEvent(QTimerEvent *) data->prevUnreferencedPtr = 0; data->prevUnreferenced = 0; - removalCost -= data->cost(); + remove -= data->cost(); data->removeFromCache(); delete data; } +} + +void QDeclarativePixmapStore::timerEvent(QTimerEvent *) +{ + int removalCost = m_unreferencedCost / CACHE_REMOVAL_FRACTION; + + shrinkCache(removalCost); if (m_unreferencedPixmaps == 0) { killTimer(m_timerId); @@ -693,7 +721,7 @@ bool QDeclarativePixmapReply::event(QEvent *event) int QDeclarativePixmapData::cost() const { - return pixmap.width() * pixmap.height() * pixmap.depth(); + return (pixmap.width() * pixmap.height() * pixmap.depth()) / 8; } void QDeclarativePixmapData::addref() diff --git a/src/declarative/util/qdeclarativesmoothedanimation.cpp b/src/declarative/util/qdeclarativesmoothedanimation.cpp index 5d47c30..727f427 100644 --- a/src/declarative/util/qdeclarativesmoothedanimation.cpp +++ b/src/declarative/util/qdeclarativesmoothedanimation.cpp @@ -253,15 +253,22 @@ void QSmoothedAnimation::init() \inherits NumberAnimation \brief The SmoothedAnimation element allows a property to smoothly track a value. - The SmoothedAnimation animates a property's value to a set target value - using an ease in/out quad easing curve. If the animation is restarted - with a different target value, the easing curves used to animate to the old - and the new target values are smoothly spliced together to avoid any obvious - visual glitches by maintaining the current velocity. - - The property animation is configured by setting the velocity at which the - animation should occur, or the duration that the animation should take. - If both a velocity and a duration are specified, the one that results in + A SmoothedAnimation animates a property's value to a set target value + using an ease in/out quad easing curve. When the target value changes, + the easing curves used to animate between the old and new target values + are smoothly spliced together to create a smooth movement to the new + target value that maintains the current velocity. + + The follow example shows one \l Rectangle tracking the position of another + using SmoothedAnimation. The green rectangle's \c x and \c y values are + bound to those of the red rectangle. Whenever these values change, the + green rectangle smoothly animates to its new position: + + \snippet doc/src/snippets/declarative/smoothedanimation.qml 0 + + A SmoothedAnimation can be configured by setting the \l velocity at which the + animation should occur, or the \l duration that the animation should take. + If both the \l velocity and \l duration are specified, the one that results in the quickest animation is chosen for each change in the target value. For example, animating from 0 to 800 will take 4 seconds if a velocity @@ -271,35 +278,6 @@ void QSmoothedAnimation::init() will take 8 seconds with a duration of 8000 set, and will take 8 seconds with both a velocity of 200 and a duration of 8000 set. - The follow example shows one rectangle tracking the position of another. -\code -import Qt 4.7 - -Rectangle { - width: 800; height: 600; color: "blue" - - Rectangle { - color: "green" - width: 60; height: 60; - x: rect1.x - 5; y: rect1.y - 5; - Behavior on x { SmoothedAnimation { velocity: 200 } } - Behavior on y { SmoothedAnimation { velocity: 200 } } - } - - Rectangle { - id: rect1 - color: "red" - width: 50; height: 50; - } - - focus: true - Keys.onRightPressed: rect1.x = rect1.x + 100 - Keys.onLeftPressed: rect1.x = rect1.x - 100 - Keys.onUpPressed: rect1.y = rect1.y - 100 - Keys.onDownPressed: rect1.y = rect1.y + 100 -} -\endcode - The default velocity of SmoothedAnimation is 200 units/second. Note that if the range of the value being animated is small, then the velocity will need to be adjusted appropriately. For example, the opacity of an item ranges from 0 - 1.0. @@ -307,7 +285,12 @@ Rectangle { set to a value such as 0.5 units/second. Animating from 0 to 1.0 with a velocity of 0.5 will take 2000 ms to complete. - \sa {QML Animation}, {declarative/animation/basics}{Animation basics example} + Like any other animation element, a SmoothedAnimation can be applied in a + number of ways, including transitions, behaviors and property value + sources. The \l PropertyAnimation documentation shows a variety of methods + for creating animations. + + \sa SpringAnimation, NumberAnimation, {QML Animation}, {declarative/animation/basics}{Animation basics example} */ QDeclarativeSmoothedAnimation::QDeclarativeSmoothedAnimation(QObject *parent) @@ -388,11 +371,13 @@ void QDeclarativeSmoothedAnimation::transition(QDeclarativeStateActions &actions Sets how the SmoothedAnimation behaves if an animation direction is reversed. - If reversing mode is \c SmoothedAnimation.Eased, the animation will smoothly decelerate, and - then reverse direction. If the reversing mode is \c SmoothedAnimation.Immediate, the - animation will immediately begin accelerating in the reverse direction, - begining with a velocity of 0. If the reversing mode is \c SmoothedAnimation.Sync, the - property is immediately set to the target value. + Possible values are: + + \list + \o SmoothedAnimation.Eased (default) - the animation will smoothly decelerate, and then reverse direction + \o SmoothedAnimation.Immediate - the animation will immediately begin accelerating in the reverse direction, beginning with a velocity of 0 + \o SmoothedAnimation.Sync - the property is immediately set to the target value + \endlist */ QDeclarativeSmoothedAnimation::ReversingMode QDeclarativeSmoothedAnimation::reversingMode() const { diff --git a/src/declarative/util/qdeclarativespringanimation.cpp b/src/declarative/util/qdeclarativespringanimation.cpp index 4cf2fc0..8ce4832 100644 --- a/src/declarative/util/qdeclarativespringanimation.cpp +++ b/src/declarative/util/qdeclarativespringanimation.cpp @@ -207,14 +207,26 @@ void QDeclarativeSpringAnimationPrivate::updateMode() \qmlclass SpringAnimation QDeclarativeSpringAnimation \since 4.7 - \brief The SpringAnimation element allows a property to track a value in a spring-like motion + \brief The SpringAnimation element allows a property to track a value in a spring-like motion. SpringAnimation mimics the oscillatory behavior of a spring, with the appropriate \l spring constant to control the acceleration and the \l damping to control how quickly the effect dies away. You can also limit the maximum \l velocity of the animation. + The following \l Rectangle moves to the position of the mouse using a + SpringAnimation when the mouse is clicked. The use of the \l Behavior + on the \c x and \c y values indicates that whenever these values are + changed, a SpringAnimation should be applied. + \snippet doc/src/snippets/declarative/springanimation.qml 0 + + Like any other animation element, a SpringAnimation can be applied in a + number of ways, including transitions, behaviors and property value + sources. The \l PropertyAnimation documentation shows a variety of methods + for creating animations. + + \sa SmoothedAnimation, {QML Animation}, {declarative/animation/basics}{Animation basics example}, {declarative/toys/clocks}{Clocks example} */ QDeclarativeSpringAnimation::QDeclarativeSpringAnimation(QObject *parent) @@ -244,6 +256,11 @@ qreal QDeclarativeSpringAnimation::to() const /*! \qmlproperty real SpringAnimation::to + + This property holds the value at which the animation will end. + + If not set, the animation will continue until it reaches the + value that is being tracked. */ void QDeclarativeSpringAnimation::setTo(qreal value) @@ -266,6 +283,11 @@ qreal QDeclarativeSpringAnimation::from() const /*! \qmlproperty real SpringAnimation::from + + This property holds the value from which the animation will begin. + + If not set, the animation will start whenever the tracked value has + changed, regardless of its value. */ void QDeclarativeSpringAnimation::setFrom(qreal value) @@ -283,7 +305,10 @@ void QDeclarativeSpringAnimation::setFrom(qreal value) /*! \qmlproperty real SpringAnimation::velocity + This property holds the maximum velocity allowed when tracking the source. + + The default value is 0 (no maximum velocity). */ qreal QDeclarativeSpringAnimation::velocity() const @@ -302,13 +327,14 @@ void QDeclarativeSpringAnimation::setVelocity(qreal velocity) /*! \qmlproperty real SpringAnimation::spring - This property holds the spring constant - The spring constant describes how strongly the target is pulled towards the - source. Setting spring to 0 turns off spring tracking. Useful values 0 - 5.0 + This property describes how strongly the target is pulled towards the + source. The default value is 0 (that is, the spring-like motion is disabled). + + The useful value range is 0 - 5.0. - When a spring constant is set and the velocity property is greater than 0, - velocity limits the maximum speed. + When this property is set and the \l velocity value is greater than 0, + the \l velocity limits the maximum speed. */ qreal QDeclarativeSpringAnimation::spring() const { @@ -325,10 +351,13 @@ void QDeclarativeSpringAnimation::setSpring(qreal spring) /*! \qmlproperty real SpringAnimation::damping - This property holds the spring damping constant + This property holds the spring damping value. + + This value describes how quickly the spring-like motion comes to rest. + The default value is 0. - The damping constant describes how quickly a sprung follower comes to rest. - Useful range is 0 - 1.0 + The useful value range is 0 - 1.0. The lower the value, the faster it + comes to rest. */ qreal QDeclarativeSpringAnimation::damping() const { @@ -348,7 +377,7 @@ void QDeclarativeSpringAnimation::setDamping(qreal damping) /*! \qmlproperty real SpringAnimation::epsilon - This property holds the spring epsilon + This property holds the spring epsilon. The epsilon is the rate and amount of change in the value which is close enough to 0 to be considered equal to zero. This will depend on the usage of the value. @@ -370,7 +399,7 @@ void QDeclarativeSpringAnimation::setEpsilon(qreal epsilon) /*! \qmlproperty real SpringAnimation::modulus - This property holds the modulus value. + This property holds the modulus value. The default value is 0. Setting a \a modulus forces the target value to "wrap around" at the modulus. For example, setting the modulus to 360 will cause a value of 370 to wrap around to 10. @@ -395,8 +424,10 @@ void QDeclarativeSpringAnimation::setModulus(qreal modulus) \qmlproperty real SpringAnimation::mass This property holds the "mass" of the property being moved. - mass is 1.0 by default. Setting a different mass changes the dynamics of - a \l spring follow. + The value is 1.0 by default. + + A greater mass causes slower movement and a greater spring-like + motion when an item comes to rest. */ qreal QDeclarativeSpringAnimation::mass() const { diff --git a/src/declarative/util/qdeclarativestate.cpp b/src/declarative/util/qdeclarativestate.cpp index ae19a9c..0d43d21 100644 --- a/src/declarative/util/qdeclarativestate.cpp +++ b/src/declarative/util/qdeclarativestate.cpp @@ -144,7 +144,7 @@ QDeclarativeStateOperation::QDeclarativeStateOperation(QObjectPrivate &dd, QObje 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 + The following example displays a single \l 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 @@ -157,7 +157,7 @@ QDeclarativeStateOperation::QDeclarativeStateOperation(QObjectPrivate &dd, QObje 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 + \note Setting the state of an object from within another state of the same object is not allowed. \sa {declarative/animation/states}{states example}, {qmlstates}{States}, {state-transitions}{Transitions}, QtDeclarative @@ -194,7 +194,7 @@ QDeclarativeState::~QDeclarativeState() \qmlproperty string State::name This property holds the name of the state. - Each state should have a unique name. + Each state should have a unique name within its item. */ QString QDeclarativeState::name() const { @@ -226,7 +226,10 @@ bool QDeclarativeState::isWhenKnown() const This property holds when the state should be applied. This should be set to an expression that evaluates to \c true when you want the state to - be applied. + be applied. For example, the following \l Rectangle changes in and out of the "hidden" + state when the \l MouseArea is pressed: + + \snippet doc/src/snippets/declarative/state-when.qml 0 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 @@ -342,8 +345,10 @@ QDeclarativeStatePrivate::generateActionList(QDeclarativeStateGroup *group) cons if (!extends.isEmpty()) { QList<QDeclarativeState *> states = group->states(); for (int ii = 0; ii < states.count(); ++ii) - if (states.at(ii)->name() == extends) + if (states.at(ii)->name() == extends) { + qmlExecuteDeferred(states.at(ii)); applyList = static_cast<QDeclarativeStatePrivate*>(states.at(ii)->d_func())->generateActionList(group); + } } foreach(QDeclarativeStateOperation *op, operations) diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp index 5590449..2291c16 100644 --- a/src/declarative/util/qdeclarativestateoperations.cpp +++ b/src/declarative/util/qdeclarativestateoperations.cpp @@ -1501,8 +1501,12 @@ void QDeclarativeAnchorChanges::rewind() d->target->setX(d->rewindX); d->target->setY(d->rewindY); - d->target->setWidth(d->rewindWidth); - d->target->setHeight(d->rewindHeight); + if (targetPrivate->widthValid) { + d->target->setWidth(d->rewindWidth); + } + if (targetPrivate->heightValid) { + d->target->setHeight(d->rewindHeight); + } } void QDeclarativeAnchorChanges::saveCurrentValues() diff --git a/src/declarative/util/qdeclarativetimeline.cpp b/src/declarative/util/qdeclarativetimeline.cpp index 0258b3c..378c539 100644 --- a/src/declarative/util/qdeclarativetimeline.cpp +++ b/src/declarative/util/qdeclarativetimeline.cpp @@ -524,7 +524,7 @@ int QDeclarativeTimeLine::duration() const Following operations on \a timeLineValue in this timeline will be scheduled after all the currently scheduled actions on \a syncTo are complete. In - psuedo-code this is equivalent to: + pseudo-code this is equivalent to: \code QDeclarativeTimeLine::pause(timeLineValue, min(0, length_of(syncTo) - length_of(timeLineValue))) \endcode @@ -549,7 +549,7 @@ void QDeclarativeTimeLine::sync(QDeclarativeTimeLineValue &timeLineValue, QDecla Synchronize the end point of \a timeLineValue to the endpoint of the longest action cursrently scheduled in the timeline. - In psuedo-code, this is equivalent to: + In pseudo-code, this is equivalent to: \code QDeclarativeTimeLine::pause(timeLineValue, length_of(timeline) - length_of(timeLineValue)) \endcode diff --git a/src/declarative/util/qdeclarativetimer.cpp b/src/declarative/util/qdeclarativetimer.cpp index 576995f..838a8f3 100644 --- a/src/declarative/util/qdeclarativetimer.cpp +++ b/src/declarative/util/qdeclarativetimer.cpp @@ -73,11 +73,12 @@ public: \since 4.7 \brief The Timer item triggers a handler at a specified interval. - A timer can be used to trigger an action either once, or repeatedly + A Timer can be used to trigger an action either once, or repeatedly at a given interval. - Here is a timer that shows the current date and time, and updates - the text every 500 milliseconds: + Here is a Timer that shows the current date and time, and updates + the text every 500 milliseconds. It uses the JavaScript \c Date + object to access the current time. \qml import Qt 4.7 @@ -88,9 +89,7 @@ public: onTriggered: time.text = Date().toString() } - Text { - id: time - } + Text { id: time } } \endqml diff --git a/src/declarative/util/qdeclarativetransition.cpp b/src/declarative/util/qdeclarativetransition.cpp index 38ed97e..582191b 100644 --- a/src/declarative/util/qdeclarativetransition.cpp +++ b/src/declarative/util/qdeclarativetransition.cpp @@ -56,6 +56,28 @@ QT_BEGIN_NAMESPACE \since 4.7 \brief The Transition element defines animated transitions that occur on state changes. + A Transition defines the animations to be applied when a \l State change occurs. + + For example, the following \l Rectangle has two states: the default state, and + an added "moved" state. In the "moved state, the rectangle's position changes + to (50, 50). The added \l Transition specifies that when the rectangle + changes between the default and the "moved" state, any changes + to the \c x and \c y properties should be animated, using an \c Easing.InOutQuad. + + \snippet doc/src/snippets/declarative/transition.qml 0 + + To define multiple transitions, specify \l Item::transitions as a list: + + \qml + Item { + ... + transitions: [ + Transition { ... }, + Transition { ... } + ] + } + \endqml + \sa {declarative/animation/states}{states example}, {qmlstates}{States}, {state-transitions}{Transitions}, {QtDeclarative} */ @@ -171,18 +193,31 @@ void QDeclarativeTransition::prepare(QDeclarativeStateOperation::ActionList &act /*! \qmlproperty string Transition::from \qmlproperty string Transition::to - These properties are selectors indicating which state changes should trigger the transition. - from is used in conjunction with to to determine when a transition should - be applied. By default from and to are both "*" (any state). In the following example, - the transition is applied when changing from state1 to state2. - \code - Transition { - from: "state1" - to: "state2" - ... + These properties indicate the state changes that trigger the transition. + + The default values for these properties is "*" (that is, any state). + + For example, the following transition has not set the \c to and \c from + properties, so the animation is always applied when changing between + the two states (i.e. when the mouse is pressed and released). + + \snippet doc/src/snippets/declarative/transition-from-to.qml 0 + + If the transition was changed to this: + + \qml + transitions: Transition { + to: "brighter" + ColorAnimation { duration: 1000 } + } } - \endcode + \endqml + + The animation would only be applied when changing from the default state to + the "brighter" state (i.e. when the mouse is pressed, but not on release). + + \sa reversible */ QString QDeclarativeTransition::fromState() const { @@ -205,6 +240,24 @@ void QDeclarativeTransition::setFromState(const QString &f) This property holds whether the transition should be automatically reversed when the conditions that triggered this transition are reversed. The default value is false. + + By default, transitions run in parallel and are applied to all state + changes if the \l from and \l to states have not been set. In this + situation, the transition is automatically applied when a state change + is reversed, and it is not necessary to set this property to reverse + the transition. + + However, if a SequentialAnimation is used, or if the \l from or \l to + properties have been set, this property will need to be set to reverse + a transition when a state change is reverted. For example, the following + transition applies a sequential animation when the mouse is pressed, + and reverses the sequence of the animation when the mouse is released: + + \snippet doc/src/snippets/declarative/transition-reversible.qml 0 + + If the transition did not set the \c to and \c reversible values, then + on the mouse release, the transition would play the PropertyAnimation + before the ColorAnimation instead of reversing the sequence. */ bool QDeclarativeTransition::reversible() const { @@ -241,12 +294,27 @@ void QDeclarativeTransition::setToState(const QString &t) /*! \qmlproperty list<Animation> Transition::animations \default + This property holds a list of the animations to be run for this transition. + \qml + Transition { + PropertyAnimation { ... } + NumberAnimation { ... } + } + \endqml + The top-level animations are run in parallel. To run them sequentially, - you can create a single SequentialAnimation which contains all the animations, - and assign that to animations the animations property. - \default + define them within a SequentialAnimation: + + \qml + Transition { + SequentialAnimation { + PropertyAnimation { ... } + NumberAnimation { ... } + } + } + \endqml */ QDeclarativeListProperty<QDeclarativeAbstractAnimation> QDeclarativeTransition::animations() { diff --git a/src/declarative/util/qdeclarativeview.cpp b/src/declarative/util/qdeclarativeview.cpp index 496f2ad..8f06858 100644 --- a/src/declarative/util/qdeclarativeview.cpp +++ b/src/declarative/util/qdeclarativeview.cpp @@ -132,7 +132,7 @@ class QDeclarativeViewPrivate : public QGraphicsViewPrivate, public QDeclarative public: QDeclarativeViewPrivate() : root(0), declarativeItemRoot(0), graphicsWidgetRoot(0), component(0), resizeMode(QDeclarativeView::SizeViewToRootObject), initialSize(0,0) {} - ~QDeclarativeViewPrivate() { delete root; } + ~QDeclarativeViewPrivate() { delete root; delete engine; } void execute(); void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry); void initResize(); @@ -145,7 +145,7 @@ public: QUrl source; - QDeclarativeEngine engine; + QDeclarativeEngine* engine; QDeclarativeComponent *component; QBasicTimer resizetimer; @@ -170,7 +170,7 @@ void QDeclarativeViewPrivate::execute() component = 0; } if (!source.isEmpty()) { - component = new QDeclarativeComponent(&engine, source, q); + component = new QDeclarativeComponent(engine, source, q); if (!component->isLoading()) { q->continueExecute(); } else { @@ -275,6 +275,7 @@ QDeclarativeView::QDeclarativeView(const QUrl &source, QWidget *parent) void QDeclarativeViewPrivate::init() { Q_Q(QDeclarativeView); + engine = new QDeclarativeEngine(); q->setScene(&scene); q->setOptimizationFlags(QGraphicsView::DontSavePainterState); @@ -338,10 +339,10 @@ QUrl QDeclarativeView::source() const Returns a pointer to the QDeclarativeEngine used for instantiating QML Components. */ -QDeclarativeEngine* QDeclarativeView::engine() +QDeclarativeEngine* QDeclarativeView::engine() const { - Q_D(QDeclarativeView); - return &d->engine; + Q_D(const QDeclarativeView); + return d->engine; } /*! @@ -351,10 +352,10 @@ QDeclarativeEngine* QDeclarativeView::engine() arranged hierarchically and this hierarchy is managed by the QDeclarativeEngine. */ -QDeclarativeContext* QDeclarativeView::rootContext() +QDeclarativeContext* QDeclarativeView::rootContext() const { - Q_D(QDeclarativeView); - return d->engine.rootContext(); + Q_D(const QDeclarativeView); + return d->engine->rootContext(); } /*! @@ -364,7 +365,7 @@ QDeclarativeContext* QDeclarativeView::rootContext() \value Null This QDeclarativeView has no source set. \value Ready This QDeclarativeView has loaded and created the QML component. \value Loading This QDeclarativeView is loading network data. - \value Error An error has occured. Call errorDescription() to retrieve a description. + \value Error An error has occurred. Call errorDescription() to retrieve a description. */ /*! \enum QDeclarativeView::ResizeMode @@ -390,7 +391,7 @@ QDeclarativeView::Status QDeclarativeView::status() const } /*! - Return the list of errors that occured during the last compile or create + Return the list of errors that occurred during the last compile or create operation. An empty list is returned if isError() is not set. */ QList<QDeclarativeError> QDeclarativeView::errors() const diff --git a/src/declarative/util/qdeclarativeview.h b/src/declarative/util/qdeclarativeview.h index cdcf134..d3e4948 100644 --- a/src/declarative/util/qdeclarativeview.h +++ b/src/declarative/util/qdeclarativeview.h @@ -75,8 +75,8 @@ public: QUrl source() const; void setSource(const QUrl&); - QDeclarativeEngine* engine(); - QDeclarativeContext* rootContext(); + QDeclarativeEngine* engine() const; + QDeclarativeContext* rootContext() const; QGraphicsObject *rootObject() const; diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp index 9895ff2..7c1e1fd 100644 --- a/src/declarative/util/qdeclarativexmllistmodel.cpp +++ b/src/declarative/util/qdeclarativexmllistmodel.cpp @@ -567,7 +567,7 @@ void QDeclarativeXmlListModelPrivate::clear_role(QDeclarativeListProperty<QDecla \image qml-xmllistmodel-example.png The XmlListModel data is loaded asynchronously, and \l status - is set to \l XmlListModel::Ready when loading is complete. + is set to \c XmlListModel.Ready when loading is complete. Note this means when XmlListModel is used for a view, the view is not populated until the model is loaded. @@ -596,7 +596,7 @@ void QDeclarativeXmlListModelPrivate::clear_role(QDeclarativeListProperty<QDecla with a combined value of all key roles that is not already present in the model. - \sa {demos/declarative/rssnews}{RSS News demo} + \sa {RSS News} */ QDeclarativeXmlListModel::QDeclarativeXmlListModel(QObject *parent) diff --git a/src/declarative/util/qlistmodelinterface.cpp b/src/declarative/util/qlistmodelinterface.cpp index 98d6a5b..acf4dd6 100644 --- a/src/declarative/util/qlistmodelinterface.cpp +++ b/src/declarative/util/qlistmodelinterface.cpp @@ -71,7 +71,7 @@ QT_BEGIN_NAMESPACE */ /*! \fn QHash<int,QVariant> QListModelInterface::data(int index, const QList<int>& roles) const - Returns the data at the given \a index for the specifed \a roles. + Returns the data at the given \a index for the specified \a roles. */ /*! \fn bool QListModelInterface::setData(int index, const QHash<int,QVariant>& values) |