[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdepim/libkdepim
From:       Stephen Kelly <steveire () gmail ! com>
Date:       2010-12-03 1:40:32
Message-ID: 20101203014032.3989DAC8A4 () svn ! kde ! org
[Download RAW message or body]

SVN commit 1203002 by skelly:

Handle the special case(s) of removing from the end.

CCBUG: 251365

 M  +109 -4    kdescendantsproxymodel.cpp  


--- trunk/KDE/kdepim/libkdepim/kdescendantsproxymodel.cpp #1203001:1203002
@@ -709,6 +709,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);
@@ -739,16 +753,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_const_iterator lowerBound = m_mapping.rightLowerBound(proxyStart);
+  if (lowerBound == m_mapping.rightConstEnd()) {
+    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.rightConstBegin()) {
+    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_const_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)


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic