bool BOutlineListView::_SwapItems(int32 first, int32 second) { // same item, do nothing if (first == second) return true; // fail, first item out of bounds if ((first < 0) || (first >= CountItems())) return false; // fail, second item out of bounds if ((second < 0) || (second >= CountItems())) return false; int32 firstIndex = min_c(first, 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); _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 + secondSubItems.CountItems()); Invalidate(Bounds()); return true; }
bool BOutlineListView::AddItem(BListItem* item, int32 fullListIndex) { if (fullListIndex < 0) fullListIndex = 0; else if (fullListIndex > FullListCountItems()) fullListIndex = FullListCountItems(); if (!fFullList.AddItem(item, fullListIndex)) return false; // Check if this item is visible, and if it is, add it to the // other list, too if (item->fLevel > 0) { BListItem* super = _SuperitemForIndex(fullListIndex, item->fLevel); if (super == NULL) return true; bool hadSubitems = super->fHasSubitems; super->fHasSubitems = true; if (!super->IsItemVisible() || !super->IsExpanded()) { item->SetItemVisible(false); return true; } if (!hadSubitems) Invalidate(LatchRect(ItemFrame(IndexOf(super)), super->OutlineLevel())); } int32 listIndex = _FindPreviousVisibleIndex(fullListIndex); if (!BListView::AddItem(item, IndexOf(FullListItemAt(listIndex)) + 1)) { // adding didn't work out, we need to remove it from the main list again fFullList.RemoveItem(fullListIndex); return false; } return true; }
/*! \brief Removes a single item from the list and all of its children. Unlike the BeOS version, this one will actually delete the children, too, as there should be no reference left to them. This may cause problems for applications that actually take the misbehaviour of the Be classes into account. */ BListItem* BOutlineListView::_RemoveItem(BListItem* item, int32 fullIndex) { if (item == NULL || fullIndex < 0 || fullIndex >= FullListCountItems()) return NULL; uint32 level = item->OutlineLevel(); int32 superIndex; BListItem* super = _SuperitemForIndex(fullIndex, level, &superIndex); if (item->IsItemVisible()) { // remove children, too while (fullIndex + 1 < FullListCountItems()) { BListItem* subItem = FullListItemAt(fullIndex + 1); if (subItem->OutlineLevel() <= level) break; if (subItem->IsItemVisible()) BListView::RemoveItem(subItem); fFullList.RemoveItem(fullIndex + 1); delete subItem; } BListView::RemoveItem(item); } fFullList.RemoveItem(fullIndex); if (super != NULL) { // we might need to change the fHasSubitems field of the parent BListItem* child = FullListItemAt(superIndex + 1); if (child == NULL || child->OutlineLevel() <= super->OutlineLevel()) super->fHasSubitems = false; } return item; }