diff options
-rw-r--r-- | examples/declarative/listview/sections.qml | 3 | ||||
-rw-r--r-- | src/declarative/graphicsitems/qmlgraphicslistview.cpp | 89 | ||||
-rw-r--r-- | src/declarative/graphicsitems/qmlgraphicslistview_p.h | 32 | ||||
-rw-r--r-- | src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp | 45 | ||||
-rw-r--r-- | src/declarative/graphicsitems/qmlgraphicsvisualitemmodel_p.h | 3 | ||||
-rw-r--r-- | src/declarative/qml/qmlcontext.cpp | 24 | ||||
-rw-r--r-- | src/declarative/qml/qmlcontext.h | 2 |
7 files changed, 161 insertions, 37 deletions
diff --git a/examples/declarative/listview/sections.qml b/examples/declarative/listview/sections.qml index 6b1a589..b51cf58 100644 --- a/examples/declarative/listview/sections.qml +++ b/examples/declarative/listview/sections.qml @@ -64,7 +64,8 @@ Rectangle { highlight: petHighlight // The sectionExpression is simply the size of the pet. // We use this to determine which section we are in above. - sectionExpression: "size" + section.property: "size" + section.criteria: ViewSection.FullString focus: true } } diff --git a/src/declarative/graphicsitems/qmlgraphicslistview.cpp b/src/declarative/graphicsitems/qmlgraphicslistview.cpp index 989970e..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 @@ -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; } @@ -411,7 +440,7 @@ public: } void itemGeometryChanged(QmlGraphicsItem *, const QRectF &newGeometry, const QRectF &oldGeometry) { - if (orient == QmlGraphicsListView::Vertical && newGeometry.height() != oldGeometry.height() + if ((orient == QmlGraphicsListView::Vertical && newGeometry.height() != oldGeometry.height()) || newGeometry.width() != oldGeometry.width()) { layout(); fixupPosition(); @@ -471,7 +500,7 @@ public: int buffer; QmlEaseFollow *highlightPosAnimator; QmlEaseFollow *highlightSizeAnimator; - QString sectionExpression; + QmlGraphicsViewSection *sectionCriteria; QString currentSection; qreal spacing; qreal highlightMoveSpeed; @@ -528,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(); @@ -649,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(); @@ -816,7 +844,7 @@ void QmlGraphicsListViewPrivate::updateHighlight() void QmlGraphicsListViewPrivate::updateSections() { - if (!sectionExpression.isEmpty()) { + if (sectionCriteria) { QString prevSection; if (visibleIndex > 0) prevSection = sectionAt(visibleIndex-1); @@ -832,7 +860,7 @@ void QmlGraphicsListViewPrivate::updateSections() void QmlGraphicsListViewPrivate::updateCurrentSection() { - if (sectionExpression.isEmpty() || visibleItems.isEmpty()) { + if (sectionCriteria || visibleItems.isEmpty()) { currentSection = QString(); return; } @@ -1289,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. */ /*! @@ -1298,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. */ /*! @@ -1747,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 @@ -1760,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; } /*! @@ -2560,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 cb9f5c4..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; @@ -201,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/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/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp index c3971ae..445bf03 100644 --- a/src/declarative/qml/qmlcontext.cpp +++ b/src/declarative/qml/qmlcontext.cpp @@ -442,6 +442,30 @@ 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) { + value = d->defaultObjects.at(ii)->property(utf8Name); + if (!value.isValid() && parentContext()) + value = parentContext()->contextProperty(name); + if (value.isValid()) + break; + } + } 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 &); |