1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef UI_BASE_MODELS_LIST_MODEL_H_ 6 #define UI_BASE_MODELS_LIST_MODEL_H_ 7 8 #include "base/basictypes.h" 9 #include "base/logging.h" 10 #include "base/memory/scoped_vector.h" 11 #include "base/observer_list.h" 12 #include "ui/base/models/list_model_observer.h" 13 14 namespace ui { 15 16 // A list model that manages a list of ItemType pointers. Items added to the 17 // model are owned by the model. An item can be taken out of the model by 18 // RemoveAt. 19 template <class ItemType> 20 class ListModel { 21 public: 22 ListModel() {} 23 ~ListModel() {} 24 25 // Adds |item| to the model at given |index|. 26 void AddAt(size_t index, ItemType* item) { 27 DCHECK_LE(index, item_count()); 28 items_.insert(items_.begin() + index, item); 29 NotifyItemsAdded(index, 1); 30 } 31 32 // Convenience function to append an item to the model. 33 void Add(ItemType* item) { 34 AddAt(item_count(), item); 35 } 36 37 // Removes an item at given |index| from the model. Note the removed item 38 // is NOT deleted and it's up to the caller to delete it. 39 ItemType* RemoveAt(size_t index) { 40 DCHECK_LT(index, item_count()); 41 ItemType* item = items_[index]; 42 items_.weak_erase(items_.begin() + index); 43 NotifyItemsRemoved(index, 1); 44 return item; 45 } 46 47 // Removes all items from the model. This does NOT delete the items. 48 void RemoveAll() { 49 size_t count = item_count(); 50 items_.weak_clear(); 51 NotifyItemsRemoved(0, count); 52 } 53 54 // Removes an item at given |index| from the model and deletes it. 55 void DeleteAt(size_t index) { 56 delete RemoveAt(index); 57 } 58 59 // Removes and deletes all items from the model. 60 void DeleteAll() { 61 ScopedVector<ItemType> to_be_deleted(items_.Pass()); 62 NotifyItemsRemoved(0, to_be_deleted.size()); 63 } 64 65 // Moves the item at |index| to |target_index|. |target_index| is in terms 66 // of the model *after* the item at |index| is removed. 67 void Move(size_t index, size_t target_index) { 68 DCHECK_LT(index, item_count()); 69 DCHECK_LT(target_index, item_count()); 70 71 if (index == target_index) 72 return; 73 74 ItemType* item = items_[index]; 75 items_.weak_erase(items_.begin() + index); 76 items_.insert(items_.begin() + target_index, item); 77 NotifyItemMoved(index, target_index); 78 } 79 80 void AddObserver(ListModelObserver* observer) { 81 observers_.AddObserver(observer); 82 } 83 84 void RemoveObserver(ListModelObserver* observer) { 85 observers_.RemoveObserver(observer); 86 } 87 88 void NotifyItemsAdded(size_t start, size_t count) { 89 FOR_EACH_OBSERVER(ListModelObserver, 90 observers_, 91 ListItemsAdded(start, count)); 92 } 93 94 void NotifyItemsRemoved(size_t start, size_t count) { 95 FOR_EACH_OBSERVER(ListModelObserver, 96 observers_, 97 ListItemsRemoved(start, count)); 98 } 99 100 void NotifyItemMoved(size_t index, size_t target_index) { 101 FOR_EACH_OBSERVER(ListModelObserver, 102 observers_, 103 ListItemMoved(index, target_index)); 104 } 105 106 void NotifyItemsChanged(size_t start, size_t count) { 107 FOR_EACH_OBSERVER(ListModelObserver, 108 observers_, 109 ListItemsChanged(start, count)); 110 } 111 112 size_t item_count() const { return items_.size(); } 113 114 const ItemType* GetItemAt(size_t index) const { 115 DCHECK_LT(index, item_count()); 116 return items_[index]; 117 } 118 ItemType* GetItemAt(size_t index) { 119 return const_cast<ItemType*>( 120 const_cast<const ListModel<ItemType>*>(this)->GetItemAt(index)); 121 } 122 123 private: 124 ScopedVector<ItemType> items_; 125 ObserverList<ListModelObserver> observers_; 126 127 DISALLOW_COPY_AND_ASSIGN(ListModel<ItemType>); 128 }; 129 130 } // namespace ui 131 132 #endif // UI_BASE_MODELS_LIST_MODEL_H_ 133