summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den-exter@nokia.com>2011-06-30 14:21:22 +1000
committerAndrew den Exter <andrew.den-exter@nokia.com>2011-06-30 16:09:14 +1000
commitf017b9fbcdb31ad5b175024bc0469cc2cac3a8a8 (patch)
tree17ef7cb9d20a6dba085266e1c28a0d5583275f63
parentc0fd56243fd622ae0e077a1473fc066ebf424bc7 (diff)
Fix issues in merge operation.wip/visuallistmodel
Provide a way for internal items to be merged if possible, and correctly remove the from item from the composite list.
-rw-r--r--examples/declarative/modelviews/visualdatamodel/visualdatamodel.qml2
-rw-r--r--src/declarative/items/qsgvisualitemmodel.cpp42
-rw-r--r--src/declarative/util/qdeclarativelistcompositor.cpp78
-rw-r--r--src/declarative/util/qdeclarativelistcompositor_p.h5
4 files changed, 102 insertions, 25 deletions
diff --git a/examples/declarative/modelviews/visualdatamodel/visualdatamodel.qml b/examples/declarative/modelviews/visualdatamodel/visualdatamodel.qml
index 0374ac9da6..38f1e12604 100644
--- a/examples/declarative/modelviews/visualdatamodel/visualdatamodel.qml
+++ b/examples/declarative/modelviews/visualdatamodel/visualdatamodel.qml
@@ -76,7 +76,7 @@ Rectangle {
var message = visualModel.get(j)
if (!message.outbound)
continue;
- for (var k = inserts[i].start - 1 - delta; k >= 0; ++k) {
+ for (var k = inserts[i].start - 1 - delta; k >= 0; --k) {
var existing = visualModel.get(k);
if (!existing.outbound)
continue;
diff --git a/src/declarative/items/qsgvisualitemmodel.cpp b/src/declarative/items/qsgvisualitemmodel.cpp
index feecbe5b92..2447814565 100644
--- a/src/declarative/items/qsgvisualitemmodel.cpp
+++ b/src/declarative/items/qsgvisualitemmodel.cpp
@@ -347,6 +347,9 @@ protected:
*t = *f;
}
}
+
+ bool mergeInternalData(int from, int to);
+ bool mergeInternalData(int internalIndex, void *list, int index);
};
class QSGVisualDataParts;
@@ -497,6 +500,7 @@ public:
}
QSGVisualData *model() const { return m_model; }
+ void setModel(QSGVisualData *model, int index);
QDeclarativeComponent *delegate() const { return m_delegate; }
void ensureProperties();
@@ -532,6 +536,23 @@ QSGVisualModelData *QSGVisualModelPrivate::createScriptData(QDeclarativeComponen
return data;
}
+
+bool QSGVisualModelPrivate::mergeInternalData(int internalIndex, void *list, int index)
+{
+ if (children[internalIndex].data)
+ children[internalIndex].data->setModel(static_cast<QSGVisualData *>(list), index);
+ return true;
+}
+
+bool QSGVisualModelPrivate::mergeInternalData(int from, int to)
+{
+ Q_UNUSED(to);
+ if (children[to].data && children[from].data)
+ children[to].data->setModel(children[from].data->model(), children[from].data->index());
+ removeInternalData(from, 1);
+ return true;
+}
+
QSGVisualModel::QSGVisualModel(QObject *parent)
: QObject(*(new QSGVisualModelPrivate), parent)
{
@@ -1019,14 +1040,17 @@ void QSGVisualModel::merge(int from, int to)
return;
if (!d->transaction)
d->childrenChanged = false;
- if (!d->merge(from, to)) {
+ int internalIndex = d->merge(from, to);
+ if (internalIndex == -1) {
qmlInfo(this) << "Items cannot be merged" << from << to;
- } else if (d->transaction) {
- d->transactionChanges.insertRemove(from, 1);
} else {
- emit itemsRemoved(from, 1);
- if (d->childrenChanged)
- emit childrenChanged();
+ if (d->transaction) {
+ d->transactionChanges.insertRemove(from, from + 1);
+ } else {
+ emit itemsRemoved(from, 1);
+ if (d->childrenChanged)
+ emit childrenChanged();
+ }
}
}
@@ -1280,6 +1304,12 @@ void QSGVisualModelData::setIndex(int index)
emit indexChanged();
}
+void QSGVisualModelData::setModel(QSGVisualData *model, int index)
+{
+ m_model = model;
+ m_index = index;
+ emit indexChanged();
+}
//---------------------------------------------------------------------------
diff --git a/src/declarative/util/qdeclarativelistcompositor.cpp b/src/declarative/util/qdeclarativelistcompositor.cpp
index b081549e59..6fba99fb99 100644
--- a/src/declarative/util/qdeclarativelistcompositor.cpp
+++ b/src/declarative/util/qdeclarativelistcompositor.cpp
@@ -521,7 +521,7 @@ void QDeclarativeListCompositor::move(int from, int to, int count)
Q_ASSERT(qt_verifyIntegrity(ranges, absoluteCount, internalCount));
}
-bool QDeclarativeListCompositor::merge(int from, int to)
+int QDeclarativeListCompositor::merge(int from, int to)
{
int internalIndex = 0;
int internalFrom = 0;
@@ -544,8 +544,10 @@ bool QDeclarativeListCompositor::merge(int from, int to)
internalFrom = internalIndex;
if (range->internal())
internalFrom += relativeFrom;
- relativeTo -= from - relativeFrom;
- internalIndex -= 1;
+ if (from > to)
+ relativeTo -= to - relativeFrom;
+ else
+ relativeTo -= from - relativeFrom;
break;
}
if (range->internal())
@@ -575,16 +577,44 @@ bool QDeclarativeListCompositor::merge(int from, int to)
if (fromRange == ranges.end()
|| toRange == ranges.end()
- || fromRange->list
- || !toRange->list
- || toRange->internal()) {
- return false;
+ || (!fromRange->internal() && !toRange->internal())
+ || (fromRange->list && toRange->list)) {
+ return -1;
+ } else if (fromRange->internal() && toRange->internal()) {
+ if (!mergeInternalData(internalFrom, internalTo))
+ return -1;
+ } else if (fromRange->internal()) {
+ if (!mergeInternalData(internalTo, toRange->list, toRange->index + relativeTo))
+ return -1;
+ } else if (toRange->internal()) {
+ if (!mergeInternalData(internalTo, fromRange->list, fromRange->index + relativeFrom))
+ return -1;
}
- fromRange->count -= 1;
+ void *toList = fromRange->list;
+ int toIndex = fromRange->index + relativeFrom;
- if (fromRange->count == 0)
- ranges.erase(fromRange);
+ fromRange->count -= 1;
+ int removeFrom = fromRange->index + relativeFrom;
+ if (relativeFrom > 0) {
+ int splitOffset = relativeFrom;
+ if (fromRange->list)
+ splitOffset += 1;
+ if (splitOffset < fromRange->count) {
+ fromRange = insert(fromRange, QDeclarativeCompositeRange(
+ fromRange->list, fromRange->index, relativeFrom, fromRange->flags & ~Append));
+ fromRange->index += splitOffset;
+ fromRange->count -= splitOffset;
+ } else {
+ fromRange->index += relativeFrom;
+ }
+ } else if (fromRange->list) {
+ fromRange->index += 1;
+ }
+ if (fromRange->prepend()) {
+ fromRange = insert(fromRange, QDeclarativeCompositeRange(
+ fromRange->list, removeFrom, 1, Null | Prepend));
+ }
if (relativeTo > 0) {
toRange = ++ranges.insert(toRange, QDeclarativeCompositeRange(
@@ -595,19 +625,25 @@ bool QDeclarativeListCompositor::merge(int from, int to)
if (toRange->count == 1 && !toRange->append()) {
toRange->flags |= Internal;
+ if (!toRange->list) {
+ toRange->list = toList;
+ toRange->index = toIndex;
+ }
} else {
- toRange = ++ranges.insert(toRange, QDeclarativeCompositeRange(
- toRange->list, toRange->index, 1, (toRange->flags | Internal) & ~Append));
+ if (toRange->list) {
+ toRange = ++ranges.insert(toRange, QDeclarativeCompositeRange(
+ toRange->list, toRange->index, 1, (toRange->flags | Internal) & ~Append));
+ } else {
+ toRange = ++ranges.insert(toRange, QDeclarativeCompositeRange(
+ toList, toIndex, 1, Internal));
+ }
toRange->index += 1;
toRange->count -= 1;
}
- if (internalFrom != internalTo)
- moveInternalData(internalFrom, internalTo, 1);
-
absoluteCount -= 1;
- return true;
+ return internalTo;
}
void QDeclarativeListCompositor::clear()
@@ -985,6 +1021,16 @@ void QDeclarativeListCompositor::listItemsChanged(void *list, int start, int end
}
}
+bool QDeclarativeListCompositor::mergeInternalData(int, int)
+{
+ return false;
+}
+
+bool QDeclarativeListCompositor::mergeInternalData(int, void *, int)
+{
+ return false;
+}
+
void QDeclarativeListCompositor::compress()
{
}
diff --git a/src/declarative/util/qdeclarativelistcompositor_p.h b/src/declarative/util/qdeclarativelistcompositor_p.h
index 2d2123ad8c..e3220f1466 100644
--- a/src/declarative/util/qdeclarativelistcompositor_p.h
+++ b/src/declarative/util/qdeclarativelistcompositor_p.h
@@ -106,7 +106,7 @@ public:
void removeAt(int index, int count);
void removeList(void *list, QVector<QDeclarativeChangeSet::Remove> *changes);
void move(int from, int to, int count);
- bool merge(int from, int to);
+ int merge(int from, int to);
void clear();
void clearData(int internalIndex, int count);
@@ -128,7 +128,8 @@ protected:
virtual void replaceInternalData(int index, const void *data) = 0;
virtual void removeInternalData(int index, int count) = 0;
virtual void moveInternalData(int from, int to, int count) = 0;
-
+ virtual bool mergeInternalData(int from, int to);
+ virtual bool mergeInternalData(int internalIndex, void *list, int range);
private:
int absoluteCount;