From 08c2f7f5fbc55939626842e5764df856c8972d66 Mon Sep 17 00:00:00 2001 From: Frank Reininghaus Date: Thu, 25 Jul 2013 22:15:19 +0200 Subject: [PATCH] Prevent that removing items can cause icons to overlap When items are removed, new items may become visible because of that. This includes (a) Items *behind* the removed range. KItemListView may try to create their widgets at their "imaginary" old positions and move them to the new position with an animation. (b) Items *before* the removed range, if the deletion causes the view to scroll up. In that case, the "imaginary" old position and the new position was equal, but KItemListView still tried to determine the "old" position by adding the number of removed items to the index. The result was that the widgets were created at completely wrong positions, and no animation was started to fix this. Thanks to Emmanuel for helping to find the cause of this bug! BUG: 302373 FIXED-IN: 4.11.0 REVIEW: 111630 --- src/kitemviews/kitemlistview.cpp | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index d2b3fa103b..0c3183cd57 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -1635,18 +1635,22 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha widget->resize(itemBounds.size()); if (animate && changedCount < 0) { - // Items have been deleted, move the created item to the - // imaginary old position. They will get animated to the new position - // later. - const QRectF itemRect = m_layouter->itemRect(i - changedCount); - if (itemRect.isEmpty()) { - const QPointF invisibleOldPos = (scrollOrientation() == Qt::Vertical) - ? QPointF(0, size().height()) : QPointF(size().width(), 0); - widget->setPos(invisibleOldPos); - } else { - widget->setPos(itemRect.topLeft()); + // Items have been deleted. + if (i >= changedIndex) { + // The item is located behind the removed range. Move the + // created item to the imaginary old position outside the + // view. It will get animated to the new position later. + const int previousIndex = i - changedCount; + const QRectF itemRect = m_layouter->itemRect(previousIndex); + if (itemRect.isEmpty()) { + const QPointF invisibleOldPos = (scrollOrientation() == Qt::Vertical) + ? QPointF(0, size().height()) : QPointF(size().width(), 0); + widget->setPos(invisibleOldPos); + } else { + widget->setPos(itemRect.topLeft()); + } + applyNewPos = false; } - applyNewPos = false; } if (supportsExpanding && changedCount == 0) { @@ -1665,7 +1669,7 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha const bool itemsRemoved = (changedCount < 0); const bool itemsInserted = (changedCount > 0); - if (itemsRemoved && (i >= changedIndex + changedCount + 1)) { + if (itemsRemoved && (i >= changedIndex)) { // The item is located after the removed items. Animate the moving of the position. applyNewPos = !moveWidget(widget, newPos); } else if (itemsInserted && i >= changedIndex) {