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.
5 #ifndef UI_BASE_MODELS_LIST_MODEL_H_
6 #define UI_BASE_MODELS_LIST_MODEL_H_
8 #include "base/basictypes.h"
9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/memory/scoped_vector.h"
12 #include "base/observer_list.h"
13 #include "ui/base/models/list_model_observer.h"
17 // A list model that manages a list of ItemType pointers. Items added to the
18 // model are owned by the model. An item can be taken out of the model by
20 template <class ItemType
>
26 // Adds |item| at the |index| into |items_|. Takes ownership of |item|.
27 void AddAt(size_t index
, ItemType
* item
) {
28 DCHECK_LE(index
, item_count());
29 items_
.insert(items_
.begin() + index
, item
);
30 NotifyItemsAdded(index
, 1);
33 // Convenience function to append an item to the model.
34 void Add(ItemType
* item
) {
35 AddAt(item_count(), item
);
38 // Removes the item at |index| from |items_| without deleting it.
39 // Returns a scoped pointer containing the removed item.
40 scoped_ptr
<ItemType
> RemoveAt(size_t index
) {
41 DCHECK_LT(index
, item_count());
42 ItemType
* item
= items_
[index
];
43 items_
.weak_erase(items_
.begin() + index
);
44 NotifyItemsRemoved(index
, 1);
45 return make_scoped_ptr
<ItemType
>(item
);
48 // Removes all items from the model. This does NOT delete the items.
50 size_t count
= item_count();
52 NotifyItemsRemoved(0, count
);
55 // Removes the item at |index| from |items_| and deletes it.
56 void DeleteAt(size_t index
) {
57 scoped_ptr
<ItemType
> item
= RemoveAt(index
);
58 // |item| will be deleted on destruction.
61 // Removes and deletes all items from the model.
63 ScopedVector
<ItemType
> to_be_deleted(items_
.Pass());
64 NotifyItemsRemoved(0, to_be_deleted
.size());
67 // Moves the item at |index| to |target_index|. |target_index| is in terms
68 // of the model *after* the item at |index| is removed.
69 void Move(size_t index
, size_t target_index
) {
70 DCHECK_LT(index
, item_count());
71 DCHECK_LT(target_index
, item_count());
73 if (index
== target_index
)
76 ItemType
* item
= items_
[index
];
77 items_
.weak_erase(items_
.begin() + index
);
78 items_
.insert(items_
.begin() + target_index
, item
);
79 NotifyItemMoved(index
, target_index
);
82 void AddObserver(ListModelObserver
* observer
) {
83 observers_
.AddObserver(observer
);
86 void RemoveObserver(ListModelObserver
* observer
) {
87 observers_
.RemoveObserver(observer
);
90 void NotifyItemsAdded(size_t start
, size_t count
) {
91 FOR_EACH_OBSERVER(ListModelObserver
,
93 ListItemsAdded(start
, count
));
96 void NotifyItemsRemoved(size_t start
, size_t count
) {
97 FOR_EACH_OBSERVER(ListModelObserver
,
99 ListItemsRemoved(start
, count
));
102 void NotifyItemMoved(size_t index
, size_t target_index
) {
103 FOR_EACH_OBSERVER(ListModelObserver
,
105 ListItemMoved(index
, target_index
));
108 void NotifyItemsChanged(size_t start
, size_t count
) {
109 FOR_EACH_OBSERVER(ListModelObserver
,
111 ListItemsChanged(start
, count
));
114 size_t item_count() const { return items_
.size(); }
116 const ItemType
* GetItemAt(size_t index
) const {
117 DCHECK_LT(index
, item_count());
118 return items_
[index
];
120 ItemType
* GetItemAt(size_t index
) {
121 return const_cast<ItemType
*>(
122 const_cast<const ListModel
<ItemType
>*>(this)->GetItemAt(index
));
125 // Iteration interface.
126 typename ScopedVector
<ItemType
>::iterator
begin() { return items_
.begin(); }
127 typename ScopedVector
<ItemType
>::const_iterator
begin() const {
128 return items_
.begin();
130 typename ScopedVector
<ItemType
>::iterator
end() { return items_
.end(); }
131 typename ScopedVector
<ItemType
>::const_iterator
end() const {
136 ScopedVector
<ItemType
> items_
;
137 ObserverList
<ListModelObserver
> observers_
;
139 DISALLOW_COPY_AND_ASSIGN(ListModel
<ItemType
>);
144 #endif // UI_BASE_MODELS_LIST_MODEL_H_