From 84d75fa44432462fd3495f379c275d0b64c428f1 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Sat, 28 Jun 2008 03:03:56 +0000 Subject: [PATCH] Rewrote SwapItems() so as to not fail in various cases. Fixed logic error in CountItemsUnder() that would sometimes return the wrong count. This would result in issues such as Vision's network reordering failing to reorder down due to retrieving the wrong item based on the count. This fixes ticket #2447. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26149 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/interface/OutlineListView.h | 4 +- src/kits/interface/OutlineListView.cpp | 76 ++++++++++++++------------ 2 files changed, 43 insertions(+), 37 deletions(-) diff --git a/headers/os/interface/OutlineListView.h b/headers/os/interface/OutlineListView.h index 2032caa1be..ccc4a64ff8 100644 --- a/headers/os/interface/OutlineListView.h +++ b/headers/os/interface/OutlineListView.h @@ -118,9 +118,7 @@ class BOutlineListView : public BListView { BListItem* _RemoveItem(BListItem* item, int32 fullListIndex); bool _SwapItems(int32 first, int32 second); - void _DoSwap(BList &list, int32 firstIndex, int32 secondIndex, - int32 firstCount, int32 secondCount, int32 swapCount); - int32 _GetSubitemCount(BList &list, int32 itemIndex); + void _CullInvisibleItems(BList &list); BListItem* RemoveOne(int32 fullListIndex); static void TrackInLatchItem(void *); diff --git a/src/kits/interface/OutlineListView.cpp b/src/kits/interface/OutlineListView.cpp index 8a6f1b53e5..2fc659c8e6 100644 --- a/src/kits/interface/OutlineListView.cpp +++ b/src/kits/interface/OutlineListView.cpp @@ -688,7 +688,7 @@ int32 BOutlineListView::CountItemsUnder(BListItem* underItem, bool oneLevelOnly) const { - int32 i = IndexOf(underItem); + int32 i = FullListIndexOf(underItem) + 1; if (i == -1) return 0; @@ -698,7 +698,7 @@ BOutlineListView::CountItemsUnder(BListItem* underItem, BListItem *item = FullListItemAt(i); // If we jump out of the subtree, return count - if (item->fLevel < underItem->OutlineLevel()) + if (item->fLevel <= underItem->OutlineLevel()) return count; // If the level matches, increase count @@ -770,29 +770,42 @@ BOutlineListView::ItemUnderAt(BListItem* underItem, return NULL; } -int32 -BOutlineListView::_GetSubitemCount(BList &list, int32 itemIndex) +static void _GetSubItems(BList &sourceList, BList &destList, + BListItem *parent, int32 start) { - uint32 level = ((BListItem *)list.ItemAt(itemIndex))->OutlineLevel(); - int32 count = 1; // the count we return includes the parent - for (int32 i = itemIndex + 1; i < fFullList.CountItems(); i++, count++) { - if (((BListItem *)list.ItemAt(i))->OutlineLevel() <= level) + for (int32 i = start; i < sourceList.CountItems(); i++) { + BListItem *item = (BListItem *)sourceList.ItemAt(i); + if (item->OutlineLevel() <= parent->OutlineLevel()) break; + destList.AddItem(item); } +} - return count; +static void +_DoSwap(BList &list, int32 firstIndex, int32 secondIndex, BList *firstItems, + BList *secondItems) +{ + BListItem *item = (BListItem *)list.ItemAt(firstIndex); + list.SwapItems(firstIndex, secondIndex); + list.RemoveItems(secondIndex + 1, secondItems->CountItems()); + list.RemoveItems(firstIndex + 1, firstItems->CountItems()); + list.AddList(secondItems, firstIndex + 1); + int32 newIndex = list.IndexOf(item); + if (newIndex + 1 < list.CountItems()) + list.AddList(firstItems, newIndex + 1); + else + list.AddList(firstItems); } void -BOutlineListView::_DoSwap(BList &list, int32 firstIndex, int32 secondIndex, int32 firstCount, - int32 secondCount, int32 swapCount) +BOutlineListView::_CullInvisibleItems(BList &list) { - if (firstCount < secondCount) { - for (int32 i = swapCount + 1; i < secondCount; i++) - list.MoveItem(secondIndex + swapCount + i, firstIndex + i); - } else { - for (int32 i = swapCount + 1; i < firstCount; i++) - list.MoveItem(firstIndex + swapCount + 1, secondIndex + swapCount + 1); + int32 index = 0; + while (index < list.CountItems()) { + if (reinterpret_cast(list.ItemAt(index))->IsItemVisible()) + ++index; + else + list.RemoveItem(index); } } @@ -815,32 +828,27 @@ BOutlineListView::_SwapItems(int32 first, int32 second) int32 secondIndex = max_c(first, second); BListItem *firstItem = ItemAt(firstIndex); BListItem *secondItem = ItemAt(secondIndex); + BList firstSubItems, secondSubItems; if (Superitem(firstItem) != Superitem(secondItem)) return false; - if (!firstItem->IsItemVisible() || !secondItem->IsItemVisible()) return false; - + int32 fullFirstIndex = FullListIndex(firstIndex); int32 fullSecondIndex = FullListIndex(secondIndex); - int32 firstCount = _GetSubitemCount(fFullList, fullFirstIndex); - int32 secondCount = _GetSubitemCount(fFullList, fullSecondIndex); - - int32 index = (firstCount < secondCount) ? firstCount : secondCount; - for (int32 i = 0; i < index; i++) - fFullList.SwapItems(fullFirstIndex + i, fullSecondIndex + i); - _DoSwap(fFullList, fullFirstIndex, fullSecondIndex, firstCount, secondCount, index); - - firstCount = _GetSubitemCount(fList, firstIndex); - secondCount = _GetSubitemCount(fList, secondIndex); - index = (firstCount < secondCount) ? firstCount : secondCount; - for (int32 i = 0; i < index; i++) - fList.SwapItems(firstIndex + i, secondIndex + i); - _DoSwap(fList, firstIndex, secondIndex, firstCount, secondCount, index); + _GetSubItems(fFullList, firstSubItems, firstItem, fullFirstIndex + 1); + _GetSubItems(fFullList, secondSubItems, secondItem, fullSecondIndex + 1); + _DoSwap(fFullList, fullFirstIndex, fullSecondIndex, &firstSubItems, + &secondSubItems); + + _CullInvisibleItems(firstSubItems); + _CullInvisibleItems(secondSubItems); + _DoSwap(fList, firstIndex, secondIndex, &firstSubItems, + &secondSubItems); _RecalcItemTops(firstIndex); - _RescanSelection(firstIndex, secondIndex + secondCount); + _RescanSelection(firstIndex, secondIndex + secondSubItems.CountItems()); Invalidate(Bounds()); return true; }