summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/declarative/listview/sections.qml3
-rw-r--r--src/declarative/graphicsitems/qmlgraphicslistview.cpp89
-rw-r--r--src/declarative/graphicsitems/qmlgraphicslistview_p.h32
-rw-r--r--src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp45
-rw-r--r--src/declarative/graphicsitems/qmlgraphicsvisualitemmodel_p.h3
-rw-r--r--src/declarative/qml/qmlcontext.cpp24
-rw-r--r--src/declarative/qml/qmlcontext.h2
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 &);