bool ColumnListView::RemoveItems(int32 fullListIndex, int32 count) { CLVListItem* TheItem; if(fHierarchical) { uint32 LastSuperItemLevel = ULONG_MAX; int32 Counter; int32 DisplayItemsToRemove = 0; int32 FirstDisplayItemToRemove = -1; for(Counter = fullListIndex; Counter < fullListIndex+count; Counter++) { TheItem = FullListItemAt(Counter); if(TheItem->fOutlineLevel < LastSuperItemLevel) LastSuperItemLevel = TheItem->fOutlineLevel; if(BListView::HasItem((BListItem*)TheItem)) { DisplayItemsToRemove++; if(FirstDisplayItemToRemove == -1) FirstDisplayItemToRemove = BListView::IndexOf(TheItem); } } while(true) { TheItem = FullListItemAt(Counter); if(TheItem && TheItem->fOutlineLevel > LastSuperItemLevel) { count++; Counter++; if(BListView::HasItem((BListItem*)TheItem)) { DisplayItemsToRemove++; if(FirstDisplayItemToRemove == -1) FirstDisplayItemToRemove = BListView::IndexOf((BListItem*)TheItem); } } else break; } while(DisplayItemsToRemove > 0) { if(BListView::RemoveItem(FirstDisplayItemToRemove) == NULL) return false; DisplayItemsToRemove--; } return fFullItemList.RemoveItems(fullListIndex,count); } else return BListView::RemoveItems(fullListIndex,count); }
BListItem* BOutlineListView::EachItemUnder(BListItem* underItem, bool oneLevelOnly, BListItem* (*eachFunc)(BListItem* item, void* arg), void* arg) { 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) { item = eachFunc(item, arg); if (item != NULL) return item; } i++; } return NULL; }
BListItem* BOutlineListView::ItemUnderAt(BListItem* underItem, bool oneLevelOnly, int32 index) const { int32 i = FullListIndexOf(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) { if (index == 0) return item; index--; } i++; } return NULL; }
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 the level matches, put them into the list // (we handle the case of a missing sublevel gracefully) list->AddItem(item); fullIndex++; if (item->HasSubitems()) { // we're going deeper _BuildTree(item, fullIndex); } } return list; }
int32 BOutlineListView::CountItemsUnder(BListItem* underItem, bool oneLevelOnly) const { int32 i = FullListIndexOf(underItem); if (i == -1) return 0; ++i; int32 count = 0; uint32 baseLevel = underItem->OutlineLevel(); for (; i < FullListCountItems(); i++) { BListItem* item = FullListItemAt(i); // If we jump out of the subtree, return count if (item->fLevel <= baseLevel) return count; // If the level matches, increase count if (!oneLevelOnly || item->fLevel == baseLevel + 1) count++; } return count; }
void MimeTypeListView::ShowIcons(bool showIcons) { if (showIcons == fShowIcons) return; fShowIcons = showIcons; if (Window() == NULL) return; // update items BFont font; GetFont(&font); for (int32 i = FullListCountItems(); i-- > 0;) { MimeTypeItem* item = dynamic_cast<MimeTypeItem*>(FullListItemAt(i)); if (item == NULL) continue; if (!item->IsSupertypeOnly()) item->ShowIcon(showIcons); item->Update(this, &font); } FrameResized(Bounds().Width(), Bounds().Height()); // update scroller Invalidate(); }
bool BOutlineListView::IsExpanded(int32 fullListIndex) { BListItem* item = FullListItemAt(fullListIndex); if (!item) return false; return item->IsExpanded(); }
int32 RosterView::FindUser(UserID *compare_user) { if (compare_user == NULL) return -1; for (int i=0; i<FullListCountItems(); ++i) { RosterItem *item = dynamic_cast<RosterItem *>(FullListItemAt(i)); if (item == NULL || item->StalePointer()) continue; if (item->GetUserID() == compare_user) return i; } return -1; }
void MimeTypeListView::DetachedFromWindow() { BOutlineListView::DetachedFromWindow(); BMimeType::StopWatching(this); // free all items, they will be retrieved again in AttachedToWindow() for (int32 i = FullListCountItems(); i-- > 0;) { delete FullListItemAt(i); } }
void MimeTypeListView::_MakeTypesUnique(MimeTypeItem* underItem) { SortItemsUnder(underItem, underItem != NULL, &MimeTypeItem::Compare); bool lastItemSame = false; MimeTypeItem* last = NULL; int32 index = 0; uint32 level = 0; if (underItem != NULL) { index = FullListIndexOf(underItem) + 1; level = underItem->OutlineLevel() + 1; } for (; index < FullListCountItems(); index++) { MimeTypeItem* item = dynamic_cast<MimeTypeItem*>(FullListItemAt(index)); if (item == NULL) continue; if (item->OutlineLevel() < level) { // left sub-tree break; } item->SetText(item->Description()); if (last == NULL || MimeTypeItem::CompareLabels(last, item)) { if (lastItemSame) { last->AddSubtype(); if (Window()) InvalidateItem(IndexOf(last)); } lastItemSame = false; last = item; continue; } lastItemSame = true; last->AddSubtype(); if (Window()) InvalidateItem(IndexOf(last)); last = item; } if (lastItemSame) { last->AddSubtype(); if (Window()) InvalidateItem(IndexOf(last)); } }
int32 BOutlineListView::_FindPreviousVisibleIndex(int32 fullListIndex) { fullListIndex--; while (fullListIndex >= 0) { if (FullListItemAt(fullListIndex)->fVisible) return fullListIndex; fullListIndex--; } return -1; }
/*! \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; }
LanguageListItem* LanguageListView::ItemForLanguageCode(const char* code, int32* _index) const { for (int32 index = 0; index < FullListCountItems(); index++) { LanguageListItem* item = static_cast<LanguageListItem*>(FullListItemAt(index)); if (item->Code() == code) { if (_index != NULL) *_index = index; return item; } } return NULL; }
MimeTypeItem* MimeTypeListView::FindItem(const char* type) { if (type == NULL) return NULL; for (int32 i = FullListCountItems(); i-- > 0;) { MimeTypeItem* item = dynamic_cast<MimeTypeItem*>(FullListItemAt(i)); if (item == NULL) continue; if (!strcasecmp(item->Type(), type)) return item; } return NULL; }
int32 ColumnListView::FullListNumberOfSubitems(const CLVListItem* item) const { if(!fHierarchical) return 0; int32 ItemPos = FullListIndexOf(item); int32 SubItemPos; uint32 SuperItemLevel = item->fOutlineLevel; if(ItemPos >= 0) { for(SubItemPos = ItemPos + 1; SubItemPos >= 1; SubItemPos++) { CLVListItem* TheItem = FullListItemAt(SubItemPos); if(TheItem == NULL || TheItem->fOutlineLevel <= SuperItemLevel) break; } } else return 0; return SubItemPos-ItemPos-1; }
/*! Returns the super item before the item specified by \a fullListIndex and \a level. */ BListItem* BOutlineListView::_SuperitemForIndex(int32 fullListIndex, int32 level, int32* _superIndex) { BListItem* item; fullListIndex--; while (fullListIndex >= 0) { if ((item = FullListItemAt(fullListIndex))->OutlineLevel() < (uint32)level) { if (_superIndex != NULL) *_superIndex = fullListIndex; return item; } fullListIndex--; } return NULL; }
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; }
BListItem* BOutlineListView::RemoveItem(int32 fullIndex) { return _RemoveItem(FullListItemAt(fullIndex), fullIndex); }