• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_ptr.h"
11 #include "base/memory/scoped_vector.h"
12 #include "base/observer_list.h"
13 #include "ui/base/models/list_model_observer.h"
14 
15 namespace ui {
16 
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
19 // RemoveAt.
20 template <class ItemType>
21 class ListModel {
22  public:
ListModel()23   ListModel() {}
~ListModel()24   ~ListModel() {}
25 
26   // Adds |item| at the |index| into |items_|. Takes ownership of |item|.
AddAt(size_t index,ItemType * 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);
31   }
32 
33   // Convenience function to append an item to the model.
Add(ItemType * item)34   void Add(ItemType* item) {
35     AddAt(item_count(), item);
36   }
37 
38   // Removes the item at |index| from |items_| without deleting it.
39   // Returns a scoped pointer containing the removed item.
RemoveAt(size_t index)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);
46   }
47 
48   // Removes all items from the model. This does NOT delete the items.
RemoveAll()49   void RemoveAll() {
50     size_t count = item_count();
51     items_.weak_clear();
52     NotifyItemsRemoved(0, count);
53   }
54 
55   // Removes the item at |index| from |items_| and deletes it.
DeleteAt(size_t index)56   void DeleteAt(size_t index) {
57     scoped_ptr<ItemType> item = RemoveAt(index);
58     // |item| will be deleted on destruction.
59   }
60 
61   // Removes and deletes all items from the model.
DeleteAll()62   void DeleteAll() {
63     ScopedVector<ItemType> to_be_deleted(items_.Pass());
64     NotifyItemsRemoved(0, to_be_deleted.size());
65   }
66 
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.
Move(size_t index,size_t target_index)69   void Move(size_t index, size_t target_index) {
70     DCHECK_LT(index, item_count());
71     DCHECK_LT(target_index, item_count());
72 
73     if (index == target_index)
74       return;
75 
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);
80   }
81 
AddObserver(ListModelObserver * observer)82   void AddObserver(ListModelObserver* observer) {
83     observers_.AddObserver(observer);
84   }
85 
RemoveObserver(ListModelObserver * observer)86   void RemoveObserver(ListModelObserver* observer) {
87     observers_.RemoveObserver(observer);
88   }
89 
NotifyItemsAdded(size_t start,size_t count)90   void NotifyItemsAdded(size_t start, size_t count) {
91     FOR_EACH_OBSERVER(ListModelObserver,
92                       observers_,
93                       ListItemsAdded(start, count));
94   }
95 
NotifyItemsRemoved(size_t start,size_t count)96   void NotifyItemsRemoved(size_t start, size_t count) {
97     FOR_EACH_OBSERVER(ListModelObserver,
98                       observers_,
99                       ListItemsRemoved(start, count));
100   }
101 
NotifyItemMoved(size_t index,size_t target_index)102   void NotifyItemMoved(size_t index, size_t target_index) {
103     FOR_EACH_OBSERVER(ListModelObserver,
104                       observers_,
105                       ListItemMoved(index, target_index));
106   }
107 
NotifyItemsChanged(size_t start,size_t count)108   void NotifyItemsChanged(size_t start, size_t count) {
109     FOR_EACH_OBSERVER(ListModelObserver,
110                       observers_,
111                       ListItemsChanged(start, count));
112   }
113 
item_count()114   size_t item_count() const { return items_.size(); }
115 
GetItemAt(size_t index)116   const ItemType* GetItemAt(size_t index) const {
117     DCHECK_LT(index, item_count());
118     return items_[index];
119   }
GetItemAt(size_t index)120   ItemType* GetItemAt(size_t index) {
121     return const_cast<ItemType*>(
122         const_cast<const ListModel<ItemType>*>(this)->GetItemAt(index));
123   }
124 
125  private:
126   ScopedVector<ItemType> items_;
127   ObserverList<ListModelObserver> observers_;
128 
129   DISALLOW_COPY_AND_ASSIGN(ListModel<ItemType>);
130 };
131 
132 }  // namespace ui
133 
134 #endif  // UI_BASE_MODELS_LIST_MODEL_H_
135