| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2006-2008 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 #include "chrome/browser/bookmarks/bookmark_folder_tree_model.h" | |
| 6 | |
| 7 #include "app/l10n_util.h" | |
| 8 #include "app/resource_bundle.h" | |
| 9 #include "chrome/browser/bookmarks/bookmark_model.h" | |
| 10 #include "grit/generated_resources.h" | |
| 11 #include "grit/theme_resources.h" | |
| 12 #include "third_party/skia/include/core/SkBitmap.h" | |
| 13 | |
| 14 BookmarkFolderTreeModel::BookmarkFolderTreeModel(BookmarkModel* model) | |
| 15 : TreeNodeModel<FolderNode>(new FolderNode(NULL)), | |
| 16 model_(model), | |
| 17 recently_bookmarked_node_(new FolderNode(NULL)), | |
| 18 search_node_(new FolderNode(NULL)) { | |
| 19 recently_bookmarked_node_->SetTitle( | |
| 20 l10n_util::GetString(IDS_BOOKMARK_TREE_RECENTLY_BOOKMARKED_NODE_TITLE)); | |
| 21 search_node_->SetTitle( | |
| 22 l10n_util::GetString(IDS_BOOKMARK_TREE_SEARCH_NODE_TITLE)); | |
| 23 if (model_->IsLoaded()) | |
| 24 AddRootChildren(); | |
| 25 model_->AddObserver(this); | |
| 26 } | |
| 27 | |
| 28 BookmarkFolderTreeModel::~BookmarkFolderTreeModel() { | |
| 29 if (model_) | |
| 30 model_->RemoveObserver(this); | |
| 31 } | |
| 32 | |
| 33 BookmarkFolderTreeModel::NodeType BookmarkFolderTreeModel::GetNodeType( | |
| 34 TreeModelNode* node) { | |
| 35 if (node == recently_bookmarked_node_) | |
| 36 return RECENTLY_BOOKMARKED; | |
| 37 if (node == search_node_) | |
| 38 return SEARCH; | |
| 39 if (node == GetRoot()) | |
| 40 return NONE; | |
| 41 return BOOKMARK; | |
| 42 } | |
| 43 | |
| 44 FolderNode* BookmarkFolderTreeModel::GetFolderNodeForBookmarkNode( | |
| 45 const BookmarkNode* node) { | |
| 46 if (!node->is_folder()) | |
| 47 return NULL; | |
| 48 | |
| 49 return GetFolderNodeForBookmarkNode(AsNode(GetRoot()), node); | |
| 50 } | |
| 51 | |
| 52 const BookmarkNode* BookmarkFolderTreeModel::TreeNodeAsBookmarkNode( | |
| 53 TreeModelNode* node) { | |
| 54 if (GetNodeType(node) != BOOKMARK) | |
| 55 return NULL; | |
| 56 return AsNode(node)->value; | |
| 57 } | |
| 58 | |
| 59 void BookmarkFolderTreeModel::Loaded(BookmarkModel* model) { | |
| 60 AddRootChildren(); | |
| 61 } | |
| 62 | |
| 63 void BookmarkFolderTreeModel::BookmarkModelBeingDeleted(BookmarkModel* model) { | |
| 64 DCHECK(model_); | |
| 65 model_->RemoveObserver(this); | |
| 66 model_ = NULL; | |
| 67 } | |
| 68 | |
| 69 void BookmarkFolderTreeModel::BookmarkNodeMoved(BookmarkModel* model, | |
| 70 const BookmarkNode* old_parent, | |
| 71 int old_index, | |
| 72 const BookmarkNode* new_parent, | |
| 73 int new_index) { | |
| 74 const BookmarkNode* moved_node = new_parent->GetChild(new_index); | |
| 75 if (!moved_node->is_folder()) | |
| 76 return; // We're only showing folders, so we can ignore this. | |
| 77 | |
| 78 FolderNode* moved_folder_node = GetFolderNodeForBookmarkNode(moved_node); | |
| 79 DCHECK(moved_folder_node); | |
| 80 int old_folder_index = | |
| 81 moved_folder_node->GetParent()->IndexOfChild(moved_folder_node); | |
| 82 Remove(moved_folder_node->GetParent(), old_folder_index); | |
| 83 int new_folder_index = CalculateIndexForChild(moved_node); | |
| 84 Add(GetFolderNodeForBookmarkNode(new_parent), new_folder_index, | |
| 85 moved_folder_node); | |
| 86 } | |
| 87 | |
| 88 void BookmarkFolderTreeModel::BookmarkNodeAdded(BookmarkModel* model, | |
| 89 const BookmarkNode* parent, | |
| 90 int index) { | |
| 91 const BookmarkNode* new_node = parent->GetChild(index); | |
| 92 if (!new_node->is_folder()) | |
| 93 return; // We're only showing folders, so we can ignore this. | |
| 94 | |
| 95 int folder_index = CalculateIndexForChild(new_node); | |
| 96 Add(GetFolderNodeForBookmarkNode(parent), folder_index, | |
| 97 CreateFolderNode(new_node)); | |
| 98 } | |
| 99 | |
| 100 void BookmarkFolderTreeModel::BookmarkNodeRemoved(BookmarkModel* model, | |
| 101 const BookmarkNode* parent, | |
| 102 int index, | |
| 103 const BookmarkNode* node) { | |
| 104 if (!node->is_folder()) | |
| 105 return; // We're only showing folders. | |
| 106 | |
| 107 FolderNode* folder_node = GetFolderNodeForBookmarkNode(parent); | |
| 108 DCHECK(folder_node); | |
| 109 for (int i = 0; i < folder_node->GetChildCount(); ++i) { | |
| 110 if (folder_node->GetChild(i)->value == node) { | |
| 111 scoped_ptr<FolderNode> removed_node(Remove(folder_node, i)); | |
| 112 return; | |
| 113 } | |
| 114 } | |
| 115 | |
| 116 // If we get here it means a folder was removed that we didn't know about, | |
| 117 // which shouldn't happen. | |
| 118 NOTREACHED(); | |
| 119 } | |
| 120 | |
| 121 void BookmarkFolderTreeModel::BookmarkNodeChanged(BookmarkModel* model, | |
| 122 const BookmarkNode* node) { | |
| 123 if (!node->is_folder()) | |
| 124 return; | |
| 125 | |
| 126 FolderNode* folder_node = GetFolderNodeForBookmarkNode(node); | |
| 127 if (!folder_node) | |
| 128 return; | |
| 129 | |
| 130 folder_node->SetTitle(node->GetTitle()); | |
| 131 FOR_EACH_OBSERVER(TreeModelObserver, | |
| 132 observer_list(), | |
| 133 TreeNodeChanged(this, folder_node)); | |
| 134 } | |
| 135 | |
| 136 void BookmarkFolderTreeModel::BookmarkNodeChildrenReordered( | |
| 137 BookmarkModel* model, | |
| 138 const BookmarkNode* node) { | |
| 139 FolderNode* folder_node = GetFolderNodeForBookmarkNode(node); | |
| 140 DCHECK(folder_node); | |
| 141 if (folder_node->GetChildCount() <= 1) | |
| 142 return; // Order won't have changed if 1 or fewer nodes. | |
| 143 | |
| 144 // Build a map between folder node and bookmark node. | |
| 145 std::map<const BookmarkNode*, FolderNode*> bn_to_folder; | |
| 146 for (int i = 0; i < folder_node->GetChildCount(); ++i) | |
| 147 bn_to_folder[folder_node->GetChild(i)->value] = folder_node->GetChild(i); | |
| 148 | |
| 149 // Remove all the folder nodes. | |
| 150 int original_count = folder_node->GetChildCount(); | |
| 151 folder_node->RemoveAll(); | |
| 152 | |
| 153 // And add them back in the new order. | |
| 154 for (int i = 0; i < node->GetChildCount(); ++i) { | |
| 155 const BookmarkNode* child = node->GetChild(i); | |
| 156 if (child->is_folder()) { | |
| 157 DCHECK(bn_to_folder.find(child) != bn_to_folder.end()); | |
| 158 folder_node->Add(folder_node->GetChildCount(), bn_to_folder[child]); | |
| 159 } | |
| 160 } | |
| 161 // The new count better match the original count, otherwise we're leaking and | |
| 162 // treeview is likely to get way out of sync. | |
| 163 DCHECK(original_count == folder_node->GetChildCount()); | |
| 164 | |
| 165 // Finally, notify observers. | |
| 166 FOR_EACH_OBSERVER(TreeModelObserver, | |
| 167 observer_list(), | |
| 168 TreeNodeChildrenReordered(this, folder_node)); | |
| 169 } | |
| 170 | |
| 171 void BookmarkFolderTreeModel::GetIcons(std::vector<SkBitmap>* icons) { | |
| 172 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | |
| 173 icons->push_back(*rb.GetBitmapNamed(IDR_BOOKMARK_MANAGER_RECENT_ICON)); | |
| 174 icons->push_back(*rb.GetBitmapNamed(IDR_BOOKMARK_MANAGER_SEARCH_ICON)); | |
| 175 } | |
| 176 | |
| 177 int BookmarkFolderTreeModel::GetIconIndex(TreeModelNode* node) { | |
| 178 if (node == recently_bookmarked_node_) | |
| 179 return 0; | |
| 180 if (node == search_node_) | |
| 181 return 1; | |
| 182 | |
| 183 // Return -1 to use the default. | |
| 184 return -1; | |
| 185 } | |
| 186 | |
| 187 void BookmarkFolderTreeModel::AddRootChildren() { | |
| 188 Add(AsNode(GetRoot()), 0, CreateFolderNode(model_->GetBookmarkBarNode())); | |
| 189 Add(AsNode(GetRoot()), 1, CreateFolderNode(model_->other_node())); | |
| 190 Add(AsNode(GetRoot()), 2, recently_bookmarked_node_); | |
| 191 Add(AsNode(GetRoot()), 3, search_node_); | |
| 192 } | |
| 193 | |
| 194 FolderNode* BookmarkFolderTreeModel::GetFolderNodeForBookmarkNode( | |
| 195 FolderNode* folder_node, | |
| 196 const BookmarkNode* node) { | |
| 197 DCHECK(node->is_folder()); | |
| 198 if (folder_node->value == node) | |
| 199 return folder_node; | |
| 200 for (int i = 0; i < folder_node->GetChildCount(); ++i) { | |
| 201 FolderNode* result = | |
| 202 GetFolderNodeForBookmarkNode(folder_node->GetChild(i), node); | |
| 203 if (result) | |
| 204 return result; | |
| 205 } | |
| 206 return NULL; | |
| 207 } | |
| 208 | |
| 209 FolderNode* BookmarkFolderTreeModel::CreateFolderNode( | |
| 210 const BookmarkNode* node) { | |
| 211 DCHECK(node->is_folder()); | |
| 212 FolderNode* folder_node = new FolderNode(node); | |
| 213 folder_node->SetTitle(node->GetTitle()); | |
| 214 | |
| 215 // And clone the children folders. | |
| 216 for (int i = 0; i < node->GetChildCount(); ++i) { | |
| 217 const BookmarkNode* child = node->GetChild(i); | |
| 218 if (child->is_folder()) | |
| 219 folder_node->Add(folder_node->GetChildCount(), CreateFolderNode(child)); | |
| 220 } | |
| 221 return folder_node; | |
| 222 } | |
| 223 | |
| 224 int BookmarkFolderTreeModel::CalculateIndexForChild(const BookmarkNode* node) { | |
| 225 const BookmarkNode* parent = node->GetParent(); | |
| 226 DCHECK(parent); | |
| 227 for (int i = 0, folder_count = 0; i < parent->GetChildCount(); ++i) { | |
| 228 const BookmarkNode* child = parent->GetChild(i); | |
| 229 if (child == node) | |
| 230 return folder_count; | |
| 231 if (child->is_folder()) | |
| 232 folder_count++; | |
| 233 } | |
| 234 NOTREACHED(); | |
| 235 return 0; | |
| 236 } | |
| OLD | NEW |