aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/items/qquickitemview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/items/qquickitemview.cpp')
-rw-r--r--src/declarative/items/qquickitemview.cpp1732
1 files changed, 0 insertions, 1732 deletions
diff --git a/src/declarative/items/qquickitemview.cpp b/src/declarative/items/qquickitemview.cpp
deleted file mode 100644
index edbe2a5d06..0000000000
--- a/src/declarative/items/qquickitemview.cpp
+++ /dev/null
@@ -1,1732 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 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$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qquickitemview_p_p.h"
-
-QT_BEGIN_NAMESPACE
-
-
-FxViewItem::FxViewItem(QQuickItem *i, bool own)
- : item(i), ownItem(own), index(-1)
-{
-}
-
-FxViewItem::~FxViewItem()
-{
- if (ownItem && item) {
- item->setParentItem(0);
- item->deleteLater();
- item = 0;
- }
-}
-
-
-QQuickItemViewChangeSet::QQuickItemViewChangeSet()
- : active(false)
-{
- reset();
-}
-
-bool QQuickItemViewChangeSet::hasPendingChanges() const
-{
- return !pendingChanges.isEmpty();
-}
-
-void QQuickItemViewChangeSet::applyChanges(const QDeclarativeChangeSet &changeSet)
-{
- pendingChanges.apply(changeSet);
-
- int moveId = -1;
- int moveOffset;
-
- foreach (const QDeclarativeChangeSet::Remove &r, changeSet.removes()) {
- itemCount -= r.count;
- if (moveId == -1 && newCurrentIndex >= r.index + r.count) {
- newCurrentIndex -= r.count;
- currentChanged = true;
- } else if (moveId == -1 && newCurrentIndex >= r.index && newCurrentIndex < r.index + r.count) {
- // current item has been removed.
- if (r.isMove()) {
- moveId = r.moveId;
- moveOffset = newCurrentIndex - r.index;
- } else {
- currentRemoved = true;
- newCurrentIndex = -1;
- if (itemCount)
- newCurrentIndex = qMin(r.index, itemCount - 1);
- }
- currentChanged = true;
- }
- }
- foreach (const QDeclarativeChangeSet::Insert &i, changeSet.inserts()) {
- if (moveId == -1) {
- if (itemCount && newCurrentIndex >= i.index) {
- newCurrentIndex += i.count;
- currentChanged = true;
- } else if (newCurrentIndex < 0) {
- newCurrentIndex = 0;
- currentChanged = true;
- } else if (newCurrentIndex == 0 && !itemCount) {
- // this is the first item, set the initial current index
- currentChanged = true;
- }
- } else if (moveId == i.moveId) {
- newCurrentIndex = i.index + moveOffset;
- }
- itemCount += i.count;
- }
-}
-
-void QQuickItemViewChangeSet::prepare(int currentIndex, int count)
-{
- if (active)
- return;
- reset();
- active = true;
- itemCount = count;
- newCurrentIndex = currentIndex;
-}
-
-void QQuickItemViewChangeSet::reset()
-{
- itemCount = 0;
- newCurrentIndex = -1;
- pendingChanges.clear();
- removedItems.clear();
- active = false;
- currentChanged = false;
- currentRemoved = false;
-}
-
-
-QQuickItemView::QQuickItemView(QQuickFlickablePrivate &dd, QQuickItem *parent)
- : QQuickFlickable(dd, parent)
-{
- Q_D(QQuickItemView);
- d->init();
-}
-
-QQuickItemView::~QQuickItemView()
-{
- Q_D(QQuickItemView);
- d->clear();
- if (d->ownModel)
- delete d->model;
- delete d->header;
- delete d->footer;
-}
-
-
-QQuickItem *QQuickItemView::currentItem() const
-{
- Q_D(const QQuickItemView);
- if (!d->currentItem)
- return 0;
- const_cast<QQuickItemViewPrivate*>(d)->applyPendingChanges();
- return d->currentItem->item;
-}
-
-QVariant QQuickItemView::model() const
-{
- Q_D(const QQuickItemView);
- return d->modelVariant;
-}
-
-void QQuickItemView::setModel(const QVariant &model)
-{
- Q_D(QQuickItemView);
- if (d->modelVariant == model)
- return;
- if (d->model) {
- disconnect(d->model, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)),
- this, SLOT(modelUpdated(QDeclarativeChangeSet,bool)));
- disconnect(d->model, SIGNAL(initItem(int,QQuickItem*)), this, SLOT(initItem(int,QQuickItem*)));
- disconnect(d->model, SIGNAL(createdItem(int,QQuickItem*)), this, SLOT(createdItem(int,QQuickItem*)));
- disconnect(d->model, SIGNAL(destroyingItem(QQuickItem*)), this, SLOT(destroyingItem(QQuickItem*)));
- }
-
- QQuickVisualModel *oldModel = d->model;
-
- d->clear();
- d->setPosition(d->contentStartPosition());
- d->model = 0;
- d->modelVariant = model;
-
- QObject *object = qvariant_cast<QObject*>(model);
- QQuickVisualModel *vim = 0;
- if (object && (vim = qobject_cast<QQuickVisualModel *>(object))) {
- if (d->ownModel) {
- delete oldModel;
- d->ownModel = false;
- }
- d->model = vim;
- } else {
- if (!d->ownModel) {
- d->model = new QQuickVisualDataModel(qmlContext(this), this);
- d->ownModel = true;
- if (isComponentComplete())
- static_cast<QQuickVisualDataModel *>(d->model.data())->componentComplete();
- } else {
- d->model = oldModel;
- }
- if (QQuickVisualDataModel *dataModel = qobject_cast<QQuickVisualDataModel*>(d->model))
- dataModel->setModel(model);
- }
-
- if (d->model) {
- d->bufferMode = QQuickItemViewPrivate::BufferBefore | QQuickItemViewPrivate::BufferAfter;
- connect(d->model, SIGNAL(createdItem(int,QQuickItem*)), this, SLOT(createdItem(int,QQuickItem*)));
- connect(d->model, SIGNAL(initItem(int,QQuickItem*)), this, SLOT(initItem(int,QQuickItem*)));
- connect(d->model, SIGNAL(destroyingItem(QQuickItem*)), this, SLOT(destroyingItem(QQuickItem*)));
- if (isComponentComplete()) {
- updateSections();
- d->refill();
- if ((d->currentIndex >= d->model->count() || d->currentIndex < 0) && !d->currentIndexCleared) {
- setCurrentIndex(0);
- } else {
- d->moveReason = QQuickItemViewPrivate::SetIndex;
- d->updateCurrent(d->currentIndex);
- if (d->highlight && d->currentItem) {
- if (d->autoHighlight)
- d->resetHighlightPosition();
- d->updateTrackedItem();
- }
- d->moveReason = QQuickItemViewPrivate::Other;
- }
- d->updateViewport();
- }
- connect(d->model, SIGNAL(modelUpdated(QDeclarativeChangeSet,bool)),
- this, SLOT(modelUpdated(QDeclarativeChangeSet,bool)));
- emit countChanged();
- }
- emit modelChanged();
-}
-
-QDeclarativeComponent *QQuickItemView::delegate() const
-{
- Q_D(const QQuickItemView);
- if (d->model) {
- if (QQuickVisualDataModel *dataModel = qobject_cast<QQuickVisualDataModel*>(d->model))
- return dataModel->delegate();
- }
-
- return 0;
-}
-
-void QQuickItemView::setDelegate(QDeclarativeComponent *delegate)
-{
- Q_D(QQuickItemView);
- if (delegate == this->delegate())
- return;
- if (!d->ownModel) {
- d->model = new QQuickVisualDataModel(qmlContext(this));
- d->ownModel = true;
- }
- if (QQuickVisualDataModel *dataModel = qobject_cast<QQuickVisualDataModel*>(d->model)) {
- int oldCount = dataModel->count();
- 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;
- updateSections();
- d->refill();
- d->moveReason = QQuickItemViewPrivate::SetIndex;
- d->updateCurrent(d->currentIndex);
- if (d->highlight && d->currentItem) {
- if (d->autoHighlight)
- d->resetHighlightPosition();
- d->updateTrackedItem();
- }
- d->moveReason = QQuickItemViewPrivate::Other;
- d->updateViewport();
- }
- if (oldCount != dataModel->count())
- emit countChanged();
- }
- emit delegateChanged();
-}
-
-
-int QQuickItemView::count() const
-{
- Q_D(const QQuickItemView);
- if (!d->model)
- return 0;
- const_cast<QQuickItemViewPrivate*>(d)->applyPendingChanges();
- return d->model->count();
-}
-
-int QQuickItemView::currentIndex() const
-{
- Q_D(const QQuickItemView);
- const_cast<QQuickItemViewPrivate*>(d)->applyPendingChanges();
- return d->currentIndex;
-}
-
-void QQuickItemView::setCurrentIndex(int index)
-{
- Q_D(QQuickItemView);
- if (d->requestedIndex >= 0 && !d->requestedAsync) // currently creating item
- return;
- d->currentIndexCleared = (index == -1);
-
- d->applyPendingChanges();
- if (index == d->currentIndex)
- return;
- if (isComponentComplete() && d->isValid()) {
- d->moveReason = QQuickItemViewPrivate::SetIndex;
- d->updateCurrent(index);
- } else if (d->currentIndex != index) {
- d->currentIndex = index;
- emit currentIndexChanged();
- }
-}
-
-
-bool QQuickItemView::isWrapEnabled() const
-{
- Q_D(const QQuickItemView);
- return d->wrap;
-}
-
-void QQuickItemView::setWrapEnabled(bool wrap)
-{
- Q_D(QQuickItemView);
- if (d->wrap == wrap)
- return;
- d->wrap = wrap;
- emit keyNavigationWrapsChanged();
-}
-
-int QQuickItemView::cacheBuffer() const
-{
- Q_D(const QQuickItemView);
- return d->buffer;
-}
-
-void QQuickItemView::setCacheBuffer(int b)
-{
- Q_D(QQuickItemView);
- if (d->buffer != b) {
- d->buffer = b;
- if (isComponentComplete()) {
- d->bufferMode = QQuickItemViewPrivate::BufferBefore | QQuickItemViewPrivate::BufferAfter;
- d->refill();
- }
- emit cacheBufferChanged();
- }
-}
-
-
-Qt::LayoutDirection QQuickItemView::layoutDirection() const
-{
- Q_D(const QQuickItemView);
- return d->layoutDirection;
-}
-
-void QQuickItemView::setLayoutDirection(Qt::LayoutDirection layoutDirection)
-{
- Q_D(QQuickItemView);
- if (d->layoutDirection != layoutDirection) {
- d->layoutDirection = layoutDirection;
- d->regenerate();
- emit layoutDirectionChanged();
- emit effectiveLayoutDirectionChanged();
- }
-}
-
-Qt::LayoutDirection QQuickItemView::effectiveLayoutDirection() const
-{
- Q_D(const QQuickItemView);
- if (d->effectiveLayoutMirror)
- return d->layoutDirection == Qt::RightToLeft ? Qt::LeftToRight : Qt::RightToLeft;
- else
- return d->layoutDirection;
-}
-
-
-QDeclarativeComponent *QQuickItemView::header() const
-{
- Q_D(const QQuickItemView);
- return d->headerComponent;
-}
-
-QQuickItem *QQuickItemView::headerItem() const
-{
- Q_D(const QQuickItemView);
- const_cast<QQuickItemViewPrivate*>(d)->applyPendingChanges();
- return d->header ? d->header->item : 0;
-}
-
-void QQuickItemView::setHeader(QDeclarativeComponent *headerComponent)
-{
- Q_D(QQuickItemView);
- if (d->headerComponent != headerComponent) {
- d->applyPendingChanges();
- delete d->header;
- d->header = 0;
- d->headerComponent = headerComponent;
-
- d->markExtentsDirty();
-
- if (isComponentComplete()) {
- d->updateHeader();
- d->updateFooter();
- d->updateViewport();
- d->fixupPosition();
- } else {
- emit headerItemChanged();
- }
- emit headerChanged();
- }
-}
-
-QDeclarativeComponent *QQuickItemView::footer() const
-{
- Q_D(const QQuickItemView);
- return d->footerComponent;
-}
-
-QQuickItem *QQuickItemView::footerItem() const
-{
- Q_D(const QQuickItemView);
- const_cast<QQuickItemViewPrivate*>(d)->applyPendingChanges();
- return d->footer ? d->footer->item : 0;
-}
-
-void QQuickItemView::setFooter(QDeclarativeComponent *footerComponent)
-{
- Q_D(QQuickItemView);
- if (d->footerComponent != footerComponent) {
- d->applyPendingChanges();
- delete d->footer;
- d->footer = 0;
- d->footerComponent = footerComponent;
-
- if (isComponentComplete()) {
- d->updateFooter();
- d->updateViewport();
- d->fixupPosition();
- } else {
- emit footerItemChanged();
- }
- emit footerChanged();
- }
-}
-
-QDeclarativeComponent *QQuickItemView::highlight() const
-{
- Q_D(const QQuickItemView);
- const_cast<QQuickItemViewPrivate*>(d)->applyPendingChanges();
- return d->highlightComponent;
-}
-
-void QQuickItemView::setHighlight(QDeclarativeComponent *highlightComponent)
-{
- Q_D(QQuickItemView);
- if (highlightComponent != d->highlightComponent) {
- d->applyPendingChanges();
- d->highlightComponent = highlightComponent;
- d->createHighlight();
- if (d->currentItem)
- d->updateHighlight();
- emit highlightChanged();
- }
-}
-
-QQuickItem *QQuickItemView::highlightItem() const
-{
- Q_D(const QQuickItemView);
- const_cast<QQuickItemViewPrivate*>(d)->applyPendingChanges();
- return d->highlight ? d->highlight->item : 0;
-}
-
-bool QQuickItemView::highlightFollowsCurrentItem() const
-{
- Q_D(const QQuickItemView);
- return d->autoHighlight;
-}
-
-void QQuickItemView::setHighlightFollowsCurrentItem(bool autoHighlight)
-{
- Q_D(QQuickItemView);
- if (d->autoHighlight != autoHighlight) {
- d->autoHighlight = autoHighlight;
- if (autoHighlight)
- d->updateHighlight();
- emit highlightFollowsCurrentItemChanged();
- }
-}
-
-QQuickItemView::HighlightRangeMode QQuickItemView::highlightRangeMode() const
-{
- Q_D(const QQuickItemView);
- return static_cast<QQuickItemView::HighlightRangeMode>(d->highlightRange);
-}
-
-void QQuickItemView::setHighlightRangeMode(HighlightRangeMode mode)
-{
- Q_D(QQuickItemView);
- if (d->highlightRange == mode)
- return;
- d->highlightRange = mode;
- d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
- emit highlightRangeModeChanged();
-}
-
-//###Possibly rename these properties, since they are very useful even without a highlight?
-qreal QQuickItemView::preferredHighlightBegin() const
-{
- Q_D(const QQuickItemView);
- return d->highlightRangeStart;
-}
-
-void QQuickItemView::setPreferredHighlightBegin(qreal start)
-{
- Q_D(QQuickItemView);
- d->highlightRangeStartValid = true;
- if (d->highlightRangeStart == start)
- return;
- d->highlightRangeStart = start;
- d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
- emit preferredHighlightBeginChanged();
-}
-
-void QQuickItemView::resetPreferredHighlightBegin()
-{
- Q_D(QQuickItemView);
- d->highlightRangeStartValid = false;
- if (d->highlightRangeStart == 0)
- return;
- d->highlightRangeStart = 0;
- emit preferredHighlightBeginChanged();
-}
-
-qreal QQuickItemView::preferredHighlightEnd() const
-{
- Q_D(const QQuickItemView);
- return d->highlightRangeEnd;
-}
-
-void QQuickItemView::setPreferredHighlightEnd(qreal end)
-{
- Q_D(QQuickItemView);
- d->highlightRangeEndValid = true;
- if (d->highlightRangeEnd == end)
- return;
- d->highlightRangeEnd = end;
- d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd;
- emit preferredHighlightEndChanged();
-}
-
-void QQuickItemView::resetPreferredHighlightEnd()
-{
- Q_D(QQuickItemView);
- d->highlightRangeEndValid = false;
- if (d->highlightRangeEnd == 0)
- return;
- d->highlightRangeEnd = 0;
- emit preferredHighlightEndChanged();
-}
-
-int QQuickItemView::highlightMoveDuration() const
-{
- Q_D(const QQuickItemView);
- return d->highlightMoveDuration;
-}
-
-void QQuickItemView::setHighlightMoveDuration(int duration)
-{
- Q_D(QQuickItemView);
- if (d->highlightMoveDuration != duration) {
- d->highlightMoveDuration = duration;
- emit highlightMoveDurationChanged();
- }
-}
-
-void QQuickItemViewPrivate::positionViewAtIndex(int index, int mode)
-{
- Q_Q(QQuickItemView);
- if (!isValid())
- return;
- if (mode < QQuickItemView::Beginning || mode > QQuickItemView::Contain)
- return;
-
- applyPendingChanges();
- int idx = qMax(qMin(index, model->count()-1), 0);
-
- qreal pos = isContentFlowReversed() ? -position() - size() : position();
- FxViewItem *item = visibleItem(idx);
- qreal maxExtent;
- if (layoutOrientation() == Qt::Vertical)
- maxExtent = -q->maxYExtent();
- else
- maxExtent = isContentFlowReversed() ? q->minXExtent()-size(): -q->maxXExtent();
- if (!item) {
- int itemPos = positionAt(idx);
- changedVisibleIndex(idx);
- // save the currently visible items in case any of them end up visible again
- QList<FxViewItem *> oldVisible = visibleItems;
- visibleItems.clear();
- setPosition(qMin(qreal(itemPos), maxExtent));
- // now release the reference to all the old visible items.
- for (int i = 0; i < oldVisible.count(); ++i)
- releaseItem(oldVisible.at(i));
- item = visibleItem(idx);
- }
- if (item) {
- const qreal itemPos = item->position();
- switch (mode) {
- case QQuickItemView::Beginning:
- pos = itemPos;
- if (index < 0 && header)
- pos -= headerSize();
- break;
- case QQuickItemView::Center:
- pos = itemPos - (size() - item->size())/2;
- break;
- case QQuickItemView::End:
- pos = itemPos - size() + item->size();
- if (index >= model->count() && footer)
- pos += footerSize();
- break;
- case QQuickItemView::Visible:
- if (itemPos > pos + size())
- pos = itemPos - size() + item->size();
- else if (item->endPosition() <= pos)
- pos = itemPos;
- break;
- case QQuickItemView::Contain:
- if (item->endPosition() >= pos + size())
- pos = itemPos - size() + item->size();
- if (itemPos < pos)
- pos = itemPos;
- }
- pos = qMin(pos, maxExtent);
- qreal minExtent;
- if (layoutOrientation() == Qt::Vertical)
- minExtent = -q->minYExtent();
- else
- minExtent = isContentFlowReversed() ? q->maxXExtent()-size(): -q->minXExtent();
- pos = qMax(pos, minExtent);
- moveReason = QQuickItemViewPrivate::Other;
- q->cancelFlick();
- setPosition(pos);
-
- if (highlight) {
- if (autoHighlight)
- resetHighlightPosition();
- updateHighlight();
- }
- }
- fixupPosition();
-}
-
-void QQuickItemView::positionViewAtIndex(int index, int mode)
-{
- Q_D(QQuickItemView);
- if (!d->isValid() || index < 0 || index >= d->model->count())
- return;
- d->positionViewAtIndex(index, mode);
-}
-
-
-void QQuickItemView::positionViewAtBeginning()
-{
- Q_D(QQuickItemView);
- if (!d->isValid())
- return;
- d->positionViewAtIndex(-1, Beginning);
-}
-
-void QQuickItemView::positionViewAtEnd()
-{
- Q_D(QQuickItemView);
- if (!d->isValid())
- return;
- d->positionViewAtIndex(d->model->count(), End);
-}
-
-int QQuickItemView::indexAt(qreal x, qreal y) const
-{
- Q_D(const QQuickItemView);
- for (int i = 0; i < d->visibleItems.count(); ++i) {
- const FxViewItem *item = d->visibleItems.at(i);
- if (item->contains(x, y))
- return item->index;
- }
-
- return -1;
-}
-
-void QQuickItemViewPrivate::applyPendingChanges()
-{
- Q_Q(QQuickItemView);
- if (q->isComponentComplete() && currentChanges.hasPendingChanges())
- layout();
-}
-
-// for debugging only
-void QQuickItemViewPrivate::checkVisible() const
-{
- int skip = 0;
- for (int i = 0; i < visibleItems.count(); ++i) {
- FxViewItem *item = visibleItems.at(i);
- if (item->index == -1) {
- ++skip;
- } else if (item->index != visibleIndex + i - skip) {
- qFatal("index %d %d %d", visibleIndex, i, item->index);
- }
- }
-}
-
-void QQuickItemViewPrivate::itemGeometryChanged(QQuickItem *item, const QRectF &newGeometry, const QRectF &oldGeometry)
-{
- Q_Q(QQuickItemView);
- QQuickFlickablePrivate::itemGeometryChanged(item, newGeometry, oldGeometry);
- if (!q->isComponentComplete())
- return;
-
- if (header && header->item == item) {
- updateHeader();
- markExtentsDirty();
- if (!q->isMoving() && !q->isFlicking())
- fixupPosition();
- } else if (footer && footer->item == item) {
- updateFooter();
- markExtentsDirty();
- if (!q->isMoving() && !q->isFlicking())
- fixupPosition();
- }
-
- if (currentItem && currentItem->item == item)
- updateHighlight();
- if (trackedItem && trackedItem->item == item)
- q->trackedPositionChanged();
-}
-
-void QQuickItemView::destroyRemoved()
-{
- Q_D(QQuickItemView);
- for (QList<FxViewItem*>::Iterator it = d->visibleItems.begin();
- it != d->visibleItems.end();) {
- FxViewItem *item = *it;
- if (item->index == -1 && item->attached->delayRemove() == false) {
- d->releaseItem(item);
- it = d->visibleItems.erase(it);
- } else {
- ++it;
- }
- }
-
- // Correct the positioning of the items
- d->updateSections();
- d->forceLayout = true;
- d->layout();
-}
-
-void QQuickItemView::modelUpdated(const QDeclarativeChangeSet &changeSet, bool reset)
-{
- Q_D(QQuickItemView);
- if (reset) {
- d->moveReason = QQuickItemViewPrivate::SetIndex;
- d->regenerate();
- if (d->highlight && d->currentItem) {
- if (d->autoHighlight)
- d->resetHighlightPosition();
- d->updateTrackedItem();
- }
- d->moveReason = QQuickItemViewPrivate::Other;
-
- emit countChanged();
- } else {
- d->currentChanges.prepare(d->currentIndex, d->itemCount);
- d->currentChanges.applyChanges(changeSet);
- polish();
- }
-}
-
-void QQuickItemView::animStopped()
-{
- Q_D(QQuickItemView);
- d->bufferMode = QQuickItemViewPrivate::BufferBefore | QQuickItemViewPrivate::BufferAfter;
- d->refill();
- if (d->haveHighlightRange && d->highlightRange == QQuickItemView::StrictlyEnforceRange)
- d->updateHighlight();
-}
-
-
-void QQuickItemView::trackedPositionChanged()
-{
- Q_D(QQuickItemView);
- if (!d->trackedItem || !d->currentItem)
- return;
- if (d->moveReason == QQuickItemViewPrivate::SetIndex) {
- qreal trackedPos = d->trackedItem->position();
- qreal trackedSize = d->trackedItem->size();
- if (d->trackedItem != d->currentItem) {
- trackedSize += d->currentItem->sectionSize();
- }
- qreal viewPos = d->isContentFlowReversed() ? -d->position()-d->size() : d->position();
- qreal pos = viewPos;
- if (d->haveHighlightRange) {
- if (trackedPos > pos + d->highlightRangeEnd - trackedSize)
- pos = trackedPos - d->highlightRangeEnd + trackedSize;
- if (trackedPos < pos + d->highlightRangeStart)
- pos = trackedPos - d->highlightRangeStart;
- if (d->highlightRange != StrictlyEnforceRange) {
- if (pos > d->endPosition() - d->size())
- pos = d->endPosition() - d->size();
- if (pos < d->startPosition())
- pos = d->startPosition();
- }
- } else {
- qreal trackedEndPos = d->trackedItem->endPosition();
- qreal toItemPos = d->currentItem->position();
- qreal toItemEndPos = d->currentItem->endPosition();
-
- if (d->header && d->showHeaderForIndex(d->currentIndex)) {
- trackedPos -= d->headerSize();
- trackedEndPos -= d->headerSize();
- toItemPos -= d->headerSize();
- toItemEndPos -= d->headerSize();
- } else if (d->footer && d->showFooterForIndex(d->currentIndex)) {
- trackedPos += d->footerSize();
- trackedEndPos += d->footerSize();
- toItemPos += d->footerSize();
- toItemEndPos += d->footerSize();
- }
-
- if (trackedPos < viewPos && toItemPos < viewPos) {
- pos = qMax(trackedPos, toItemPos);
- } else if (trackedEndPos >= viewPos + d->size()
- && toItemEndPos >= viewPos + d->size()) {
- if (trackedEndPos <= toItemEndPos) {
- pos = trackedEndPos - d->size();
- if (trackedSize > d->size())
- pos = trackedPos;
- } else {
- pos = toItemEndPos - d->size();
- if (d->currentItem->size() > d->size())
- pos = d->currentItem->position();
- }
- }
- }
- if (viewPos != pos) {
- cancelFlick();
- d->calcVelocity = true;
- d->setPosition(pos);
- d->calcVelocity = false;
- }
- }
-}
-
-void QQuickItemView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
-{
- Q_D(QQuickItemView);
- d->markExtentsDirty();
- QQuickFlickable::geometryChanged(newGeometry, oldGeometry);
-}
-
-
-qreal QQuickItemView::minYExtent() const
-{
- Q_D(const QQuickItemView);
- if (d->layoutOrientation() == Qt::Horizontal)
- return QQuickFlickable::minYExtent();
-
- if (d->vData.minExtentDirty) {
- d->minExtent = d->vData.startMargin-d->startPosition();
- if (d->header)
- d->minExtent += d->headerSize();
- if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
- d->minExtent += d->highlightRangeStart;
- if (d->visibleItem(0))
- d->minExtent -= d->visibleItem(0)->sectionSize();
- d->minExtent = qMax(d->minExtent, -(d->endPositionAt(0) - d->highlightRangeEnd));
- }
- d->vData.minExtentDirty = false;
- }
-
- return d->minExtent;
-}
-
-qreal QQuickItemView::maxYExtent() const
-{
- Q_D(const QQuickItemView);
- if (d->layoutOrientation() == Qt::Horizontal)
- return height();
-
- if (d->vData.maxExtentDirty) {
- if (!d->model || !d->model->count()) {
- d->maxExtent = d->header ? -d->headerSize() : 0;
- d->maxExtent += height();
- } else if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
- d->maxExtent = -(d->positionAt(d->model->count()-1) - d->highlightRangeStart);
- if (d->highlightRangeEnd != d->highlightRangeStart)
- d->maxExtent = qMin(d->maxExtent, -(d->endPosition() - d->highlightRangeEnd));
- } else {
- d->maxExtent = -(d->endPosition() - height());
- }
-
- if (d->footer)
- d->maxExtent -= d->footerSize();
- d->maxExtent -= d->vData.endMargin;
- qreal minY = minYExtent();
- if (d->maxExtent > minY)
- d->maxExtent = minY;
- d->vData.maxExtentDirty = false;
- }
- return d->maxExtent;
-}
-
-qreal QQuickItemView::minXExtent() const
-{
- Q_D(const QQuickItemView);
- if (d->layoutOrientation() == Qt::Vertical)
- return QQuickFlickable::minXExtent();
-
- if (d->hData.minExtentDirty) {
- d->minExtent = -d->startPosition();
- qreal highlightStart;
- qreal highlightEnd;
- qreal endPositionFirstItem = 0;
- if (d->isContentFlowReversed()) {
- d->minExtent += d->hData.endMargin;
- if (d->model && d->model->count())
- endPositionFirstItem = d->positionAt(d->model->count()-1);
- else if (d->header)
- d->minExtent += d->headerSize();
- highlightStart = d->highlightRangeEndValid ? d->size() - d->highlightRangeEnd : d->size();
- highlightEnd = d->highlightRangeStartValid ? d->size() - d->highlightRangeStart : d->size();
- if (d->footer)
- d->minExtent += d->footerSize();
- qreal maxX = maxXExtent();
- if (d->minExtent < maxX)
- d->minExtent = maxX;
- } else {
- d->minExtent += d->hData.startMargin;
- endPositionFirstItem = d->endPositionAt(0);
- highlightStart = d->highlightRangeStart;
- highlightEnd = d->highlightRangeEnd;
- if (d->header)
- d->minExtent += d->headerSize();
- }
- if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
- d->minExtent += highlightStart;
- d->minExtent = d->isContentFlowReversed()
- ? qMin(d->minExtent, endPositionFirstItem + highlightEnd)
- : qMax(d->minExtent, -(endPositionFirstItem - highlightEnd));
- }
- d->hData.minExtentDirty = false;
- }
-
- return d->minExtent;
-}
-
-qreal QQuickItemView::maxXExtent() const
-{
- Q_D(const QQuickItemView);
- if (d->layoutOrientation() == Qt::Vertical)
- return width();
-
- if (d->hData.maxExtentDirty) {
- qreal highlightStart;
- qreal highlightEnd;
- qreal lastItemPosition = 0;
- d->maxExtent = 0;
- if (d->isContentFlowReversed()) {
- highlightStart = d->highlightRangeEndValid ? d->size() - d->highlightRangeEnd : d->size();
- highlightEnd = d->highlightRangeStartValid ? d->size() - d->highlightRangeStart : d->size();
- lastItemPosition = d->endPosition();
- } else {
- highlightStart = d->highlightRangeStart;
- highlightEnd = d->highlightRangeEnd;
- if (d->model && d->model->count())
- lastItemPosition = d->positionAt(d->model->count()-1);
- }
- if (!d->model || !d->model->count()) {
- if (!d->isContentFlowReversed())
- d->maxExtent = d->header ? -d->headerSize() : 0;
- d->maxExtent += width();
- } else if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) {
- d->maxExtent = -(lastItemPosition - highlightStart);
- if (highlightEnd != highlightStart) {
- d->maxExtent = d->isContentFlowReversed()
- ? qMax(d->maxExtent, -(d->endPosition() - highlightEnd))
- : qMin(d->maxExtent, -(d->endPosition() - highlightEnd));
- }
- } else {
- d->maxExtent = -(d->endPosition() - width());
- }
- if (d->isContentFlowReversed()) {
- if (d->header)
- d->maxExtent -= d->headerSize();
- d->maxExtent -= d->hData.startMargin;
- } else {
- if (d->footer)
- d->maxExtent -= d->footerSize();
- d->maxExtent -= d->hData.endMargin;
- qreal minX = minXExtent();
- if (d->maxExtent > minX)
- d->maxExtent = minX;
- }
- d->hData.maxExtentDirty = false;
- }
-
- return d->maxExtent;
-}
-
-void QQuickItemView::setContentX(qreal pos)
-{
- Q_D(QQuickItemView);
- // Positioning the view manually should override any current movement state
- d->moveReason = QQuickItemViewPrivate::Other;
- QQuickFlickable::setContentX(pos);
-}
-
-void QQuickItemView::setContentY(qreal pos)
-{
- Q_D(QQuickItemView);
- // Positioning the view manually should override any current movement state
- d->moveReason = QQuickItemViewPrivate::Other;
- QQuickFlickable::setContentY(pos);
-}
-
-qreal QQuickItemView::xOrigin() const
-{
- Q_D(const QQuickItemView);
- if (d->isContentFlowReversed())
- return -maxXExtent() + d->size() - d->hData.startMargin;
- else
- return -minXExtent() + d->hData.startMargin;
-}
-
-void QQuickItemView::updatePolish()
-{
- Q_D(QQuickItemView);
- QQuickFlickable::updatePolish();
- d->layout();
-}
-
-void QQuickItemView::componentComplete()
-{
- Q_D(QQuickItemView);
- if (d->model && d->ownModel)
- static_cast<QQuickVisualDataModel *>(d->model.data())->componentComplete();
-
- QQuickFlickable::componentComplete();
-
- updateSections();
- d->updateHeader();
- d->updateFooter();
- d->updateViewport();
- d->setPosition(d->contentStartPosition());
- if (d->isValid()) {
- d->refill();
- d->moveReason = QQuickItemViewPrivate::SetIndex;
- if (d->currentIndex < 0 && !d->currentIndexCleared)
- d->updateCurrent(0);
- else
- d->updateCurrent(d->currentIndex);
- if (d->highlight && d->currentItem) {
- if (d->autoHighlight)
- d->resetHighlightPosition();
- d->updateTrackedItem();
- }
- d->moveReason = QQuickItemViewPrivate::Other;
- d->fixupPosition();
- }
- if (d->model && d->model->count())
- emit countChanged();
-}
-
-
-
-QQuickItemViewPrivate::QQuickItemViewPrivate()
- : itemCount(0)
- , buffer(0), bufferMode(BufferBefore | BufferAfter)
- , layoutDirection(Qt::LeftToRight)
- , moveReason(Other)
- , visibleIndex(0)
- , currentIndex(-1), currentItem(0)
- , trackedItem(0), requestedIndex(-1), requestedItem(0)
- , highlightComponent(0), highlight(0)
- , highlightRange(QQuickItemView::NoHighlightRange)
- , highlightRangeStart(0), highlightRangeEnd(0)
- , highlightMoveDuration(150)
- , headerComponent(0), header(0), footerComponent(0), footer(0)
- , minExtent(0), maxExtent(0)
- , ownModel(false), wrap(false), deferredRelease(false)
- , inApplyModelChanges(false), inViewportMoved(false), forceLayout(false), currentIndexCleared(false)
- , haveHighlightRange(false), autoHighlight(true), highlightRangeStartValid(false), highlightRangeEndValid(false)
- , fillCacheBuffer(false), inRequest(false), requestedAsync(false)
-{
-}
-
-bool QQuickItemViewPrivate::isValid() const
-{
- return model && model->count() && model->isValid();
-}
-
-qreal QQuickItemViewPrivate::position() const
-{
- Q_Q(const QQuickItemView);
- return layoutOrientation() == Qt::Vertical ? q->contentY() : q->contentX();
-}
-
-qreal QQuickItemViewPrivate::size() const
-{
- Q_Q(const QQuickItemView);
- return layoutOrientation() == Qt::Vertical ? q->height() : q->width();
-}
-
-qreal QQuickItemViewPrivate::startPosition() const
-{
- return isContentFlowReversed() ? -lastPosition() : originPosition();
-}
-
-qreal QQuickItemViewPrivate::endPosition() const
-{
- return isContentFlowReversed() ? -originPosition() : lastPosition();
-}
-
-qreal QQuickItemViewPrivate::contentStartPosition() const
-{
- qreal pos = -headerSize();
- if (layoutOrientation() == Qt::Vertical)
- pos -= vData.startMargin;
- else if (isContentFlowReversed())
- pos -= hData.endMargin;
- else
- pos -= hData.startMargin;
-
- return pos;
-}
-
-int QQuickItemViewPrivate::findLastVisibleIndex(int defaultValue) const
-{
- if (visibleItems.count()) {
- int i = visibleItems.count() - 1;
- while (i > 0 && visibleItems.at(i)->index == -1)
- --i;
- if (visibleItems.at(i)->index != -1)
- return visibleItems.at(i)->index;
- }
- return defaultValue;
-}
-
-FxViewItem *QQuickItemViewPrivate::visibleItem(int modelIndex) const {
- if (modelIndex >= visibleIndex && modelIndex < visibleIndex + visibleItems.count()) {
- for (int i = modelIndex - visibleIndex; i < visibleItems.count(); ++i) {
- FxViewItem *item = visibleItems.at(i);
- if (item->index == modelIndex)
- return item;
- }
- }
- return 0;
-}
-
-FxViewItem *QQuickItemViewPrivate::firstVisibleItem() const {
- const qreal pos = isContentFlowReversed() ? -position()-size() : position();
- for (int i = 0; i < visibleItems.count(); ++i) {
- FxViewItem *item = visibleItems.at(i);
- if (item->index != -1 && item->endPosition() > pos)
- return item;
- }
- return visibleItems.count() ? visibleItems.first() : 0;
-}
-
-// Map a model index to visibleItems list index.
-// These may differ if removed items are still present in the visible list,
-// e.g. doing a removal animation
-int QQuickItemViewPrivate::mapFromModel(int modelIndex) const
-{
- if (modelIndex < visibleIndex || modelIndex >= visibleIndex + visibleItems.count())
- return -1;
- for (int i = 0; i < visibleItems.count(); ++i) {
- FxViewItem *item = visibleItems.at(i);
- if (item->index == modelIndex)
- return i;
- if (item->index > modelIndex)
- return -1;
- }
- return -1; // Not in visibleList
-}
-
-void QQuickItemViewPrivate::init()
-{
- Q_Q(QQuickItemView);
- QQuickItemPrivate::get(contentItem)->childrenDoNotOverlap = true;
- q->setFlag(QQuickItem::ItemIsFocusScope);
- addItemChangeListener(this, Geometry);
- QObject::connect(q, SIGNAL(movementEnded()), q, SLOT(animStopped()));
- q->setFlickableDirection(QQuickFlickable::VerticalFlick);
-}
-
-void QQuickItemViewPrivate::updateCurrent(int modelIndex)
-{
- Q_Q(QQuickItemView);
- applyPendingChanges();
-
- if (!q->isComponentComplete() || !isValid() || modelIndex < 0 || modelIndex >= model->count()) {
- if (currentItem) {
- currentItem->attached->setIsCurrentItem(false);
- releaseItem(currentItem);
- currentItem = 0;
- currentIndex = modelIndex;
- emit q->currentIndexChanged();
- emit q->currentItemChanged();
- updateHighlight();
- } else if (currentIndex != modelIndex) {
- currentIndex = modelIndex;
- emit q->currentIndexChanged();
- }
- return;
- }
-
- if (currentItem && currentIndex == modelIndex) {
- updateHighlight();
- return;
- }
-
- FxViewItem *oldCurrentItem = currentItem;
- int oldCurrentIndex = currentIndex;
- currentIndex = modelIndex;
- currentItem = createItem(modelIndex, false);
- if (oldCurrentItem && (!currentItem || oldCurrentItem->item != currentItem->item))
- oldCurrentItem->attached->setIsCurrentItem(false);
- if (currentItem) {
- currentItem->item->setFocus(true);
- currentItem->attached->setIsCurrentItem(true);
- initializeCurrentItem();
- }
-
- updateHighlight();
- if (oldCurrentIndex != currentIndex)
- emit q->currentIndexChanged();
- if (oldCurrentItem != currentItem)
- emit q->currentItemChanged();
- releaseItem(oldCurrentItem);
-}
-
-void QQuickItemViewPrivate::clear()
-{
- currentChanges.reset();
- timeline.clear();
-
- for (int i = 0; i < visibleItems.count(); ++i)
- releaseItem(visibleItems.at(i));
- visibleItems.clear();
- visibleIndex = 0;
-
- releaseItem(currentItem);
- currentItem = 0;
- createHighlight();
- trackedItem = 0;
-
- markExtentsDirty();
- itemCount = 0;
-}
-
-
-void QQuickItemViewPrivate::mirrorChange()
-{
- Q_Q(QQuickItemView);
- regenerate();
- emit q->effectiveLayoutDirectionChanged();
-}
-
-void QQuickItemViewPrivate::refill()
-{
- if (isContentFlowReversed())
- refill(-position()-size(), -position());
- else
- refill(position(), position()+size());
-}
-
-void QQuickItemViewPrivate::refill(qreal from, qreal to, bool doBuffer)
-{
- Q_Q(QQuickItemView);
- if (!isValid() || !q->isComponentComplete())
- return;
-
- currentChanges.reset();
-
- int prevCount = itemCount;
- itemCount = model->count();
- qreal bufferFrom = from - buffer;
- qreal bufferTo = to + buffer;
- qreal fillFrom = from;
- qreal fillTo = to;
- if (doBuffer && (bufferMode & BufferAfter))
- fillTo = bufferTo;
- if (doBuffer && (bufferMode & BufferBefore))
- fillFrom = bufferFrom;
-
- // Item creation and release is staggered in order to avoid
- // creating/releasing multiple items in one frame
- // while flicking (as much as possible).
-
- bool changed = addVisibleItems(fillFrom, fillTo, doBuffer);
-
- if (!changed || deferredRelease) { // avoid destroying items in the same frame that we create
- if (removeNonVisibleItems(bufferFrom, bufferTo))
- changed = true;
- deferredRelease = false;
- } else {
- deferredRelease = true;
- }
-
- if (changed) {
- markExtentsDirty();
- visibleItemsChanged();
- } else if (!doBuffer && buffer && bufferMode != NoBuffer) {
- refill(from, to, true);
- }
-
- if (!q->isMoving() && changed) {
- fillCacheBuffer = true;
- q->polish();
- }
-
- if (prevCount != itemCount)
- emit q->countChanged();
-}
-
-void QQuickItemViewPrivate::regenerate()
-{
- Q_Q(QQuickItemView);
- if (q->isComponentComplete()) {
- currentChanges.reset();
- delete header;
- header = 0;
- delete footer;
- footer = 0;
- updateHeader();
- updateFooter();
- clear();
- updateViewport();
- setPosition(contentStartPosition());
- refill();
- updateCurrent(currentIndex);
- }
-}
-
-void QQuickItemViewPrivate::updateViewport()
-{
- Q_Q(QQuickItemView);
- if (isValid()) {
- if (layoutOrientation() == Qt::Vertical)
- q->setContentHeight(endPosition() - startPosition());
- else
- q->setContentWidth(endPosition() - startPosition());
- }
-}
-
-void QQuickItemViewPrivate::layout()
-{
- Q_Q(QQuickItemView);
- if (inApplyModelChanges)
- return;
-
- if (!isValid() && !visibleItems.count()) {
- clear();
- setPosition(contentStartPosition());
- return;
- }
-
- if (!applyModelChanges() && !forceLayout) {
- if (fillCacheBuffer)
- refill();
- return;
- }
- forceLayout = false;
-
- layoutVisibleItems();
- refill();
-
- markExtentsDirty();
-
- updateHighlight();
-
- if (!q->isMoving() && !q->isFlicking()) {
- fixupPosition();
- refill();
- }
-
- updateHeader();
- updateFooter();
- updateViewport();
- updateUnrequestedPositions();
-}
-
-bool QQuickItemViewPrivate::applyModelChanges()
-{
- Q_Q(QQuickItemView);
- if (!q->isComponentComplete() || !currentChanges.hasPendingChanges() || inApplyModelChanges)
- return false;
-
- inApplyModelChanges = true;
-
- updateUnrequestedIndexes();
- moveReason = QQuickItemViewPrivate::Other;
-
- int prevCount = itemCount;
- bool visibleAffected = false;
- bool viewportChanged = !currentChanges.pendingChanges.removes().isEmpty()
- || !currentChanges.pendingChanges.inserts().isEmpty();
-
- FxViewItem *firstVisible = firstVisibleItem();
- FxViewItem *origVisibleItemsFirst = visibleItems.count() ? visibleItems.first() : 0;
- int firstItemIndex = firstVisible ? firstVisible->index : -1;
- qreal removedBeforeFirstVisibleBy = 0;
-
- const QVector<QDeclarativeChangeSet::Remove> &removals = currentChanges.pendingChanges.removes();
- for (int i=0; i<removals.count(); i++) {
- itemCount -= removals[i].count;
-
- // Remove the items from the visible list, skipping anything already marked for removal
- QList<FxViewItem*>::Iterator it = visibleItems.begin();
- while (it != visibleItems.end()) {
- FxViewItem *item = *it;
- if (item->index == -1 || item->index < removals[i].index) {
- // already removed, or before removed items
- if (!visibleAffected && item->index < removals[i].index)
- visibleAffected = true;
- ++it;
- } else if (item->index >= removals[i].index + removals[i].count) {
- // after removed items
- item->index -= removals[i].count;
- ++it;
- } else {
- // removed item
- visibleAffected = true;
- if (!removals[i].isMove())
- item->attached->emitRemove();
-
- if (item->attached->delayRemove() && !removals[i].isMove()) {
- item->index = -1;
- QObject::connect(item->attached, SIGNAL(delayRemoveChanged()), q, SLOT(destroyRemoved()), Qt::QueuedConnection);
- ++it;
- } else {
- if (firstVisible && item->position() < firstVisible->position() && item != visibleItems.first())
- removedBeforeFirstVisibleBy += item->size();
- if (removals[i].isMove()) {
- currentChanges.removedItems.insert(removals[i].moveKey(item->index), item);
- } else {
- if (item == firstVisible)
- firstVisible = 0;
- currentChanges.removedItems.insertMulti(QDeclarativeChangeSet::MoveKey(), item);
- }
- it = visibleItems.erase(it);
- }
- }
- }
- if (!visibleAffected && needsRefillForAddedOrRemovedIndex(removals[i].index))
- visibleAffected = true;
- }
- if (!removals.isEmpty())
- updateVisibleIndex();
-
- const QVector<QDeclarativeChangeSet::Insert> &insertions = currentChanges.pendingChanges.inserts();
- InsertionsResult insertResult;
- bool allInsertionsBeforeVisible = true;
-
- for (int i=0; i<insertions.count(); i++) {
- bool wasEmpty = visibleItems.isEmpty();
- if (applyInsertionChange(insertions[i], firstVisible, &insertResult))
- visibleAffected = true;
- if (!visibleAffected && needsRefillForAddedOrRemovedIndex(insertions[i].index))
- visibleAffected = true;
- if (insertions[i].index >= visibleIndex)
- allInsertionsBeforeVisible = false;
- if (wasEmpty && !visibleItems.isEmpty())
- resetFirstItemPosition();
- itemCount += insertions[i].count;
- }
- for (int i=0; i<insertResult.addedItems.count(); ++i)
- insertResult.addedItems.at(i)->attached->emitAdd();
-
- // if the first visible item has moved, ensure another one takes its place
- // so that we avoid shifting all content forwards
- // (if an item is removed from before the first visible, the first visible should not move upwards)
- bool movedBackToFirstVisible = false;
- if (firstVisible && firstItemIndex >= 0) {
- for (int i=0; i<insertResult.movedBackwards.count(); i++) {
- if (insertResult.movedBackwards[i]->index == firstItemIndex) {
- // an item has moved backwards up to the first visible's position
- resetItemPosition(insertResult.movedBackwards[i], firstVisible);
- insertResult.movedBackwards.removeAt(i);
- movedBackToFirstVisible = true;
- break;
- }
- }
- if (!movedBackToFirstVisible && !allInsertionsBeforeVisible) {
- // first visible item has moved forward, another visible item takes its place
- FxViewItem *item = visibleItem(firstItemIndex);
- if (item)
- resetItemPosition(item, firstVisible);
- }
- }
-
- // Ensure we don't cause an ugly list scroll
- if (firstVisible && visibleItems.count() && visibleItems.first() != firstVisible) {
- // ensure first item is placed at correct postion if moving backward
- // since it will be used to position all subsequent items
- if (insertResult.movedBackwards.count() && origVisibleItemsFirst)
- resetItemPosition(visibleItems.first(), origVisibleItemsFirst);
-
- // correct the first item position (unless it has already been fixed)
- if (!movedBackToFirstVisible) {
- qreal moveBackwardsBy = insertResult.sizeAddedBeforeVisible;
- for (int i=0; i<insertResult.movedBackwards.count(); i++)
- moveBackwardsBy += insertResult.movedBackwards[i]->size();
- moveItemBy(visibleItems.first(), removedBeforeFirstVisibleBy, moveBackwardsBy);
- }
- }
-
- // Whatever removed/moved items remain are no longer visible items.
- for (QHash<QDeclarativeChangeSet::MoveKey, FxViewItem *>::Iterator it = currentChanges.removedItems.begin();
- it != currentChanges.removedItems.end(); ++it) {
- releaseItem(it.value());
- }
- currentChanges.removedItems.clear();
-
- if (currentChanges.currentChanged) {
- if (currentChanges.currentRemoved && currentItem) {
- currentItem->attached->setIsCurrentItem(false);
- releaseItem(currentItem);
- currentItem = 0;
- }
- if (!currentIndexCleared)
- updateCurrent(currentChanges.newCurrentIndex);
- }
- currentChanges.reset();
-
- updateSections();
- if (prevCount != itemCount)
- emit q->countChanged();
-
- if (!visibleAffected)
- visibleAffected = !currentChanges.pendingChanges.changes().isEmpty();
- if (!visibleAffected && viewportChanged)
- updateViewport();
-
- inApplyModelChanges = false;
- return visibleAffected;
-}
-
-/*
- This may return 0 if the item is being created asynchronously.
- When the item becomes available, refill() will be called and the item
- will be returned on the next call to createItem().
-*/
-FxViewItem *QQuickItemViewPrivate::createItem(int modelIndex, bool asynchronous)
-{
- Q_Q(QQuickItemView);
- if (requestedIndex == modelIndex && (asynchronous || requestedAsync == asynchronous))
- return 0;
-
- if (requestedIndex != -1 && requestedIndex != modelIndex) {
- delete requestedItem;
- requestedItem = 0;
- }
-
- requestedIndex = modelIndex;
- requestedAsync = asynchronous;
- inRequest = true;
-
- if (QQuickItem *item = model->item(modelIndex, asynchronous)) {
- item->setParentItem(q->contentItem());
- QDeclarative_setParent_noEvent(item, q->contentItem());
- requestedIndex = -1;
- fillCacheBuffer = false;
- FxViewItem *viewItem = requestedItem;
- if (!viewItem)
- viewItem = newViewItem(modelIndex, item); // already in cache, so viewItem not initialized in initItem()
- if (viewItem) {
- viewItem->index = modelIndex;
- // do other set up for the new item that should not happen
- // until after bindings are evaluated
- initializeViewItem(viewItem);
- unrequestedItems.remove(item);
- }
- requestedItem = 0;
- inRequest = false;
- return viewItem;
- }
-
- inRequest = false;
- return 0;
-}
-
-void QQuickItemView::createdItem(int index, QQuickItem *item)
-{
- Q_D(QQuickItemView);
- if (d->requestedIndex != index) {
- item->setParentItem(contentItem());
- d->unrequestedItems.insert(item, index);
- item->setVisible(false);
- d->repositionPackageItemAt(item, index);
- } else {
- d->requestedIndex = -1;
- if (!d->inRequest) {
- if (index == d->currentIndex)
- d->updateCurrent(index);
- d->refill();
- } else {
- d->fillCacheBuffer = true;
- polish();
- }
- }
-}
-
-void QQuickItemView::initItem(int index, QQuickItem *item)
-{
- Q_D(QQuickItemView);
- item->setZ(1);
- if (d->requestedIndex == index) {
- item->setParentItem(contentItem());
- QDeclarative_setParent_noEvent(item, contentItem());
- d->requestedItem = d->newViewItem(index, item);
- }
-}
-
-void QQuickItemView::destroyingItem(QQuickItem *item)
-{
- Q_D(QQuickItemView);
- d->unrequestedItems.remove(item);
-}
-
-void QQuickItemViewPrivate::releaseItem(FxViewItem *item)
-{
- Q_Q(QQuickItemView);
- if (!item || !model)
- return;
- if (trackedItem == item)
- trackedItem = 0;
- QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item->item);
- itemPrivate->removeItemChangeListener(this, QQuickItemPrivate::Geometry);
- 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));
- }
- delete item;
-}
-
-QQuickItem *QQuickItemViewPrivate::createHighlightItem()
-{
- return createComponentItem(highlightComponent, true, true);
-}
-
-QQuickItem *QQuickItemViewPrivate::createComponentItem(QDeclarativeComponent *component, bool receiveItemGeometryChanges, bool createDefault)
-{
- Q_Q(QQuickItemView);
-
- QQuickItem *item = 0;
- if (component) {
- QDeclarativeContext *creationContext = component->creationContext();
- QDeclarativeContext *context = new QDeclarativeContext(
- creationContext ? creationContext : qmlContext(q));
- QObject *nobj = component->create(context);
- if (nobj) {
- QDeclarative_setParent_noEvent(context, nobj);
- item = qobject_cast<QQuickItem *>(nobj);
- if (!item)
- delete nobj;
- } else {
- delete context;
- }
- } else if (createDefault) {
- item = new QQuickItem;
- }
- if (item) {
- QDeclarative_setParent_noEvent(item, q->contentItem());
- item->setParentItem(q->contentItem());
- if (receiveItemGeometryChanges) {
- QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item);
- itemPrivate->addItemChangeListener(this, QQuickItemPrivate::Geometry);
- }
- }
- return item;
-}
-
-void QQuickItemViewPrivate::updateTrackedItem()
-{
- Q_Q(QQuickItemView);
- FxViewItem *item = currentItem;
- if (highlight)
- item = highlight;
- trackedItem = item;
-
- if (trackedItem)
- q->trackedPositionChanged();
-}
-
-void QQuickItemViewPrivate::updateUnrequestedIndexes()
-{
- Q_Q(QQuickItemView);
- for (QHash<QQuickItem*,int>::iterator it = unrequestedItems.begin(); it != unrequestedItems.end(); ++it)
- *it = model->indexOf(it.key(), q);
-}
-
-void QQuickItemViewPrivate::updateUnrequestedPositions()
-{
- for (QHash<QQuickItem*,int>::const_iterator it = unrequestedItems.begin(); it != unrequestedItems.end(); ++it)
- repositionPackageItemAt(it.key(), it.value());
-}
-
-void QQuickItemViewPrivate::updateVisibleIndex()
-{
- visibleIndex = 0;
- for (QList<FxViewItem*>::Iterator it = visibleItems.begin(); it != visibleItems.end(); ++it) {
- if ((*it)->index != -1) {
- visibleIndex = (*it)->index;
- break;
- }
- }
-}
-
-QT_END_NAMESPACE