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_TREE_NODE_MODEL_H_ 6 #define UI_BASE_MODELS_TREE_NODE_MODEL_H_ 7 8 #include <algorithm> 9 #include <vector> 10 11 #include "base/basictypes.h" 12 #include "base/compiler_specific.h" 13 #include "base/logging.h" 14 #include "base/memory/scoped_ptr.h" 15 #include "base/memory/scoped_vector.h" 16 #include "base/observer_list.h" 17 #include "base/strings/string16.h" 18 #include "ui/base/models/tree_model.h" 19 20 namespace ui { 21 22 // TreeNodeModel and TreeNodes provide an implementation of TreeModel around 23 // TreeNodes. 24 // 25 // TreeNodes own their children, so that deleting a node deletes all 26 // descendants. 27 // 28 // TreeNodes do NOT maintain a pointer back to the model. As such, if you 29 // are using TreeNodes with a TreeNodeModel you will need to notify the observer 30 // yourself any time you make any change directly to the TreeNodes. For example, 31 // if you directly invoke set_title on a node it does not notify the observer, 32 // you will need to do it yourself. This includes the following methods: Add, 33 // Remove and set_title. TreeNodeModel provides cover methods that mutate the 34 // TreeNodes and notify the observer. If you are using TreeNodes with a 35 // TreeNodeModel use the cover methods to save yourself the headache. 36 // 37 // The following example creates a TreeNode with two children and then 38 // creates a TreeNodeModel from it: 39 // 40 // TreeNodeWithValue<int>* root = new TreeNodeWithValue<int>(); 41 // root->Add(new TreeNodeWithValue<int>(ASCIIToUTF16("child 1"), 0)); 42 // root->Add(new TreeNodeWithValue<int>(ASCIIToUTF16("child 2"), 1)); 43 // TreeNodeModel<TreeNodeWithValue<int> > model(root); 44 // 45 // Two variants of TreeNode are provided here: 46 // 47 // . TreeNode itself is intended for subclassing. It has one type parameter 48 // that corresponds to the type of the node. When subclassing use your class 49 // name as the type parameter, eg: 50 // class MyTreeNode : public TreeNode<MyTreeNode> . 51 // . TreeNodeWithValue is a trivial subclass of TreeNode that has one type 52 // type parameter: a value type that is associated with the node. 53 // 54 // Which you use depends upon the situation. If you want to subclass and add 55 // methods, then use TreeNode. If you don't need any extra methods and just 56 // want to associate a value with each node, then use TreeNodeWithValue. 57 // 58 // Regardless of which TreeNode you use, if you are using the nodes with a 59 // TreeView take care to notify the observer when mutating the nodes. 60 61 // TreeNode ------------------------------------------------------------------- 62 63 template <class NodeType> 64 class TreeNode : public TreeModelNode { 65 public: 66 TreeNode() : parent_(NULL) {} 67 68 explicit TreeNode(const base::string16& title) 69 : title_(title), parent_(NULL) {} 70 71 virtual ~TreeNode() {} 72 73 // Adds |node| as a child of this node, at |index|. 74 virtual void Add(NodeType* node, int index) { 75 DCHECK(node); 76 DCHECK_GE(index, 0); 77 DCHECK_LE(index, child_count()); 78 // If |node| has a parent, remove it from its parent. 79 NodeType* parent = node->parent_; 80 if (parent) 81 parent->Remove(node); 82 node->parent_ = static_cast<NodeType*>(this); 83 children_.insert(children_.begin() + index, node); 84 } 85 86 // Removes |node| from this node and returns it. It's up to the caller to 87 // delete it. 88 virtual NodeType* Remove(NodeType* node) { 89 typename std::vector<NodeType*>::iterator i = 90 std::find(children_.begin(), children_.end(), node); 91 DCHECK(i != children_.end()); 92 node->parent_ = NULL; 93 children_.weak_erase(i); 94 return node; 95 } 96 97 // Removes all the children from this node. This does NOT delete the nodes. 98 void RemoveAll() { 99 for (size_t i = 0; i < children_.size(); ++i) 100 children_[i]->parent_ = NULL; 101 children_.weak_clear(); 102 } 103 104 // Removes all existing children without deleting the nodes and adds all nodes 105 // contained in |children| into this node as children. 106 void SetChildren(const std::vector<NodeType*>& children) { 107 RemoveAll(); 108 for (size_t i = 0; i < children.size(); ++i) 109 Add(children[i], static_cast<int>(i)); 110 } 111 112 // Returns the parent node, or NULL if this is the root node. 113 const NodeType* parent() const { return parent_; } 114 NodeType* parent() { return parent_; } 115 116 // Returns true if this is the root node. 117 bool is_root() const { return parent_ == NULL; } 118 119 // Returns the number of children. 120 int child_count() const { return static_cast<int>(children_.size()); } 121 122 // Returns true if this node has no children. 123 bool empty() const { return children_.empty(); } 124 125 // Returns the number of all nodes in the subtree rooted at this node, 126 // including this node. 127 int GetTotalNodeCount() const { 128 int count = 1; // Start with one to include the node itself. 129 for (size_t i = 0; i < children_.size(); ++i) 130 count += children_[i]->GetTotalNodeCount(); 131 return count; 132 } 133 134 // Returns the node at |index|. 135 const NodeType* GetChild(int index) const { 136 DCHECK_GE(index, 0); 137 DCHECK_LT(index, child_count()); 138 return children_[index]; 139 } 140 NodeType* GetChild(int index) { 141 return const_cast<NodeType*>( 142 static_cast<const NodeType&>(*this).GetChild(index)); 143 } 144 145 // Returns the index of |node|, or -1 if |node| is not a child of this. 146 int GetIndexOf(const NodeType* node) const { 147 DCHECK(node); 148 typename std::vector<NodeType*>::const_iterator i = 149 std::find(children_.begin(), children_.end(), node); 150 return i != children_.end() ? static_cast<int>(i - children_.begin()) : -1; 151 } 152 153 // Sets the title of the node. 154 virtual void SetTitle(const base::string16& title) { title_ = title; } 155 156 // TreeModelNode: 157 virtual const base::string16& GetTitle() const OVERRIDE { return title_; } 158 159 // Returns true if this == ancestor, or one of this nodes parents is 160 // ancestor. 161 bool HasAncestor(const NodeType* ancestor) const { 162 if (ancestor == this) 163 return true; 164 if (!ancestor) 165 return false; 166 return parent_ ? parent_->HasAncestor(ancestor) : false; 167 } 168 169 protected: 170 std::vector<NodeType*>& children() { return children_.get(); } 171 172 private: 173 // Title displayed in the tree. 174 base::string16 title_; 175 176 // This node's parent. 177 NodeType* parent_; 178 179 // This node's children. 180 ScopedVector<NodeType> children_; 181 182 DISALLOW_COPY_AND_ASSIGN(TreeNode); 183 }; 184 185 // TreeNodeWithValue ---------------------------------------------------------- 186 187 template <class ValueType> 188 class TreeNodeWithValue : public TreeNode< TreeNodeWithValue<ValueType> > { 189 public: 190 TreeNodeWithValue() {} 191 192 explicit TreeNodeWithValue(const ValueType& value) 193 : ParentType(base::string16()), value(value) {} 194 195 TreeNodeWithValue(const base::string16& title, const ValueType& value) 196 : ParentType(title), value(value) {} 197 198 ValueType value; 199 200 private: 201 typedef TreeNode< TreeNodeWithValue<ValueType> > ParentType; 202 203 DISALLOW_COPY_AND_ASSIGN(TreeNodeWithValue); 204 }; 205 206 // TreeNodeModel -------------------------------------------------------------- 207 208 // TreeModel implementation intended to be used with TreeNodes. 209 template <class NodeType> 210 class TreeNodeModel : public TreeModel { 211 public: 212 // Creates a TreeNodeModel with the specified root node. The root is owned 213 // by the TreeNodeModel. 214 explicit TreeNodeModel(NodeType* root) : root_(root) {} 215 virtual ~TreeNodeModel() {} 216 217 NodeType* AsNode(TreeModelNode* model_node) { 218 return static_cast<NodeType*>(model_node); 219 } 220 221 void Add(NodeType* parent, NodeType* node, int index) { 222 DCHECK(parent && node); 223 parent->Add(node, index); 224 NotifyObserverTreeNodesAdded(parent, index, 1); 225 } 226 227 NodeType* Remove(NodeType* parent, NodeType* node) { 228 DCHECK(parent); 229 int index = parent->GetIndexOf(node); 230 NodeType* delete_node = parent->Remove(node); 231 NotifyObserverTreeNodesRemoved(parent, index, 1); 232 return delete_node; 233 } 234 235 void NotifyObserverTreeNodesAdded(NodeType* parent, int start, int count) { 236 FOR_EACH_OBSERVER(TreeModelObserver, 237 observer_list_, 238 TreeNodesAdded(this, parent, start, count)); 239 } 240 241 void NotifyObserverTreeNodesRemoved(NodeType* parent, int start, int count) { 242 FOR_EACH_OBSERVER(TreeModelObserver, 243 observer_list_, 244 TreeNodesRemoved(this, parent, start, count)); 245 } 246 247 void NotifyObserverTreeNodeChanged(TreeModelNode* node) { 248 FOR_EACH_OBSERVER(TreeModelObserver, 249 observer_list_, 250 TreeNodeChanged(this, node)); 251 } 252 253 // TreeModel: 254 virtual NodeType* GetRoot() OVERRIDE { 255 return root_.get(); 256 } 257 258 virtual int GetChildCount(TreeModelNode* parent) OVERRIDE { 259 DCHECK(parent); 260 return AsNode(parent)->child_count(); 261 } 262 263 virtual NodeType* GetChild(TreeModelNode* parent, int index) OVERRIDE { 264 DCHECK(parent); 265 return AsNode(parent)->GetChild(index); 266 } 267 268 virtual int GetIndexOf(TreeModelNode* parent, TreeModelNode* child) OVERRIDE { 269 DCHECK(parent); 270 return AsNode(parent)->GetIndexOf(AsNode(child)); 271 } 272 273 virtual TreeModelNode* GetParent(TreeModelNode* node) OVERRIDE { 274 DCHECK(node); 275 return AsNode(node)->parent(); 276 } 277 278 virtual void AddObserver(TreeModelObserver* observer) OVERRIDE { 279 observer_list_.AddObserver(observer); 280 } 281 282 virtual void RemoveObserver(TreeModelObserver* observer) OVERRIDE { 283 observer_list_.RemoveObserver(observer); 284 } 285 286 virtual void SetTitle(TreeModelNode* node, 287 const base::string16& title) OVERRIDE { 288 DCHECK(node); 289 AsNode(node)->SetTitle(title); 290 NotifyObserverTreeNodeChanged(node); 291 } 292 293 private: 294 // The observers. 295 ObserverList<TreeModelObserver> observer_list_; 296 297 // The root. 298 scoped_ptr<NodeType> root_; 299 300 DISALLOW_COPY_AND_ASSIGN(TreeNodeModel); 301 }; 302 303 } // namespace ui 304 305 #endif // UI_BASE_MODELS_TREE_NODE_MODEL_H_ 306