Home | History | Annotate | Download | only in models
      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