Files
haiku-beta6/src/kits/interface/OutlineListView.cpp
T

981 lines
18 KiB
C++
Raw Normal View History

/*
* Copyright 2001-2006, Haiku Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
* Marc Flerackers ([email protected])
* Axel Dörfler, [email protected]
*/
//! BOutlineListView represents a "nestable" list view.
2003-06-16 07:55:04 +00:00
#include <OutlineListView.h>
#include <stdio.h>
#include <stdlib.h>
2003-06-16 07:55:04 +00:00
/*!
\brief A simple recursive quick sort implementations for BListItem arrays.
2003-06-16 07:55:04 +00:00
We need to implement it ourselves, since the BOutlineListView sort methods
use a different comparison function than the standard functions.
*/
static void
quick_sort_item_array(BListItem** items, int32 first, int32 last,
int (*compareFunc)(const BListItem* a, const BListItem* b))
{
if (last - 1 <= first)
return;
2003-06-16 07:55:04 +00:00
BListItem* pivot = items[first + (rand() % (last - first))];
// choose an arbitrary pivot element
2003-06-16 07:55:04 +00:00
int32 left = first;
int32 right = last;
2003-06-16 07:55:04 +00:00
do {
while (compareFunc(items[left], pivot) < 0) {
left++;
}
while (compareFunc(items[right], pivot) > 0) {
right--;
}
if (left <= right) {
// swap entries
BListItem* temp = items[left];
items[left] = items[right];
items[right] = temp;
left++;
right--;
}
} while (left <= right);
// At this point, the elements in the left half are all smaller
// than the elements in the right half
if (first < right) {
// sort left half
quick_sort_item_array(items, first, right, compareFunc);
}
if (left < last) {
// sort right half
quick_sort_item_array(items, left, last, compareFunc);
}
}
// #pragma mark -
BOutlineListView::BOutlineListView(BRect frame, const char* name,
list_view_type type, uint32 resizeMode, uint32 flags)
: BListView(frame, name, type, resizeMode, flags)
2003-06-16 07:55:04 +00:00
{
}
BOutlineListView::BOutlineListView(BMessage* archive)
: BListView(archive)
2003-06-16 07:55:04 +00:00
{
}
2003-06-16 07:55:04 +00:00
BOutlineListView::~BOutlineListView()
{
fFullList.MakeEmpty();
2003-06-16 07:55:04 +00:00
}
BArchivable *
BOutlineListView::Instantiate(BMessage* archive)
2003-06-16 07:55:04 +00:00
{
if (validate_instantiation(archive, "BOutlineListView"))
return new BOutlineListView(archive);
return NULL;
2003-06-16 07:55:04 +00:00
}
status_t
BOutlineListView::Archive(BMessage* archive, bool deep) const
2003-06-16 07:55:04 +00:00
{
return BListView::Archive(archive, deep);
2003-06-16 07:55:04 +00:00
}
void
BOutlineListView::MouseDown(BPoint point)
2003-06-16 07:55:04 +00:00
{
MakeFocus();
int32 index = IndexOf(point);
if (index != -1) {
2003-06-16 07:55:04 +00:00
BListItem *item = ItemAt(index);
if (item->fHasSubitems
&& LatchRect(ItemFrame(index), item->fLevel).Contains(point)) {
2003-06-16 07:55:04 +00:00
if (item->IsExpanded())
Collapse(item);
else
Expand(item);
} else
BListView::MouseDown(point);
2003-06-16 07:55:04 +00:00
}
}
void
BOutlineListView::KeyDown(const char* bytes, int32 numBytes)
2003-06-16 07:55:04 +00:00
{
if (numBytes == 1) {
switch (bytes[0]) {
case B_RIGHT_ARROW:
2003-06-16 07:55:04 +00:00
{
BListItem *item = ItemAt(CurrentSelection());
if (item && item->fHasSubitems)
2003-06-16 07:55:04 +00:00
Expand(item);
return;
2003-06-16 07:55:04 +00:00
}
case B_LEFT_ARROW:
2003-06-16 07:55:04 +00:00
{
BListItem *item = ItemAt(CurrentSelection());
if (item && item->fHasSubitems)
Collapse(item);
return;
2003-06-16 07:55:04 +00:00
}
}
}
BListView::KeyDown(bytes, numBytes);
2003-06-16 07:55:04 +00:00
}
void
BOutlineListView::FrameMoved(BPoint newPosition)
2003-06-16 07:55:04 +00:00
{
BListView::FrameMoved(newPosition);
2003-06-16 07:55:04 +00:00
}
void
BOutlineListView::FrameResized(float newWidth, float newHeight)
2003-06-16 07:55:04 +00:00
{
BListView::FrameResized(newWidth, newHeight);
2003-06-16 07:55:04 +00:00
}
void
BOutlineListView::MouseUp(BPoint where)
2003-06-16 07:55:04 +00:00
{
BListView::MouseUp(where);
}
bool
BOutlineListView::AddUnder(BListItem* item, BListItem* superitem)
2003-06-16 07:55:04 +00:00
{
fFullList.AddItem(item, FullListIndexOf(superitem) + 1);
2003-06-16 07:55:04 +00:00
item->fLevel = superitem->OutlineLevel() + 1;
superitem->fHasSubitems = true;
if (superitem->IsItemVisible() && superitem->IsExpanded()) {
2003-06-16 07:55:04 +00:00
item->SetItemVisible(true);
int32 index = BListView::IndexOf(superitem);
BListView::AddItem(item, index + 1);
Invalidate(LatchRect(ItemFrame(index), superitem->OutlineLevel()));
} else
2003-06-16 07:55:04 +00:00
item->SetItemVisible(false);
return true;
}
bool
BOutlineListView::AddItem(BListItem* item)
{
if (!fFullList.AddItem(item))
2003-06-16 07:55:04 +00:00
return false;
return BListView::AddItem(item);
}
bool
BOutlineListView::AddItem(BListItem* item, int32 fullListIndex)
2003-06-16 07:55:04 +00:00
{
if (fullListIndex < 0)
fullListIndex = 0;
else if (fullListIndex > CountItems())
fullListIndex = CountItems();
fFullList.AddItem(item, fullListIndex);
2003-06-16 07:55:04 +00:00
if (item->fLevel > 0) {
2003-06-16 07:55:04 +00:00
BListItem *super = SuperitemForIndex(fullListIndex, item->fLevel);
if (!super->IsItemVisible() || !super->IsExpanded())
return true;
}
int32 listIndex = FindPreviousVisibleIndex(fullListIndex);
return BListView::AddItem(item, IndexOf(FullListItemAt(listIndex)) + 1);
2003-06-16 07:55:04 +00:00
}
bool
BOutlineListView::AddList(BList* newItems)
2003-06-16 07:55:04 +00:00
{
printf("BOutlineListView::AddList Not implemented\n");
return false;
}
bool
BOutlineListView::AddList(BList* newItems, int32 fullListIndex)
2003-06-16 07:55:04 +00:00
{
printf("BOutlineListView::AddList Not implemented\n");
return false;
}
bool
BOutlineListView::RemoveItem(BListItem* item)
2003-06-16 07:55:04 +00:00
{
return _RemoveItem(item, FullListIndexOf(item)) != NULL;
2003-06-16 07:55:04 +00:00
}
BListItem*
BOutlineListView::RemoveItem(int32 fullIndex)
{
return _RemoveItem(FullListItemAt(fullIndex), fullIndex);
2003-06-16 07:55:04 +00:00
}
bool
BOutlineListView::RemoveItems(int32 fullListIndex, int32 count)
2003-06-16 07:55:04 +00:00
{
printf("BOutlineListView::RemoveItems Not implemented\n");
return false;
}
BListItem *
BOutlineListView::FullListItemAt(int32 fullListIndex) const
2003-06-16 07:55:04 +00:00
{
return (BListItem*)fFullList.ItemAt(fullListIndex);
2003-06-16 07:55:04 +00:00
}
int32
BOutlineListView::FullListIndexOf(BPoint point) const
2003-06-16 07:55:04 +00:00
{
return BListView::IndexOf(point);
}
int32
BOutlineListView::FullListIndexOf(BListItem* item) const
2003-06-16 07:55:04 +00:00
{
return fFullList.IndexOf(item);
2003-06-16 07:55:04 +00:00
}
BListItem *
BOutlineListView::FullListFirstItem() const
2003-06-16 07:55:04 +00:00
{
return (BListItem*)fFullList.FirstItem();
2003-06-16 07:55:04 +00:00
}
BListItem *
BOutlineListView::FullListLastItem() const
2003-06-16 07:55:04 +00:00
{
return (BListItem*)fFullList.LastItem();
2003-06-16 07:55:04 +00:00
}
bool
BOutlineListView::FullListHasItem(BListItem *item) const
2003-06-16 07:55:04 +00:00
{
return fFullList.HasItem(item);
2003-06-16 07:55:04 +00:00
}
int32
BOutlineListView::FullListCountItems() const
2003-06-16 07:55:04 +00:00
{
return fFullList.CountItems();
2003-06-16 07:55:04 +00:00
}
int32
BOutlineListView::FullListCurrentSelection(int32 index) const
2003-06-16 07:55:04 +00:00
{
int32 i = BListView::CurrentSelection(index);
BListItem *item = BListView::ItemAt(i);
2003-06-16 07:55:04 +00:00
if (item)
return fFullList.IndexOf(item);
return -1;
2003-06-16 07:55:04 +00:00
}
void
BOutlineListView::MakeEmpty()
2003-06-16 07:55:04 +00:00
{
fFullList.MakeEmpty();
2003-06-16 07:55:04 +00:00
BListView::MakeEmpty();
}
bool
BOutlineListView::FullListIsEmpty() const
2003-06-16 07:55:04 +00:00
{
return fFullList.IsEmpty();
2003-06-16 07:55:04 +00:00
}
void
BOutlineListView::FullListDoForEach(bool(*func)(BListItem* item))
2003-06-16 07:55:04 +00:00
{
fFullList.DoForEach(reinterpret_cast<bool (*)(void*)>(func));
2003-06-16 07:55:04 +00:00
}
void
BOutlineListView::FullListDoForEach(bool (*func)(BListItem* item, void* arg),
void* arg)
2003-06-16 07:55:04 +00:00
{
fList.DoForEach(reinterpret_cast<bool (*)(void*, void*)>(func), arg);
2003-06-16 07:55:04 +00:00
}
BListItem *
BOutlineListView::Superitem(const BListItem* item)
2003-06-16 07:55:04 +00:00
{
int32 index = FullListIndexOf((BListItem*)item);
if (index == -1)
return NULL;
return SuperitemForIndex(index, item->OutlineLevel());
2003-06-16 07:55:04 +00:00
}
void
BOutlineListView::Expand(BListItem* item)
{
if (item->IsExpanded() || !FullListHasItem(item))
2003-06-16 07:55:04 +00:00
return;
item->fExpanded = true;
uint32 level = item->fLevel;
int32 fullIndex = FullListIndexOf(item);
int32 index = IndexOf(item) + 1;
int32 count = FullListCountItems() - fullIndex - 1;
BListItem** items = (BListItem**)fFullList.Items() + fullIndex + 1;
2003-06-16 07:55:04 +00:00
BFont font;
GetFont(&font);
while (count-- > 0) {
item = items[0];
if (item->fLevel <= level)
break;
if (!item->IsItemVisible()) {
// fix selection hints
if (index <= fFirstSelected)
fFirstSelected++;
if (index <= fLastSelected)
fLastSelected++;
fList.AddItem(item, index++);
item->Update(this, &font);
item->SetItemVisible(true);
2003-06-16 07:55:04 +00:00
}
if (item->HasSubitems() && !item->IsExpanded()) {
// Skip hidden children
uint32 subLevel = item->fLevel;
2003-06-16 07:55:04 +00:00
items++;
while (--count > 0 && items[0]->fLevel > subLevel)
2003-06-16 07:55:04 +00:00
items++;
} else
2003-06-16 07:55:04 +00:00
items++;
}
2005-11-15 01:36:10 +00:00
_FixupScrollBar();
2003-06-16 07:55:04 +00:00
Invalidate();
}
void
BOutlineListView::Collapse(BListItem* item)
{
if (!item->IsExpanded() || !FullListHasItem(item))
2003-06-16 07:55:04 +00:00
return;
item->fExpanded = false;
uint32 level = item->fLevel;
int32 fullIndex = FullListIndexOf(item);
int32 index = IndexOf(item);
int32 max = FullListCountItems() - fullIndex - 1;
int32 count = 0;
BListItem** items = (BListItem**)fFullList.Items() + fullIndex + 1;
while (max-- > 0) {
item = items[0];
if (item->fLevel <= level)
break;
if (item->IsItemVisible()) {
fList.RemoveItem(item);
item->SetItemVisible(false);
if (item->IsSelected())
item->Deselect();
count++;
2003-06-16 07:55:04 +00:00
}
items++;
}
// fix selection hints
// TODO: revise for multi selection lists
if (index < fFirstSelected) {
if (index + count < fFirstSelected) {
fFirstSelected -= count;
fLastSelected -= count;
} else {
// select top item
//fFirstSelected = fLastSelected = index;
//item->Select();
Select(index);
}
}
2005-11-15 01:36:10 +00:00
_FixupScrollBar();
2003-06-16 07:55:04 +00:00
Invalidate();
}
bool
BOutlineListView::IsExpanded(int32 fullListIndex)
2003-06-16 07:55:04 +00:00
{
BListItem *item = FullListItemAt(fullListIndex);
if (!item)
return false;
return item->IsExpanded();
}
BHandler *
BOutlineListView::ResolveSpecifier(BMessage* msg, int32 index,
BMessage* specifier, int32 what, const char* property)
2003-06-16 07:55:04 +00:00
{
return BListView::ResolveSpecifier(msg, index, specifier, what, property);
2003-06-16 07:55:04 +00:00
}
status_t
BOutlineListView::GetSupportedSuites(BMessage* data)
2003-06-16 07:55:04 +00:00
{
return BListView::GetSupportedSuites(data);
}
status_t
BOutlineListView::Perform(perform_code d, void* arg)
2003-06-16 07:55:04 +00:00
{
return BListView::Perform(d, arg);
}
void
BOutlineListView::ResizeToPreferred()
2003-06-16 07:55:04 +00:00
{
BListView::ResizeToPreferred();
}
void
BOutlineListView::GetPreferredSize(float* _width, float* _height)
2003-06-16 07:55:04 +00:00
{
BListView::GetPreferredSize(_width, _height);
2003-06-16 07:55:04 +00:00
}
void
BOutlineListView::MakeFocus(bool state)
2003-06-16 07:55:04 +00:00
{
BListView::MakeFocus(state);
}
void
BOutlineListView::AllAttached()
2003-06-16 07:55:04 +00:00
{
BListView::AllAttached();
}
void
BOutlineListView::AllDetached()
2003-06-16 07:55:04 +00:00
{
BListView::AllDetached();
}
void
BOutlineListView::DetachedFromWindow()
2003-06-16 07:55:04 +00:00
{
BListView::DetachedFromWindow();
}
void
BOutlineListView::FullListSortItems(int (*compareFunc)(const BListItem* a,
const BListItem* b))
2003-06-16 07:55:04 +00:00
{
SortItemsUnder(NULL, false, compareFunc);
2003-06-16 07:55:04 +00:00
}
void
BOutlineListView::SortItemsUnder(BListItem* underItem, bool oneLevelOnly,
int (*compareFunc)(const BListItem* a, const BListItem* b))
2003-06-16 07:55:04 +00:00
{
// This method is quite complicated: basically, it creates a real tree
// from the items of the full list, sorts them as needed, and then
// populates the entries back into the full and display lists
int32 firstIndex = FullListIndexOf(underItem) + 1;
int32 lastIndex = firstIndex;
BList* tree = _BuildTree(underItem, lastIndex);
_SortTree(tree, oneLevelOnly, compareFunc);
// Populate to the full list
_PopulateTree(tree, fFullList, firstIndex, false);
// Populate to BListView's list
firstIndex = fList.IndexOf(underItem) + 1;
_PopulateTree(tree, fList, firstIndex, true);
_DestructTree(tree);
2003-06-16 07:55:04 +00:00
}
void
BOutlineListView::_PopulateTree(BList* tree, BList& target,
int32& firstIndex, bool onlyVisible)
2003-06-16 07:55:04 +00:00
{
BListItem** items = (BListItem**)target.Items();
int32 count = tree->CountItems();
2003-06-16 07:55:04 +00:00
for (int32 index = 0; index < count; index++) {
BListItem* item = (BListItem*)tree->ItemAtFast(index);
2003-06-16 07:55:04 +00:00
items[firstIndex++] = item;
if (item->HasSubitems() && (!onlyVisible || item->IsExpanded()))
_PopulateTree(item->fTemporaryList, target, firstIndex, onlyVisible);
}
}
void
BOutlineListView::_SortTree(BList* tree, bool oneLevelOnly,
int (*compareFunc)(const BListItem* a, const BListItem* b))
{
// home-brewn quick sort for our compareFunc
quick_sort_item_array((BListItem**)tree->Items(), 0, tree->CountItems() - 1,
compareFunc);
2003-06-16 07:55:04 +00:00
if (oneLevelOnly)
return;
2003-06-16 07:55:04 +00:00
for (int32 index = tree->CountItems(); index-- > 0;) {
BListItem* item = (BListItem*)tree->ItemAt(index);
2003-06-16 07:55:04 +00:00
if (item->HasSubitems())
_SortTree(item->fTemporaryList, false, compareFunc);
}
}
2003-06-16 07:55:04 +00:00
void
BOutlineListView::_DestructTree(BList* tree)
{
for (int32 index = tree->CountItems(); index-- > 0;) {
BListItem* item = (BListItem*)tree->ItemAt(index);
if (item->HasSubitems())
_DestructTree(item->fTemporaryList);
2003-06-16 07:55:04 +00:00
}
delete tree;
}
2003-06-16 07:55:04 +00:00
BList*
BOutlineListView::_BuildTree(BListItem* underItem, int32& fullIndex)
{
int32 fullCount = FullListCountItems();
uint32 level = underItem != NULL ? underItem->OutlineLevel() + 1 : 0;
BList* list = new BList;
if (underItem != NULL)
underItem->fTemporaryList = list;
while (fullIndex < fullCount) {
BListItem *item = FullListItemAt(fullIndex);
// If we jump out of the subtree, break out
if (item->fLevel < level)
break;
if (item->fLevel == level) {
// If the level matches, put them into the list
list->AddItem(item);
}
fullIndex++;
if (item->HasSubitems()) {
// we're going deeper
_BuildTree(item, fullIndex);
2003-06-16 07:55:04 +00:00
}
}
return list;
2003-06-16 07:55:04 +00:00
}
int32
BOutlineListView::CountItemsUnder(BListItem* underItem,
bool oneLevelOnly) const
2003-06-16 07:55:04 +00:00
{
int32 i = IndexOf(underItem);
if (i == -1)
return 0;
2003-06-16 07:55:04 +00:00
int32 count = 0;
while (i < FullListCountItems()) {
BListItem *item = FullListItemAt(i);
// If we jump out of the subtree, return count
if (item->fLevel < underItem->OutlineLevel())
return count;
// If the level matches, increase count
if (!oneLevelOnly || item->fLevel == underItem->OutlineLevel() + 1)
count++;
i++;
}
return count;
2003-06-16 07:55:04 +00:00
}
BListItem *
BOutlineListView::EachItemUnder(BListItem *underItem, bool oneLevelOnly,
BListItem *(*eachFunc)(BListItem* item, void* arg), void* arg)
2003-06-16 07:55:04 +00:00
{
int32 i = IndexOf(underItem);
if (i == -1)
return NULL;
while (i < FullListCountItems()) {
BListItem *item = FullListItemAt(i);
2003-06-16 07:55:04 +00:00
// If we jump out of the subtree, return NULL
if (item->fLevel < underItem->OutlineLevel())
return NULL;
2003-06-16 07:55:04 +00:00
// If the level matches, check the index
if (!oneLevelOnly || item->fLevel == underItem->OutlineLevel() + 1) {
item = eachFunc(item, arg);
if (item != NULL)
return item;
2003-06-16 07:55:04 +00:00
}
i++;
2003-06-16 07:55:04 +00:00
}
return NULL;
}
2003-06-16 07:55:04 +00:00
BListItem *
BOutlineListView::ItemUnderAt(BListItem* underItem,
bool oneLevelOnly, int32 index) const
{
int32 i = IndexOf(underItem);
if (i == -1)
return NULL;
while (i < FullListCountItems()) {
BListItem *item = FullListItemAt(i);
// If we jump out of the subtree, return NULL
if (item->fLevel < underItem->OutlineLevel())
return NULL;
// If the level matches, check the index
if (!oneLevelOnly || item->fLevel == underItem->OutlineLevel() + 1) {
2003-06-16 07:55:04 +00:00
if (index == 0)
return item;
index--;
2003-06-16 07:55:04 +00:00
}
i++;
2003-06-16 07:55:04 +00:00
}
return NULL;
}
bool
BOutlineListView::DoMiscellaneous(MiscCode code, MiscData* data)
2003-06-16 07:55:04 +00:00
{
return BListView::DoMiscellaneous(code, data);
}
void
BOutlineListView::MessageReceived(BMessage* msg)
2003-06-16 07:55:04 +00:00
{
BListView::MessageReceived(msg);
}
2003-06-16 07:55:04 +00:00
void BOutlineListView::_ReservedOutlineListView1() {}
void BOutlineListView::_ReservedOutlineListView2() {}
void BOutlineListView::_ReservedOutlineListView3() {}
void BOutlineListView::_ReservedOutlineListView4() {}
int32
BOutlineListView::FullListIndex(int32 index) const
2003-06-16 07:55:04 +00:00
{
BListItem *item = ItemAt(index);
if (item == NULL)
return -1;
return FullListIndexOf(item);
2003-06-16 07:55:04 +00:00
}
int32
BOutlineListView::ListViewIndex(int32 index) const
2003-06-16 07:55:04 +00:00
{
BListItem *item = ItemAt(index);
if (item == NULL)
return -1;
return BListView::IndexOf(item);
2003-06-16 07:55:04 +00:00
}
void
BOutlineListView::ExpandOrCollapse(BListItem *underItem, bool expand)
2003-06-16 07:55:04 +00:00
{
}
BRect
BOutlineListView::LatchRect(BRect itemRect, int32 level) const
2003-06-16 07:55:04 +00:00
{
return BRect(itemRect.left, itemRect.top, itemRect.left
+ (level * 10.0f + 15.0f), itemRect.bottom);
2003-06-16 07:55:04 +00:00
}
void
BOutlineListView::DrawLatch(BRect itemRect, int32 level, bool collapsed,
bool highlighted, bool misTracked)
2003-06-16 07:55:04 +00:00
{
float left = level * 10.0f;
if (collapsed) {
2003-06-16 07:55:04 +00:00
SetHighColor(192, 192, 192);
FillTriangle(itemRect.LeftTop() + BPoint(left + 4.0f, 2.0f),
itemRect.LeftTop() + BPoint(left + 4.0f, 10.0f),
itemRect.LeftTop() + BPoint(left + 8.0f, 6.0f));
SetHighColor(0, 0, 0);
StrokeTriangle(itemRect.LeftTop() + BPoint(left + 4.0f, 2.0f),
itemRect.LeftTop() + BPoint(left + 4.0f, 10.0f),
itemRect.LeftTop() + BPoint(left + 8.0f, 6.0f));
} else {
2003-06-16 07:55:04 +00:00
SetHighColor(192, 192, 192);
2003-06-16 07:55:04 +00:00
FillTriangle(itemRect.LeftTop() + BPoint(left + 2.0f, 4.0f),
itemRect.LeftTop() + BPoint(left + 10.0f, 4.0f),
itemRect.LeftTop() + BPoint(left + 6.0f, 8.0f));
SetHighColor(0, 0, 0);
StrokeTriangle(itemRect.LeftTop() + BPoint(left + 2.0f, 4.0f),
itemRect.LeftTop() + BPoint(left + 10.0f, 4.0f),
itemRect.LeftTop() + BPoint(left + 6.0f, 8.0f));
}
}
void
BOutlineListView::DrawItem(BListItem* item, BRect itemRect, bool complete)
2003-06-16 07:55:04 +00:00
{
if (item->fHasSubitems)
DrawLatch(itemRect, item->fLevel, !item->IsExpanded(), false, false);
itemRect.left += (item->fLevel) * 10.0f + 15.0f;
item->DrawItem(this, itemRect, complete);
}
/*!
\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)
2003-06-16 07:55:04 +00:00
{
if (item == NULL || fullIndex < 0 || fullIndex >= FullListCountItems())
return NULL;
if (item->IsItemVisible()) {
// remove children, too
uint32 level = item->OutlineLevel();
int32 max = FullListCountItems() - fullIndex - 1;
BListItem** items = (BListItem**)fFullList.Items() + fullIndex + 1;
while (max-- > 0) {
BListItem* subItem = items[0];
if (subItem->fLevel <= level)
break;
if (subItem->IsItemVisible())
BListView::RemoveItem(subItem);
fFullList.RemoveItem(fullIndex + 1);
// TODO: this might be problematic, see comment above
delete subItem;
}
BListView::RemoveItem(item);
}
fFullList.RemoveItem(fullIndex);
return item;
2003-06-16 07:55:04 +00:00
}
BListItem *
BOutlineListView::RemoveOne(int32 fullListIndex)
2003-06-16 07:55:04 +00:00
{
return NULL;
}
void
BOutlineListView::TrackInLatchItem(void *)
2003-06-16 07:55:04 +00:00
{
}
void
BOutlineListView::TrackOutLatchItem(void *)
2003-06-16 07:55:04 +00:00
{
}
bool
BOutlineListView::OutlineSwapItems(int32 a, int32 b)
2003-06-16 07:55:04 +00:00
{
return false;
}
bool
BOutlineListView::OutlineMoveItem(int32 from, int32 to)
2003-06-16 07:55:04 +00:00
{
return false;
}
bool
BOutlineListView::OutlineReplaceItem(int32 index, BListItem *item)
2003-06-16 07:55:04 +00:00
{
return false;
}
void
BOutlineListView::CommonMoveItems(int32 from, int32 count, int32 to)
2003-06-16 07:55:04 +00:00
{
}
BListItem *
BOutlineListView::SuperitemForIndex(int32 fullListIndex, int32 level)
2003-06-16 07:55:04 +00:00
{
BListItem *item;
fullListIndex--;
while (fullListIndex >= 0) {
2003-06-16 07:55:04 +00:00
if ((item = FullListItemAt(fullListIndex))->OutlineLevel() <
(uint32)level)
return item;
fullListIndex--;
}
return NULL;
}
int32
BOutlineListView::FindPreviousVisibleIndex(int32 fullListIndex)
2003-06-16 07:55:04 +00:00
{
fullListIndex--;
while (fullListIndex >= 0) {
2003-06-16 07:55:04 +00:00
if (FullListItemAt(fullListIndex)->fVisible)
return fullListIndex;
fullListIndex--;
}
return -1;
}