[Marble-commits] KDE/kdeedu/marble/src/lib
Dennis Nienhüser
earthwings at gentoo.org
Mon Jan 17 21:38:22 CET 2011
SVN commit 1215150 by nienhueser:
Sync with trunk/KDE/kdelibs/kdeui/itemviews/kdescendantsproxymodel.cpp rev. 1214937. Contains a small fix by me, to be overwritten later when it's in kdelibs.
M +115 -5 kdescendantsproxymodel.cpp
--- trunk/KDE/kdeedu/marble/src/lib/kdescendantsproxymodel.cpp #1215149:1215150
@@ -422,7 +422,6 @@
if (d->m_mapping.isEmpty())
return QModelIndex();
-
{
// TODO: Consider a parent Mapping to speed this up.
@@ -706,6 +705,20 @@
q->beginRemoveRows(QModelIndex(), proxyStart, proxyEnd);
}
+static QModelIndex getFirstDeepest(QAbstractItemModel *model, const QModelIndex &parent, int *count) {
+ static const int column = 0;
+ Q_ASSERT(model->hasChildren(parent));
+ Q_ASSERT(model->rowCount(parent) > 0);
+ for (int row = 0; row < model->rowCount(parent); ++row) {
+ (*count)++;
+ const QModelIndex child = model->index(row, column, parent);
+ Q_ASSERT(child.isValid());
+ if (model->hasChildren(child))
+ return getFirstDeepest(model, child, count);
+ }
+ return model->index(model->rowCount(parent) - 1, column, parent);
+}
+
void KDescendantsProxyModelPrivate::sourceRowsRemoved(const QModelIndex &parent, int start, int end)
{
Q_Q(KDescendantsProxyModel);
@@ -736,16 +749,107 @@
updateInternalIndexes(proxyStart, -1 * difference);
- if (rowCount == start && rowCount != 0)
- {
+ if (rowCount != start || rowCount == 0) {
+ q->endRemoveRows();
+ return;
+ }
+
static const int column = 0;
- const QModelIndex newIndex = q->sourceModel()->index(rowCount - 1, column, parent);
- m_mapping.insert(newIndex, proxyStart - 1);
+ const QModelIndex newEnd = q->sourceModel()->index(rowCount - 1, column, parent);
+ Q_ASSERT(newEnd.isValid());
+
+ if (m_mapping.isEmpty()) {
+ m_mapping.insert(newEnd, newEnd.row());
+ q->endRemoveRows();
+ return;
}
+ if (q->sourceModel()->hasChildren(newEnd)) {
+ int count = 0;
+ const QModelIndex firstDeepest = getFirstDeepest(q->sourceModel(), newEnd, &count);
+ Q_ASSERT(firstDeepest.isValid());
+ const int firstDeepestProxy = m_mapping.leftToRight(firstDeepest);
+ m_mapping.insert(newEnd, firstDeepestProxy - count);
q->endRemoveRows();
+ return;
}
+ Mapping::right_iterator lowerBound = m_mapping.rightLowerBound(proxyStart);
+ if (lowerBound == m_mapping.rightEnd()) {
+ int proxyRow = (lowerBound - 1).key();
+ for (int row = newEnd.row(); row >= 0; --row ) {
+ const QModelIndex newEndSibling = q->sourceModel()->index(row, column, parent);
+ if (!q->sourceModel()->hasChildren(newEndSibling)) {
+ ++proxyRow;
+ } else {
+ break;
+ }
+ }
+ m_mapping.insert(newEnd, proxyRow);
+ q->endRemoveRows();
+ return;
+ } else if (lowerBound == m_mapping.rightBegin()) {
+ int proxyRow = rowCount - 1;
+ QModelIndex trackedParent = parent;
+ while (trackedParent.isValid()) {
+ proxyRow += (trackedParent.row() + 1);
+ trackedParent = trackedParent.parent();
+ }
+ m_mapping.insert(newEnd, proxyRow);
+ q->endRemoveRows();
+ return;
+ }
+ const Mapping::right_iterator boundAbove = lowerBound - 1;
+
+ QVector<QModelIndex> targetParents;
+ targetParents.push_back(parent);
+ {
+ QModelIndex target = parent;
+ int count = 0;
+ while (target.isValid()) {
+ if (target == boundAbove.value()) {
+ m_mapping.insert(newEnd, count + boundAbove.key() + newEnd.row() + 1);
+ q->endRemoveRows();
+ return;
+ }
+ count += (target.row() + 1);
+ target = target.parent();
+ if (target.isValid())
+ targetParents.push_back(target);
+ }
+ }
+
+ QModelIndex boundParent = boundAbove.value().parent();
+ QModelIndex prevParent = boundParent;
+ Q_ASSERT(boundParent.isValid());
+ while (boundParent.isValid()) {
+ prevParent = boundParent;
+ boundParent = boundParent.parent();
+
+ if (targetParents.contains(prevParent))
+ break;
+
+ if (!m_mapping.leftContains(prevParent))
+ break;
+
+ if (m_mapping.leftToRight(prevParent) > boundAbove.key())
+ break;
+ }
+
+ QModelIndex trackedParent = parent;
+
+ int proxyRow = boundAbove.key();
+
+ Q_ASSERT(prevParent.isValid());
+ proxyRow -= prevParent.row();
+ while (trackedParent != boundParent) {
+ proxyRow += (trackedParent.row() + 1);
+ trackedParent = trackedParent.parent();
+ }
+ m_mapping.insert(newEnd, proxyRow + newEnd.row());
+ q->endRemoveRows();
+}
+
void KDescendantsProxyModelPrivate::sourceRowsAboutToBeMoved(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destStart)
{
Q_UNUSED(srcParent)
@@ -847,6 +951,12 @@
const int topRow = topLeft.row();
const int bottomRow = bottomRight.row();
+ if (m_mapping.isEmpty() && q->sourceModel()->hasChildren())
+ {
+ Q_ASSERT(q->sourceModel()->rowCount() > 0);
+ synchronousMappingRefresh();
+ }
+
for(int i = topRow; i <= bottomRow; ++i)
{
const QModelIndex sourceTopLeft = q->sourceModel()->index(i, topLeft.column(), topLeft.parent());
More information about the Marble-commits
mailing list