diff options
Diffstat (limited to 'src/declarative')
24 files changed, 406 insertions, 98 deletions
diff --git a/src/declarative/3rdparty/qlistmodelinterface_p.h b/src/declarative/3rdparty/qlistmodelinterface_p.h index f7c956a..a958ead 100644 --- a/src/declarative/3rdparty/qlistmodelinterface_p.h +++ b/src/declarative/3rdparty/qlistmodelinterface_p.h @@ -60,6 +60,7 @@ class Q_DECLARATIVE_EXPORT QListModelInterface : public QObject virtual int count() const = 0; virtual QHash<int,QVariant> data(int index, const QList<int>& roles = QList<int>()) const = 0; + virtual QVariant data(int index, int role) const = 0; virtual bool setData(int index, const QHash<int,QVariant>& values) { Q_UNUSED(index); Q_UNUSED(values); return false; } diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index 97cefd5..940dc14 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -1,3 +1,11 @@ + + +Listview: sectionExpression has been replaced by section.property, section.criteria + + +============================================================================= +The changes below are pre-4.6.0 release. + QML API Review ============== diff --git a/src/declarative/graphicsitems/graphicsitems.pri b/src/declarative/graphicsitems/graphicsitems.pri index 728c9c0..5199c5d 100644 --- a/src/declarative/graphicsitems/graphicsitems.pri +++ b/src/declarative/graphicsitems/graphicsitems.pri @@ -48,6 +48,7 @@ HEADERS += \ $$PWD/qmlgraphicsgraphicsobjectcontainer_p.h \ $$PWD/qmlgraphicsparticles_p.h \ $$PWD/qmlgraphicslayoutitem_p.h \ + $$PWD/qmlgraphicsitemgeometrylistener_p.h \ $$PWD/qmlgraphicseffects.cpp SOURCES += \ diff --git a/src/declarative/graphicsitems/qmlgraphicsanchors.cpp b/src/declarative/graphicsitems/qmlgraphicsanchors.cpp index 96d76cf..0febf08 100644 --- a/src/declarative/graphicsitems/qmlgraphicsanchors.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsanchors.cpp @@ -241,22 +241,20 @@ void QmlGraphicsAnchorsPrivate::clearItem(QmlGraphicsItem *item) void QmlGraphicsAnchorsPrivate::addDepend(QmlGraphicsItem *item) { - Q_Q(QmlGraphicsAnchors); if (!item) return; QmlGraphicsItemPrivate *p = static_cast<QmlGraphicsItemPrivate *>(QGraphicsItemPrivate::get(item)); - p->dependantAnchors.append(q); + p->addGeometryListener(this); } void QmlGraphicsAnchorsPrivate::remDepend(QmlGraphicsItem *item) { - Q_Q(QmlGraphicsAnchors); if (!item) return; QmlGraphicsItemPrivate *p = static_cast<QmlGraphicsItemPrivate *>(QGraphicsItemPrivate::get(item)); - p->dependantAnchors.removeOne(q); + p->removeGeometryListener(this); } bool QmlGraphicsAnchorsPrivate::isItemComplete() const @@ -332,7 +330,7 @@ void QmlGraphicsAnchorsPrivate::updateOnComplete() updateVerticalAnchors(); } -void QmlGraphicsAnchorsPrivate::update(QmlGraphicsItem *, const QRectF &newG, const QRectF &oldG) +void QmlGraphicsAnchorsPrivate::itemGeometryChanged(QmlGraphicsItem *, const QRectF &newG, const QRectF &oldG) { fillChanged(); centerInChanged(); diff --git a/src/declarative/graphicsitems/qmlgraphicsanchors_p_p.h b/src/declarative/graphicsitems/qmlgraphicsanchors_p_p.h index 4f7fde0..91c8ff1 100644 --- a/src/declarative/graphicsitems/qmlgraphicsanchors_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsanchors_p_p.h @@ -54,7 +54,7 @@ // #include "qmlgraphicsanchors_p.h" - +#include "qmlgraphicsitemgeometrylistener_p.h" #include <private/qobject_p.h> QT_BEGIN_NAMESPACE @@ -91,7 +91,7 @@ Q_DECLARE_METATYPE(QmlGraphicsAnchorLine) -class QmlGraphicsAnchorsPrivate : public QObjectPrivate +class QmlGraphicsAnchorsPrivate : public QObjectPrivate, public QmlGraphicsItemGeometryListener { Q_DECLARE_PUBLIC(QmlGraphicsAnchors) public: @@ -128,7 +128,10 @@ public: void updateOnComplete(); void updateMe(); - void update(QmlGraphicsItem *, const QRectF &, const QRectF &); + + // QmlGraphicsItemGeometryListener interface + void itemGeometryChanged(QmlGraphicsItem *, const QRectF &, const QRectF &); + QmlGraphicsAnchorsPrivate *anchorPrivate() { return this; } bool checkHValid() const; bool checkVValid() const; diff --git a/src/declarative/graphicsitems/qmlgraphicsitem.cpp b/src/declarative/graphicsitems/qmlgraphicsitem.cpp index ef4dfc2..4d587e4d 100644 --- a/src/declarative/graphicsitems/qmlgraphicsitem.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsitem.cpp @@ -1478,17 +1478,18 @@ QmlGraphicsItem::QmlGraphicsItem(QmlGraphicsItemPrivate &dd, QmlGraphicsItem *pa QmlGraphicsItem::~QmlGraphicsItem() { Q_D(QmlGraphicsItem); - for (int ii = 0; ii < d->dependantAnchors.count(); ++ii) { - QmlGraphicsAnchors *anchor = d->dependantAnchors.at(ii); - anchor->d_func()->clearItem(this); + for (int ii = 0; ii < d->geometryListeners.count(); ++ii) { + QmlGraphicsAnchorsPrivate *anchor = d->geometryListeners.at(ii)->anchorPrivate(); + if (anchor) + anchor->clearItem(this); } if (!d->parent || (parentItem() && !parentItem()->QGraphicsItem::d_ptr->inDestructor)) - for (int ii = 0; ii < d->dependantAnchors.count(); ++ii) { - QmlGraphicsAnchors *anchor = d->dependantAnchors.at(ii); - if (anchor->d_func()->item && anchor->d_func()->item->parentItem() != this) //child will be deleted anyway - anchor->d_func()->updateOnComplete(); + for (int ii = 0; ii < d->geometryListeners.count(); ++ii) { + QmlGraphicsAnchorsPrivate *anchor = d->geometryListeners.at(ii)->anchorPrivate(); + if (anchor && anchor->item && anchor->item->parentItem() != this) //child will be deleted anyway + anchor->updateOnComplete(); } - d->dependantAnchors.clear(); + d->geometryListeners.clear(); delete d->_anchorLines; d->_anchorLines = 0; delete d->_anchors; d->_anchors = 0; delete d->_stateGroup; d->_stateGroup = 0; @@ -1974,12 +1975,22 @@ void QmlGraphicsItem::geometryChanged(const QRectF &newGeometry, if (newGeometry.height() != oldGeometry.height()) emit heightChanged(); - for(int ii = 0; ii < d->dependantAnchors.count(); ++ii) { - QmlGraphicsAnchors *anchor = d->dependantAnchors.at(ii); - anchor->d_func()->update(this, newGeometry, oldGeometry); + for(int ii = 0; ii < d->geometryListeners.count(); ++ii) { + QmlGraphicsItemGeometryListener *listener = d->geometryListeners.at(ii); + listener->itemGeometryChanged(this, newGeometry, oldGeometry); } } +void QmlGraphicsItemPrivate::addGeometryListener(QmlGraphicsItemGeometryListener *listener) +{ + geometryListeners.append(listener); +} + +void QmlGraphicsItemPrivate::removeGeometryListener(QmlGraphicsItemGeometryListener *listener) +{ + geometryListeners.removeOne(listener); +} + /*! \internal */ void QmlGraphicsItem::keyPressEvent(QKeyEvent *event) { @@ -2227,9 +2238,10 @@ void QmlGraphicsItem::setBaselineOffset(qreal offset) d->_baselineOffset = offset; emit baselineOffsetChanged(); - for(int ii = 0; ii < d->dependantAnchors.count(); ++ii) { - QmlGraphicsAnchors *anchor = d->dependantAnchors.at(ii); - anchor->d_func()->updateVerticalAnchors(); + for(int ii = 0; ii < d->geometryListeners.count(); ++ii) { + QmlGraphicsAnchorsPrivate *anchor = d->geometryListeners.at(ii)->anchorPrivate(); + if (anchor) + anchor->updateVerticalAnchors(); } } diff --git a/src/declarative/graphicsitems/qmlgraphicsitem_p.h b/src/declarative/graphicsitems/qmlgraphicsitem_p.h index 304e36c..9496590 100644 --- a/src/declarative/graphicsitems/qmlgraphicsitem_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsitem_p.h @@ -57,6 +57,7 @@ #include "qmlgraphicsanchors_p.h" #include "qmlgraphicsanchors_p_p.h" +#include "qmlgraphicsitemgeometrylistener_p.h" #include "../util/qmlstate_p.h" #include "../util/qmlnullablevalue_p_p.h" @@ -182,7 +183,6 @@ public: } return _anchors; } - QList<QmlGraphicsAnchors *> dependantAnchors; QmlGraphicsAnchors *_anchors; QmlGraphicsContents *_contents; @@ -206,6 +206,10 @@ public: return _anchorLines; } + void addGeometryListener(QmlGraphicsItemGeometryListener *); + void removeGeometryListener(QmlGraphicsItemGeometryListener *); + QList<QmlGraphicsItemGeometryListener *> geometryListeners; + QmlStateGroup *states(); QmlStateGroup *_stateGroup; diff --git a/src/declarative/graphicsitems/qmlgraphicsitemgeometrylistener_p.h b/src/declarative/graphicsitems/qmlgraphicsitemgeometrylistener_p.h new file mode 100644 index 0000000..6230e93 --- /dev/null +++ b/src/declarative/graphicsitems/qmlgraphicsitemgeometrylistener_p.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMLGRAPHICSITEMGEOMETRYLISTENER +#define QMLGRAPHICSITEMGEOMETRYLISTENER + +// +// 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. +// + +QT_BEGIN_NAMESPACE + +class QRectF; +class QmlGraphicsItem; +class QmlGraphicsAnchorsPrivate; +class QmlGraphicsItemGeometryListener +{ +public: + virtual void itemGeometryChanged(QmlGraphicsItem *, const QRectF &newGeometry, const QRectF &oldGeometry) = 0; + virtual QmlGraphicsAnchorsPrivate *anchorPrivate() { return 0; } +}; + +QT_END_NAMESPACE + +#endif // QMLGRAPHICSITEMGEOMETRYLISTENER diff --git a/src/declarative/graphicsitems/qmlgraphicslistview.cpp b/src/declarative/graphicsitems/qmlgraphicslistview.cpp index 16e9d6e..bf734b8 100644 --- a/src/declarative/graphicsitems/qmlgraphicslistview.cpp +++ b/src/declarative/graphicsitems/qmlgraphicslistview.cpp @@ -51,6 +51,31 @@ #include <QKeyEvent> QT_BEGIN_NAMESPACE + +void QmlGraphicsViewSection::setProperty(const QString &property) +{ + if (property != m_property) { + m_property = property; + emit changed(); + } +} + +void QmlGraphicsViewSection::setCriteria(QmlGraphicsViewSection::SectionCriteria criteria) +{ + if (criteria != m_criteria) { + m_criteria = criteria; + emit changed(); + } +} + +QString QmlGraphicsViewSection::sectionString(const QString &value) +{ + if (m_criteria == FirstCharacter) + return value.at(0); + else + return value; +} + class QmlGraphicsListViewAttached : public QObject { Q_OBJECT @@ -166,7 +191,7 @@ public: //---------------------------------------------------------------------------- -class QmlGraphicsListViewPrivate : public QmlGraphicsFlickablePrivate +class QmlGraphicsListViewPrivate : public QmlGraphicsFlickablePrivate, private QmlGraphicsItemGeometryListener { Q_DECLARE_PUBLIC(QmlGraphicsListView) @@ -177,7 +202,8 @@ public: , averageSize(100.0), currentIndex(-1), requestedIndex(-1) , highlightRangeStart(0), highlightRangeEnd(0) , highlightComponent(0), highlight(0), trackedItem(0) - , moveReason(Other), buffer(0), highlightPosAnimator(0), highlightSizeAnimator(0), spacing(0.0) + , moveReason(Other), buffer(0), highlightPosAnimator(0), highlightSizeAnimator(0) + , sectionCriteria(0), spacing(0.0) , highlightMoveSpeed(400), highlightResizeSpeed(400), highlightRange(QmlGraphicsListView::NoHighlightRange) , snapMode(QmlGraphicsListView::NoSnap), overshootDist(0.0) , footerComponent(0), footer(0), headerComponent(0), header(0) @@ -291,12 +317,15 @@ public: } QString sectionAt(int modelIndex) { - Q_Q(QmlGraphicsListView); if (FxListItem *item = visibleItem(modelIndex)) return item->attached->section(); + QString section; - if (!sectionExpression.isEmpty()) - section = model->evaluate(modelIndex, sectionExpression, q).toString(); + if (sectionCriteria) { + QString propValue = model->value(modelIndex, sectionCriteria->property()).toString(); + section = sectionCriteria->sectionString(propValue); + } + return section; } @@ -410,6 +439,13 @@ public: q->setViewportWidth(q->minXExtent() - q->maxXExtent()); } + void itemGeometryChanged(QmlGraphicsItem *, const QRectF &newGeometry, const QRectF &oldGeometry) { + if ((orient == QmlGraphicsListView::Vertical && newGeometry.height() != oldGeometry.height()) + || newGeometry.width() != oldGeometry.width()) { + layout(); + fixupPosition(); + } + } // for debugging only void checkVisible() const { @@ -464,7 +500,7 @@ public: int buffer; QmlEaseFollow *highlightPosAnimator; QmlEaseFollow *highlightSizeAnimator; - QString sectionExpression; + QmlGraphicsViewSection *sectionCriteria; QString currentSection; qreal spacing; qreal highlightMoveSpeed; @@ -486,12 +522,8 @@ public: bool correctFlick : 1; bool inFlickCorrection : 1; bool lazyRelease : 1; - - static int itemResizedIdx; }; -int QmlGraphicsListViewPrivate::itemResizedIdx = -1; - void QmlGraphicsListViewPrivate::init() { Q_Q(QmlGraphicsListView); @@ -500,8 +532,6 @@ void QmlGraphicsListViewPrivate::init() QObject::connect(q, SIGNAL(widthChanged()), q, SLOT(refill())); QObject::connect(q, SIGNAL(movementEnded()), q, SLOT(animStopped())); q->setFlickDirection(QmlGraphicsFlickable::VerticalFlick); - if (itemResizedIdx == -1) - itemResizedIdx = QmlGraphicsListView::staticMetaObject.indexOfSlot("itemResized()"); } void QmlGraphicsListViewPrivate::clear() @@ -527,10 +557,9 @@ FxListItem *QmlGraphicsListViewPrivate::createItem(int modelIndex) listItem = new FxListItem(item, q); listItem->index = modelIndex; // initialise attached properties - if (!sectionExpression.isEmpty()) { - QmlExpression e(qmlContext(listItem->item), sectionExpression, q); - e.setTrackChange(false); - listItem->attached->m_section = e.value().toString(); + if (sectionCriteria) { + QString propValue = model->value(modelIndex, sectionCriteria->property()).toString(); + listItem->attached->m_section = sectionCriteria->sectionString(propValue); if (modelIndex > 0) { if (FxListItem *item = visibleItem(modelIndex-1)) listItem->attached->m_prevSection = item->attached->section(); @@ -543,10 +572,7 @@ FxListItem *QmlGraphicsListViewPrivate::createItem(int modelIndex) listItem->item->setZValue(1); listItem->item->setParent(q->viewport()); QmlGraphicsItemPrivate *itemPrivate = static_cast<QmlGraphicsItemPrivate*>(QGraphicsItemPrivate::get(item)); - if (orient == QmlGraphicsListView::Vertical) - itemPrivate->connectToHeightChanged(q, itemResizedIdx); - else - itemPrivate->connectToWidthChanged(q, itemResizedIdx); + itemPrivate->addGeometryListener(this); } requestedIndex = -1; @@ -565,14 +591,11 @@ void QmlGraphicsListViewPrivate::releaseItem(FxListItem *item) QObject::disconnect(trackedItem->item, notifier2, q, SLOT(trackedPositionChanged())); trackedItem = 0; } + QmlGraphicsItemPrivate *itemPrivate = static_cast<QmlGraphicsItemPrivate*>(QGraphicsItemPrivate::get(item->item)); + itemPrivate->removeGeometryListener(this); if (model->release(item->item) == 0) { // item was not destroyed, and we no longer reference it. unrequestedItems.insert(item->item, model->indexOf(item->item, q)); - QmlGraphicsItemPrivate *itemPrivate = static_cast<QmlGraphicsItemPrivate*>(QGraphicsItemPrivate::get(item->item)); - if (orient == QmlGraphicsListView::Vertical) - itemPrivate->disconnectFromHeightChanged(q, itemResizedIdx); - else - itemPrivate->disconnectFromWidthChanged(q, itemResizedIdx); } delete item; } @@ -654,7 +677,7 @@ void QmlGraphicsListViewPrivate::refill(qreal from, qreal to, bool doBuffer) if (visibleItems.count()) visiblePos = visibleItems.first()->position(); updateAverage(); - if (!sectionExpression.isEmpty()) + if (sectionCriteria) updateCurrentSection(); if (header) updateHeader(); @@ -821,7 +844,7 @@ void QmlGraphicsListViewPrivate::updateHighlight() void QmlGraphicsListViewPrivate::updateSections() { - if (!sectionExpression.isEmpty()) { + if (sectionCriteria) { QString prevSection; if (visibleIndex > 0) prevSection = sectionAt(visibleIndex-1); @@ -837,7 +860,7 @@ void QmlGraphicsListViewPrivate::updateSections() void QmlGraphicsListViewPrivate::updateCurrentSection() { - if (sectionExpression.isEmpty() || visibleItems.isEmpty()) { + if (sectionCriteria || visibleItems.isEmpty()) { currentSection = QString(); return; } @@ -1294,7 +1317,7 @@ QmlGraphicsListView::~QmlGraphicsListView() It is attached to each instance of the delegate. - The section is evaluated using the \l {ListView::sectionExpression}{sectionExpression} property. + The section is evaluated using the \l {ListView::section.property}{section} properties. */ /*! @@ -1303,7 +1326,7 @@ QmlGraphicsListView::~QmlGraphicsListView() It is attached to each instance of the delegate. - The section is evaluated using the \l {ListView::sectionExpression}{sectionExpression} property. + The section is evaluated using the \l {ListView::section.property}{section} properties. */ /*! @@ -1752,8 +1775,19 @@ void QmlGraphicsListView::setCacheBuffer(int b) } /*! - \qmlproperty string ListView::sectionExpression - This property holds the expression to be evaluated for the section attached property. + \qmlproperty string ListView::section.property + \qmlproperty enumeration ListView::section.criteria + These properties hold the expression to be evaluated for the section attached property. + + section.property hold the name of the property to use to determine + the section the item is in. + + section.criteria holds the criteria to use to get the section. It + can be either: + \list + \o ViewSection.FullString (default) - section is the value of the property. + \o ViewSection.FirstCharacter - section is the first character of the property value. + \endlist Each item in the list has attached properties named \c ListView.section and \c ListView.prevSection. These may be used to place a section header for @@ -1765,19 +1799,12 @@ void QmlGraphicsListView::setCacheBuffer(int b) \image ListViewSections.png */ -QString QmlGraphicsListView::sectionExpression() const -{ - Q_D(const QmlGraphicsListView); - return d->sectionExpression; -} - -void QmlGraphicsListView::setSectionExpression(const QString &expression) +QmlGraphicsViewSection *QmlGraphicsListView::sectionCriteria() { Q_D(QmlGraphicsListView); - if (d->sectionExpression != expression) { - d->sectionExpression = expression; - emit sectionExpressionChanged(); - } + if (!d->sectionCriteria) + d->sectionCriteria = new QmlGraphicsViewSection(this); + return d->sectionCriteria; } /*! @@ -2207,16 +2234,6 @@ void QmlGraphicsListView::trackedPositionChanged() } } -void QmlGraphicsListView::itemResized() -{ - Q_D(QmlGraphicsListView); - QmlGraphicsItem *item = qobject_cast<QmlGraphicsItem*>(sender()); - if (item) { - d->layout(); - d->fixupPosition(); - } -} - void QmlGraphicsListView::itemsInserted(int modelIndex, int count) { Q_D(QmlGraphicsListView); @@ -2575,6 +2592,7 @@ QmlGraphicsListViewAttached *QmlGraphicsListView::qmlAttachedProperties(QObject } QML_DEFINE_TYPE(Qt,4,6,ListView,QmlGraphicsListView) +QML_DEFINE_TYPE(Qt,4,6,ViewSection,QmlGraphicsViewSection) QT_END_NAMESPACE diff --git a/src/declarative/graphicsitems/qmlgraphicslistview_p.h b/src/declarative/graphicsitems/qmlgraphicslistview_p.h index 6dc131c..18b2ab5 100644 --- a/src/declarative/graphicsitems/qmlgraphicslistview_p.h +++ b/src/declarative/graphicsitems/qmlgraphicslistview_p.h @@ -50,6 +50,32 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) +class Q_DECLARATIVE_EXPORT QmlGraphicsViewSection : 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_ENUMS(SectionCriteria) +public: + QmlGraphicsViewSection(QObject *parent=0) : QObject(parent), m_criteria(FullString) {} + + QString property() const { return m_property; } + void setProperty(const QString &); + + enum SectionCriteria { FullString, FirstCharacter }; + SectionCriteria criteria() const { return m_criteria; } + void setCriteria(SectionCriteria); + + QString sectionString(const QString &value); + +Q_SIGNALS: + void changed(); + +private: + QString m_property; + SectionCriteria m_criteria; +}; + class QmlGraphicsVisualModel; class QmlGraphicsListViewAttached; @@ -79,7 +105,7 @@ class Q_DECLARATIVE_EXPORT QmlGraphicsListView : public QmlGraphicsFlickable Q_PROPERTY(Orientation orientation READ orientation WRITE setOrientation NOTIFY orientationChanged) Q_PROPERTY(bool keyNavigationWraps READ isWrapEnabled WRITE setWrapEnabled) Q_PROPERTY(int cacheBuffer READ cacheBuffer WRITE setCacheBuffer) - Q_PROPERTY(QString sectionExpression READ sectionExpression WRITE setSectionExpression NOTIFY sectionExpressionChanged) + Q_PROPERTY(QmlGraphicsViewSection *section READ sectionCriteria CONSTANT) Q_PROPERTY(QString currentSection READ currentSection NOTIFY currentSectionChanged) Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode) @@ -138,8 +164,7 @@ public: int cacheBuffer() const; void setCacheBuffer(int); - QString sectionExpression() const; - void setSectionExpression(const QString &); + QmlGraphicsViewSection *sectionCriteria(); QString currentSection() const; qreal highlightMoveSpeed() const; @@ -188,7 +213,6 @@ protected: private Q_SLOTS: void refill(); void trackedPositionChanged(); - void itemResized(); void itemsInserted(int index, int count); void itemsRemoved(int index, int count); void itemsMoved(int from, int to, int count); @@ -202,6 +226,7 @@ QT_END_NAMESPACE QML_DECLARE_TYPEINFO(QmlGraphicsListView, QML_HAS_ATTACHED_PROPERTIES) QML_DECLARE_TYPE(QmlGraphicsListView) +QML_DECLARE_TYPE(QmlGraphicsViewSection) QT_END_HEADER diff --git a/src/declarative/graphicsitems/qmlgraphicspositioners.cpp b/src/declarative/graphicsitems/qmlgraphicspositioners.cpp index 60abdde..ecaab80 100644 --- a/src/declarative/graphicsitems/qmlgraphicspositioners.cpp +++ b/src/declarative/graphicsitems/qmlgraphicspositioners.cpp @@ -67,10 +67,7 @@ void QmlGraphicsBasePositionerPrivate::watchChanges(QmlGraphicsItem *other) QmlGraphicsItemPrivate *otherPrivate = static_cast<QmlGraphicsItemPrivate*>(QGraphicsItemPrivate::get(other)); - if(type == QmlGraphicsBasePositioner::Vertical || type == QmlGraphicsBasePositioner::Both) - otherPrivate->connectToHeightChanged(q, prePosIdx); - if(type == QmlGraphicsBasePositioner::Horizontal || type == QmlGraphicsBasePositioner::Both) - otherPrivate->connectToWidthChanged(q, prePosIdx); + otherPrivate->addGeometryListener(this); otherPrivate->registerSiblingOrderNotification(this); watched << other; @@ -83,11 +80,8 @@ void QmlGraphicsBasePositionerPrivate::unwatchChanges(QmlGraphicsItem* other) bool stillAlive = false; //Use the returns from disconnect to see if it was deleted or just reparented stillAlive |= QMetaObject::disconnect(other, visibleIdx, q, prePosIdx); stillAlive |= QMetaObject::disconnect(other, opacityIdx, q, prePosIdx); - //Is disconnect expensive enough to be worth this check? - if(type == QmlGraphicsBasePositioner::Vertical || type == QmlGraphicsBasePositioner::Both) - stillAlive |= otherPrivate->disconnectFromHeightChanged(q, prePosIdx); - if(type == QmlGraphicsBasePositioner::Horizontal || type == QmlGraphicsBasePositioner::Both) - stillAlive |= otherPrivate->disconnectFromWidthChanged(q, prePosIdx); + + otherPrivate->removeGeometryListener(this); if(stillAlive) otherPrivate->unregisterSiblingOrderNotification(this); diff --git a/src/declarative/graphicsitems/qmlgraphicspositioners_p_p.h b/src/declarative/graphicsitems/qmlgraphicspositioners_p_p.h index db795ec..63c1c83 100644 --- a/src/declarative/graphicsitems/qmlgraphicspositioners_p_p.h +++ b/src/declarative/graphicsitems/qmlgraphicspositioners_p_p.h @@ -66,7 +66,7 @@ #include <QtCore/QTimer> QT_BEGIN_NAMESPACE -class QmlGraphicsBasePositionerPrivate : public QmlGraphicsItemPrivate +class QmlGraphicsBasePositionerPrivate : public QmlGraphicsItemPrivate, public QmlGraphicsItemGeometryListener { Q_DECLARE_PUBLIC(QmlGraphicsBasePositioner) @@ -125,6 +125,13 @@ public: queuedPositioning = true; } } + + void itemGeometryChanged(QmlGraphicsItem *, const QRectF &newGeometry, const QRectF &oldGeometry) + { + Q_Q(QmlGraphicsBasePositioner); + if (newGeometry.size() != oldGeometry.size()) + q->prePositioning(); + } }; QT_END_NAMESPACE diff --git a/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp b/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp index 7c2159f..6b4a773 100644 --- a/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp @@ -44,6 +44,7 @@ #include "qmlgraphicsitem.h" #include <qmlcontext.h> +#include <qmlengine.h> #include <qmlexpression.h> #include <qmlpackage_p.h> #include <qmlopenmetaobject_p.h> @@ -208,9 +209,19 @@ void QmlGraphicsVisualItemModel::completeItem() // Nothing to do } +QVariant QmlGraphicsVisualItemModel::value(int index, const QString &name) +{ + Q_D(QmlGraphicsVisualItemModel); + if (index < 0 || index >= d->children.count()) + return QVariant(); + return QmlEngine::contextForObject(d->children.at(index))->contextProperty(name); +} + QVariant QmlGraphicsVisualItemModel::evaluate(int index, const QString &expression, QObject *objectContext) { Q_D(QmlGraphicsVisualItemModel); + if (index < 0 || index >= d->children.count()) + return QVariant(); QmlContext *ccontext = qmlContext(this); QmlContext *ctxt = new QmlContext(ccontext); ctxt->addDefaultObject(d->children.at(index)); @@ -878,6 +889,33 @@ void QmlGraphicsVisualDataModel::completeItem() d->m_delegate->completeCreate(); } +QVariant QmlGraphicsVisualDataModel::value(int index, const QString &name) +{ + Q_D(QmlGraphicsVisualDataModel); + if (d->m_visualItemModel) + return d->m_visualItemModel->value(index, name); + + if ((!d->m_listModelInterface && !d->m_abstractItemModel) || !d->m_delegate) + return QVariant(); + + QVariant val; + QObject *nobj = d->m_cache.item(index); + if (nobj) { + val = QmlEngine::contextForObject(nobj)->contextProperty(name); + } else { + QmlContext *ccontext = d->m_context; + if (!ccontext) ccontext = qmlContext(this); + QmlContext *ctxt = new QmlContext(ccontext); + QmlGraphicsVisualDataModelData *data = new QmlGraphicsVisualDataModelData(index, this); + ctxt->addDefaultObject(data); + val = ctxt->contextProperty(name); + delete data; + delete ctxt; + } + + return val; +} + QVariant QmlGraphicsVisualDataModel::evaluate(int index, const QString &expression, QObject *objectContext) { Q_D(QmlGraphicsVisualDataModel); @@ -914,11 +952,8 @@ QVariant QmlGraphicsVisualDataModel::evaluate(int index, const QString &expressi int QmlGraphicsVisualDataModel::indexOf(QmlGraphicsItem *item, QObject *objectContext) const { - QmlExpression e(qmlContext(item), QLatin1String("index"), objectContext); - e.setTrackChange(false); - QVariant value = e.value(); - if (value.isValid()) - return value.toInt(); + QVariant val = QmlEngine::contextForObject(item)->contextProperty("index"); + return val.toInt(); return -1; } diff --git a/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel_p.h b/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel_p.h index 4e76aee..4e8a19b 100644 --- a/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel_p.h +++ b/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel_p.h @@ -82,6 +82,7 @@ public: virtual ReleaseFlags release(QmlGraphicsItem *item) = 0; virtual void completeItem() = 0; virtual QVariant evaluate(int index, const QString &expression, QObject *objectContext) = 0; + virtual QVariant value(int index, const QString &role) { return QVariant(); } virtual int indexOf(QmlGraphicsItem *item, QObject *objectContext) const = 0; @@ -120,6 +121,7 @@ public: virtual QmlGraphicsItem *item(int index, bool complete=true); virtual ReleaseFlags release(QmlGraphicsItem *item); virtual void completeItem(); + virtual QVariant value(int index, const QString &role); virtual QVariant evaluate(int index, const QString &expression, QObject *objectContext); virtual int indexOf(QmlGraphicsItem *item, QObject *objectContext) const; @@ -166,6 +168,7 @@ public: QmlGraphicsItem *item(int index, const QByteArray &, bool complete=true); ReleaseFlags release(QmlGraphicsItem *item); void completeItem(); + virtual QVariant value(int index, const QString &role); QVariant evaluate(int index, const QString &expression, QObject *objectContext); int indexOf(QmlGraphicsItem *item, QObject *objectContext) const; diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp index f25f8b8..acfdda3 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -2037,6 +2037,14 @@ bool QmlCompiler::buildPropertyLiteralAssignment(QmlParser::Property *prop, if (v->value.isScript()) { + //optimization for <Type>.<EnumValue> enum assignments + bool isEnumAssignment = false; + COMPILE_CHECK(testQualifiedEnumAssignment(obj->metaObject()->property(prop->index), obj, v, &isEnumAssignment)); + if (isEnumAssignment) { + v->type = Value::Literal; + return true; + } + COMPILE_CHECK(buildBinding(v, prop, ctxt)); v->type = Value::PropertyBinding; @@ -2051,6 +2059,50 @@ bool QmlCompiler::buildPropertyLiteralAssignment(QmlParser::Property *prop, return true; } +bool QmlCompiler::testQualifiedEnumAssignment(const QMetaProperty &prop, + QmlParser::Object *obj, + QmlParser::Value *v, + bool *isAssignment) +{ + *isAssignment = false; + if (!prop.isEnumType()) + return true; + + if (!prop.isWritable()) + COMPILE_EXCEPTION(v, QCoreApplication::translate("QmlCompiler","Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop.name()))); + + QString string = v->value.asString(); + if (!string.at(0).isUpper()) + return true; + + QStringList parts = string.split(QLatin1Char('.')); + if (parts.count() != 2) + return true; + + QString typeName = parts.at(0); + QmlType *type = 0; + QmlEnginePrivate::get(engine)->resolveType(unit->imports, typeName.toUtf8(), + &type, 0, 0, 0, 0); + + if (!type || obj->typeName != type->qmlTypeName()) + return true; + + QString enumValue = parts.at(1); + int value; + if (prop.isFlagType()) { + value = prop.enumerator().keysToValue(enumValue.toUtf8().constData()); + } else + value = prop.enumerator().keyToValue(enumValue.toUtf8().constData()); + if (value == -1) + return true; + + v->type = Value::Literal; + v->value = QmlParser::Variant(enumValue); + *isAssignment = true; + + return true; +} + // Ensures that the dynamic meta specification on obj is valid bool QmlCompiler::checkDynamicMeta(QmlParser::Object *obj) { @@ -2352,10 +2404,10 @@ bool QmlCompiler::compileAlias(QMetaObjectBuilder &builder, QStringList alias = astNodeToStringList(node); if (alias.count() != 1 && alias.count() != 2) - COMPILE_EXCEPTION(prop.defaultValue, QCoreApplication::translate("QmlCompiler","Invalid alias location")); + COMPILE_EXCEPTION(prop.defaultValue, QCoreApplication::translate("QmlCompiler","Invalid alias reference. An alias reference must be specified as <id> or <id>.<property>")); if (!compileState.ids.contains(alias.at(0))) - COMPILE_EXCEPTION(prop.defaultValue, QCoreApplication::translate("QmlCompiler","Invalid alias location")); + COMPILE_EXCEPTION(prop.defaultValue, QCoreApplication::translate("QmlCompiler","Invalid alias reference. Unable to find id \"%1\"").arg(alias.at(0))); Object *idObject = compileState.ids[alias.at(0)]; diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h index 3fcba15..740d97c 100644 --- a/src/declarative/qml/qmlcompiler_p.h +++ b/src/declarative/qml/qmlcompiler_p.h @@ -219,6 +219,10 @@ private: bool doesPropertyExist(QmlParser::Property *prop, QmlParser::Object *obj); bool testLiteralAssignment(const QMetaProperty &prop, QmlParser::Value *value); + bool testQualifiedEnumAssignment(const QMetaProperty &prop, + QmlParser::Object *obj, + QmlParser::Value *value, + bool *isAssignment); enum DynamicMetaMode { IgnoreAliases, ResolveAliases, ForceCreation }; bool mergeDynamicMetaProperties(QmlParser::Object *obj); bool buildDynamicMeta(QmlParser::Object *obj, DynamicMetaMode mode); diff --git a/src/declarative/qml/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp index c3971ae..49bb59c 100644 --- a/src/declarative/qml/qmlcontext.cpp +++ b/src/declarative/qml/qmlcontext.cpp @@ -442,6 +442,38 @@ void QmlContext::setContextProperty(const QString &name, QObject *value) } } +QVariant QmlContext::contextProperty(const QString &name) const +{ + Q_D(const QmlContext); + QVariant value; + int idx = -1; + if (d->propertyNames) + idx = d->propertyNames->value(name); + + if (idx == -1) { + QByteArray utf8Name = name.toUtf8(); + for (int ii = d->defaultObjects.count() - 1; ii >= 0; --ii) { + QObject *obj = d->defaultObjects.at(ii); + QmlDeclarativeData *data = QmlDeclarativeData::get(obj); + if (data && data->propertyCache) { + QmlPropertyCache::Data *property = data->propertyCache->property(name); + if (property) + value = obj->metaObject()->property(property->coreIndex).read(obj); + } else { + value = obj->property(utf8Name); + } + if (value.isValid()) + break; + } + if (!value.isValid() && parentContext()) + value = parentContext()->contextProperty(name); + } else { + value = d->propertyValues[idx]; + } + + return value; +} + /*! Resolves the URL \a src relative to the URL of the containing component. diff --git a/src/declarative/qml/qmlcontext.h b/src/declarative/qml/qmlcontext.h index de1d092..7547004 100644 --- a/src/declarative/qml/qmlcontext.h +++ b/src/declarative/qml/qmlcontext.h @@ -75,6 +75,8 @@ public: void setContextProperty(const QString &, QObject *); void setContextProperty(const QString &, const QVariant &); + QVariant contextProperty(const QString &) const; + QUrl resolvedUrl(const QUrl &); void setBaseUrl(const QUrl &); diff --git a/src/declarative/qml/qmlscriptparser.cpp b/src/declarative/qml/qmlscriptparser.cpp index 35234ec..a24ef51 100644 --- a/src/declarative/qml/qmlscriptparser.cpp +++ b/src/declarative/qml/qmlscriptparser.cpp @@ -600,6 +600,9 @@ bool ProcessAST::visit(AST::UiPublicMember *node) if (node->expression) { // default value property.defaultValue = new Property; property.defaultValue->parent = _stateStack.top().object; + property.defaultValue->location = + location(node->expression->firstSourceLocation(), + node->expression->lastSourceLocation()); Value *value = new Value; value->location = location(node->expression->firstSourceLocation(), node->expression->lastSourceLocation()); diff --git a/src/declarative/qml/qmlsqldatabase.cpp b/src/declarative/qml/qmlsqldatabase.cpp index c3c3ca3..4fa63cb 100644 --- a/src/declarative/qml/qmlsqldatabase.cpp +++ b/src/declarative/qml/qmlsqldatabase.cpp @@ -44,7 +44,7 @@ #include "qmlengine.h" #include "qmlengine_p.h" #include "qmlrefcount_p.h" -#include "qmlengine_p.h" +#include "qmlexpression_p.h" #include <QtCore/qobject.h> #include <QtScript/qscriptvalue.h> @@ -319,6 +319,10 @@ static QScriptValue qmlsqldatabase_transaction_shared(QScriptContext *context, Q instance.setProperty(QLatin1String("executeSql"), engine->newFunction(qmlsqldatabase_executeSql_outsidetransaction)); if (engine->hasUncaughtException()) { + QmlError error; + QmlExpressionPrivate::exceptionToError(engine, error); + qWarning() << error; + engine->clearExceptions(); db.rollback(); } else { if (!db.commit()) diff --git a/src/declarative/util/qmllistmodel.cpp b/src/declarative/util/qmllistmodel.cpp index f4317af..de6ee2e 100644 --- a/src/declarative/util/qmllistmodel.cpp +++ b/src/declarative/util/qmllistmodel.cpp @@ -421,6 +421,29 @@ QHash<int,QVariant> QmlListModel::data(int index, const QList<int> &roles) const return rv; } +QVariant QmlListModel::data(int index, int role) const +{ + checkRoles(); + QVariant rv; + if (index >= count()) + return rv; + + ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index)); + if (!node) + return rv; + + const QString &roleString = roleStrings.at(role); + + QHash<QString, ModelNode *>::ConstIterator iter = + node->properties.find(roleString); + if (iter != node->properties.end()) { + ModelNode *row = *iter; + rv = valueForNode(row); + } + + return rv; +} + /*! \qmlproperty int ListModel::count The number of data entries in the model. diff --git a/src/declarative/util/qmllistmodel_p.h b/src/declarative/util/qmllistmodel_p.h index 2a1a57d..47236d0 100644 --- a/src/declarative/util/qmllistmodel_p.h +++ b/src/declarative/util/qmllistmodel_p.h @@ -72,6 +72,7 @@ public: virtual QString toString(int role) const; virtual int count() const; virtual QHash<int,QVariant> data(int index, const QList<int> &roles = (QList<int>())) const; + virtual QVariant data(int index, int role) const; Q_INVOKABLE void clear(); Q_INVOKABLE void remove(int index); diff --git a/src/declarative/util/qmlxmllistmodel.cpp b/src/declarative/util/qmlxmllistmodel.cpp index 46ef739..d31fadf 100644 --- a/src/declarative/util/qmlxmllistmodel.cpp +++ b/src/declarative/util/qmlxmllistmodel.cpp @@ -462,6 +462,13 @@ QHash<int,QVariant> QmlXmlListModel::data(int index, const QList<int> &roles) co return rv; } +QVariant QmlXmlListModel::data(int index, int role) const +{ + Q_D(const QmlXmlListModel); + int roleIndex = d->roles.indexOf(role); + return (roleIndex == -1) ? QVariant() : d->data.at(roleIndex).at(index); +} + /*! \qmlproperty int XmlListModel::count The number of data entries in the model. diff --git a/src/declarative/util/qmlxmllistmodel_p.h b/src/declarative/util/qmlxmllistmodel_p.h index 67fc751..e4b8cab 100644 --- a/src/declarative/util/qmlxmllistmodel_p.h +++ b/src/declarative/util/qmlxmllistmodel_p.h @@ -79,6 +79,7 @@ public: ~QmlXmlListModel(); virtual QHash<int,QVariant> data(int index, const QList<int> &roles = (QList<int>())) const; + virtual QVariant data(int index, int role) const; virtual int count() const; virtual QList<int> roles() const; virtual QString toString(int role) const; |