22 #include <QtCore/QStack>
23 #include <QtCore/QStringList>
24 #include <QtCore/QWeakPointer>
25 #include <QtGui/QItemSelectionRange>
28 #include "kbihash_p.h"
29 #include "kvoidpointerfactory_p.h"
37 #define KDO(object) kDebug() << #object << object
38 #define SON(object) object->setObjectName(#object)
44 template<
typename ModelIndex>
50 if (list.contains(idx))
53 QModelIndex parent = idx.parent();
54 while (parent.isValid()) {
55 if (list.contains(parent))
57 parent = parent.parent();
62 static bool isDescendantOf(
const QModelIndex &ancestor,
const QModelIndex &descendant)
64 if (!descendant.isValid())
67 if (ancestor == descendant)
70 QModelIndex parent = descendant.parent();
71 while (parent.isValid()) {
72 if (parent == ancestor)
75 parent = parent.parent();
80 static bool isDescendantOf(
const QItemSelection &selection,
const QModelIndex &descendant)
82 if (!descendant.isValid())
85 if (selection.contains(descendant))
88 QModelIndex parent = descendant.parent();
89 while (parent.isValid()) {
90 if (selection.contains(parent))
93 parent = parent.parent();
98 static bool isDescendantOf(
const QItemSelectionRange &range,
const QModelIndex &descendant)
100 if (!descendant.isValid())
103 if (range.contains(descendant))
106 QModelIndex parent = descendant.parent();
107 while (parent.isValid()) {
108 if (range.contains(parent))
111 parent = parent.parent();
118 QModelIndex commonParent = index;
119 QModelIndex youngestAncestor;
121 int firstCommonParent = -1;
122 int bestParentRow = -1;
123 while (commonParent.isValid()) {
124 youngestAncestor = commonParent;
125 commonParent = commonParent.parent();
127 for (
int i = 0; i < rootAncestors.size(); ++i) {
128 const QModelIndexList ancestorList = rootAncestors.at(i);
130 const int parentRow = ancestorList.indexOf(commonParent);
135 if (parentRow > bestParentRow) {
136 firstCommonParent = i;
137 bestParentRow = parentRow;
141 if (firstCommonParent >= 0)
146 Q_ASSERT(firstCommonParent >= 0);
148 const QModelIndexList firstAnsList = rootAncestors.at(firstCommonParent);
150 const QModelIndex eldestSibling = firstAnsList.value(bestParentRow + 1);
152 if (eldestSibling.isValid()) {
155 if (eldestSibling.row() >= youngestAncestor.row())
156 return firstCommonParent;
159 int siblingOffset = 1;
164 if (rootAncestors.size() <= firstCommonParent + siblingOffset) {
165 return firstCommonParent + siblingOffset;
179 QModelIndexList ansList = rootAncestors.at(firstCommonParent + siblingOffset);
180 if (ansList.size() <= bestParentRow) {
181 return firstCommonParent + siblingOffset;
184 QModelIndex nextParent = ansList.at(bestParentRow);
185 while (nextParent == commonParent) {
186 if (ansList.size() < bestParentRow + 1)
191 const QModelIndex nextSibling = ansList.value(bestParentRow + 1);
193 if (!nextSibling.isValid()) {
197 if (youngestAncestor.row() <= nextSibling.row()) {
203 if (rootAncestors.size() <= firstCommonParent + siblingOffset)
206 ansList = rootAncestors.at(firstCommonParent + siblingOffset);
210 if (ansList.size() <= bestParentRow) {
214 nextParent = ansList.at(bestParentRow);
217 return firstCommonParent + siblingOffset;
223 template<
typename ModelIndex>
226 if (!index.isValid())
256 foreach(
const QModelIndex &root, list) {
257 QModelIndexList ancestors;
259 QModelIndex parent = root.parent();
260 while (parent.isValid()) {
261 ancestors.prepend(parent);
262 parent = parent.parent();
264 ancestors.prepend(QModelIndex());
265 rootAncestors << ancestors;
283 QItemSelection rootSelection;
284 QItemSelection selection = _selection;
286 while (it != selection.end()) {
287 if (!it->topLeft().parent().isValid())
289 rootSelection.append(*it);
290 it = selection.erase(it);
295 it = selection.begin();
297 while ( it != end ) {
298 const QItemSelectionRange range = *it;
299 it = selection.erase(it);
304 rootSelection << range;
306 return rootSelection;
313 bool operator()(
const QItemSelectionRange &left,
const QItemSelectionRange &right)
const
315 if (right.model() == left.model()) {
317 const QModelIndex topLeftParent = left.parent();
318 const QModelIndex otherTopLeftParent = right.parent();
319 if (topLeftParent == otherTopLeftParent) {
320 if (right.top() == left.top()) {
321 if (right.left() == left.left()) {
322 if (right.bottom() == left.bottom()) {
323 return left.right() < right.right();
325 return left.bottom() < right.bottom();
327 return left.left() < right.left();
329 return left.top() < right.top();
331 return topLeftParent < otherTopLeftParent;
333 return left.model() < right.model();
339 if (selection.size() <= 1)
342 QItemSelection::const_iterator it = selection.begin();
343 const QItemSelection::const_iterator
end = selection.end();
346 QItemSelection::const_iterator scout = it + 1;
348 QItemSelection result;
349 while (scout != end) {
351 int bottom = it->bottom();
352 while (scout != end && it->parent() == scout->parent() && bottom + 1 == scout->top()) {
353 bottom = scout->bottom();
356 if (bottom != it->bottom()) {
357 const QModelIndex topLeft = it->topLeft();
358 result << QItemSelectionRange(topLeft, topLeft.sibling(bottom, it->right()));
360 Q_ASSERT(it != scout);
375 if (selection.size() <= 1)
389 QItemSelection::iterator i = selection.begin();
390 while (i != selection.end()) {
392 i = selection.erase(i);
398 qSort(selection.begin(), selection.end(), lt);
403 class KSelectionProxyModelPrivate
408 m_startWithChildTrees(false),
409 m_omitChildren(false),
410 m_omitDescendants(false),
411 m_includeAllSelected(false),
412 m_rowsInserted(false),
413 m_rowsRemoved(false),
416 m_doubleResetting(false),
417 m_layoutChanging(false),
418 m_ignoreNextLayoutAboutToBeChanged(false),
419 m_ignoreNextLayoutChanged(false),
420 m_selectionModel(selectionModel)
437 KVoidPointerFactory<> m_voidPointerFactory;
451 void updateInternalIndexes(const QModelIndex &parent,
int start,
int offset);
460 void updateInternalTopIndexes(
int start,
int offset);
462 void updateFirstChildMapping(const QModelIndex& parent,
int offset);
464 bool isFlat()
const {
return m_omitChildren || (m_omitDescendants && m_startWithChildTrees); }
470 bool ensureMappable(
const QModelIndex &parent)
const;
471 bool parentIsMappable(
const QModelIndex &parent)
const {
return parentAlreadyMapped(parent) || m_rootIndexList.contains(parent); }
476 QModelIndex mapFromSource(
const QModelIndex &parent)
const;
483 void createParentMappings(
const QModelIndex &parent,
int start,
int end)
const;
484 void createFirstChildMapping(
const QModelIndex &parent,
int proxyRow)
const;
485 bool firstChildAlreadyMapped(
const QModelIndex &firstChild)
const;
486 bool parentAlreadyMapped(
const QModelIndex &parent)
const;
487 void removeFirstChildMappings(
int start,
int end);
488 void removeParentMappings(
const QModelIndex &parent,
int start,
int end);
499 QModelIndex mapParentToSource(
const QModelIndex &proxyParent)
const;
508 QModelIndex mapParentFromSource(
const QModelIndex &sourceParent)
const;
510 QModelIndex mapTopLevelToSource(
int row,
int column)
const;
511 QModelIndex mapTopLevelFromSource(
const QModelIndex &sourceIndex)
const;
512 QModelIndex createTopLevelIndex(
int row,
int column)
const;
513 int topLevelRowCount()
const;
515 void* parentId(
const QModelIndex &proxyParent)
const {
return m_parentIds.rightToLeft(proxyParent); }
516 QModelIndex parentForId(
void *
id)
const {
return m_parentIds.leftToRight(
id); }
529 void endRemoveRows(
const QModelIndex &sourceParent,
int proxyStart,
int proxyEnd);
530 void endInsertRows(
const QModelIndex &parent,
int start,
int end);
532 void sourceRowsAboutToBeInserted(
const QModelIndex &parent,
int start,
int end);
533 void sourceRowsInserted(
const QModelIndex &parent,
int start,
int end);
534 void sourceRowsAboutToBeRemoved(
const QModelIndex &parent,
int start,
int end);
535 void sourceRowsRemoved(
const QModelIndex &parent,
int start,
int end);
536 void sourceRowsAboutToBeMoved(
const QModelIndex &parent,
int start,
int end,
const QModelIndex &destParent,
int destRow);
537 void sourceRowsMoved(
const QModelIndex &parent,
int start,
int end,
const QModelIndex &destParent,
int destRow);
538 void sourceModelAboutToBeReset();
539 void sourceModelReset();
540 void sourceLayoutAboutToBeChanged();
541 void sourceLayoutChanged();
542 void emitContinuousRanges(
const QModelIndex &sourceFirst,
const QModelIndex &sourceLast,
543 const QModelIndex &proxyFirst,
const QModelIndex &proxyLast);
544 void sourceDataChanged(
const QModelIndex &topLeft ,
const QModelIndex &bottomRight);
546 void removeSelectionFromProxy(
const QItemSelection &selection);
547 void removeRangeFromProxy(
const QItemSelectionRange &range);
549 void selectionChanged(
const QItemSelection &selected,
const QItemSelection &deselected);
550 void sourceModelDestroyed();
552 void resetInternalData();
558 int getProxyInitialRow(
const QModelIndex &parent)
const;
569 int getTargetRow(
int rootListRow);
574 void insertSelectionIntoProxy(
const QItemSelection& selection);
576 bool m_startWithChildTrees;
578 bool m_omitDescendants;
579 bool m_includeAllSelected;
585 bool m_doubleResetting;
586 bool m_layoutChanging;
587 bool m_ignoreNextLayoutAboutToBeChanged;
588 bool m_ignoreNextLayoutChanged;
589 const QWeakPointer<QItemSelectionModel> m_selectionModel;
594 QModelIndexList m_proxyIndexes;
596 struct PendingSelectionChange
598 PendingSelectionChange() {}
599 PendingSelectionChange(
const QItemSelection &selected_,
const QItemSelection &deselected_)
600 : selected(selected_), deselected(deselected_)
604 QItemSelection selected;
605 QItemSelection deselected;
607 QVector<PendingSelectionChange> m_pendingSelectionChanges;
610 void KSelectionProxyModelPrivate::emitContinuousRanges(
const QModelIndex &sourceFirst,
const QModelIndex &sourceLast,
611 const QModelIndex &proxyFirst,
const QModelIndex &proxyLast)
615 Q_ASSERT(sourceFirst.model() == q->sourceModel());
616 Q_ASSERT(sourceLast.model() == q->sourceModel());
617 Q_ASSERT(proxyFirst.model() == q);
618 Q_ASSERT(proxyLast.model() == q);
620 const int proxyRangeSize = proxyLast.row() - proxyFirst.row();
621 const int sourceRangeSize = sourceLast.row() - sourceFirst.row();
623 if (proxyRangeSize == sourceRangeSize) {
624 emit q->dataChanged(proxyFirst, proxyLast);
645 emit q->dataChanged(proxyFirst, proxyLast);
648 void KSelectionProxyModelPrivate::sourceDataChanged(
const QModelIndex &topLeft,
const QModelIndex &bottomRight)
652 Q_ASSERT(topLeft.model() == q->sourceModel());
653 Q_ASSERT(bottomRight.model() == q->sourceModel());
655 const QModelIndex sourceRangeParent = topLeft.parent();
656 if (!sourceRangeParent.isValid() && m_startWithChildTrees && !m_rootIndexList.contains(sourceRangeParent))
659 const QModelIndex proxyTopLeft = q->mapFromSource(topLeft);
660 const QModelIndex proxyBottomRight = q->mapFromSource(bottomRight);
662 const QModelIndex proxyRangeParent = proxyTopLeft.parent();
664 if (!m_omitChildren && m_omitDescendants && m_startWithChildTrees && m_includeAllSelected) {
666 if (proxyTopLeft.isValid())
667 emitContinuousRanges(topLeft, bottomRight, proxyTopLeft, proxyBottomRight);
671 if ((m_omitChildren && !m_startWithChildTrees && m_includeAllSelected)
672 || (!proxyRangeParent.isValid() && !m_startWithChildTrees)) {
676 for (
int row = topLeft.row(); row <= bottomRight.row(); ++row) {
677 const QModelIndex index = q->sourceModel()->index(row, topLeft.column(), topLeft.parent());
678 const int idx = m_rootIndexList.indexOf(index);
680 changedRows.append(idx);
683 if (changedRows.isEmpty())
685 int first = changedRows.first();
686 int previous = first;
689 for ( ; it !=
end; ++it) {
690 if (*it == previous + 1) {
693 const QModelIndex _top = q->index(first, topLeft.column());
694 const QModelIndex _bottom = q->index(previous, bottomRight.column());
695 emit q->dataChanged(_top, _bottom);
696 previous = first = *it;
699 if (first != previous) {
700 const QModelIndex _top = q->index(first, topLeft.column());
701 const QModelIndex _bottom = q->index(previous, bottomRight.column());
702 emit q->dataChanged(_top, _bottom);
706 if (proxyRangeParent.isValid()) {
707 if (m_omitChildren && !m_startWithChildTrees && !m_includeAllSelected)
710 if (!proxyTopLeft.isValid())
713 emit q->dataChanged(proxyTopLeft, proxyBottomRight);
717 if (m_startWithChildTrees && !m_omitChildren && !m_includeAllSelected && !m_omitDescendants) {
719 if (proxyTopLeft.isValid())
720 emit q->dataChanged(proxyTopLeft, proxyBottomRight);
725 void KSelectionProxyModelPrivate::sourceLayoutAboutToBeChanged()
729 if (m_ignoreNextLayoutAboutToBeChanged) {
730 m_ignoreNextLayoutAboutToBeChanged =
false;
734 if (m_rootIndexList.isEmpty())
737 emit q->layoutAboutToBeChanged();
739 QPersistentModelIndex srcPersistentIndex;
740 foreach(
const QPersistentModelIndex &proxyPersistentIndex, q->persistentIndexList()) {
741 m_proxyIndexes << proxyPersistentIndex;
742 Q_ASSERT(proxyPersistentIndex.isValid());
743 srcPersistentIndex = q->mapToSource(proxyPersistentIndex);
744 Q_ASSERT(srcPersistentIndex.isValid());
745 m_layoutChangePersistentIndexes << srcPersistentIndex;
748 QItemSelection selection;
749 foreach (
const QModelIndex &rootIndex, m_rootIndexList)
752 emit q->rootIndexAboutToBeRemoved(rootIndex);
753 selection.append(QItemSelectionRange(rootIndex, rootIndex));
757 emit q->rootSelectionAboutToBeRemoved(selection);
759 m_rootIndexList.clear();
762 void KSelectionProxyModelPrivate::sourceLayoutChanged()
766 if (m_ignoreNextLayoutChanged) {
767 m_ignoreNextLayoutChanged =
false;
771 if (m_selectionModel.data()->selection().isEmpty()) {
785 m_rootIndexList.clear();
786 m_mappedFirstChildren.clear();
787 m_mappedParents.clear();
791 m_layoutChanging =
true;
792 selectionChanged(m_selectionModel.data()->selection(), QItemSelection());
794 m_layoutChanging =
false;
796 for (
int i = 0; i < m_proxyIndexes.size(); ++i) {
797 q->changePersistentIndex(m_proxyIndexes.at(i), q->mapFromSource(m_layoutChangePersistentIndexes.at(i)));
800 m_layoutChangePersistentIndexes.clear();
801 m_proxyIndexes.clear();
803 emit q->layoutChanged();
806 void KSelectionProxyModelPrivate::resetInternalData()
808 m_rootIndexList.clear();
809 m_layoutChangePersistentIndexes.clear();
810 m_proxyIndexes.clear();
811 m_mappedParents.clear();
813 m_mappedFirstChildren.clear();
814 m_voidPointerFactory.clear();
817 void KSelectionProxyModelPrivate::sourceModelDestroyed()
826 void KSelectionProxyModelPrivate::sourceModelAboutToBeReset()
842 m_doubleResetting =
true;
846 q->beginResetModel();
850 void KSelectionProxyModelPrivate::sourceModelReset()
854 if (m_doubleResetting) {
855 m_doubleResetting =
false;
862 if (!m_selectionModel.isNull())
863 m_selectionModel.data()->reset();
868 int KSelectionProxyModelPrivate::getProxyInitialRow(
const QModelIndex &parent)
const
870 Q_ASSERT(m_rootIndexList.contains(parent));
893 Q_ASSERT(parent.model() == q->sourceModel());
895 int parentPosition = m_rootIndexList.indexOf(parent);
897 QModelIndex parentAbove;
900 while (parentPosition > 0) {
903 parentAbove = m_rootIndexList.at(parentPosition);
904 Q_ASSERT(parentAbove.isValid());
906 int rows = q->sourceModel()->rowCount(parentAbove);
908 QModelIndex sourceIndexAbove = q->sourceModel()->index(rows - 1, 0, parentAbove);
909 Q_ASSERT(sourceIndexAbove.isValid());
910 QModelIndex proxyChildAbove = mapFromSource(sourceIndexAbove);
911 Q_ASSERT(proxyChildAbove.isValid());
912 return proxyChildAbove.row() + 1;
918 void KSelectionProxyModelPrivate::updateFirstChildMapping(
const QModelIndex& parent,
int offset)
922 Q_ASSERT(parent.isValid() ? parent.model() == q->sourceModel() :
true);
924 static const int column = 0;
925 static const int row = 0;
927 const QPersistentModelIndex srcIndex = q->sourceModel()->index(row, column, parent);
929 const QPersistentModelIndex previousFirstChild = q->sourceModel()->index(offset, column, parent);
931 SourceIndexProxyRowMapping::left_iterator it = m_mappedFirstChildren.findLeft(previousFirstChild);
932 if (it == m_mappedFirstChildren.leftEnd())
935 Q_ASSERT(srcIndex.isValid());
936 const int proxyRow = it.value();
937 Q_ASSERT(proxyRow >= 0);
939 m_mappedFirstChildren.eraseLeft(it);
943 m_mappedFirstChildren.insert(srcIndex, proxyRow - offset);
946 QPair< int, int > KSelectionProxyModelPrivate::beginInsertRows(
const QModelIndex& parent,
int start,
int end)
const
948 const QModelIndex proxyParent = mapFromSource(parent);
950 if (!proxyParent.isValid())
952 if (!m_startWithChildTrees)
953 return qMakePair(-1, -1);
955 if (!m_rootIndexList.contains(parent))
956 return qMakePair(-1, -1);
959 if (!m_startWithChildTrees) {
961 if (proxyParent.isValid())
962 return qMakePair(start, end);
963 return qMakePair(-1, -1);
966 if (!m_includeAllSelected && proxyParent.isValid()) {
968 return qMakePair(start, end);
971 if (!m_rootIndexList.contains(parent))
972 return qMakePair(-1, -1);
974 const int proxyStartRow = getProxyInitialRow(parent) + start;
975 return qMakePair(proxyStartRow, proxyStartRow + (end - start));
978 void KSelectionProxyModelPrivate::sourceRowsAboutToBeInserted(
const QModelIndex &parent,
int start,
int end)
982 Q_ASSERT(parent.isValid() ? parent.model() == q->sourceModel() :
true);
984 if (!m_selectionModel.data()->hasSelection())
992 if (!parent.isValid())
996 if (pair.first == -1)
999 const QModelIndex proxyParent = m_startWithChildTrees ? QModelIndex() : mapFromSource(parent);
1001 m_rowsInserted =
true;
1002 q->beginInsertRows(proxyParent, pair.first, pair.second);
1005 void KSelectionProxyModelPrivate::endInsertRows(
const QModelIndex& parent,
int start,
int end)
1008 const QModelIndex proxyParent = mapFromSource(parent);
1009 const int offset = end - start + 1;
1011 const bool isNewParent = (q->sourceModel()->rowCount(parent) == offset);
1013 if (m_startWithChildTrees && m_rootIndexList.contains(parent)) {
1014 const int proxyInitialRow = getProxyInitialRow(parent);
1015 Q_ASSERT(proxyInitialRow >= 0);
1016 const int proxyStartRow = proxyInitialRow + start;
1018 updateInternalTopIndexes(proxyStartRow, offset);
1020 createFirstChildMapping(parent, proxyStartRow);
1021 else if (start == 0)
1024 updateFirstChildMapping(parent, end + 1);
1026 Q_ASSERT(proxyParent.isValid());
1028 updateInternalIndexes(proxyParent, start, offset);
1030 createParentMappings(parent.parent(), parent.row(), parent.row());
1032 createParentMappings(parent, start, end);
1035 void KSelectionProxyModelPrivate::sourceRowsInserted(
const QModelIndex &parent,
int start,
int end)
1039 Q_ASSERT(parent.isValid() ? parent.model() == q->sourceModel() :
true);
1041 if (!m_rowsInserted)
1043 m_rowsInserted =
false;
1044 endInsertRows(parent, start, end);
1046 foreach(
const PendingSelectionChange &pendingChange, m_pendingSelectionChanges)
1048 selectionChanged(pendingChange.selected, pendingChange.deselected);
1050 m_pendingSelectionChanges.clear();
1053 QPair<int, int> KSelectionProxyModelPrivate::beginRemoveRows(
const QModelIndex& parent,
int start,
int end)
const
1059 if (m_omitChildren && !m_startWithChildTrees && !m_includeAllSelected) {
1061 if (m_rootIndexList.contains(parent) ||
isDescendantOf(m_rootIndexList, parent)) {
1062 return qMakePair(-1, -1);
1066 const QModelIndex proxyParent = mapParentFromSource(parent);
1068 if (!m_includeAllSelected && !m_omitChildren) {
1070 if (proxyParent.isValid()) {
1073 if (m_startWithChildTrees && m_rootIndexList.contains(parent)) {
1075 const int proxyStartRow = getProxyInitialRow(parent) + start;
1076 return qMakePair(proxyStartRow, proxyStartRow + (end - start));
1080 if (m_includeAllSelected && m_startWithChildTrees) {
1082 int position = m_rootIndexList.indexOf(parent);
1083 if (position != -1) {
1084 const int proxyStartRow = getProxyInitialRow(parent) + start;
1085 int proxyEndRow = proxyStartRow + (end - start);
1087 while (m_rootIndexList.size() < position) {
1088 const QModelIndex idx = m_rootIndexList.at(position);
1090 proxyEndRow += q->sourceModel()->rowCount(idx);
1094 return qMakePair(proxyStartRow, proxyEndRow);
1096 return qMakePair(-1, -1);
1101 int rootPosition = 0;
1102 int rootStartRemove = -1;
1103 int rootEndRemove = -1;
1104 int siblingCount = 0;
1106 for ( ; rootIt != rootEnd; ++rootIt, ++rootPosition) {
1107 if (m_omitChildren && m_includeAllSelected) {
1109 if (parent == rootIt->parent() && rootIt->row() <= end && rootIt->row() >= start) {
1110 if (rootStartRemove == -1)
1111 rootStartRemove = rootPosition;
1114 if (rootStartRemove != -1)
1119 if (rootStartRemove == -1)
1120 rootStartRemove = rootPosition;
1122 if (m_startWithChildTrees)
1123 siblingCount += q->sourceModel()->rowCount(*rootIt);
1125 if (rootStartRemove != -1)
1130 if (rootStartRemove != -1) {
1131 return qMakePair(siblingCount + rootStartRemove, siblingCount + rootEndRemove);
1134 return qMakePair(-1, -1);
1137 void KSelectionProxyModelPrivate::sourceRowsAboutToBeRemoved(
const QModelIndex &parent,
int start,
int end)
1141 Q_ASSERT(parent.isValid() ? parent.model() == q->sourceModel() :
true);
1143 if (!m_selectionModel.data()->hasSelection())
1147 if (pair.first == -1)
1150 const QModelIndex proxyParent = mapParentFromSource(parent);
1152 m_rowsRemoved =
true;
1153 m_proxyRemoveRows = pair;
1154 q->beginRemoveRows(proxyParent, pair.first, pair.second);
1157 void KSelectionProxyModelPrivate::endRemoveRows(
const QModelIndex &sourceParent,
int proxyStart,
int proxyEnd)
1159 const QModelIndex proxyParent = mapParentFromSource(sourceParent);
1176 SourceProxyIndexMapping::right_iterator it = m_mappedParents.rightBegin();
1178 while (it != m_mappedParents.rightEnd()) {
1179 if (!it.value().isValid()) {
1180 m_parentIds.removeRight(it.key());
1181 it = m_mappedParents.eraseRight(it);
1203 removeFirstChildMappings(proxyStart, proxyEnd);
1206 if (proxyParent.isValid())
1207 updateInternalIndexes(proxyParent, proxyEnd + 1, -1*(proxyEnd - proxyStart + 1));
1209 updateInternalTopIndexes(proxyEnd + 1, -1*(proxyEnd - proxyStart + 1));
1212 while (rootIt != m_rootIndexList.end()) {
1213 if (!rootIt->isValid())
1214 rootIt = m_rootIndexList.erase(rootIt);
1220 void KSelectionProxyModelPrivate::sourceRowsRemoved(
const QModelIndex &parent,
int start,
int end)
1225 Q_ASSERT(parent.isValid() ? parent.model() == q->sourceModel() : true);
1227 if (!m_selectionModel.data()->hasSelection())
1232 m_rowsRemoved = false;
1234 Q_ASSERT(m_proxyRemoveRows.first >= 0);
1235 Q_ASSERT(m_proxyRemoveRows.second >= 0);
1236 endRemoveRows(parent, m_proxyRemoveRows.first, m_proxyRemoveRows.second);
1237 if (m_startWithChildTrees && start == 0 && q->sourceModel()->hasChildren(parent))
1240 createFirstChildMapping(parent, m_proxyRemoveRows.first);
1242 m_proxyRemoveRows = qMakePair(-1, -1);
1246 void KSelectionProxyModelPrivate::sourceRowsAboutToBeMoved(const QModelIndex &srcParent,
int srcStart,
int srcEnd, const QModelIndex &destParent,
int destRow)
1251 Q_UNUSED(destParent)
1255 void KSelectionProxyModelPrivate::sourceRowsMoved(const QModelIndex &srcParent,
int srcStart,
int srcEnd, const QModelIndex &destParent,
int destRow)
1260 Q_UNUSED(destParent)
1264 QModelIndex KSelectionProxyModelPrivate::mapParentToSource(const QModelIndex &proxyParent)
const
1266 return m_mappedParents.rightToLeft(proxyParent);
1269 QModelIndex KSelectionProxyModelPrivate::mapParentFromSource(
const QModelIndex &sourceParent)
const
1271 return m_mappedParents.leftToRight(sourceParent);
1276 if (!startWithChildTrees) {
1277 Q_ASSERT(rootIndexList.size() > row);
1278 Q_UNUSED(rootIndexList);
1281 Q_ASSERT(!mappedFirstChildren.isEmpty());
1283 SourceIndexProxyRowMapping::right_const_iterator result = mappedFirstChildren.rightUpperBound(row) - 1;
1285 Q_ASSERT(result != mappedFirstChildren.rightEnd());
1286 const int proxyFirstRow = result.key();
1287 const QModelIndex sourceFirstChild = result.value();
1288 Q_ASSERT(proxyFirstRow >= 0);
1289 Q_ASSERT(sourceFirstChild.isValid());
1290 Q_ASSERT(sourceFirstChild.parent().isValid());
1291 Q_ASSERT(row <= proxyFirstRow + sourceFirstChild.model()->rowCount(sourceFirstChild.parent()));
1296 QModelIndex KSelectionProxyModelPrivate::createTopLevelIndex(
int row,
int column)
const
1300 Q_ASSERT(
indexIsValid(m_startWithChildTrees, row, m_rootIndexList, m_mappedFirstChildren));
1301 return q->createIndex(row, column);
1305 QModelIndex KSelectionProxyModelPrivate::mapTopLevelFromSource(
const QModelIndex &sourceIndex)
const
1309 const QModelIndex sourceParent = sourceIndex.parent();
1310 const int row = m_rootIndexList.indexOf(sourceIndex);
1312 return QModelIndex();
1314 if (!m_startWithChildTrees) {
1315 Q_ASSERT(m_rootIndexList.size() > row);
1316 return q->createIndex(row, sourceIndex.column());
1318 if (!m_rootIndexList.contains(sourceParent))
1319 return QModelIndex();
1321 const QModelIndex firstChild = q->sourceModel()->index(0, 0, sourceParent);
1322 const int firstProxyRow = m_mappedFirstChildren.leftToRight(firstChild);
1324 return q->createIndex(firstProxyRow + sourceIndex.row(), sourceIndex.column());
1327 QModelIndex KSelectionProxyModelPrivate::mapFromSource(
const QModelIndex &sourceIndex)
const
1331 const QModelIndex maybeMapped = mapParentFromSource(sourceIndex);
1332 if (maybeMapped.isValid()) {
1336 const QModelIndex sourceParent = sourceIndex.parent();
1338 const QModelIndex proxyParent = mapParentFromSource(sourceParent);
1339 if (proxyParent.isValid()) {
1340 void *
const parentId = m_parentIds.rightToLeft(proxyParent);
1341 static const int column = 0;
1342 return q->createIndex(sourceIndex.row(), column, parentId);
1345 const QModelIndex firstChild = q->sourceModel()->index(0, 0, sourceParent);
1347 if (m_mappedFirstChildren.leftContains(firstChild))
1349 const int firstProxyRow = m_mappedFirstChildren.leftToRight(firstChild);
1350 return q->createIndex(firstProxyRow + sourceIndex.row(), sourceIndex.column());
1352 return mapTopLevelFromSource(sourceIndex);
1355 int KSelectionProxyModelPrivate::topLevelRowCount()
const
1359 if (!m_startWithChildTrees)
1360 return m_rootIndexList.size();
1362 if (m_mappedFirstChildren.isEmpty())
1365 const SourceIndexProxyRowMapping::right_const_iterator result = m_mappedFirstChildren.rightConstEnd() - 1;
1367 const int proxyFirstRow = result.key();
1368 const QModelIndex sourceFirstChild = result.value();
1369 Q_ASSERT(sourceFirstChild.isValid());
1370 const QModelIndex sourceParent = sourceFirstChild.parent();
1371 Q_ASSERT(sourceParent.isValid());
1372 return q->sourceModel()->rowCount(sourceParent) + proxyFirstRow;
1375 bool KSelectionProxyModelPrivate::ensureMappable(
const QModelIndex &parent)
const
1382 if (parentIsMappable(parent))
1385 QModelIndex ancestor = parent.parent();
1386 QModelIndexList ancestorList;
1387 while (ancestor.isValid())
1389 if (parentIsMappable(ancestor))
1392 ancestorList.prepend(ancestor);
1394 ancestor = ancestor.parent();
1397 if (!ancestor.isValid())
1402 for(
int i = 0; i < ancestorList.size(); ++i)
1404 const QModelIndex existingAncestor = mapParentFromSource(ancestor);
1405 Q_ASSERT(existingAncestor.isValid());
1407 void *
const ansId = m_parentIds.rightToLeft(existingAncestor);
1408 const QModelIndex newSourceParent = ancestorList.at(i);
1409 const QModelIndex newProxyParent = q->createIndex(newSourceParent.row(), newSourceParent.column(), ansId);
1411 void *
const newId = m_voidPointerFactory.createPointer();
1412 m_parentIds.insert(newId, newProxyParent);
1413 m_mappedParents.insert(QPersistentModelIndex(newSourceParent), newProxyParent);
1414 ancestor = newSourceParent;
1419 void KSelectionProxyModelPrivate::updateInternalTopIndexes(
int start,
int offset)
1421 updateInternalIndexes(QModelIndex(), start, offset);
1425 SourceIndexProxyRowMapping::right_iterator it = m_mappedFirstChildren.rightLowerBound(start);
1426 const SourceIndexProxyRowMapping::right_iterator end = m_mappedFirstChildren.rightEnd();
1428 for ( ; it !=
end; ++it)
1430 updates.insert(*it, it.key() + offset);
1437 for ( ; it !=
end; ++it)
1439 m_mappedFirstChildren.insert(it.key(), it.value());
1444 void KSelectionProxyModelPrivate::updateInternalIndexes(
const QModelIndex &parent,
int start,
int offset)
1448 Q_ASSERT(start + offset >= 0);
1449 Q_ASSERT(parent.isValid() ? parent.model() == q :
true);
1454 SourceProxyIndexMapping::left_iterator mappedParentIt = m_mappedParents.leftBegin();
1459 for ( ; mappedParentIt != m_mappedParents.leftEnd(); ++mappedParentIt) {
1460 const QModelIndex proxyIndex = mappedParentIt.value();
1461 Q_ASSERT(proxyIndex.isValid());
1463 if (proxyIndex.row() < start)
1466 const QModelIndex proxyParent = proxyIndex.parent();
1468 if (parent.isValid()) {
1469 if (proxyParent != parent)
1472 if (proxyParent.isValid())
1475 Q_ASSERT(m_parentIds.rightContains(proxyIndex));
1476 void *
const key = m_parentIds.rightToLeft(proxyIndex);
1478 const QModelIndex newIndex = q->createIndex(proxyIndex.row() + offset, proxyIndex.column(), proxyIndex.internalPointer());
1480 Q_ASSERT(newIndex.isValid());
1482 updatedParentIds.insert(key, newIndex);
1483 updatedParents.insert(mappedParentIt.key(), newIndex);
1489 for ( ; it !=
end; ++it)
1490 m_mappedParents.insert(it.key(), it.value());
1496 for ( ; it !=
end; ++it)
1497 m_parentIds.insert(it.key(), it.value());
1501 bool KSelectionProxyModelPrivate::parentAlreadyMapped(
const QModelIndex &parent)
const
1504 Q_ASSERT(parent.model() == q->sourceModel());
1505 return m_mappedParents.leftContains(parent);
1508 bool KSelectionProxyModelPrivate::firstChildAlreadyMapped(
const QModelIndex &firstChild)
const
1511 Q_ASSERT(firstChild.model() == q->sourceModel());
1512 return m_mappedFirstChildren.leftContains(firstChild);
1515 void KSelectionProxyModelPrivate::createFirstChildMapping(
const QModelIndex& parent,
int proxyRow)
const
1519 Q_ASSERT(parent.isValid() ? parent.model() == q->sourceModel() :
true);
1521 static const int column = 0;
1522 static const int row = 0;
1524 const QPersistentModelIndex srcIndex = q->sourceModel()->index(row, column, parent);
1526 if (firstChildAlreadyMapped(srcIndex))
1529 Q_ASSERT(srcIndex.isValid());
1530 m_mappedFirstChildren.insert(srcIndex, proxyRow);
1533 void KSelectionProxyModelPrivate::createParentMappings(
const QModelIndex &parent,
int start,
int end)
const
1540 Q_ASSERT(parent.isValid() ? parent.model() == q->sourceModel() :
true);
1542 static const int column = 0;
1544 for (
int row = start; row <=
end; ++row) {
1545 const QModelIndex srcIndex = q->sourceModel()->index(row, column, parent);
1546 Q_ASSERT(srcIndex.isValid());
1547 if (!q->sourceModel()->hasChildren(srcIndex) || parentAlreadyMapped(srcIndex))
1550 const QModelIndex proxyIndex = mapFromSource(srcIndex);
1551 if (!proxyIndex.isValid())
1554 void *
const newId = m_voidPointerFactory.createPointer();
1555 m_parentIds.insert(newId, proxyIndex);
1556 Q_ASSERT(srcIndex.isValid());
1557 m_mappedParents.insert(QPersistentModelIndex(srcIndex), proxyIndex);
1561 void KSelectionProxyModelPrivate::removeFirstChildMappings(
int start,
int end)
1563 SourceIndexProxyRowMapping::right_iterator it = m_mappedFirstChildren.rightLowerBound(start);
1564 const SourceIndexProxyRowMapping::right_iterator endIt = m_mappedFirstChildren.rightUpperBound(end);
1566 it = m_mappedFirstChildren.eraseRight(it);
1569 void KSelectionProxyModelPrivate::removeParentMappings(
const QModelIndex &parent,
int start,
int end)
1573 Q_ASSERT(parent.isValid() ? parent.model() == q :
true);
1575 SourceProxyIndexMapping::right_iterator it = m_mappedParents.rightBegin();
1576 SourceProxyIndexMapping::right_iterator endIt = m_mappedParents.rightEnd();
1582 QModelIndexList list;
1584 const bool flatList = isFlat();
1586 while (it != endIt) {
1587 if (it.key().row() >= start && it.key().row() <=
end)
1589 const QModelIndex sourceParent = it.value();
1590 const QModelIndex proxyGrandParent = mapParentFromSource(sourceParent.parent());
1591 if (proxyGrandParent == parent)
1596 removeParentMappings(it.key(), 0, q->sourceModel()->rowCount(it.value()) - 1);
1598 m_parentIds.removeRight(it.key());
1599 it = m_mappedParents.eraseRight(it);
1607 QModelIndex KSelectionProxyModelPrivate::mapTopLevelToSource(
int row,
int column)
const
1609 if (!m_startWithChildTrees)
1611 const QModelIndex idx = m_rootIndexList.at(row);
1612 return idx.sibling(idx.row(), column);
1615 if (m_mappedFirstChildren.isEmpty())
1616 return QModelIndex();
1618 SourceIndexProxyRowMapping::right_iterator result = m_mappedFirstChildren.rightUpperBound(row) - 1;
1620 Q_ASSERT(result != m_mappedFirstChildren.rightEnd());
1622 const int proxyFirstRow = result.key();
1623 const QModelIndex sourceFirstChild = result.value();
1624 Q_ASSERT(sourceFirstChild.isValid());
1625 return sourceFirstChild.sibling(row - proxyFirstRow, column);
1628 void KSelectionProxyModelPrivate::removeSelectionFromProxy(
const QItemSelection &selection)
1631 if (selection.isEmpty())
1634 q->rootSelectionAboutToBeRemoved(selection);
1636 foreach(
const QItemSelectionRange range, selection)
1637 removeRangeFromProxy(range);
1640 void KSelectionProxyModelPrivate::removeRangeFromProxy(
const QItemSelectionRange &range)
1644 Q_ASSERT(range.model() == q->sourceModel());
1646 const QModelIndex sourceTopLeft = range.topLeft();
1647 const QModelIndex proxyTopLeft = mapFromSource(sourceTopLeft);
1648 const QModelIndex sourceBottomLeft = range.bottomRight().sibling(range.bottom(), 0);
1649 const QModelIndex proxyBottomLeft = mapFromSource(sourceBottomLeft);
1650 const QModelIndex proxyParent = proxyTopLeft.parent();
1651 const QModelIndex sourceParent = sourceTopLeft.parent();
1653 if (m_startWithChildTrees) {
1654 Q_ASSERT(sourceTopLeft.isValid());
1655 Q_ASSERT(sourceBottomLeft.isValid());
1656 const int startRootIdx = m_rootIndexList.indexOf(sourceTopLeft);
1657 int endRootIdx = m_rootIndexList.indexOf(sourceBottomLeft);
1658 QItemSelection extraRanges;
1659 if (m_includeAllSelected) {
1662 int idx = startRootIdx;
1663 const int bottomIdx = endRootIdx;
1664 const int rootListSize = m_rootIndexList.size();
1666 while (next <= bottomIdx)
1668 if (next < rootListSize && m_rootIndexList.at(next).parent() == sourceParent) {
1676 while (idx <= bottomIdx)
1678 const QModelIndex index= m_rootIndexList.at(idx);
1679 if (m_rootIndexList.at(idx).parent() == sourceParent)
1680 extraRanges << QItemSelectionRange(index, index);
1684 Q_ASSERT(endRootIdx != -1);
1685 int childrenCount = q->sourceModel()->rowCount(sourceTopLeft);
1686 for (
int rootIdx = startRootIdx + 1; rootIdx <= endRootIdx; ++rootIdx)
1688 childrenCount += q->sourceModel()->rowCount(m_rootIndexList.at(rootIdx));
1690 if (childrenCount == 0)
1692 for (
int rootIdx = startRootIdx; rootIdx <= endRootIdx; --endRootIdx)
1694 const QModelIndex idx = m_rootIndexList.at(rootIdx);
1695 q->rootIndexAboutToBeRemoved(idx);
1696 m_rootIndexList.removeOne(idx);
1700 if (!m_includeAllSelected)
1703 for ( ; endRootIdx < m_rootIndexList.size(); ++endRootIdx) {
1704 const QModelIndex idx = m_rootIndexList.at(endRootIdx);
1706 childrenCount += q->sourceModel()->rowCount(idx);
1712 const int proxyStart = getTargetRow(startRootIdx);
1713 int proxyEnd = proxyStart + childrenCount - 1;
1714 q->beginRemoveRows(QModelIndex(), proxyStart, proxyEnd);
1716 for (
int rootIdx = startRootIdx; rootIdx <= endRootIdx; ++rootIdx)
1718 q->rootIndexAboutToBeRemoved(m_rootIndexList.at(rootIdx));
1721 removeParentMappings(QModelIndex(), proxyStart, proxyEnd);
1722 removeFirstChildMappings(proxyStart, proxyEnd);
1723 int numRemovedChildren = 0;
1724 for (
int rootIdx = startRootIdx; rootIdx <= endRootIdx; --endRootIdx)
1726 const QModelIndex idx = m_rootIndexList.at(rootIdx);
1727 const int childCount = q->sourceModel()->rowCount(idx);
1728 m_rootIndexList.removeAt(rootIdx);
1729 numRemovedChildren += childCount;
1731 updateInternalTopIndexes(proxyEnd + 1, -1 * numRemovedChildren);
1733 if (m_includeAllSelected) {
1737 if (!proxyTopLeft.isValid())
1739 const int height = range.height();
1740 q->beginRemoveRows(proxyParent, proxyTopLeft.row(), proxyTopLeft.row() + height - 1);
1743 for (
int i = 0; i < height; ++i)
1745 const QModelIndex idx = sourceTopLeft.sibling(range.top() + i, sourceTopLeft.column());
1746 q->rootIndexAboutToBeRemoved(idx);
1749 removeParentMappings(proxyParent, proxyTopLeft.row(), proxyTopLeft.row() + height - 1);
1750 updateInternalIndexes(proxyParent, proxyTopLeft.row() + height, -1 * height);
1752 for (
int i = 0; i < height; ++i)
1754 const QModelIndex idx = sourceTopLeft.sibling(range.top() + i, sourceTopLeft.column());
1755 Q_ASSERT(idx.isValid());
1756 const bool b = m_rootIndexList.removeOne(idx);
1767 void KSelectionProxyModelPrivate::selectionChanged(const QItemSelection &_selected, const QItemSelection &_deselected)
1771 if (!q->sourceModel() || (_selected.isEmpty() && _deselected.isEmpty()))
1774 if (m_rowsInserted || m_rowsRemoved) {
1775 m_pendingSelectionChanges.append(PendingSelectionChange(_selected, _deselected));
1792 const QItemSelection selected =
kNormalizeSelection(m_indexMapper->mapSelectionRightToLeft(_selected));
1793 const QItemSelection deselected =
kNormalizeSelection(m_indexMapper->mapSelectionRightToLeft(_deselected));
1795 #if QT_VERSION < 0x040800
1798 QItemSelection reportedSelection = m_selectionModel.data()->selection();
1800 QItemSelection fullSelection = m_indexMapper->mapSelectionRightToLeft(reportedSelection);
1802 QItemSelection fullSelection = m_indexMapper->mapSelectionRightToLeft(m_selectionModel.data()->selection());
1807 QItemSelection newRootRanges;
1808 QItemSelection removedRootRanges;
1809 if (!m_includeAllSelected) {
1812 QItemSelection existingSelection = fullSelection;
1819 const QItemSelection existingRootRanges =
getRootRanges(existingSelection);
1821 QMutableListIterator<QItemSelectionRange> i(newRootRanges);
1822 while (i.hasNext()) {
1823 const QItemSelectionRange range = i.next();
1824 const QModelIndex topLeft = range.topLeft();
1831 QItemSelection exposedSelection;
1833 QItemSelection deselectedRootRanges =
getRootRanges(deselected);
1834 QListIterator<QItemSelectionRange> i(deselectedRootRanges);
1835 while (i.hasNext()) {
1836 const QItemSelectionRange range = i.next();
1837 const QModelIndex topLeft = range.topLeft();
1853 foreach (
const QItemSelectionRange &selectedRange, existingRootRanges) {
1854 const QModelIndex selectedRangeTopLeft = selectedRange.topLeft();
1861 exposedSelection.append(selectedRange);
1863 removedRootRanges << range;
1868 QItemSelection obscuredRanges;
1870 QListIterator<QItemSelectionRange> i(existingRootRanges);
1871 while (i.hasNext()) {
1872 const QItemSelectionRange range = i.next();
1874 obscuredRanges << range;
1883 removedRootRanges = deselected;
1884 newRootRanges = selected;
1887 removeSelectionFromProxy(removedRootRanges);
1889 if (!m_selectionModel.data()->hasSelection())
1891 Q_ASSERT(m_rootIndexList.isEmpty());
1892 Q_ASSERT(m_mappedFirstChildren.isEmpty());
1893 Q_ASSERT(m_mappedParents.isEmpty());
1894 Q_ASSERT(m_parentIds.isEmpty());
1897 insertSelectionIntoProxy(newRootRanges);
1900 int KSelectionProxyModelPrivate::getTargetRow(
int rootListRow)
1903 if (!m_startWithChildTrees)
1907 while (rootListRow >= 0) {
1908 const QModelIndex idx = m_rootIndexList.at(rootListRow);
1909 Q_ASSERT(idx.isValid());
1910 const int rowCount = q->sourceModel()->rowCount(idx);
1912 static const int column = 0;
1913 const QModelIndex srcIdx = q->sourceModel()->index(rowCount - 1, column, idx);
1914 const QModelIndex proxyLastChild = mapFromSource(srcIdx);
1915 return proxyLastChild.row() + 1;
1922 void KSelectionProxyModelPrivate::insertSelectionIntoProxy(
const QItemSelection &selection)
1926 if (selection.isEmpty())
1929 foreach(
const QModelIndex &newIndex, selection.indexes()) {
1930 Q_ASSERT(newIndex.model() == q->sourceModel());
1931 if (newIndex.column() > 0)
1933 if (m_startWithChildTrees) {
1934 const int rootListRow =
getRootListRow(m_rootIndexList, newIndex);
1935 Q_ASSERT(q->sourceModel() == newIndex.model());
1936 const int rowCount = q->sourceModel()->rowCount(newIndex);
1937 const int startRow = getTargetRow(rootListRow);
1939 if (rowCount == 0) {
1942 m_rootIndexList.insert(rootListRow, newIndex);
1943 if (!m_resetting || m_layoutChanging)
1944 emit q->rootIndexAdded(newIndex);
1948 q->beginInsertRows(QModelIndex(), startRow, startRow + rowCount - 1);
1949 Q_ASSERT(newIndex.isValid());
1950 m_rootIndexList.insert(rootListRow, newIndex);
1951 if (!m_resetting || m_layoutChanging)
1952 emit q->rootIndexAdded(newIndex);
1955 for (
int i = 0; i < rootListRow; ++i)
1956 _start += q->sourceModel()->rowCount(m_rootIndexList.at(i));
1958 updateInternalTopIndexes(_start, rowCount);
1959 createFirstChildMapping(newIndex, _start);
1960 createParentMappings(newIndex, 0, rowCount - 1);
1969 q->beginInsertRows(QModelIndex(), row, row);
1971 Q_ASSERT(newIndex.isValid());
1972 m_rootIndexList.insert(row, newIndex);
1974 if (!m_resetting || m_layoutChanging)
1975 emit q->rootIndexAdded(newIndex);
1976 Q_ASSERT(m_rootIndexList.size() > row);
1977 updateInternalIndexes(QModelIndex(), row, 1);
1978 createParentMappings(newIndex.parent(), newIndex.row(), newIndex.row());
1985 q->rootSelectionAdded(selection);
1989 :
QAbstractProxyModel(parent), d_ptr(new KSelectionProxyModelPrivate(this, selectionModel))
2004 d->m_filterBehavior = behavior;
2008 d->m_omitChildren =
false;
2009 d->m_omitDescendants =
false;
2010 d->m_startWithChildTrees =
false;
2011 d->m_includeAllSelected =
false;
2015 d->m_omitChildren =
true;
2016 d->m_startWithChildTrees =
false;
2017 d->m_includeAllSelected =
false;
2021 d->m_omitChildren =
false;
2022 d->m_omitDescendants =
false;
2023 d->m_startWithChildTrees =
true;
2024 d->m_includeAllSelected =
false;
2028 d->m_omitChildren =
true;
2029 d->m_startWithChildTrees =
false;
2030 d->m_includeAllSelected =
true;
2034 d->m_omitChildren =
false;
2035 d->m_omitDescendants =
true;
2036 d->m_startWithChildTrees =
true;
2037 d->m_includeAllSelected =
true;
2041 d->resetInternalData();
2042 d->selectionChanged(d->m_selectionModel.data()->selection(), QItemSelection());
2050 return d->m_filterBehavior;
2057 Q_ASSERT(_sourceModel !=
this);
2059 if (_sourceModel == sourceModel())
2062 disconnect(d->m_selectionModel.data()->model(), SIGNAL(modelAboutToBeReset()),
this, SLOT(sourceModelAboutToBeReset()));
2063 connect(d->m_selectionModel.data()->model(), SIGNAL(modelAboutToBeReset()),
this, SLOT(sourceModelAboutToBeReset()));
2064 disconnect(d->m_selectionModel.data()->model(), SIGNAL(modelReset()),
this, SLOT(sourceModelReset()));
2065 connect(d->m_selectionModel.data()->model(), SIGNAL(modelReset()),
this, SLOT(sourceModelReset()));
2067 disconnect(d->m_selectionModel.data(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
2068 this, SLOT(selectionChanged(QItemSelection,QItemSelection)));
2069 connect(d->m_selectionModel.data(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
2070 SLOT(selectionChanged(QItemSelection,QItemSelection)));
2073 d->m_resetting =
true;
2076 disconnect(_sourceModel, SIGNAL(rowsAboutToBeInserted(QModelIndex,
int,
int)),
2077 this, SLOT(sourceRowsAboutToBeInserted(QModelIndex,
int,
int)));
2078 disconnect(_sourceModel, SIGNAL(rowsInserted(QModelIndex,
int,
int)),
2079 this, SLOT(sourceRowsInserted(QModelIndex,
int,
int)));
2080 disconnect(_sourceModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,
int,
int)),
2081 this, SLOT(sourceRowsAboutToBeRemoved(QModelIndex,
int,
int)));
2082 disconnect(_sourceModel, SIGNAL(rowsRemoved(QModelIndex,
int,
int)),
2083 this, SLOT(sourceRowsRemoved(QModelIndex,
int,
int)));
2088 disconnect(_sourceModel, SIGNAL(modelAboutToBeReset()),
2089 this, SLOT(sourceModelAboutToBeReset()));
2090 disconnect(_sourceModel, SIGNAL(modelReset()),
2091 this, SLOT(sourceModelReset()));
2092 disconnect(_sourceModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
2093 this, SLOT(sourceDataChanged(QModelIndex,QModelIndex)));
2094 disconnect(_sourceModel, SIGNAL(layoutAboutToBeChanged()),
2095 this, SLOT(sourceLayoutAboutToBeChanged()));
2096 disconnect(_sourceModel, SIGNAL(layoutChanged()),
2097 this, SLOT(sourceLayoutChanged()));
2098 disconnect(_sourceModel, SIGNAL(destroyed()),
2099 this, SLOT(sourceModelDestroyed()));
2103 d->resetInternalData();
2104 QAbstractProxyModel::setSourceModel(_sourceModel);
2107 if (d->m_selectionModel.data()->hasSelection())
2108 d->selectionChanged(d->m_selectionModel.data()->selection(), QItemSelection());
2110 connect(_sourceModel, SIGNAL(rowsAboutToBeInserted(QModelIndex,
int,
int)),
2111 SLOT(sourceRowsAboutToBeInserted(QModelIndex,
int,
int)));
2112 connect(_sourceModel, SIGNAL(rowsInserted(QModelIndex,
int,
int)),
2113 SLOT(sourceRowsInserted(QModelIndex,
int,
int)));
2114 connect(_sourceModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,
int,
int)),
2115 SLOT(sourceRowsAboutToBeRemoved(QModelIndex,
int,
int)));
2116 connect(_sourceModel, SIGNAL(rowsRemoved(QModelIndex,
int,
int)),
2117 SLOT(sourceRowsRemoved(QModelIndex,
int,
int)));
2122 connect(_sourceModel, SIGNAL(modelAboutToBeReset()),
2123 SLOT(sourceModelAboutToBeReset()));
2124 connect(_sourceModel, SIGNAL(modelReset()),
2125 SLOT(sourceModelReset()));
2126 connect(_sourceModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
2127 SLOT(sourceDataChanged(QModelIndex,QModelIndex)));
2128 connect(_sourceModel, SIGNAL(layoutAboutToBeChanged()),
2129 SLOT(sourceLayoutAboutToBeChanged()));
2130 connect(_sourceModel, SIGNAL(layoutChanged()),
2131 SLOT(sourceLayoutChanged()));
2132 connect(_sourceModel, SIGNAL(destroyed()),
2133 SLOT(sourceModelDestroyed()));
2136 d->m_resetting =
false;
2144 if (!proxyIndex.isValid() || !sourceModel() || d->m_rootIndexList.isEmpty())
2145 return QModelIndex();
2147 Q_ASSERT(proxyIndex.internalPointer() >= 0);
2148 Q_ASSERT(proxyIndex.model() ==
this);
2150 if (proxyIndex.internalPointer() == 0)
2151 return d->mapTopLevelToSource(proxyIndex.row(), proxyIndex.column());
2153 const QModelIndex proxyParent = d->parentForId(proxyIndex.internalPointer());
2154 Q_ASSERT(proxyParent.isValid());
2155 const QModelIndex sourceParent = d->mapParentToSource(proxyParent);
2156 Q_ASSERT(sourceParent.isValid());
2157 return sourceModel()->index(proxyIndex.row(), proxyIndex.column(), sourceParent);
2164 if (!sourceModel() || !sourceIndex.isValid() || d->m_rootIndexList.isEmpty())
2165 return QModelIndex();
2167 Q_ASSERT(sourceIndex.model() == sourceModel());
2169 if (!sourceIndex.isValid())
2170 return QModelIndex();
2172 if (!d->ensureMappable(sourceIndex))
2173 return QModelIndex();
2175 return d->mapFromSource(sourceIndex);
2182 if (!sourceModel() || index.column() > 0 || d->m_rootIndexList.isEmpty())
2185 Q_ASSERT(index.isValid() ? index.model() ==
this :
true);
2186 if (!index.isValid())
2187 return d->topLevelRowCount();
2193 QModelIndex sourceParent = d->mapParentToSource(index);
2195 if (!sourceParent.isValid() && sourceModel()->hasChildren(sourceParent)) {
2197 d->createParentMappings(sourceParent, 0, sourceModel()->
rowCount(sourceParent) - 1);
2198 sourceParent = d->mapParentToSource(index);
2201 if (!sourceParent.isValid())
2204 return sourceModel()->rowCount(sourceParent);
2211 if (!sourceModel() || d->m_rootIndexList.isEmpty() || !hasIndex(row, column, parent))
2212 return QModelIndex();
2214 Q_ASSERT(parent.isValid() ? parent.model() ==
this :
true);
2216 if (!parent.isValid())
2217 return d->createTopLevelIndex(row, column);
2219 void *
const parentId = d->parentId(parent);
2221 return createIndex(row, column, parentId);
2228 if (!sourceModel() || !index.isValid() || d->m_rootIndexList.isEmpty())
2229 return QModelIndex();
2231 Q_ASSERT(index.model() ==
this);
2233 return d->parentForId(index.internalPointer());
2238 if (!index.isValid() || !sourceModel())
2239 return QAbstractProxyModel::flags(index);
2241 Q_ASSERT(index.model() ==
this);
2244 Q_ASSERT(srcIndex.isValid());
2245 return sourceModel()->flags(srcIndex);
2253 if (index.isValid()) {
2254 Q_ASSERT(index.model() ==
this);
2256 return idx.data(role);
2258 return sourceModel()->data(index, role);
2265 return sourceModel()->headerData(section, orientation, role);
2271 return QAbstractProxyModel::mimeData(indexes);
2272 QModelIndexList sourceIndexes;
2273 foreach(
const QModelIndex& index, indexes)
2275 return sourceModel()->mimeData(sourceIndexes);
2281 return QAbstractProxyModel::mimeTypes();
2282 return sourceModel()->mimeTypes();
2288 return QAbstractProxyModel::supportedDropActions();
2289 return sourceModel()->supportedDropActions();
2296 if (d->m_rootIndexList.isEmpty() || !sourceModel())
2299 if (parent.isValid()) {
2300 Q_ASSERT(parent.model() ==
this);
2303 return sourceModel()->hasChildren(
mapToSource(parent));
2306 if (!d->m_startWithChildTrees)
2309 return !d->m_mappedFirstChildren.isEmpty();
2316 if (!sourceModel() || index.column() > 0
2320 #if QT_VERSION >= 0x040700
2321 || d->m_rootIndexList.isEmpty()
2326 return sourceModel()->columnCount(
mapToSource(index));
2332 return d->m_selectionModel.data();
2338 if (!sourceModel() || d->m_rootIndexList.isEmpty())
2341 if ((row == -1) && (column == -1))
2342 return sourceModel()->dropMimeData(data, action, -1, -1,
mapToSource(parent));
2344 int source_destination_row = -1;
2345 int source_destination_column = -1;
2346 QModelIndex source_parent;
2350 source_destination_row = sourceModel()->rowCount(source_parent);
2352 const QModelIndex proxy_index =
index(row, column, parent);
2353 const QModelIndex source_index =
mapToSource(proxy_index);
2354 source_destination_row = source_index.row();
2355 source_destination_column = source_index.column();
2356 source_parent = source_index.parent();
2358 return sourceModel()->dropMimeData(data, action, source_destination_row,
2359 source_destination_column, source_parent);
2365 return d->m_rootIndexList;
2370 if (role < Qt::UserRole)
2371 return QAbstractProxyModel::match(start, role, value, hits, flags);
2373 QModelIndexList list;
2374 QModelIndex proxyIndex;
2375 foreach(
const QModelIndex &idx, sourceModel()->
match(
mapToSource(start), role, value, hits, flags)) {
2377 if (proxyIndex.isValid())
2386 if (!d->m_startWithChildTrees && d->m_includeAllSelected) {
2389 QItemSelection proxySelection;
2390 foreach(
const QItemSelectionRange &range, selection)
2393 if (!proxyTopLeft.isValid())
2395 QModelIndex proxyBottomRight =
mapFromSource(range.bottomRight());
2396 Q_ASSERT(proxyBottomRight.isValid());
2397 proxySelection.append(QItemSelectionRange(proxyTopLeft, proxyBottomRight));
2399 return proxySelection;
2402 QItemSelection proxySelection;
2403 QItemSelection::const_iterator it = selection.constBegin();
2404 const QItemSelection::const_iterator end = selection.constEnd();
2405 for ( ; it !=
end; ++it) {
2406 const QModelIndex proxyTopLeft =
mapFromSource(it->topLeft());
2407 if (!proxyTopLeft.isValid())
2410 if (it->height() == 1 && it->width() == 1)
2411 proxySelection.append(QItemSelectionRange(proxyTopLeft, proxyTopLeft));
2413 proxySelection.append(QItemSelectionRange(proxyTopLeft, d->mapFromSource(it->bottomRight())));
2415 return proxySelection;
2422 if (selection.isEmpty())
2425 if (!d->m_startWithChildTrees && d->m_includeAllSelected) {
2428 QItemSelection sourceSelection;
2429 foreach(
const QItemSelectionRange &range, selection)
2431 QModelIndex sourceTopLeft =
mapToSource(range.topLeft());
2432 Q_ASSERT(sourceTopLeft.isValid());
2434 QModelIndex sourceBottomRight =
mapToSource(range.bottomRight());
2435 Q_ASSERT(sourceBottomRight.isValid());
2436 sourceSelection.append(QItemSelectionRange(sourceTopLeft, sourceBottomRight));
2438 return sourceSelection;
2442 QItemSelection sourceSelection;
2443 QItemSelection extraSelection;
2444 QItemSelection::const_iterator it = selection.constBegin();
2445 const QItemSelection::const_iterator end = selection.constEnd();
2446 for ( ; it !=
end; ++it) {
2447 const QModelIndex sourceTopLeft =
mapToSource(it->topLeft());
2448 if (it->height() == 1 && it->width() == 1) {
2449 sourceSelection.append(QItemSelectionRange(sourceTopLeft, sourceTopLeft));
2450 }
else if (it->parent().isValid()) {
2451 sourceSelection.append(QItemSelectionRange(sourceTopLeft,
mapToSource(it->bottomRight())));
2455 if (d->m_startWithChildTrees) {
2456 const QModelIndex sourceParent =
mapFromSource(sourceTopLeft);
2457 Q_ASSERT(sourceParent.isValid());
2458 const int rowCount = sourceModel()->rowCount(sourceParent);
2459 if (rowCount < it->bottom()) {
2460 Q_ASSERT(sourceTopLeft.isValid());
2461 Q_ASSERT(it->bottomRight().isValid());
2462 const QModelIndex sourceBottomRight =
mapToSource(it->bottomRight());
2463 Q_ASSERT(sourceBottomRight.isValid());
2464 sourceSelection.append(QItemSelectionRange(sourceTopLeft, sourceBottomRight));
2468 const QModelIndex sourceBottomRight = sourceModel()->index(rowCount - 1, it->right(), sourceParent);
2469 Q_ASSERT(sourceTopLeft.isValid());
2470 Q_ASSERT(sourceBottomRight.isValid());
2471 sourceSelection.append(QItemSelectionRange(sourceTopLeft, sourceBottomRight));
2473 extraSelection.append(QItemSelectionRange(createIndex(it->top() -
rowCount, it->right()), it->bottomRight()));
2475 QItemSelection topSelection;
2476 const QModelIndex idx = createIndex(it->top(), it->right());
2478 Q_ASSERT(sourceIdx.isValid());
2479 topSelection.append(QItemSelectionRange(sourceTopLeft, sourceIdx));
2480 for (
int i = it->top() + 1; i < it->bottom(); ++it) {
2481 const QModelIndex left =
mapToSource(createIndex(i, 0));
2482 const QModelIndex right =
mapToSource(createIndex(i, it->right()));
2483 Q_ASSERT(left.isValid());
2484 Q_ASSERT(right.isValid());
2485 topSelection.append(QItemSelectionRange(left, right));
2492 return sourceSelection;
2495 #include "moc_kselectionproxymodel.cpp"
virtual QStringList mimeTypes() const
QList< QPersistentModelIndex > sourceRootIndexes() const
static QItemSelection getRootRanges(const QItemSelection &_selection)
Returns a selection in which no descendants of selected indexes are also themselves selected...
static bool indexIsValid(bool startWithChildTrees, int row, const QList< QPersistentModelIndex > &rootIndexList, const SourceIndexProxyRowMapping &mappedFirstChildren)
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const
QItemSelection kNormalizeSelection(QItemSelection selection)
virtual Qt::DropActions supportedDropActions() const
virtual void setSourceModel(QAbstractItemModel *sourceModel)
reimp.
bool isDescendantOf(const QList< ModelIndex > &list, const QModelIndex &idx)
Return true if idx is a descendant of one of the indexes in list.
virtual QMimeData * mimeData(const QModelIndexList &indexes) const
virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
KBiHash< void *, QModelIndex > ParentMapping
virtual QModelIndexList match(const QModelIndex &start, int role, const QVariant &value, int hits=1, Qt::MatchFlags flags=Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap)) const
virtual bool hasChildren(const QModelIndex &parent=QModelIndex()) const
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
static int getRootListRow(const QList< ModelIndex > &list, const QModelIndex &index)
Determines the correct location to insert index into list.
QItemSelection mapSelectionToSource(const QItemSelection &selection) const
KAction * next(const QObject *recvr, const char *slot, QObject *parent)
Scroll down one page.
virtual Qt::ItemFlags flags(const QModelIndex &index) const
static int _getRootListRow(const QList< QModelIndexList > &rootAncestors, const QModelIndex &index)
QItemSelection mapSelectionFromSource(const QItemSelection &selection) const
virtual QModelIndex index(int, int, const QModelIndex &=QModelIndex()) const
QModelIndex mapToSource(const QModelIndex &proxyIndex) const
KSelectionProxyModel(QItemSelectionModel *selectionModel, QObject *parent=0)
ctor.
KBiHash< QPersistentModelIndex, QModelIndex > SourceProxyIndexMapping
This class facilitates easy mapping of indexes and selections through proxy models.
void setFilterBehavior(FilterBehavior behavior)
Set the filter behaviors of this model.
virtual QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const
virtual int columnCount(const QModelIndex &=QModelIndex()) const
A Proxy Model which presents a subset of its source model to observers.
virtual ~KSelectionProxyModel()
dtor
KHash2Map< QPersistentModelIndex, int > SourceIndexProxyRowMapping
virtual QModelIndex parent(const QModelIndex &) const
static QItemSelection stableNormalizeSelection(const QItemSelection &selection)
const KShortcut & end()
Goto end of the document.
QItemSelectionModel * selectionModel() const
FilterBehavior filterBehavior() const