aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative/items/qsgvisualdatamodel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/items/qsgvisualdatamodel.cpp')
-rw-r--r--src/declarative/items/qsgvisualdatamodel.cpp152
1 files changed, 127 insertions, 25 deletions
diff --git a/src/declarative/items/qsgvisualdatamodel.cpp b/src/declarative/items/qsgvisualdatamodel.cpp
index e0d353a93f..47edc5d8f0 100644
--- a/src/declarative/items/qsgvisualdatamodel.cpp
+++ b/src/declarative/items/qsgvisualdatamodel.cpp
@@ -131,14 +131,14 @@ public:
void init();
void connectModel(QSGVisualAdaptorModel *model);
- QObject *object(Compositor::Group group, int index, bool complete);
- QSGItem *item(Compositor::Group group, int index, bool complete);
+ QObject *object(Compositor::Group group, int index, bool complete, bool reference);
void destroy(QObject *object);
QSGVisualDataModel::ReleaseFlags release(QObject *object);
QString stringValue(Compositor::Group group, int index, const QString &name);
int cacheIndexOf(QObject *object) const;
void emitCreatedPackage(Compositor::iterator at, QDeclarativePackage *package);
- void emitCreatedItem(int index, QSGItem *item) { emit q_func()->createdItem(index, item); }
+ void emitCreatedItem(Compositor::iterator at, QSGItem *item) {
+ emit q_func()->createdItem(at.index[m_compositorGroup], item); }
void emitDestroyingPackage(QDeclarativePackage *package);
void emitDestroyingItem(QSGItem *item) { emit q_func()->destroyingItem(item); }
@@ -194,6 +194,7 @@ public:
struct {
QSGVisualDataGroup *m_cacheItems;
QSGVisualDataGroup *m_items;
+ QSGVisualDataGroup *m_persistedItems;
};
QSGVisualDataGroup *m_groups[Compositor::MaximumGroupCount];
};
@@ -341,9 +342,10 @@ public:
}
void referenceObject() { ++objectRef; }
- bool releaseObject() { return --objectRef == 0; }
+ bool releaseObject() { return --objectRef == 0 && !(groups & Compositor::PersistedFlag); }
+ bool isObjectReferenced() const { return objectRef == 0 && !(groups & Compositor::PersistedFlag); }
- bool isReferenced() const { return objectRef || scriptRef; }
+ bool isReferenced() const { return objectRef || scriptRef || (groups & Compositor::PersistedFlag); }
void Dispose();
@@ -409,7 +411,7 @@ QSGVisualDataModelPrivate::QSGVisualDataModelPrivate(QDeclarativeContext *ctxt)
, m_filterGroup(QStringLiteral("items"))
, m_cacheItems(0)
, m_items(0)
- , m_groupCount(2)
+ , m_groupCount(3)
{
}
@@ -427,11 +429,14 @@ void QSGVisualDataModelPrivate::connectModel(QSGVisualAdaptorModel *model)
void QSGVisualDataModelPrivate::init()
{
Q_Q(QSGVisualDataModel);
+ m_compositor.setRemoveGroups(Compositor::GroupMask & ~Compositor::PersistedFlag);
+
m_adaptorModel = new QSGVisualAdaptorModel;
QObject::connect(m_adaptorModel, SIGNAL(rootIndexChanged()), q, SIGNAL(rootIndexChanged()));
m_items = new QSGVisualDataGroup(QStringLiteral("items"), q, Compositor::Default, q);
m_items->setDefaultInclude(true);
+ m_persistedItems = new QSGVisualDataGroup(QStringLiteral("persistedItems"), q, Compositor::Persisted, q);
QSGVisualDataGroupPrivate::get(m_items)->emitters.insert(this);
}
@@ -477,9 +482,12 @@ void QSGVisualDataModel::componentComplete()
int defaultGroups = 0;
QStringList groupNames;
groupNames.append(QStringLiteral("items"));
+ groupNames.append(QStringLiteral("persistedItems"));
if (QSGVisualDataGroupPrivate::get(d->m_items)->defaultInclude)
defaultGroups |= Compositor::DefaultFlag;
- for (int i = 2; i < d->m_groupCount; ++i) {
+ if (QSGVisualDataGroupPrivate::get(d->m_persistedItems)->defaultInclude)
+ defaultGroups |= Compositor::PersistedFlag;
+ for (int i = 3; 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];
@@ -683,6 +691,16 @@ int QSGVisualDataModel::count() const
return d->m_compositor.count(d->m_compositorGroup);
}
+void QSGVisualDataModelPrivate::destroy(QObject *object)
+{
+ QObjectPrivate *p = QObjectPrivate::get(object);
+ Q_ASSERT(p->declarativeData);
+ QDeclarativeData *data = static_cast<QDeclarativeData*>(p->declarativeData);
+ if (data->ownContext && data->context)
+ data->context->clearContext();
+ object->deleteLater();
+}
+
QSGVisualDataModel::ReleaseFlags QSGVisualDataModelPrivate::release(QObject *object)
{
QSGVisualDataModel::ReleaseFlags stat = 0;
@@ -693,12 +711,7 @@ QSGVisualDataModel::ReleaseFlags QSGVisualDataModelPrivate::release(QObject *obj
if (cacheIndex != -1) {
QSGVisualDataModelCacheItem *cacheItem = m_cache.at(cacheIndex);
if (cacheItem->releaseObject()) {
- QObjectPrivate *p = QObjectPrivate::get(object);
- Q_ASSERT(p->declarativeData);
- QDeclarativeData *data = static_cast<QDeclarativeData*>(p->declarativeData);
- if (data->ownContext && data->context)
- data->context->clearContext();
- object->deleteLater();
+ destroy(object);
cacheItem->object = 0;
stat |= QSGVisualModel::Destroyed;
if (!cacheItem->isReferenced()) {
@@ -733,7 +746,7 @@ void QSGVisualDataModelPrivate::group_append(
QSGVisualDataModelPrivate *d = static_cast<QSGVisualDataModelPrivate *>(property->data);
if (d->m_complete)
return;
- if (d->m_groupCount == 10) {
+ if (d->m_groupCount == 11) {
qmlInfo(d->q_func()) << QSGVisualDataModel::tr("The maximum number of supported VisualDataGroups is 8");
return;
}
@@ -799,6 +812,29 @@ QSGVisualDataGroup *QSGVisualDataModel::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.
+*/
+
+QSGVisualDataGroup *QSGVisualDataModel::persistedItems()
+{
+ Q_D(QSGVisualDataModel);
+ return d->m_persistedItems;
+}
+
+/*!
\qmlproperty string QtQuick2::VisualDataModel::filterOnGroup
This property holds the name of the group used to filter the visual data model.
@@ -918,13 +954,9 @@ void QSGVisualDataModelPrivate::emitDestroyingPackage(QDeclarativePackage *packa
QSGVisualDataGroupPrivate::get(m_groups[i])->destroyingPackage(package);
}
-QObject *QSGVisualDataModelPrivate::object(Compositor::Group group, int index, bool complete)
+QObject *QSGVisualDataModelPrivate::object(Compositor::Group group, int index, bool complete, bool reference)
{
Q_Q(QSGVisualDataModel);
- if (!m_delegate || index < 0 || index >= m_compositor.count(group)) {
- qWarning() << "VisualDataModel::item: index out range" << index << m_compositor.count(group);
- return 0;
- }
Compositor::iterator it = m_compositor.find(group, index);
QSGVisualDataModelCacheItem *cacheItem = it->inCache() ? m_cache.at(it.cacheIndex) : 0;
@@ -970,8 +1002,12 @@ QObject *QSGVisualDataModelPrivate::object(Compositor::Group group, int index, b
new QSGVisualDataModelAttachedMetaObject(cacheItem->attached, m_cacheMetaType);
cacheItem->attached->emitChanges();
- if (QDeclarativePackage *package = qobject_cast<QDeclarativePackage *>(cacheItem->object))
+ if (QDeclarativePackage *package = qobject_cast<QDeclarativePackage *>(cacheItem->object)) {
emitCreatedPackage(it, package);
+ } else if (!reference) {
+ if (QSGItem *item = qobject_cast<QSGItem *>(cacheItem->object))
+ emitCreatedItem(it, item);
+ }
m_completePending = !complete;
if (complete)
@@ -987,14 +1023,20 @@ QObject *QSGVisualDataModelPrivate::object(Compositor::Group group, int index, b
if (index == m_compositor.count(group) - 1 && m_adaptorModel->canFetchMore())
QCoreApplication::postEvent(q, new QEvent(QEvent::UpdateRequest));
- cacheItem->referenceObject();
+ if (reference)
+ cacheItem->referenceObject();
return cacheItem->object;
}
QSGItem *QSGVisualDataModel::item(int index, bool complete)
{
Q_D(QSGVisualDataModel);
- QObject *object = d->object(d->m_compositorGroup, index, complete);
+ 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, complete, true);
if (QSGItem *item = qobject_cast<QSGItem *>(object))
return item;
if (d->m_completePending)
@@ -1251,6 +1293,14 @@ void QSGVisualDataModelPrivate::itemsRemoved(
} else {
for (; cacheIndex < remove.cacheIndex + remove.count - removedCache; ++cacheIndex) {
QSGVisualDataModelCacheItem *cacheItem = m_cache.at(cacheIndex);
+ if (remove.inGroup(Compositor::Persisted) && cacheItem->objectRef == 0) {
+ destroy(cacheItem->object);
+ if (QDeclarativePackage *package = qobject_cast<QDeclarativePackage *>(cacheItem->object))
+ emitDestroyingPackage(package);
+ else if (QSGItem *item = qobject_cast<QSGItem *>(cacheItem->object))
+ emitDestroyingItem(item);
+ cacheItem->object = 0;
+ }
if (remove.groups() == cacheItem->groups && !cacheItem->isReferenced()) {
m_compositor.clearFlags(Compositor::Cache, cacheIndex, 1, Compositor::CacheFlag);
m_cache.removeAt(cacheIndex);
@@ -1742,6 +1792,26 @@ void QSGVisualDataModelAttached::setGroups(const QStringList &groups)
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 QSGVisualDataModelAttached::emitChanges()
{
if (m_modelChanged) {
@@ -1925,9 +1995,9 @@ void QSGVisualDataGroup::setDefaultInclude(bool include)
a delegate
\o \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.
- \o \b inItems Whether the item belongs to the \l {VisualDataModel::items}{items} group.
+ \o \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.
- \o \b itemsIndex The index of the item within the \l {VisualDataModel::items}{items} group.
+ \o \b itemsIndex The index of the item within the \l {QtQuick2::VisualDataModel::items}{items} group.
\o \b {in\i{GroupName}} Whether the item belongs to the dynamic group \i groupName. Writing to
this property will add or remove the item from the group.
\o \b {\i{groupName}Index} The index of the item within the dynamic group \i groupName.
@@ -1969,6 +2039,33 @@ QDeclarativeV8Handle QSGVisualDataGroup::get(int index)
}
/*!
+ \qmlmethod QtQuick2::VisualDataGroup::create(int index)
+
+ Returns a reference to the instantiated item at \a index in the group.
+
+ All items returned by create are added to the persistedItems group. Items in this
+ group remain instantiated when not referenced by any view.
+*/
+
+QObject *QSGVisualDataGroup::create(int index)
+{
+ Q_D(QSGVisualDataGroup);
+ if (!d->model)
+ return 0;
+
+ QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(d->model);
+ if (index < 0 || index >= model->m_compositor.count(d->group)) {
+ qmlInfo(this) << tr("create: index out of range");
+ return 0;
+ }
+
+ QObject *object = model->object(d->group, index, true, false);
+ if (object)
+ model->addGroups(d->group, index, 1, Compositor::PersistedFlag);
+ return object;
+}
+
+/*!
\qmlmethod QtQuick2::VisualDataGroup::remove(int index, int count)
Removes \a count items starting at \a index from the group.
@@ -2332,7 +2429,12 @@ QSGItem *QSGVisualPartsModel::item(int index, bool complete)
{
QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(m_model);
- QObject *object = model->object(m_compositorGroup, index, complete);
+ 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, complete, true);
if (QDeclarativePackage *package = qobject_cast<QDeclarativePackage *>(object)) {
QObject *part = package->part(m_part);