INT32 GenericTreeModel::Insert(GenericTreeModelItem* item, GenericTreeModelItem* parent, INT32 index) { OP_ASSERT(!item->IsInModel()); OP_ASSERT(index <= GetCount()); if (m_items.Insert(index, item) != OpStatus::OK) return -1; item->SetGenericModel(this); item->SetGenericParentItem(parent); item->SetLastIndex(index); item->SetSubtreeSize(0); UpdateSubtreeSizes(parent, 1); m_id_to_item.Add(item->GetID(), item); if (parent) m_is_flat = FALSE; item->OnAdded(); if (SetChangeType(TREE_CHANGED)) { BroadcastItemAdded(index); } return index; }
int32_t nsTreeContentView::EnsureSubtree(int32_t aIndex) { Row* row = mRows[aIndex]; nsIContent* child; child = nsTreeUtils::GetImmediateChild(row->mContent, nsGkAtoms::treechildren); if (!child || !child->IsXUL()) { return 0; } nsAutoTArray<Row*, 8> rows; int32_t index = 0; Serialize(child, aIndex, &index, rows); mRows.InsertElementsAt(aIndex + 1, rows); int32_t count = rows.Length(); row->mSubtreeSize += count; UpdateSubtreeSizes(row->mParentIndex, count); // Update parent indexes, but skip newly added rows. // They already have correct values. UpdateParentIndexes(aIndex, count + 1, count); return count; }
void GenericTreeModel::Remove(INT32 index, BOOL all_children, BOOL delete_item) { INT32 subtreesize = all_children ? GetSubtreeSize(index) : 0; BOOL broadcast = SetChangeType(TREE_CHANGED); GenericTreeModelItem* parent = GetGenericParentItem(index); if (broadcast) { BroadcastSubtreeRemoving(parent ? parent->GetIndex() : -1, index, subtreesize); } if (!all_children) { INT32 child = GetChildIndex(index); while (child != -1) { INT32 sibling = GetSiblingIndex(child); GetGenericItemByIndex(child)->SetGenericParentItem(parent); child = sibling; } } INT32 count = subtreesize + 1; Removing(index, count); UpdateSubtreeSizes(parent, -count); OpTreeModelItem* data; for(UINT32 i = index, count_item = index + count; i < count_item; i++) m_id_to_item.Remove(m_items.Get(i)->GetID(), &data); if (delete_item) { m_items.Delete(index, count); } else { m_items.Remove(index, count); } if (broadcast) { BroadcastSubtreeRemoved(parent ? parent->GetIndex() : -1, index, subtreesize); } }
int32_t nsTreeContentView::RemoveSubtree(int32_t aIndex) { Row* row = mRows[aIndex]; int32_t count = row->mSubtreeSize; for (int32_t i = 0; i < count; i++) { delete mRows[aIndex + i + 1]; } mRows.RemoveElementsAt(aIndex + 1, count); row->mSubtreeSize -= count; UpdateSubtreeSizes(row->mParentIndex, -count); UpdateParentIndexes(aIndex, 0, -count); return count; }
int32_t nsTreeContentView::RemoveRow(int32_t aIndex) { Row* row = mRows[aIndex]; int32_t count = row->mSubtreeSize + 1; int32_t parentIndex = row->mParentIndex; delete row; for(int32_t i = 1; i < count; i++) { delete mRows[aIndex + i]; } mRows.RemoveElementsAt(aIndex, count); UpdateSubtreeSizes(parentIndex, -count); UpdateParentIndexes(aIndex, 0, -count); return count; }
int32_t nsTreeContentView::InsertRow(int32_t aParentIndex, int32_t aIndex, nsIContent* aContent) { nsAutoTArray<Row*, 8> rows; nsIAtom *tag = aContent->Tag(); if (aContent->IsXUL()) { if (tag == nsGkAtoms::treeitem) SerializeItem(aContent, aParentIndex, &aIndex, rows); else if (tag == nsGkAtoms::treeseparator) SerializeSeparator(aContent, aParentIndex, &aIndex, rows); } mRows.InsertElementsAt(aParentIndex + aIndex + 1, rows); int32_t count = rows.Length(); UpdateSubtreeSizes(aParentIndex, count); // Update parent indexes, but skip added rows. // They already have correct values. UpdateParentIndexes(aParentIndex + aIndex, count + 1, count); return count; }
void GenericTreeModel::Move(INT32 index, INT32 parent_index, INT32 previous_index) { if (index == -1 || index == previous_index) { return; } INT32 subtree_size = GetSubtreeSize(index); INT32 count = subtree_size + 1; GenericTreeModelItem* item = GetGenericItemByIndex(index); GenericTreeModelItem* parent = item->GetGenericParentItem(); GenericTreeModelItem* new_parent = GetGenericItemByIndex(parent_index); GenericTreeModelItem* new_previous = GetGenericItemByIndex(previous_index); OP_ASSERT(!new_parent || !new_previous || new_parent == new_previous->GetGenericParentItem()); if(new_previous && !new_parent) new_parent = new_previous->GetGenericParentItem(); BOOL broadcast = SetChangeType(TREE_CHANGED); // 1. Save item and subtree OpAutoArray<GenericTreeModelItem*> to_be_moved (OP_NEWA(GenericTreeModelItem*, count)); if (!to_be_moved.get()) return; for(INT32 j = 0; j < count; j++) { to_be_moved[j] = m_items.Get(index + j); } // 2. Remove the subtree if (broadcast) BroadcastSubtreeRemoving(parent ? parent->GetIndex() : -1, index, subtree_size); if(parent) UpdateSubtreeSizes(parent, -count); m_items.Remove(index,count); if (broadcast) BroadcastSubtreeRemoved(parent ? parent->GetIndex() : -1, index, subtree_size); // 3. Insert it in proper position,update parent of item if needed // NOTICE: index of new_previous and new_parent may have changed! dont use previous_index and parent_index here INT32 insert_pos = new_previous ? new_previous->GetIndex() + new_previous->GetSubtreeSize() + 1 : new_parent ? new_parent->GetIndex() + 1 : 0; for(INT32 i=0; i<count; i++) { m_items.Insert(insert_pos + i, to_be_moved[i]); } item->SetGenericParentItem(new_parent); if(new_parent) UpdateSubtreeSizes(new_parent, count); if(broadcast) { for(INT32 i=0; i<count; i++) BroadcastItemAdded(insert_pos + i); } }