diff options
Diffstat (limited to 'src/quick')
32 files changed, 230 insertions, 8730 deletions
diff --git a/src/quick/items/items.pri b/src/quick/items/items.pri index 5272a3d5f7..2183a2bc63 100644 --- a/src/quick/items/items.pri +++ b/src/quick/items/items.pri @@ -38,10 +38,6 @@ HEADERS += \ $$PWD/qquickflickable_p.h \ $$PWD/qquickflickable_p_p.h \ $$PWD/qquicklistview_p.h \ - $$PWD/qquickvisualadaptormodel_p.h \ - $$PWD/qquickvisualdatamodel_p.h \ - $$PWD/qquickvisualdatamodel_p_p.h \ - $$PWD/qquickvisualitemmodel_p.h \ $$PWD/qquickrepeater_p.h \ $$PWD/qquickrepeater_p_p.h \ $$PWD/qquickgridview_p.h \ @@ -99,9 +95,6 @@ SOURCES += \ $$PWD/qquickpincharea.cpp \ $$PWD/qquickflickable.cpp \ $$PWD/qquicklistview.cpp \ - $$PWD/qquickvisualadaptormodel.cpp \ - $$PWD/qquickvisualdatamodel.cpp \ - $$PWD/qquickvisualitemmodel.cpp \ $$PWD/qquickrepeater.cpp \ $$PWD/qquickgridview.cpp \ $$PWD/qquickpathview.cpp \ diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp index fd9ce9ffcd..ea8badb584 100644 --- a/src/quick/items/qquickgridview.cpp +++ b/src/quick/items/qquickgridview.cpp @@ -40,10 +40,10 @@ ****************************************************************************/ #include "qquickgridview_p.h" -#include "qquickvisualitemmodel_p.h" #include "qquickflickable_p_p.h" #include "qquickitemview_p_p.h" +#include <private/qqmlobjectmodel_p.h> #include <private/qquicksmoothedanimation_p_p.h> #include <QtGui/qevent.h> @@ -209,7 +209,7 @@ public: virtual void setPosition(qreal pos); virtual void layoutVisibleItems(int fromModelIndex = 0); - virtual bool applyInsertionChange(const QQuickChangeSet::Insert &insert, ChangeResult *changeResult, QList<FxViewItem *> *addedItems, QList<MovedItem> *movingIntoView); + virtual bool applyInsertionChange(const QQmlChangeSet::Insert &insert, ChangeResult *changeResult, QList<FxViewItem *> *addedItems, QList<MovedItem> *movingIntoView); virtual void translateAndTransitionItemsAfter(int afterModelIndex, const ChangeResult &insertionResult, const ChangeResult &removalResult); virtual bool needsRefillForAddedOrRemovedIndex(int index) const; @@ -2105,13 +2105,16 @@ void QQuickGridView::geometryChanged(const QRectF &newGeometry, const QRectF &ol QQuickItemView::geometryChanged(newGeometry, oldGeometry); } -void QQuickGridView::initItem(int index, QQuickItem *item) +void QQuickGridView::initItem(int index, QObject *obj) { - QQuickItemView::initItem(index, item); - QQuickGridViewAttached *attached = static_cast<QQuickGridViewAttached *>( - qmlAttachedPropertiesObject<QQuickGridView>(item)); - if (attached) - attached->setView(this); + QQuickItemView::initItem(index, obj); + QQuickItem *item = qmlobject_cast<QQuickItem*>(obj); + if (item) { + QQuickGridViewAttached *attached = static_cast<QQuickGridViewAttached *>( + qmlAttachedPropertiesObject<QQuickGridView>(item)); + if (attached) + attached->setView(this); + } } /*! @@ -2286,7 +2289,7 @@ void QQuickGridView::moveCurrentIndexRight() } } -bool QQuickGridViewPrivate::applyInsertionChange(const QQuickChangeSet::Insert &change, ChangeResult *insertResult, QList<FxViewItem *> *addedItems, QList<MovedItem> *movingIntoView) +bool QQuickGridViewPrivate::applyInsertionChange(const QQmlChangeSet::Insert &change, ChangeResult *insertResult, QList<FxViewItem *> *addedItems, QList<MovedItem> *movingIntoView) { Q_Q(QQuickGridView); diff --git a/src/quick/items/qquickgridview_p.h b/src/quick/items/qquickgridview_p.h index 64cb814f8c..a1c0ce9389 100644 --- a/src/quick/items/qquickgridview_p.h +++ b/src/quick/items/qquickgridview_p.h @@ -50,7 +50,6 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -class QQuickVisualModel; class QQuickGridViewAttached; class QQuickGridViewPrivate; class Q_AUTOTEST_EXPORT QQuickGridView : public QQuickItemView @@ -112,7 +111,7 @@ protected: virtual void viewportMoved(Qt::Orientations); virtual void keyPressEvent(QKeyEvent *); virtual void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); - virtual void initItem(int index, QQuickItem *item); + virtual void initItem(int index, QObject *item); }; class QQuickGridViewAttached : public QQuickItemViewAttached diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp index c04807168f..043baebd0a 100644 --- a/src/quick/items/qquickitemsmodule.cpp +++ b/src/quick/items/qquickitemsmodule.cpp @@ -57,8 +57,6 @@ #include "qquickflickable_p.h" #include "qquickflickable_p_p.h" #include "qquicklistview_p.h" -#include "qquickvisualitemmodel_p.h" -#include "qquickvisualdatamodel_p.h" #include "qquickgridview_p.h" #include "qquickpathview_p.h" #include "qquickitemviewtransition_p.h" @@ -161,9 +159,6 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor) qmlRegisterType<QQuickTextEdit>(uri,major,minor,"TextEdit"); qmlRegisterType<QQuickTextInput>(uri,major,minor,"TextInput"); qmlRegisterType<QQuickViewSection>(uri,major,minor,"ViewSection"); - qmlRegisterType<QQuickVisualDataModel>(uri,major,minor,"VisualDataModel"); - qmlRegisterType<QQuickVisualDataGroup>(uri,major,minor,"VisualDataGroup"); - qmlRegisterType<QQuickVisualItemModel>(uri,major,minor,"VisualItemModel"); qmlRegisterType<QQuickItemLayer>(); qmlRegisterType<QQuickAnchors>(); @@ -178,7 +173,6 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor) #ifndef QT_NO_VALIDATOR qmlRegisterType<QValidator>(); #endif - qmlRegisterType<QQuickVisualModel>(); qmlRegisterType<QQuickPen>(); qmlRegisterType<QQuickFlickableVisibleArea>(); qRegisterMetaType<QQuickAnchorLine>("QQuickAnchorLine"); diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index b73fb8c5b6..198052b939 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -41,6 +41,7 @@ #include "qquickitemview_p_p.h" #include <QtQuick/private/qquicktransition_p.h> +#include <QtQml/QQmlInfo> #include "qplatformdefs.h" QT_BEGIN_NAMESPACE @@ -147,14 +148,14 @@ bool QQuickItemViewChangeSet::hasPendingChanges() const return !pendingChanges.isEmpty(); } -void QQuickItemViewChangeSet::applyChanges(const QQuickChangeSet &changeSet) +void QQuickItemViewChangeSet::applyChanges(const QQmlChangeSet &changeSet) { pendingChanges.apply(changeSet); int moveId = -1; int moveOffset = 0; - foreach (const QQuickChangeSet::Remove &r, changeSet.removes()) { + foreach (const QQmlChangeSet::Remove &r, changeSet.removes()) { itemCount -= r.count; if (moveId == -1 && newCurrentIndex >= r.index + r.count) { newCurrentIndex -= r.count; @@ -173,7 +174,7 @@ void QQuickItemViewChangeSet::applyChanges(const QQuickChangeSet &changeSet) currentChanged = true; } } - foreach (const QQuickChangeSet::Insert &i, changeSet.inserts()) { + foreach (const QQmlChangeSet::Insert &i, changeSet.inserts()) { if (moveId == -1) { if (itemCount && newCurrentIndex >= i.index) { newCurrentIndex += i.count; @@ -266,14 +267,14 @@ void QQuickItemView::setModel(const QVariant &model) if (d->modelVariant == model) return; if (d->model) { - disconnect(d->model, SIGNAL(modelUpdated(QQuickChangeSet,bool)), - this, SLOT(modelUpdated(QQuickChangeSet,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*))); + disconnect(d->model, SIGNAL(modelUpdated(QQmlChangeSet,bool)), + this, SLOT(modelUpdated(QQmlChangeSet,bool))); + disconnect(d->model, SIGNAL(initItem(int,QObject*)), this, SLOT(initItem(int,QObject*))); + disconnect(d->model, SIGNAL(createdItem(int,QObject*)), this, SLOT(createdItem(int,QObject*))); + disconnect(d->model, SIGNAL(destroyingItem(QObject*)), this, SLOT(destroyingItem(QObject*))); } - QQuickVisualModel *oldModel = d->model; + QQmlInstanceModel *oldModel = d->model; d->clear(); d->model = 0; @@ -281,8 +282,8 @@ void QQuickItemView::setModel(const QVariant &model) d->modelVariant = model; QObject *object = qvariant_cast<QObject*>(model); - QQuickVisualModel *vim = 0; - if (object && (vim = qobject_cast<QQuickVisualModel *>(object))) { + QQmlInstanceModel *vim = 0; + if (object && (vim = qobject_cast<QQmlInstanceModel *>(object))) { if (d->ownModel) { delete oldModel; d->ownModel = false; @@ -290,22 +291,22 @@ void QQuickItemView::setModel(const QVariant &model) d->model = vim; } else { if (!d->ownModel) { - d->model = new QQuickVisualDataModel(qmlContext(this), this); + d->model = new QQmlDelegateModel(qmlContext(this), this); d->ownModel = true; if (isComponentComplete()) - static_cast<QQuickVisualDataModel *>(d->model.data())->componentComplete(); + static_cast<QQmlDelegateModel *>(d->model.data())->componentComplete(); } else { d->model = oldModel; } - if (QQuickVisualDataModel *dataModel = qobject_cast<QQuickVisualDataModel*>(d->model)) + if (QQmlDelegateModel *dataModel = qobject_cast<QQmlDelegateModel*>(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*))); + connect(d->model, SIGNAL(createdItem(int,QObject*)), this, SLOT(createdItem(int,QObject*))); + connect(d->model, SIGNAL(initItem(int,QObject*)), this, SLOT(initItem(int,QObject*))); + connect(d->model, SIGNAL(destroyingItem(QObject*)), this, SLOT(destroyingItem(QObject*))); if (isComponentComplete()) { d->updateSectionCriteria(); d->refill(); @@ -319,8 +320,8 @@ void QQuickItemView::setModel(const QVariant &model) } } - connect(d->model, SIGNAL(modelUpdated(QQuickChangeSet,bool)), - this, SLOT(modelUpdated(QQuickChangeSet,bool))); + connect(d->model, SIGNAL(modelUpdated(QQmlChangeSet,bool)), + this, SLOT(modelUpdated(QQmlChangeSet,bool))); emit countChanged(); } emit modelChanged(); @@ -330,7 +331,7 @@ QQmlComponent *QQuickItemView::delegate() const { Q_D(const QQuickItemView); if (d->model) { - if (QQuickVisualDataModel *dataModel = qobject_cast<QQuickVisualDataModel*>(d->model)) + if (QQmlDelegateModel *dataModel = qobject_cast<QQmlDelegateModel*>(d->model)) return dataModel->delegate(); } @@ -343,10 +344,10 @@ void QQuickItemView::setDelegate(QQmlComponent *delegate) if (delegate == this->delegate()) return; if (!d->ownModel) { - d->model = new QQuickVisualDataModel(qmlContext(this)); + d->model = new QQmlDelegateModel(qmlContext(this)); d->ownModel = true; } - if (QQuickVisualDataModel *dataModel = qobject_cast<QQuickVisualDataModel*>(d->model)) { + if (QQmlDelegateModel *dataModel = qobject_cast<QQmlDelegateModel*>(d->model)) { int oldCount = dataModel->count(); dataModel->setDelegate(delegate); if (isComponentComplete()) { @@ -371,6 +372,7 @@ void QQuickItemView::setDelegate(QQmlComponent *delegate) emit countChanged(); } emit delegateChanged(); + d->delegateValidated = false; } @@ -972,7 +974,7 @@ void QQuickItemViewPrivate::applyPendingChanges() layout(); } -int QQuickItemViewPrivate::findMoveKeyIndex(QQuickChangeSet::MoveKey key, const QVector<QQuickChangeSet::Remove> &changes) const +int QQuickItemViewPrivate::findMoveKeyIndex(QQmlChangeSet::MoveKey key, const QVector<QQmlChangeSet::Remove> &changes) const { for (int i=0; i<changes.count(); i++) { for (int j=changes[i].index; j<changes[i].index + changes[i].count; j++) { @@ -1152,7 +1154,7 @@ void QQuickItemView::destroyRemoved() d->forceLayoutPolish(); } -void QQuickItemView::modelUpdated(const QQuickChangeSet &changeSet, bool reset) +void QQuickItemView::modelUpdated(const QQmlChangeSet &changeSet, bool reset) { Q_D(QQuickItemView); if (reset) { @@ -1388,7 +1390,7 @@ void QQuickItemView::componentComplete() { Q_D(QQuickItemView); if (d->model && d->ownModel) - static_cast<QQuickVisualDataModel *>(d->model.data())->componentComplete(); + static_cast<QQmlDelegateModel *>(d->model.data())->componentComplete(); QQuickFlickable::componentComplete(); @@ -1440,7 +1442,7 @@ QQuickItemViewPrivate::QQuickItemViewPrivate() , inLayout(false), inViewportMoved(false), forceLayout(false), currentIndexCleared(false) , haveHighlightRange(false), autoHighlight(true), highlightRangeStartValid(false), highlightRangeEndValid(false) , fillCacheBuffer(false), inRequest(false) - , runDelayedRemoveTransition(false) + , runDelayedRemoveTransition(false), delegateValidated(false) { bufferPause.addAnimationChangeListener(this, QAbstractAnimationJob::Completion); bufferPause.setLoopCount(1); @@ -1874,8 +1876,8 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult totalInsertionResult->visiblePos = prevViewPos; totalRemovalResult->visiblePos = prevViewPos; - const QVector<QQuickChangeSet::Remove> &removals = currentChanges.pendingChanges.removes(); - const QVector<QQuickChangeSet::Insert> &insertions = currentChanges.pendingChanges.inserts(); + const QVector<QQmlChangeSet::Remove> &removals = currentChanges.pendingChanges.removes(); + const QVector<QQmlChangeSet::Insert> &insertions = currentChanges.pendingChanges.inserts(); ChangeResult insertionResult(prevViewPos); ChangeResult removalResult(prevViewPos); @@ -1895,7 +1897,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult } } if (runDelayedRemoveTransition) { - QQuickChangeSet::Remove removal; + QQmlChangeSet::Remove removal; for (QList<FxViewItem*>::Iterator it = visibleItems.begin(); it != visibleItems.end();) { FxViewItem *item = *it; if (item->index == -1 && !item->attached->delayRemove()) { @@ -1963,7 +1965,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult // Whatever removed/moved items remain are no longer visible items. prepareRemoveTransitions(¤tChanges.removedItems); - for (QHash<QQuickChangeSet::MoveKey, FxViewItem *>::Iterator it = currentChanges.removedItems.begin(); + for (QHash<QQmlChangeSet::MoveKey, FxViewItem *>::Iterator it = currentChanges.removedItems.begin(); it != currentChanges.removedItems.end(); ++it) { releaseItem(it.value()); } @@ -1992,7 +1994,7 @@ bool QQuickItemViewPrivate::applyModelChanges(ChangeResult *totalInsertionResult return visibleAffected; } -bool QQuickItemViewPrivate::applyRemovalChange(const QQuickChangeSet::Remove &removal, ChangeResult *removeResult, int *removedCount) +bool QQuickItemViewPrivate::applyRemovalChange(const QQmlChangeSet::Remove &removal, ChangeResult *removeResult, int *removedCount) { Q_Q(QQuickItemView); bool visibleAffected = false; @@ -2042,7 +2044,7 @@ bool QQuickItemViewPrivate::applyRemovalChange(const QQuickChangeSet::Remove &re return visibleAffected; } -void QQuickItemViewPrivate::removeItem(FxViewItem *item, const QQuickChangeSet::Remove &removal, ChangeResult *removeResult) +void QQuickItemViewPrivate::removeItem(FxViewItem *item, const QQmlChangeSet::Remove &removal, ChangeResult *removeResult) { if (removeResult->visiblePos.isValid()) { if (item->position() < removeResult->visiblePos) @@ -2055,7 +2057,7 @@ void QQuickItemViewPrivate::removeItem(FxViewItem *item, const QQuickChangeSet:: item->transitionNextReposition(transitioner, QQuickItemViewTransitioner::MoveTransition, true); } else { // track item so it is released later - currentChanges.removedItems.insertMulti(QQuickChangeSet::MoveKey(), item); + currentChanges.removedItems.insertMulti(QQmlChangeSet::MoveKey(), item); } if (!removeResult->changedFirstItem && item == *visibleItems.constBegin()) removeResult->changedFirstItem = true; @@ -2120,14 +2122,14 @@ void QQuickItemViewPrivate::prepareVisibleItemTransitions() visibleItems[i]->prepareTransition(transitioner, viewBounds); } -void QQuickItemViewPrivate::prepareRemoveTransitions(QHash<QQuickChangeSet::MoveKey, FxViewItem *> *removedItems) +void QQuickItemViewPrivate::prepareRemoveTransitions(QHash<QQmlChangeSet::MoveKey, FxViewItem *> *removedItems) { if (!transitioner) return; if (transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, true) || transitioner->canTransition(QQuickItemViewTransitioner::RemoveTransition, false)) { - for (QHash<QQuickChangeSet::MoveKey, FxViewItem *>::Iterator it = removedItems->begin(); + for (QHash<QQmlChangeSet::MoveKey, FxViewItem *>::Iterator it = removedItems->begin(); it != removedItems->end(); ) { bool isRemove = it.key().moveId < 0; if (isRemove) { @@ -2197,7 +2199,20 @@ FxViewItem *QQuickItemViewPrivate::createItem(int modelIndex, bool asynchronous) requestedIndex = modelIndex; inRequest = true; - if (QQuickItem *item = model->item(modelIndex, asynchronous)) { + QObject* object = model->object(modelIndex, asynchronous); + QQuickItem *item = qmlobject_cast<QQuickItem*>(object); + if (!item) { + if (object) { + model->release(object); + if (!delegateValidated) { + delegateValidated = true; + QObject* delegate = q->delegate(); + qmlInfo(delegate ? delegate : q) << q->tr("Delegate must be of Item type"); + } + } + inRequest = false; + return 0; + } else { item->setParentItem(q->contentItem()); if (requestedIndex == modelIndex) requestedIndex = -1; @@ -2212,15 +2227,13 @@ FxViewItem *QQuickItemViewPrivate::createItem(int modelIndex, bool asynchronous) inRequest = false; return viewItem; } - - inRequest = false; - return 0; } -void QQuickItemView::createdItem(int index, QQuickItem *item) +void QQuickItemView::createdItem(int index, QObject* object) { Q_D(QQuickItemView); + QQuickItem* item = qmlobject_cast<QQuickItem*>(object); if (!d->inRequest) { d->unrequestedItems.insert(item, index); d->requestedIndex = -1; @@ -2235,16 +2248,21 @@ void QQuickItemView::createdItem(int index, QQuickItem *item) } } -void QQuickItemView::initItem(int, QQuickItem *item) +void QQuickItemView::initItem(int, QObject *object) { - item->setZ(1); - item->setParentItem(contentItem()); - QQuickItemPrivate::get(item)->setCulled(true); + QQuickItem* item = qmlobject_cast<QQuickItem*>(object); + if (item) { + item->setZ(1); + item->setParentItem(contentItem()); + QQuickItemPrivate::get(item)->setCulled(true); + } } -void QQuickItemView::destroyingItem(QQuickItem *item) +void QQuickItemView::destroyingItem(QObject *object) { Q_D(QQuickItemView); + QQuickItem* item = qmlobject_cast<QQuickItem*>(object); + item->setParentItem(0); d->unrequestedItems.remove(item); } @@ -2257,14 +2275,16 @@ bool QQuickItemViewPrivate::releaseItem(FxViewItem *item) trackedItem = 0; QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item->item); itemPrivate->removeItemChangeListener(this, QQuickItemPrivate::Geometry); - QQuickVisualModel::ReleaseFlags flags = model->release(item->item); + QQmlInstanceModel::ReleaseFlags flags = model->release(item->item); if (flags == 0) { // item was not destroyed, and we no longer reference it. QQuickItemPrivate::get(item->item)->setCulled(true); unrequestedItems.insert(item->item, model->indexOf(item->item, q)); + } else if (flags & QQmlInstanceModel::Destroyed) { + item->item->setParentItem(0); } delete item; - return flags != QQuickVisualModel::Referenced; + return flags != QQmlInstanceModel::Referenced; } QQuickItem *QQuickItemViewPrivate::createHighlightItem() diff --git a/src/quick/items/qquickitemview_p.h b/src/quick/items/qquickitemview_p.h index 82180a2e13..f94137100d 100644 --- a/src/quick/items/qquickitemview_p.h +++ b/src/quick/items/qquickitemview_p.h @@ -48,7 +48,7 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -class QQuickChangeSet; +class QQmlChangeSet; class QQuickItemViewPrivate; @@ -257,10 +257,10 @@ protected: protected slots: void destroyRemoved(); - void createdItem(int index, QQuickItem *item); - virtual void initItem(int index, QQuickItem *item); - void modelUpdated(const QQuickChangeSet &changeSet, bool reset); - void destroyingItem(QQuickItem *item); + void createdItem(int index, QObject *item); + virtual void initItem(int index, QObject *item); + void modelUpdated(const QQmlChangeSet &changeSet, bool reset); + void destroyingItem(QObject *item); void animStopped(); void trackedPositionChanged(); diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h index 0efc458c3d..af895fb983 100644 --- a/src/quick/items/qquickitemview_p_p.h +++ b/src/quick/items/qquickitemview_p_p.h @@ -45,9 +45,9 @@ #include "qquickitemview_p.h" #include "qquickitemviewtransition_p.h" #include "qquickflickable_p_p.h" -#include "qquickvisualdatamodel_p.h" -#include "qquickvisualitemmodel_p.h" -#include <private/qquickchangeset_p.h> +#include <QtQml/private/qqmlobjectmodel_p.h> +#include <QtQml/private/qqmldelegatemodel_p.h> +#include <QtQml/private/qqmlchangeset_p.h> QT_BEGIN_HEADER @@ -103,14 +103,14 @@ public: void prepare(int currentIndex, int count); void reset(); - void applyChanges(const QQuickChangeSet &changeSet); + void applyChanges(const QQmlChangeSet &changeSet); void applyBufferedChanges(const QQuickItemViewChangeSet &other); int itemCount; int newCurrentIndex; - QQuickChangeSet pendingChanges; - QHash<QQuickChangeSet::MoveKey, FxViewItem *> removedItems; + QQmlChangeSet pendingChanges; + QHash<QQmlChangeSet::MoveKey, FxViewItem *> removedItems; bool active : 1; bool currentChanged : 1; @@ -209,18 +209,18 @@ public: void applyPendingChanges(); bool applyModelChanges(ChangeResult *insertionResult, ChangeResult *removalResult); - bool applyRemovalChange(const QQuickChangeSet::Remove &removal, ChangeResult *changeResult, int *removedCount); - void removeItem(FxViewItem *item, const QQuickChangeSet::Remove &removal, ChangeResult *removeResult); + bool applyRemovalChange(const QQmlChangeSet::Remove &removal, ChangeResult *changeResult, int *removedCount); + void removeItem(FxViewItem *item, const QQmlChangeSet::Remove &removal, ChangeResult *removeResult); void repositionFirstItem(FxViewItem *prevVisibleItemsFirst, qreal prevVisibleItemsFirstPos, FxViewItem *prevFirstVisible, ChangeResult *insertionResult, ChangeResult *removalResult); void createTransitioner(); void prepareVisibleItemTransitions(); - void prepareRemoveTransitions(QHash<QQuickChangeSet::MoveKey, FxViewItem *> *removedItems); + void prepareRemoveTransitions(QHash<QQmlChangeSet::MoveKey, FxViewItem *> *removedItems); bool prepareNonVisibleItemTransition(FxViewItem *item, const QRectF &viewBounds); virtual void viewItemTransitionFinished(QQuickItemViewTransitionableItem *item); - int findMoveKeyIndex(QQuickChangeSet::MoveKey key, const QVector<QQuickChangeSet::Remove> &changes) const; + int findMoveKeyIndex(QQmlChangeSet::MoveKey key, const QVector<QQmlChangeSet::Remove> &changes) const; void checkVisible() const; void showVisibleItems() const; @@ -251,7 +251,7 @@ public: q->polish(); } - QQmlGuard<QQuickVisualModel> model; + QQmlGuard<QQmlInstanceModel> model; QVariant modelVariant; int itemCount; int buffer; @@ -286,8 +286,8 @@ public: struct MovedItem { FxViewItem *item; - QQuickChangeSet::MoveKey moveKey; - MovedItem(FxViewItem *i, QQuickChangeSet::MoveKey k) + QQmlChangeSet::MoveKey moveKey; + MovedItem(FxViewItem *i, QQmlChangeSet::MoveKey k) : item(i), moveKey(k) {} }; QQuickItemViewTransitioner *transitioner; @@ -309,6 +309,7 @@ public: bool fillCacheBuffer : 1; bool inRequest : 1; bool runDelayedRemoveTransition : 1; + bool delegateValidated : 1; protected: virtual Qt::Orientation layoutOrientation() const = 0; @@ -346,7 +347,7 @@ protected: virtual void layoutVisibleItems(int fromModelIndex = 0) = 0; virtual void changedVisibleIndex(int newIndex) = 0; - virtual bool applyInsertionChange(const QQuickChangeSet::Insert &insert, ChangeResult *changeResult, + virtual bool applyInsertionChange(const QQmlChangeSet::Insert &insert, ChangeResult *changeResult, QList<FxViewItem *> *newItems, QList<MovedItem> *movingIntoView) = 0; virtual bool needsRefillForAddedOrRemovedIndex(int) const { return false; } diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index 57f1b99456..297f64176c 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -41,8 +41,8 @@ #include "qquicklistview_p.h" #include "qquickitemview_p_p.h" -#include "qquickvisualitemmodel_p.h" +#include <private/qqmlobjectmodel_p.h> #include <QtQml/qqmlexpression.h> #include <QtQml/qqmlengine.h> #include <QtQml/qqmlinfo.h> @@ -106,7 +106,7 @@ public: virtual void setPosition(qreal pos); virtual void layoutVisibleItems(int fromModelIndex = 0); - virtual bool applyInsertionChange(const QQuickChangeSet::Insert &insert, ChangeResult *changeResult, QList<FxViewItem *> *addedItems, QList<MovedItem> *movingIntoView); + virtual bool applyInsertionChange(const QQmlChangeSet::Insert &insert, ChangeResult *changeResult, QList<FxViewItem *> *addedItems, QList<MovedItem> *movingIntoView); virtual void translateAndTransitionItemsAfter(int afterIndex, const ChangeResult &insertionResult, const ChangeResult &removalResult); virtual void updateSectionCriteria(); @@ -2803,13 +2803,16 @@ void QQuickListView::geometryChanged(const QRectF &newGeometry, const QRectF &ol QQuickItemView::geometryChanged(newGeometry, oldGeometry); } -void QQuickListView::initItem(int index, QQuickItem *item) +void QQuickListView::initItem(int index, QObject *object) { - QQuickItemView::initItem(index, item); - QQuickListViewAttached *attached = static_cast<QQuickListViewAttached *>( - qmlAttachedPropertiesObject<QQuickListView>(item)); - if (attached) - attached->setView(this); + QQuickItemView::initItem(index, object); + QQuickItem *item = qmlobject_cast<QQuickItem*>(object); + if (item) { + QQuickListViewAttached *attached = static_cast<QQuickListViewAttached *>( + qmlAttachedPropertiesObject<QQuickListView>(item)); + if (attached) + attached->setView(this); + } } @@ -2867,7 +2870,7 @@ void QQuickListViewPrivate::updateSectionCriteria() } } -bool QQuickListViewPrivate::applyInsertionChange(const QQuickChangeSet::Insert &change, ChangeResult *insertResult, QList<FxViewItem *> *addedItems, QList<MovedItem> *movingIntoView) +bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Insert &change, ChangeResult *insertResult, QList<FxViewItem *> *addedItems, QList<MovedItem> *movingIntoView) { int modelIndex = change.index; int count = change.count; diff --git a/src/quick/items/qquicklistview_p.h b/src/quick/items/qquicklistview_p.h index f6c405e86b..e0ad1ffc1b 100644 --- a/src/quick/items/qquicklistview_p.h +++ b/src/quick/items/qquicklistview_p.h @@ -96,7 +96,7 @@ private: }; -class QQuickVisualModel; +class QQmlInstanceModel; class QQuickListViewAttached; class Q_AUTOTEST_EXPORT QQuickListView : public QQuickItemView { @@ -169,7 +169,7 @@ protected: virtual void viewportMoved(Qt::Orientations orient); virtual void keyPressEvent(QKeyEvent *); virtual void geometryChanged(const QRectF &newGeometry,const QRectF &oldGeometry); - virtual void initItem(int index, QQuickItem *item); + virtual void initItem(int index, QObject *item); }; class QQuickListViewAttached : public QQuickItemViewAttached diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index a7be50bc11..e9aa6985fc 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -46,8 +46,9 @@ #include <QtQuick/private/qquickstate_p.h> #include <private/qqmlglobal_p.h> #include <private/qqmlopenmetaobject_p.h> -#include <private/qquickchangeset_p.h> +#include <private/qqmlchangeset_p.h> +#include <QtQml/qqmlinfo.h> #include <QtGui/qevent.h> #include <QtGui/qevent.h> #include <QtGui/qguiapplication.h> @@ -117,7 +118,7 @@ QQuickPathViewPrivate::QQuickPathViewPrivate() , offset(0.0), offsetAdj(0.0), mappedRange(1.0), mappedCache(0.0) , stealMouse(false), ownModel(false), interactive(true), haveHighlightRange(true) , autoHighlight(true), highlightUp(false), layoutScheduled(false) - , moving(false), flicking(false), dragging(false), inRequest(false) + , moving(false), flicking(false), dragging(false), inRequest(false), delegateValidated(false) , dragMargin(0), deceleration(100), maximumFlickVelocity(QML_FLICK_DEFAULTMAXVELOCITY) , moveOffset(this, &QQuickPathViewPrivate::setAdjustedOffset), flickDuration(0) , firstIndex(-1), pathItems(-1), requestedIndex(-1), cacheSize(0), requestedZ(0) @@ -150,8 +151,18 @@ QQuickItem *QQuickPathViewPrivate::getItem(int modelIndex, qreal z, bool async) requestedIndex = modelIndex; requestedZ = z; inRequest = true; - QQuickItem *item = model->item(modelIndex, async); - if (item) { + QObject *object = model->object(modelIndex, async); + QQuickItem *item = qmlobject_cast<QQuickItem*>(object); + if (!item) { + if (object) { + model->release(object); + if (!delegateValidated) { + delegateValidated = true; + QObject* delegate = q->delegate(); + qmlInfo(delegate ? delegate : q) << q->tr("Delegate must be of Item type"); + } + } + } else { item->setParentItem(q); requestedIndex = -1; QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); @@ -161,9 +172,10 @@ QQuickItem *QQuickPathViewPrivate::getItem(int modelIndex, qreal z, bool async) return item; } -void QQuickPathView::createdItem(int index, QQuickItem *item) +void QQuickPathView::createdItem(int index, QObject *object) { Q_D(QQuickPathView); + QQuickItem *item = qmlobject_cast<QQuickItem*>(object); if (d->requestedIndex != index) { qPathViewAttachedType = d->attachedType(); QQuickPathViewAttached *att = static_cast<QQuickPathViewAttached *>(qmlAttachedPropertiesObject<QQuickPathView>(item)); @@ -181,10 +193,11 @@ void QQuickPathView::createdItem(int index, QQuickItem *item) } } -void QQuickPathView::initItem(int index, QQuickItem *item) +void QQuickPathView::initItem(int index, QObject *object) { Q_D(QQuickPathView); - if (d->requestedIndex == index) { + QQuickItem *item = qmlobject_cast<QQuickItem*>(object); + if (item && d->requestedIndex == index) { QQuickItemPrivate::get(item)->setCulled(true); item->setParentItem(this); qPathViewAttachedType = d->attachedType(); @@ -209,10 +222,14 @@ void QQuickPathViewPrivate::releaseItem(QQuickItem *item) return; QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); itemPrivate->removeItemChangeListener(this, QQuickItemPrivate::Geometry); - if (model->release(item) == 0) { + QQmlInstanceModel::ReleaseFlags flags = model->release(item); + if (!flags) { // item was not destroyed, and we no longer reference it. if (QQuickPathViewAttached *att = attached(item)) att->setOnPath(false); + } else if (flags & QQmlInstanceModel::Destroyed) { + // but we still reference it + item->setParentItem(0); } } @@ -619,19 +636,19 @@ void QQuickPathView::setModel(const QVariant &model) return; if (d->model) { - qmlobject_disconnect(d->model, QQuickVisualModel, SIGNAL(modelUpdated(QQuickChangeSet,bool)), - this, QQuickPathView, SLOT(modelUpdated(QQuickChangeSet,bool))); - qmlobject_disconnect(d->model, QQuickVisualModel, SIGNAL(createdItem(int,QQuickItem*)), - this, QQuickPathView, SLOT(createdItem(int,QQuickItem*))); - qmlobject_disconnect(d->model, QQuickVisualModel, SIGNAL(initItem(int,QQuickItem*)), - this, QQuickPathView, SLOT(initItem(int,QQuickItem*))); + qmlobject_disconnect(d->model, QQmlInstanceModel, SIGNAL(modelUpdated(QQmlChangeSet,bool)), + this, QQuickPathView, SLOT(modelUpdated(QQmlChangeSet,bool))); + qmlobject_disconnect(d->model, QQmlInstanceModel, SIGNAL(createdItem(int,QObject*)), + this, QQuickPathView, SLOT(createdItem(int,QObject*))); + qmlobject_disconnect(d->model, QQmlInstanceModel, SIGNAL(initItem(int,QObject*)), + this, QQuickPathView, SLOT(initItem(int,QObject*))); d->clear(); } d->modelVariant = model; QObject *object = qvariant_cast<QObject*>(model); - QQuickVisualModel *vim = 0; - if (object && (vim = qobject_cast<QQuickVisualModel *>(object))) { + QQmlInstanceModel *vim = 0; + if (object && (vim = qobject_cast<QQmlInstanceModel *>(object))) { if (d->ownModel) { delete d->model; d->ownModel = false; @@ -639,23 +656,23 @@ void QQuickPathView::setModel(const QVariant &model) d->model = vim; } else { if (!d->ownModel) { - d->model = new QQuickVisualDataModel(qmlContext(this)); + d->model = new QQmlDelegateModel(qmlContext(this)); d->ownModel = true; if (isComponentComplete()) - static_cast<QQuickVisualDataModel *>(d->model.data())->componentComplete(); + static_cast<QQmlDelegateModel *>(d->model.data())->componentComplete(); } - if (QQuickVisualDataModel *dataModel = qobject_cast<QQuickVisualDataModel*>(d->model)) + if (QQmlDelegateModel *dataModel = qobject_cast<QQmlDelegateModel*>(d->model)) dataModel->setModel(model); } int oldModelCount = d->modelCount; d->modelCount = 0; if (d->model) { - qmlobject_connect(d->model, QQuickVisualModel, SIGNAL(modelUpdated(QQuickChangeSet,bool)), - this, QQuickPathView, SLOT(modelUpdated(QQuickChangeSet,bool))); - qmlobject_connect(d->model, QQuickVisualModel, SIGNAL(createdItem(int,QQuickItem*)), - this, QQuickPathView, SLOT(createdItem(int,QQuickItem*))); - qmlobject_connect(d->model, QQuickVisualModel, SIGNAL(initItem(int,QQuickItem*)), - this, QQuickPathView, SLOT(initItem(int,QQuickItem*))); + qmlobject_connect(d->model, QQmlInstanceModel, SIGNAL(modelUpdated(QQmlChangeSet,bool)), + this, QQuickPathView, SLOT(modelUpdated(QQmlChangeSet,bool))); + qmlobject_connect(d->model, QQmlInstanceModel, SIGNAL(createdItem(int,QObject*)), + this, QQuickPathView, SLOT(createdItem(int,QObject*))); + qmlobject_connect(d->model, QQmlInstanceModel, SIGNAL(initItem(int,QObject*)), + this, QQuickPathView, SLOT(initItem(int,QObject*))); d->modelCount = d->model->count(); } if (isComponentComplete()) { @@ -1210,7 +1227,7 @@ QQmlComponent *QQuickPathView::delegate() const { Q_D(const QQuickPathView); if (d->model) { - if (QQuickVisualDataModel *dataModel = qobject_cast<QQuickVisualDataModel*>(d->model)) + if (QQmlDelegateModel *dataModel = qobject_cast<QQmlDelegateModel*>(d->model)) return dataModel->delegate(); } @@ -1223,10 +1240,10 @@ void QQuickPathView::setDelegate(QQmlComponent *delegate) if (delegate == this->delegate()) return; if (!d->ownModel) { - d->model = new QQuickVisualDataModel(qmlContext(this)); + d->model = new QQmlDelegateModel(qmlContext(this)); d->ownModel = true; } - if (QQuickVisualDataModel *dataModel = qobject_cast<QQuickVisualDataModel*>(d->model)) { + if (QQmlDelegateModel *dataModel = qobject_cast<QQmlDelegateModel*>(d->model)) { int oldCount = dataModel->count(); dataModel->setDelegate(delegate); d->modelCount = dataModel->count(); @@ -1234,6 +1251,7 @@ void QQuickPathView::setDelegate(QQmlComponent *delegate) if (oldCount != dataModel->count()) emit countChanged(); emit delegateChanged(); + d->delegateValidated = false; } } @@ -1821,7 +1839,7 @@ void QQuickPathView::componentComplete() { Q_D(QQuickPathView); if (d->model && d->ownModel) - static_cast<QQuickVisualDataModel *>(d->model.data())->componentComplete(); + static_cast<QQmlDelegateModel *>(d->model.data())->componentComplete(); QQuickItem::componentComplete(); @@ -1983,7 +2001,7 @@ void QQuickPathView::refill() d->releaseItem(d->itemCache.takeLast()); } -void QQuickPathView::modelUpdated(const QQuickChangeSet &changeSet, bool reset) +void QQuickPathView::modelUpdated(const QQmlChangeSet &changeSet, bool reset) { Q_D(QQuickPathView); if (!d->model || !d->model->isValid() || !d->path || !isComponentComplete()) @@ -2004,7 +2022,7 @@ void QQuickPathView::modelUpdated(const QQuickChangeSet &changeSet, bool reset) int moveOffset; bool currentChanged = false; bool changedOffset = false; - foreach (const QQuickChangeSet::Remove &r, changeSet.removes()) { + foreach (const QQmlChangeSet::Remove &r, changeSet.removes()) { if (moveId == -1 && d->currentIndex >= r.index + r.count) { d->currentIndex -= r.count; currentChanged = true; @@ -2030,7 +2048,7 @@ void QQuickPathView::modelUpdated(const QQuickChangeSet &changeSet, bool reset) } d->modelCount -= r.count; } - foreach (const QQuickChangeSet::Insert &i, changeSet.inserts()) { + foreach (const QQmlChangeSet::Insert &i, changeSet.inserts()) { if (d->modelCount) { if (moveId == -1 && i.index <= d->currentIndex) { d->currentIndex += i.count; @@ -2082,7 +2100,7 @@ void QQuickPathView::modelUpdated(const QQuickChangeSet &changeSet, bool reset) emit countChanged(); } -void QQuickPathView::destroyingItem(QQuickItem *item) +void QQuickPathView::destroyingItem(QObject *item) { Q_UNUSED(item); } diff --git a/src/quick/items/qquickpathview_p.h b/src/quick/items/qquickpathview_p.h index 9cb6b881a0..1ee23edf5b 100644 --- a/src/quick/items/qquickpathview_p.h +++ b/src/quick/items/qquickpathview_p.h @@ -50,7 +50,7 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -class QQuickChangeSet; +class QQmlChangeSet; class QQuickPathViewPrivate; class QQuickPathViewAttached; @@ -216,10 +216,10 @@ private Q_SLOTS: void refill(); void ticked(); void movementEnding(); - void modelUpdated(const QQuickChangeSet &changeSet, bool reset); - void createdItem(int index, QQuickItem *item); - void initItem(int index, QQuickItem *item); - void destroyingItem(QQuickItem *item); + void modelUpdated(const QQmlChangeSet &changeSet, bool reset); + void createdItem(int index, QObject *item); + void initItem(int index, QObject *item); + void destroyingItem(QObject *item); void pathUpdated(); private: diff --git a/src/quick/items/qquickpathview_p_p.h b/src/quick/items/qquickpathview_p_p.h index 9f504db22f..26533057d1 100644 --- a/src/quick/items/qquickpathview_p_p.h +++ b/src/quick/items/qquickpathview_p_p.h @@ -55,7 +55,6 @@ #include "qquickpathview_p.h" #include "qquickitem_p.h" -#include "qquickvisualdatamodel_p.h" #include <QtQml/qqml.h> #include <QtCore/qdatetime.h> @@ -63,6 +62,7 @@ #include <private/qquickanimation_p_p.h> #include <private/qqmlguard_p.h> +#include <private/qqmldelegatemodel_p.h> #include <private/qquicktimeline_p_p.h> QT_BEGIN_NAMESPACE @@ -152,6 +152,7 @@ public: bool dragging : 1; bool requestedOnPath : 1; bool inRequest : 1; + bool delegateValidated : 1; QElapsedTimer timer; qint64 lastPosTime; QPointF lastPos; @@ -168,7 +169,7 @@ public: qreal requestedZ; QList<QQuickItem *> items; QList<QQuickItem *> itemCache; - QQmlGuard<QQuickVisualModel> model; + QQmlGuard<QQmlInstanceModel> model; QVariant modelVariant; enum MovementReason { Other, SetIndex, Mouse }; MovementReason moveReason; diff --git a/src/quick/items/qquickrepeater.cpp b/src/quick/items/qquickrepeater.cpp index 68f70a5227..c986e469cf 100644 --- a/src/quick/items/qquickrepeater.cpp +++ b/src/quick/items/qquickrepeater.cpp @@ -41,16 +41,18 @@ #include "qquickrepeater_p.h" #include "qquickrepeater_p_p.h" -#include "qquickvisualdatamodel_p.h" #include <private/qqmlglobal_p.h> -#include <private/qquicklistaccessor_p.h> -#include <private/qquickchangeset_p.h> +#include <private/qqmllistaccessor_p.h> +#include <private/qqmlchangeset_p.h> +#include <private/qqmldelegatemodel_p.h> + +#include <QtQml/QQmlInfo> QT_BEGIN_NAMESPACE QQuickRepeaterPrivate::QQuickRepeaterPrivate() - : model(0), ownModel(false), inRequest(false), dataSourceIsObject(false), itemCount(0), createFrom(-1) + : model(0), ownModel(false), inRequest(false), dataSourceIsObject(false), delegateValidated(false), itemCount(0), createFrom(-1) { } @@ -192,18 +194,18 @@ void QQuickRepeater::setModel(const QVariant &model) clear(); if (d->model) { - disconnect(d->model, SIGNAL(modelUpdated(QQuickChangeSet,bool)), - this, SLOT(modelUpdated(QQuickChangeSet,bool))); - disconnect(d->model, SIGNAL(createdItem(int,QQuickItem*)), this, SLOT(createdItem(int,QQuickItem*))); - disconnect(d->model, SIGNAL(initItem(int,QQuickItem*)), this, SLOT(initItem(int,QQuickItem*))); -// disconnect(d->model, SIGNAL(destroyingItem(QQuickItem*)), this, SLOT(destroyingItem(QQuickItem*))); + disconnect(d->model, SIGNAL(modelUpdated(QQmlChangeSet,bool)), + this, SLOT(modelUpdated(QQmlChangeSet,bool))); + disconnect(d->model, SIGNAL(createdItem(int,QObject*)), this, SLOT(createdItem(int,QObject*))); + disconnect(d->model, SIGNAL(initItem(int,QObject*)), this, SLOT(initItem(int,QObject*))); +// disconnect(d->model, SIGNAL(destroyingItem(QObject*)), this, SLOT(destroyingItem(QObject*))); } d->dataSource = model; QObject *object = qvariant_cast<QObject*>(model); d->dataSourceAsObject = object; d->dataSourceIsObject = object != 0; - QQuickVisualModel *vim = 0; - if (object && (vim = qobject_cast<QQuickVisualModel *>(object))) { + QQmlInstanceModel *vim = 0; + if (object && (vim = qobject_cast<QQmlInstanceModel *>(object))) { if (d->ownModel) { delete d->model; d->ownModel = false; @@ -211,20 +213,20 @@ void QQuickRepeater::setModel(const QVariant &model) d->model = vim; } else { if (!d->ownModel) { - d->model = new QQuickVisualDataModel(qmlContext(this)); + d->model = new QQmlDelegateModel(qmlContext(this)); d->ownModel = true; if (isComponentComplete()) - static_cast<QQuickVisualDataModel *>(d->model)->componentComplete(); + static_cast<QQmlDelegateModel *>(d->model)->componentComplete(); } - if (QQuickVisualDataModel *dataModel = qobject_cast<QQuickVisualDataModel*>(d->model)) + if (QQmlDelegateModel *dataModel = qobject_cast<QQmlDelegateModel*>(d->model)) dataModel->setModel(model); } if (d->model) { - connect(d->model, SIGNAL(modelUpdated(QQuickChangeSet,bool)), - this, SLOT(modelUpdated(QQuickChangeSet,bool))); - 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*))); + connect(d->model, SIGNAL(modelUpdated(QQmlChangeSet,bool)), + this, SLOT(modelUpdated(QQmlChangeSet,bool))); + connect(d->model, SIGNAL(createdItem(int,QObject*)), this, SLOT(createdItem(int,QObject*))); + connect(d->model, SIGNAL(initItem(int,QObject*)), this, SLOT(initItem(int,QObject*))); +// connect(d->model, SIGNAL(destroyingItem(QObject*)), this, SLOT(destroyingItem(QObject*))); regenerate(); } emit modelChanged(); @@ -268,7 +270,7 @@ QQmlComponent *QQuickRepeater::delegate() const { Q_D(const QQuickRepeater); if (d->model) { - if (QQuickVisualDataModel *dataModel = qobject_cast<QQuickVisualDataModel*>(d->model)) + if (QQmlDelegateModel *dataModel = qobject_cast<QQmlDelegateModel*>(d->model)) return dataModel->delegate(); } @@ -278,18 +280,20 @@ QQmlComponent *QQuickRepeater::delegate() const void QQuickRepeater::setDelegate(QQmlComponent *delegate) { Q_D(QQuickRepeater); - if (QQuickVisualDataModel *dataModel = qobject_cast<QQuickVisualDataModel*>(d->model)) + if (QQmlDelegateModel *dataModel = qobject_cast<QQmlDelegateModel*>(d->model)) if (delegate == dataModel->delegate()) return; if (!d->ownModel) { - d->model = new QQuickVisualDataModel(qmlContext(this)); + d->model = new QQmlDelegateModel(qmlContext(this)); d->ownModel = true; } - if (QQuickVisualDataModel *dataModel = qobject_cast<QQuickVisualDataModel*>(d->model)) { + + if (QQmlDelegateModel *dataModel = qobject_cast<QQmlDelegateModel*>(d->model)) { dataModel->setDelegate(delegate); regenerate(); emit delegateChanged(); + d->delegateValidated = false; } } @@ -324,7 +328,7 @@ void QQuickRepeater::componentComplete() { Q_D(QQuickRepeater); if (d->model && d->ownModel) - static_cast<QQuickVisualDataModel *>(d->model)->componentComplete(); + static_cast<QQmlDelegateModel *>(d->model)->componentComplete(); QQuickItem::componentComplete(); regenerate(); if (d->model && d->model->count()) @@ -349,6 +353,7 @@ void QQuickRepeater::clear() QQuickItem *item = d->deletables.at(i); if (complete) emit itemRemoved(i, item); + item->setParentItem(0); d->model->release(item); } } @@ -381,8 +386,17 @@ void QQuickRepeaterPrivate::createItems() inRequest = true; for (int ii = createFrom; ii < itemCount; ++ii) { if (!deletables.at(ii)) { - QQuickItem *item = model->item(ii, false); + QObject *object = model->object(ii, false); + QQuickItem *item = qmlobject_cast<QQuickItem*>(object); if (!item) { + if (object) { + model->release(object); + if (!delegateValidated) { + delegateValidated = true; + QObject* delegate = q->delegate(); + qmlInfo(delegate ? delegate : q) << q->tr("Delegate must be of Item type"); + } + } createFrom = ii; break; } @@ -406,19 +420,21 @@ void QQuickRepeaterPrivate::createItems() inRequest = false; } -void QQuickRepeater::createdItem(int, QQuickItem *) +void QQuickRepeater::createdItem(int, QObject *) { Q_D(QQuickRepeater); if (!d->inRequest) d->createItems(); } -void QQuickRepeater::initItem(int, QQuickItem *item) +void QQuickRepeater::initItem(int, QObject *object) { - item->setParentItem(parentItem()); + QQuickItem *item = qmlobject_cast<QQuickItem*>(object); + if (item) + item->setParentItem(parentItem()); } -void QQuickRepeater::modelUpdated(const QQuickChangeSet &changeSet, bool reset) +void QQuickRepeater::modelUpdated(const QQmlChangeSet &changeSet, bool reset) { Q_D(QQuickRepeater); @@ -434,7 +450,7 @@ void QQuickRepeater::modelUpdated(const QQuickChangeSet &changeSet, bool reset) int difference = 0; QHash<int, QVector<QPointer<QQuickItem> > > moved; - foreach (const QQuickChangeSet::Remove &remove, changeSet.removes()) { + foreach (const QQmlChangeSet::Remove &remove, changeSet.removes()) { int index = qMin(remove.index, d->deletables.count()); int count = qMin(remove.index + remove.count, d->deletables.count()) - index; if (remove.isMove()) { @@ -446,8 +462,10 @@ void QQuickRepeater::modelUpdated(const QQuickChangeSet &changeSet, bool reset) QQuickItem *item = d->deletables.at(index); d->deletables.remove(index); emit itemRemoved(index, item); - if (item) + if (item) { + item->setParentItem(0); d->model->release(item); + } --d->itemCount; } @@ -455,7 +473,7 @@ void QQuickRepeater::modelUpdated(const QQuickChangeSet &changeSet, bool reset) } d->createFrom = -1; - foreach (const QQuickChangeSet::Insert &insert, changeSet.inserts()) { + foreach (const QQmlChangeSet::Insert &insert, changeSet.inserts()) { int index = qMin(insert.index, d->deletables.count()); if (insert.isMove()) { QVector<QPointer<QQuickItem> > items = moved.value(insert.moveId); diff --git a/src/quick/items/qquickrepeater_p.h b/src/quick/items/qquickrepeater_p.h index 17153694c9..8698b8224f 100644 --- a/src/quick/items/qquickrepeater_p.h +++ b/src/quick/items/qquickrepeater_p.h @@ -48,7 +48,7 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -class QQuickChangeSet; +class QQmlChangeSet; class QQuickRepeaterPrivate; class Q_AUTOTEST_EXPORT QQuickRepeater : public QQuickItem @@ -91,9 +91,9 @@ protected: void itemChange(ItemChange change, const ItemChangeData &value); private Q_SLOTS: - void createdItem(int index, QQuickItem *item); - void initItem(int, QQuickItem *item); - void modelUpdated(const QQuickChangeSet &changeSet, bool reset); + void createdItem(int index, QObject *item); + void initItem(int, QObject *item); + void modelUpdated(const QQmlChangeSet &changeSet, bool reset); private: Q_DISABLE_COPY(QQuickRepeater) diff --git a/src/quick/items/qquickrepeater_p_p.h b/src/quick/items/qquickrepeater_p_p.h index a187aea39c..f220eb4fcb 100644 --- a/src/quick/items/qquickrepeater_p_p.h +++ b/src/quick/items/qquickrepeater_p_p.h @@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE class QQmlContext; -class QQuickVisualModel; +class QQmlInstanceModel; class QQuickRepeaterPrivate : public QQuickItemPrivate { Q_DECLARE_PUBLIC(QQuickRepeater) @@ -73,12 +73,13 @@ public: private: void createItems(); - QQuickVisualModel *model; + QQmlInstanceModel *model; QVariant dataSource; QQmlGuard<QObject> dataSourceAsObject; bool ownModel : 1; bool inRequest : 1; bool dataSourceIsObject : 1; + bool delegateValidated : 1; int itemCount; int createFrom; diff --git a/src/quick/items/qquickvisualadaptormodel.cpp b/src/quick/items/qquickvisualadaptormodel.cpp deleted file mode 100644 index b57f4bbe76..0000000000 --- a/src/quick/items/qquickvisualadaptormodel.cpp +++ /dev/null @@ -1,977 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickvisualadaptormodel_p.h" -#include "qquickvisualdatamodel_p_p.h" - -#include <private/qmetaobjectbuilder_p.h> -#include <private/qqmlproperty_p.h> -#include <private/qv8engine_p.h> - -QT_BEGIN_NAMESPACE - -class QQuickVisualAdaptorModelEngineData : public QV8Engine::Deletable -{ -public: - enum - { - Index, - ModelData, - HasModelChildren, - StringCount - }; - - QQuickVisualAdaptorModelEngineData(QV8Engine *engine); - ~QQuickVisualAdaptorModelEngineData(); - - v8::Local<v8::String> index() { return strings->Get(Index)->ToString(); } - v8::Local<v8::String> modelData() { return strings->Get(ModelData)->ToString(); } - v8::Local<v8::String> hasModelChildren() { return strings->Get(HasModelChildren)->ToString(); } - - v8::Persistent<v8::Function> constructorListItem; - v8::Persistent<v8::Array> strings; -}; - -V8_DEFINE_EXTENSION(QQuickVisualAdaptorModelEngineData, engineData) - -static v8::Handle<v8::Value> get_index(v8::Local<v8::String>, const v8::AccessorInfo &info) -{ - QQuickVisualDataModelItem *data = v8_resource_cast<QQuickVisualDataModelItem>(info.This()); - V8ASSERT_TYPE(data, "Not a valid VisualData object"); - - return v8::Int32::New(data->index); -} - -template <typename T, typename M> static void setModelDataType(QMetaObjectBuilder *builder, M *metaType) -{ - builder->setFlags(QMetaObjectBuilder::DynamicMetaObject); - builder->setClassName(T::staticMetaObject.className()); - builder->setSuperClass(&T::staticMetaObject); - metaType->propertyOffset = T::staticMetaObject.propertyCount(); - metaType->signalOffset = T::staticMetaObject.methodCount(); -} - -static void addProperty(QMetaObjectBuilder *builder, int propertyId, const QByteArray &propertyName, const QByteArray &propertyType) -{ - builder->addSignal("__" + QByteArray::number(propertyId) + "()"); - QMetaPropertyBuilder property = builder->addProperty( - propertyName, propertyType, propertyId); - property.setWritable(true); -} - -class VDMModelDelegateDataType; - -class QQuickVDMCachedModelData : public QQuickVisualDataModelItem -{ -public: - QQuickVDMCachedModelData( - QQuickVisualDataModelItemMetaType *metaType, - VDMModelDelegateDataType *dataType, - int index); - - int metaCall(QMetaObject::Call call, int id, void **arguments); - - virtual QVariant value(int role) const = 0; - virtual void setValue(int role, const QVariant &value) = 0; - - void setValue(const QString &role, const QVariant &value); - bool resolveIndex(const QQuickVisualAdaptorModel &model, int idx); - - static v8::Handle<v8::Value> get_property(v8::Local<v8::String>, const v8::AccessorInfo &info); - static void set_property( - v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info); - - VDMModelDelegateDataType *type; - QVector<QVariant> cachedData; -}; - -class VDMModelDelegateDataType - : public QQmlRefCount - , public QQuickVisualAdaptorModel::Accessors - , public QAbstractDynamicMetaObject -{ -public: - VDMModelDelegateDataType(QQuickVisualAdaptorModel *model) - : model(model) - , metaObject(0) - , propertyCache(0) - , propertyOffset(0) - , signalOffset(0) - , hasModelData(false) - { - } - - ~VDMModelDelegateDataType() - { - if (propertyCache) - propertyCache->release(); - free(metaObject); - - qPersistentDispose(constructor); - } - - bool notify( - const QQuickVisualAdaptorModel &, - const QList<QQuickVisualDataModelItem *> &items, - int index, - int count, - const QVector<int> &roles) const - { - bool changed = roles.isEmpty() && !watchedRoles.isEmpty(); - if (!changed && !watchedRoles.isEmpty() && watchedRoleIds.isEmpty()) { - QList<int> roleIds; - foreach (const QByteArray &r, watchedRoles) { - QHash<QByteArray, int>::const_iterator it = roleNames.find(r); - if (it != roleNames.end()) - roleIds << it.value(); - } - const_cast<VDMModelDelegateDataType *>(this)->watchedRoleIds = roleIds; - } - - QVector<int> signalIndexes; - for (int i = 0; i < roles.count(); ++i) { - const int role = roles.at(i); - if (!changed && watchedRoleIds.contains(role)) - changed = true; - - int propertyId = propertyRoles.indexOf(role); - if (propertyId != -1) - signalIndexes.append(propertyId + signalOffset); - } - if (roles.isEmpty()) { - for (int propertyId = 0; propertyId < propertyRoles.count(); ++propertyId) - signalIndexes.append(propertyId + signalOffset); - } - - for (int i = 0, c = items.count(); i < c; ++i) { - QQuickVisualDataModelItem *item = items.at(i); - const int idx = item->modelIndex(); - if (idx >= index && idx < index + count) { - for (int i = 0; i < signalIndexes.count(); ++i) - QMetaObject::activate(item, signalIndexes.at(i), 0); - } - } - return changed; - } - - void replaceWatchedRoles( - QQuickVisualAdaptorModel &, - const QList<QByteArray> &oldRoles, - const QList<QByteArray> &newRoles) const - { - VDMModelDelegateDataType *dataType = const_cast<VDMModelDelegateDataType *>(this); - - dataType->watchedRoleIds.clear(); - foreach (const QByteArray &oldRole, oldRoles) - dataType->watchedRoles.removeOne(oldRole); - dataType->watchedRoles += newRoles; - } - - void initializeConstructor(QQuickVisualAdaptorModelEngineData *const data) - { - constructor = qPersistentNew(v8::ObjectTemplate::New()); - constructor->SetHasExternalResource(true); - constructor->SetAccessor(data->index(), get_index); - - typedef QHash<QByteArray, int>::const_iterator iterator; - for (iterator it = roleNames.constBegin(), end = roleNames.constEnd(); it != end; ++it) { - const int propertyId = propertyRoles.indexOf(it.value()); - const QByteArray &propertyName = it.key(); - - constructor->SetAccessor( - v8::String::New(propertyName.constData(), propertyName.length()), - QQuickVDMCachedModelData::get_property, - QQuickVDMCachedModelData::set_property, - v8::Int32::New(propertyId)); - } - } - - // QAbstractDynamicMetaObject - - void objectDestroyed(QObject *) - { - release(); - } - - int metaCall(QObject *object, QMetaObject::Call call, int id, void **arguments) - { - return static_cast<QQuickVDMCachedModelData *>(object)->metaCall(call, id, arguments); - } - - v8::Persistent<v8::ObjectTemplate> constructor; - QList<int> propertyRoles; - QList<int> watchedRoleIds; - QList<QByteArray> watchedRoles; - QHash<QByteArray, int> roleNames; - QQuickVisualAdaptorModel *model; - QMetaObject *metaObject; - QQmlPropertyCache *propertyCache; - int propertyOffset; - int signalOffset; - bool hasModelData; -}; - -QQuickVDMCachedModelData::QQuickVDMCachedModelData( - QQuickVisualDataModelItemMetaType *metaType, VDMModelDelegateDataType *dataType, int index) - : QQuickVisualDataModelItem(metaType, index) - , type(dataType) -{ - if (index == -1) - cachedData.resize(type->hasModelData ? 1 : type->propertyRoles.count()); - - QObjectPrivate::get(this)->metaObject = type; - - type->addref(); - - QQmlData *qmldata = QQmlData::get(this, true); - qmldata->propertyCache = dataType->propertyCache; - qmldata->propertyCache->addref(); -} - -int QQuickVDMCachedModelData::metaCall(QMetaObject::Call call, int id, void **arguments) -{ - if (call == QMetaObject::ReadProperty && id >= type->propertyOffset) { - const int propertyIndex = id - type->propertyOffset; - if (index == -1) { - if (!cachedData.isEmpty()) { - *static_cast<QVariant *>(arguments[0]) = cachedData.at( - type->hasModelData ? 0 : propertyIndex); - } - } else if (*type->model) { - *static_cast<QVariant *>(arguments[0]) = value(type->propertyRoles.at(propertyIndex)); - } - return -1; - } else if (call == QMetaObject::WriteProperty && id >= type->propertyOffset) { - const int propertyIndex = id - type->propertyOffset; - if (index == -1) { - const QMetaObject *meta = metaObject(); - if (cachedData.count() > 1) { - cachedData[propertyIndex] = *static_cast<QVariant *>(arguments[0]); - QMetaObject::activate(this, meta, propertyIndex, 0); - } else if (cachedData.count() == 1) { - cachedData[0] = *static_cast<QVariant *>(arguments[0]); - QMetaObject::activate(this, meta, 0, 0); - QMetaObject::activate(this, meta, 1, 0); - } - } else if (*type->model) { - setValue(type->propertyRoles.at(propertyIndex), *static_cast<QVariant *>(arguments[0])); - } - return -1; - } else { - return qt_metacall(call, id, arguments); - } -} - -void QQuickVDMCachedModelData::setValue(const QString &role, const QVariant &value) -{ - QHash<QByteArray, int>::iterator it = type->roleNames.find(role.toUtf8()); - if (it != type->roleNames.end()) { - for (int i = 0; i < type->propertyRoles.count(); ++i) { - if (type->propertyRoles.at(i) == *it) { - cachedData[i] = value; - return; - } - } - } -} - -bool QQuickVDMCachedModelData::resolveIndex(const QQuickVisualAdaptorModel &, int idx) -{ - if (index == -1) { - Q_ASSERT(idx >= 0); - index = idx; - cachedData.clear(); - emit modelIndexChanged(); - const QMetaObject *meta = metaObject(); - const int propertyCount = type->propertyRoles.count(); - for (int i = 0; i < propertyCount; ++i) - QMetaObject::activate(this, meta, i, 0); - return true; - } else { - return false; - } -} - -v8::Handle<v8::Value> QQuickVDMCachedModelData::get_property( - v8::Local<v8::String>, const v8::AccessorInfo &info) -{ - QQuickVisualDataModelItem *data = v8_resource_cast<QQuickVisualDataModelItem>(info.This()); - V8ASSERT_TYPE(data, "Not a valid VisualData object"); - - QQuickVDMCachedModelData *modelData = static_cast<QQuickVDMCachedModelData *>(data); - const int propertyId = info.Data()->Int32Value(); - if (data->index == -1) { - if (!modelData->cachedData.isEmpty()) { - return data->engine->fromVariant( - modelData->cachedData.at(modelData->type->hasModelData ? 0 : propertyId)); - } - } else if (*modelData->type->model) { - return data->engine->fromVariant( - modelData->value(modelData->type->propertyRoles.at(propertyId))); - } - return v8::Undefined(); -} - -void QQuickVDMCachedModelData::set_property( - v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info) -{ - QQuickVisualDataModelItem *data = v8_resource_cast<QQuickVisualDataModelItem>(info.This()); - V8ASSERT_TYPE_SETTER(data, "Not a valid VisualData object"); - - const int propertyId = info.Data()->Int32Value(); - if (data->index == -1) { - QQuickVDMCachedModelData *modelData = static_cast<QQuickVDMCachedModelData *>(data); - if (!modelData->cachedData.isEmpty()) { - if (modelData->cachedData.count() > 1) { - modelData->cachedData[propertyId] = data->engine->toVariant(value, QVariant::Invalid); - QMetaObject::activate(data, data->metaObject(), propertyId, 0); - } else if (modelData->cachedData.count() == 1) { - modelData->cachedData[0] = data->engine->toVariant(value, QVariant::Invalid); - QMetaObject::activate(data, data->metaObject(), 0, 0); - QMetaObject::activate(data, data->metaObject(), 1, 0); - } - } - } -} - -//----------------------------------------------------------------- -// QAbstractItemModel -//----------------------------------------------------------------- - -class QQuickVDMAbstractItemModelData : public QQuickVDMCachedModelData -{ - Q_OBJECT - Q_PROPERTY(bool hasModelChildren READ hasModelChildren CONSTANT) -public: - QQuickVDMAbstractItemModelData( - QQuickVisualDataModelItemMetaType *metaType, - VDMModelDelegateDataType *dataType, - int index) - : QQuickVDMCachedModelData(metaType, dataType, index) - { - } - - bool hasModelChildren() const - { - if (index >= 0 && *type->model) { - const QAbstractItemModel * const model = type->model->aim(); - return model->hasChildren(model->index(index, 0, type->model->rootIndex)); - } else { - return false; - } - } - - QVariant value(int role) const - { - return type->model->aim()->index(index, 0, type->model->rootIndex).data(role); - } - - void setValue(int role, const QVariant &value) - { - type->model->aim()->setData( - type->model->aim()->index(index, 0, type->model->rootIndex), value, role); - } - - v8::Handle<v8::Value> get() - { - if (type->constructor.IsEmpty()) { - QQuickVisualAdaptorModelEngineData * const data = engineData(engine); - v8::HandleScope handleScope; - v8::Context::Scope contextScope(engine->context()); - type->initializeConstructor(data); - type->constructor->SetAccessor(data->hasModelChildren(), get_hasModelChildren); - } - v8::Local<v8::Object> data = type->constructor->NewInstance(); - data->SetExternalResource(this); - ++scriptRef; - return data; - } - - static v8::Handle<v8::Value> get_hasModelChildren(v8::Local<v8::String>, const v8::AccessorInfo &info) - { - QQuickVisualDataModelItem *data = v8_resource_cast<QQuickVisualDataModelItem>(info.This()); - V8ASSERT_TYPE(data, "Not a valid VisualData object"); - - const QQuickVisualAdaptorModel *const model = static_cast<QQuickVDMCachedModelData *>(data)->type->model; - if (data->index >= 0 && *model) { - const QAbstractItemModel * const aim = model->aim(); - return v8::Boolean::New(aim->hasChildren(aim->index(data->index, 0, model->rootIndex))); - } else { - return v8::Boolean::New(false); - } - } -}; - -class VDMAbstractItemModelDataType : public VDMModelDelegateDataType -{ -public: - VDMAbstractItemModelDataType(QQuickVisualAdaptorModel *model) - : VDMModelDelegateDataType(model) - { - } - - int count(const QQuickVisualAdaptorModel &model) const - { - return model.aim()->rowCount(model.rootIndex); - } - - void cleanup(QQuickVisualAdaptorModel &model, QQuickVisualDataModel *vdm) const - { - QAbstractItemModel * const aim = model.aim(); - if (aim && vdm) { - QObject::disconnect(aim, SIGNAL(rowsInserted(QModelIndex,int,int)), - vdm, SLOT(_q_rowsInserted(QModelIndex,int,int))); - QObject::disconnect(aim, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), - vdm, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int))); - QObject::disconnect(aim, SIGNAL(rowsRemoved(QModelIndex,int,int)), - vdm, SLOT(_q_rowsRemoved(QModelIndex,int,int))); - QObject::disconnect(aim, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)), - vdm, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>))); - QObject::disconnect(aim, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), - vdm, SLOT(_q_rowsMoved(QModelIndex,int,int,QModelIndex,int))); - QObject::disconnect(aim, SIGNAL(modelReset()), - vdm, SLOT(_q_modelReset())); - QObject::disconnect(aim, SIGNAL(layoutChanged()), - vdm, SLOT(_q_layoutChanged())); - } - - const_cast<VDMAbstractItemModelDataType *>(this)->release(); - } - - QVariant value(const QQuickVisualAdaptorModel &model, int index, const QString &role) const - { - QHash<QByteArray, int>::const_iterator it = roleNames.find(role.toUtf8()); - if (it != roleNames.end()) { - return model.aim()->index(index, 0, model.rootIndex).data(*it); - } else if (role == QLatin1String("hasModelChildren")) { - return QVariant(model.aim()->hasChildren(model.aim()->index(index, 0, model.rootIndex))); - } else { - return QVariant(); - } - } - - QVariant parentModelIndex(const QQuickVisualAdaptorModel &model) const - { - return model - ? QVariant::fromValue(model.aim()->parent(model.rootIndex)) - : QVariant(); - } - - QVariant modelIndex(const QQuickVisualAdaptorModel &model, int index) const - { - return model - ? QVariant::fromValue(model.aim()->index(index, 0, model.rootIndex)) - : QVariant(); - } - - bool canFetchMore(const QQuickVisualAdaptorModel &model) const - { - return model && model.aim()->canFetchMore(model.rootIndex); - } - - void fetchMore(QQuickVisualAdaptorModel &model) const - { - if (model) - model.aim()->fetchMore(model.rootIndex); - } - - QQuickVisualDataModelItem *createItem( - QQuickVisualAdaptorModel &model, - QQuickVisualDataModelItemMetaType *metaType, - QQmlEngine *engine, - int index) const - { - VDMAbstractItemModelDataType *dataType = const_cast<VDMAbstractItemModelDataType *>(this); - if (!metaObject) - dataType->initializeMetaType(model, engine); - return new QQuickVDMAbstractItemModelData(metaType, dataType, index); - } - - void initializeMetaType(QQuickVisualAdaptorModel &model, QQmlEngine *engine) - { - QMetaObjectBuilder builder; - setModelDataType<QQuickVDMAbstractItemModelData>(&builder, this); - - const QByteArray propertyType = QByteArrayLiteral("QVariant"); - const QHash<int, QByteArray> names = model.aim()->roleNames(); - for (QHash<int, QByteArray>::const_iterator it = names.begin(); it != names.end(); ++it) { - const int propertyId = propertyRoles.count(); - propertyRoles.append(it.key()); - roleNames.insert(it.value(), it.key()); - addProperty(&builder, propertyId, it.value(), propertyType); - } - if (propertyRoles.count() == 1) { - hasModelData = true; - const int role = names.begin().key(); - const QByteArray propertyName = QByteArrayLiteral("modelData"); - - propertyRoles.append(role); - roleNames.insert(propertyName, role); - addProperty(&builder, 1, propertyName, propertyType); - } - - metaObject = builder.toMetaObject(); - *static_cast<QMetaObject *>(this) = *metaObject; - propertyCache = new QQmlPropertyCache(engine, metaObject); - } -}; - -//----------------------------------------------------------------- -// QQuickListAccessor -//----------------------------------------------------------------- - -class QQuickVDMListAccessorData : public QQuickVisualDataModelItem -{ - Q_OBJECT - Q_PROPERTY(QVariant modelData READ modelData WRITE setModelData NOTIFY modelDataChanged) -public: - QQuickVDMListAccessorData(QQuickVisualDataModelItemMetaType *metaType, int index, const QVariant &value) - : QQuickVisualDataModelItem(metaType, index) - , cachedData(value) - { - } - - QVariant modelData() const - { - return cachedData; - } - - void setModelData(const QVariant &data) - { - if (index == -1 && data != cachedData) { - cachedData = data; - emit modelDataChanged(); - } - } - - static v8::Handle<v8::Value> get_modelData(v8::Local<v8::String>, const v8::AccessorInfo &info) - { - QQuickVisualDataModelItem *data = v8_resource_cast<QQuickVisualDataModelItem>(info.This()); - V8ASSERT_TYPE(data, "Not a valid VisualData object"); - - return data->engine->fromVariant(static_cast<QQuickVDMListAccessorData *>(data)->cachedData); - } - - static void set_modelData(v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info) - { - QQuickVisualDataModelItem *data = v8_resource_cast<QQuickVisualDataModelItem>(info.This()); - V8ASSERT_TYPE_SETTER(data, "Not a valid VisualData object"); - - static_cast<QQuickVDMListAccessorData *>(data)->setModelData( - data->engine->toVariant(value, QVariant::Invalid)); - } - - v8::Handle<v8::Value> get() - { - v8::Local<v8::Object> data = engineData(engine)->constructorListItem->NewInstance(); - data->SetExternalResource(this); - ++scriptRef; - return data; - } - - void setValue(const QString &role, const QVariant &value) - { - if (role == QLatin1String("modelData")) - cachedData = value; - } - - bool resolveIndex(const QQuickVisualAdaptorModel &model, int idx) - { - if (index == -1) { - index = idx; - cachedData = model.list.at(idx); - emit modelIndexChanged(); - emit modelDataChanged(); - return true; - } else { - return false; - } - } - - -Q_SIGNALS: - void modelDataChanged(); - -private: - QVariant cachedData; -}; - - -class VDMListDelegateDataType : public QQuickVisualAdaptorModel::Accessors -{ -public: - inline VDMListDelegateDataType() {} - - int count(const QQuickVisualAdaptorModel &model) const - { - return model.list.count(); - } - - QVariant value(const QQuickVisualAdaptorModel &model, int index, const QString &role) const - { - return role == QLatin1String("modelData") - ? model.list.at(index) - : QVariant(); - } - - QQuickVisualDataModelItem *createItem( - QQuickVisualAdaptorModel &model, - QQuickVisualDataModelItemMetaType *metaType, - QQmlEngine *, - int index) const - { - return new QQuickVDMListAccessorData( - metaType, - index, - index >= 0 && index < model.list.count() ? model.list.at(index) : QVariant()); - } -}; - -//----------------------------------------------------------------- -// QObject -//----------------------------------------------------------------- - -class VDMObjectDelegateDataType; -class QQuickVDMObjectData : public QQuickVisualDataModelItem, public QQuickVisualAdaptorModelProxyInterface -{ - Q_OBJECT - Q_PROPERTY(QObject *modelData READ modelData CONSTANT) - Q_INTERFACES(QQuickVisualAdaptorModelProxyInterface) -public: - QQuickVDMObjectData( - QQuickVisualDataModelItemMetaType *metaType, - VDMObjectDelegateDataType *dataType, - int index, - QObject *object); - - QObject *modelData() const { return object; } - QObject *proxiedObject() { return object; } - - QQmlGuard<QObject> object; -}; - -class VDMObjectDelegateDataType : public QQmlRefCount, public QQuickVisualAdaptorModel::Accessors -{ -public: - QMetaObject *metaObject; - int propertyOffset; - int signalOffset; - bool shared; - QMetaObjectBuilder builder; - - VDMObjectDelegateDataType() - : metaObject(0) - , propertyOffset(0) - , signalOffset(0) - , shared(true) - { - } - - VDMObjectDelegateDataType(const VDMObjectDelegateDataType &type) - : QQmlRefCount() - , QQuickVisualAdaptorModel::Accessors() - , metaObject(0) - , propertyOffset(type.propertyOffset) - , signalOffset(type.signalOffset) - , shared(false) - , builder(type.metaObject, QMetaObjectBuilder::Properties - | QMetaObjectBuilder::Signals - | QMetaObjectBuilder::SuperClass - | QMetaObjectBuilder::ClassName) - { - builder.setFlags(QMetaObjectBuilder::DynamicMetaObject); - } - - ~VDMObjectDelegateDataType() - { - free(metaObject); - } - - int count(const QQuickVisualAdaptorModel &model) const - { - return model.list.count(); - } - - QVariant value(const QQuickVisualAdaptorModel &model, int index, const QString &role) const - { - if (QObject *object = model.list.at(index).value<QObject *>()) - return object->property(role.toUtf8()); - return QVariant(); - } - - QQuickVisualDataModelItem *createItem( - QQuickVisualAdaptorModel &model, - QQuickVisualDataModelItemMetaType *metaType, - QQmlEngine *, - int index) const - { - VDMObjectDelegateDataType *dataType = const_cast<VDMObjectDelegateDataType *>(this); - if (!metaObject) - dataType->initializeMetaType(model); - return index >= 0 && index < model.list.count() - ? new QQuickVDMObjectData(metaType, dataType, index, qvariant_cast<QObject *>(model.list.at(index))) - : 0; - } - - void initializeMetaType(QQuickVisualAdaptorModel &) - { - setModelDataType<QQuickVDMObjectData>(&builder, this); - - metaObject = builder.toMetaObject(); - } - - void cleanup(QQuickVisualAdaptorModel &, QQuickVisualDataModel *) const - { - const_cast<VDMObjectDelegateDataType *>(this)->release(); - } -}; - -class QQuickVDMObjectDataMetaObject : public QAbstractDynamicMetaObject -{ -public: - QQuickVDMObjectDataMetaObject(QQuickVDMObjectData *data, VDMObjectDelegateDataType *type) - : m_data(data) - , m_type(type) - { - QObjectPrivate *op = QObjectPrivate::get(m_data); - *static_cast<QMetaObject *>(this) = *type->metaObject; - op->metaObject = this; - m_type->addref(); - } - - ~QQuickVDMObjectDataMetaObject() - { - m_type->release(); - } - - int metaCall(QMetaObject::Call call, int id, void **arguments) - { - static const int objectPropertyOffset = QObject::staticMetaObject.propertyCount(); - if (id >= m_type->propertyOffset - && (call == QMetaObject::ReadProperty - || call == QMetaObject::WriteProperty - || call == QMetaObject::ResetProperty)) { - if (m_data->object) - QMetaObject::metacall(m_data->object, call, id - m_type->propertyOffset + objectPropertyOffset, arguments); - return -1; - } else if (id >= m_type->signalOffset && call == QMetaObject::InvokeMetaMethod) { - QMetaObject::activate(m_data, this, id - m_type->signalOffset, 0); - return -1; - } else { - return m_data->qt_metacall(call, id, arguments); - } - } - - int createProperty(const char *name, const char *) - { - if (!m_data->object) - return -1; - const QMetaObject *metaObject = m_data->object->metaObject(); - static const int objectPropertyOffset = QObject::staticMetaObject.propertyCount(); - - const int previousPropertyCount = propertyCount() - propertyOffset(); - int propertyIndex = metaObject->indexOfProperty(name); - if (propertyIndex == -1) - return -1; - if (previousPropertyCount + objectPropertyOffset == metaObject->propertyCount()) - return propertyIndex + m_type->propertyOffset - objectPropertyOffset; - - if (m_type->shared) { - VDMObjectDelegateDataType *type = m_type; - m_type = new VDMObjectDelegateDataType(*m_type); - type->release(); - } - - const int previousMethodCount = methodCount(); - int notifierId = previousMethodCount - methodOffset(); - for (int propertyId = previousPropertyCount; propertyId < metaObject->propertyCount() - objectPropertyOffset; ++propertyId) { - QMetaProperty property = metaObject->property(propertyId + objectPropertyOffset); - QMetaPropertyBuilder propertyBuilder; - if (property.hasNotifySignal()) { - m_type->builder.addSignal("__" + QByteArray::number(propertyId) + "()"); - propertyBuilder = m_type->builder.addProperty(property.name(), property.typeName(), notifierId); - ++notifierId; - } else { - propertyBuilder = m_type->builder.addProperty(property.name(), property.typeName()); - } - propertyBuilder.setWritable(property.isWritable()); - propertyBuilder.setResettable(property.isResettable()); - propertyBuilder.setConstant(property.isConstant()); - } - - if (m_type->metaObject) - free(m_type->metaObject); - m_type->metaObject = m_type->builder.toMetaObject(); - *static_cast<QMetaObject *>(this) = *m_type->metaObject; - - notifierId = previousMethodCount; - for (int i = previousPropertyCount; i < metaObject->propertyCount() - objectPropertyOffset; ++i) { - QMetaProperty property = metaObject->property(i + objectPropertyOffset); - if (property.hasNotifySignal()) { - QQmlPropertyPrivate::connect( - m_data->object, property.notifySignalIndex(), m_data, notifierId); - ++notifierId; - } - } - return propertyIndex + m_type->propertyOffset - objectPropertyOffset; - } - - QQuickVDMObjectData *m_data; - VDMObjectDelegateDataType *m_type; -}; - -QQuickVDMObjectData::QQuickVDMObjectData( - QQuickVisualDataModelItemMetaType *metaType, - VDMObjectDelegateDataType *dataType, - int index, - QObject *object) - : QQuickVisualDataModelItem(metaType, index) - , object(object) -{ - new QQuickVDMObjectDataMetaObject(this, dataType); -} - -//----------------------------------------------------------------- -// QQuickVisualAdaptorModel -//----------------------------------------------------------------- - -static const QQuickVisualAdaptorModel::Accessors qt_vdm_null_accessors; -static const VDMListDelegateDataType qt_vdm_list_accessors; - -QQuickVisualAdaptorModel::Accessors::~Accessors() -{ -} - -QQuickVisualAdaptorModel::QQuickVisualAdaptorModel() - : accessors(&qt_vdm_null_accessors) -{ -} - -QQuickVisualAdaptorModel::~QQuickVisualAdaptorModel() -{ - accessors->cleanup(*this); -} - -void QQuickVisualAdaptorModel::setModel(const QVariant &variant, QQuickVisualDataModel *vdm, QQmlEngine *engine) -{ - accessors->cleanup(*this, vdm); - - list.setList(variant, engine); - - if (QObject *object = qvariant_cast<QObject *>(variant)) { - setObject(object); - if (QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(object)) { - accessors = new VDMAbstractItemModelDataType(this); - - qmlobject_connect(model, QAbstractItemModel, SIGNAL(rowsInserted(QModelIndex,int,int)), - vdm, QQuickVisualDataModel, SLOT(_q_rowsInserted(QModelIndex,int,int))); - qmlobject_connect(model, QAbstractItemModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), - vdm, QQuickVisualDataModel, SLOT(_q_rowsRemoved(QModelIndex,int,int))); - qmlobject_connect(model, QAbstractItemModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), - vdm, QQuickVisualDataModel, SLOT(_q_rowsAboutToBeRemoved(QModelIndex,int,int))); - qmlobject_connect(model, QAbstractItemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)), - vdm, QQuickVisualDataModel, SLOT(_q_dataChanged(QModelIndex,QModelIndex,QVector<int>))); - qmlobject_connect(model, QAbstractItemModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), - vdm, QQuickVisualDataModel, SLOT(_q_rowsMoved(QModelIndex,int,int,QModelIndex,int))); - qmlobject_connect(model, QAbstractItemModel, SIGNAL(modelReset()), - vdm, QQuickVisualDataModel, SLOT(_q_modelReset())); - qmlobject_connect(model, QAbstractItemModel, SIGNAL(layoutChanged()), - vdm, QQuickVisualDataModel, SLOT(_q_layoutChanged())); - } else { - accessors = new VDMObjectDelegateDataType; - } - } else if (list.type() == QQuickListAccessor::ListProperty) { - setObject(static_cast<const QQmlListReference *>(variant.constData())->object()); - accessors = new VDMObjectDelegateDataType; - } else if (list.type() != QQuickListAccessor::Invalid) { - Q_ASSERT(list.type() != QQuickListAccessor::Instance); // Should have cast to QObject. - setObject(0); - accessors = &qt_vdm_list_accessors; - } else { - setObject(0); - accessors = &qt_vdm_null_accessors; - } -} - -void QQuickVisualAdaptorModel::invalidateModel(QQuickVisualDataModel *vdm) -{ - accessors->cleanup(*this, vdm); - accessors = &qt_vdm_null_accessors; - // Don't clear the model object as we still need the guard to clear the list variant if the - // object is destroyed. -} - -bool QQuickVisualAdaptorModel::isValid() const -{ - return accessors != &qt_vdm_null_accessors; -} - -void QQuickVisualAdaptorModel::objectDestroyed(QObject *) -{ - setModel(QVariant(), 0, 0); -} - -QQuickVisualAdaptorModelEngineData::QQuickVisualAdaptorModelEngineData(QV8Engine *) -{ - strings = qPersistentNew(v8::Array::New(StringCount)); - strings->Set(Index, v8::String::New("index")); - strings->Set(ModelData, v8::String::New("modelData")); - strings->Set(HasModelChildren, v8::String::New("hasModelChildren")); - - v8::Local<v8::FunctionTemplate> listItem = v8::FunctionTemplate::New(); - listItem->InstanceTemplate()->SetHasExternalResource(true); - listItem->InstanceTemplate()->SetAccessor(index(), get_index); - listItem->InstanceTemplate()->SetAccessor( - modelData(), - QQuickVDMListAccessorData::get_modelData, - QQuickVDMListAccessorData::set_modelData); - constructorListItem = qPersistentNew(listItem->GetFunction()); -} - -QQuickVisualAdaptorModelEngineData::~QQuickVisualAdaptorModelEngineData() -{ - qPersistentDispose(constructorListItem); - qPersistentDispose(strings); -} - -QT_END_NAMESPACE - -#include <qquickvisualadaptormodel.moc> diff --git a/src/quick/items/qquickvisualadaptormodel_p.h b/src/quick/items/qquickvisualadaptormodel_p.h deleted file mode 100644 index 40890f8560..0000000000 --- a/src/quick/items/qquickvisualadaptormodel_p.h +++ /dev/null @@ -1,156 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQUICKVISUALADAPTORMODEL_P_H -#define QQUICKVISUALADAPTORMODEL_P_H - -#include <QtCore/qabstractitemmodel.h> - -#include "private/qquicklistaccessor_p.h" - -#include <private/qqmlguard_p.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQmlEngine; - -class QQuickVisualDataModel; -class QQuickVisualDataModelItem; -class QQuickVisualDataModelItemMetaType; - -class QQuickVisualAdaptorModel : public QQmlGuard<QObject> -{ -public: - class Accessors - { - public: - inline Accessors() {} - virtual ~Accessors(); - virtual int count(const QQuickVisualAdaptorModel &) const { return 0; } - virtual void cleanup(QQuickVisualAdaptorModel &, QQuickVisualDataModel * = 0) const {} - - virtual QVariant value(const QQuickVisualAdaptorModel &, int, const QString &) const { - return QVariant(); } - - virtual QQuickVisualDataModelItem *createItem( - QQuickVisualAdaptorModel &, - QQuickVisualDataModelItemMetaType *, - QQmlEngine *, - int) const { return 0; } - - virtual bool notify( - const QQuickVisualAdaptorModel &, - const QList<QQuickVisualDataModelItem *> &, - int, - int, - const QVector<int> &) const { return false; } - virtual void replaceWatchedRoles( - QQuickVisualAdaptorModel &, - const QList<QByteArray> &, - const QList<QByteArray> &) const {} - virtual QVariant parentModelIndex(const QQuickVisualAdaptorModel &) const { - return QVariant(); } - virtual QVariant modelIndex(const QQuickVisualAdaptorModel &, int) const { - return QVariant(); } - virtual bool canFetchMore(const QQuickVisualAdaptorModel &) const { return false; } - virtual void fetchMore(QQuickVisualAdaptorModel &) const {} - }; - - const Accessors *accessors; - QPersistentModelIndex rootIndex; - QQuickListAccessor list; - - QQuickVisualAdaptorModel(); - ~QQuickVisualAdaptorModel(); - - inline QVariant model() const { return list.list(); } - void setModel(const QVariant &variant, QQuickVisualDataModel *vdm, QQmlEngine *engine); - void invalidateModel(QQuickVisualDataModel *vdm); - - bool isValid() const; - - inline QAbstractItemModel *aim() { return static_cast<QAbstractItemModel *>(object()); } - inline const QAbstractItemModel *aim() const { return static_cast<const QAbstractItemModel *>(object()); } - - inline int count() const { return qMax(0, accessors->count(*this)); } - inline QVariant value(int index, const QString &role) const { - return accessors->value(*this, index, role); } - inline QQuickVisualDataModelItem *createItem(QQuickVisualDataModelItemMetaType *metaType, QQmlEngine *engine, int index) { - return accessors->createItem(*this, metaType, engine, index); } - inline bool hasProxyObject() const { - return list.type() == QQuickListAccessor::Instance || list.type() == QQuickListAccessor::ListProperty; } - - inline bool notify( - const QList<QQuickVisualDataModelItem *> &items, - int index, - int count, - const QVector<int> &roles) const { - return accessors->notify(*this, items, index, count, roles); } - inline void replaceWatchedRoles( - const QList<QByteArray> &oldRoles, const QList<QByteArray> &newRoles) { - accessors->replaceWatchedRoles(*this, oldRoles, newRoles); } - - inline QVariant modelIndex(int index) const { return accessors->modelIndex(*this, index); } - inline QVariant parentModelIndex() const { return accessors->parentModelIndex(*this); } - inline bool canFetchMore() const { return accessors->canFetchMore(*this); } - inline void fetchMore() { return accessors->fetchMore(*this); } - -protected: - void objectDestroyed(QObject *); -}; - -class QQuickVisualAdaptorModelProxyInterface -{ -public: - virtual ~QQuickVisualAdaptorModelProxyInterface() {} - - virtual QObject *proxiedObject() = 0; -}; - -#define QQuickVisualAdaptorModelProxyInterface_iid "org.qt-project.Qt.QQuickVisualAdaptorModelProxyInterface" - -Q_DECLARE_INTERFACE(QQuickVisualAdaptorModelProxyInterface, QQuickVisualAdaptorModelProxyInterface_iid) - -QT_END_NAMESPACE - -#endif diff --git a/src/quick/items/qquickvisualdatamodel.cpp b/src/quick/items/qquickvisualdatamodel.cpp deleted file mode 100644 index d2e50e8b8a..0000000000 --- a/src/quick/items/qquickvisualdatamodel.cpp +++ /dev/null @@ -1,3173 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickvisualdatamodel_p_p.h" -#include "qquickitem.h" - -#include <QtQml/qqmlinfo.h> - -#include <private/qquickpackage_p.h> -#include <private/qmetaobjectbuilder_p.h> -#include <private/qquickvisualadaptormodel_p.h> -#include <private/qquickchangeset_p.h> -#include <private/qqmlengine_p.h> -#include <private/qqmlcomponent_p.h> -#include <private/qqmlincubator_p.h> -#include <private/qqmlcompiler_p.h> - -QT_BEGIN_NAMESPACE - -class QQuickVisualDataModelEngineData : public QV8Engine::Deletable -{ -public: - enum - { - Model, - Groups, - IsUnresolved, - ItemsIndex, - PersistedItemsIndex, - InItems, - InPersistedItems, - StringCount - }; - - QQuickVisualDataModelEngineData(QV8Engine *engine); - ~QQuickVisualDataModelEngineData(); - - v8::Local<v8::Object> array( - QV8Engine *engine, const QVector<QQuickChangeSet::Remove> &changes); - v8::Local<v8::Object> array( - QV8Engine *engine, const QVector<QQuickChangeSet::Insert> &changes); - v8::Local<v8::Object> array( - QV8Engine *engine, const QVector<QQuickChangeSet::Change> &changes); - - - inline v8::Local<v8::String> model() { return strings->Get(Model)->ToString(); } - inline v8::Local<v8::String> groups() { return strings->Get(Groups)->ToString(); } - inline v8::Local<v8::String> isUnresolved() { return strings->Get(IsUnresolved)->ToString(); } - inline v8::Local<v8::String> itemsIndex() { return strings->Get(ItemsIndex)->ToString(); } - inline v8::Local<v8::String> persistedItemsIndex() { return strings->Get(PersistedItemsIndex)->ToString(); } - inline v8::Local<v8::String> inItems() { return strings->Get(InItems)->ToString(); } - inline v8::Local<v8::String> inPersistedItems() { return strings->Get(InPersistedItems)->ToString(); } - - v8::Persistent<v8::Array> strings; - v8::Persistent<v8::Function> constructorChange; - v8::Persistent<v8::Function> constructorChangeArray; -}; - -V8_DEFINE_EXTENSION(QQuickVisualDataModelEngineData, engineData) - - -void QQuickVisualDataModelPartsMetaObject::propertyCreated(int, QMetaPropertyBuilder &prop) -{ - prop.setWritable(false); -} - -QVariant QQuickVisualDataModelPartsMetaObject::initialValue(int id) -{ - QQuickVisualDataModelParts *parts = static_cast<QQuickVisualDataModelParts *>(object()); - QQuickVisualPartsModel *m = new QQuickVisualPartsModel( - parts->model, QString::fromUtf8(name(id)), parts); - parts->models.append(m); - return QVariant::fromValue(static_cast<QObject *>(m)); -} - -QQuickVisualDataModelParts::QQuickVisualDataModelParts(QQuickVisualDataModel *parent) -: QObject(parent), model(parent) -{ - new QQuickVisualDataModelPartsMetaObject(this); -} - -//--------------------------------------------------------------------------- - -/*! - \qmltype VisualDataModel - \instantiates QQuickVisualDataModel - \inqmlmodule QtQuick 2 - \ingroup qtquick-models - \brief Encapsulates a model and delegate - - The VisualDataModel type encapsulates a model and the delegate that will - be instantiated for items in the model. - - It is usually not necessary to create a VisualDataModel. - However, it can be useful for manipulating and accessing the \l modelIndex - when a QAbstractItemModel subclass is used as the - model. Also, VisualDataModel is used together with \l Package to - provide delegates to multiple views, and with VisualDataGroup to sort and filter - delegate items. - - The example below illustrates using a VisualDataModel with a ListView. - - \snippet qml/visualdatamodel.qml 0 -*/ - -QQuickVisualDataModelPrivate::QQuickVisualDataModelPrivate(QQmlContext *ctxt) - : m_delegate(0) - , m_cacheMetaType(0) - , m_context(ctxt) - , m_parts(0) - , m_filterGroup(QStringLiteral("items")) - , m_count(0) - , m_groupCount(Compositor::MinimumGroupCount) - , m_compositorGroup(Compositor::Cache) - , m_complete(false) - , m_delegateValidated(false) - , m_reset(false) - , m_transaction(false) - , m_incubatorCleanupScheduled(false) - , m_cacheItems(0) - , m_items(0) - , m_persistedItems(0) -{ -} - -QQuickVisualDataModelPrivate::~QQuickVisualDataModelPrivate() -{ - qDeleteAll(m_finishedIncubating); - - if (m_cacheMetaType) - m_cacheMetaType->release(); -} - -void QQuickVisualDataModelPrivate::init() -{ - Q_Q(QQuickVisualDataModel); - m_compositor.setRemoveGroups(Compositor::GroupMask & ~Compositor::PersistedFlag); - - m_items = new QQuickVisualDataGroup(QStringLiteral("items"), q, Compositor::Default, q); - m_items->setDefaultInclude(true); - m_persistedItems = new QQuickVisualDataGroup(QStringLiteral("persistedItems"), q, Compositor::Persisted, q); - QQuickVisualDataGroupPrivate::get(m_items)->emitters.insert(this); -} - -QQuickVisualDataModel::QQuickVisualDataModel() -: QQuickVisualModel(*(new QQuickVisualDataModelPrivate(0))) -{ - Q_D(QQuickVisualDataModel); - d->init(); -} - -QQuickVisualDataModel::QQuickVisualDataModel(QQmlContext *ctxt, QObject *parent) -: QQuickVisualModel(*(new QQuickVisualDataModelPrivate(ctxt)), parent) -{ - Q_D(QQuickVisualDataModel); - d->init(); -} - -QQuickVisualDataModel::~QQuickVisualDataModel() -{ - Q_D(QQuickVisualDataModel); - - foreach (QQuickVisualDataModelItem *cacheItem, d->m_cache) { - if (cacheItem->object) { - delete cacheItem->object; - - cacheItem->object = 0; - cacheItem->contextData->destroy(); - cacheItem->contextData = 0; - cacheItem->scriptRef -= 1; - } - cacheItem->groups &= ~Compositor::UnresolvedFlag; - cacheItem->objectRef = 0; - if (!cacheItem->isReferenced()) - delete cacheItem; - } -} - - -void QQuickVisualDataModel::classBegin() -{ - Q_D(QQuickVisualDataModel); - if (!d->m_context) - d->m_context = qmlContext(this); -} - -void QQuickVisualDataModel::componentComplete() -{ - Q_D(QQuickVisualDataModel); - d->m_complete = true; - - int defaultGroups = 0; - QStringList groupNames; - groupNames.append(QStringLiteral("items")); - groupNames.append(QStringLiteral("persistedItems")); - if (QQuickVisualDataGroupPrivate::get(d->m_items)->defaultInclude) - defaultGroups |= Compositor::DefaultFlag; - if (QQuickVisualDataGroupPrivate::get(d->m_persistedItems)->defaultInclude) - defaultGroups |= Compositor::PersistedFlag; - for (int i = Compositor::MinimumGroupCount; i < d->m_groupCount; ++i) { - QString name = d->m_groups[i]->name(); - if (name.isEmpty()) { - d->m_groups[i] = d->m_groups[d->m_groupCount - 1]; - --d->m_groupCount; - --i; - } else if (name.at(0).isUpper()) { - qmlInfo(d->m_groups[i]) << QQuickVisualDataGroup::tr("Group names must start with a lower case letter"); - d->m_groups[i] = d->m_groups[d->m_groupCount - 1]; - --d->m_groupCount; - --i; - } else { - groupNames.append(name); - - QQuickVisualDataGroupPrivate *group = QQuickVisualDataGroupPrivate::get(d->m_groups[i]); - group->setModel(this, Compositor::Group(i)); - if (group->defaultInclude) - defaultGroups |= (1 << i); - } - } - - d->m_cacheMetaType = new QQuickVisualDataModelItemMetaType( - QQmlEnginePrivate::getV8Engine(d->m_context->engine()), this, groupNames); - - d->m_compositor.setGroupCount(d->m_groupCount); - d->m_compositor.setDefaultGroups(defaultGroups); - d->updateFilterGroup(); - - while (!d->m_pendingParts.isEmpty()) - static_cast<QQuickVisualPartsModel *>(d->m_pendingParts.first())->updateFilterGroup(); - - QVector<Compositor::Insert> inserts; - d->m_count = d->m_adaptorModel.count(); - d->m_compositor.append( - &d->m_adaptorModel, - 0, - d->m_count, - defaultGroups | Compositor::AppendFlag | Compositor::PrependFlag, - &inserts); - d->itemsInserted(inserts); - d->emitChanges(); - - if (d->m_adaptorModel.canFetchMore()) - QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest)); -} - -/*! - \qmlproperty model QtQuick2::VisualDataModel::model - This property holds the model providing data for the VisualDataModel. - - The model provides a set of data that is used to create the items - for a view. For large or dynamic datasets the model is usually - provided by a C++ model object. The C++ model object must be a \l - {QAbstractItemModel} subclass or a simple list. - - Models can also be created directly in QML, using a \l{ListModel} or - \l{XmlListModel}. - - \sa {qml-data-models}{Data Models} -*/ -QVariant QQuickVisualDataModel::model() const -{ - Q_D(const QQuickVisualDataModel); - return d->m_adaptorModel.model(); -} - -void QQuickVisualDataModel::setModel(const QVariant &model) -{ - Q_D(QQuickVisualDataModel); - - if (d->m_complete) - _q_itemsRemoved(0, d->m_count); - - d->m_adaptorModel.setModel(model, this, d->m_context->engine()); - d->m_adaptorModel.replaceWatchedRoles(QList<QByteArray>(), d->m_watchedRoles); - for (int i = 0; d->m_parts && i < d->m_parts->models.count(); ++i) { - d->m_adaptorModel.replaceWatchedRoles( - QList<QByteArray>(), d->m_parts->models.at(i)->watchedRoles()); - } - - if (d->m_complete) { - _q_itemsInserted(0, d->m_adaptorModel.count()); - if (d->m_adaptorModel.canFetchMore()) - QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest)); - } -} - -/*! - \qmlproperty Component QtQuick2::VisualDataModel::delegate - - The delegate provides a template defining each item instantiated by a view. - The index is exposed as an accessible \c index property. Properties of the - model are also available depending upon the type of \l {qml-data-models}{Data Model}. -*/ -QQmlComponent *QQuickVisualDataModel::delegate() const -{ - Q_D(const QQuickVisualDataModel); - return d->m_delegate; -} - -void QQuickVisualDataModel::setDelegate(QQmlComponent *delegate) -{ - Q_D(QQuickVisualDataModel); - if (d->m_transaction) { - qmlInfo(this) << tr("The delegate of a VisualDataModel cannot be changed within onUpdated."); - return; - } - bool wasValid = d->m_delegate != 0; - d->m_delegate = delegate; - d->m_delegateValidated = false; - if (wasValid && d->m_complete) { - for (int i = 1; i < d->m_groupCount; ++i) { - QQuickVisualDataGroupPrivate::get(d->m_groups[i])->changeSet.remove( - 0, d->m_compositor.count(Compositor::Group(i))); - } - } - if (d->m_complete && d->m_delegate) { - for (int i = 1; i < d->m_groupCount; ++i) { - QQuickVisualDataGroupPrivate::get(d->m_groups[i])->changeSet.insert( - 0, d->m_compositor.count(Compositor::Group(i))); - } - } - d->emitChanges(); -} - -/*! - \qmlproperty QModelIndex QtQuick2::VisualDataModel::rootIndex - - QAbstractItemModel provides a hierarchical tree of data, whereas - QML only operates on list data. \c rootIndex allows the children of - any node in a QAbstractItemModel to be provided by this model. - - This property only affects models of type QAbstractItemModel that - are hierarchical (e.g, a tree model). - - For example, here is a simple interactive file system browser. - When a directory name is clicked, the view's \c rootIndex is set to the - QModelIndex node of the clicked directory, thus updating the view to show - the new directory's contents. - - \c main.cpp: - \snippet qml/visualdatamodel_rootindex/main.cpp 0 - - \c view.qml: - \snippet qml/visualdatamodel_rootindex/view.qml 0 - - If the \l model is a QAbstractItemModel subclass, the delegate can also - reference a \c hasModelChildren property (optionally qualified by a - \e model. prefix) that indicates whether the delegate's model item has - any child nodes. - - - \sa modelIndex(), parentModelIndex() -*/ -QVariant QQuickVisualDataModel::rootIndex() const -{ - Q_D(const QQuickVisualDataModel); - return QVariant::fromValue(QModelIndex(d->m_adaptorModel.rootIndex)); -} - -void QQuickVisualDataModel::setRootIndex(const QVariant &root) -{ - Q_D(QQuickVisualDataModel); - - QModelIndex modelIndex = qvariant_cast<QModelIndex>(root); - const bool changed = d->m_adaptorModel.rootIndex != modelIndex; - if (changed || !d->m_adaptorModel.isValid()) { - const int oldCount = d->m_count; - d->m_adaptorModel.rootIndex = modelIndex; - if (!d->m_adaptorModel.isValid() && d->m_adaptorModel.aim()) // The previous root index was invalidated, so we need to reconnect the model. - d->m_adaptorModel.setModel(d->m_adaptorModel.list.list(), this, d->m_context->engine()); - if (d->m_adaptorModel.canFetchMore()) - d->m_adaptorModel.fetchMore(); - if (d->m_complete) { - const int newCount = d->m_adaptorModel.count(); - if (oldCount) - _q_itemsRemoved(0, oldCount); - if (newCount) - _q_itemsInserted(0, newCount); - } - if (changed) - emit rootIndexChanged(); - } -} - -/*! - \qmlmethod QModelIndex QtQuick2::VisualDataModel::modelIndex(int index) - - QAbstractItemModel provides a hierarchical tree of data, whereas - QML only operates on list data. This function assists in using - tree models in QML. - - Returns a QModelIndex for the specified index. - This value can be assigned to rootIndex. - - \sa rootIndex -*/ -QVariant QQuickVisualDataModel::modelIndex(int idx) const -{ - Q_D(const QQuickVisualDataModel); - return d->m_adaptorModel.modelIndex(idx); -} - -/*! - \qmlmethod QModelIndex QtQuick2::VisualDataModel::parentModelIndex() - - QAbstractItemModel provides a hierarchical tree of data, whereas - QML only operates on list data. This function assists in using - tree models in QML. - - Returns a QModelIndex for the parent of the current rootIndex. - This value can be assigned to rootIndex. - - \sa rootIndex -*/ -QVariant QQuickVisualDataModel::parentModelIndex() const -{ - Q_D(const QQuickVisualDataModel); - return d->m_adaptorModel.parentModelIndex(); -} - -/*! - \qmlproperty int QtQuick2::VisualDataModel::count -*/ - -int QQuickVisualDataModel::count() const -{ - Q_D(const QQuickVisualDataModel); - if (!d->m_delegate) - return 0; - return d->m_compositor.count(d->m_compositorGroup); -} - -QQuickVisualDataModel::ReleaseFlags QQuickVisualDataModelPrivate::release(QObject *object) -{ - QQuickVisualDataModel::ReleaseFlags stat = 0; - if (!object) - return stat; - - if (QQuickVisualDataModelItem *cacheItem = QQuickVisualDataModelItem::dataForObject(object)) { - if (cacheItem->releaseObject()) { - cacheItem->destroyObject(); - if (QQuickItem *item = qmlobject_cast<QQuickItem *>(object)) - emitDestroyingItem(item); - if (cacheItem->incubationTask) { - releaseIncubator(cacheItem->incubationTask); - cacheItem->incubationTask = 0; - } - cacheItem->Dispose(); - stat |= QQuickVisualModel::Destroyed; - } else { - stat |= QQuickVisualDataModel::Referenced; - } - } - return stat; -} - -/* - Returns ReleaseStatus flags. -*/ - -QQuickVisualDataModel::ReleaseFlags QQuickVisualDataModel::release(QQuickItem *item) -{ - Q_D(QQuickVisualDataModel); - QQuickVisualModel::ReleaseFlags stat = d->release(item); - if (stat & Destroyed) - item->setParentItem(0); - return stat; -} - -// Cancel a requested async item -void QQuickVisualDataModel::cancel(int index) -{ - Q_D(QQuickVisualDataModel); - if (!d->m_delegate || index < 0 || index >= d->m_compositor.count(d->m_compositorGroup)) { - qWarning() << "VisualDataModel::cancel: index out range" << index << d->m_compositor.count(d->m_compositorGroup); - return; - } - - Compositor::iterator it = d->m_compositor.find(d->m_compositorGroup, index); - QQuickVisualDataModelItem *cacheItem = it->inCache() ? d->m_cache.at(it.cacheIndex) : 0; - if (cacheItem) { - if (cacheItem->incubationTask && !cacheItem->isObjectReferenced()) { - d->releaseIncubator(cacheItem->incubationTask); - cacheItem->incubationTask = 0; - - if (cacheItem->object) { - QObject *object = cacheItem->object; - cacheItem->destroyObject(); - if (QQuickItem *item = qmlobject_cast<QQuickItem *>(object)) - d->emitDestroyingItem(item); - else if (QQuickPackage *package = qmlobject_cast<QQuickPackage *>(object)) - d->emitDestroyingPackage(package); - } - - cacheItem->scriptRef -= 1; - } - if (!cacheItem->isReferenced()) { - d->m_compositor.clearFlags(Compositor::Cache, it.cacheIndex, 1, Compositor::CacheFlag); - d->m_cache.removeAt(it.cacheIndex); - delete cacheItem; - Q_ASSERT(d->m_cache.count() == d->m_compositor.count(Compositor::Cache)); - } - } -} - -void QQuickVisualDataModelPrivate::group_append( - QQmlListProperty<QQuickVisualDataGroup> *property, QQuickVisualDataGroup *group) -{ - QQuickVisualDataModelPrivate *d = static_cast<QQuickVisualDataModelPrivate *>(property->data); - if (d->m_complete) - return; - if (d->m_groupCount == Compositor::MaximumGroupCount) { - qmlInfo(d->q_func()) << QQuickVisualDataModel::tr("The maximum number of supported VisualDataGroups is 8"); - return; - } - d->m_groups[d->m_groupCount] = group; - d->m_groupCount += 1; -} - -int QQuickVisualDataModelPrivate::group_count( - QQmlListProperty<QQuickVisualDataGroup> *property) -{ - QQuickVisualDataModelPrivate *d = static_cast<QQuickVisualDataModelPrivate *>(property->data); - return d->m_groupCount - 1; -} - -QQuickVisualDataGroup *QQuickVisualDataModelPrivate::group_at( - QQmlListProperty<QQuickVisualDataGroup> *property, int index) -{ - QQuickVisualDataModelPrivate *d = static_cast<QQuickVisualDataModelPrivate *>(property->data); - return index >= 0 && index < d->m_groupCount - 1 - ? d->m_groups[index + 1] - : 0; -} - -/*! - \qmlproperty list<VisualDataGroup> QtQuick2::VisualDataModel::groups - - This property holds a visual data model's group definitions. - - Groups define a sub-set of the items in a visual data model and can be used to filter - a model. - - For every group defined in a VisualDataModel two attached properties are added to each - delegate item. The first of the form VisualDataModel.in\e{GroupName} holds whether the - item belongs to the group and the second VisualDataModel.\e{groupName}Index holds the - index of the item in that group. - - The following example illustrates using groups to select items in a model. - - \snippet qml/visualdatagroup.qml 0 -*/ - -QQmlListProperty<QQuickVisualDataGroup> QQuickVisualDataModel::groups() -{ - Q_D(QQuickVisualDataModel); - return QQmlListProperty<QQuickVisualDataGroup>( - this, - d, - QQuickVisualDataModelPrivate::group_append, - QQuickVisualDataModelPrivate::group_count, - QQuickVisualDataModelPrivate::group_at, - 0); -} - -/*! - \qmlproperty VisualDataGroup QtQuick2::VisualDataModel::items - - This property holds visual data model's default group to which all new items are added. -*/ - -QQuickVisualDataGroup *QQuickVisualDataModel::items() -{ - Q_D(QQuickVisualDataModel); - return d->m_items; -} - -/*! - \qmlproperty VisualDataGroup QtQuick2::VisualDataModel::persistedItems - - This property holds visual data model's persisted items group. - - Items in this group are not destroyed when released by a view, instead they are persisted - until removed from the group. - - An item can be removed from the persistedItems group by setting the - VisualDataModel.inPersistedItems property to false. If the item is not referenced by a view - at that time it will be destroyed. Adding an item to this group will not create a new - instance. - - Items returned by the \l QtQuick2::VisualDataGroup::create() function are automatically added - to this group. -*/ - -QQuickVisualDataGroup *QQuickVisualDataModel::persistedItems() -{ - Q_D(QQuickVisualDataModel); - return d->m_persistedItems; -} - -/*! - \qmlproperty string QtQuick2::VisualDataModel::filterOnGroup - - This property holds the name of the group used to filter the visual data model. - - Only items which belong to this group are visible to a view. - - By default this is the \l items group. -*/ - -QString QQuickVisualDataModel::filterGroup() const -{ - Q_D(const QQuickVisualDataModel); - return d->m_filterGroup; -} - -void QQuickVisualDataModel::setFilterGroup(const QString &group) -{ - Q_D(QQuickVisualDataModel); - - if (d->m_transaction) { - qmlInfo(this) << tr("The group of a VisualDataModel cannot be changed within onChanged"); - return; - } - - if (d->m_filterGroup != group) { - d->m_filterGroup = group; - d->updateFilterGroup(); - emit filterGroupChanged(); - } -} - -void QQuickVisualDataModel::resetFilterGroup() -{ - setFilterGroup(QStringLiteral("items")); -} - -void QQuickVisualDataModelPrivate::updateFilterGroup() -{ - Q_Q(QQuickVisualDataModel); - if (!m_cacheMetaType) - return; - - QQuickListCompositor::Group previousGroup = m_compositorGroup; - m_compositorGroup = Compositor::Default; - for (int i = 1; i < m_groupCount; ++i) { - if (m_filterGroup == m_cacheMetaType->groupNames.at(i - 1)) { - m_compositorGroup = Compositor::Group(i); - break; - } - } - - QQuickVisualDataGroupPrivate::get(m_groups[m_compositorGroup])->emitters.insert(this); - if (m_compositorGroup != previousGroup) { - QVector<QQuickChangeSet::Remove> removes; - QVector<QQuickChangeSet::Insert> inserts; - m_compositor.transition(previousGroup, m_compositorGroup, &removes, &inserts); - - QQuickChangeSet changeSet; - changeSet.move(removes, inserts); - emit q->modelUpdated(changeSet, false); - - if (changeSet.difference() != 0) - emit q->countChanged(); - - if (m_parts) { - foreach (QQuickVisualPartsModel *model, m_parts->models) - model->updateFilterGroup(m_compositorGroup, changeSet); - } - } -} - -/*! - \qmlproperty object QtQuick2::VisualDataModel::parts - - The \a parts property selects a VisualDataModel which creates - delegates from the part named. This is used in conjunction with - the \l Package type. - - For example, the code below selects a model which creates - delegates named \e list from a \l Package: - - \code - VisualDataModel { - id: visualModel - delegate: Package { - Item { Package.name: "list" } - } - model: myModel - } - - ListView { - width: 200; height:200 - model: visualModel.parts.list - } - \endcode - - \sa Package -*/ - -QObject *QQuickVisualDataModel::parts() -{ - Q_D(QQuickVisualDataModel); - if (!d->m_parts) - d->m_parts = new QQuickVisualDataModelParts(this); - return d->m_parts; -} - -void QQuickVisualDataModelPrivate::emitCreatedPackage(QVDMIncubationTask *incubationTask, QQuickPackage *package) -{ - for (int i = 1; i < m_groupCount; ++i) - QQuickVisualDataGroupPrivate::get(m_groups[i])->createdPackage(incubationTask->index[i], package); -} - -void QQuickVisualDataModelPrivate::emitInitPackage(QVDMIncubationTask *incubationTask, QQuickPackage *package) -{ - for (int i = 1; i < m_groupCount; ++i) - QQuickVisualDataGroupPrivate::get(m_groups[i])->initPackage(incubationTask->index[i], package); -} - -void QQuickVisualDataModelPrivate::emitDestroyingPackage(QQuickPackage *package) -{ - for (int i = 1; i < m_groupCount; ++i) - QQuickVisualDataGroupPrivate::get(m_groups[i])->destroyingPackage(package); -} - -void QVDMIncubationTask::statusChanged(Status status) -{ - vdm->incubatorStatusChanged(this, status); -} - -void QQuickVisualDataModelPrivate::releaseIncubator(QVDMIncubationTask *incubationTask) -{ - Q_Q(QQuickVisualDataModel); - if (!incubationTask->isError()) - incubationTask->clear(); - m_finishedIncubating.append(incubationTask); - if (!m_incubatorCleanupScheduled) { - m_incubatorCleanupScheduled = true; - QCoreApplication::postEvent(q, new QEvent(QEvent::User)); - } -} - -void QQuickVisualDataModelPrivate::removeCacheItem(QQuickVisualDataModelItem *cacheItem) -{ - int cidx = m_cache.indexOf(cacheItem); - if (cidx >= 0) { - m_compositor.clearFlags(Compositor::Cache, cidx, 1, Compositor::CacheFlag); - m_cache.removeAt(cidx); - } - Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache)); -} - -void QQuickVisualDataModelPrivate::incubatorStatusChanged(QVDMIncubationTask *incubationTask, QQmlIncubator::Status status) -{ - Q_Q(QQuickVisualDataModel); - if (status != QQmlIncubator::Ready && status != QQmlIncubator::Error) - return; - - QQuickVisualDataModelItem *cacheItem = incubationTask->incubating; - cacheItem->incubationTask = 0; - incubationTask->incubating = 0; - releaseIncubator(incubationTask); - - if (status == QQmlIncubator::Ready) { - if (QQuickItem *item = qmlobject_cast<QQuickItem *>(cacheItem->object)) - emitCreatedItem(incubationTask, item); - else if (QQuickPackage *package = qmlobject_cast<QQuickPackage *>(cacheItem->object)) - emitCreatedPackage(incubationTask, package); - } else if (status == QQmlIncubator::Error) { - qmlInfo(q, m_delegate->errors()) << "Error creating delegate"; - } - - if (!cacheItem->isObjectReferenced()) { - if (QQuickItem *item = qmlobject_cast<QQuickItem *>(cacheItem->object)) - emitDestroyingItem(item); - else if (QQuickPackage *package = qmlobject_cast<QQuickPackage *>(cacheItem->object)) - emitDestroyingPackage(package); - delete cacheItem->object; - cacheItem->object = 0; - cacheItem->scriptRef -= 1; - cacheItem->contextData->destroy(); - cacheItem->contextData = 0; - if (!cacheItem->isReferenced()) { - removeCacheItem(cacheItem); - delete cacheItem; - } - } -} - -void QVDMIncubationTask::setInitialState(QObject *o) -{ - vdm->setInitialState(this, o); -} - -void QQuickVisualDataModelPrivate::setInitialState(QVDMIncubationTask *incubationTask, QObject *o) -{ - QQuickVisualDataModelItem *cacheItem = incubationTask->incubating; - cacheItem->object = o; - - if (QQuickItem *item = qmlobject_cast<QQuickItem *>(cacheItem->object)) - emitInitItem(incubationTask, item); - else if (QQuickPackage *package = qmlobject_cast<QQuickPackage *>(cacheItem->object)) - emitInitPackage(incubationTask, package); -} - -QObject *QQuickVisualDataModelPrivate::object(Compositor::Group group, int index, bool asynchronous) -{ - Q_Q(QQuickVisualDataModel); - if (!m_delegate || index < 0 || index >= m_compositor.count(group)) { - qWarning() << "VisualDataModel::item: index out range" << index << m_compositor.count(group); - return 0; - } else if (!m_context->isValid()) { - return 0; - } - - Compositor::iterator it = m_compositor.find(group, index); - - QQuickVisualDataModelItem *cacheItem = it->inCache() ? m_cache.at(it.cacheIndex) : 0; - - if (!cacheItem) { - cacheItem = m_adaptorModel.createItem(m_cacheMetaType, m_context->engine(), it.modelIndex()); - if (!cacheItem) - return 0; - - cacheItem->groups = it->flags; - - m_cache.insert(it.cacheIndex, cacheItem); - m_compositor.setFlags(it, 1, Compositor::CacheFlag); - Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache)); - } - - // Bump the reference counts temporarily so neither the content data or the delegate object - // are deleted if incubatorStatusChanged() is called synchronously. - cacheItem->scriptRef += 1; - cacheItem->referenceObject(); - - if (cacheItem->incubationTask) { - if (!asynchronous && cacheItem->incubationTask->incubationMode() == QQmlIncubator::Asynchronous) { - // previously requested async - now needed immediately - cacheItem->incubationTask->forceCompletion(); - } - } else if (!cacheItem->object) { - QQmlContext *creationContext = m_delegate->creationContext(); - - cacheItem->scriptRef += 1; - - cacheItem->incubationTask = new QVDMIncubationTask(this, asynchronous ? QQmlIncubator::Asynchronous : QQmlIncubator::AsynchronousIfNested); - cacheItem->incubationTask->incubating = cacheItem; - cacheItem->incubationTask->clear(); - - for (int i = 1; i < m_groupCount; ++i) - cacheItem->incubationTask->index[i] = it.index[i]; - - QQmlContextData *ctxt = new QQmlContextData; - ctxt->setParent(QQmlContextData::get(creationContext ? creationContext : m_context)); - ctxt->contextObject = cacheItem; - cacheItem->contextData = ctxt; - - if (m_adaptorModel.hasProxyObject()) { - if (QQuickVisualAdaptorModelProxyInterface *proxy - = qobject_cast<QQuickVisualAdaptorModelProxyInterface *>(cacheItem)) { - ctxt = new QQmlContextData; - ctxt->setParent(cacheItem->contextData, true); - ctxt->contextObject = proxy->proxiedObject(); - } - } - - cacheItem->incubateObject( - m_delegate, - m_context->engine(), - ctxt, - QQmlContextData::get(m_context)); - } - - if (index == m_compositor.count(group) - 1 && m_adaptorModel.canFetchMore()) - QCoreApplication::postEvent(q, new QEvent(QEvent::UpdateRequest)); - - // Remove the temporary reference count. - cacheItem->scriptRef -= 1; - if (cacheItem->object) - return cacheItem->object; - - cacheItem->releaseObject(); - if (!cacheItem->isReferenced()) { - removeCacheItem(cacheItem); - delete cacheItem; - } - - return 0; -} - -/* - If asynchronous is true or the component is being loaded asynchronously due - to an ancestor being loaded asynchronously, item() may return 0. In this - case itemCreated() will be emitted when the item is available. The item - at this stage does not have any references, so item() must be called again - to ensure a reference is held. Any call to item() which returns a valid item - must be matched by a call to release() in order to destroy the item. -*/ -QQuickItem *QQuickVisualDataModel::item(int index, bool asynchronous) -{ - Q_D(QQuickVisualDataModel); - if (!d->m_delegate || index < 0 || index >= d->m_compositor.count(d->m_compositorGroup)) { - qWarning() << "VisualDataModel::item: index out range" << index << d->m_compositor.count(d->m_compositorGroup); - return 0; - } - - QObject *object = d->object(d->m_compositorGroup, index, asynchronous); - if (!object) - return 0; - - if (QQuickItem *item = qmlobject_cast<QQuickItem *>(object)) - return item; - - d->release(object); - if (!d->m_delegateValidated) { - if (object) - qmlInfo(d->m_delegate) << QQuickVisualDataModel::tr("Delegate component must be Item type."); - d->m_delegateValidated = true; - } - return 0; -} - -QString QQuickVisualDataModelPrivate::stringValue(Compositor::Group group, int index, const QString &name) -{ - Compositor::iterator it = m_compositor.find(group, index); - if (QQuickVisualAdaptorModel *model = it.list<QQuickVisualAdaptorModel>()) { - QString role = name; - int dot = name.indexOf(QLatin1Char('.')); - if (dot > 0) - role = name.left(dot); - QVariant value = model->value(it.modelIndex(), role); - while (dot > 0) { - QObject *obj = qvariant_cast<QObject*>(value); - if (!obj) - return QString(); - int from = dot+1; - dot = name.indexOf(QLatin1Char('.'), from); - value = obj->property(name.mid(from, dot-from).toUtf8()); - } - return value.toString(); - } - return QString(); -} - -QString QQuickVisualDataModel::stringValue(int index, const QString &name) -{ - Q_D(QQuickVisualDataModel); - return d->stringValue(d->m_compositorGroup, index, name); -} - -int QQuickVisualDataModel::indexOf(QQuickItem *item, QObject *) const -{ - Q_D(const QQuickVisualDataModel); - if (QQuickVisualDataModelItem *cacheItem = QQuickVisualDataModelItem::dataForObject(item)) - return cacheItem->groupIndex(d->m_compositorGroup); - return -1; -} - -void QQuickVisualDataModel::setWatchedRoles(QList<QByteArray> roles) -{ - Q_D(QQuickVisualDataModel); - d->m_adaptorModel.replaceWatchedRoles(d->m_watchedRoles, roles); - d->m_watchedRoles = roles; -} - -void QQuickVisualDataModelPrivate::addGroups( - Compositor::iterator from, int count, Compositor::Group group, int groupFlags) -{ - QVector<Compositor::Insert> inserts; - m_compositor.setFlags(from, count, group, groupFlags, &inserts); - itemsInserted(inserts); - emitChanges(); -} - -void QQuickVisualDataModelPrivate::removeGroups( - Compositor::iterator from, int count, Compositor::Group group, int groupFlags) -{ - QVector<Compositor::Remove> removes; - m_compositor.clearFlags(from, count, group, groupFlags, &removes); - itemsRemoved(removes); - emitChanges(); -} - -void QQuickVisualDataModelPrivate::setGroups( - Compositor::iterator from, int count, Compositor::Group group, int groupFlags) -{ - QVector<Compositor::Remove> removes; - QVector<Compositor::Insert> inserts; - - m_compositor.setFlags(from, count, group, groupFlags, &inserts); - itemsInserted(inserts); - const int removeFlags = ~groupFlags & Compositor::GroupMask; - - from = m_compositor.find(from.group, from.index[from.group]); - m_compositor.clearFlags(from, count, group, removeFlags, &removes); - itemsRemoved(removes); - emitChanges(); -} - -bool QQuickVisualDataModel::event(QEvent *e) -{ - Q_D(QQuickVisualDataModel); - if (e->type() == QEvent::UpdateRequest) { - d->m_adaptorModel.fetchMore(); - } else if (e->type() == QEvent::User) { - d->m_incubatorCleanupScheduled = false; - qDeleteAll(d->m_finishedIncubating); - d->m_finishedIncubating.clear(); - } - return QQuickVisualModel::event(e); -} - -void QQuickVisualDataModelPrivate::itemsChanged(const QVector<Compositor::Change> &changes) -{ - if (!m_delegate) - return; - - QVarLengthArray<QVector<QQuickChangeSet::Change>, Compositor::MaximumGroupCount> translatedChanges(m_groupCount); - - foreach (const Compositor::Change &change, changes) { - for (int i = 1; i < m_groupCount; ++i) { - if (change.inGroup(i)) { - translatedChanges[i].append(QQuickChangeSet::Change(change.index[i], change.count)); - } - } - } - - for (int i = 1; i < m_groupCount; ++i) - QQuickVisualDataGroupPrivate::get(m_groups[i])->changeSet.change(translatedChanges.at(i)); -} - -void QQuickVisualDataModel::_q_itemsChanged(int index, int count, const QVector<int> &roles) -{ - Q_D(QQuickVisualDataModel); - if (count <= 0 || !d->m_complete) - return; - - if (d->m_adaptorModel.notify(d->m_cache, index, count, roles)) { - QVector<Compositor::Change> changes; - d->m_compositor.listItemsChanged(&d->m_adaptorModel, index, count, &changes); - d->itemsChanged(changes); - d->emitChanges(); - } -} - -static void incrementIndexes(QQuickVisualDataModelItem *cacheItem, int count, const int *deltas) -{ - if (QVDMIncubationTask *incubationTask = cacheItem->incubationTask) { - for (int i = 1; i < count; ++i) - incubationTask->index[i] += deltas[i]; - } - if (QQuickVisualDataModelAttached *attached = cacheItem->attached) { - for (int i = 1; i < count; ++i) - attached->m_currentIndex[i] += deltas[i]; - } -} - -void QQuickVisualDataModelPrivate::itemsInserted( - const QVector<Compositor::Insert> &inserts, - QVarLengthArray<QVector<QQuickChangeSet::Insert>, Compositor::MaximumGroupCount> *translatedInserts, - QHash<int, QList<QQuickVisualDataModelItem *> > *movedItems) -{ - int cacheIndex = 0; - - int inserted[Compositor::MaximumGroupCount]; - for (int i = 1; i < m_groupCount; ++i) - inserted[i] = 0; - - foreach (const Compositor::Insert &insert, inserts) { - for (; cacheIndex < insert.cacheIndex; ++cacheIndex) - incrementIndexes(m_cache.at(cacheIndex), m_groupCount, inserted); - - for (int i = 1; i < m_groupCount; ++i) { - if (insert.inGroup(i)) { - (*translatedInserts)[i].append( - QQuickChangeSet::Insert(insert.index[i], insert.count, insert.moveId)); - inserted[i] += insert.count; - } - } - - if (!insert.inCache()) - continue; - - if (movedItems && insert.isMove()) { - QList<QQuickVisualDataModelItem *> items = movedItems->take(insert.moveId); - Q_ASSERT(items.count() == insert.count); - m_cache = m_cache.mid(0, insert.cacheIndex) + items + m_cache.mid(insert.cacheIndex); - } - if (insert.inGroup()) { - for (int offset = 0; cacheIndex < insert.cacheIndex + insert.count; ++cacheIndex, ++offset) { - QQuickVisualDataModelItem *cacheItem = m_cache.at(cacheIndex); - cacheItem->groups |= insert.flags & Compositor::GroupMask; - - if (QVDMIncubationTask *incubationTask = cacheItem->incubationTask) { - for (int i = 1; i < m_groupCount; ++i) - incubationTask->index[i] = cacheItem->groups & (1 << i) - ? insert.index[i] + offset - : insert.index[i]; - } - if (QQuickVisualDataModelAttached *attached = cacheItem->attached) { - for (int i = 1; i < m_groupCount; ++i) - attached->m_currentIndex[i] = cacheItem->groups & (1 << i) - ? insert.index[i] + offset - : insert.index[i]; - } - } - } else { - cacheIndex = insert.cacheIndex + insert.count; - } - } - for (; cacheIndex < m_cache.count(); ++cacheIndex) - incrementIndexes(m_cache.at(cacheIndex), m_groupCount, inserted); -} - -void QQuickVisualDataModelPrivate::itemsInserted(const QVector<Compositor::Insert> &inserts) -{ - QVarLengthArray<QVector<QQuickChangeSet::Insert>, Compositor::MaximumGroupCount> translatedInserts(m_groupCount); - itemsInserted(inserts, &translatedInserts); - Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache)); - if (!m_delegate) - return; - - for (int i = 1; i < m_groupCount; ++i) - QQuickVisualDataGroupPrivate::get(m_groups[i])->changeSet.insert(translatedInserts.at(i)); -} - -void QQuickVisualDataModel::_q_itemsInserted(int index, int count) -{ - - Q_D(QQuickVisualDataModel); - if (count <= 0 || !d->m_complete) - return; - - d->m_count += count; - - for (int i = 0, c = d->m_cache.count(); i < c; ++i) { - QQuickVisualDataModelItem *item = d->m_cache.at(i); - if (item->modelIndex() >= index) - item->setModelIndex(item->modelIndex() + count); - } - - QVector<Compositor::Insert> inserts; - d->m_compositor.listItemsInserted(&d->m_adaptorModel, index, count, &inserts); - d->itemsInserted(inserts); - d->emitChanges(); -} - -void QQuickVisualDataModelPrivate::itemsRemoved( - const QVector<Compositor::Remove> &removes, - QVarLengthArray<QVector<QQuickChangeSet::Remove>, Compositor::MaximumGroupCount> *translatedRemoves, - QHash<int, QList<QQuickVisualDataModelItem *> > *movedItems) -{ - int cacheIndex = 0; - int removedCache = 0; - - int removed[Compositor::MaximumGroupCount]; - for (int i = 1; i < m_groupCount; ++i) - removed[i] = 0; - - foreach (const Compositor::Remove &remove, removes) { - for (; cacheIndex < remove.cacheIndex; ++cacheIndex) - incrementIndexes(m_cache.at(cacheIndex), m_groupCount, removed); - - for (int i = 1; i < m_groupCount; ++i) { - if (remove.inGroup(i)) { - (*translatedRemoves)[i].append( - QQuickChangeSet::Remove(remove.index[i], remove.count, remove.moveId)); - removed[i] -= remove.count; - } - } - - if (!remove.inCache()) - continue; - - if (movedItems && remove.isMove()) { - movedItems->insert(remove.moveId, m_cache.mid(remove.cacheIndex, remove.count)); - QList<QQuickVisualDataModelItem *>::iterator begin = m_cache.begin() + remove.cacheIndex; - QList<QQuickVisualDataModelItem *>::iterator end = begin + remove.count; - m_cache.erase(begin, end); - } else { - for (; cacheIndex < remove.cacheIndex + remove.count - removedCache; ++cacheIndex) { - QQuickVisualDataModelItem *cacheItem = m_cache.at(cacheIndex); - if (remove.inGroup(Compositor::Persisted) && cacheItem->objectRef == 0 && cacheItem->object) { - QObject *object = cacheItem->object; - cacheItem->destroyObject(); - if (QQuickPackage *package = qmlobject_cast<QQuickPackage *>(object)) - emitDestroyingPackage(package); - else if (QQuickItem *item = qmlobject_cast<QQuickItem *>(object)) - emitDestroyingItem(item); - cacheItem->scriptRef -= 1; - } - if (!cacheItem->isReferenced()) { - m_compositor.clearFlags(Compositor::Cache, cacheIndex, 1, Compositor::CacheFlag); - m_cache.removeAt(cacheIndex); - delete cacheItem; - --cacheIndex; - ++removedCache; - Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache)); - } else if (remove.groups() == cacheItem->groups) { - cacheItem->groups = 0; - if (QVDMIncubationTask *incubationTask = cacheItem->incubationTask) { - for (int i = 1; i < m_groupCount; ++i) - incubationTask->index[i] = -1; - } - if (QQuickVisualDataModelAttached *attached = cacheItem->attached) { - for (int i = 1; i < m_groupCount; ++i) - attached->m_currentIndex[i] = -1; - } - } else { - if (QVDMIncubationTask *incubationTask = cacheItem->incubationTask) { - for (int i = 1; i < m_groupCount; ++i) { - if (remove.inGroup(i)) - incubationTask->index[i] = remove.index[i]; - } - } - if (QQuickVisualDataModelAttached *attached = cacheItem->attached) { - for (int i = 1; i < m_groupCount; ++i) { - if (remove.inGroup(i)) - attached->m_currentIndex[i] = remove.index[i]; - } - } - cacheItem->groups &= ~remove.flags; - } - } - } - } - - for (; cacheIndex < m_cache.count(); ++cacheIndex) - incrementIndexes(m_cache.at(cacheIndex), m_groupCount, removed); -} - -void QQuickVisualDataModelPrivate::itemsRemoved(const QVector<Compositor::Remove> &removes) -{ - QVarLengthArray<QVector<QQuickChangeSet::Remove>, Compositor::MaximumGroupCount> translatedRemoves(m_groupCount); - itemsRemoved(removes, &translatedRemoves); - Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache)); - if (!m_delegate) - return; - - for (int i = 1; i < m_groupCount; ++i) - QQuickVisualDataGroupPrivate::get(m_groups[i])->changeSet.remove(translatedRemoves.at(i)); -} - -void QQuickVisualDataModel::_q_itemsRemoved(int index, int count) -{ - Q_D(QQuickVisualDataModel); - if (count <= 0|| !d->m_complete) - return; - - d->m_count -= count; - - for (int i = 0, c = d->m_cache.count(); i < c; ++i) { - QQuickVisualDataModelItem *item = d->m_cache.at(i); - if (item->modelIndex() >= index + count) - item->setModelIndex(item->modelIndex() - count); - else if (item->modelIndex() >= index) - item->setModelIndex(-1); - } - - QVector<Compositor::Remove> removes; - d->m_compositor.listItemsRemoved(&d->m_adaptorModel, index, count, &removes); - d->itemsRemoved(removes); - - d->emitChanges(); -} - -void QQuickVisualDataModelPrivate::itemsMoved( - const QVector<Compositor::Remove> &removes, const QVector<Compositor::Insert> &inserts) -{ - QHash<int, QList<QQuickVisualDataModelItem *> > movedItems; - - QVarLengthArray<QVector<QQuickChangeSet::Remove>, Compositor::MaximumGroupCount> translatedRemoves(m_groupCount); - itemsRemoved(removes, &translatedRemoves, &movedItems); - - QVarLengthArray<QVector<QQuickChangeSet::Insert>, Compositor::MaximumGroupCount> translatedInserts(m_groupCount); - itemsInserted(inserts, &translatedInserts, &movedItems); - Q_ASSERT(m_cache.count() == m_compositor.count(Compositor::Cache)); - Q_ASSERT(movedItems.isEmpty()); - if (!m_delegate) - return; - - for (int i = 1; i < m_groupCount; ++i) { - QQuickVisualDataGroupPrivate::get(m_groups[i])->changeSet.move( - translatedRemoves.at(i), - translatedInserts.at(i)); - } -} - -void QQuickVisualDataModel::_q_itemsMoved(int from, int to, int count) -{ - Q_D(QQuickVisualDataModel); - if (count <= 0 || !d->m_complete) - return; - - const int minimum = qMin(from, to); - const int maximum = qMax(from, to) + count; - const int difference = from > to ? count : -count; - - for (int i = 0, c = d->m_cache.count(); i < c; ++i) { - QQuickVisualDataModelItem *item = d->m_cache.at(i); - if (item->modelIndex() >= from && item->modelIndex() < from + count) - item->setModelIndex(item->modelIndex() - from + to); - else if (item->modelIndex() >= minimum && item->modelIndex() < maximum) - item->setModelIndex(item->modelIndex() + difference); - } - - QVector<Compositor::Remove> removes; - QVector<Compositor::Insert> inserts; - d->m_compositor.listItemsMoved(&d->m_adaptorModel, from, to, count, &removes, &inserts); - d->itemsMoved(removes, inserts); - d->emitChanges(); -} - -template <typename T> v8::Local<v8::Array> -QQuickVisualDataModelPrivate::buildChangeList(const QVector<T> &changes) -{ - v8::Local<v8::Array> indexes = v8::Array::New(changes.count()); - v8::Local<v8::String> indexKey = v8::String::New("index"); - v8::Local<v8::String> countKey = v8::String::New("count"); - v8::Local<v8::String> moveIdKey = v8::String::New("moveId"); - - for (int i = 0; i < changes.count(); ++i) { - v8::Local<v8::Object> object = v8::Object::New(); - object->Set(indexKey, v8::Integer::New(changes.at(i).index)); - object->Set(countKey, v8::Integer::New(changes.at(i).count)); - object->Set(moveIdKey, changes.at(i).moveId != -1 ? v8::Integer::New(changes.at(i).count) : v8::Undefined()); - indexes->Set(i, object); - } - return indexes; -} - -void QQuickVisualDataModelPrivate::emitModelUpdated(const QQuickChangeSet &changeSet, bool reset) -{ - Q_Q(QQuickVisualDataModel); - emit q->modelUpdated(changeSet, reset); - if (changeSet.difference() != 0) - emit q->countChanged(); -} - -void QQuickVisualDataModelPrivate::emitChanges() -{ - if (m_transaction || !m_complete || !m_context->isValid()) - return; - - m_transaction = true; - QV8Engine *engine = QQmlEnginePrivate::getV8Engine(m_context->engine()); - for (int i = 1; i < m_groupCount; ++i) - QQuickVisualDataGroupPrivate::get(m_groups[i])->emitChanges(engine); - m_transaction = false; - - const bool reset = m_reset; - m_reset = false; - for (int i = 1; i < m_groupCount; ++i) - QQuickVisualDataGroupPrivate::get(m_groups[i])->emitModelUpdated(reset); - - foreach (QQuickVisualDataModelItem *cacheItem, m_cache) { - if (cacheItem->attached) - cacheItem->attached->emitChanges(); - } -} - -void QQuickVisualDataModel::_q_modelReset() -{ - Q_D(QQuickVisualDataModel); - if (!d->m_delegate) - return; - - int oldCount = d->m_count; - d->m_adaptorModel.rootIndex = QModelIndex(); - - if (d->m_complete) { - d->m_count = d->m_adaptorModel.count(); - - for (int i = 0, c = d->m_cache.count(); i < c; ++i) { - QQuickVisualDataModelItem *item = d->m_cache.at(i); - if (item->modelIndex() != -1) - item->setModelIndex(-1); - } - - QVector<Compositor::Remove> removes; - QVector<Compositor::Insert> inserts; - if (oldCount) - d->m_compositor.listItemsRemoved(&d->m_adaptorModel, 0, oldCount, &removes); - if (d->m_count) - d->m_compositor.listItemsInserted(&d->m_adaptorModel, 0, d->m_count, &inserts); - d->itemsMoved(removes, inserts); - d->m_reset = true; - - if (d->m_adaptorModel.canFetchMore()) - d->m_adaptorModel.fetchMore(); - - d->emitChanges(); - } - emit rootIndexChanged(); -} - -void QQuickVisualDataModel::_q_rowsInserted(const QModelIndex &parent, int begin, int end) -{ - Q_D(QQuickVisualDataModel); - if (parent == d->m_adaptorModel.rootIndex) - _q_itemsInserted(begin, end - begin + 1); -} - -void QQuickVisualDataModel::_q_rowsAboutToBeRemoved(const QModelIndex &parent, int begin, int end) -{ - Q_D(QQuickVisualDataModel); - if (!d->m_adaptorModel.rootIndex.isValid()) - return; - const QModelIndex index = d->m_adaptorModel.rootIndex; - if (index.parent() == parent && index.row() >= begin && index.row() <= end) { - const int oldCount = d->m_count; - d->m_count = 0; - d->m_adaptorModel.invalidateModel(this); - - if (d->m_complete && oldCount > 0) { - QVector<Compositor::Remove> removes; - d->m_compositor.listItemsRemoved(&d->m_adaptorModel, 0, oldCount, &removes); - d->itemsRemoved(removes); - d->emitChanges(); - } - } -} - -void QQuickVisualDataModel::_q_rowsRemoved(const QModelIndex &parent, int begin, int end) -{ - Q_D(QQuickVisualDataModel); - if (parent == d->m_adaptorModel.rootIndex) - _q_itemsRemoved(begin, end - begin + 1); -} - -void QQuickVisualDataModel::_q_rowsMoved( - const QModelIndex &sourceParent, int sourceStart, int sourceEnd, - const QModelIndex &destinationParent, int destinationRow) -{ - Q_D(QQuickVisualDataModel); - const int count = sourceEnd - sourceStart + 1; - if (destinationParent == d->m_adaptorModel.rootIndex && sourceParent == d->m_adaptorModel.rootIndex) { - _q_itemsMoved(sourceStart, sourceStart > destinationRow ? destinationRow : destinationRow - count, count); - } else if (sourceParent == d->m_adaptorModel.rootIndex) { - _q_itemsRemoved(sourceStart, count); - } else if (destinationParent == d->m_adaptorModel.rootIndex) { - _q_itemsInserted(destinationRow, count); - } -} - -void QQuickVisualDataModel::_q_dataChanged(const QModelIndex &begin, const QModelIndex &end, const QVector<int> &roles) -{ - Q_D(QQuickVisualDataModel); - if (begin.parent() == d->m_adaptorModel.rootIndex) - _q_itemsChanged(begin.row(), end.row() - begin.row() + 1, roles); -} - -void QQuickVisualDataModel::_q_layoutChanged() -{ - Q_D(QQuickVisualDataModel); - _q_itemsChanged(0, d->m_count, QVector<int>()); -} - -QQuickVisualDataModelAttached *QQuickVisualDataModel::qmlAttachedProperties(QObject *obj) -{ - if (QQuickVisualDataModelItem *cacheItem = QQuickVisualDataModelItem::dataForObject(obj)) { - if (cacheItem->object == obj) { // Don't create attached item for child objects. - cacheItem->attached = new QQuickVisualDataModelAttached(cacheItem, obj); - return cacheItem->attached; - } - } - return new QQuickVisualDataModelAttached(obj); -} - -bool QQuickVisualDataModelPrivate::insert( - Compositor::insert_iterator &before, const v8::Local<v8::Object> &object, int groups) -{ - if (!m_context->isValid()) - return false; - - QQuickVisualDataModelItem *cacheItem = m_adaptorModel.createItem(m_cacheMetaType, m_context->engine(), -1); - if (!cacheItem) - return false; - - v8::Local<v8::Array> propertyNames = object->GetPropertyNames(); - for (uint i = 0; i < propertyNames->Length(); ++i) { - v8::Local<v8::String> propertyName = propertyNames->Get(i)->ToString(); - cacheItem->setValue( - m_cacheMetaType->v8Engine->toString(propertyName), - m_cacheMetaType->v8Engine->toVariant(object->Get(propertyName), QVariant::Invalid)); - } - - cacheItem->groups = groups | Compositor::UnresolvedFlag | Compositor::CacheFlag; - - // Must be before the new object is inserted into the cache or its indexes will be adjusted too. - itemsInserted(QVector<Compositor::Insert>() << Compositor::Insert(before, 1, cacheItem->groups & ~Compositor::CacheFlag)); - - before = m_compositor.insert(before, 0, 0, 1, cacheItem->groups); - m_cache.insert(before.cacheIndex, cacheItem); - - return true; -} - -//============================================================================ - -QQuickVisualDataModelItemMetaType::QQuickVisualDataModelItemMetaType( - QV8Engine *engine, QQuickVisualDataModel *model, const QStringList &groupNames) - : model(model) - , groupCount(groupNames.count() + 1) - , v8Engine(engine) - , metaObject(0) - , groupNames(groupNames) -{ -} - -QQuickVisualDataModelItemMetaType::~QQuickVisualDataModelItemMetaType() -{ - if (metaObject) - metaObject->release(); - qPersistentDispose(constructor); -} - -void QQuickVisualDataModelItemMetaType::initializeMetaObject() -{ - QMetaObjectBuilder builder; - builder.setFlags(QMetaObjectBuilder::DynamicMetaObject); - builder.setClassName(QQuickVisualDataModelAttached::staticMetaObject.className()); - builder.setSuperClass(&QQuickVisualDataModelAttached::staticMetaObject); - - int notifierId = 0; - for (int i = 0; i < groupNames.count(); ++i, ++notifierId) { - QString propertyName = QStringLiteral("in") + groupNames.at(i); - propertyName.replace(2, 1, propertyName.at(2).toUpper()); - builder.addSignal("__" + propertyName.toUtf8() + "Changed()"); - QMetaPropertyBuilder propertyBuilder = builder.addProperty( - propertyName.toUtf8(), "bool", notifierId); - propertyBuilder.setWritable(true); - } - for (int i = 0; i < groupNames.count(); ++i, ++notifierId) { - const QString propertyName = groupNames.at(i) + QStringLiteral("Index"); - builder.addSignal("__" + propertyName.toUtf8() + "Changed()"); - QMetaPropertyBuilder propertyBuilder = builder.addProperty( - propertyName.toUtf8(), "int", notifierId); - propertyBuilder.setWritable(true); - } - - metaObject = new QQuickVisualDataModelAttachedMetaObject(this, builder.toMetaObject()); -} - -void QQuickVisualDataModelItemMetaType::initializeConstructor() -{ - v8::HandleScope handleScope; - v8::Context::Scope contextScope(v8Engine->context()); - - QQuickVisualDataModelEngineData *data = engineData(v8Engine); - - constructor = qPersistentNew(v8::ObjectTemplate::New()); - - constructor->SetHasExternalResource(true); - constructor->SetAccessor(data->model(), get_model); - constructor->SetAccessor(data->groups(), get_groups, set_groups); - constructor->SetAccessor(data->isUnresolved(), get_member, 0, v8::Int32::New(30)); - constructor->SetAccessor(data->inItems(), get_member, set_member, v8::Int32::New(1)); - constructor->SetAccessor(data->inPersistedItems(), get_member, set_member, v8::Int32::New(2)); - constructor->SetAccessor(data->itemsIndex(), get_index, 0, v8::Int32::New(1)); - constructor->SetAccessor(data->persistedItemsIndex(), get_index, 0, v8::Int32::New(2)); - - for (int i = 2; i < groupNames.count(); ++i) { - QString propertyName = QStringLiteral("in") + groupNames.at(i); - propertyName.replace(2, 1, propertyName.at(2).toUpper()); - constructor->SetAccessor( - v8Engine->toString(propertyName), get_member, set_member, v8::Int32::New(i + 1)); - } - for (int i = 2; i < groupNames.count(); ++i) { - const QString propertyName = groupNames.at(i) + QStringLiteral("Index"); - constructor->SetAccessor( - v8Engine->toString(propertyName), get_index, 0, v8::Int32::New(i + 1)); - } -} - -int QQuickVisualDataModelItemMetaType::parseGroups(const QStringList &groups) const -{ - int groupFlags = 0; - foreach (const QString &groupName, groups) { - int index = groupNames.indexOf(groupName); - if (index != -1) - groupFlags |= 2 << index; - } - return groupFlags; -} - -int QQuickVisualDataModelItemMetaType::parseGroups(const v8::Local<v8::Value> &groups) const -{ - int groupFlags = 0; - if (groups->IsString()) { - const QString groupName = v8Engine->toString(groups); - int index = groupNames.indexOf(groupName); - if (index != -1) - groupFlags |= 2 << index; - } else if (groups->IsArray()) { - v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(groups); - for (uint i = 0; i < array->Length(); ++i) { - const QString groupName = v8Engine->toString(array->Get(i)); - int index = groupNames.indexOf(groupName); - if (index != -1) - groupFlags |= 2 << index; - } - } - return groupFlags; -} - -v8::Handle<v8::Value> QQuickVisualDataModelItemMetaType::get_model( - v8::Local<v8::String>, const v8::AccessorInfo &info) -{ - QQuickVisualDataModelItem *cacheItem = v8_resource_cast<QQuickVisualDataModelItem>(info.This()); - V8ASSERT_TYPE(cacheItem, "Not a valid VisualData object"); - if (!cacheItem->metaType->model) - return v8::Undefined(); - - return cacheItem->get(); -} - -v8::Handle<v8::Value> QQuickVisualDataModelItemMetaType::get_groups( - v8::Local<v8::String>, const v8::AccessorInfo &info) -{ - QQuickVisualDataModelItem *cacheItem = v8_resource_cast<QQuickVisualDataModelItem>(info.This()); - V8ASSERT_TYPE(cacheItem, "Not a valid VisualData object"); - - QStringList groups; - for (int i = 1; i < cacheItem->metaType->groupCount; ++i) { - if (cacheItem->groups & (1 << i)) - groups.append(cacheItem->metaType->groupNames.at(i - 1)); - } - - return cacheItem->engine->fromVariant(groups); -} - -void QQuickVisualDataModelItemMetaType::set_groups( - v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info) -{ - QQuickVisualDataModelItem *cacheItem = v8_resource_cast<QQuickVisualDataModelItem>(info.This()); - V8ASSERT_TYPE_SETTER(cacheItem, "Not a valid VisualData object"); - - if (!cacheItem->metaType->model) - return; - QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(cacheItem->metaType->model); - - const int groupFlags = model->m_cacheMetaType->parseGroups(value); - const int cacheIndex = model->m_cache.indexOf(cacheItem); - Compositor::iterator it = model->m_compositor.find(Compositor::Cache, cacheIndex); - model->setGroups(it, 1, Compositor::Cache, groupFlags); -} - -v8::Handle<v8::Value> QQuickVisualDataModelItemMetaType::get_member( - v8::Local<v8::String>, const v8::AccessorInfo &info) -{ - QQuickVisualDataModelItem *cacheItem = v8_resource_cast<QQuickVisualDataModelItem>(info.This()); - V8ASSERT_TYPE(cacheItem, "Not a valid VisualData object"); - - return v8::Boolean::New(cacheItem->groups & (1 << info.Data()->Int32Value())); -} - -void QQuickVisualDataModelItemMetaType::set_member( - v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info) -{ - QQuickVisualDataModelItem *cacheItem = v8_resource_cast<QQuickVisualDataModelItem>(info.This()); - V8ASSERT_TYPE_SETTER(cacheItem, "Not a valid VisualData object"); - - if (!cacheItem->metaType->model) - return; - QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(cacheItem->metaType->model); - - Compositor::Group group = Compositor::Group(info.Data()->Int32Value()); - const bool member = value->BooleanValue(); - const int groupFlag = (1 << group); - if (member == ((cacheItem->groups & groupFlag) != 0)) - return; - - const int cacheIndex = model->m_cache.indexOf(cacheItem); - Compositor::iterator it = model->m_compositor.find(Compositor::Cache, cacheIndex); - if (member) - model->addGroups(it, 1, Compositor::Cache, groupFlag); - else - model->removeGroups(it, 1, Compositor::Cache, groupFlag); -} - -v8::Handle<v8::Value> QQuickVisualDataModelItemMetaType::get_index( - v8::Local<v8::String>, const v8::AccessorInfo &info) -{ - QQuickVisualDataModelItem *cacheItem = v8_resource_cast<QQuickVisualDataModelItem>(info.This()); - V8ASSERT_TYPE(cacheItem, "Not a valid VisualData object"); - - return v8::Integer::New(cacheItem->groupIndex(Compositor::Group(info.Data()->Int32Value()))); -} - - -//--------------------------------------------------------------------------- - -QQuickVisualDataModelItem::QQuickVisualDataModelItem( - QQuickVisualDataModelItemMetaType *metaType, int modelIndex) - : QV8ObjectResource(metaType->v8Engine) - , metaType(metaType) - , contextData(0) - , object(0) - , attached(0) - , incubationTask(0) - , objectRef(0) - , scriptRef(0) - , groups(0) - , index(modelIndex) -{ - metaType->addref(); -} - -QQuickVisualDataModelItem::~QQuickVisualDataModelItem() -{ - Q_ASSERT(scriptRef == 0); - Q_ASSERT(objectRef == 0); - Q_ASSERT(!object); - - if (incubationTask && metaType->model) - QQuickVisualDataModelPrivate::get(metaType->model)->releaseIncubator(incubationTask); - - metaType->release(); - -} - -void QQuickVisualDataModelItem::Dispose() -{ - --scriptRef; - if (isReferenced()) - return; - - if (metaType->model) { - QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(metaType->model); - model->removeCacheItem(this); - } - delete this; -} - -/* - This is essentially a copy of QQmlComponent::create(); except it takes the QQmlContextData - arguments instead of QQmlContext which means we don't have to construct the rather weighty - wrapper class for every delegate item. -*/ -void QQuickVisualDataModelItem::incubateObject( - QQmlComponent *component, - QQmlEngine *engine, - QQmlContextData *context, - QQmlContextData *forContext) -{ - QQmlIncubatorPrivate *incubatorPriv = QQmlIncubatorPrivate::get(incubationTask); - QQmlEnginePrivate *enginePriv = QQmlEnginePrivate::get(engine); - QQmlComponentPrivate *componentPriv = QQmlComponentPrivate::get(component); - - incubatorPriv->compiledData = componentPriv->cc; - incubatorPriv->compiledData->addref(); - incubatorPriv->vme.init( - context, - componentPriv->cc, - componentPriv->start, - componentPriv->creationContext); - - enginePriv->incubate(*incubationTask, forContext); -} - -void QQuickVisualDataModelItem::destroyObject() -{ - Q_ASSERT(object); - Q_ASSERT(contextData); - - QObjectPrivate *p = QObjectPrivate::get(object); - Q_ASSERT(p->declarativeData); - QQmlData *data = static_cast<QQmlData*>(p->declarativeData); - if (data->ownContext && data->context) - data->context->clearContext(); - object->deleteLater(); - - if (attached) { - attached->m_cacheItem = 0; - attached = 0; - } - - contextData->destroy(); - contextData = 0; - object = 0; -} - -QQuickVisualDataModelItem *QQuickVisualDataModelItem::dataForObject(QObject *object) -{ - QObjectPrivate *p = QObjectPrivate::get(object); - QQmlContextData *context = p->declarativeData - ? static_cast<QQmlData *>(p->declarativeData)->context - : 0; - for (context = context ? context->parent : 0; context; context = context->parent) { - if (QQuickVisualDataModelItem *cacheItem = qobject_cast<QQuickVisualDataModelItem *>( - context->contextObject)) { - return cacheItem; - } - } - return 0; -} - -int QQuickVisualDataModelItem::groupIndex(Compositor::Group group) -{ - if (QQuickVisualDataModelPrivate * const model = metaType->model - ? QQuickVisualDataModelPrivate::get(metaType->model) - : 0) { - return model->m_compositor.find(Compositor::Cache, model->m_cache.indexOf(this)).index[group]; - } - return -1; -} - -//--------------------------------------------------------------------------- - -QQuickVisualDataModelAttachedMetaObject::QQuickVisualDataModelAttachedMetaObject( - QQuickVisualDataModelItemMetaType *metaType, QMetaObject *metaObject) - : metaType(metaType) - , metaObject(metaObject) - , memberPropertyOffset(QQuickVisualDataModelAttached::staticMetaObject.propertyCount()) - , indexPropertyOffset(QQuickVisualDataModelAttached::staticMetaObject.propertyCount() + metaType->groupNames.count()) -{ - // Don't reference count the meta-type here as that would create a circular reference. - // Instead we rely the fact that the meta-type's reference count can't reach 0 without first - // destroying all delegates with attached objects. - *static_cast<QMetaObject *>(this) = *metaObject; -} - -QQuickVisualDataModelAttachedMetaObject::~QQuickVisualDataModelAttachedMetaObject() -{ - ::free(metaObject); -} - -void QQuickVisualDataModelAttachedMetaObject::objectDestroyed(QObject *) -{ - release(); -} - -int QQuickVisualDataModelAttachedMetaObject::metaCall(QObject *object, QMetaObject::Call call, int _id, void **arguments) -{ - QQuickVisualDataModelAttached *attached = static_cast<QQuickVisualDataModelAttached *>(object); - if (call == QMetaObject::ReadProperty) { - if (_id >= indexPropertyOffset) { - Compositor::Group group = Compositor::Group(_id - indexPropertyOffset + 1); - *static_cast<int *>(arguments[0]) = attached->m_currentIndex[group]; - return -1; - } else if (_id >= memberPropertyOffset) { - Compositor::Group group = Compositor::Group(_id - memberPropertyOffset + 1); - *static_cast<bool *>(arguments[0]) = attached->m_cacheItem->groups & (1 << group); - return -1; - } - } else if (call == QMetaObject::WriteProperty) { - if (_id >= memberPropertyOffset) { - if (!metaType->model) - return -1; - QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(metaType->model); - Compositor::Group group = Compositor::Group(_id - memberPropertyOffset + 1); - const int groupFlag = 1 << group; - const bool member = attached->m_cacheItem->groups & groupFlag; - if (member && !*static_cast<bool *>(arguments[0])) { - Compositor::iterator it = model->m_compositor.find( - group, attached->m_currentIndex[group]); - model->removeGroups(it, 1, group, groupFlag); - } else if (!member && *static_cast<bool *>(arguments[0])) { - for (int i = 1; i < metaType->groupCount; ++i) { - if (attached->m_cacheItem->groups & (1 << i)) { - Compositor::iterator it = model->m_compositor.find( - Compositor::Group(i), attached->m_currentIndex[i]); - model->addGroups(it, 1, Compositor::Group(i), groupFlag); - break; - } - } - } - return -1; - } - } - return attached->qt_metacall(call, _id, arguments); -} - -QQuickVisualDataModelAttached::QQuickVisualDataModelAttached(QObject *parent) - : m_cacheItem(0) - , m_previousGroups(0) -{ - QQml_setParent_noEvent(this, parent); -} - -QQuickVisualDataModelAttached::QQuickVisualDataModelAttached( - QQuickVisualDataModelItem *cacheItem, QObject *parent) - : m_cacheItem(cacheItem) - , m_previousGroups(cacheItem->groups) -{ - QQml_setParent_noEvent(this, parent); - if (QVDMIncubationTask *incubationTask = m_cacheItem->incubationTask) { - for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i) - m_currentIndex[i] = m_previousIndex[i] = incubationTask->index[i]; - } else { - QQuickVisualDataModelPrivate * const model = QQuickVisualDataModelPrivate::get(m_cacheItem->metaType->model); - Compositor::iterator it = model->m_compositor.find( - Compositor::Cache, model->m_cache.indexOf(m_cacheItem)); - for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i) - m_currentIndex[i] = m_previousIndex[i] = it.index[i]; - } - - if (!cacheItem->metaType->metaObject) - cacheItem->metaType->initializeMetaObject(); - - QObjectPrivate::get(this)->metaObject = cacheItem->metaType->metaObject; - cacheItem->metaType->metaObject->addref(); -} - -/*! - \qmlattachedproperty int QtQuick2::VisualDataModel::model - - This attached property holds the visual data model this delegate instance belongs to. - - It is attached to each instance of the delegate. -*/ - -QQuickVisualDataModel *QQuickVisualDataModelAttached::model() const -{ - return m_cacheItem ? m_cacheItem->metaType->model : 0; -} - -/*! - \qmlattachedproperty stringlist QtQuick2::VisualDataModel::groups - - This attached property holds the name of VisualDataGroups the item belongs to. - - It is attached to each instance of the delegate. -*/ - -QStringList QQuickVisualDataModelAttached::groups() const -{ - QStringList groups; - - if (!m_cacheItem) - return groups; - for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i) { - if (m_cacheItem->groups & (1 << i)) - groups.append(m_cacheItem->metaType->groupNames.at(i - 1)); - } - return groups; -} - -void QQuickVisualDataModelAttached::setGroups(const QStringList &groups) -{ - if (!m_cacheItem) - return; - - QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(m_cacheItem->metaType->model); - - const int groupFlags = model->m_cacheMetaType->parseGroups(groups); - const int cacheIndex = model->m_cache.indexOf(m_cacheItem); - Compositor::iterator it = model->m_compositor.find(Compositor::Cache, cacheIndex); - model->setGroups(it, 1, Compositor::Cache, groupFlags); -} - -/*! - \qmlattachedproperty bool QtQuick2::VisualDataModel::isUnresolved - - This attached property holds whether the visual item is bound to a data model index. - Returns true if the item is not bound to the model, and false if it is. - - An unresolved item can be bound to the data model using the VisualDataGroup::resolve() - function. - - It is attached to each instance of the delegate. -*/ - -bool QQuickVisualDataModelAttached::isUnresolved() const -{ - if (!m_cacheItem) - return false; - - return m_cacheItem->groups & Compositor::UnresolvedFlag; -} - -/*! - \qmlattachedproperty int QtQuick2::VisualDataModel::inItems - - This attached property holds whether the item belongs to the default \l items VisualDataGroup. - - Changing this property will add or remove the item from the items group. - - It is attached to each instance of the delegate. -*/ - -/*! - \qmlattachedproperty int QtQuick2::VisualDataModel::itemsIndex - - This attached property holds the index of the item in the default \l items VisualDataGroup. - - It is attached to each instance of the delegate. -*/ - -/*! - \qmlattachedproperty int QtQuick2::VisualDataModel::inPersistedItems - - This attached property holds whether the item belongs to the \l persistedItems VisualDataGroup. - - Changing this property will add or remove the item from the items group. Change with caution - as removing an item from the persistedItems group will destroy the current instance if it is - not referenced by a model. - - It is attached to each instance of the delegate. -*/ - -/*! - \qmlattachedproperty int QtQuick2::VisualDataModel::persistedItemsIndex - - This attached property holds the index of the item in the \l persistedItems VisualDataGroup. - - It is attached to each instance of the delegate. -*/ - -void QQuickVisualDataModelAttached::emitChanges() -{ - const int groupChanges = m_previousGroups ^ m_cacheItem->groups; - m_previousGroups = m_cacheItem->groups; - - int indexChanges = 0; - for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i) { - if (m_previousIndex[i] != m_currentIndex[i]) { - m_previousIndex[i] = m_currentIndex[i]; - indexChanges |= (1 << i); - } - } - - int notifierId = 0; - const QMetaObject *meta = metaObject(); - for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i, ++notifierId) { - if (groupChanges & (1 << i)) - QMetaObject::activate(this, meta, notifierId, 0); - } - for (int i = 1; i < m_cacheItem->metaType->groupCount; ++i, ++notifierId) { - if (indexChanges & (1 << i)) - QMetaObject::activate(this, meta, notifierId, 0); - } - - if (groupChanges) - emit groupsChanged(); -} - -//============================================================================ - -void QQuickVisualDataGroupPrivate::setModel(QQuickVisualDataModel *m, Compositor::Group g) -{ - Q_ASSERT(!model); - model = m; - group = g; -} - -bool QQuickVisualDataGroupPrivate::isChangedConnected() -{ - Q_Q(QQuickVisualDataGroup); - IS_SIGNAL_CONNECTED(q, QQuickVisualDataGroup, changed, (const QQmlV8Handle &,const QQmlV8Handle &)); -} - -void QQuickVisualDataGroupPrivate::emitChanges(QV8Engine *engine) -{ - Q_Q(QQuickVisualDataGroup); - if (isChangedConnected() && !changeSet.isEmpty()) { - v8::HandleScope handleScope; - v8::Context::Scope contextScope(engine->context()); - v8::Local<v8::Object> removed = engineData(engine)->array(engine, changeSet.removes()); - v8::Local<v8::Object> inserted = engineData(engine)->array(engine, changeSet.inserts()); - emit q->changed(QQmlV8Handle::fromHandle(removed), QQmlV8Handle::fromHandle(inserted)); - } - if (changeSet.difference() != 0) - emit q->countChanged(); -} - -void QQuickVisualDataGroupPrivate::emitModelUpdated(bool reset) -{ - for (QQuickVisualDataGroupEmitterList::iterator it = emitters.begin(); it != emitters.end(); ++it) - it->emitModelUpdated(changeSet, reset); - changeSet.clear(); -} - -void QQuickVisualDataGroupPrivate::createdPackage(int index, QQuickPackage *package) -{ - for (QQuickVisualDataGroupEmitterList::iterator it = emitters.begin(); it != emitters.end(); ++it) - it->createdPackage(index, package); -} - -void QQuickVisualDataGroupPrivate::initPackage(int index, QQuickPackage *package) -{ - for (QQuickVisualDataGroupEmitterList::iterator it = emitters.begin(); it != emitters.end(); ++it) - it->initPackage(index, package); -} - -void QQuickVisualDataGroupPrivate::destroyingPackage(QQuickPackage *package) -{ - for (QQuickVisualDataGroupEmitterList::iterator it = emitters.begin(); it != emitters.end(); ++it) - it->destroyingPackage(package); -} - -/*! - \qmltype VisualDataGroup - \instantiates QQuickVisualDataGroup - \inqmlmodule QtQuick 2 - \ingroup qtquick-models - \brief Encapsulates a filtered set of visual data items - - The VisualDataGroup type provides a means to address the model data of a VisualDataModel's - delegate items, as well as sort and filter these delegate items. - - The initial set of instantiable delegate items in a VisualDataModel is represented - by its \l {QtQuick2::VisualDataModel::items}{items} group, which normally directly reflects - the contents of the model assigned to VisualDataModel::model. This set can be changed to - the contents of any other member of VisualDataModel::groups by assigning the \l name of that - VisualDataGroup to the VisualDataModel::filterOnGroup property. - - The data of an item in a VisualDataGroup can be accessed using the get() function, which returns - information about group membership and indexes as well as model data. In combination - with the move() function this can be used to implement view sorting, with remove() to filter - items out of a view, or with setGroups() and \l Package delegates to categorize items into - different views. - - Data from models can be supplemented by inserting data directly into a VisualDataGroup - with the insert() function. This can be used to introduce mock items into a view, or - placeholder items that are later \l {resolve()}{resolved} to real model data when it becomes - available. - - Delegate items can also be be instantiated directly from a VisualDataGroup using the - create() function, making it possible to use VisualDataModel without an accompanying view - type or to cherry-pick specific items that should be instantiated irregardless of whether - they're currently within a view's visible area. - - \sa {QML Dynamic View Ordering Tutorial} -*/ - -QQuickVisualDataGroup::QQuickVisualDataGroup(QObject *parent) - : QObject(*new QQuickVisualDataGroupPrivate, parent) -{ -} - -QQuickVisualDataGroup::QQuickVisualDataGroup( - const QString &name, QQuickVisualDataModel *model, int index, QObject *parent) - : QObject(*new QQuickVisualDataGroupPrivate, parent) -{ - Q_D(QQuickVisualDataGroup); - d->name = name; - d->setModel(model, Compositor::Group(index)); -} - -QQuickVisualDataGroup::~QQuickVisualDataGroup() -{ -} - -/*! - \qmlproperty string QtQuick2::VisualDataGroup::name - - This property holds the name of the group. - - Each group in a model must have a unique name starting with a lower case letter. -*/ - -QString QQuickVisualDataGroup::name() const -{ - Q_D(const QQuickVisualDataGroup); - return d->name; -} - -void QQuickVisualDataGroup::setName(const QString &name) -{ - Q_D(QQuickVisualDataGroup); - if (d->model) - return; - if (d->name != name) { - d->name = name; - emit nameChanged(); - } -} - -/*! - \qmlproperty int QtQuick2::VisualDataGroup::count - - This property holds the number of items in the group. -*/ - -int QQuickVisualDataGroup::count() const -{ - Q_D(const QQuickVisualDataGroup); - if (!d->model) - return 0; - return QQuickVisualDataModelPrivate::get(d->model)->m_compositor.count(d->group); -} - -/*! - \qmlproperty bool QtQuick2::VisualDataGroup::includeByDefault - - This property holds whether new items are assigned to this group by default. -*/ - -bool QQuickVisualDataGroup::defaultInclude() const -{ - Q_D(const QQuickVisualDataGroup); - return d->defaultInclude; -} - -void QQuickVisualDataGroup::setDefaultInclude(bool include) -{ - Q_D(QQuickVisualDataGroup); - if (d->defaultInclude != include) { - d->defaultInclude = include; - - if (d->model) { - if (include) - QQuickVisualDataModelPrivate::get(d->model)->m_compositor.setDefaultGroup(d->group); - else - QQuickVisualDataModelPrivate::get(d->model)->m_compositor.clearDefaultGroup(d->group); - } - emit defaultIncludeChanged(); - } -} - -/*! - \qmlmethod object QtQuick2::VisualDataGroup::get(int index) - - Returns a javascript object describing the item at \a index in the group. - - The returned object contains the same information that is available to a delegate from the - VisualDataModel attached as well as the model for that item. It has the properties: - - \list - \li \b model The model data of the item. This is the same as the model context property in - a delegate - \li \b groups A list the of names of groups the item is a member of. This property can be - written to change the item's membership. - \li \b inItems Whether the item belongs to the \l {QtQuick2::VisualDataModel::items}{items} group. - Writing to this property will add or remove the item from the group. - \li \b itemsIndex The index of the item within the \l {QtQuick2::VisualDataModel::items}{items} group. - \li \b {in<GroupName>} Whether the item belongs to the dynamic group \e groupName. Writing to - this property will add or remove the item from the group. - \li \b {<groupName>Index} The index of the item within the dynamic group \e groupName. - \li \b isUnresolved Whether the item is bound to an index in the model assigned to - VisualDataModel::model. Returns true if the item is not bound to the model, and false if it is. - \endlist -*/ - -QQmlV8Handle QQuickVisualDataGroup::get(int index) -{ - Q_D(QQuickVisualDataGroup); - if (!d->model) - return QQmlV8Handle::fromHandle(v8::Undefined());; - - QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(d->model); - if (!model->m_context->isValid()) { - return QQmlV8Handle::fromHandle(v8::Undefined()); - } else if (index < 0 || index >= model->m_compositor.count(d->group)) { - qmlInfo(this) << tr("get: index out of range"); - return QQmlV8Handle::fromHandle(v8::Undefined()); - } - - Compositor::iterator it = model->m_compositor.find(d->group, index); - QQuickVisualDataModelItem *cacheItem = it->inCache() - ? model->m_cache.at(it.cacheIndex) - : 0; - - if (!cacheItem) { - cacheItem = model->m_adaptorModel.createItem( - model->m_cacheMetaType, model->m_context->engine(), it.modelIndex()); - if (!cacheItem) - return QQmlV8Handle::fromHandle(v8::Undefined()); - cacheItem->groups = it->flags; - - model->m_cache.insert(it.cacheIndex, cacheItem); - model->m_compositor.setFlags(it, 1, Compositor::CacheFlag); - } - - if (model->m_cacheMetaType->constructor.IsEmpty()) - model->m_cacheMetaType->initializeConstructor(); - v8::Local<v8::Object> handle = model->m_cacheMetaType->constructor->NewInstance(); - handle->SetExternalResource(cacheItem); - ++cacheItem->scriptRef; - - return QQmlV8Handle::fromHandle(handle); -} - -bool QQuickVisualDataGroupPrivate::parseIndex( - const v8::Local<v8::Value> &value, int *index, Compositor::Group *group) const -{ - if (value->IsInt32()) { - *index = value->Int32Value(); - return true; - } else if (value->IsObject()) { - v8::Local<v8::Object> object = value->ToObject(); - QQuickVisualDataModelItem * const cacheItem = v8_resource_cast<QQuickVisualDataModelItem>(object); - if (QQuickVisualDataModelPrivate *model = cacheItem && cacheItem->metaType->model - ? QQuickVisualDataModelPrivate::get(cacheItem->metaType->model) - : 0) { - *index = model->m_cache.indexOf(cacheItem); - *group = Compositor::Cache; - return true; - } - } - return false; -} - -/*! - \qmlmethod QtQuick2::VisualDataGroup::insert(int index, jsdict data, array groups = undefined) - \qmlmethod QtQuick2::VisualDataGroup::insert(jsdict data, var groups = undefined) - - Creates a new entry at \a index in a VisualDataModel with the values from \a data that - correspond to roles in the model assigned to VisualDataModel::model. - - If no index is supplied the data is appended to the model. - - The optional \a groups parameter identifies the groups the new entry should belong to, - if unspecified this is equal to the group insert was called on. - - Data inserted into a VisualDataModel can later be merged with an existing entry in - VisualDataModel::model using the \l resolve() function. This can be used to create placeholder - items that are later replaced by actual data. -*/ - -void QQuickVisualDataGroup::insert(QQmlV8Function *args) -{ - Q_D(QQuickVisualDataGroup); - QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(d->model); - - int index = model->m_compositor.count(d->group); - Compositor::Group group = d->group; - - if (args->Length() == 0) - return; - - int i = 0; - v8::Local<v8::Value> v = (*args)[i]; - if (d->parseIndex(v, &index, &group)) { - if (index < 0 || index > model->m_compositor.count(group)) { - qmlInfo(this) << tr("insert: index out of range"); - return; - } - if (++i == args->Length()) - return; - v = (*args)[i]; - } - - Compositor::insert_iterator before = index < model->m_compositor.count(group) - ? model->m_compositor.findInsertPosition(group, index) - : model->m_compositor.end(); - - int groups = 1 << d->group; - if (++i < args->Length()) - groups |= model->m_cacheMetaType->parseGroups((*args)[i]); - - if (v->IsArray()) { - return; - } else if (v->IsObject()) { - model->insert(before, v->ToObject(), groups); - model->emitChanges(); - } -} - -/*! - \qmlmethod QtQuick2::VisualDataGroup::create(int index) - \qmlmethod QtQuick2::VisualDataGroup::create(int index, jsdict data, array groups = undefined) - \qmlmethod QtQuick2::VisualDataGroup::create(jsdict data, array groups = undefined) - - Returns a reference to the instantiated item at \a index in the group. - - If a \a data object is provided it will be \l {insert}{inserted} at \a index and an item - referencing this new entry will be returned. The optional \a groups parameter identifies - the groups the new entry should belong to, if unspecified this is equal to the group create() - was called on. - - All items returned by create are added to the - \l {QtQuick2::VisualDataModel::persistedItems}{persistedItems} group. Items in this - group remain instantiated when not referenced by any view. -*/ - -void QQuickVisualDataGroup::create(QQmlV8Function *args) -{ - Q_D(QQuickVisualDataGroup); - if (!d->model) - return; - - if (args->Length() == 0) - return; - - QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(d->model); - - int index = model->m_compositor.count(d->group); - Compositor::Group group = d->group; - - int i = 0; - v8::Local<v8::Value> v = (*args)[i]; - if (d->parseIndex(v, &index, &group)) - ++i; - - if (i < args->Length() && index >= 0 && index <= model->m_compositor.count(group)) { - v = (*args)[i]; - if (v->IsObject()) { - int groups = 1 << d->group; - if (++i < args->Length()) - groups |= model->m_cacheMetaType->parseGroups((*args)[i]); - - Compositor::insert_iterator before = index < model->m_compositor.count(group) - ? model->m_compositor.findInsertPosition(group, index) - : model->m_compositor.end(); - - index = before.index[d->group]; - group = d->group; - - if (!model->insert(before, v->ToObject(), groups)) { - return; - } - } - } - if (index < 0 || index >= model->m_compositor.count(group)) { - qmlInfo(this) << tr("create: index out of range"); - return; - } - - QObject *object = model->object(group, index, false); - if (object) { - QVector<Compositor::Insert> inserts; - Compositor::iterator it = model->m_compositor.find(group, index); - model->m_compositor.setFlags(it, 1, d->group, Compositor::PersistedFlag, &inserts); - model->itemsInserted(inserts); - model->m_cache.at(it.cacheIndex)->releaseObject(); - } - - args->returnValue(args->engine()->newQObject(object)); - model->emitChanges(); -} - -/*! - \qmlmethod QtQuick2::VisualDataGroup::resolve(int from, int to) - - Binds an unresolved item at \a from to an item in VisualDataModel::model at index \a to. - - Unresolved items are entries whose data has been \l {insert()}{inserted} into a VisualDataGroup - instead of being derived from a VisualDataModel::model index. Resolving an item will replace - the item at the target index with the unresolved item. A resolved an item will reflect the data - of the source model at its bound index and will move when that index moves like any other item. - - If a new item is replaced in the VisualDataGroup onChanged() handler its insertion and - replacement will be communicated to views as an atomic operation, creating the appearance - that the model contents have not changed, or if the unresolved and model item are not adjacent - that the previously unresolved item has simply moved. - -*/ -void QQuickVisualDataGroup::resolve(QQmlV8Function *args) -{ - Q_D(QQuickVisualDataGroup); - if (!d->model) - return; - - QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(d->model); - - if (args->Length() < 2) - return; - - int from = -1; - int to = -1; - Compositor::Group fromGroup = d->group; - Compositor::Group toGroup = d->group; - - v8::Local<v8::Value> v = (*args)[0]; - if (d->parseIndex(v, &from, &fromGroup)) { - if (from < 0 || from >= model->m_compositor.count(fromGroup)) { - qmlInfo(this) << tr("resolve: from index out of range"); - return; - } - } else { - qmlInfo(this) << tr("resolve: from index invalid"); - return; - } - - v = (*args)[1]; - if (d->parseIndex(v, &to, &toGroup)) { - if (to < 0 || to >= model->m_compositor.count(toGroup)) { - qmlInfo(this) << tr("resolve: to index out of range"); - return; - } - } else { - qmlInfo(this) << tr("resolve: to index invalid"); - return; - } - - Compositor::iterator fromIt = model->m_compositor.find(fromGroup, from); - Compositor::iterator toIt = model->m_compositor.find(toGroup, to); - - if (!fromIt->isUnresolved()) { - qmlInfo(this) << tr("resolve: from is not an unresolved item"); - return; - } - if (!toIt->list) { - qmlInfo(this) << tr("resolve: to is not a model item"); - return; - } - - const int unresolvedFlags = fromIt->flags; - const int resolvedFlags = toIt->flags; - const int resolvedIndex = toIt.modelIndex(); - void * const resolvedList = toIt->list; - - QQuickVisualDataModelItem *cacheItem = model->m_cache.at(fromIt.cacheIndex); - cacheItem->groups &= ~Compositor::UnresolvedFlag; - - if (toIt.cacheIndex > fromIt.cacheIndex) - toIt.decrementIndexes(1, unresolvedFlags); - if (!toIt->inGroup(fromGroup) || toIt.index[fromGroup] > from) - from += 1; - - model->itemsMoved( - QVector<Compositor::Remove>() << Compositor::Remove(fromIt, 1, unresolvedFlags, 0), - QVector<Compositor::Insert>() << Compositor::Insert(toIt, 1, unresolvedFlags, 0)); - model->itemsInserted( - QVector<Compositor::Insert>() << Compositor::Insert(toIt, 1, (resolvedFlags & ~unresolvedFlags) | Compositor::CacheFlag)); - toIt.incrementIndexes(1, resolvedFlags | unresolvedFlags); - model->itemsRemoved(QVector<Compositor::Remove>() << Compositor::Remove(toIt, 1, resolvedFlags)); - - model->m_compositor.setFlags(toGroup, to, 1, unresolvedFlags & ~Compositor::UnresolvedFlag); - model->m_compositor.clearFlags(fromGroup, from, 1, unresolvedFlags); - - if (resolvedFlags & Compositor::CacheFlag) - model->m_compositor.insert(Compositor::Cache, toIt.cacheIndex, resolvedList, resolvedIndex, 1, Compositor::CacheFlag); - - Q_ASSERT(model->m_cache.count() == model->m_compositor.count(Compositor::Cache)); - - if (!cacheItem->isReferenced()) { - Q_ASSERT(toIt.cacheIndex == model->m_cache.indexOf(cacheItem)); - model->m_cache.removeAt(toIt.cacheIndex); - model->m_compositor.clearFlags(Compositor::Cache, toIt.cacheIndex, 1, Compositor::CacheFlag); - delete cacheItem; - Q_ASSERT(model->m_cache.count() == model->m_compositor.count(Compositor::Cache)); - } else { - cacheItem->resolveIndex(model->m_adaptorModel, resolvedIndex); - if (cacheItem->attached) - cacheItem->attached->emitUnresolvedChanged(); - } - - model->emitChanges(); -} - -/*! - \qmlmethod QtQuick2::VisualDataGroup::remove(int index, int count) - - Removes \a count items starting at \a index from the group. -*/ - -void QQuickVisualDataGroup::remove(QQmlV8Function *args) -{ - Q_D(QQuickVisualDataGroup); - if (!d->model) - return; - Compositor::Group group = d->group; - int index = -1; - int count = 1; - - if (args->Length() == 0) - return; - - int i = 0; - v8::Local<v8::Value> v = (*args)[i]; - if (!d->parseIndex(v, &index, &group)) { - qmlInfo(this) << tr("remove: invalid index"); - return; - } - - if (++i < args->Length()) { - v = (*args)[i]; - if (v->IsInt32()) - count = v->Int32Value(); - } - - QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(d->model); - if (index < 0 || index >= model->m_compositor.count(group)) { - qmlInfo(this) << tr("remove: index out of range"); - } else if (count != 0) { - Compositor::iterator it = model->m_compositor.find(group, index); - if (count < 0 || count > model->m_compositor.count(d->group) - it.index[d->group]) { - qmlInfo(this) << tr("remove: invalid count"); - } else { - model->removeGroups(it, count, d->group, 1 << d->group); - } - } -} - -bool QQuickVisualDataGroupPrivate::parseGroupArgs( - QQmlV8Function *args, Compositor::Group *group, int *index, int *count, int *groups) const -{ - if (!model || !QQuickVisualDataModelPrivate::get(model)->m_cacheMetaType) - return false; - - if (args->Length() < 2) - return false; - - int i = 0; - v8::Local<v8::Value> v = (*args)[i]; - if (!parseIndex(v, index, group)) - return false; - - v = (*args)[++i]; - if (v->IsInt32()) { - *count = v->Int32Value(); - - if (++i == args->Length()) - return false; - v = (*args)[i]; - } - - *groups = QQuickVisualDataModelPrivate::get(model)->m_cacheMetaType->parseGroups(v); - - return true; -} - -/*! - \qmlmethod QtQuick2::VisualDataGroup::addGroups(int index, int count, stringlist groups) - - Adds \a count items starting at \a index to \a groups. -*/ - -void QQuickVisualDataGroup::addGroups(QQmlV8Function *args) -{ - Q_D(QQuickVisualDataGroup); - Compositor::Group group = d->group; - int index = -1; - int count = 1; - int groups = 0; - - if (!d->parseGroupArgs(args, &group, &index, &count, &groups)) - return; - - QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(d->model); - if (index < 0 || index >= model->m_compositor.count(group)) { - qmlInfo(this) << tr("addGroups: index out of range"); - } else if (count != 0) { - Compositor::iterator it = model->m_compositor.find(group, index); - if (count < 0 || count > model->m_compositor.count(d->group) - it.index[d->group]) { - qmlInfo(this) << tr("addGroups: invalid count"); - } else { - model->addGroups(it, count, d->group, groups); - } - } -} - -/*! - \qmlmethod QtQuick2::VisualDataGroup::removeGroups(int index, int count, stringlist groups) - - Removes \a count items starting at \a index from \a groups. -*/ - -void QQuickVisualDataGroup::removeGroups(QQmlV8Function *args) -{ - Q_D(QQuickVisualDataGroup); - Compositor::Group group = d->group; - int index = -1; - int count = 1; - int groups = 0; - - if (!d->parseGroupArgs(args, &group, &index, &count, &groups)) - return; - - QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(d->model); - if (index < 0 || index >= model->m_compositor.count(group)) { - qmlInfo(this) << tr("removeGroups: index out of range"); - } else if (count != 0) { - Compositor::iterator it = model->m_compositor.find(group, index); - if (count < 0 || count > model->m_compositor.count(d->group) - it.index[d->group]) { - qmlInfo(this) << tr("removeGroups: invalid count"); - } else { - model->removeGroups(it, count, d->group, groups); - } - } -} - -/*! - \qmlmethod QtQuick2::VisualDataGroup::setGroups(int index, int count, stringlist groups) - - Sets the \a groups \a count items starting at \a index belong to. -*/ - -void QQuickVisualDataGroup::setGroups(QQmlV8Function *args) -{ - Q_D(QQuickVisualDataGroup); - Compositor::Group group = d->group; - int index = -1; - int count = 1; - int groups = 0; - - if (!d->parseGroupArgs(args, &group, &index, &count, &groups)) - return; - - QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(d->model); - if (index < 0 || index >= model->m_compositor.count(group)) { - qmlInfo(this) << tr("setGroups: index out of range"); - } else if (count != 0) { - Compositor::iterator it = model->m_compositor.find(group, index); - if (count < 0 || count > model->m_compositor.count(d->group) - it.index[d->group]) { - qmlInfo(this) << tr("setGroups: invalid count"); - } else { - model->setGroups(it, count, d->group, groups); - } - } -} - -/*! - \qmlmethod QtQuick2::VisualDataGroup::setGroups(int index, int count, stringlist groups) - - Sets the \a groups \a count items starting at \a index belong to. -*/ - -/*! - \qmlmethod QtQuick2::VisualDataGroup::move(var from, var to, int count) - - Moves \a count at \a from in a group \a to a new position. -*/ - -void QQuickVisualDataGroup::move(QQmlV8Function *args) -{ - Q_D(QQuickVisualDataGroup); - - if (args->Length() < 2) - return; - - Compositor::Group fromGroup = d->group; - Compositor::Group toGroup = d->group; - int from = -1; - int to = -1; - int count = 1; - - if (!d->parseIndex((*args)[0], &from, &fromGroup)) { - qmlInfo(this) << tr("move: invalid from index"); - return; - } - - if (!d->parseIndex((*args)[1], &to, &toGroup)) { - qmlInfo(this) << tr("move: invalid to index"); - return; - } - - if (args->Length() > 2) { - v8::Local<v8::Value> v = (*args)[2]; - if (v->IsInt32()) - count = v->Int32Value(); - } - - QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(d->model); - - if (count < 0) { - qmlInfo(this) << tr("move: invalid count"); - } else if (from < 0 || from + count > model->m_compositor.count(fromGroup)) { - qmlInfo(this) << tr("move: from index out of range"); - } else if (!model->m_compositor.verifyMoveTo(fromGroup, from, toGroup, to, count, d->group)) { - qmlInfo(this) << tr("move: to index out of range"); - } else if (count > 0) { - QVector<Compositor::Remove> removes; - QVector<Compositor::Insert> inserts; - - model->m_compositor.move(fromGroup, from, toGroup, to, count, d->group, &removes, &inserts); - model->itemsMoved(removes, inserts); - model->emitChanges(); - } - -} - -/*! - \qmlsignal QtQuick2::VisualDataGroup::onChanged(array removed, array inserted) - - This handler is called when items have been removed from or inserted into the group. - - Each object in the \a removed and \a inserted arrays has two values; the \e index of the first - item inserted or removed and a \e count of the number of consecutive items inserted or removed. - - Each index is adjusted for previous changes with all removed items preceding any inserted - items. -*/ - -//============================================================================ - -QQuickVisualPartsModel::QQuickVisualPartsModel(QQuickVisualDataModel *model, const QString &part, QObject *parent) - : QQuickVisualModel(*new QObjectPrivate, parent) - , m_model(model) - , m_part(part) - , m_compositorGroup(Compositor::Cache) - , m_inheritGroup(true) -{ - QQuickVisualDataModelPrivate *d = QQuickVisualDataModelPrivate::get(m_model); - if (d->m_cacheMetaType) { - QQuickVisualDataGroupPrivate::get(d->m_groups[1])->emitters.insert(this); - m_compositorGroup = Compositor::Default; - } else { - d->m_pendingParts.insert(this); - } -} - -QQuickVisualPartsModel::~QQuickVisualPartsModel() -{ -} - -QString QQuickVisualPartsModel::filterGroup() const -{ - if (m_inheritGroup) - return m_model->filterGroup(); - return m_filterGroup; -} - -void QQuickVisualPartsModel::setFilterGroup(const QString &group) -{ - if (QQuickVisualDataModelPrivate::get(m_model)->m_transaction) { - qmlInfo(this) << tr("The group of a VisualDataModel cannot be changed within onChanged"); - return; - } - - if (m_filterGroup != group || m_inheritGroup) { - m_filterGroup = group; - m_inheritGroup = false; - updateFilterGroup(); - - emit filterGroupChanged(); - } -} - -void QQuickVisualPartsModel::resetFilterGroup() -{ - if (!m_inheritGroup) { - m_inheritGroup = true; - updateFilterGroup(); - emit filterGroupChanged(); - } -} - -void QQuickVisualPartsModel::updateFilterGroup() -{ - QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(m_model); - if (!model->m_cacheMetaType) - return; - - if (m_inheritGroup) { - if (m_filterGroup == model->m_filterGroup) - return; - m_filterGroup = model->m_filterGroup; - } - - QQuickListCompositor::Group previousGroup = m_compositorGroup; - m_compositorGroup = Compositor::Default; - QQuickVisualDataGroupPrivate::get(model->m_groups[Compositor::Default])->emitters.insert(this); - for (int i = 1; i < model->m_groupCount; ++i) { - if (m_filterGroup == model->m_cacheMetaType->groupNames.at(i - 1)) { - m_compositorGroup = Compositor::Group(i); - break; - } - } - - QQuickVisualDataGroupPrivate::get(model->m_groups[m_compositorGroup])->emitters.insert(this); - if (m_compositorGroup != previousGroup) { - QVector<QQuickChangeSet::Remove> removes; - QVector<QQuickChangeSet::Insert> inserts; - model->m_compositor.transition(previousGroup, m_compositorGroup, &removes, &inserts); - - QQuickChangeSet changeSet; - changeSet.move(removes, inserts); - if (!changeSet.isEmpty()) - emit modelUpdated(changeSet, false); - - if (changeSet.difference() != 0) - emit countChanged(); - } -} - -void QQuickVisualPartsModel::updateFilterGroup( - Compositor::Group group, const QQuickChangeSet &changeSet) -{ - if (!m_inheritGroup) - return; - - m_compositorGroup = group; - QQuickVisualDataGroupPrivate::get(QQuickVisualDataModelPrivate::get(m_model)->m_groups[m_compositorGroup])->emitters.insert(this); - - if (!changeSet.isEmpty()) - emit modelUpdated(changeSet, false); - - if (changeSet.difference() != 0) - emit countChanged(); - - emit filterGroupChanged(); -} - -int QQuickVisualPartsModel::count() const -{ - QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(m_model); - return model->m_delegate - ? model->m_compositor.count(m_compositorGroup) - : 0; -} - -bool QQuickVisualPartsModel::isValid() const -{ - return m_model->isValid(); -} - -QQuickItem *QQuickVisualPartsModel::item(int index, bool asynchronous) -{ - QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(m_model); - - if (!model->m_delegate || index < 0 || index >= model->m_compositor.count(m_compositorGroup)) { - qWarning() << "VisualDataModel::item: index out range" << index << model->m_compositor.count(m_compositorGroup); - return 0; - } - - QObject *object = model->object(m_compositorGroup, index, asynchronous); - - if (QQuickPackage *package = qmlobject_cast<QQuickPackage *>(object)) { - QObject *part = package->part(m_part); - if (!part) - return 0; - if (QQuickItem *item = qmlobject_cast<QQuickItem *>(part)) { - m_packaged.insertMulti(item, package); - return item; - } - } - - model->release(object); - if (!model->m_delegateValidated) { - if (object) - qmlInfo(model->m_delegate) << tr("Delegate component must be Package type."); - model->m_delegateValidated = true; - } - - return 0; -} - -QQuickVisualModel::ReleaseFlags QQuickVisualPartsModel::release(QQuickItem *item) -{ - QQuickVisualModel::ReleaseFlags flags = 0; - - QHash<QObject *, QQuickPackage *>::iterator it = m_packaged.find(item); - if (it != m_packaged.end()) { - QQuickPackage *package = *it; - QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(m_model); - flags = model->release(package); - m_packaged.erase(it); - if (!m_packaged.contains(item)) - flags &= ~Referenced; - if (flags & Destroyed) - QQuickVisualDataModelPrivate::get(m_model)->emitDestroyingPackage(package); - } - return flags; -} - -QString QQuickVisualPartsModel::stringValue(int index, const QString &role) -{ - return QQuickVisualDataModelPrivate::get(m_model)->stringValue(m_compositorGroup, index, role); -} - -void QQuickVisualPartsModel::setWatchedRoles(QList<QByteArray> roles) -{ - QQuickVisualDataModelPrivate *model = QQuickVisualDataModelPrivate::get(m_model); - model->m_adaptorModel.replaceWatchedRoles(m_watchedRoles, roles); - m_watchedRoles = roles; -} - -int QQuickVisualPartsModel::indexOf(QQuickItem *item, QObject *) const -{ - QHash<QObject *, QQuickPackage *>::const_iterator it = m_packaged.find(item); - if (it != m_packaged.end()) { - if (QQuickVisualDataModelItem *cacheItem = QQuickVisualDataModelItem::dataForObject(*it)) - return cacheItem->groupIndex(m_compositorGroup); - } - return -1; -} - -void QQuickVisualPartsModel::createdPackage(int index, QQuickPackage *package) -{ - if (QQuickItem *item = qmlobject_cast<QQuickItem *>(package->part(m_part))) - emit createdItem(index, item); -} - -void QQuickVisualPartsModel::initPackage(int index, QQuickPackage *package) -{ - if (QQuickItem *item = qmlobject_cast<QQuickItem *>(package->part(m_part))) - emit initItem(index, item); -} - -void QQuickVisualPartsModel::destroyingPackage(QQuickPackage *package) -{ - if (QQuickItem *item = qmlobject_cast<QQuickItem *>(package->part(m_part))) { - Q_ASSERT(!m_packaged.contains(item)); - emit destroyingItem(item); - item->setParentItem(0); - } -} - -void QQuickVisualPartsModel::emitModelUpdated(const QQuickChangeSet &changeSet, bool reset) -{ - emit modelUpdated(changeSet, reset); - if (changeSet.difference() != 0) - emit countChanged(); -} - -//============================================================================ - -v8::Handle<v8::Value> get_change_index(v8::Local<v8::String>, const v8::AccessorInfo &info) -{ - return info.This()->GetInternalField(0); -} - -v8::Handle<v8::Value> get_change_count(v8::Local<v8::String>, const v8::AccessorInfo &info) -{ - return info.This()->GetInternalField(1); -} - -v8::Handle<v8::Value> get_change_moveId(v8::Local<v8::String>, const v8::AccessorInfo &info) -{ - return info.This()->GetInternalField(2); -} - -class QQuickVisualDataGroupChangeArray : public QV8ObjectResource -{ - V8_RESOURCE_TYPE(ChangeSetArrayType) -public: - QQuickVisualDataGroupChangeArray(QV8Engine *engine) - : QV8ObjectResource(engine) - { - } - - virtual quint32 count() const = 0; - virtual const QQuickChangeSet::Change &at(int index) const = 0; - - static v8::Handle<v8::Value> get_change(quint32 index, const v8::AccessorInfo &info) - { - QQuickVisualDataGroupChangeArray *array = v8_resource_cast<QQuickVisualDataGroupChangeArray>(info.This()); - V8ASSERT_TYPE(array, "Not a valid change array"); - - if (index >= array->count()) - return v8::Undefined(); - - const QQuickChangeSet::Change &change = array->at(index); - - v8::Local<v8::Object> object = engineData(array->engine)->constructorChange->NewInstance(); - object->SetInternalField(0, v8::Int32::New(change.index)); - object->SetInternalField(1, v8::Int32::New(change.count)); - if (change.isMove()) - object->SetInternalField(2, v8::Int32::New(change.moveId)); - - return object; - } - - static v8::Handle<v8::Value> get_length(v8::Local<v8::String>, const v8::AccessorInfo &info) - { - QQuickVisualDataGroupChangeArray *array = v8_resource_cast<QQuickVisualDataGroupChangeArray>(info.This()); - V8ASSERT_TYPE(array, "Not a valid change array"); - - return v8::Integer::New(array->count()); - } - - static v8::Local<v8::Function> constructor() - { - v8::Local<v8::FunctionTemplate> changeArray = v8::FunctionTemplate::New(); - changeArray->InstanceTemplate()->SetHasExternalResource(true); - changeArray->InstanceTemplate()->SetIndexedPropertyHandler(get_change); - changeArray->InstanceTemplate()->SetAccessor(v8::String::New("length"), get_length); - return changeArray->GetFunction(); - } -}; - -class QQuickVisualDataGroupRemoveArray : public QQuickVisualDataGroupChangeArray -{ -public: - QQuickVisualDataGroupRemoveArray(QV8Engine *engine, const QVector<QQuickChangeSet::Remove> &changes) - : QQuickVisualDataGroupChangeArray(engine) - , changes(changes) - { - } - - quint32 count() const { return changes.count(); } - const QQuickChangeSet::Change &at(int index) const { return changes.at(index); } - -private: - QVector<QQuickChangeSet::Remove> changes; -}; - -class QQuickVisualDataGroupInsertArray : public QQuickVisualDataGroupChangeArray -{ -public: - QQuickVisualDataGroupInsertArray(QV8Engine *engine, const QVector<QQuickChangeSet::Insert> &changes) - : QQuickVisualDataGroupChangeArray(engine) - , changes(changes) - { - } - - quint32 count() const { return changes.count(); } - const QQuickChangeSet::Change &at(int index) const { return changes.at(index); } - -private: - QVector<QQuickChangeSet::Insert> changes; -}; - -QQuickVisualDataModelEngineData::QQuickVisualDataModelEngineData(QV8Engine *) -{ - strings = qPersistentNew(v8::Array::New(StringCount)); - strings->Set(Model, v8::String::New("model")); - strings->Set(Groups, v8::String::New("groups")); - strings->Set(IsUnresolved, v8::String::New("isUnresolved")); - strings->Set(ItemsIndex, v8::String::New("itemsIndex")); - strings->Set(PersistedItemsIndex, v8::String::New("persistedItemsIndex")); - strings->Set(InItems, v8::String::New("inItems")); - strings->Set(InPersistedItems, v8::String::New("inPersistedItems")); - - v8::Local<v8::FunctionTemplate> change = v8::FunctionTemplate::New(); - change->InstanceTemplate()->SetAccessor(v8::String::New("index"), get_change_index); - change->InstanceTemplate()->SetAccessor(v8::String::New("count"), get_change_count); - change->InstanceTemplate()->SetAccessor(v8::String::New("moveId"), get_change_moveId); - change->InstanceTemplate()->SetInternalFieldCount(3); - constructorChange = qPersistentNew(change->GetFunction()); - constructorChangeArray = qPersistentNew(QQuickVisualDataGroupChangeArray::constructor()); -} - -QQuickVisualDataModelEngineData::~QQuickVisualDataModelEngineData() -{ - qPersistentDispose(strings); - qPersistentDispose(constructorChange); - qPersistentDispose(constructorChangeArray); -} - -v8::Local<v8::Object> QQuickVisualDataModelEngineData::array( - QV8Engine *engine, const QVector<QQuickChangeSet::Remove> &changes) -{ - v8::Local<v8::Object> array = constructorChangeArray->NewInstance(); - array->SetExternalResource(new QQuickVisualDataGroupRemoveArray(engine, changes)); - return array; -} - -v8::Local<v8::Object> QQuickVisualDataModelEngineData::array( - QV8Engine *engine, const QVector<QQuickChangeSet::Insert> &changes) -{ - v8::Local<v8::Object> array = constructorChangeArray->NewInstance(); - array->SetExternalResource(new QQuickVisualDataGroupInsertArray(engine, changes)); - return array; -} - -QT_END_NAMESPACE - diff --git a/src/quick/items/qquickvisualdatamodel_p.h b/src/quick/items/qquickvisualdatamodel_p.h deleted file mode 100644 index 03e06c82ac..0000000000 --- a/src/quick/items/qquickvisualdatamodel_p.h +++ /dev/null @@ -1,238 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQUICKVISUALDATAMODEL_P_H -#define QQUICKVISUALDATAMODEL_P_H - -#include <private/qtquickglobal_p.h> -#include <private/qquicklistcompositor_p.h> -#include <private/qquickvisualitemmodel_p.h> - -#include <QtCore/qabstractitemmodel.h> -#include <QtCore/qstringlist.h> - -#include <private/qv8engine_p.h> -#include <private/qqmlglobal_p.h> - -QT_BEGIN_HEADER - -Q_DECLARE_METATYPE(QModelIndex) - -QT_BEGIN_NAMESPACE - -class QQuickChangeSet; -class QQmlComponent; -class QQuickPackage; -class QQmlV8Function; -class QQuickVisualDataGroup; -class QQuickVisualDataModelAttached; -class QQuickVisualDataModelPrivate; - - -class Q_QUICK_PRIVATE_EXPORT QQuickVisualDataModel : public QQuickVisualModel, public QQmlParserStatus -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QQuickVisualDataModel) - - Q_PROPERTY(QVariant model READ model WRITE setModel) - Q_PROPERTY(QQmlComponent *delegate READ delegate WRITE setDelegate) - Q_PROPERTY(QString filterOnGroup READ filterGroup WRITE setFilterGroup NOTIFY filterGroupChanged RESET resetFilterGroup) - Q_PROPERTY(QQuickVisualDataGroup *items READ items CONSTANT) - Q_PROPERTY(QQuickVisualDataGroup *persistedItems READ persistedItems CONSTANT) - Q_PROPERTY(QQmlListProperty<QQuickVisualDataGroup> groups READ groups CONSTANT) - Q_PROPERTY(QObject *parts READ parts CONSTANT) - Q_PROPERTY(QVariant rootIndex READ rootIndex WRITE setRootIndex NOTIFY rootIndexChanged) - Q_CLASSINFO("DefaultProperty", "delegate") - Q_INTERFACES(QQmlParserStatus) -public: - QQuickVisualDataModel(); - QQuickVisualDataModel(QQmlContext *, QObject *parent=0); - virtual ~QQuickVisualDataModel(); - - void classBegin(); - void componentComplete(); - - QVariant model() const; - void setModel(const QVariant &); - - QQmlComponent *delegate() const; - void setDelegate(QQmlComponent *); - - QVariant rootIndex() const; - void setRootIndex(const QVariant &root); - - Q_INVOKABLE QVariant modelIndex(int idx) const; - Q_INVOKABLE QVariant parentModelIndex() const; - - int count() const; - bool isValid() const { return delegate() != 0; } - QQuickItem *item(int index, bool asynchronous=false); - ReleaseFlags release(QQuickItem *item); - void cancel(int index); - virtual QString stringValue(int index, const QString &role); - virtual void setWatchedRoles(QList<QByteArray> roles); - - int indexOf(QQuickItem *item, QObject *objectContext) const; - - QString filterGroup() const; - void setFilterGroup(const QString &group); - void resetFilterGroup(); - - QQuickVisualDataGroup *items(); - QQuickVisualDataGroup *persistedItems(); - QQmlListProperty<QQuickVisualDataGroup> groups(); - QObject *parts(); - - bool event(QEvent *); - - static QQuickVisualDataModelAttached *qmlAttachedProperties(QObject *obj); - -Q_SIGNALS: - void filterGroupChanged(); - void defaultGroupsChanged(); - void rootIndexChanged(); - -private Q_SLOTS: - void _q_itemsChanged(int index, int count, const QVector<int> &roles); - void _q_itemsInserted(int index, int count); - void _q_itemsRemoved(int index, int count); - void _q_itemsMoved(int from, int to, int count); - void _q_modelReset(); - void _q_rowsInserted(const QModelIndex &,int,int); - void _q_rowsAboutToBeRemoved(const QModelIndex &parent, int begin, int end); - void _q_rowsRemoved(const QModelIndex &,int,int); - void _q_rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int); - void _q_dataChanged(const QModelIndex&,const QModelIndex&,const QVector<int> &); - void _q_layoutChanged(); - -private: - Q_DISABLE_COPY(QQuickVisualDataModel) -}; - -class QQuickVisualDataGroupPrivate; -class Q_AUTOTEST_EXPORT QQuickVisualDataGroup : public QObject -{ - Q_OBJECT - Q_PROPERTY(int count READ count NOTIFY countChanged) - Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) - Q_PROPERTY(bool includeByDefault READ defaultInclude WRITE setDefaultInclude NOTIFY defaultIncludeChanged) -public: - QQuickVisualDataGroup(QObject *parent = 0); - QQuickVisualDataGroup(const QString &name, QQuickVisualDataModel *model, int compositorType, QObject *parent = 0); - ~QQuickVisualDataGroup(); - - QString name() const; - void setName(const QString &name); - - int count() const; - - bool defaultInclude() const; - void setDefaultInclude(bool include); - - Q_INVOKABLE QQmlV8Handle get(int index); - -public Q_SLOTS: - void insert(QQmlV8Function *); - void create(QQmlV8Function *); - void resolve(QQmlV8Function *); - void remove(QQmlV8Function *); - void addGroups(QQmlV8Function *); - void removeGroups(QQmlV8Function *); - void setGroups(QQmlV8Function *); - void move(QQmlV8Function *); - -Q_SIGNALS: - void countChanged(); - void nameChanged(); - void defaultIncludeChanged(); - void changed(const QQmlV8Handle &removed, const QQmlV8Handle &inserted); -private: - Q_DECLARE_PRIVATE(QQuickVisualDataGroup) -}; - -class QQuickVisualDataModelItem; -class QQuickVisualDataModelAttachedMetaObject; -class QQuickVisualDataModelAttached : public QObject -{ - Q_OBJECT - Q_PROPERTY(QQuickVisualDataModel *model READ model CONSTANT) - Q_PROPERTY(QStringList groups READ groups WRITE setGroups NOTIFY groupsChanged) - Q_PROPERTY(bool isUnresolved READ isUnresolved NOTIFY unresolvedChanged) -public: - QQuickVisualDataModelAttached(QObject *parent); - QQuickVisualDataModelAttached(QQuickVisualDataModelItem *cacheItem, QObject *parent); - ~QQuickVisualDataModelAttached() {} - - void setCacheItem(QQuickVisualDataModelItem *item); - - QQuickVisualDataModel *model() const; - - QStringList groups() const; - void setGroups(const QStringList &groups); - - bool isUnresolved() const; - - void emitChanges(); - - void emitUnresolvedChanged() { emit unresolvedChanged(); } - -Q_SIGNALS: - void groupsChanged(); - void unresolvedChanged(); - -public: - QQuickVisualDataModelItem *m_cacheItem; - int m_previousGroups; - int m_currentIndex[QQuickListCompositor::MaximumGroupCount]; - int m_previousIndex[QQuickListCompositor::MaximumGroupCount]; - - friend class QQuickVisualDataModelAttachedMetaObject; -}; - -QT_END_NAMESPACE - -QML_DECLARE_TYPE(QQuickVisualDataModel) -QML_DECLARE_TYPEINFO(QQuickVisualDataModel, QML_HAS_ATTACHED_PROPERTIES) -QML_DECLARE_TYPE(QQuickVisualDataGroup) - -QT_END_HEADER - -#endif // QQUICKVISUALDATAMODEL_P_H diff --git a/src/quick/items/qquickvisualdatamodel_p_p.h b/src/quick/items/qquickvisualdatamodel_p_p.h deleted file mode 100644 index 89ecece064..0000000000 --- a/src/quick/items/qquickvisualdatamodel_p_p.h +++ /dev/null @@ -1,411 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQUICKVISUALDATAMODEL_P_P_H -#define QQUICKVISUALDATAMODEL_P_P_H - -#include "qquickvisualdatamodel_p.h" - -#include "qquickvisualadaptormodel_p.h" - -#include <QtQml/qqmlcontext.h> -#include <QtQml/qqmlincubator.h> - -#include <private/qqmlopenmetaobject_p.h> - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -QT_BEGIN_NAMESPACE - -typedef QQuickListCompositor Compositor; - -class QQuickVisualDataModelAttachedMetaObject; - -class QQuickVisualDataModelItemMetaType : public QQmlRefCount -{ -public: - QQuickVisualDataModelItemMetaType(QV8Engine *engine, QQuickVisualDataModel *model, const QStringList &groupNames); - ~QQuickVisualDataModelItemMetaType(); - - void initializeMetaObject(); - void initializeConstructor(); - - int parseGroups(const QStringList &groupNames) const; - int parseGroups(const v8::Local<v8::Value> &groupNames) const; - - static void release_index(v8::Persistent<v8::Value> object, void *parameter); - static void release_model(v8::Persistent<v8::Value> object, void *parameter); - - static v8::Handle<v8::Value> get_model(v8::Local<v8::String>, const v8::AccessorInfo &info); - static v8::Handle<v8::Value> get_groups(v8::Local<v8::String>, const v8::AccessorInfo &info); - static void set_groups( - v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info); - static v8::Handle<v8::Value> get_member(v8::Local<v8::String>, const v8::AccessorInfo &info); - static void set_member( - v8::Local<v8::String>, v8::Local<v8::Value> value, const v8::AccessorInfo &info); - static v8::Handle<v8::Value> get_index(v8::Local<v8::String>, const v8::AccessorInfo &info); - - QQmlGuard<QQuickVisualDataModel> model; - const int groupCount; - QV8Engine * const v8Engine; - QQuickVisualDataModelAttachedMetaObject *metaObject; - const QStringList groupNames; - v8::Persistent<v8::ObjectTemplate> constructor; -}; - -class QQuickVisualAdaptorModel; -class QVDMIncubationTask; - -class QQuickVisualDataModelItem : public QObject, public QV8ObjectResource -{ - Q_OBJECT - Q_PROPERTY(int index READ modelIndex NOTIFY modelIndexChanged) - Q_PROPERTY(QObject *model READ modelObject CONSTANT) - V8_RESOURCE_TYPE(VisualDataItemType) -public: - QQuickVisualDataModelItem(QQuickVisualDataModelItemMetaType *metaType, int modelIndex); - ~QQuickVisualDataModelItem(); - - void referenceObject() { ++objectRef; } - bool releaseObject() { return --objectRef == 0 && !(groups & Compositor::PersistedFlag); } - bool isObjectReferenced() const { return objectRef != 0 || (groups & Compositor::PersistedFlag); } - - bool isReferenced() const { - return scriptRef - || incubationTask - || ((groups & Compositor::UnresolvedFlag) && (groups & Compositor::GroupMask)); - } - - void Dispose(); - - QObject *modelObject() { return this; } - - void incubateObject( - QQmlComponent *component, - QQmlEngine *engine, - QQmlContextData *context, - QQmlContextData *forContext); - void destroyObject(); - - static QQuickVisualDataModelItem *dataForObject(QObject *object); - - int groupIndex(Compositor::Group group); - - int modelIndex() const { return index; } - void setModelIndex(int idx) { index = idx; emit modelIndexChanged(); } - - virtual v8::Handle<v8::Value> get() { return engine->newQObject(this); } - - virtual void setValue(const QString &role, const QVariant &value) { Q_UNUSED(role); Q_UNUSED(value); } - virtual bool resolveIndex(const QQuickVisualAdaptorModel &, int) { return false; } - - QQuickVisualDataModelItemMetaType * const metaType; - QQmlContextData *contextData; - QObject *object; - QQuickVisualDataModelAttached *attached; - QVDMIncubationTask *incubationTask; - int objectRef; - int scriptRef; - int groups; - int index; - - -Q_SIGNALS: - void modelIndexChanged(); - -protected: - void objectDestroyed(QObject *); -}; - - -class QQuickVisualDataModelPrivate; -class QVDMIncubationTask : public QQmlIncubator -{ -public: - QVDMIncubationTask(QQuickVisualDataModelPrivate *l, IncubationMode mode) - : QQmlIncubator(mode) - , incubating(0) - , vdm(l) {} - - virtual void statusChanged(Status); - virtual void setInitialState(QObject *); - - QQuickVisualDataModelItem *incubating; - QQuickVisualDataModelPrivate *vdm; - int index[QQuickListCompositor::MaximumGroupCount]; -}; - - -class QQuickVisualDataGroupEmitter -{ -public: - virtual ~QQuickVisualDataGroupEmitter() {} - virtual void emitModelUpdated(const QQuickChangeSet &changeSet, bool reset) = 0; - virtual void createdPackage(int, QQuickPackage *) {} - virtual void initPackage(int, QQuickPackage *) {} - virtual void destroyingPackage(QQuickPackage *) {} - - QIntrusiveListNode emitterNode; -}; - -typedef QIntrusiveList<QQuickVisualDataGroupEmitter, &QQuickVisualDataGroupEmitter::emitterNode> QQuickVisualDataGroupEmitterList; - -class QQuickVisualDataGroupPrivate : public QObjectPrivate -{ -public: - Q_DECLARE_PUBLIC(QQuickVisualDataGroup) - - QQuickVisualDataGroupPrivate() : group(Compositor::Cache), defaultInclude(false) {} - - static QQuickVisualDataGroupPrivate *get(QQuickVisualDataGroup *group) { - return static_cast<QQuickVisualDataGroupPrivate *>(QObjectPrivate::get(group)); } - - void setModel(QQuickVisualDataModel *model, Compositor::Group group); - bool isChangedConnected(); - void emitChanges(QV8Engine *engine); - void emitModelUpdated(bool reset); - - void createdPackage(int index, QQuickPackage *package); - void initPackage(int index, QQuickPackage *package); - void destroyingPackage(QQuickPackage *package); - - bool parseIndex(const v8::Local<v8::Value> &value, int *index, Compositor::Group *group) const; - bool parseGroupArgs( - QQmlV8Function *args, Compositor::Group *group, int *index, int *count, int *groups) const; - - Compositor::Group group; - QQmlGuard<QQuickVisualDataModel> model; - QQuickVisualDataGroupEmitterList emitters; - QQuickChangeSet changeSet; - QString name; - bool defaultInclude; -}; - -class QQuickVisualDataModelParts; - -class QQuickVisualDataModelPrivate : public QObjectPrivate, public QQuickVisualDataGroupEmitter -{ - Q_DECLARE_PUBLIC(QQuickVisualDataModel) -public: - QQuickVisualDataModelPrivate(QQmlContext *); - ~QQuickVisualDataModelPrivate(); - - static QQuickVisualDataModelPrivate *get(QQuickVisualDataModel *m) { - return static_cast<QQuickVisualDataModelPrivate *>(QObjectPrivate::get(m)); - } - - void init(); - void connectModel(QQuickVisualAdaptorModel *model); - - QObject *object(Compositor::Group group, int index, bool asynchronous); - QQuickVisualDataModel::ReleaseFlags release(QObject *object); - QString stringValue(Compositor::Group group, int index, const QString &name); - void emitCreatedPackage(QVDMIncubationTask *incubationTask, QQuickPackage *package); - void emitInitPackage(QVDMIncubationTask *incubationTask, QQuickPackage *package); - void emitCreatedItem(QVDMIncubationTask *incubationTask, QQuickItem *item) { - emit q_func()->createdItem(incubationTask->index[m_compositorGroup], item); } - void emitInitItem(QVDMIncubationTask *incubationTask, QQuickItem *item) { - emit q_func()->initItem(incubationTask->index[m_compositorGroup], item); } - void emitDestroyingPackage(QQuickPackage *package); - void emitDestroyingItem(QQuickItem *item) { emit q_func()->destroyingItem(item); } - void removeCacheItem(QQuickVisualDataModelItem *cacheItem); - - void updateFilterGroup(); - - void addGroups(Compositor::iterator from, int count, Compositor::Group group, int groupFlags); - void removeGroups(Compositor::iterator from, int count, Compositor::Group group, int groupFlags); - void setGroups(Compositor::iterator from, int count, Compositor::Group group, int groupFlags); - - void itemsInserted( - const QVector<Compositor::Insert> &inserts, - QVarLengthArray<QVector<QQuickChangeSet::Insert>, Compositor::MaximumGroupCount> *translatedInserts, - QHash<int, QList<QQuickVisualDataModelItem *> > *movedItems = 0); - void itemsInserted(const QVector<Compositor::Insert> &inserts); - void itemsRemoved( - const QVector<Compositor::Remove> &removes, - QVarLengthArray<QVector<QQuickChangeSet::Remove>, Compositor::MaximumGroupCount> *translatedRemoves, - QHash<int, QList<QQuickVisualDataModelItem *> > *movedItems = 0); - void itemsRemoved(const QVector<Compositor::Remove> &removes); - void itemsMoved( - const QVector<Compositor::Remove> &removes, const QVector<Compositor::Insert> &inserts); - void itemsChanged(const QVector<Compositor::Change> &changes); - template <typename T> static v8::Local<v8::Array> buildChangeList(const QVector<T> &changes); - void emitChanges(); - void emitModelUpdated(const QQuickChangeSet &changeSet, bool reset); - - bool insert(Compositor::insert_iterator &before, const v8::Local<v8::Object> &object, int groups); - - static void group_append(QQmlListProperty<QQuickVisualDataGroup> *property, QQuickVisualDataGroup *group); - static int group_count(QQmlListProperty<QQuickVisualDataGroup> *property); - static QQuickVisualDataGroup *group_at(QQmlListProperty<QQuickVisualDataGroup> *property, int index); - - void releaseIncubator(QVDMIncubationTask *incubationTask); - void incubatorStatusChanged(QVDMIncubationTask *incubationTask, QQmlIncubator::Status status); - void setInitialState(QVDMIncubationTask *incubationTask, QObject *o); - - QQuickVisualAdaptorModel m_adaptorModel; - QQuickListCompositor m_compositor; - QQmlComponent *m_delegate; - QQuickVisualDataModelItemMetaType *m_cacheMetaType; - QQmlContext *m_context; - QQuickVisualDataModelParts *m_parts; - QQuickVisualDataGroupEmitterList m_pendingParts; - - QList<QQuickVisualDataModelItem *> m_cache; - QList<QVDMIncubationTask *> m_finishedIncubating; - QList<QByteArray> m_watchedRoles; - - QString m_filterGroup; - - int m_count; - int m_groupCount; - - QQuickListCompositor::Group m_compositorGroup; - bool m_complete : 1; - bool m_delegateValidated : 1; - bool m_reset : 1; - bool m_transaction : 1; - bool m_incubatorCleanupScheduled : 1; - - union { - struct { - QQuickVisualDataGroup *m_cacheItems; - QQuickVisualDataGroup *m_items; - QQuickVisualDataGroup *m_persistedItems; - }; - QQuickVisualDataGroup *m_groups[Compositor::MaximumGroupCount]; - }; -}; - -class QQuickVisualPartsModel : public QQuickVisualModel, public QQuickVisualDataGroupEmitter -{ - Q_OBJECT - Q_PROPERTY(QString filterOnGroup READ filterGroup WRITE setFilterGroup NOTIFY filterGroupChanged RESET resetFilterGroup) -public: - QQuickVisualPartsModel(QQuickVisualDataModel *model, const QString &part, QObject *parent = 0); - ~QQuickVisualPartsModel(); - - QString filterGroup() const; - void setFilterGroup(const QString &group); - void resetFilterGroup(); - void updateFilterGroup(); - void updateFilterGroup(Compositor::Group group, const QQuickChangeSet &changeSet); - - int count() const; - bool isValid() const; - QQuickItem *item(int index, bool asynchronous=false); - ReleaseFlags release(QQuickItem *item); - QString stringValue(int index, const QString &role); - QList<QByteArray> watchedRoles() const { return m_watchedRoles; } - void setWatchedRoles(QList<QByteArray> roles); - - int indexOf(QQuickItem *item, QObject *objectContext) const; - - void emitModelUpdated(const QQuickChangeSet &changeSet, bool reset); - - void createdPackage(int index, QQuickPackage *package); - void initPackage(int index, QQuickPackage *package); - void destroyingPackage(QQuickPackage *package); - -Q_SIGNALS: - void filterGroupChanged(); - -private: - QQuickVisualDataModel *m_model; - QHash<QObject *, QQuickPackage *> m_packaged; - QString m_part; - QString m_filterGroup; - QList<QByteArray> m_watchedRoles; - Compositor::Group m_compositorGroup; - bool m_inheritGroup; -}; - -class QMetaPropertyBuilder; - -class QQuickVisualDataModelPartsMetaObject : public QQmlOpenMetaObject -{ -public: - QQuickVisualDataModelPartsMetaObject(QObject *parent) - : QQmlOpenMetaObject(parent) {} - - virtual void propertyCreated(int, QMetaPropertyBuilder &); - virtual QVariant initialValue(int); -}; - -class QQuickVisualDataModelParts : public QObject -{ -Q_OBJECT -public: - QQuickVisualDataModelParts(QQuickVisualDataModel *parent); - - QQuickVisualDataModel *model; - QList<QQuickVisualPartsModel *> models; -}; - -class QQuickVisualDataModelAttachedMetaObject : public QAbstractDynamicMetaObject, public QQmlRefCount -{ -public: - QQuickVisualDataModelAttachedMetaObject( - QQuickVisualDataModelItemMetaType *metaType, QMetaObject *metaObject); - ~QQuickVisualDataModelAttachedMetaObject(); - - void objectDestroyed(QObject *); - int metaCall(QObject *, QMetaObject::Call, int _id, void **); - -private: - QQuickVisualDataModelItemMetaType * const metaType; - QMetaObject * const metaObject; - const int memberPropertyOffset; - const int indexPropertyOffset; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/quick/items/qquickvisualitemmodel.cpp b/src/quick/items/qquickvisualitemmodel.cpp deleted file mode 100644 index bdc489e2cf..0000000000 --- a/src/quick/items/qquickvisualitemmodel.cpp +++ /dev/null @@ -1,256 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickvisualitemmodel_p.h" -#include "qquickitem.h" - -#include <QtCore/qcoreapplication.h> -#include <QtQml/qqmlcontext.h> -#include <QtQml/qqmlengine.h> - -#include <private/qquickchangeset_p.h> -#include <private/qqmlglobal_p.h> -#include <private/qobject_p.h> - -#include <QtCore/qhash.h> -#include <QtCore/qlist.h> - -QT_BEGIN_NAMESPACE - -QHash<QObject*, QQuickVisualItemModelAttached*> QQuickVisualItemModelAttached::attachedProperties; - - -class QQuickVisualItemModelPrivate : public QObjectPrivate -{ - Q_DECLARE_PUBLIC(QQuickVisualItemModel) -public: - class Item { - public: - Item(QQuickItem *i) : item(i), ref(0) {} - - void addRef() { ++ref; } - bool deref() { return --ref == 0; } - - QQuickItem *item; - int ref; - }; - - QQuickVisualItemModelPrivate() : QObjectPrivate() {} - - static void children_append(QQmlListProperty<QQuickItem> *prop, QQuickItem *item) { - static_cast<QQuickVisualItemModelPrivate *>(prop->data)->children.append(Item(item)); - static_cast<QQuickVisualItemModelPrivate *>(prop->data)->itemAppended(); - static_cast<QQuickVisualItemModelPrivate *>(prop->data)->emitChildrenChanged(); - } - - static int children_count(QQmlListProperty<QQuickItem> *prop) { - return static_cast<QQuickVisualItemModelPrivate *>(prop->data)->children.count(); - } - - static QQuickItem *children_at(QQmlListProperty<QQuickItem> *prop, int index) { - return static_cast<QQuickVisualItemModelPrivate *>(prop->data)->children.at(index).item; - } - - static void children_clear(QQmlListProperty<QQuickItem> *prop) { - static_cast<QQuickVisualItemModelPrivate *>(prop->data)->itemCleared(static_cast<QQuickVisualItemModelPrivate *>(prop->data)->children); - static_cast<QQuickVisualItemModelPrivate *>(prop->data)->children.clear(); - static_cast<QQuickVisualItemModelPrivate *>(prop->data)->emitChildrenChanged(); - } - - void itemAppended() { - Q_Q(QQuickVisualItemModel); - QQuickVisualItemModelAttached *attached = QQuickVisualItemModelAttached::properties(children.last().item); - attached->setIndex(children.count()-1); - QQuickChangeSet changeSet; - changeSet.insert(children.count() - 1, 1); - emit q->modelUpdated(changeSet, false); - emit q->countChanged(); - } - - void itemCleared(const QList<Item> &children) { - Q_Q(QQuickVisualItemModel); - foreach (const Item &child, children) - emit q->destroyingItem(child.item); - emit q->countChanged(); - } - - void emitChildrenChanged() { - Q_Q(QQuickVisualItemModel); - emit q->childrenChanged(); - } - - int indexOf(QQuickItem *item) const { - for (int i = 0; i < children.count(); ++i) - if (children.at(i).item == item) - return i; - return -1; - } - - - QList<Item> children; -}; - - -/*! - \qmltype VisualItemModel - \instantiates QQuickVisualItemModel - \inqmlmodule QtQuick 2 - \ingroup qtquick-models - \brief Defines items to be used added to a view - - A VisualItemModel contains the visual items to be used in a view. - When a VisualItemModel is used in a view, the view does not require - a delegate since the VisualItemModel already contains the visual - delegate (items). - - An item can determine its index within the - model via the \l{VisualItemModel::index}{index} attached property. - - The example below places three colored rectangles in a ListView. - \code - import QtQuick 2.0 - - Rectangle { - VisualItemModel { - id: itemModel - Rectangle { height: 30; width: 80; color: "red" } - Rectangle { height: 30; width: 80; color: "green" } - Rectangle { height: 30; width: 80; color: "blue" } - } - - ListView { - anchors.fill: parent - model: itemModel - } - } - \endcode - - \image visualitemmodel.png - - \sa {quick/modelviews/visualitemmodel}{VisualItemModel example} -*/ -QQuickVisualItemModel::QQuickVisualItemModel(QObject *parent) - : QQuickVisualModel(*(new QQuickVisualItemModelPrivate), parent) -{ -} - -/*! - \qmlattachedproperty int QtQuick2::VisualItemModel::index - This attached property holds the index of this delegate's item within the model. - - It is attached to each instance of the delegate. -*/ - -QQmlListProperty<QQuickItem> QQuickVisualItemModel::children() -{ - Q_D(QQuickVisualItemModel); - return QQmlListProperty<QQuickItem>(this, - d, - d->children_append, - d->children_count, - d->children_at, - d->children_clear); -} - -/*! - \qmlproperty int QtQuick2::VisualItemModel::count - - The number of items in the model. This property is readonly. -*/ -int QQuickVisualItemModel::count() const -{ - Q_D(const QQuickVisualItemModel); - return d->children.count(); -} - -bool QQuickVisualItemModel::isValid() const -{ - return true; -} - -QQuickItem *QQuickVisualItemModel::item(int index, bool) -{ - Q_D(QQuickVisualItemModel); - QQuickVisualItemModelPrivate::Item &item = d->children[index]; - item.addRef(); - if (item.ref == 1) { - emit initItem(index, item.item); - emit createdItem(index, item.item); - } - return item.item; -} - -QQuickVisualModel::ReleaseFlags QQuickVisualItemModel::release(QQuickItem *item) -{ - Q_D(QQuickVisualItemModel); - int idx = d->indexOf(item); - if (idx >= 0) { - if (d->children[idx].deref()) { - // XXX todo - the original did item->scene()->removeItem(). Why? - item->setParentItem(0); - } else { - return QQuickVisualModel::Referenced; - } - } - return 0; -} - -QString QQuickVisualItemModel::stringValue(int index, const QString &name) -{ - Q_D(QQuickVisualItemModel); - if (index < 0 || index >= d->children.count()) - return QString(); - return QQmlEngine::contextForObject(d->children.at(index).item)->contextProperty(name).toString(); -} - -int QQuickVisualItemModel::indexOf(QQuickItem *item, QObject *) const -{ - Q_D(const QQuickVisualItemModel); - return d->indexOf(item); -} - -QQuickVisualItemModelAttached *QQuickVisualItemModel::qmlAttachedProperties(QObject *obj) -{ - return QQuickVisualItemModelAttached::properties(obj); -} - -QT_END_NAMESPACE - diff --git a/src/quick/items/qquickvisualitemmodel_p.h b/src/quick/items/qquickvisualitemmodel_p.h deleted file mode 100644 index a5d50f9d38..0000000000 --- a/src/quick/items/qquickvisualitemmodel_p.h +++ /dev/null @@ -1,174 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQUICKVISUALITEMMODEL_P_H -#define QQUICKVISUALITEMMODEL_P_H - -#include <private/qtquickglobal_p.h> -#include <QtQml/qqml.h> -#include <QtCore/qobject.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickItem; -class QQuickChangeSet; - -class Q_QUICK_PRIVATE_EXPORT QQuickVisualModel : public QObject -{ - Q_OBJECT - - Q_PROPERTY(int count READ count NOTIFY countChanged) - -public: - virtual ~QQuickVisualModel() {} - - enum ReleaseFlag { Referenced = 0x01, Destroyed = 0x02 }; - Q_DECLARE_FLAGS(ReleaseFlags, ReleaseFlag) - - virtual int count() const = 0; - virtual bool isValid() const = 0; - virtual QQuickItem *item(int index, bool asynchronous=false) = 0; - virtual ReleaseFlags release(QQuickItem *item) = 0; - virtual void cancel(int) {} - virtual QString stringValue(int, const QString &) = 0; - virtual void setWatchedRoles(QList<QByteArray> roles) = 0; - - virtual int indexOf(QQuickItem *item, QObject *objectContext) const = 0; - -Q_SIGNALS: - void countChanged(); - void modelUpdated(const QQuickChangeSet &changeSet, bool reset); - void createdItem(int index, QQuickItem *item); - void initItem(int index, QQuickItem *item); - void destroyingItem(QQuickItem *item); - -protected: - QQuickVisualModel(QObjectPrivate &dd, QObject *parent = 0) - : QObject(dd, parent) {} - -private: - Q_DISABLE_COPY(QQuickVisualModel) -}; - -class QQuickVisualItemModelAttached; -class QQuickVisualItemModelPrivate; -class Q_QUICK_PRIVATE_EXPORT QQuickVisualItemModel : public QQuickVisualModel -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QQuickVisualItemModel) - - Q_PROPERTY(QQmlListProperty<QQuickItem> children READ children NOTIFY childrenChanged DESIGNABLE false) - Q_CLASSINFO("DefaultProperty", "children") - -public: - QQuickVisualItemModel(QObject *parent=0); - virtual ~QQuickVisualItemModel() {} - - virtual int count() const; - virtual bool isValid() const; - virtual QQuickItem *item(int index, bool asynchronous=false); - virtual ReleaseFlags release(QQuickItem *item); - virtual QString stringValue(int index, const QString &role); - virtual void setWatchedRoles(QList<QByteArray>) {} - - virtual int indexOf(QQuickItem *item, QObject *objectContext) const; - - QQmlListProperty<QQuickItem> children(); - - static QQuickVisualItemModelAttached *qmlAttachedProperties(QObject *obj); - -Q_SIGNALS: - void childrenChanged(); - -private: - Q_DISABLE_COPY(QQuickVisualItemModel) -}; - -class QQuickVisualItemModelAttached : public QObject -{ - Q_OBJECT - -public: - QQuickVisualItemModelAttached(QObject *parent) - : QObject(parent), m_index(0) {} - ~QQuickVisualItemModelAttached() { - attachedProperties.remove(parent()); - } - - Q_PROPERTY(int index READ index NOTIFY indexChanged) - int index() const { return m_index; } - void setIndex(int idx) { - if (m_index != idx) { - m_index = idx; - emit indexChanged(); - } - } - - static QQuickVisualItemModelAttached *properties(QObject *obj) { - QQuickVisualItemModelAttached *rv = attachedProperties.value(obj); - if (!rv) { - rv = new QQuickVisualItemModelAttached(obj); - attachedProperties.insert(obj, rv); - } - return rv; - } - -Q_SIGNALS: - void indexChanged(); - -public: - int m_index; - - static QHash<QObject*, QQuickVisualItemModelAttached*> attachedProperties; -}; - - -QT_END_NAMESPACE - -QML_DECLARE_TYPE(QQuickVisualModel) -QML_DECLARE_TYPE(QQuickVisualItemModel) -QML_DECLARE_TYPEINFO(QQuickVisualItemModel, QML_HAS_ATTACHED_PROPERTIES) - -QT_END_HEADER - -#endif // QQUICKVISUALITEMMODEL_P_H diff --git a/src/quick/util/qquickchangeset.cpp b/src/quick/util/qquickchangeset.cpp deleted file mode 100644 index d416749d52..0000000000 --- a/src/quick/util/qquickchangeset.cpp +++ /dev/null @@ -1,621 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickchangeset_p.h" - -QT_BEGIN_NAMESPACE - - -/*! - \class QQuickChangeSet - \brief The QQuickChangeSet class stores an ordered list of notifications about - changes to a linear data set. - \internal - - QQuickChangeSet can be used to record a series of notications about items in an indexed list - being inserted, removed, moved, and changed. Notifications in the set are re-ordered so that - all notifications of a single type are grouped together and sorted in order of ascending index, - with remove notifications preceding all others, followed by insert notification, and then - change notifications. - - Moves in a change set are represented by a remove notification paired with an insert - notification by way of a shared unique moveId. Re-ordering may result in one or both of the - paired notifications being divided, when this happens the offset member of the notification - will indicate the relative offset of the divided notification from the beginning of the - original. -*/ - -/*! - Constructs an empty change set. -*/ - -QQuickChangeSet::QQuickChangeSet() - : m_difference(0) -{ -} - -/*! - Constructs a copy of a \a changeSet. -*/ - -QQuickChangeSet::QQuickChangeSet(const QQuickChangeSet &changeSet) - : m_removes(changeSet.m_removes) - , m_inserts(changeSet.m_inserts) - , m_changes(changeSet.m_changes) - , m_difference(changeSet.m_difference) -{ -} - -/*! - Destroys a change set. -*/ - -QQuickChangeSet::~QQuickChangeSet() -{ -} - -/*! - Assigns the value of a \a changeSet to another. -*/ - -QQuickChangeSet &QQuickChangeSet::operator =(const QQuickChangeSet &changeSet) -{ - m_removes = changeSet.m_removes; - m_inserts = changeSet.m_inserts; - m_changes = changeSet.m_changes; - m_difference = changeSet.m_difference; - return *this; -} - -/*! - Appends a notification that \a count items were inserted at \a index. -*/ - -void QQuickChangeSet::insert(int index, int count) -{ - insert(QVector<Insert>() << Insert(index, count)); -} - -/*! - Appends a notification that \a count items were removed at \a index. -*/ - -void QQuickChangeSet::remove(int index, int count) -{ - QVector<Remove> removes; - removes.append(Remove(index, count)); - remove(&removes, 0); -} - -/*! - Appends a notification that \a count items were moved \a from one index \a to another. - - The \a moveId must be unique across the lifetime of the change set and any related - change sets. -*/ - -void QQuickChangeSet::move(int from, int to, int count, int moveId) -{ - QVector<Remove> removes; - removes.append(Remove(from, count, moveId)); - QVector<Insert> inserts; - inserts.append(Insert(to, count, moveId)); - remove(&removes, &inserts); - insert(inserts); -} - -/*! - Appends a notification that \a count items were changed at \a index. -*/ - -void QQuickChangeSet::change(int index, int count) -{ - QVector<Change> changes; - changes.append(Change(index, count)); - change(changes); -} - -/*! - Applies the changes in a \a changeSet to another. -*/ - -void QQuickChangeSet::apply(const QQuickChangeSet &changeSet) -{ - QVector<Remove> r = changeSet.m_removes; - QVector<Insert> i = changeSet.m_inserts; - QVector<Change> c = changeSet.m_changes; - remove(&r, &i); - insert(i); - change(c); -} - -/*! - Applies a list of \a removes to a change set. - - If a remove contains a moveId then any intersecting insert in the set will replace the - corresponding intersection in the optional \a inserts list. -*/ - -void QQuickChangeSet::remove(const QVector<Remove> &removes, QVector<Insert> *inserts) -{ - QVector<Remove> r = removes; - remove(&r, inserts); -} - -void QQuickChangeSet::remove(QVector<Remove> *removes, QVector<Insert> *inserts) -{ - int removeCount = 0; - int insertCount = 0; - QVector<Insert>::iterator insert = m_inserts.begin(); - QVector<Change>::iterator change = m_changes.begin(); - QVector<Remove>::iterator rit = removes->begin(); - for (; rit != removes->end(); ++rit) { - int index = rit->index + removeCount; - int count = rit->count; - - // Decrement the accumulated remove count from the indexes of any changes prior to the - // current remove. - for (; change != m_changes.end() && change->end() < rit->index; ++change) - change->index -= removeCount; - // Remove any portion of a change notification that intersects the current remove. - for (; change != m_changes.end() && change->index > rit->end(); ++change) { - change->count -= qMin(change->end(), rit->end()) - qMax(change->index, rit->index); - if (change->count == 0) { - change = m_changes.erase(change); - } else if (rit->index < change->index) { - change->index = rit->index; - } - } - - // Decrement the accumulated remove count from the indexes of any inserts prior to the - // current remove. - for (; insert != m_inserts.end() && insert->end() <= index; ++insert) { - insertCount += insert->count; - insert->index -= removeCount; - } - - rit->index -= insertCount; - - // Remove any portion of a insert notification that intersects the current remove. - while (insert != m_inserts.end() && insert->index < index + count) { - int offset = index - insert->index; - const int difference = qMin(insert->end(), index + count) - qMax(insert->index, index); - - // If part of the remove or insert that precedes the intersection has a moveId create - // a new delta for that portion and subtract the size of that delta from the current - // one. - if (offset < 0 && rit->moveId != -1) { - rit = removes->insert(rit, Remove( - rit->index, -offset, rit->moveId, rit->offset)); - ++rit; - rit->count -= -offset; - rit->offset += -offset; - index += -offset; - count -= -offset; - removeCount += -offset; - offset = 0; - } else if (offset > 0 && insert->moveId != -1) { - insert = m_inserts.insert(insert, Insert( - insert->index - removeCount, offset, insert->moveId, insert->offset)); - ++insert; - insert->index += offset; - insert->count -= offset; - insert->offset += offset; - rit->index -= offset; - insertCount += offset; - } - - // If the current remove has a move id, find any inserts with the same move id and - // replace the corresponding sections with the insert removed from the change set. - if (rit->moveId != -1 && difference > 0 && inserts) { - for (QVector<Insert>::iterator iit = inserts->begin(); iit != inserts->end(); ++iit) { - if (iit->moveId != rit->moveId - || rit->offset > iit->offset + iit->count - || iit->offset > rit->offset + difference) { - continue; - } - // If the intersecting insert starts before the replacement one create - // a new insert for the portion prior to the replacement insert. - const int overlapOffset = rit->offset - iit->offset; - if (overlapOffset > 0) { - iit = inserts->insert(iit, Insert( - iit->index, overlapOffset, iit->moveId, iit->offset)); - ++iit; - iit->index += overlapOffset; - iit->count -= overlapOffset; - iit->offset += overlapOffset; - } - if (iit->offset >= rit->offset - && iit->offset + iit->count <= rit->offset + difference) { - // If the replacement insert completely encapsulates the existing - // one just change the moveId. - iit->moveId = insert->moveId; - iit->offset = insert->offset + qMax(0, -overlapOffset); - } else { - // Create a new insertion before the intersecting one with the number of intersecting - // items and remove that number from that insert. - const int count - = qMin(iit->offset + iit->count, rit->offset + difference) - - qMax(iit->offset, rit->offset); - iit = inserts->insert(iit, Insert( - iit->index, - count, - insert->moveId, - insert->offset + qMax(0, -overlapOffset))); - ++iit; - iit->index += count; - iit->count -= count; - iit->offset += count; - } - } - } - - // Subtract the number of intersecting items from the current remove and insert. - insert->count -= difference; - insert->offset += difference; - rit->count -= difference; - rit->offset += difference; - - index += difference; - count -= difference; - removeCount += difference; - - if (insert->count == 0) { - insert = m_inserts.erase(insert); - } else if (rit->count == -offset || rit->count == 0) { - insert->index += difference; - break; - } else { - insert->index -= removeCount - difference; - rit->index -= insert->count; - insertCount += insert->count; - ++insert; - } - } - removeCount += rit->count; - } - for (; insert != m_inserts.end(); ++insert) - insert->index -= removeCount; - - removeCount = 0; - QVector<Remove>::iterator remove = m_removes.begin(); - for (rit = removes->begin(); rit != removes->end(); ++rit) { - if (rit->count == 0) - continue; - // Accumulate consecutive removes into a single delta before attempting to apply. - for (QVector<Remove>::iterator next = rit + 1; next != removes->end() - && next->index == rit->index - && next->moveId == -1 - && rit->moveId == -1; ++next) { - next->count += rit->count; - rit = next; - } - int index = rit->index + removeCount; - // Decrement the accumulated remove count from the indexes of any inserts prior to the - // current remove. - for (; remove != m_removes.end() && index > remove->index; ++remove) - remove->index -= removeCount; - while (remove != m_removes.end() && index + rit->count >= remove->index) { - int count = 0; - const int offset = remove->index - index; - QVector<Remove>::iterator rend = remove; - for (; rend != m_removes.end() - && rit->moveId == -1 - && rend->moveId == -1 - && index + rit->count >= rend->index; ++rend) { - count += rend->count; - } - if (remove != rend) { - // Accumulate all existing non-move removes that are encapsulated by or immediately - // follow the current remove into it. - int difference = 0; - if (rend == m_removes.end()) { - difference = rit->count; - } else if (rit->index + rit->count < rend->index - removeCount) { - difference = rit->count; - } else if (rend->moveId != -1) { - difference = rend->index - removeCount - rit->index; - index += difference; - } - count += difference; - - rit->count -= difference; - removeCount += difference; - remove->index = rit->index; - remove->count = count; - remove = m_removes.erase(++remove, rend); - } else { - // Insert a remove for the portion of the unmergable current remove prior to the - // point of intersection. - if (offset > 0) { - remove = m_removes.insert(remove, Remove( - rit->index, offset, rit->moveId, rit->offset)); - ++remove; - rit->count -= offset; - rit->offset += offset; - removeCount += offset; - index += offset; - } - remove->index = rit->index; - - ++remove; - } - } - - if (rit->count > 0) { - remove = m_removes.insert(remove, *rit); - ++remove; - } - removeCount += rit->count; - } - for (; remove != m_removes.end(); ++remove) - remove->index -= removeCount; - m_difference -= removeCount; -} - -/*! - Applies a list of \a inserts to a change set. -*/ - -void QQuickChangeSet::insert(const QVector<Insert> &inserts) -{ - int insertCount = 0; - QVector<Insert>::iterator insert = m_inserts.begin(); - QVector<Change>::iterator change = m_changes.begin(); - for (QVector<Insert>::const_iterator iit = inserts.begin(); iit != inserts.end(); ++iit) { - if (iit->count == 0) - continue; - int index = iit->index - insertCount; - - Insert current = *iit; - // Accumulate consecutive inserts into a single delta before attempting to insert. - for (QVector<Insert>::const_iterator next = iit + 1; next != inserts.end() - && next->index == iit->index + iit->count - && next->moveId == -1 - && iit->moveId == -1; ++next) { - current.count += next->count; - iit = next; - } - - // Increment the index of any changes before the current insert by the accumlated insert - // count. - for (; change != m_changes.end() && change->index >= index; ++change) - change->index += insertCount; - // If the current insert index is in the middle of a change split it in two at that - // point and increment the index of the latter half. - if (change != m_changes.end() && change->index < index + iit->count) { - int offset = index - change->index; - change = m_changes.insert(change, Change(change->index + insertCount, offset)); - ++change; - change->index += iit->count + offset; - change->count -= offset; - } - - // Increment the index of any inserts before the current insert by the accumlated insert - // count. - for (; insert != m_inserts.end() && index > insert->index + insert->count; ++insert) - insert->index += insertCount; - if (insert == m_inserts.end()) { - insert = m_inserts.insert(insert, current); - ++insert; - } else { - const int offset = index - insert->index; - - if (offset < 0) { - // If the current insert is before an existing insert and not adjacent just insert - // it into the list. - insert = m_inserts.insert(insert, current); - ++insert; - } else if (iit->moveId == -1 && insert->moveId == -1) { - // If neither the current nor existing insert has a moveId add the current insert - // to the existing one. - if (offset < insert->count) { - insert->index -= current.count; - insert->count += current.count; - } else { - insert->index += insertCount; - insert->count += current.count; - ++insert; - } - } else if (offset < insert->count) { - // If either insert has a moveId then split the existing insert and insert the - // current one in the middle. - if (offset > 0) { - insert = m_inserts.insert(insert, Insert( - insert->index + insertCount, offset, insert->moveId, insert->offset)); - ++insert; - insert->index += offset; - insert->count -= offset; - insert->offset += offset; - } - insert = m_inserts.insert(insert, current); - ++insert; - } else { - insert->index += insertCount; - ++insert; - insert = m_inserts.insert(insert, current); - ++insert; - } - } - insertCount += current.count; - } - for (; insert != m_inserts.end(); ++insert) - insert->index += insertCount; - m_difference += insertCount; -} - -/*! - Applies a combined list of \a removes and \a inserts to a change set. This is equivalent - calling \l remove() followed by \l insert() with the same lists. -*/ - -void QQuickChangeSet::move(const QVector<Remove> &removes, const QVector<Insert> &inserts) -{ - QVector<Remove> r = removes; - QVector<Insert> i = inserts; - remove(&r, &i); - insert(i); -} - -/*! - Applies a list of \a changes to a change set. -*/ - -void QQuickChangeSet::change(const QVector<Change> &changes) -{ - QVector<Change> c = changes; - change(&c); -} - -void QQuickChangeSet::change(QVector<Change> *changes) -{ - QVector<Insert>::iterator insert = m_inserts.begin(); - QVector<Change>::iterator change = m_changes.begin(); - for (QVector<Change>::iterator cit = changes->begin(); cit != changes->end(); ++cit) { - for (; insert != m_inserts.end() && insert->end() < cit->index; ++insert) {} - for (; insert != m_inserts.end() && insert->index < cit->end(); ++insert) { - const int offset = insert->index - cit->index; - const int count = cit->count + cit->index - insert->index - insert->count; - if (offset == 0) { - cit->index = insert->index + insert->count; - cit->count = count; - } else { - cit = changes->insert(++cit, Change(insert->index + insert->count, count)); - --cit; - cit->count = offset; - } - } - - for (; change != m_changes.end() && change->index + change->count < cit->index; ++change) {} - if (change == m_changes.end() || change->index > cit->index + cit->count) { - if (cit->count > 0) { - change = m_changes.insert(change, *cit); - ++change; - } - } else { - if (cit->index < change->index) { - change->count += change->index - cit->index; - change->index = cit->index; - } - - if (cit->index + cit->count > change->index + change->count) { - change->count = cit->index + cit->count - change->index; - QVector<Change>::iterator cbegin = change; - QVector<Change>::iterator cend = ++cbegin; - for (; cend != m_changes.end() && cend->index <= change->index + change->count; ++cend) { - if (cend->index + cend->count > change->index + change->count) - change->count = cend->index + cend->count - change->index; - } - if (cbegin != cend) { - change = m_changes.erase(cbegin, cend); - --change; - } - } - } - } -} - -/*! - Prints the contents of a change \a set to the \a debug stream. -*/ - -QDebug operator <<(QDebug debug, const QQuickChangeSet &set) -{ - debug.nospace() << "QQuickChangeSet("; - foreach (const QQuickChangeSet::Remove &remove, set.removes()) debug << remove; - foreach (const QQuickChangeSet::Insert &insert, set.inserts()) debug << insert; - foreach (const QQuickChangeSet::Change &change, set.changes()) debug << change; - return debug.nospace() << ')'; -} - -/*! - Prints a \a remove to the \a debug stream. -*/ - -QDebug operator <<(QDebug debug, const QQuickChangeSet::Remove &remove) -{ - if (remove.moveId == -1) { - return (debug.nospace() - << "Remove(" << remove.index - << ',' << remove.count - << ')').space(); - } else { - return (debug.nospace() - << "Remove(" << remove.index - << ',' << remove.count - << ',' << remove.moveId - << ',' << remove.offset - << ')').space(); - } -} - -/*! - Prints an \a insert to the \a debug stream. -*/ - -QDebug operator <<(QDebug debug, const QQuickChangeSet::Insert &insert) -{ - if (insert.moveId == -1) { - return (debug.nospace() - << "Insert(" << insert.index - << ',' << insert.count - << ')').space(); - } else { - return (debug.nospace() - << "Insert(" << insert.index - << ',' << insert.count - << ',' << insert.moveId - << ',' << insert.offset - << ')').space(); - } -} - -/*! - Prints a \a change to the \a debug stream. -*/ - -QDebug operator <<(QDebug debug, const QQuickChangeSet::Change &change) -{ - return (debug.nospace() << "Change(" << change.index << ',' << change.count << ')').space(); -} - -QT_END_NAMESPACE - diff --git a/src/quick/util/qquickchangeset_p.h b/src/quick/util/qquickchangeset_p.h deleted file mode 100644 index 83b9023309..0000000000 --- a/src/quick/util/qquickchangeset_p.h +++ /dev/null @@ -1,166 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQUICKCHANGESET_P_H -#define QQUICKCHANGESET_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qdebug.h> -#include <QtCore/qvector.h> - -QT_BEGIN_NAMESPACE - -class Q_AUTOTEST_EXPORT QQuickChangeSet -{ -public: - struct MoveKey - { - MoveKey() : moveId(-1), offset(0) {} - MoveKey(int moveId, int offset) : moveId(moveId), offset(offset) {} - int moveId; - int offset; - }; - - struct Change - { - Change() : index(0), count(0), moveId(-1) {} - Change(int index, int count, int moveId = -1, int offset = 0) - : index(index), count(count), moveId(moveId), offset(offset) {} - - int index; - int count; - int moveId; - int offset; - - bool isMove() const { return moveId >= 0; } - - MoveKey moveKey(int index) const { - return MoveKey(moveId, index - Change::index + offset); } - - int start() const { return index; } - int end() const { return index + count; } - }; - - - struct Insert : public Change - { - Insert() {} - Insert(int index, int count, int moveId = -1, int offset = 0) - : Change(index, count, moveId, offset) {} - }; - - struct Remove : public Change - { - Remove() {} - Remove(int index, int count, int moveId = -1, int offset = 0) - : Change(index, count, moveId, offset) {} - }; - - QQuickChangeSet(); - QQuickChangeSet(const QQuickChangeSet &changeSet); - ~QQuickChangeSet(); - - QQuickChangeSet &operator =(const QQuickChangeSet &changeSet); - - const QVector<Remove> &removes() const { return m_removes; } - const QVector<Insert> &inserts() const { return m_inserts; } - const QVector<Change> &changes() const { return m_changes; } - - void insert(int index, int count); - void remove(int index, int count); - void move(int from, int to, int count, int moveId); - void change(int index, int count); - - void insert(const QVector<Insert> &inserts); - void remove(const QVector<Remove> &removes, QVector<Insert> *inserts = 0); - void move(const QVector<Remove> &removes, const QVector<Insert> &inserts); - void change(const QVector<Change> &changes); - void apply(const QQuickChangeSet &changeSet); - - bool isEmpty() const { return m_removes.empty() && m_inserts.empty() && m_changes.isEmpty(); } - - void clear() - { - m_removes.clear(); - m_inserts.clear(); - m_changes.clear(); - m_difference = 0; - } - - int difference() const { return m_difference; } - -private: - void remove(QVector<Remove> *removes, QVector<Insert> *inserts); - void change(QVector<Change> *changes); - - QVector<Remove> m_removes; - QVector<Insert> m_inserts; - QVector<Change> m_changes; - int m_difference; -}; - -Q_DECLARE_TYPEINFO(QQuickChangeSet::Change, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QQuickChangeSet::Remove, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QQuickChangeSet::Insert, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QQuickChangeSet::MoveKey, Q_PRIMITIVE_TYPE); - -inline uint qHash(const QQuickChangeSet::MoveKey &key) { return qHash(qMakePair(key.moveId, key.offset)); } -inline bool operator ==(const QQuickChangeSet::MoveKey &l, const QQuickChangeSet::MoveKey &r) { - return l.moveId == r.moveId && l.offset == r.offset; } - -Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQuickChangeSet::Remove &remove); -Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQuickChangeSet::Insert &insert); -Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQuickChangeSet::Change &change); -Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQuickChangeSet &change); - -QT_END_NAMESPACE - -#endif diff --git a/src/quick/util/qquicklistaccessor.cpp b/src/quick/util/qquicklistaccessor.cpp deleted file mode 100644 index 5cd6c77770..0000000000 --- a/src/quick/util/qquicklistaccessor.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquicklistaccessor_p.h" - -#include <private/qqmlmetatype_p.h> - -#include <QtCore/qstringlist.h> -#include <QtCore/qdebug.h> - -// ### Remove me -#include <private/qqmlengine_p.h> - -QT_BEGIN_NAMESPACE - -QQuickListAccessor::QQuickListAccessor() -: m_type(Invalid) -{ -} - -QQuickListAccessor::~QQuickListAccessor() -{ -} - -QVariant QQuickListAccessor::list() const -{ - return d; -} - -void QQuickListAccessor::setList(const QVariant &v, QQmlEngine *engine) -{ - d = v; - - QQmlEnginePrivate *enginePrivate = engine?QQmlEnginePrivate::get(engine):0; - - if (!d.isValid()) { - m_type = Invalid; - } else if (d.userType() == QVariant::StringList) { - m_type = StringList; - } else if (d.userType() == QMetaType::QVariantList) { - m_type = VariantList; - } else if (d.canConvert(QVariant::Int)) { - m_type = Integer; - } else if ((!enginePrivate && QQmlMetaType::isQObject(d.userType())) || - (enginePrivate && enginePrivate->isQObject(d.userType()))) { - QObject *data = enginePrivate?enginePrivate->toQObject(v):QQmlMetaType::toQObject(v); - d = QVariant::fromValue(data); - m_type = Instance; - } else if (d.userType() == qMetaTypeId<QQmlListReference>()) { - m_type = ListProperty; - } else { - m_type = Instance; - } -} - -int QQuickListAccessor::count() const -{ - switch(m_type) { - case StringList: - return qvariant_cast<QStringList>(d).count(); - case VariantList: - return qvariant_cast<QVariantList>(d).count(); - case ListProperty: - return ((QQmlListReference *)d.constData())->count(); - case Instance: - return 1; - case Integer: - return d.toInt(); - default: - case Invalid: - return 0; - } -} - -QVariant QQuickListAccessor::at(int idx) const -{ - Q_ASSERT(idx >= 0 && idx < count()); - switch(m_type) { - case StringList: - return QVariant::fromValue(qvariant_cast<QStringList>(d).at(idx)); - case VariantList: - return qvariant_cast<QVariantList>(d).at(idx); - case ListProperty: - return QVariant::fromValue(((QQmlListReference *)d.constData())->at(idx)); - case Instance: - return d; - case Integer: - return QVariant(idx); - default: - case Invalid: - return QVariant(); - } -} - -bool QQuickListAccessor::isValid() const -{ - return m_type != Invalid; -} - -QT_END_NAMESPACE diff --git a/src/quick/util/qquicklistaccessor_p.h b/src/quick/util/qquicklistaccessor_p.h deleted file mode 100644 index 0a2957a9cc..0000000000 --- a/src/quick/util/qquicklistaccessor_p.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQUICKLISTACCESSOR_H -#define QQUICKLISTACCESSOR_H - -#include <QtCore/QVariant> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQmlEngine; -class Q_AUTOTEST_EXPORT QQuickListAccessor -{ -public: - QQuickListAccessor(); - ~QQuickListAccessor(); - - QVariant list() const; - void setList(const QVariant &, QQmlEngine * = 0); - - bool isValid() const; - - int count() const; - QVariant at(int) const; - - enum Type { Invalid, StringList, VariantList, ListProperty, Instance, Integer }; - Type type() const { return m_type; } - -private: - Type m_type; - QVariant d; -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QQUICKLISTACCESSOR_H diff --git a/src/quick/util/qquicklistcompositor.cpp b/src/quick/util/qquicklistcompositor.cpp deleted file mode 100644 index a9e9acee23..0000000000 --- a/src/quick/util/qquicklistcompositor.cpp +++ /dev/null @@ -1,1484 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquicklistcompositor_p.h" - -#include <QtCore/qvarlengtharray.h> - -//#define QT_QML_VERIFY_MINIMAL -//#define QT_QML_VERIFY_INTEGRITY - -QT_BEGIN_NAMESPACE - -/*! - \class QQuickListCompositor - \brief The QQuickListCompositor class provides a lookup table for filtered, or re-ordered list - indexes. - \internal - - QQuickListCompositor is intended as an aid for developing proxy models. It doesn't however - directly proxy a list or model, instead a range of indexes from one or many lists can be - inserted into the compositor and then categorized and shuffled around and it will manage the - task of translating from an index in the combined space into an index in a particular list. - - Within a compositor indexes are categorized into groups where a group is a sub-set of the - total indexes referenced by the compositor, each with an address space ranging from 0 to - the number of indexes in the group - 1. Group memberships are independent of each other with - the one exception that items always retain the same order so if an index is moved within a - group, its position in other groups will change as well. - - The iterator classes encapsulate information about a specific position in a compositor group. - This includes a source list, the index of an item within that list and the groups that item - is a member of. The iterator for a specific position in a group can be retrieved with the - find() function and the addition and subtraction operators of the iterators can be used to - navigate to adjacent items in the same group. - - Items can be added to the compositor with the append() and insert() functions, group - membership can be changed with the setFlags() and clearFlags() functions, and the position - of items in the compositor can be changed with the move() function. Each of these functions - optionally returns a list of the changes made to indexes within each group which can then - be propagated to view so that it can correctly refresh its contents; e.g. 3 items - removed at index 6, and 5 items inserted at index 1. The notification changes are always - ordered from the start of the list to the end and accumulate, so if 5 items are removed at - index 4, one is skipped and then 3 move are removed, the changes returned are 5 items removed - at index 4, followed by 3 items removed at index 4. - - When the contents of a source list change, the mappings within the compositor can be updated - with the listItemsInserted(), listItemsRemoved(), listItemsMoved(), and listItemsChanged() - functions. Like the direct manipulation functions these too return a list of group indexes - affected by the change. If items are removed from a source list they are also removed from - any groups they belong to with the one exception being items belonging to the \l Cache group. - When items belonging to this group are removed the list, index, and other group membership - information are discarded but Cache membership is retained until explicitly removed. This - allows the cache index to be retained until cached resources for that item are actually - released. - - Internally the index mapping is stored as a list of Range objects, each has a list identifier, - a start index, a count, and a set of flags which represent group membership and some other - properties. The group index of a range is the sum of all preceding ranges that are members of - that group. To avoid the inefficiency of iterating over potentially all ranges when looking - for a specific index, each time a lookup is done the range and its indexes are cached and the - next lookup is done relative to this. This works out to near constant time in most relevant - use cases because successive index lookups are most frequently adjacent. The total number of - ranges is often quite small, which helps as well. If there is a need for faster random access - then a skip list like index may be an appropriate addition. - - \sa VisualDataModel -*/ - -#ifdef QT_QML_VERIFY_MINIMAL -#define QT_QML_VERIFY_INTEGRITY -/* - Diagnostic to verify there are no consecutive ranges, or that the compositor contains the - most compact representation possible. - - Returns false and prints a warning if any range has a starting index equal to the end - (index + count) index of the previous range, and both ranges also have the same flags and list - property. - - If there are no consecutive ranges this will return true. -*/ - -static bool qt_verifyMinimal( - const QQuickListCompositor::iterator &begin, - const QQuickListCompositor::iterator &end) -{ - bool minimal = true; - int index = 0; - - for (const QQuickListCompositor::Range *range = begin->next; range != *end; range = range->next, ++index) { - if (range->previous->list == range->list - && range->previous->flags == (range->flags & ~QQuickListCompositor::AppendFlag) - && range->previous->end() == range->index) { - qWarning() << index << "Consecutive ranges"; - qWarning() << *range->previous; - qWarning() << *range; - minimal = false; - } - } - - return minimal; -} - -#endif - -#ifdef QT_QML_VERIFY_INTEGRITY -static bool qt_printInfo(const QQuickListCompositor &compositor) -{ - qWarning() << compositor; - return true; -} - -/* - Diagnostic to verify the integrity of a compositor. - - Per range this verifies there are no invalid range combinations, that non-append ranges have - positive non-zero counts, and that list ranges have non-negative indexes. - - Accumulatively this verifies that the cached total group counts match the sum of counts - of member ranges. -*/ - -static bool qt_verifyIntegrity( - const QQuickListCompositor::iterator &begin, - const QQuickListCompositor::iterator &end, - const QQuickListCompositor::iterator &cachedIt) -{ - bool valid = true; - - int index = 0; - QQuickListCompositor::iterator it; - for (it = begin; *it != *end; *it = it->next) { - if (it->count == 0 && !it->append()) { - qWarning() << index << "Empty non-append range"; - valid = false; - } - if (it->count < 0) { - qWarning() << index << "Negative count"; - valid = false; - } - if (it->list && it->flags != QQuickListCompositor::CacheFlag && it->index < 0) { - qWarning() << index <<"Negative index"; - valid = false; - } - if (it->previous->next != it.range) { - qWarning() << index << "broken list: it->previous->next != it.range"; - valid = false; - } - if (it->next->previous != it.range) { - qWarning() << index << "broken list: it->next->previous != it.range"; - valid = false; - } - if (*it == *cachedIt) { - for (int i = 0; i < end.groupCount; ++i) { - int groupIndex = it.index[i]; - if (cachedIt->flags & (1 << i)) - groupIndex += cachedIt.offset; - if (groupIndex != cachedIt.index[i]) { - qWarning() << index - << "invalid cached index" - << QQuickListCompositor::Group(i) - << "Expected:" - << groupIndex - << "Actual" - << cachedIt.index[i] - << cachedIt; - valid = false; - } - } - } - it.incrementIndexes(it->count); - ++index; - } - - for (int i = 0; i < end.groupCount; ++i) { - if (end.index[i] != it.index[i]) { - qWarning() << "Group" << i << "count invalid. Expected:" << end.index[i] << "Actual:" << it.index[i]; - valid = false; - } - } - return valid; -} -#endif - -#if defined(QT_QML_VERIFY_MINIMAL) -# define QT_QML_VERIFY_LISTCOMPOSITOR Q_ASSERT(!(!(qt_verifyIntegrity(iterator(m_ranges.next, 0, Default, m_groupCount), m_end, m_cacheIt) \ - && qt_verifyMinimal(iterator(m_ranges.next, 0, Default, m_groupCount), m_end)) \ - && qt_printInfo(*this))); -#elif defined(QT_QML_VERIFY_INTEGRITY) -# define QT_QML_VERIFY_LISTCOMPOSITOR Q_ASSERT(!(!qt_verifyIntegrity(iterator(m_ranges.next, 0, Default, m_groupCount), m_end, m_cacheIt) \ - && qt_printInfo(*this))); -#else -# define QT_QML_VERIFY_LISTCOMPOSITOR -#endif - -//#define QT_QML_TRACE_LISTCOMPOSITOR(args) qDebug() << m_end.index[1] << m_end.index[0] << Q_FUNC_INFO args; -#define QT_QML_TRACE_LISTCOMPOSITOR(args) - -QQuickListCompositor::iterator &QQuickListCompositor::iterator::operator +=(int difference) -{ - // Update all indexes to the start of the range. - decrementIndexes(offset); - - // If the iterator group isn't a member of the current range ignore the current offset. - if (!(range->flags & groupFlag)) - offset = 0; - - offset += difference; - - // Iterate backwards looking for a range with a positive offset. - while (offset <= 0 && range->previous->flags) { - range = range->previous; - if (range->flags & groupFlag) - offset += range->count; - decrementIndexes(range->count); - } - - // Iterate forwards looking for the first range which contains both the offset and the - // iterator group. - while (range->flags && (offset >= range->count || !(range->flags & groupFlag))) { - if (range->flags & groupFlag) - offset -= range->count; - incrementIndexes(range->count); - range = range->next; - } - - // Update all the indexes to inclue the remaining offset. - incrementIndexes(offset); - - return *this; -} - -QQuickListCompositor::insert_iterator &QQuickListCompositor::insert_iterator::operator +=(int difference) -{ - iterator::operator +=(difference); - - // If the previous range contains the append flag move the iterator to the tail of the previous - // range so that appended appear after the insert position. - if (offset == 0 && range->previous->append()) { - range = range->previous; - offset = range->inGroup() ? range->count : 0; - } - - return *this; -} - - -/*! - Constructs an empty list compositor. -*/ - -QQuickListCompositor::QQuickListCompositor() - : m_end(m_ranges.next, 0, Default, 2) - , m_cacheIt(m_end) - , m_groupCount(2) - , m_defaultFlags(PrependFlag | DefaultFlag) - , m_removeFlags(AppendFlag | PrependFlag | GroupMask) - , m_moveId(0) -{ -} - -/*! - Destroys a list compositor. -*/ - -QQuickListCompositor::~QQuickListCompositor() -{ - for (Range *next, *range = m_ranges.next; range != &m_ranges; range = next) { - next = range->next; - delete range; - } -} - -/*! - Inserts a range with the given source \a list, start \a index, \a count and \a flags, in front - of the existing range \a before. -*/ - -inline QQuickListCompositor::Range *QQuickListCompositor::insert( - Range *before, void *list, int index, int count, uint flags) -{ - return new Range(before, list, index, count, flags); -} - -/*! - Erases a \a range from the compositor. - - Returns a pointer to the next range in the compositor. -*/ - -inline QQuickListCompositor::Range *QQuickListCompositor::erase( - Range *range) -{ - Range *next = range->next; - next->previous = range->previous; - next->previous->next = range->next; - delete range; - return next; -} - -/*! - Sets the number (\a count) of possible groups that items may belong to in a compositor. -*/ - -void QQuickListCompositor::setGroupCount(int count) -{ - m_groupCount = count; - m_end = iterator(&m_ranges, 0, Default, m_groupCount); - m_cacheIt = m_end; -} - -/*! - Returns the number of items that belong to a \a group. -*/ - -int QQuickListCompositor::count(Group group) const -{ - return m_end.index[group]; -} - -/*! - Returns an iterator representing the item at \a index in a \a group. - - The index must be between 0 and count(group) - 1. -*/ - -QQuickListCompositor::iterator QQuickListCompositor::find(Group group, int index) -{ - QT_QML_TRACE_LISTCOMPOSITOR(<< group << index) - Q_ASSERT(index >=0 && index < count(group)); - if (m_cacheIt == m_end) { - m_cacheIt = iterator(m_ranges.next, 0, group, m_groupCount); - m_cacheIt += index; - } else { - const int offset = index - m_cacheIt.index[group]; - m_cacheIt.setGroup(group); - m_cacheIt += offset; - } - Q_ASSERT(m_cacheIt.index[group] == index); - Q_ASSERT(m_cacheIt->inGroup(group)); - QT_QML_VERIFY_LISTCOMPOSITOR - return m_cacheIt; -} - -/*! - Returns an iterator representing the item at \a index in a \a group. - - The index must be between 0 and count(group) - 1. -*/ - -QQuickListCompositor::iterator QQuickListCompositor::find(Group group, int index) const -{ - return const_cast<QQuickListCompositor *>(this)->find(group, index); -} - -/*! - Returns an iterator representing an insert position in front of the item at \a index in a - \a group. - - The iterator for an insert position can sometimes resolve to a different Range than a regular - iterator. This is because when items are inserted on a boundary between Ranges, if the first - range has the Append flag set then the items should be inserted into that range to ensure - that the append position for the existing range remains after the insert position. - - The index must be between 0 and count(group) - 1. -*/ - -QQuickListCompositor::insert_iterator QQuickListCompositor::findInsertPosition(Group group, int index) -{ - QT_QML_TRACE_LISTCOMPOSITOR(<< group << index) - Q_ASSERT(index >=0 && index <= count(group)); - insert_iterator it; - if (m_cacheIt == m_end) { - it = iterator(m_ranges.next, 0, group, m_groupCount); - it += index; - } else { - const int offset = index - m_cacheIt.index[group]; - it = m_cacheIt; - it.setGroup(group); - it += offset; - } - Q_ASSERT(it.index[group] == index); - return it; -} - -/*! - Appends a range of \a count indexes starting at \a index from a \a list into a compositor - with the given \a flags. - - If supplied the \a inserts list will be populated with the positions of the inserted items - in each group. -*/ - -void QQuickListCompositor::append( - void *list, int index, int count, uint flags, QVector<Insert> *inserts) -{ - QT_QML_TRACE_LISTCOMPOSITOR(<< list << index << count << flags) - insert(m_end, list, index, count, flags, inserts); -} - -/*! - Inserts a range of \a count indexes starting at \a index from a \a list with the given \a flags - into a \a group at index \a before. - - If supplied the \a inserts list will be populated with the positions of items inserted into - each group. -*/ - -void QQuickListCompositor::insert( - Group group, int before, void *list, int index, int count, uint flags, QVector<Insert> *inserts) -{ - QT_QML_TRACE_LISTCOMPOSITOR(<< group << before << list << index << count << flags) - insert(findInsertPosition(group, before), list, index, count, flags, inserts); -} - -/*! - Inserts a range of \a count indexes starting at \a index from a \a list with the given \a flags - into a compositor at position \a before. - - If supplied the \a inserts list will be populated with the positions of items inserted into - each group. -*/ - -QQuickListCompositor::iterator QQuickListCompositor::insert( - iterator before, void *list, int index, int count, uint flags, QVector<Insert> *inserts) -{ - QT_QML_TRACE_LISTCOMPOSITOR(<< before << list << index << count << flags) - if (inserts) { - inserts->append(Insert(before, count, flags & GroupMask)); - } - if (before.offset > 0) { - // Inserting into the middle of a range. Split it two and update the iterator so it's - // positioned at the start of the second half. - *before = insert( - *before, before->list, before->index, before.offset, before->flags & ~AppendFlag)->next; - before->index += before.offset; - before->count -= before.offset; - before.offset = 0; - } - - - if (!(flags & AppendFlag) && *before != m_ranges.next - && before->previous->list == list - && before->previous->flags == flags - && (!list || before->previous->end() == index)) { - // The insert arguments represent a continuation of the previous range so increment - // its count instead of inserting a new range. - before->previous->count += count; - before.incrementIndexes(count, flags); - } else { - *before = insert(*before, list, index, count, flags); - before.offset = 0; - } - - if (!(flags & AppendFlag) && before->next != &m_ranges - && before->list == before->next->list - && before->flags == before->next->flags - && (!list || before->end() == before->next->index)) { - // The current range and the next are continuous so add their counts and delete one. - before->next->index = before->index; - before->next->count += before->count; - *before = erase(*before); - } - - m_end.incrementIndexes(count, flags); - m_cacheIt = before; - QT_QML_VERIFY_LISTCOMPOSITOR - return before; -} - -/*! - Sets the given flags \a flags on \a count items belonging to \a group starting at the position - identified by \a fromGroup and the index \a from. - - If supplied the \a inserts list will be populated with insert notifications for affected groups. -*/ - -void QQuickListCompositor::setFlags( - Group fromGroup, int from, int count, Group group, int flags, QVector<Insert> *inserts) -{ - QT_QML_TRACE_LISTCOMPOSITOR(<< fromGroup << from << count << group << flags) - setFlags(find(fromGroup, from), count, group, flags, inserts); -} - -/*! - Sets the given flags \a flags on \a count items belonging to \a group starting at the position - \a from. - - If supplied the \a inserts list will be populated with insert notifications for affected groups. -*/ - -void QQuickListCompositor::setFlags( - iterator from, int count, Group group, uint flags, QVector<Insert> *inserts) -{ - QT_QML_TRACE_LISTCOMPOSITOR(<< from << count << flags) - if (!flags || !count) - return; - - if (from != group) { - // Skip to the next full range if the start one is not a member of the target group. - from.incrementIndexes(from->count - from.offset); - from.offset = 0; - *from = from->next; - } else if (from.offset > 0) { - // If the start position is mid range split off the portion unaffected. - *from = insert(*from, from->list, from->index, from.offset, from->flags & ~AppendFlag)->next; - from->index += from.offset; - from->count -= from.offset; - from.offset = 0; - } - - for (; count > 0; *from = from->next) { - if (from != from.group) { - // Skip ranges that are not members of the target group. - from.incrementIndexes(from->count); - continue; - } - // Find the number of items affected in the current range. - const int difference = qMin(count, from->count); - count -= difference; - - // Determine the actual changes made to the range and increment counts accordingly. - const uint insertFlags = ~from->flags & flags; - const uint setFlags = (from->flags | flags) & ~AppendFlag; - if (insertFlags && inserts) - inserts->append(Insert(from, difference, insertFlags | (from->flags & CacheFlag))); - m_end.incrementIndexes(difference, insertFlags); - from.incrementIndexes(difference, setFlags); - - if (from->previous != &m_ranges - && from->previous->list == from->list - && (!from->list || from->previous->end() == from->index) - && from->previous->flags == setFlags) { - // If the additional flags make the current range a continuation of the previous - // then move the affected items over to the previous range. - from->previous->count += difference; - from->index += difference; - from->count -= difference; - if (from->count == 0) { - // Delete the current range if it is now empty, preserving the append flag - // in the previous range. - if (from->append()) - from->previous->flags |= AppendFlag; - *from = erase(*from)->previous; - continue; - } else { - break; - } - } else if (!insertFlags) { - // No new flags, so roll onto the next range. - from.incrementIndexes(from->count - difference); - continue; - } else if (difference < from->count) { - // Create a new range with the updated flags, and remove the affected items - // from the current range. - *from = insert(*from, from->list, from->index, difference, setFlags)->next; - from->index += difference; - from->count -= difference; - } else { - // The whole range is affected so simply update the flags. - from->flags |= flags; - continue; - } - from.incrementIndexes(from->count); - } - - if (from->previous != &m_ranges - && from->previous->list == from->list - && (!from->list || from->previous->end() == from->index) - && from->previous->flags == (from->flags & ~AppendFlag)) { - // If the following range is now a continuation, merge it with its previous range. - from.offset = from->previous->count; - from->previous->count += from->count; - from->previous->flags = from->flags; - *from = erase(*from)->previous; - } - m_cacheIt = from; - QT_QML_VERIFY_LISTCOMPOSITOR -} - -/*! - Clears the given flags \a flags on \a count items belonging to \a group starting at the position - \a from. - - If supplied the \a removes list will be populated with remove notifications for affected groups. -*/ - -void QQuickListCompositor::clearFlags( - Group fromGroup, int from, int count, Group group, uint flags, QVector<Remove> *removes) -{ - QT_QML_TRACE_LISTCOMPOSITOR(<< fromGroup << from << count << group << flags) - clearFlags(find(fromGroup, from), count, group, flags, removes); -} - -/*! - Clears the given flags \a flags on \a count items belonging to \a group starting at the position - identified by \a fromGroup and the index \a from. - - If supplied the \a removes list will be populated with remove notifications for affected groups. -*/ - -void QQuickListCompositor::clearFlags( - iterator from, int count, Group group, uint flags, QVector<Remove> *removes) -{ - QT_QML_TRACE_LISTCOMPOSITOR(<< from << count << flags) - if (!flags || !count) - return; - - const bool clearCache = flags & CacheFlag; - - if (from != group) { - // Skip to the next full range if the start one is not a member of the target group. - from.incrementIndexes(from->count - from.offset); - from.offset = 0; - *from = from->next; - } else if (from.offset > 0) { - // If the start position is mid range split off the portion unaffected. - *from = insert(*from, from->list, from->index, from.offset, from->flags & ~AppendFlag)->next; - from->index += from.offset; - from->count -= from.offset; - from.offset = 0; - } - - for (; count > 0; *from = from->next) { - if (from != group) { - // Skip ranges that are not members of the target group. - from.incrementIndexes(from->count); - continue; - } - // Find the number of items affected in the current range. - const int difference = qMin(count, from->count); - count -= difference; - - - // Determine the actual changes made to the range and decrement counts accordingly. - const uint removeFlags = from->flags & flags & ~(AppendFlag | PrependFlag); - const uint clearedFlags = from->flags & ~(flags | AppendFlag | UnresolvedFlag); - if (removeFlags && removes) { - const int maskedFlags = clearCache - ? (removeFlags & ~CacheFlag) - : (removeFlags | (from->flags & CacheFlag)); - if (maskedFlags) - removes->append(Remove(from, difference, maskedFlags)); - } - m_end.decrementIndexes(difference, removeFlags); - from.incrementIndexes(difference, clearedFlags); - - if (from->previous != &m_ranges - && from->previous->list == from->list - && (!from->list || clearedFlags == CacheFlag || from->previous->end() == from->index) - && from->previous->flags == clearedFlags) { - // If the removed flags make the current range a continuation of the previous - // then move the affected items over to the previous range. - from->previous->count += difference; - from->index += difference; - from->count -= difference; - if (from->count == 0) { - // Delete the current range if it is now empty, preserving the append flag - if (from->append()) - from->previous->flags |= AppendFlag; - *from = erase(*from)->previous; - } else { - from.incrementIndexes(from->count); - } - } else if (difference < from->count) { - // Create a new range with the reduced flags, and remove the affected items from - // the current range. - if (clearedFlags) - *from = insert(*from, from->list, from->index, difference, clearedFlags)->next; - from->index += difference; - from->count -= difference; - from.incrementIndexes(from->count); - } else if (clearedFlags) { - // The whole range is affected so simply update the flags. - from->flags &= ~flags; - } else { - // All flags have been removed from the range so remove it. - *from = erase(*from)->previous; - } - } - - if (*from != &m_ranges && from->previous != &m_ranges - && from->previous->list == from->list - && (!from->list || from->previous->end() == from->index) - && from->previous->flags == (from->flags & ~AppendFlag)) { - // If the following range is now a continuation, merge it with its previous range. - from.offset = from->previous->count; - from->previous->count += from->count; - from->previous->flags = from->flags; - *from = erase(*from)->previous; - } - m_cacheIt = from; - QT_QML_VERIFY_LISTCOMPOSITOR -} - -bool QQuickListCompositor::verifyMoveTo( - Group fromGroup, int from, Group toGroup, int to, int count, Group group) const -{ - if (group != toGroup) { - // determine how many items from the destination group intersect with the source group. - iterator fromIt = find(fromGroup, from); - - int intersectingCount = 0; - - for (; count > 0; *fromIt = fromIt->next) { - if (*fromIt == &m_ranges) - return false; - if (!fromIt->inGroup(group)) - continue; - if (fromIt->inGroup(toGroup)) - intersectingCount += qMin(count, fromIt->count - fromIt.offset); - count -= fromIt->count - fromIt.offset; - fromIt.offset = 0; - } - count = intersectingCount; - } - - return to >= 0 && to + count <= m_end.index[toGroup]; -} - -/*! - \internal - - Moves \a count items belonging to \a moveGroup from the index \a from in \a fromGroup - to the index \a to in \a toGroup. - - If \a removes and \a inserts are not null they will be populated with per group notifications - of the items moved. - */ - -void QQuickListCompositor::move( - Group fromGroup, - int from, - Group toGroup, - int to, - int count, - Group moveGroup, - QVector<Remove> *removes, - QVector<Insert> *inserts) -{ - QT_QML_TRACE_LISTCOMPOSITOR(<< fromGroup << from << toGroup << to << count) - Q_ASSERT(count > 0); - Q_ASSERT(from >=0); - Q_ASSERT(verifyMoveTo(fromGroup, from, toGroup, to, count, moveGroup)); - - // Find the position of the first item to move. - iterator fromIt = find(fromGroup, from); - - if (fromIt != moveGroup) { - // If the range at the from index doesn't contain items from the move group; skip - // to the next range. - fromIt.incrementIndexes(fromIt->count - fromIt.offset); - fromIt.offset = 0; - *fromIt = fromIt->next; - } else if (fromIt.offset > 0) { - // If the range at the from index contains items from the move group and the index isn't - // at the start of the range; split the range at the index and move the iterator to start - // of the second range. - *fromIt = insert( - *fromIt, fromIt->list, fromIt->index, fromIt.offset, fromIt->flags & ~AppendFlag)->next; - fromIt->index += fromIt.offset; - fromIt->count -= fromIt.offset; - fromIt.offset = 0; - } - - // Remove count items belonging to the move group from the list. - Range movedFlags; - for (int moveId = m_moveId; count > 0;) { - if (fromIt != moveGroup) { - // Skip ranges not containing items from the move group. - fromIt.incrementIndexes(fromIt->count); - *fromIt = fromIt->next; - continue; - } - int difference = qMin(count, fromIt->count); - - // Create a new static range containing the moved items from an existing range. - new Range( - &movedFlags, - fromIt->list, - fromIt->index, - difference, - fromIt->flags & ~(PrependFlag | AppendFlag)); - // Remove moved items from the count, the existing range, and a remove notification. - if (removes) - removes->append(Remove(fromIt, difference, fromIt->flags, ++moveId)); - count -= difference; - fromIt->count -= difference; - - // If the existing range contains the prepend flag replace the removed items with - // a placeholder range for new items inserted into the source model. - int removeIndex = fromIt->index; - if (fromIt->prepend() - && fromIt->previous != &m_ranges - && fromIt->previous->flags == PrependFlag - && fromIt->previous->list == fromIt->list - && fromIt->previous->end() == fromIt->index) { - // Grow the previous range instead of creating a new one if possible. - fromIt->previous->count += difference; - } else if (fromIt->prepend()) { - *fromIt = insert(*fromIt, fromIt->list, removeIndex, difference, PrependFlag)->next; - } - fromIt->index += difference; - - if (fromIt->count == 0) { - // If the existing range has no items remaining; remove it from the list. - if (fromIt->append()) - fromIt->previous->flags |= AppendFlag; - *fromIt = erase(*fromIt); - - // If the ranges before and after the removed range can be joined, do so. - if (*fromIt != m_ranges.next && fromIt->flags == PrependFlag - && fromIt->previous != &m_ranges - && fromIt->previous->flags == PrependFlag - && fromIt->previous->list == fromIt->list - && fromIt->previous->end() == fromIt->index) { - fromIt.incrementIndexes(fromIt->count); - fromIt->previous->count += fromIt->count; - *fromIt = erase(*fromIt); - } - } else if (count > 0) { - *fromIt = fromIt->next; - } - } - - // Try and join the range following the removed items to the range preceding it. - if (*fromIt != m_ranges.next - && *fromIt != &m_ranges - && fromIt->previous->list == fromIt->list - && (!fromIt->list || fromIt->previous->end() == fromIt->index) - && fromIt->previous->flags == (fromIt->flags & ~AppendFlag)) { - if (fromIt == fromIt.group) - fromIt.offset = fromIt->previous->count; - fromIt.offset = fromIt->previous->count; - fromIt->previous->count += fromIt->count; - fromIt->previous->flags = fromIt->flags; - *fromIt = erase(*fromIt)->previous; - } - - // Find the destination position of the move. - insert_iterator toIt = fromIt; - toIt.setGroup(toGroup); - - const int difference = to - toIt.index[toGroup]; - toIt += difference; - - // If the insert position is part way through a range; split it and move the iterator to the - // start of the second range. - if (toIt.offset > 0) { - *toIt = insert(*toIt, toIt->list, toIt->index, toIt.offset, toIt->flags & ~AppendFlag)->next; - toIt->index += toIt.offset; - toIt->count -= toIt.offset; - toIt.offset = 0; - } - - // Insert the moved ranges before the insert iterator, growing the previous range if that - // is an option. - for (Range *range = movedFlags.previous; range != &movedFlags; range = range->previous) { - if (*toIt != &m_ranges - && range->list == toIt->list - && (!range->list || range->end() == toIt->index) - && range->flags == (toIt->flags & ~AppendFlag)) { - toIt->index -= range->count; - toIt->count += range->count; - } else { - *toIt = insert(*toIt, range->list, range->index, range->count, range->flags); - } - } - - // Try and join the range after the inserted ranges to the last range inserted. - if (*toIt != m_ranges.next - && toIt->previous->list == toIt->list - && (!toIt->list || (toIt->previous->end() == toIt->index && toIt->previous->flags == (toIt->flags & ~AppendFlag)))) { - toIt.offset = toIt->previous->count; - toIt->previous->count += toIt->count; - toIt->previous->flags = toIt->flags; - *toIt = erase(*toIt)->previous; - } - // Create insert notification for the ranges moved. - Insert insert(toIt, 0, 0, 0); - for (Range *next, *range = movedFlags.next; range != &movedFlags; range = next) { - insert.count = range->count; - insert.flags = range->flags; - if (inserts) { - insert.moveId = ++m_moveId; - inserts->append(insert); - } - for (int i = 0; i < m_groupCount; ++i) { - if (insert.inGroup(i)) - insert.index[i] += range->count; - } - - next = range->next; - delete range; - } - - m_cacheIt = toIt; - - QT_QML_VERIFY_LISTCOMPOSITOR -} - -/*! - Clears the contents of a compositor. -*/ - -void QQuickListCompositor::clear() -{ - QT_QML_TRACE_LISTCOMPOSITOR( ) - for (Range *range = m_ranges.next; range != &m_ranges; range = erase(range)) {} - m_end = iterator(m_ranges.next, 0, Default, m_groupCount); - m_cacheIt = m_end; -} - -void QQuickListCompositor::listItemsInserted( - QVector<Insert> *translatedInsertions, - void *list, - const QVector<QQuickChangeSet::Insert> &insertions, - const QVector<MovedFlags> *movedFlags) -{ - QT_QML_TRACE_LISTCOMPOSITOR(<< list << insertions) - for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) { - if (it->list != list || it->flags == CacheFlag) { - // Skip ranges that don't reference list. - it.incrementIndexes(it->count); - continue; - } else if (it->flags & MovedFlag) { - // Skip ranges that were already moved in listItemsRemoved. - it->flags &= ~MovedFlag; - it.incrementIndexes(it->count); - continue; - } - foreach (const QQuickChangeSet::Insert &insertion, insertions) { - int offset = insertion.index - it->index; - if ((offset > 0 && offset < it->count) - || (offset == 0 && it->prepend()) - || (offset == it->count && it->append())) { - // The insert index is within the current range. - if (it->prepend()) { - // The range has the prepend flag set so we insert new items into the range. - uint flags = m_defaultFlags; - if (insertion.isMove()) { - // If the insert was part of a move replace the default flags with - // the flags from the source range. - for (QVector<MovedFlags>::const_iterator move = movedFlags->begin(); - move != movedFlags->end(); - ++move) { - if (move->moveId == insertion.moveId) { - flags = move->flags; - break; - } - } - } - if (flags & ~(AppendFlag | PrependFlag)) { - // If any items are added to groups append an insert notification. - Insert translatedInsert(it, insertion.count, flags, insertion.moveId); - for (int i = 0; i < m_groupCount; ++i) { - if (it->inGroup(i)) - translatedInsert.index[i] += offset; - } - translatedInsertions->append(translatedInsert); - } - if ((it->flags & ~AppendFlag) == flags) { - // Accumulate items on the current range it its flags are the same as - // the insert flags. - it->count += insertion.count; - } else if (offset == 0 - && it->previous != &m_ranges - && it->previous->list == list - && it->previous->end() == insertion.index - && it->previous->flags == flags) { - // Attempt to append to the previous range if the insert position is at - // the start of the current range. - it->previous->count += insertion.count; - it->index += insertion.count; - it.incrementIndexes(insertion.count); - } else { - if (offset > 0) { - // Divide the current range at the insert position. - it.incrementIndexes(offset); - *it = insert(*it, it->list, it->index, offset, it->flags & ~AppendFlag)->next; - } - // Insert a new range, and increment the start index of the current range. - *it = insert(*it, it->list, insertion.index, insertion.count, flags)->next; - it.incrementIndexes(insertion.count, flags); - it->index += offset + insertion.count; - it->count -= offset; - } - m_end.incrementIndexes(insertion.count, flags); - } else { - // The range doesn't have the prepend flag set so split the range into parts; - // one before the insert position and one after the last inserted item. - if (offset > 0) { - *it = insert(*it, it->list, it->index, offset, it->flags)->next; - it->index += offset; - it->count -= offset; - } - it->index += insertion.count; - } - } else if (offset <= 0) { - // The insert position was before the current range so increment the start index. - it->index += insertion.count; - } - } - it.incrementIndexes(it->count); - } - m_cacheIt = m_end; - QT_QML_VERIFY_LISTCOMPOSITOR -} - -/*! - Updates the contents of a compositor when \a count items are inserted into a \a list at - \a index. - - This corrects the indexes of each range for that list in the compositor, splitting the range - in two if the insert index is in the middle of that range. If a range at the insert position - has the Prepend flag set then a new range will be inserted at that position with the groups - specified in defaultGroups(). If the insert index corresponds to the end of a range with - the Append flag set a new range will be inserted before the end of the append range. - - The \a translatedInsertions list is populated with insert notifications for affected - groups. -*/ - -void QQuickListCompositor::listItemsInserted( - void *list, int index, int count, QVector<Insert> *translatedInsertions) -{ - QT_QML_TRACE_LISTCOMPOSITOR(<< list << index << count) - Q_ASSERT(count > 0); - - QVector<QQuickChangeSet::Insert> insertions; - insertions.append(QQuickChangeSet::Insert(index, count)); - - listItemsInserted(translatedInsertions, list, insertions); -} - -void QQuickListCompositor::listItemsRemoved( - QVector<Remove> *translatedRemovals, - void *list, - QVector<QQuickChangeSet::Remove> *removals, - QVector<QQuickChangeSet::Insert> *insertions, - QVector<MovedFlags> *movedFlags) -{ - QT_QML_TRACE_LISTCOMPOSITOR(<< list << *removals) - - for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) { - if (it->list != list || it->flags == CacheFlag) { - // Skip ranges that don't reference list. - it.incrementIndexes(it->count); - continue; - } - bool removed = false; - for (QVector<QQuickChangeSet::Remove>::iterator removal = removals->begin(); - !removed && removal != removals->end(); - ++removal) { - int relativeIndex = removal->index - it->index; - int itemsRemoved = removal->count; - if (relativeIndex + removal->count > 0 && relativeIndex < it->count) { - // If the current range intersects the remove; remove the intersecting items. - const int offset = qMax(0, relativeIndex); - int removeCount = qMin(it->count, relativeIndex + removal->count) - offset; - it->count -= removeCount; - int removeFlags = it->flags & m_removeFlags; - Remove translatedRemoval(it, removeCount, it->flags); - for (int i = 0; i < m_groupCount; ++i) { - if (it->inGroup(i)) - translatedRemoval.index[i] += offset; - } - if (removal->isMove()) { - // If the removal was part of a move find the corresponding insert. - QVector<QQuickChangeSet::Insert>::iterator insertion = insertions->begin(); - for (; insertion != insertions->end() && insertion->moveId != removal->moveId; - ++insertion) {} - Q_ASSERT(insertion != insertions->end()); - Q_ASSERT(insertion->count == removal->count); - - if (relativeIndex < 0) { - // If the remove started before the current range, split it and the - // corresponding insert so we're only working with intersecting part. - int splitMoveId = ++m_moveId; - removal = removals->insert(removal, QQuickChangeSet::Remove( - removal->index, -relativeIndex, splitMoveId)); - ++removal; - removal->count -= -relativeIndex; - insertion = insertions->insert(insertion, QQuickChangeSet::Insert( - insertion->index, -relativeIndex, splitMoveId)); - ++insertion; - insertion->index += -relativeIndex; - insertion->count -= -relativeIndex; - } - - if (it->prepend()) { - // If the current range has the prepend flag preserve its flags to transfer - // to its new location. - removeFlags |= it->flags & CacheFlag; - translatedRemoval.moveId = ++m_moveId; - movedFlags->append(MovedFlags(m_moveId, it->flags & ~AppendFlag)); - - if (removeCount < removal->count) { - // If the remove doesn't encompass all of the current range, - // split it and the corresponding insert. - removal = removals->insert(removal, QQuickChangeSet::Remove( - removal->index, removeCount, translatedRemoval.moveId)); - ++removal; - insertion = insertions->insert(insertion, QQuickChangeSet::Insert( - insertion->index, removeCount, translatedRemoval.moveId)); - ++insertion; - - removal->count -= removeCount; - insertion->index += removeCount; - insertion->count -= removeCount; - } else { - // If there's no need to split the move simply replace its moveId - // with that of the translated move. - removal->moveId = translatedRemoval.moveId; - insertion->moveId = translatedRemoval.moveId; - } - } else { - // If the current range doesn't have prepend flags then insert a new range - // with list indexes from the corresponding insert location. The MoveFlag - // is to notify listItemsInserted that it can skip evaluation of that range. - if (offset > 0) { - *it = insert(*it, it->list, it->index, offset, it->flags & ~AppendFlag)->next; - it->index += offset; - it->count -= offset; - it.incrementIndexes(offset); - } - if (it->previous != &m_ranges - && it->previous->list == it->list - && it->end() == insertion->index - && it->previous->flags == (it->flags | MovedFlag)) { - it->previous->count += removeCount; - } else { - *it = insert(*it, it->list, insertion->index, removeCount, it->flags | MovedFlag)->next; - } - // Clear the changed flags as the item hasn't been removed. - translatedRemoval.flags = 0; - removeFlags = 0; - } - } else if (it->inCache()) { - // If not moving and the current range has the cache flag, insert a new range - // with just the cache flag set to retain caching information for the removed - // range. - if (offset > 0) { - *it = insert(*it, it->list, it->index, offset, it->flags & ~AppendFlag)->next; - it->index += offset; - it->count -= offset; - it.incrementIndexes(offset); - } - if (it->previous != &m_ranges - && it->previous->list == it->list - && it->previous->flags == CacheFlag) { - it->previous->count += removeCount; - } else { - *it = insert(*it, it->list, -1, removeCount, CacheFlag)->next; - } - it.index[Cache] += removeCount; - } - if (removeFlags & GroupMask) - translatedRemovals->append(translatedRemoval); - m_end.decrementIndexes(removeCount, removeFlags); - if (it->count == 0 && !it->append()) { - // Erase empty non-append ranges. - *it = erase(*it)->previous; - removed = true; - } else if (relativeIndex <= 0) { - // If the remove started before the current range move the start index of - // the range to the remove index. - it->index = removal->index; - } - } else if (relativeIndex < 0) { - // If the remove was before the current range decrement the start index by the - // number of items removed. - it->index -= itemsRemoved; - - if (it->previous != &m_ranges - && it->previous->list == it->list - && it->previous->end() == it->index - && it->previous->flags == (it->flags & ~AppendFlag)) { - // Compress ranges made continuous by the removal of separating ranges. - it.decrementIndexes(it->previous->count); - it->previous->count += it->count; - it->previous->flags = it->flags; - *it = erase(*it)->previous; - } - } - } - if (it->flags == CacheFlag && it->next->flags == CacheFlag && it->next->list == it->list) { - // Compress consecutive cache only ranges. - it.index[Cache] += it->next->count; - it->count += it->next->count; - erase(it->next); - } else if (!removed) { - it.incrementIndexes(it->count); - } - } - m_cacheIt = m_end; - QT_QML_VERIFY_LISTCOMPOSITOR -} - - -/*! - Updates the contents of a compositor when \a count items are removed from a \a list at - \a index. - - Ranges that intersect the specified range are removed from the compositor and the indexes of - ranges after index + count are updated. - - The \a translatedRemovals list is populated with remove notifications for the affected - groups. -*/ - - -void QQuickListCompositor::listItemsRemoved( - void *list, int index, int count, QVector<Remove> *translatedRemovals) -{ - QT_QML_TRACE_LISTCOMPOSITOR(<< list << index << count) - Q_ASSERT(count >= 0); - - QVector<QQuickChangeSet::Remove> removals; - removals.append(QQuickChangeSet::Remove(index, count)); - listItemsRemoved(translatedRemovals, list, &removals, 0, 0); -} - -/*! - Updates the contents of a compositor when \a count items are removed from a \a list at - \a index. - - Ranges that intersect the specified range are removed from the compositor and the indexes of - ranges after index + count are updated. - - The \a translatedRemovals and translatedInserts lists are populated with move - notifications for the affected groups. -*/ - -void QQuickListCompositor::listItemsMoved( - void *list, - int from, - int to, - int count, - QVector<Remove> *translatedRemovals, - QVector<Insert> *translatedInsertions) -{ - QT_QML_TRACE_LISTCOMPOSITOR(<< list << from << to << count) - Q_ASSERT(count >= 0); - - QVector<QQuickChangeSet::Remove> removals; - QVector<QQuickChangeSet::Insert> insertions; - QVector<MovedFlags> movedFlags; - removals.append(QQuickChangeSet::Remove(from, count, 0)); - insertions.append(QQuickChangeSet::Insert(to, count, 0)); - - listItemsRemoved(translatedRemovals, list, &removals, &insertions, &movedFlags); - listItemsInserted(translatedInsertions, list, insertions, &movedFlags); -} - -void QQuickListCompositor::listItemsChanged( - QVector<Change> *translatedChanges, - void *list, - const QVector<QQuickChangeSet::Change> &changes) -{ - QT_QML_TRACE_LISTCOMPOSITOR(<< list << changes) - for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) { - if (it->list != list || it->flags == CacheFlag) { - it.incrementIndexes(it->count); - continue; - } else if (!it->inGroup()) { - continue; - } - foreach (const QQuickChangeSet::Change &change, changes) { - const int offset = change.index - it->index; - if (offset + change.count > 0 && offset < it->count) { - const int changeOffset = qMax(0, offset); - const int changeCount = qMin(it->count, offset + change.count) - changeOffset; - - Change translatedChange(it, changeCount, it->flags); - for (int i = 0; i < m_groupCount; ++i) { - if (it->inGroup(i)) - translatedChange.index[i] += changeOffset; - } - translatedChanges->append(translatedChange); - } - } - it.incrementIndexes(it->count); - } -} - - -/*! - Translates the positions of \a count changed items at \a index in a \a list. - - The \a translatedChanges list is populated with change notifications for the - affected groups. -*/ - -void QQuickListCompositor::listItemsChanged( - void *list, int index, int count, QVector<Change> *translatedChanges) -{ - QT_QML_TRACE_LISTCOMPOSITOR(<< list << index << count) - Q_ASSERT(count >= 0); - QVector<QQuickChangeSet::Change> changes; - changes.append(QQuickChangeSet::Change(index, count)); - listItemsChanged(translatedChanges, list, changes); -} - -void QQuickListCompositor::transition( - Group from, - Group to, - QVector<QQuickChangeSet::Remove> *removes, - QVector<QQuickChangeSet::Insert> *inserts) -{ - int removeCount = 0; - for (iterator it(m_ranges.next, 0, Default, m_groupCount); *it != &m_ranges; *it = it->next) { - if (it == from && it != to) { - removes->append(QQuickChangeSet::Remove(it.index[from]- removeCount, it->count)); - removeCount += it->count; - } else if (it != from && it == to) { - inserts->append(QQuickChangeSet::Insert(it.index[to], it->count)); - } - it.incrementIndexes(it->count); - } -} - -/*! - \internal - Writes the name of \a group to \a debug. -*/ - -QDebug operator <<(QDebug debug, const QQuickListCompositor::Group &group) -{ - switch (group) { - case QQuickListCompositor::Cache: return debug << "Cache"; - case QQuickListCompositor::Default: return debug << "Default"; - default: return (debug.nospace() << "Group" << int(group)).space(); - } - -} - -/*! - \internal - Writes the contents of \a range to \a debug. -*/ - -QDebug operator <<(QDebug debug, const QQuickListCompositor::Range &range) -{ - (debug.nospace() - << "Range(" - << range.list) << ' ' - << range.index << ' ' - << range.count << ' ' - << (range.isUnresolved() ? 'U' : '0') - << (range.append() ? 'A' : '0') - << (range.prepend() ? 'P' : '0'); - for (int i = QQuickListCompositor::MaximumGroupCount - 1; i >= 2; --i) - debug << (range.inGroup(i) ? '1' : '0'); - return (debug - << (range.inGroup(QQuickListCompositor::Default) ? 'D' : '0') - << (range.inGroup(QQuickListCompositor::Cache) ? 'C' : '0')); -} - -static void qt_print_indexes(QDebug &debug, int count, const int *indexes) -{ - for (int i = count - 1; i >= 0; --i) - debug << indexes[i]; -} - -/*! - \internal - Writes the contents of \a it to \a debug. -*/ - -QDebug operator <<(QDebug debug, const QQuickListCompositor::iterator &it) -{ - (debug.nospace() << "iterator(" << it.group).space() << "offset:" << it.offset; - qt_print_indexes(debug, it.groupCount, it.index); - return ((debug << **it).nospace() << ')').space(); -} - -static QDebug qt_print_change(QDebug debug, const char *name, const QQuickListCompositor::Change &change) -{ - debug.nospace() << name << '(' << change.moveId << ' ' << change.count << ' '; - for (int i = QQuickListCompositor::MaximumGroupCount - 1; i >= 2; --i) - debug << (change.inGroup(i) ? '1' : '0'); - debug << (change.inGroup(QQuickListCompositor::Default) ? 'D' : '0') - << (change.inGroup(QQuickListCompositor::Cache) ? 'C' : '0'); - int i = QQuickListCompositor::MaximumGroupCount - 1; - for (; i >= 0 && !change.inGroup(i); --i) {} - for (; i >= 0; --i) - debug << ' ' << change.index[i]; - return (debug << ')').maybeSpace(); -} - -/*! - \internal - Writes the contents of \a change to \a debug. -*/ - -QDebug operator <<(QDebug debug, const QQuickListCompositor::Change &change) -{ - return qt_print_change(debug, "Change", change); -} - -/*! - \internal - Writes the contents of \a remove to \a debug. -*/ - -QDebug operator <<(QDebug debug, const QQuickListCompositor::Remove &remove) -{ - return qt_print_change(debug, "Remove", remove); -} - -/*! - \internal - Writes the contents of \a insert to \a debug. -*/ - -QDebug operator <<(QDebug debug, const QQuickListCompositor::Insert &insert) -{ - return qt_print_change(debug, "Insert", insert); -} - -/*! - \internal - Writes the contents of \a list to \a debug. -*/ - -QDebug operator <<(QDebug debug, const QQuickListCompositor &list) -{ - int indexes[QQuickListCompositor::MaximumGroupCount]; - for (int i = 0; i < QQuickListCompositor::MaximumGroupCount; ++i) - indexes[i] = 0; - debug.nospace() << "QQuickListCompositor("; - qt_print_indexes(debug, list.m_groupCount, list.m_end.index); - for (QQuickListCompositor::Range *range = list.m_ranges.next; range != &list.m_ranges; range = range->next) { - (debug << '\n').space(); - qt_print_indexes(debug, list.m_groupCount, indexes); - debug << ' ' << *range; - - for (int i = 0; i < list.m_groupCount; ++i) { - if (range->inGroup(i)) - indexes[i] += range->count; - } - } - return (debug << ')').maybeSpace(); -} - -QT_END_NAMESPACE diff --git a/src/quick/util/qquicklistcompositor_p.h b/src/quick/util/qquicklistcompositor_p.h deleted file mode 100644 index b2fe69d6a2..0000000000 --- a/src/quick/util/qquicklistcompositor_p.h +++ /dev/null @@ -1,375 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQUICKLISTCOMPOSITOR_P_H -#define QQUICKLISTCOMPOSITOR_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qglobal.h> -#include <QtCore/qvector.h> - -#include <private/qquickchangeset_p.h> - -#include <QtCore/qdebug.h> - -QT_BEGIN_NAMESPACE - -class Q_AUTOTEST_EXPORT QQuickListCompositor -{ -public: - enum { MinimumGroupCount = 3, MaximumGroupCount = 11 }; - - enum Group - { - Cache = 0, - Default = 1, - Persisted = 2 - }; - - enum Flag - { - CacheFlag = 1 << Cache, - DefaultFlag = 1 << Default, - PersistedFlag = 1 << Persisted, - PrependFlag = 0x10000000, - AppendFlag = 0x20000000, - UnresolvedFlag = 0x40000000, - MovedFlag = 0x80000000, - GroupMask = ~(PrependFlag | AppendFlag | UnresolvedFlag | MovedFlag | CacheFlag) - }; - - class Range - { - public: - Range() : next(this), previous(this), list(0), index(0), count(0), flags(0) {} - Range(Range *next, void *list, int index, int count, uint flags) - : next(next), previous(next->previous), list(list), index(index), count(count), flags(flags) { - next->previous = this; previous->next = this; } - - Range *next; - Range *previous; - void *list; - int index; - int count; - uint flags; - - inline int start() const { return index; } - inline int end() const { return index + count; } - - inline int groups() const { return flags & GroupMask; } - - inline bool inGroup() const { return flags & GroupMask; } - inline bool inCache() const { return flags & CacheFlag; } - inline bool inGroup(int group) const { return flags & (1 << group); } - inline bool isUnresolved() const { return flags & UnresolvedFlag; } - - inline bool prepend() const { return flags & PrependFlag; } - inline bool append() const { return flags & AppendFlag; } - }; - - class Q_AUTOTEST_EXPORT iterator - { - public: - inline iterator(); - inline iterator(const iterator &it); - inline iterator(Range *range, int offset, Group group, int groupCount); - inline ~iterator() {} - - bool operator ==(const iterator &it) const { return range == it.range && offset == it.offset; } - bool operator !=(const iterator &it) const { return range != it.range || offset != it.offset; } - - bool operator ==(Group group) const { return range->flags & (1 << group); } - bool operator !=(Group group) const { return !(range->flags & (1 << group)); } - - Range *&operator *() { return range; } - Range * const &operator *() const { return range; } - Range *operator ->() { return range; } - const Range *operator ->() const { return range; } - - iterator &operator +=(int difference); - - template<typename T> T *list() const { return static_cast<T *>(range->list); } - int modelIndex() const { return range->index + offset; } - - void incrementIndexes(int difference) { incrementIndexes(difference, range->flags); } - void decrementIndexes(int difference) { decrementIndexes(difference, range->flags); } - - inline void incrementIndexes(int difference, uint flags); - inline void decrementIndexes(int difference, uint flags); - - void setGroup(Group g) { group = g; groupFlag = 1 << g; } - - Range *range; - int offset; - Group group; - int groupFlag; - int groupCount; - union { - struct { - int cacheIndex; - }; - int index[MaximumGroupCount]; - }; - }; - - class Q_AUTOTEST_EXPORT insert_iterator : public iterator - { - public: - inline insert_iterator() {} - inline insert_iterator(const iterator &it) : iterator(it) {} - inline insert_iterator(Range *, int, Group, int); - inline ~insert_iterator() {} - - insert_iterator &operator +=(int difference); - }; - - struct Change - { - inline Change() {} - inline Change(iterator it, int count, uint flags, int moveId = -1); - int count; - uint flags; - int moveId; - union { - struct { - int cacheIndex; - }; - int index[MaximumGroupCount]; - }; - - inline bool isMove() const { return moveId >= 0; } - inline bool inCache() const { return flags & CacheFlag; } - inline bool inGroup() const { return flags & GroupMask; } - inline bool inGroup(int group) const { return flags & (CacheFlag << group); } - - inline int groups() const { return flags & GroupMask; } - }; - - struct Insert : public Change - { - Insert() {} - Insert(iterator it, int count, uint flags, int moveId = -1) - : Change(it, count, flags, moveId) {} - }; - - struct Remove : public Change - { - Remove() {} - Remove(iterator it, int count, uint flags, int moveId = -1) - : Change(it, count, flags, moveId) {} - }; - - QQuickListCompositor(); - ~QQuickListCompositor(); - - int defaultGroups() const { return m_defaultFlags & ~PrependFlag; } - void setDefaultGroups(int groups) { m_defaultFlags = groups | PrependFlag; } - void setDefaultGroup(Group group) { m_defaultFlags |= (1 << group); } - void clearDefaultGroup(Group group) { m_defaultFlags &= ~(1 << group); } - void setRemoveGroups(int groups) { m_removeFlags = PrependFlag | AppendFlag | groups; } - void setGroupCount(int count); - - int count(Group group) const; - iterator find(Group group, int index); - iterator find(Group group, int index) const; - insert_iterator findInsertPosition(Group group, int index); - - const iterator &end() { return m_end; } - - void append(void *list, int index, int count, uint flags, QVector<Insert> *inserts = 0); - void insert(Group group, int before, void *list, int index, int count, uint flags, QVector<Insert> *inserts = 0); - iterator insert(iterator before, void *list, int index, int count, uint flags, QVector<Insert> *inserts = 0); - - void setFlags(Group fromGroup, int from, int count, Group group, int flags, QVector<Insert> *inserts = 0); - void setFlags(iterator from, int count, Group group, uint flags, QVector<Insert> *inserts = 0); - void setFlags(Group fromGroup, int from, int count, uint flags, QVector<Insert> *inserts = 0) { - setFlags(fromGroup, from, count, fromGroup, flags, inserts); } - void setFlags(iterator from, int count, uint flags, QVector<Insert> *inserts = 0) { - setFlags(from, count, from.group, flags, inserts); } - - void clearFlags(Group fromGroup, int from, int count, Group group, uint flags, QVector<Remove> *removals = 0); - void clearFlags(iterator from, int count, Group group, uint flags, QVector<Remove> *removals = 0); - void clearFlags(Group fromGroup, int from, int count, uint flags, QVector<Remove> *removals = 0) { - clearFlags(fromGroup, from, count, fromGroup, flags, removals); } - void clearFlags(iterator from, int count, uint flags, QVector<Remove> *removals = 0) { - clearFlags(from, count, from.group, flags, removals); } - - bool verifyMoveTo(Group fromGroup, int from, Group toGroup, int to, int count, Group group) const; - - void move( - Group fromGroup, - int from, - Group toGroup, - int to, - int count, - Group group, - QVector<Remove> *removals = 0, - QVector<Insert> *inserts = 0); - void clear(); - - void listItemsInserted(void *list, int index, int count, QVector<Insert> *inserts); - void listItemsRemoved(void *list, int index, int count, QVector<Remove> *removals); - void listItemsMoved(void *list, int from, int to, int count, QVector<Remove> *removals, QVector<Insert> *inserts); - void listItemsChanged(void *list, int index, int count, QVector<Change> *changes); - - void transition( - Group from, - Group to, - QVector<QQuickChangeSet::Remove> *removes, - QVector<QQuickChangeSet::Insert> *inserts); - -private: - Range m_ranges; - iterator m_end; - iterator m_cacheIt; - int m_groupCount; - int m_defaultFlags; - int m_removeFlags; - int m_moveId; - - inline Range *insert(Range *before, void *list, int index, int count, uint flags); - inline Range *erase(Range *range); - - struct MovedFlags - { - MovedFlags() {} - MovedFlags(int moveId, uint flags) : moveId(moveId), flags(flags) {} - - int moveId; - uint flags; - }; - - void listItemsRemoved( - QVector<Remove> *translatedRemovals, - void *list, - QVector<QQuickChangeSet::Remove> *removals, - QVector<QQuickChangeSet::Insert> *insertions = 0, - QVector<MovedFlags> *movedFlags = 0); - void listItemsInserted( - QVector<Insert> *translatedInsertions, - void *list, - const QVector<QQuickChangeSet::Insert> &insertions, - const QVector<MovedFlags> *movedFlags = 0); - void listItemsChanged( - QVector<Change> *translatedChanges, - void *list, - const QVector<QQuickChangeSet::Change> &changes); - - friend Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQuickListCompositor &list); -}; - -Q_DECLARE_TYPEINFO(QQuickListCompositor::Change, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QQuickListCompositor::Remove, Q_PRIMITIVE_TYPE); -Q_DECLARE_TYPEINFO(QQuickListCompositor::Insert, Q_PRIMITIVE_TYPE); - -inline QQuickListCompositor::iterator::iterator() - : range(0), offset(0), group(Default), groupCount(0) {} -inline QQuickListCompositor::iterator::iterator(const iterator &it) - : range(it.range) - , offset(it.offset) - , group(it.group) - , groupFlag(it.groupFlag) - , groupCount(it.groupCount) -{ - for (int i = 0; i < groupCount; ++i) - index[i] = it.index[i]; -} - -inline QQuickListCompositor::iterator::iterator( - Range *range, int offset, Group group, int groupCount) - : range(range) - , offset(offset) - , group(group) - , groupFlag(1 << group) - , groupCount(groupCount) -{ - for (int i = 0; i < groupCount; ++i) - index[i] = 0; -} - -inline void QQuickListCompositor::iterator::incrementIndexes(int difference, uint flags) -{ - for (int i = 0; i < groupCount; ++i) { - if (flags & (1 << i)) - index[i] += difference; - } -} - -inline void QQuickListCompositor::iterator::decrementIndexes(int difference, uint flags) -{ - for (int i = 0; i < groupCount; ++i) { - if (flags & (1 << i)) - index[i] -= difference; - } -} - -inline QQuickListCompositor::insert_iterator::insert_iterator( - Range *range, int offset, Group group, int groupCount) - : iterator(range, offset, group, groupCount) {} - -inline QQuickListCompositor::Change::Change(iterator it, int count, uint flags, int moveId) - : count(count), flags(flags), moveId(moveId) -{ - for (int i = 0; i < MaximumGroupCount; ++i) - index[i] = it.index[i]; -} - -Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQuickListCompositor::Group &group); -Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQuickListCompositor::Range &range); -Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQuickListCompositor::iterator &it); -Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQuickListCompositor::Change &change); -Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQuickListCompositor::Remove &remove); -Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQuickListCompositor::Insert &insert); -Q_AUTOTEST_EXPORT QDebug operator <<(QDebug debug, const QQuickListCompositor &list); - -QT_END_NAMESPACE - -#endif diff --git a/src/quick/util/qquickpackage.cpp b/src/quick/util/qquickpackage.cpp deleted file mode 100644 index e885524b27..0000000000 --- a/src/quick/util/qquickpackage.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickpackage_p.h" - -#include <private/qobject_p.h> -#include <private/qqmlguard_p.h> - -QT_BEGIN_NAMESPACE - -/*! - \qmltype Package - \instantiates QQuickPackage - \inqmlmodule QtQuick 2 - \ingroup qtquick-views - \brief Specifies a collection of named items - - The Package class is used in conjunction with - VisualDataModel to enable delegates with a shared context - to be provided to multiple views. - - Any item within a Package may be assigned a name via the - \l{Package::name}{Package.name} attached property. - - The example below creates a Package containing two named items; - \e list and \e grid. The third item in the package (the \l Rectangle) is parented to whichever - delegate it should appear in. This allows an item to move - between views. - - \snippet quick/views/package/Delegate.qml 0 - - These named items are used as the delegates by the two views who - reference the special \l{VisualDataModel::parts} property to select - a model which provides the chosen delegate. - - \snippet quick/views/package/view.qml 0 - - \sa {quick/views/package}{Package example}, {quick/demos/photoviewer}{Photo Viewer example}, QtQml -*/ - -/*! - \qmlattachedproperty string QtQuick2::Package::name - This attached property holds the name of an item within a Package. -*/ - - -class QQuickPackagePrivate : public QObjectPrivate -{ -public: - QQuickPackagePrivate() {} - - struct DataGuard : public QQmlGuard<QObject> - { - DataGuard(QObject *obj, QList<DataGuard> *l) : list(l) { (QQmlGuard<QObject>&)*this = obj; } - QList<DataGuard> *list; - void objectDestroyed(QObject *) { - // we assume priv will always be destroyed after objectDestroyed calls - list->removeOne(*this); - } - }; - - QList<DataGuard> dataList; - static void data_append(QQmlListProperty<QObject> *prop, QObject *o) { - QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data); - list->append(DataGuard(o, list)); - } - static void data_clear(QQmlListProperty<QObject> *prop) { - QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data); - list->clear(); - } - static QObject *data_at(QQmlListProperty<QObject> *prop, int index) { - QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data); - return list->at(index); - } - static int data_count(QQmlListProperty<QObject> *prop) { - QList<DataGuard> *list = static_cast<QList<DataGuard> *>(prop->data); - return list->count(); - } -}; - -QHash<QObject *, QQuickPackageAttached *> QQuickPackageAttached::attached; - -QQuickPackageAttached::QQuickPackageAttached(QObject *parent) -: QObject(parent) -{ - attached.insert(parent, this); -} - -QQuickPackageAttached::~QQuickPackageAttached() -{ - attached.remove(parent()); -} - -QString QQuickPackageAttached::name() const -{ - return _name; -} - -void QQuickPackageAttached::setName(const QString &n) -{ - _name = n; -} - -QQuickPackage::QQuickPackage(QObject *parent) - : QObject(*(new QQuickPackagePrivate), parent) -{ -} - -QQuickPackage::~QQuickPackage() -{ -} - -QQmlListProperty<QObject> QQuickPackage::data() -{ - Q_D(QQuickPackage); - return QQmlListProperty<QObject>(this, &d->dataList, QQuickPackagePrivate::data_append, - QQuickPackagePrivate::data_count, - QQuickPackagePrivate::data_at, - QQuickPackagePrivate::data_clear); -} - -bool QQuickPackage::hasPart(const QString &name) -{ - Q_D(QQuickPackage); - for (int ii = 0; ii < d->dataList.count(); ++ii) { - QObject *obj = d->dataList.at(ii); - QQuickPackageAttached *a = QQuickPackageAttached::attached.value(obj); - if (a && a->name() == name) - return true; - } - return false; -} - -QObject *QQuickPackage::part(const QString &name) -{ - Q_D(QQuickPackage); - if (name.isEmpty() && !d->dataList.isEmpty()) - return d->dataList.at(0); - - for (int ii = 0; ii < d->dataList.count(); ++ii) { - QObject *obj = d->dataList.at(ii); - QQuickPackageAttached *a = QQuickPackageAttached::attached.value(obj); - if (a && a->name() == name) - return obj; - } - - if (name == QLatin1String("default") && !d->dataList.isEmpty()) - return d->dataList.at(0); - - return 0; -} - -QQuickPackageAttached *QQuickPackage::qmlAttachedProperties(QObject *o) -{ - return new QQuickPackageAttached(o); -} - - - -QT_END_NAMESPACE diff --git a/src/quick/util/qquickpackage_p.h b/src/quick/util/qquickpackage_p.h deleted file mode 100644 index a777ff4a7e..0000000000 --- a/src/quick/util/qquickpackage_p.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** 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, Digia gives you certain additional -** rights. These rights are described in the Digia 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. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQUICKPACKAGE_H -#define QQUICKPACKAGE_H - -#include <qqml.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QQuickPackagePrivate; -class QQuickPackageAttached; -class Q_AUTOTEST_EXPORT QQuickPackage : public QObject -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QQuickPackage) - - Q_CLASSINFO("DefaultProperty", "data") - Q_PROPERTY(QQmlListProperty<QObject> data READ data) - -public: - QQuickPackage(QObject *parent=0); - virtual ~QQuickPackage(); - - QQmlListProperty<QObject> data(); - - QObject *part(const QString & = QString()); - bool hasPart(const QString &); - - static QQuickPackageAttached *qmlAttachedProperties(QObject *); -}; - -class QQuickPackageAttached : public QObject -{ -Q_OBJECT -Q_PROPERTY(QString name READ name WRITE setName) -public: - QQuickPackageAttached(QObject *parent); - virtual ~QQuickPackageAttached(); - - QString name() const; - void setName(const QString &n); - - static QHash<QObject *, QQuickPackageAttached *> attached; -private: - QString _name; -}; - -QT_END_NAMESPACE - -QML_DECLARE_TYPE(QQuickPackage) -QML_DECLARE_TYPEINFO(QQuickPackage, QML_HAS_ATTACHED_PROPERTIES) - -QT_END_HEADER - -#endif // QQUICKPACKAGE_H diff --git a/src/quick/util/qquickutilmodule.cpp b/src/quick/util/qquickutilmodule.cpp index 5591f04a57..a45ec4ef15 100644 --- a/src/quick/util/qquickutilmodule.cpp +++ b/src/quick/util/qquickutilmodule.cpp @@ -45,7 +45,6 @@ #include "qquickbehavior_p.h" #include "qquicksmoothedanimation_p.h" #include "qquickfontloader_p.h" -#include "qquickpackage_p.h" #include "qquickpropertychanges_p.h" #include "qquickspringanimation_p.h" #include "qquickstategroup_p.h" @@ -73,7 +72,6 @@ void QQuickUtilModule::defineModule() qmlRegisterType<QQuickSmoothedAnimation>("QtQuick",2,0,"SmoothedAnimation"); qmlRegisterType<QQuickFontLoader>("QtQuick",2,0,"FontLoader"); qmlRegisterType<QQuickNumberAnimation>("QtQuick",2,0,"NumberAnimation"); - qmlRegisterType<QQuickPackage>("QtQuick",2,0,"Package"); qmlRegisterType<QQuickParallelAnimation>("QtQuick",2,0,"ParallelAnimation"); qmlRegisterType<QQuickPauseAnimation>("QtQuick",2,0,"PauseAnimation"); qmlRegisterType<QQuickPropertyAction>("QtQuick",2,0,"PropertyAction"); diff --git a/src/quick/util/util.pri b/src/quick/util/util.pri index 7a56a95314..7f77f7f702 100644 --- a/src/quick/util/util.pri +++ b/src/quick/util/util.pri @@ -1,7 +1,6 @@ SOURCES += \ $$PWD/qquickapplication.cpp\ $$PWD/qquickutilmodule.cpp\ - $$PWD/qquickpackage.cpp \ $$PWD/qquickanimation.cpp \ $$PWD/qquicksystempalette.cpp \ $$PWD/qquickspringanimation.cpp \ @@ -13,15 +12,12 @@ SOURCES += \ $$PWD/qquickpropertychanges.cpp \ $$PWD/qquickstategroup.cpp \ $$PWD/qquicktransition.cpp \ - $$PWD/qquicklistaccessor.cpp \ $$PWD/qquicktimeline.cpp \ $$PWD/qquickpixmapcache.cpp \ $$PWD/qquickbehavior.cpp \ $$PWD/qquickfontloader.cpp \ $$PWD/qquickstyledtext.cpp \ $$PWD/qquickpath.cpp \ - $$PWD/qquickchangeset.cpp \ - $$PWD/qquicklistcompositor.cpp \ $$PWD/qquickpathinterpolator.cpp \ $$PWD/qquickimageprovider.cpp \ $$PWD/qquicksvgparser.cpp \ @@ -31,7 +27,6 @@ SOURCES += \ HEADERS += \ $$PWD/qquickapplication_p.h\ $$PWD/qquickutilmodule_p.h\ - $$PWD/qquickpackage_p.h \ $$PWD/qquickanimation_p.h \ $$PWD/qquickanimation_p_p.h \ $$PWD/qquicksystempalette_p.h \ @@ -46,7 +41,6 @@ HEADERS += \ $$PWD/qquicktransitionmanager_p_p.h \ $$PWD/qquickstategroup_p.h \ $$PWD/qquicktransition_p.h \ - $$PWD/qquicklistaccessor_p.h \ $$PWD/qquicktimeline_p_p.h \ $$PWD/qquickpixmapcache_p.h \ $$PWD/qquickbehavior_p.h \ @@ -54,8 +48,6 @@ HEADERS += \ $$PWD/qquickstyledtext_p.h \ $$PWD/qquickpath_p.h \ $$PWD/qquickpath_p_p.h \ - $$PWD/qquickchangeset_p.h \ - $$PWD/qquicklistcompositor_p.h \ $$PWD/qquickpathinterpolator_p.h \ $$PWD/qquickimageprovider.h \ $$PWD/qquicksvgparser_p.h \ |