void FlatProxyModel::insertSubTree(const QModelIndex &source_idx, bool emitInsert) { SourceItem *newSubTree = new SourceItem(source_idx.row(), sourceToInternal(sourceModel()->parent(source_idx))); if (newSubTree->parent()) { newSubTree->setPos(newSubTree->parent()->pos() + source_idx.row() + 1); } SourceItem *lastItem = insertSubTreeHelper(newSubTree, newSubTree, source_idx); Q_ASSERT(lastItem); Q_ASSERT(lastItem->next() == 0); if (emitInsert) beginInsertRows(QModelIndex(), newSubTree->pos(), lastItem->pos()); if (newSubTree->parent()) { if (newSubTree->parent()->childCount() > source_idx.row()) { SourceItem *next = newSubTree->parent()->child(source_idx.row()); lastItem->setNext(next); int nextPos = lastItem->pos() + 1; while (next) { next->setPos(nextPos); next = next->next(); nextPos++; } } if (source_idx.row() > 0) { SourceItem *previous = newSubTree->parent()->child(source_idx.row() - 1); while (previous->childCount() > 0) { previous = previous->child(previous->childCount() - 1); } previous->setNext(newSubTree); } else { newSubTree->parent()->setNext(newSubTree); } } else { _rootSourceItem = newSubTree; } if (emitInsert) endInsertRows(); }
void FlatProxyModel::removeSubTree(const QModelIndex &source_idx, bool emitRemove) { SourceItem *sourceItem = sourceToInternal(source_idx); if (!sourceItem) return; SourceItem *prevItem = sourceItem->parent(); if (sourceItem->sourceRow() > 0) { prevItem = prevItem->child(sourceItem->sourceRow() - 1); while (prevItem->childCount() > 0) { prevItem = prevItem->child(prevItem->childCount() - 1); } } SourceItem *lastItem = sourceItem; while (lastItem->childCount() > 0) { lastItem = lastItem->child(lastItem->childCount() - 1); } if (emitRemove) beginRemoveRows(QModelIndex(), sourceItem->pos(), lastItem->pos()); int nextPos = 0; if (prevItem) { prevItem->setNext(lastItem->next()); nextPos = prevItem->pos() + 1; } SourceItem *nextItem = lastItem->next(); while (nextItem) { nextItem->setPos(nextPos); nextPos++; nextItem = nextItem->next(); } sourceItem->parent()->removeChild(sourceItem); delete sourceItem; if (emitRemove) endRemoveRows(); }
QItemSelection FlatProxyModel::mapSelectionToSource(const QItemSelection &proxySelection) const { QItemSelection sourceSelection; for (int i = 0; i < proxySelection.count(); i++) { const QItemSelectionRange &range = proxySelection[i]; SourceItem *topLeftItem = 0; SourceItem *bottomRightItem = 0; SourceItem *currentItem = static_cast<SourceItem *>(range.topLeft().internalPointer()); int row = range.topLeft().row(); int left = range.topLeft().column(); int right = range.bottomRight().column(); while (currentItem && row <= range.bottomRight().row()) { Q_ASSERT(currentItem->pos() == row); if (!topLeftItem) topLeftItem = currentItem; if (currentItem->parent() == topLeftItem->parent()) { bottomRightItem = currentItem; } else { Q_ASSERT(topLeftItem && bottomRightItem); sourceSelection << QItemSelectionRange(mapToSource(createIndex(topLeftItem->pos(), left, topLeftItem)), mapToSource(createIndex(bottomRightItem->pos(), right, bottomRightItem))); topLeftItem = 0; bottomRightItem = 0; } // update loop vars currentItem = currentItem->next(); row++; } if (topLeftItem && bottomRightItem) { // there should be one range left. sourceSelection << QItemSelectionRange(mapToSource(createIndex(topLeftItem->pos(), left, topLeftItem)), mapToSource(createIndex(bottomRightItem->pos(), right, bottomRightItem))); } } return sourceSelection; }