28 class KReparentingProxyModelPrivate
31 : q_ptr(proxyModel), m_nextId(0)
36 qint64 newId()
const {
return m_nextId++; }
49 QHash<QModelIndex, QModelIndexList> recreateMappings(
const QModelIndex &parent,
int start,
int end = -1,
int strategy = MapChildrenOnly)
const;
57 QHash<QModelIndex, QModelIndexList> mergeDescendants(QHash<QModelIndex, QModelIndexList> mappings,
const QModelIndex &parent,
int start );
63 void verifyStructure(
const QModelIndex &parent,
int start);
70 QModelIndex getIndexBelow(
const QModelIndex &index, QAbstractItemModel *model = 0)
const;
75 QModelIndex getLastDescendant(
const QModelIndex &index)
const;
77 bool isDescendantInModel(
const QModelIndex &ancestor,
const QModelIndex &descendant)
const;
87 void sourceRowsAboutToBeInserted(
const QModelIndex &parent,
int start,
int end);
88 void sourceRowsInserted(
const QModelIndex &parent,
int start,
int end);
89 void sourceRowsAboutToBeRemoved(
const QModelIndex &parent,
int start,
int end);
90 void sourceRowsRemoved(
const QModelIndex &parent,
int start,
int end);
91 void sourceRowsAboutToBeMoved(
const QModelIndex &parent,
int start,
int end,
const QModelIndex &destParent,
int destRow);
92 void sourceRowsMoved(
const QModelIndex &parent,
int start,
int end,
const QModelIndex &destParent,
int destRow);
93 void sourceModelAboutToBeReset();
94 void sourceModelReset();
95 void sourceLayoutAboutToBeChanged();
96 void sourceLayoutChanged();
97 void sourceDataChanged(
const QModelIndex &topLeft,
const QModelIndex &bottomRight);
99 mutable QHash<qint64, QPersistentModelIndex> m_parents;
100 mutable QHash<QPersistentModelIndex, QList<QPersistentModelIndex> > m_childIndexes;
102 struct PendingInsertion
105 : parentId(-1), start(-1), end(-1)
108 PendingInsertion(
const QModelIndex &_index,
int _start,
int _end)
109 : index(_index), parentId(-1), start(_start), end(_end)
112 QPersistentModelIndex index;
113 QModelIndex sourceIndex;
119 struct PendingRemoval : PendingInsertion
124 mutable QHash<qint64, QPersistentModelIndex> m_pendingRemovalParents;
125 mutable QHash<QPersistentModelIndex, QList<QPersistentModelIndex> > m_pendingRemovalChildIndexes;
127 QHash<QModelIndex, QModelIndexList> insertTree( QHash<QModelIndex, QModelIndexList> mappings,
const QModelIndex &parent );
129 void handleInsertion(
const PendingInsertion &pendingInsertion);
131 void handleRemoval(
const PendingRemoval &pendingRemoval);
133 mutable QHash<QModelIndex, PendingInsertion> m_pendingInsertions;
136 mutable qint64 m_nextId;
141 QList<QPersistentModelIndex> m_layoutChangePersistentIndexes;
142 QModelIndexList m_proxyIndexes;
144 void emitDataChangedSignals(const QModelIndex &parent,
int maxChanged);
150 QModelIndex findLastInParent(QModelIndex parent,
int start,
int end);
155 void removeTree(const QPersistentModelIndex &idx,
int start = 0,
int end = -1);
157 int pendingRemovalRowCount(const QModelIndex &sourceIndex) const;
166 bool operator()(
const QModelIndex &ancestor,
const QModelIndex &descendant)
172 QModelIndex KReparentingProxyModelPrivate::getIndexBelow(
const QModelIndex &index, QAbstractItemModel *model)
const
177 model = q->sourceModel();
179 if (model->hasChildren(index))
180 return model->index(0, 0, index);
182 QModelIndex sibling = index.sibling(index.row() + 1, index.column());
183 if (sibling.isValid())
186 QModelIndex parent = sibling.parent();
188 if(!parent.isValid())
189 return QModelIndex();
191 int affectedRow = index.row();
192 const int column = 0;
194 while (parent.isValid())
196 if (model->rowCount(parent) >= affectedRow)
197 return model->index(affectedRow + 1, column, parent);
199 affectedRow = parent.row();
200 parent = parent.parent();
203 if (model->rowCount(parent) >= affectedRow)
204 return model->index(affectedRow + 1, column, parent);
206 return QModelIndex();
209 QModelIndex KReparentingProxyModelPrivate::getLastDescendant(
const QModelIndex &index)
const
213 QModelIndex proxyIndex = q->mapFromSource(index);
215 while (q->hasChildren(proxyIndex))
217 proxyIndex = proxyIndex.child(q->rowCount(proxyIndex), proxyIndex.column());
218 if (!proxyIndex.isValid())
221 return q->mapToSource(proxyIndex);
224 QVector<QModelIndex> KReparentingProxyModelPrivate::getExistingAncestors(
const QModelIndex &descendant)
const
229 if (!descendant.isValid())
232 QModelIndex parent = q->mapFromSource(descendant).parent();
233 vector.append(q->mapToSource(parent));
234 while (parent.isValid())
236 parent = parent.parent();
237 vector.prepend(q->mapToSource(parent));
242 QHash<QModelIndex, QModelIndexList> KReparentingProxyModelPrivate::recreateMappings(
const QModelIndex &ancestor,
int start,
int end,
int strategy)
const
245 const int column = 0;
247 QHash<QModelIndex, QModelIndexList> mappings;
249 if (!ancestor.isValid() && !q->sourceModel()->hasChildren())
259 QModelIndex indexAbove;
261 indexAbove = getLastDescendant(q->sourceModel()->index(start - 1, column, ancestor));
263 indexAbove = ancestor;
267 ancestors.append(indexAbove);
269 QModelIndex nextIndex = ancestor;
271 for (
int row = start; (row <= end || end == -1); ++row)
274 if (MapDescendants == strategy)
276 nextIndex = getIndexBelow(nextIndex);
278 nextIndex = q->sourceModel()->index(row, column, ancestor);
280 if (!nextIndex.isValid())
283 QModelIndex deepestAncestor = ancestors.last();
284 if (q->isDescendantOf(deepestAncestor, nextIndex))
286 mappings[deepestAncestor].append(nextIndex);
287 ancestors.append(nextIndex);
290 kDebug()<<
"######\nNextIndex" << nextIndex.data();
291 foreach(
const QModelIndex &idx, ancestors)
293 kDebug() <<
"#" << idx << idx.data();
298 if (ancestorIt != ancestors.begin())
300 parent = *(ancestorIt - 1);
303 ancestorIt = ancestors.insert(ancestorIt, nextIndex);
305 if (ancestorIt != ancestors.end())
308 while (ancestorIt != ancestors.end())
310 ancestorIt = ancestors.erase(ancestorIt);
313 mappings[parent].append(nextIndex);
319 void KReparentingProxyModelPrivate::verifyStructure(
const QModelIndex &sourceParent,
int sourceStart)
360 QHash<QModelIndex, QModelIndexList> mappings = recreateMappings(sourceParent, sourceStart, -1);
362 if (mappings.isEmpty())
365 QModelIndex sourceFirstIndex = q->sourceModel()->index(sourceStart, 0, sourceParent);
367 QModelIndex destinationParent;
368 QModelIndexList movedIndexes;
370 QHashIterator<QModelIndex, QModelIndexList> it(mappings);
374 kDebug() << it.key() << it.key().data() << it.value();
375 if (it.value().at(0) == sourceFirstIndex)
377 destinationParent = it.key();
378 movedIndexes = it.value();
386 if (destinationParent == sourceParent)
390 Q_ASSERT(destinationParent.isValid());
391 Q_ASSERT(!movedIndexes.isEmpty());
397 QList<QPersistentModelIndex> &existingSourceIndexes = m_childIndexes[sourceParent];
398 QList<QPersistentModelIndex> existingDestinationIndexes = m_childIndexes[destinationParent];
400 QModelIndex proxySourceParent = q->mapFromSource(sourceParent);
401 QModelIndex proxyDestinationParent = q->mapFromSource(destinationParent);
404 int proxySourceStart = m_childIndexes.value(sourceParent).indexOf(movedIndexes.at(0));
405 int proxySourceEnd = proxySourceStart + movedIndexes.size() - 1;
410 int destinationRow = existingDestinationIndexes.size();
412 bool allowMove = q->beginMoveRows(proxySourceParent, proxySourceStart, proxySourceEnd, proxyDestinationParent, destinationRow);
415 for (
int row = proxySourceEnd; row >= proxySourceStart; --row)
417 existingSourceIndexes.removeAt(row);
420 QHash<QModelIndex, QModelIndexList> mapping;
421 mapping.insert(destinationParent, movedIndexes);
422 mergeDescendants(mapping, destinationParent, existingDestinationIndexes.size());
426 if (!mappings.contains(q->mapToSource(proxyDestinationParent.parent())))
429 destinationParent = q->mapToSource(proxyDestinationParent.parent());
430 movedIndexes = mappings.value(destinationParent);
446 bool KReparentingProxyModelPrivate::isDescendantInModel(
const QModelIndex& ancestor,
const QModelIndex& descendant)
const
448 kDebug() << ancestor.data() << descendant.data();
453 QModelIndex _ancestor = descendant.parent();
454 while (_ancestor.isValid())
456 if (_ancestor == ancestor)
458 _ancestor = _ancestor.parent();
460 return (!ancestor.isValid() && descendant.isValid());
466 return d->isDescendantInModel(ancestor, descendant);
473 if (!sourceIndex.isValid())
474 return QModelIndex();
476 QModelIndex sourceIndexFirstColumn = sourceIndex.sibling(sourceIndex.row(), 0);
478 QHash<QPersistentModelIndex, QList<QPersistentModelIndex> >::const_iterator it;
479 const QHash<QPersistentModelIndex, QList<QPersistentModelIndex> >::const_iterator begin = d->m_childIndexes.constBegin();
480 const QHash<QPersistentModelIndex, QList<QPersistentModelIndex> >::const_iterator end = d->m_childIndexes.constEnd();
482 for(it = begin; it != end; ++it)
484 QList<QPersistentModelIndex> list = it.value();
485 if (list.contains(sourceIndexFirstColumn))
487 QModelIndex sourceParent = it.key();
489 int row = list.indexOf(sourceIndexFirstColumn);
492 Q_ASSERT(d->m_parents.values().contains(sourceParent));
494 qint64
id = d->m_parents.key(sourceParent);
497 return createIndex(row, sourceIndex.column(),
reinterpret_cast<void*
>(id));
500 return QModelIndex();
509 if (!proxyIndex.isValid())
510 return QModelIndex();
512 qint64
id =
reinterpret_cast<qint64
>(proxyIndex.internalPointer());
517 QModelIndex sourceParent;
518 if (d->m_pendingRemovalParents.contains(
id))
521 sourceParent = d->m_pendingRemovalParents.value(
id);
523 Q_ASSERT(d->m_parents.contains(
id));
524 sourceParent = d->m_parents.value(
id);
529 QModelIndex sourceIndexFirstColumn;
530 if (d->m_pendingRemovalChildIndexes.contains(sourceParent)) {
533 foreach(
const KReparentingProxyModelPrivate::PendingRemoval &pendingRemoval, d->m_pendingRemovals)
536 if (pendingRemoval.sourceIndex == sourceParent)
539 int proxyRow = proxyIndex.row();
540 int row = proxyRow - pendingRemoval.start;
544 if (proxyRow > pendingRemoval.end)
546 Q_ASSERT(d->m_childIndexes.contains(sourceParent));
547 row = proxyRow - (pendingRemoval.end - pendingRemoval.start + 1);
549 sourceIndexFirstColumn = d->m_childIndexes.value(sourceParent).at(row);
552 sourceIndexFirstColumn = d->m_pendingRemovalChildIndexes.value(sourceParent).at(row);
557 Q_ASSERT(d->m_childIndexes.contains(sourceParent));
558 sourceIndexFirstColumn = d->m_childIndexes.value(sourceParent).at(proxyIndex.row());
561 Q_ASSERT(sourceIndexFirstColumn.isValid());
563 return sourceIndexFirstColumn.sibling(sourceIndexFirstColumn.row(), proxyIndex.column());
570 if (!parent.isValid())
571 return sourceModel()->columnCount();
573 if ( parent.column() > 0 )
579 return (d->m_childIndexes.value(sourceIndex).size() > 0)
580 ? sourceModel()->columnCount() : 0;
585 return QAbstractProxyModel::data(proxyIndex, role);
592 if (!hasIndex(row, column, parent))
593 return QModelIndex();
608 if(d->m_pendingRemovalParents.values().contains(sourceParent))
610 id = d->m_pendingRemovalParents.key(sourceParent);
613 Q_ASSERT(d->m_parents.values().contains(sourceParent));
614 id = d->m_parents.key(sourceParent);
616 return createIndex(row, column, reinterpret_cast<void*>(
id));
623 if (!child.isValid())
624 return QModelIndex();
628 QModelIndex firstColumnChild = sourceIndex;
629 if (sourceIndex.column() > 0)
630 firstColumnChild = sourceIndex.sibling(sourceIndex.row(), 0);
632 QHashIterator<QPersistentModelIndex, QList<QPersistentModelIndex> > itPending(d->m_pendingRemovalChildIndexes);
634 while (itPending.hasNext())
638 if (itPending.value().contains(firstColumnChild))
644 QHashIterator<QPersistentModelIndex, QList<QPersistentModelIndex> > it(d->m_childIndexes);
650 if (it.value().contains(firstColumnChild))
655 return QModelIndex();
658 int KReparentingProxyModelPrivate::pendingRemovalRowCount(
const QModelIndex &sourceIndex)
const
661 foreach(
const PendingRemoval &pendingRemoval, m_pendingRemovals)
664 if (pendingRemoval.sourceIndex == sourceIndex)
665 return pendingRemoval.end - pendingRemoval.start + 1;
675 if ( parent.column() > 0 )
680 int size = d->m_childIndexes.value(sourceIndex).size() + d->m_pendingRemovalChildIndexes.value(sourceIndex).size();
703 disconnect(sourceModel, SIGNAL(rowsAboutToBeInserted(QModelIndex,
int,
int)),
704 this, SLOT(sourceRowsAboutToBeInserted(QModelIndex,
int,
int)));
705 disconnect(sourceModel, SIGNAL(rowsInserted(QModelIndex,
int,
int)),
706 this, SLOT(sourceRowsInserted(QModelIndex,
int,
int)));
707 disconnect(sourceModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,
int,
int)),
708 this, SLOT(sourceRowsAboutToBeRemoved(QModelIndex,
int,
int)));
709 disconnect(sourceModel, SIGNAL(rowsRemoved(QModelIndex,
int,
int)),
710 this, SLOT(sourceRowsRemoved(QModelIndex,
int,
int)));
711 disconnect(sourceModel, SIGNAL(rowsAboutToBeMoved(QModelIndex,
int,
int,QModelIndex,
int)),
712 this, SLOT(sourceRowsAboutToBeMoved(QModelIndex,
int,
int,QModelIndex,
int)));
713 disconnect(sourceModel, SIGNAL(rowsMoved(QModelIndex,
int,
int,QModelIndex,
int)),
714 this, SLOT(sourceRowsMoved(QModelIndex,
int,
int,QModelIndex,
int)));
715 disconnect(sourceModel, SIGNAL(modelAboutToBeReset()),
716 this, SLOT(sourceModelAboutToBeReset()));
717 disconnect(sourceModel, SIGNAL(modelReset()),
718 this, SLOT(sourceModelReset()));
719 disconnect(sourceModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
720 this, SLOT(sourceDataChanged(QModelIndex,QModelIndex)));
721 disconnect(sourceModel, SIGNAL(layoutAboutToBeChanged()),
722 this, SLOT(sourceLayoutAboutToBeChanged()));
723 disconnect(sourceModel, SIGNAL(layoutChanged()),
724 this, SLOT(sourceLayoutChanged()));
726 QAbstractProxyModel::setSourceModel(sourceModel);
728 QHash<QModelIndex, QModelIndexList> mappings = d->recreateMappings(QModelIndex(), 0, sourceModel->rowCount() - 1, KReparentingProxyModelPrivate::MapDescendants);
729 d->mergeDescendants(mappings, QModelIndex(), 0);
731 connect(sourceModel, SIGNAL(rowsAboutToBeInserted(QModelIndex,
int,
int)),
732 SLOT(sourceRowsAboutToBeInserted(QModelIndex,
int,
int)));
733 connect(sourceModel, SIGNAL(rowsInserted(QModelIndex,
int,
int)),
734 SLOT(sourceRowsInserted(QModelIndex,
int,
int)));
735 connect(sourceModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,
int,
int)),
736 SLOT(sourceRowsAboutToBeRemoved(QModelIndex,
int,
int)));
737 connect(sourceModel, SIGNAL(rowsRemoved(QModelIndex,
int,
int)),
738 SLOT(sourceRowsRemoved(QModelIndex,
int,
int)));
739 connect(sourceModel, SIGNAL(rowsAboutToBeMoved(QModelIndex,
int,
int,QModelIndex,
int)),
740 SLOT(sourceRowsAboutToBeMoved(QModelIndex,
int,
int,QModelIndex,
int)));
741 connect(sourceModel, SIGNAL(rowsMoved(QModelIndex,
int,
int,QModelIndex,
int)),
742 SLOT(sourceRowsMoved(QModelIndex,
int,
int,QModelIndex,
int)));
743 connect(sourceModel, SIGNAL(modelAboutToBeReset()),
744 SLOT(sourceModelAboutToBeReset()));
745 connect(sourceModel, SIGNAL(modelReset()),
746 SLOT(sourceModelReset()));
747 connect(sourceModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
748 SLOT(sourceDataChanged(QModelIndex,QModelIndex)));
749 connect(sourceModel, SIGNAL(layoutAboutToBeChanged()),
750 SLOT(sourceLayoutAboutToBeChanged()));
751 connect(sourceModel, SIGNAL(layoutChanged()),
752 SLOT(sourceLayoutChanged()));
757 void KReparentingProxyModelPrivate::sourceRowsAboutToBeInserted(
const QModelIndex &parent,
int start,
int end)
763 PendingInsertion pendingInsertion(parent, start, end);
764 m_pendingInsertions.insert(parent, pendingInsertion);
767 QHash<QModelIndex, QModelIndexList> KReparentingProxyModelPrivate::mergeDescendants(QHash<QModelIndex, QModelIndexList> mappings,
const QModelIndex &parent,
int start)
769 QModelIndexList childIndexes = mappings.take(parent);
770 kDebug() << childIndexes;
771 if (!childIndexes.isEmpty())
773 if (!m_parents.values().contains(parent))
775 m_parents.insert(newId(), QPersistentModelIndex(parent));
779 foreach (
const QModelIndex &idx, childIndexes)
781 m_childIndexes[parent].insert(row++, QPersistentModelIndex(idx));
782 mappings = mergeDescendants(mappings, idx, 0);
787 QHash<QModelIndex, QModelIndexList> KReparentingProxyModelPrivate::insertTree( QHash<QModelIndex, QModelIndexList> mappings,
const QModelIndex &parent )
789 return QHash<QModelIndex, QModelIndexList>();
792 void KReparentingProxyModelPrivate::handleInsertion(
const PendingInsertion &pendingInsertion)
795 QModelIndex parent = pendingInsertion.index;
796 int start = pendingInsertion.start;
797 int end = pendingInsertion.end;
799 kDebug() << parent << parent.data() << start << end;
808 QHash<QModelIndex, QModelIndexList> newItemMappings = recreateMappings(parent, start, end, KReparentingProxyModelPrivate::MapDescendants);
815 kDebug() <<
"new item mappings" << newItemMappings;
817 const int column = 0;
819 kDebug() << m_childIndexes.contains(parent);
821 if (newItemMappings.contains(parent))
823 QModelIndexList newItemList = newItemMappings.value(parent);
824 kDebug() <<
"newItemList" << newItemList;
830 if (newItemList.isEmpty())
832 if (!newItemMappings.contains(parent.parent()))
835 newItemList = newItemMappings.value(parent.parent());
841 QModelIndex proxyParent = q->mapFromSource(parent);
844 QModelIndex lastDesc = q->mapFromSource(getLastDescendant(q->sourceModel()->index(start - 1, column, parent)));
846 while (lastDesc.parent() != proxyParent)
848 lastDesc = lastDesc.parent();
850 proxyStart = lastDesc.row() + 1;
853 q->beginInsertRows(proxyParent, proxyStart, proxyStart + newItemList.size() - 1);
855 newItemMappings = mergeDescendants(newItemMappings, parent, proxyStart);
859 if (!newItemMappings.contains(parent.parent()))
862 newItemList = newItemMappings.value(parent.parent());
875 void KReparentingProxyModelPrivate::sourceRowsInserted(
const QModelIndex &parent,
int start,
int end)
878 if (m_pendingInsertions.contains(parent))
880 PendingInsertion pendingInsertion = m_pendingInsertions.value(parent);
881 handleInsertion(pendingInsertion);
883 if (q->sourceModel()->rowCount(parent) <= (end + 1))
887 verifyStructure(parent, end + 1);
891 void KReparentingProxyModelPrivate::removeTree(
const QPersistentModelIndex &idxToRemove,
int start,
int end)
893 if (!m_childIndexes.contains(idxToRemove))
898 QList<QPersistentModelIndex> &toRemove = m_childIndexes[ idxToRemove ];
924 QList<QPersistentModelIndex>::iterator it = toRemove.begin();
925 QList<QPersistentModelIndex>::iterator endIt = toRemove.end();
932 endIt = it + (end - start + 1) + 1;
939 QPersistentModelIndex idx = *it;
942 if (m_parents.values().contains(idx))
944 qint64 key = m_parents.key(idx);
945 QPersistentModelIndex value = m_parents.take(key);
946 m_pendingRemovalParents.insert(key, value);
953 m_pendingRemovalChildIndexes[idxToRemove].append(idx);
956 it = toRemove.erase(it);
985 void KReparentingProxyModelPrivate::sourceRowsAboutToBeRemoved(
const QModelIndex &parent,
int start,
int end)
988 kDebug() << parent << start << end;
1010 const int column = 0;
1012 QModelIndex firstAffectedIndex = q->mapFromSource(q->sourceModel()->index(start, column, parent));
1013 QModelIndex lastAffectedIndex = q->mapFromSource(q->sourceModel()->index(end, column, parent));
1015 kDebug() <<
"firstAffectedIndex" << firstAffectedIndex.data();
1016 kDebug() <<
"lastAffectedIndex" << lastAffectedIndex.data();
1018 QModelIndex proxyParent = firstAffectedIndex.parent();
1020 Q_ASSERT(firstAffectedIndex.isValid() && lastAffectedIndex.isValid());
1024 if (isDescendantInModel(proxyParent, lastAffectedIndex))
1028 QModelIndex _parent = lastAffectedIndex.parent();
1029 QModelIndex lastAffectedAncestor = lastAffectedIndex;
1030 kDebug() <<
"last affected ancestor" << lastAffectedAncestor.data();
1031 while (_parent != proxyParent)
1033 lastAffectedAncestor = _parent;
1034 _parent = _parent.parent();
1037 if (q->hasChildren(lastAffectedAncestor))
1039 QModelIndex next = q->index(0, 0, lastAffectedAncestor);
1041 QModelIndex proxySourceParent = lastAffectedAncestor;
1042 int startRow = next.row();
1043 int lastRow = q->rowCount(lastAffectedAncestor) - 1;
1045 QList<QPersistentModelIndex> &existingSourceIndexes = m_childIndexes[q->mapToSource(proxySourceParent)];
1046 QList<QPersistentModelIndex> &existingDestinationIndexes = m_childIndexes[q->mapToSource(proxyParent)];
1048 int destRow = lastAffectedAncestor.row() + 1;
1051 kDebug() <<
"Move from" << lastAffectedAncestor.data() << startRow << lastRow <<
" To " << proxyParent.data() << destRow;
1052 bool allowMove = q->beginMoveRows(lastAffectedAncestor, startRow, lastRow, proxyParent, destRow);
1053 Q_ASSERT(allowMove);
1055 for (
int i = startRow; i <= lastRow; ++i)
1057 QPersistentModelIndex movingIdx = existingSourceIndexes.takeAt(startRow);
1058 existingDestinationIndexes.insert(destRow + (i - startRow), movingIdx);
1066 PendingRemoval removal;
1067 removal.index = proxyParent;
1068 removal.start = firstAffectedIndex.row();
1069 removal.end = lastAffectedAncestor.row();
1070 removal.parentId = proxyParent.internalId();
1071 removal.sourceIndex = q->mapToSource(proxyParent);
1072 m_pendingRemovals.append(removal);
1074 removeTree(q->mapToSource(proxyParent), removal.start, removal.end);
1076 kDebug() <<
"beg rem 1";
1077 q->beginRemoveRows(proxyParent, removal.start, removal.end);
1082 QModelIndex next = getIndexBelow(firstAffectedIndex);
1084 proxyParent = next.parent();
1086 while (isDescendantInModel(proxyParent, next))
1088 next = getIndexBelow(next);
1090 QModelIndex _parent = next.parent();
1091 QModelIndex lastAffectedAncestor = next;
1093 while (_parent != proxyParent)
1095 lastAffectedAncestor = _parent;
1096 _parent = _parent.parent();
1099 PendingRemoval removal;
1100 removal.index = proxyParent;
1101 removal.start = firstAffectedIndex.row();
1102 removal.end = lastAffectedAncestor.row();
1103 removal.parentId = proxyParent.internalId();
1104 removal.sourceIndex = q->mapToSource(proxyParent);
1105 m_pendingRemovals.append(removal);
1107 removeTree(q->mapToSource(proxyParent), removal.start, removal.end);
1109 kDebug() <<
"beg rem 1";
1110 q->beginRemoveRows(proxyParent, removal.start, removal.end);
1112 proxyParent = next.parent();
1194 QModelIndex KReparentingProxyModelPrivate::findLastInParent(QModelIndex parent,
int start,
int end)
1198 const int column = 0;
1201 return q->index(start, column, parent);
1203 int middle = start + (end - start / 2);
1205 QModelIndex sourceParent = q->mapToSource(parent);
1206 QModelIndex middleIndex = q->mapFromSource(q->sourceModel()->index(middle, column, sourceParent));
1208 if (middleIndex.parent() == parent)
1210 return findLastInParent(parent, middle, end);
1212 return findLastInParent(parent, start + ((middle - start) / 2), middle);
1273 void KReparentingProxyModelPrivate::handleRemoval(
const PendingRemoval &pendingRemoval)
1282 void KReparentingProxyModelPrivate::sourceRowsRemoved(
const QModelIndex &parent,
int start,
int end)
1284 kDebug() << parent << start << end;
1291 int lastAffectedRow = m_pendingRemovals.last().end;
1292 QModelIndex lastAffectedIndex = m_pendingRemovals.last().index;
1294 QMutableVectorIterator<PendingRemoval> it(m_pendingRemovals);
1296 while (it.hasNext())
1298 PendingRemoval removal = it.next();
1299 m_pendingRemovalChildIndexes.remove(removal.sourceIndex);
1300 m_pendingRemovalParents.remove(parent.internalId());
1303 emit q->endRemoveRows();
1305 kDebug() <<
"Remove done ##########";
1307 kDebug() << lastAffectedIndex << lastAffectedIndex.data() << lastAffectedRow;
1309 verifyStructure(lastAffectedIndex, lastAffectedRow - 1);
1312 void KReparentingProxyModelPrivate::sourceRowsAboutToBeMoved(
const QModelIndex &parent,
int start,
int end,
const QModelIndex& destParent,
int destRow)
1320 QModelIndex proxySourceParent = q->mapFromSource(parent);
1321 QModelIndex proxyDestinationParent = q->mapFromSource(destParent);
1355 QHash<QModelIndex, QModelIndexList> newMappings = recreateMappings(parent, start, end);
1359 void KReparentingProxyModelPrivate::sourceRowsMoved(
const QModelIndex &parent,
int start,
int end,
const QModelIndex& destParent,
int destRow)
1364 void KReparentingProxyModelPrivate::sourceLayoutAboutToBeChanged()
1368 emit q->layoutAboutToBeChanged();
1370 foreach(
const QPersistentModelIndex &proxyPersistentIndex, q->persistentIndexList()) {
1371 m_proxyIndexes << proxyPersistentIndex;
1372 m_layoutChangePersistentIndexes << QPersistentModelIndex(q->mapToSource(proxyPersistentIndex));
1376 void KReparentingProxyModelPrivate::sourceLayoutChanged()
1380 for(
int i = 0; i < m_proxyIndexes.size(); ++i)
1382 q->changePersistentIndex(m_proxyIndexes.at(i), q->mapFromSource(m_layoutChangePersistentIndexes.at(i)));
1385 m_layoutChangePersistentIndexes.clear();
1386 m_proxyIndexes.clear();
1388 emit q->layoutChanged();
1391 void KReparentingProxyModelPrivate::sourceModelAboutToBeReset()
1394 q->beginResetModel();
1397 void KReparentingProxyModelPrivate::sourceModelReset()
1402 m_childIndexes.clear();
1404 m_pendingInsertions.clear();
1405 m_pendingRemovals.clear();
1406 m_pendingRemovalChildIndexes.clear();
1407 m_pendingRemovalParents.clear();
1411 void KReparentingProxyModelPrivate::emitDataChangedSignals(
const QModelIndex &startIndex,
int maxChanged)
1415 QModelIndex proxyParent = startIndex.parent();
1417 const int column = 0;
1421 QModelIndex lastAffectedSibling = startIndex;
1422 QModelIndex proxySibling = getIndexBelow(startIndex, q);
1426 if (proxySibling.parent() != proxyParent || numChanged >= maxChanged)
1430 lastAffectedSibling = proxySibling;
1432 proxySibling = getIndexBelow(proxySibling);
1435 emit q->dataChanged(startIndex, lastAffectedSibling);
1436 if (numChanged < maxChanged)
1438 emitDataChangedSignals(proxySibling, maxChanged - numChanged);
1442 void KReparentingProxyModelPrivate::sourceDataChanged(
const QModelIndex &topLeft,
const QModelIndex &bottomRight)
1445 QModelIndex parent = topLeft.parent();
1446 const int start = topLeft.row();
1447 const int end = bottomRight.row();
1448 const int column = 0;
1449 const int maxChanged = end - start + 1;
1452 verifyStructure(parent, start);
1456 QModelIndex proxyStartIndex = q->mapFromSource(q->sourceModel()->index(start, column, parent));
1458 emitDataChangedSignals(proxyStartIndex, maxChanged);
1464 Q_ASSERT(sourceModel());
1465 return sourceModel()->supportedDropActions();
1469 #include "kreparentingproxymodel.moc"
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const
virtual bool hasChildren(const QModelIndex &parent=QModelIndex()) const
virtual QModelIndex parent(const QModelIndex &child) const
~KReparentingProxyModel()
Restructures a source model, changing the parents of items.
virtual QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
virtual bool isDescendantOf(const QModelIndex &ancestor, const QModelIndex &descendant) const
Reimplement this to return whether descendant is a descendant of ancestor.
virtual QVariant data(const QModelIndex &proxyIndex, int role=Qt::DisplayRole) const
virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const
virtual QModelIndex mapFromSource(const QModelIndex &sourceIndex) const
virtual Qt::DropActions supportedDropActions() const
virtual int columnCount(const QModelIndex &parent=QModelIndex()) const
virtual void setSourceModel(QAbstractItemModel *sourceModel)
KReparentingProxyModel(QObject *parent=0)