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
This commit is contained in:
Rene Gollent 2008-06-28 03:03:56 +00:00
parent a591a6b828
commit 84d75fa444
2 changed files with 43 additions and 37 deletions

View File

@ -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 *);

View File

@ -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<BListItem *>(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;
}