OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/bookmarks/bookmark_bar_model.h" | 5 #include "chrome/browser/bookmarks/bookmark_model.h" |
6 | 6 |
7 #include "base/gfx/png_decoder.h" | 7 #include "base/gfx/png_decoder.h" |
8 #include "chrome/browser/bookmarks/bookmark_storage.h" | 8 #include "chrome/browser/bookmarks/bookmark_storage.h" |
9 #include "chrome/browser/history/query_parser.h" | 9 #include "chrome/browser/history/query_parser.h" |
10 #include "chrome/browser/profile.h" | 10 #include "chrome/browser/profile.h" |
11 #include "chrome/common/scoped_vector.h" | 11 #include "chrome/common/scoped_vector.h" |
12 | 12 |
13 #include "generated_resources.h" | 13 #include "generated_resources.h" |
14 | 14 |
15 namespace { | 15 namespace { |
16 | 16 |
17 // Functions used for sorting. | 17 // Functions used for sorting. |
18 bool MoreRecentlyModified(BookmarkBarNode* n1, BookmarkBarNode* n2) { | 18 bool MoreRecentlyModified(BookmarkNode* n1, BookmarkNode* n2) { |
19 return n1->date_group_modified() > n2->date_group_modified(); | 19 return n1->date_group_modified() > n2->date_group_modified(); |
20 } | 20 } |
21 | 21 |
22 bool MoreRecentlyAdded(BookmarkBarNode* n1, BookmarkBarNode* n2) { | 22 bool MoreRecentlyAdded(BookmarkNode* n1, BookmarkNode* n2) { |
23 return n1->date_added() > n2->date_added(); | 23 return n1->date_added() > n2->date_added(); |
24 } | 24 } |
25 | 25 |
26 } // namespace | 26 } // namespace |
27 | 27 |
28 // BookmarkBarNode ------------------------------------------------------------ | 28 // BookmarkNode --------------------------------------------------------------- |
29 | 29 |
30 namespace { | 30 namespace { |
31 | 31 |
32 // ID for BookmarkBarNodes. | 32 // ID for BookmarkNodes. |
33 // Various places assume an invalid id if == 0, for that reason we start with 1. | 33 // Various places assume an invalid id if == 0, for that reason we start with 1. |
34 int next_id_ = 1; | 34 int next_id_ = 1; |
35 | 35 |
36 } | 36 } |
37 | 37 |
38 const SkBitmap& BookmarkBarNode::GetFavIcon() { | 38 const SkBitmap& BookmarkNode::GetFavIcon() { |
39 if (!loaded_favicon_) { | 39 if (!loaded_favicon_) { |
40 loaded_favicon_ = true; | 40 loaded_favicon_ = true; |
41 model_->LoadFavIcon(this); | 41 model_->LoadFavIcon(this); |
42 } | 42 } |
43 return favicon_; | 43 return favicon_; |
44 } | 44 } |
45 | 45 |
46 BookmarkBarNode::BookmarkBarNode(BookmarkBarModel* model, const GURL& url) | 46 BookmarkNode::BookmarkNode(BookmarkModel* model, const GURL& url) |
47 : model_(model), | 47 : model_(model), |
48 id_(next_id_++), | 48 id_(next_id_++), |
49 loaded_favicon_(false), | 49 loaded_favicon_(false), |
50 favicon_load_handle_(0), | 50 favicon_load_handle_(0), |
51 url_(url), | 51 url_(url), |
52 type_(!url.is_empty() ? history::StarredEntry::URL : | 52 type_(!url.is_empty() ? history::StarredEntry::URL : |
53 history::StarredEntry::BOOKMARK_BAR), | 53 history::StarredEntry::BOOKMARK_BAR), |
54 date_added_(Time::Now()) { | 54 date_added_(Time::Now()) { |
55 } | 55 } |
56 | 56 |
57 void BookmarkBarNode::Reset(const history::StarredEntry& entry) { | 57 void BookmarkNode::Reset(const history::StarredEntry& entry) { |
58 DCHECK(entry.type != history::StarredEntry::URL || | 58 DCHECK(entry.type != history::StarredEntry::URL || |
59 entry.url == url_); | 59 entry.url == url_); |
60 | 60 |
61 favicon_ = SkBitmap(); | 61 favicon_ = SkBitmap(); |
62 type_ = entry.type; | 62 type_ = entry.type; |
63 date_added_ = entry.date_added; | 63 date_added_ = entry.date_added; |
64 date_group_modified_ = entry.date_group_modified; | 64 date_group_modified_ = entry.date_group_modified; |
65 SetTitle(entry.title); | 65 SetTitle(entry.title); |
66 } | 66 } |
67 | 67 |
68 // BookmarkBarModel ----------------------------------------------------------- | 68 // BookmarkModel -------------------------------------------------------------- |
69 | 69 |
70 BookmarkBarModel::BookmarkBarModel(Profile* profile) | 70 BookmarkModel::BookmarkModel(Profile* profile) |
71 : profile_(profile), | 71 : profile_(profile), |
72 loaded_(false), | 72 loaded_(false), |
73 #pragma warning(suppress: 4355) // Okay to pass "this" here. | 73 #pragma warning(suppress: 4355) // Okay to pass "this" here. |
74 root_(this, GURL()), | 74 root_(this, GURL()), |
75 bookmark_bar_node_(NULL), | 75 bookmark_bar_node_(NULL), |
76 other_node_(NULL), | 76 other_node_(NULL), |
77 waiting_for_history_load_(false), | 77 waiting_for_history_load_(false), |
78 loaded_signal_(CreateEvent(NULL, TRUE, FALSE, NULL)) { | 78 loaded_signal_(CreateEvent(NULL, TRUE, FALSE, NULL)) { |
79 // Create the bookmark bar and other bookmarks folders. These always exist. | 79 // Create the bookmark bar and other bookmarks folders. These always exist. |
80 CreateBookmarkBarNode(); | 80 CreateBookmarkNode(); |
81 CreateOtherBookmarksNode(); | 81 CreateOtherBookmarksNode(); |
82 | 82 |
83 // And add them to the root. | 83 // And add them to the root. |
84 // | 84 // |
85 // WARNING: order is important here, various places assume bookmark bar then | 85 // WARNING: order is important here, various places assume bookmark bar then |
86 // other node. | 86 // other node. |
87 root_.Add(0, bookmark_bar_node_); | 87 root_.Add(0, bookmark_bar_node_); |
88 root_.Add(1, other_node_); | 88 root_.Add(1, other_node_); |
89 | 89 |
90 if (!profile_) { | 90 if (!profile_) { |
91 // Profile is null during testing. | 91 // Profile is null during testing. |
92 DoneLoading(); | 92 DoneLoading(); |
93 } | 93 } |
94 } | 94 } |
95 | 95 |
96 BookmarkBarModel::~BookmarkBarModel() { | 96 BookmarkModel::~BookmarkModel() { |
97 if (profile_ && store_.get()) { | 97 if (profile_ && store_.get()) { |
98 NotificationService::current()->RemoveObserver( | 98 NotificationService::current()->RemoveObserver( |
99 this, NOTIFY_FAVICON_CHANGED, Source<Profile>(profile_)); | 99 this, NOTIFY_FAVICON_CHANGED, Source<Profile>(profile_)); |
100 } | 100 } |
101 | 101 |
102 if (waiting_for_history_load_) { | 102 if (waiting_for_history_load_) { |
103 NotificationService::current()->RemoveObserver( | 103 NotificationService::current()->RemoveObserver( |
104 this, NOTIFY_HISTORY_LOADED, Source<Profile>(profile_)); | 104 this, NOTIFY_HISTORY_LOADED, Source<Profile>(profile_)); |
105 } | 105 } |
106 | 106 |
107 FOR_EACH_OBSERVER(BookmarkBarModelObserver, observers_, | 107 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
108 BookmarkModelBeingDeleted(this)); | 108 BookmarkModelBeingDeleted(this)); |
109 | 109 |
110 if (store_) { | 110 if (store_) { |
111 // The store maintains a reference back to us. We need to tell it we're gone | 111 // The store maintains a reference back to us. We need to tell it we're gone |
112 // so that it doesn't try and invoke a method back on us again. | 112 // so that it doesn't try and invoke a method back on us again. |
113 store_->BookmarkModelDeleted(); | 113 store_->BookmarkModelDeleted(); |
114 } | 114 } |
115 } | 115 } |
116 | 116 |
117 void BookmarkBarModel::Load() { | 117 void BookmarkModel::Load() { |
118 if (store_.get()) { | 118 if (store_.get()) { |
119 // If the store is non-null, it means Load was already invoked. Load should | 119 // If the store is non-null, it means Load was already invoked. Load should |
120 // only be invoked once. | 120 // only be invoked once. |
121 NOTREACHED(); | 121 NOTREACHED(); |
122 return; | 122 return; |
123 } | 123 } |
124 | 124 |
125 // Listen for changes to favicons so that we can update the favicon of the | 125 // Listen for changes to favicons so that we can update the favicon of the |
126 // node appropriately. | 126 // node appropriately. |
127 NotificationService::current()->AddObserver( | 127 NotificationService::current()->AddObserver( |
128 this, NOTIFY_FAVICON_CHANGED, Source<Profile>(profile_)); | 128 this, NOTIFY_FAVICON_CHANGED, Source<Profile>(profile_)); |
129 | 129 |
130 // Load the bookmarks. BookmarkStorage notifies us when done. | 130 // Load the bookmarks. BookmarkStorage notifies us when done. |
131 store_ = new BookmarkStorage(profile_, this); | 131 store_ = new BookmarkStorage(profile_, this); |
132 store_->LoadBookmarks(false); | 132 store_->LoadBookmarks(false); |
133 } | 133 } |
134 | 134 |
135 BookmarkBarNode* BookmarkBarModel::GetParentForNewNodes() { | 135 BookmarkNode* BookmarkModel::GetParentForNewNodes() { |
136 std::vector<BookmarkBarNode*> nodes; | 136 std::vector<BookmarkNode*> nodes; |
137 | 137 |
138 GetMostRecentlyModifiedGroupNodes(&root_, 1, &nodes); | 138 GetMostRecentlyModifiedGroupNodes(&root_, 1, &nodes); |
139 return nodes.empty() ? bookmark_bar_node_ : nodes[0]; | 139 return nodes.empty() ? bookmark_bar_node_ : nodes[0]; |
140 } | 140 } |
141 | 141 |
142 std::vector<BookmarkBarNode*> BookmarkBarModel::GetMostRecentlyModifiedGroups( | 142 std::vector<BookmarkNode*> BookmarkModel::GetMostRecentlyModifiedGroups( |
143 size_t max_count) { | 143 size_t max_count) { |
144 std::vector<BookmarkBarNode*> nodes; | 144 std::vector<BookmarkNode*> nodes; |
145 GetMostRecentlyModifiedGroupNodes(&root_, max_count, &nodes); | 145 GetMostRecentlyModifiedGroupNodes(&root_, max_count, &nodes); |
146 | 146 |
147 if (nodes.size() < max_count) { | 147 if (nodes.size() < max_count) { |
148 // Add the bookmark bar and other nodes if there is space. | 148 // Add the bookmark bar and other nodes if there is space. |
149 if (find(nodes.begin(), nodes.end(), bookmark_bar_node_) == nodes.end()) | 149 if (find(nodes.begin(), nodes.end(), bookmark_bar_node_) == nodes.end()) |
150 nodes.push_back(bookmark_bar_node_); | 150 nodes.push_back(bookmark_bar_node_); |
151 | 151 |
152 if (nodes.size() < max_count && | 152 if (nodes.size() < max_count && |
153 find(nodes.begin(), nodes.end(), other_node_) == nodes.end()) { | 153 find(nodes.begin(), nodes.end(), other_node_) == nodes.end()) { |
154 nodes.push_back(other_node_); | 154 nodes.push_back(other_node_); |
155 } | 155 } |
156 } | 156 } |
157 return nodes; | 157 return nodes; |
158 } | 158 } |
159 | 159 |
160 void BookmarkBarModel::GetMostRecentlyAddedEntries( | 160 void BookmarkModel::GetMostRecentlyAddedEntries( |
161 size_t count, | 161 size_t count, |
162 std::vector<BookmarkBarNode*>* nodes) { | 162 std::vector<BookmarkNode*>* nodes) { |
163 AutoLock url_lock(url_lock_); | 163 AutoLock url_lock(url_lock_); |
164 for (NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.begin(); | 164 for (NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.begin(); |
165 i != nodes_ordered_by_url_set_.end(); ++i) { | 165 i != nodes_ordered_by_url_set_.end(); ++i) { |
166 std::vector<BookmarkBarNode*>::iterator insert_position = | 166 std::vector<BookmarkNode*>::iterator insert_position = |
167 std::upper_bound(nodes->begin(), nodes->end(), *i, &MoreRecentlyAdded); | 167 std::upper_bound(nodes->begin(), nodes->end(), *i, &MoreRecentlyAdded); |
168 if (nodes->size() < count || insert_position != nodes->end()) { | 168 if (nodes->size() < count || insert_position != nodes->end()) { |
169 nodes->insert(insert_position, *i); | 169 nodes->insert(insert_position, *i); |
170 while (nodes->size() > count) | 170 while (nodes->size() > count) |
171 nodes->pop_back(); | 171 nodes->pop_back(); |
172 } | 172 } |
173 } | 173 } |
174 } | 174 } |
175 | 175 |
176 void BookmarkBarModel::GetBookmarksMatchingText( | 176 void BookmarkModel::GetBookmarksMatchingText( |
177 const std::wstring& text, | 177 const std::wstring& text, |
178 size_t max_count, | 178 size_t max_count, |
179 std::vector<TitleMatch>* matches) { | 179 std::vector<TitleMatch>* matches) { |
180 QueryParser parser; | 180 QueryParser parser; |
181 ScopedVector<QueryNode> query_nodes; | 181 ScopedVector<QueryNode> query_nodes; |
182 parser.ParseQuery(text, &query_nodes.get()); | 182 parser.ParseQuery(text, &query_nodes.get()); |
183 if (query_nodes.empty()) | 183 if (query_nodes.empty()) |
184 return; | 184 return; |
185 | 185 |
186 AutoLock url_lock(url_lock_); | 186 AutoLock url_lock(url_lock_); |
187 Snippet::MatchPositions match_position; | 187 Snippet::MatchPositions match_position; |
188 for (NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.begin(); | 188 for (NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.begin(); |
189 i != nodes_ordered_by_url_set_.end(); ++i) { | 189 i != nodes_ordered_by_url_set_.end(); ++i) { |
190 if (parser.DoesQueryMatch((*i)->GetTitle(), query_nodes.get(), | 190 if (parser.DoesQueryMatch((*i)->GetTitle(), query_nodes.get(), |
191 &match_position)) { | 191 &match_position)) { |
192 matches->push_back(TitleMatch()); | 192 matches->push_back(TitleMatch()); |
193 matches->back().node = *i; | 193 matches->back().node = *i; |
194 matches->back().match_positions.swap(match_position); | 194 matches->back().match_positions.swap(match_position); |
195 if (matches->size() == max_count) | 195 if (matches->size() == max_count) |
196 break; | 196 break; |
197 } | 197 } |
198 } | 198 } |
199 } | 199 } |
200 | 200 |
201 void BookmarkBarModel::Remove(BookmarkBarNode* parent, int index) { | 201 void BookmarkModel::Remove(BookmarkNode* parent, int index) { |
202 if (!loaded_ || !IsValidIndex(parent, index, false) || parent == &root_) { | 202 if (!loaded_ || !IsValidIndex(parent, index, false) || parent == &root_) { |
203 NOTREACHED(); | 203 NOTREACHED(); |
204 return; | 204 return; |
205 } | 205 } |
206 RemoveAndDeleteNode(parent->GetChild(index)); | 206 RemoveAndDeleteNode(parent->GetChild(index)); |
207 } | 207 } |
208 | 208 |
209 void BookmarkBarModel::Move(BookmarkBarNode* node, | 209 void BookmarkModel::Move(BookmarkNode* node, |
210 BookmarkBarNode* new_parent, | 210 BookmarkNode* new_parent, |
211 int index) { | 211 int index) { |
212 if (!loaded_ || !node || !IsValidIndex(new_parent, index, true) || | 212 if (!loaded_ || !node || !IsValidIndex(new_parent, index, true) || |
213 new_parent == &root_ || node == &root_ || node == bookmark_bar_node_ || | 213 new_parent == &root_ || node == &root_ || node == bookmark_bar_node_ || |
214 node == other_node_) { | 214 node == other_node_) { |
215 NOTREACHED(); | 215 NOTREACHED(); |
216 return; | 216 return; |
217 } | 217 } |
218 | 218 |
219 if (new_parent->HasAncestor(node)) { | 219 if (new_parent->HasAncestor(node)) { |
220 // Can't make an ancestor of the node be a child of the node. | 220 // Can't make an ancestor of the node be a child of the node. |
221 NOTREACHED(); | 221 NOTREACHED(); |
222 return; | 222 return; |
223 } | 223 } |
224 | 224 |
225 SetDateGroupModified(new_parent, Time::Now()); | 225 SetDateGroupModified(new_parent, Time::Now()); |
226 | 226 |
227 BookmarkBarNode* old_parent = node->GetParent(); | 227 BookmarkNode* old_parent = node->GetParent(); |
228 int old_index = old_parent->IndexOfChild(node); | 228 int old_index = old_parent->IndexOfChild(node); |
229 | 229 |
230 if (old_parent == new_parent && | 230 if (old_parent == new_parent && |
231 (index == old_index || index == old_index + 1)) { | 231 (index == old_index || index == old_index + 1)) { |
232 // Node is already in this position, nothing to do. | 232 // Node is already in this position, nothing to do. |
233 return; | 233 return; |
234 } | 234 } |
235 | 235 |
236 if (old_parent == new_parent && index > old_index) | 236 if (old_parent == new_parent && index > old_index) |
237 index--; | 237 index--; |
238 new_parent->Add(index, node); | 238 new_parent->Add(index, node); |
239 | 239 |
240 if (store_.get()) | 240 if (store_.get()) |
241 store_->ScheduleSave(); | 241 store_->ScheduleSave(); |
242 | 242 |
243 FOR_EACH_OBSERVER(BookmarkBarModelObserver, observers_, | 243 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
244 BookmarkNodeMoved(this, old_parent, old_index, | 244 BookmarkNodeMoved(this, old_parent, old_index, |
245 new_parent, index)); | 245 new_parent, index)); |
246 } | 246 } |
247 | 247 |
248 void BookmarkBarModel::SetTitle(BookmarkBarNode* node, | 248 void BookmarkModel::SetTitle(BookmarkNode* node, |
249 const std::wstring& title) { | 249 const std::wstring& title) { |
250 if (!node) { | 250 if (!node) { |
251 NOTREACHED(); | 251 NOTREACHED(); |
252 return; | 252 return; |
253 } | 253 } |
254 if (node->GetTitle() == title) | 254 if (node->GetTitle() == title) |
255 return; | 255 return; |
256 | 256 |
257 node->SetTitle(title); | 257 node->SetTitle(title); |
258 | 258 |
259 if (store_.get()) | 259 if (store_.get()) |
260 store_->ScheduleSave(); | 260 store_->ScheduleSave(); |
261 | 261 |
262 FOR_EACH_OBSERVER(BookmarkBarModelObserver, observers_, | 262 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
263 BookmarkNodeChanged(this, node)); | 263 BookmarkNodeChanged(this, node)); |
264 } | 264 } |
265 | 265 |
266 BookmarkBarNode* BookmarkBarModel::GetNodeByURL(const GURL& url) { | 266 BookmarkNode* BookmarkModel::GetNodeByURL(const GURL& url) { |
267 AutoLock url_lock(url_lock_); | 267 AutoLock url_lock(url_lock_); |
268 BookmarkBarNode tmp_node(this, url); | 268 BookmarkNode tmp_node(this, url); |
269 NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.find(&tmp_node); | 269 NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.find(&tmp_node); |
270 return (i != nodes_ordered_by_url_set_.end()) ? *i : NULL; | 270 return (i != nodes_ordered_by_url_set_.end()) ? *i : NULL; |
271 } | 271 } |
272 | 272 |
273 void BookmarkBarModel::GetBookmarks(std::vector<GURL>* urls) { | 273 void BookmarkModel::GetBookmarks(std::vector<GURL>* urls) { |
274 AutoLock url_lock(url_lock_); | 274 AutoLock url_lock(url_lock_); |
275 for (NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.begin(); | 275 for (NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.begin(); |
276 i != nodes_ordered_by_url_set_.end(); ++i) { | 276 i != nodes_ordered_by_url_set_.end(); ++i) { |
277 urls->push_back((*i)->GetURL()); | 277 urls->push_back((*i)->GetURL()); |
278 } | 278 } |
279 } | 279 } |
280 | 280 |
281 BookmarkBarNode* BookmarkBarModel::GetNodeByID(int id) { | 281 BookmarkNode* BookmarkModel::GetNodeByID(int id) { |
282 // TODO(sky): TreeNode needs a method that visits all nodes using a predicate. | 282 // TODO(sky): TreeNode needs a method that visits all nodes using a predicate. |
283 return GetNodeByID(&root_, id); | 283 return GetNodeByID(&root_, id); |
284 } | 284 } |
285 | 285 |
286 BookmarkBarNode* BookmarkBarModel::AddGroup( | 286 BookmarkNode* BookmarkModel::AddGroup( |
287 BookmarkBarNode* parent, | 287 BookmarkNode* parent, |
288 int index, | 288 int index, |
289 const std::wstring& title) { | 289 const std::wstring& title) { |
290 if (!loaded_ || parent == &root_ || !IsValidIndex(parent, index, true)) { | 290 if (!loaded_ || parent == &root_ || !IsValidIndex(parent, index, true)) { |
291 // Can't add to the root. | 291 // Can't add to the root. |
292 NOTREACHED(); | 292 NOTREACHED(); |
293 return NULL; | 293 return NULL; |
294 } | 294 } |
295 | 295 |
296 BookmarkBarNode* new_node = new BookmarkBarNode(this, GURL()); | 296 BookmarkNode* new_node = new BookmarkNode(this, GURL()); |
297 new_node->SetTitle(title); | 297 new_node->SetTitle(title); |
298 new_node->type_ = history::StarredEntry::USER_GROUP; | 298 new_node->type_ = history::StarredEntry::USER_GROUP; |
299 | 299 |
300 return AddNode(parent, index, new_node); | 300 return AddNode(parent, index, new_node); |
301 } | 301 } |
302 | 302 |
303 BookmarkBarNode* BookmarkBarModel::AddURL(BookmarkBarNode* parent, | 303 BookmarkNode* BookmarkModel::AddURL(BookmarkNode* parent, |
304 int index, | 304 int index, |
305 const std::wstring& title, | 305 const std::wstring& title, |
306 const GURL& url) { | 306 const GURL& url) { |
307 return AddURLWithCreationTime(parent, index, title, url, Time::Now()); | 307 return AddURLWithCreationTime(parent, index, title, url, Time::Now()); |
308 } | 308 } |
309 | 309 |
310 BookmarkBarNode* BookmarkBarModel::AddURLWithCreationTime( | 310 BookmarkNode* BookmarkModel::AddURLWithCreationTime( |
311 BookmarkBarNode* parent, | 311 BookmarkNode* parent, |
312 int index, | 312 int index, |
313 const std::wstring& title, | 313 const std::wstring& title, |
314 const GURL& url, | 314 const GURL& url, |
315 const Time& creation_time) { | 315 const Time& creation_time) { |
316 if (!loaded_ || !url.is_valid() || parent == &root_ || | 316 if (!loaded_ || !url.is_valid() || parent == &root_ || |
317 !IsValidIndex(parent, index, true)) { | 317 !IsValidIndex(parent, index, true)) { |
318 NOTREACHED(); | 318 NOTREACHED(); |
319 return NULL; | 319 return NULL; |
320 } | 320 } |
321 | 321 |
322 BookmarkBarNode* existing_node = GetNodeByURL(url); | 322 BookmarkNode* existing_node = GetNodeByURL(url); |
323 if (existing_node) { | 323 if (existing_node) { |
324 Move(existing_node, parent, index); | 324 Move(existing_node, parent, index); |
325 SetTitle(existing_node, title); | 325 SetTitle(existing_node, title); |
326 return existing_node; | 326 return existing_node; |
327 } | 327 } |
328 | 328 |
329 SetDateGroupModified(parent, creation_time); | 329 SetDateGroupModified(parent, creation_time); |
330 | 330 |
331 BookmarkBarNode* new_node = new BookmarkBarNode(this, url); | 331 BookmarkNode* new_node = new BookmarkNode(this, url); |
332 new_node->SetTitle(title); | 332 new_node->SetTitle(title); |
333 new_node->date_added_ = creation_time; | 333 new_node->date_added_ = creation_time; |
334 new_node->type_ = history::StarredEntry::URL; | 334 new_node->type_ = history::StarredEntry::URL; |
335 | 335 |
336 AutoLock url_lock(url_lock_); | 336 AutoLock url_lock(url_lock_); |
337 nodes_ordered_by_url_set_.insert(new_node); | 337 nodes_ordered_by_url_set_.insert(new_node); |
338 | 338 |
339 return AddNode(parent, index, new_node); | 339 return AddNode(parent, index, new_node); |
340 } | 340 } |
341 | 341 |
342 void BookmarkBarModel::SetURLStarred(const GURL& url, | 342 void BookmarkModel::SetURLStarred(const GURL& url, |
343 const std::wstring& title, | 343 const std::wstring& title, |
344 bool is_starred) { | 344 bool is_starred) { |
345 BookmarkBarNode* node = GetNodeByURL(url); | 345 BookmarkNode* node = GetNodeByURL(url); |
346 if (is_starred && !node) { | 346 if (is_starred && !node) { |
347 // Add the url. | 347 // Add the url. |
348 BookmarkBarNode* parent = GetParentForNewNodes(); | 348 BookmarkNode* parent = GetParentForNewNodes(); |
349 AddURL(parent, parent->GetChildCount(), title, url); | 349 AddURL(parent, parent->GetChildCount(), title, url); |
350 } else if (!is_starred && node) { | 350 } else if (!is_starred && node) { |
351 Remove(node->GetParent(), node->GetParent()->IndexOfChild(node)); | 351 Remove(node->GetParent(), node->GetParent()->IndexOfChild(node)); |
352 } | 352 } |
353 } | 353 } |
354 | 354 |
355 void BookmarkBarModel::ResetDateGroupModified(BookmarkBarNode* node) { | 355 void BookmarkModel::ResetDateGroupModified(BookmarkNode* node) { |
356 SetDateGroupModified(node, Time()); | 356 SetDateGroupModified(node, Time()); |
357 } | 357 } |
358 | 358 |
359 void BookmarkBarModel::FavIconLoaded(BookmarkBarNode* node) { | 359 void BookmarkModel::FavIconLoaded(BookmarkNode* node) { |
360 // Send out notification to the observer. | 360 // Send out notification to the observer. |
361 FOR_EACH_OBSERVER(BookmarkBarModelObserver, observers_, | 361 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
362 BookmarkNodeFavIconLoaded(this, node)); | 362 BookmarkNodeFavIconLoaded(this, node)); |
363 } | 363 } |
364 | 364 |
365 void BookmarkBarModel::RemoveNode(BookmarkBarNode* node, | 365 void BookmarkModel::RemoveNode(BookmarkNode* node, |
366 std::set<GURL>* removed_urls) { | 366 std::set<GURL>* removed_urls) { |
367 if (!loaded_ || !node || node == &root_ || node == bookmark_bar_node_ || | 367 if (!loaded_ || !node || node == &root_ || node == bookmark_bar_node_ || |
368 node == other_node_) { | 368 node == other_node_) { |
369 NOTREACHED(); | 369 NOTREACHED(); |
370 return; | 370 return; |
371 } | 371 } |
372 | 372 |
373 if (node->GetType() == history::StarredEntry::URL) { | 373 if (node->GetType() == history::StarredEntry::URL) { |
374 // NOTE: this is called in such a way that url_lock_ is already held. As | 374 // NOTE: this is called in such a way that url_lock_ is already held. As |
375 // such, this doesn't explicitly grab the lock. | 375 // such, this doesn't explicitly grab the lock. |
376 NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.find(node); | 376 NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.find(node); |
377 DCHECK(i != nodes_ordered_by_url_set_.end()); | 377 DCHECK(i != nodes_ordered_by_url_set_.end()); |
378 nodes_ordered_by_url_set_.erase(i); | 378 nodes_ordered_by_url_set_.erase(i); |
379 removed_urls->insert(node->GetURL()); | 379 removed_urls->insert(node->GetURL()); |
380 } | 380 } |
381 | 381 |
382 CancelPendingFavIconLoadRequests(node); | 382 CancelPendingFavIconLoadRequests(node); |
383 | 383 |
384 // Recurse through children. | 384 // Recurse through children. |
385 for (int i = node->GetChildCount() - 1; i >= 0; --i) | 385 for (int i = node->GetChildCount() - 1; i >= 0; --i) |
386 RemoveNode(node->GetChild(i), removed_urls); | 386 RemoveNode(node->GetChild(i), removed_urls); |
387 } | 387 } |
388 | 388 |
389 void BookmarkBarModel::OnBookmarkStorageLoadedBookmarks( | 389 void BookmarkModel::OnBookmarkStorageLoadedBookmarks( |
390 bool file_exists, | 390 bool file_exists, |
391 bool loaded_from_history) { | 391 bool loaded_from_history) { |
392 if (loaded_) { | 392 if (loaded_) { |
393 NOTREACHED(); | 393 NOTREACHED(); |
394 return; | 394 return; |
395 } | 395 } |
396 | 396 |
397 if (file_exists || loaded_from_history || !profile_ || | 397 if (file_exists || loaded_from_history || !profile_ || |
398 !profile_->GetHistoryService(Profile::EXPLICIT_ACCESS)) { | 398 !profile_->GetHistoryService(Profile::EXPLICIT_ACCESS)) { |
399 // The file exists, we're loaded. | 399 // The file exists, we're loaded. |
(...skipping 19 matching lines...) Expand all Loading... |
419 if (!history->backend_loaded()) { | 419 if (!history->backend_loaded()) { |
420 // The backend isn't finished loading. Wait for it. | 420 // The backend isn't finished loading. Wait for it. |
421 waiting_for_history_load_ = true; | 421 waiting_for_history_load_ = true; |
422 NotificationService::current()->AddObserver( | 422 NotificationService::current()->AddObserver( |
423 this, NOTIFY_HISTORY_LOADED, Source<Profile>(profile_)); | 423 this, NOTIFY_HISTORY_LOADED, Source<Profile>(profile_)); |
424 } else { | 424 } else { |
425 OnHistoryDone(); | 425 OnHistoryDone(); |
426 } | 426 } |
427 } | 427 } |
428 | 428 |
429 void BookmarkBarModel::OnHistoryDone() { | 429 void BookmarkModel::OnHistoryDone() { |
430 if (loaded_) { | 430 if (loaded_) { |
431 NOTREACHED(); | 431 NOTREACHED(); |
432 return; | 432 return; |
433 } | 433 } |
434 | 434 |
435 // If the bookmarks were stored in the db the db will have migrated them to | 435 // If the bookmarks were stored in the db the db will have migrated them to |
436 // a file now. Try loading from the file. | 436 // a file now. Try loading from the file. |
437 store_->LoadBookmarks(true); | 437 store_->LoadBookmarks(true); |
438 } | 438 } |
439 | 439 |
440 void BookmarkBarModel::DoneLoading() { | 440 void BookmarkModel::DoneLoading() { |
441 { | 441 { |
442 AutoLock url_lock(url_lock_); | 442 AutoLock url_lock(url_lock_); |
443 // Update nodes_ordered_by_url_set_ from the nodes. | 443 // Update nodes_ordered_by_url_set_ from the nodes. |
444 PopulateNodesByURL(&root_); | 444 PopulateNodesByURL(&root_); |
445 } | 445 } |
446 | 446 |
447 loaded_ = true; | 447 loaded_ = true; |
448 | 448 |
449 if (loaded_signal_.Get()) | 449 if (loaded_signal_.Get()) |
450 SetEvent(loaded_signal_.Get()); | 450 SetEvent(loaded_signal_.Get()); |
451 | 451 |
452 | 452 |
453 // Notify our direct observers. | 453 // Notify our direct observers. |
454 FOR_EACH_OBSERVER(BookmarkBarModelObserver, observers_, Loaded(this)); | 454 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, Loaded(this)); |
455 | 455 |
456 // And generic notification. | 456 // And generic notification. |
457 NotificationService::current()->Notify( | 457 NotificationService::current()->Notify( |
458 NOTIFY_BOOKMARK_MODEL_LOADED, | 458 NOTIFY_BOOKMARK_MODEL_LOADED, |
459 Source<Profile>(profile_), | 459 Source<Profile>(profile_), |
460 NotificationService::NoDetails()); | 460 NotificationService::NoDetails()); |
461 } | 461 } |
462 | 462 |
463 void BookmarkBarModel::RemoveAndDeleteNode(BookmarkBarNode* delete_me) { | 463 void BookmarkModel::RemoveAndDeleteNode(BookmarkNode* delete_me) { |
464 scoped_ptr<BookmarkBarNode> node(delete_me); | 464 scoped_ptr<BookmarkNode> node(delete_me); |
465 | 465 |
466 BookmarkBarNode* parent = node->GetParent(); | 466 BookmarkNode* parent = node->GetParent(); |
467 DCHECK(parent); | 467 DCHECK(parent); |
468 int index = parent->IndexOfChild(node.get()); | 468 int index = parent->IndexOfChild(node.get()); |
469 parent->Remove(index); | 469 parent->Remove(index); |
470 history::URLsStarredDetails details(false); | 470 history::URLsStarredDetails details(false); |
471 { | 471 { |
472 AutoLock url_lock(url_lock_); | 472 AutoLock url_lock(url_lock_); |
473 RemoveNode(node.get(), &details.changed_urls); | 473 RemoveNode(node.get(), &details.changed_urls); |
474 } | 474 } |
475 | 475 |
476 if (store_.get()) | 476 if (store_.get()) |
477 store_->ScheduleSave(); | 477 store_->ScheduleSave(); |
478 | 478 |
479 FOR_EACH_OBSERVER(BookmarkBarModelObserver, observers_, | 479 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
480 BookmarkNodeRemoved(this, parent, index)); | 480 BookmarkNodeRemoved(this, parent, index)); |
481 | 481 |
482 if (profile_) { | 482 if (profile_) { |
483 HistoryService* history = | 483 HistoryService* history = |
484 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); | 484 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); |
485 if (history) | 485 if (history) |
486 history->URLsNoLongerBookmarked(details.changed_urls); | 486 history->URLsNoLongerBookmarked(details.changed_urls); |
487 } | 487 } |
488 | 488 |
489 NotificationService::current()->Notify(NOTIFY_URLS_STARRED, | 489 NotificationService::current()->Notify(NOTIFY_URLS_STARRED, |
490 Source<Profile>(profile_), | 490 Source<Profile>(profile_), |
491 Details<history::URLsStarredDetails>(&details)); | 491 Details<history::URLsStarredDetails>(&details)); |
492 } | 492 } |
493 | 493 |
494 BookmarkBarNode* BookmarkBarModel::AddNode(BookmarkBarNode* parent, | 494 BookmarkNode* BookmarkModel::AddNode(BookmarkNode* parent, |
495 int index, | 495 int index, |
496 BookmarkBarNode* node) { | 496 BookmarkNode* node) { |
497 parent->Add(index, node); | 497 parent->Add(index, node); |
498 | 498 |
499 if (store_.get()) | 499 if (store_.get()) |
500 store_->ScheduleSave(); | 500 store_->ScheduleSave(); |
501 | 501 |
502 FOR_EACH_OBSERVER(BookmarkBarModelObserver, observers_, | 502 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
503 BookmarkNodeAdded(this, parent, index)); | 503 BookmarkNodeAdded(this, parent, index)); |
504 | 504 |
505 if (node->GetType() == history::StarredEntry::URL) { | 505 if (node->GetType() == history::StarredEntry::URL) { |
506 history::URLsStarredDetails details(true); | 506 history::URLsStarredDetails details(true); |
507 details.changed_urls.insert(node->GetURL()); | 507 details.changed_urls.insert(node->GetURL()); |
508 NotificationService::current()->Notify(NOTIFY_URLS_STARRED, | 508 NotificationService::current()->Notify(NOTIFY_URLS_STARRED, |
509 Source<Profile>(profile_), | 509 Source<Profile>(profile_), |
510 Details<history::URLsStarredDetails>(&details)); | 510 Details<history::URLsStarredDetails>(&details)); |
511 } | 511 } |
512 return node; | 512 return node; |
513 } | 513 } |
514 | 514 |
515 void BookmarkBarModel::BlockTillLoaded() { | 515 void BookmarkModel::BlockTillLoaded() { |
516 if (loaded_signal_.Get()) | 516 if (loaded_signal_.Get()) |
517 WaitForSingleObject(loaded_signal_.Get(), INFINITE); | 517 WaitForSingleObject(loaded_signal_.Get(), INFINITE); |
518 } | 518 } |
519 | 519 |
520 BookmarkBarNode* BookmarkBarModel::GetNodeByID(BookmarkBarNode* node, | 520 BookmarkNode* BookmarkModel::GetNodeByID(BookmarkNode* node, int id) { |
521 int id) { | |
522 if (node->id() == id) | 521 if (node->id() == id) |
523 return node; | 522 return node; |
524 | 523 |
525 for (int i = 0; i < node->GetChildCount(); ++i) { | 524 for (int i = 0; i < node->GetChildCount(); ++i) { |
526 BookmarkBarNode* result = GetNodeByID(node->GetChild(i), id); | 525 BookmarkNode* result = GetNodeByID(node->GetChild(i), id); |
527 if (result) | 526 if (result) |
528 return result; | 527 return result; |
529 } | 528 } |
530 return NULL; | 529 return NULL; |
531 } | 530 } |
532 | 531 |
533 bool BookmarkBarModel::IsValidIndex(BookmarkBarNode* parent, | 532 bool BookmarkModel::IsValidIndex(BookmarkNode* parent, |
534 int index, | 533 int index, |
535 bool allow_end) { | 534 bool allow_end) { |
536 return (parent && | 535 return (parent && |
537 (index >= 0 && (index < parent->GetChildCount() || | 536 (index >= 0 && (index < parent->GetChildCount() || |
538 (allow_end && index == parent->GetChildCount())))); | 537 (allow_end && index == parent->GetChildCount())))); |
539 } | 538 } |
540 | 539 |
541 void BookmarkBarModel::SetDateGroupModified(BookmarkBarNode* parent, | 540 void BookmarkModel::SetDateGroupModified(BookmarkNode* parent, |
542 const Time time) { | 541 const Time time) { |
543 DCHECK(parent); | 542 DCHECK(parent); |
544 parent->date_group_modified_ = time; | 543 parent->date_group_modified_ = time; |
545 | 544 |
546 if (store_.get()) | 545 if (store_.get()) |
547 store_->ScheduleSave(); | 546 store_->ScheduleSave(); |
548 } | 547 } |
549 | 548 |
550 void BookmarkBarModel::CreateBookmarkBarNode() { | 549 void BookmarkModel::CreateBookmarkNode() { |
551 history::StarredEntry entry; | 550 history::StarredEntry entry; |
552 entry.type = history::StarredEntry::BOOKMARK_BAR; | 551 entry.type = history::StarredEntry::BOOKMARK_BAR; |
553 bookmark_bar_node_ = CreateRootNodeFromStarredEntry(entry); | 552 bookmark_bar_node_ = CreateRootNodeFromStarredEntry(entry); |
554 } | 553 } |
555 | 554 |
556 void BookmarkBarModel::CreateOtherBookmarksNode() { | 555 void BookmarkModel::CreateOtherBookmarksNode() { |
557 history::StarredEntry entry; | 556 history::StarredEntry entry; |
558 entry.type = history::StarredEntry::OTHER; | 557 entry.type = history::StarredEntry::OTHER; |
559 other_node_ = CreateRootNodeFromStarredEntry(entry); | 558 other_node_ = CreateRootNodeFromStarredEntry(entry); |
560 } | 559 } |
561 | 560 |
562 BookmarkBarNode* BookmarkBarModel::CreateRootNodeFromStarredEntry( | 561 BookmarkNode* BookmarkModel::CreateRootNodeFromStarredEntry( |
563 const history::StarredEntry& entry) { | 562 const history::StarredEntry& entry) { |
564 DCHECK(entry.type == history::StarredEntry::BOOKMARK_BAR || | 563 DCHECK(entry.type == history::StarredEntry::BOOKMARK_BAR || |
565 entry.type == history::StarredEntry::OTHER); | 564 entry.type == history::StarredEntry::OTHER); |
566 BookmarkBarNode* node = new BookmarkBarNode(this, GURL()); | 565 BookmarkNode* node = new BookmarkNode(this, GURL()); |
567 node->Reset(entry); | 566 node->Reset(entry); |
568 if (entry.type == history::StarredEntry::BOOKMARK_BAR) | 567 if (entry.type == history::StarredEntry::BOOKMARK_BAR) |
569 node->SetTitle(l10n_util::GetString(IDS_BOOMARK_BAR_FOLDER_NAME)); | 568 node->SetTitle(l10n_util::GetString(IDS_BOOMARK_BAR_FOLDER_NAME)); |
570 else | 569 else |
571 node->SetTitle(l10n_util::GetString(IDS_BOOMARK_BAR_OTHER_FOLDER_NAME)); | 570 node->SetTitle(l10n_util::GetString(IDS_BOOMARK_BAR_OTHER_FOLDER_NAME)); |
572 return node; | 571 return node; |
573 } | 572 } |
574 | 573 |
575 void BookmarkBarModel::OnFavIconDataAvailable( | 574 void BookmarkModel::OnFavIconDataAvailable( |
576 HistoryService::Handle handle, | 575 HistoryService::Handle handle, |
577 bool know_favicon, | 576 bool know_favicon, |
578 scoped_refptr<RefCountedBytes> data, | 577 scoped_refptr<RefCountedBytes> data, |
579 bool expired, | 578 bool expired, |
580 GURL icon_url) { | 579 GURL icon_url) { |
581 SkBitmap fav_icon; | 580 SkBitmap fav_icon; |
582 BookmarkBarNode* node = | 581 BookmarkNode* node = |
583 load_consumer_.GetClientData( | 582 load_consumer_.GetClientData( |
584 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS), handle); | 583 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS), handle); |
585 DCHECK(node); | 584 DCHECK(node); |
586 node->favicon_load_handle_ = 0; | 585 node->favicon_load_handle_ = 0; |
587 if (know_favicon && data.get() && | 586 if (know_favicon && data.get() && |
588 PNGDecoder::Decode(&data->data, &fav_icon)) { | 587 PNGDecoder::Decode(&data->data, &fav_icon)) { |
589 node->favicon_ = fav_icon; | 588 node->favicon_ = fav_icon; |
590 FavIconLoaded(node); | 589 FavIconLoaded(node); |
591 } | 590 } |
592 } | 591 } |
593 | 592 |
594 void BookmarkBarModel::LoadFavIcon(BookmarkBarNode* node) { | 593 void BookmarkModel::LoadFavIcon(BookmarkNode* node) { |
595 if (node->GetType() != history::StarredEntry::URL) | 594 if (node->GetType() != history::StarredEntry::URL) |
596 return; | 595 return; |
597 | 596 |
598 DCHECK(node->GetURL().is_valid()); | 597 DCHECK(node->GetURL().is_valid()); |
599 HistoryService* history_service = | 598 HistoryService* history_service = |
600 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); | 599 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); |
601 if (!history_service) | 600 if (!history_service) |
602 return; | 601 return; |
603 | 602 |
604 HistoryService::Handle handle = history_service->GetFavIconForURL( | 603 HistoryService::Handle handle = history_service->GetFavIconForURL( |
605 node->GetURL(), &load_consumer_, | 604 node->GetURL(), &load_consumer_, |
606 NewCallback(this, &BookmarkBarModel::OnFavIconDataAvailable)); | 605 NewCallback(this, &BookmarkModel::OnFavIconDataAvailable)); |
607 load_consumer_.SetClientData(history_service, handle, node); | 606 load_consumer_.SetClientData(history_service, handle, node); |
608 node->favicon_load_handle_ = handle; | 607 node->favicon_load_handle_ = handle; |
609 } | 608 } |
610 | 609 |
611 void BookmarkBarModel::CancelPendingFavIconLoadRequests(BookmarkBarNode* node) { | 610 void BookmarkModel::CancelPendingFavIconLoadRequests(BookmarkNode* node) { |
612 if (node->favicon_load_handle_) { | 611 if (node->favicon_load_handle_) { |
613 HistoryService* history = | 612 HistoryService* history = |
614 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); | 613 profile_->GetHistoryService(Profile::EXPLICIT_ACCESS); |
615 if (history) | 614 if (history) |
616 history->CancelRequest(node->favicon_load_handle_); | 615 history->CancelRequest(node->favicon_load_handle_); |
617 node->favicon_load_handle_ = 0; | 616 node->favicon_load_handle_ = 0; |
618 } | 617 } |
619 } | 618 } |
620 | 619 |
621 void BookmarkBarModel::GetMostRecentlyModifiedGroupNodes( | 620 void BookmarkModel::GetMostRecentlyModifiedGroupNodes( |
622 BookmarkBarNode* parent, | 621 BookmarkNode* parent, |
623 size_t count, | 622 size_t count, |
624 std::vector<BookmarkBarNode*>* nodes) { | 623 std::vector<BookmarkNode*>* nodes) { |
625 if (parent != &root_ && parent->is_folder() && | 624 if (parent != &root_ && parent->is_folder() && |
626 parent->date_group_modified() > Time()) { | 625 parent->date_group_modified() > Time()) { |
627 if (count == 0) { | 626 if (count == 0) { |
628 nodes->push_back(parent); | 627 nodes->push_back(parent); |
629 } else { | 628 } else { |
630 std::vector<BookmarkBarNode*>::iterator i = | 629 std::vector<BookmarkNode*>::iterator i = |
631 std::upper_bound(nodes->begin(), nodes->end(), parent, | 630 std::upper_bound(nodes->begin(), nodes->end(), parent, |
632 &MoreRecentlyModified); | 631 &MoreRecentlyModified); |
633 if (nodes->size() < count || i != nodes->end()) { | 632 if (nodes->size() < count || i != nodes->end()) { |
634 nodes->insert(i, parent); | 633 nodes->insert(i, parent); |
635 while (nodes->size() > count) | 634 while (nodes->size() > count) |
636 nodes->pop_back(); | 635 nodes->pop_back(); |
637 } | 636 } |
638 } | 637 } |
639 } // else case, the root node, which we don't care about or imported nodes | 638 } // else case, the root node, which we don't care about or imported nodes |
640 // (which have a time of 0). | 639 // (which have a time of 0). |
641 for (int i = 0; i < parent->GetChildCount(); ++i) { | 640 for (int i = 0; i < parent->GetChildCount(); ++i) { |
642 BookmarkBarNode* child = parent->GetChild(i); | 641 BookmarkNode* child = parent->GetChild(i); |
643 if (child->is_folder()) | 642 if (child->is_folder()) |
644 GetMostRecentlyModifiedGroupNodes(child, count, nodes); | 643 GetMostRecentlyModifiedGroupNodes(child, count, nodes); |
645 } | 644 } |
646 } | 645 } |
647 | 646 |
648 void BookmarkBarModel::Observe(NotificationType type, | 647 void BookmarkModel::Observe(NotificationType type, |
649 const NotificationSource& source, | 648 const NotificationSource& source, |
650 const NotificationDetails& details) { | 649 const NotificationDetails& details) { |
651 switch (type) { | 650 switch (type) { |
652 case NOTIFY_FAVICON_CHANGED: { | 651 case NOTIFY_FAVICON_CHANGED: { |
653 // Prevent the observers from getting confused for multiple favicon loads. | 652 // Prevent the observers from getting confused for multiple favicon loads. |
654 Details<history::FavIconChangeDetails> favicon_details(details); | 653 Details<history::FavIconChangeDetails> favicon_details(details); |
655 for (std::set<GURL>::const_iterator i = favicon_details->urls.begin(); | 654 for (std::set<GURL>::const_iterator i = favicon_details->urls.begin(); |
656 i != favicon_details->urls.end(); ++i) { | 655 i != favicon_details->urls.end(); ++i) { |
657 BookmarkBarNode* node = GetNodeByURL(*i); | 656 BookmarkNode* node = GetNodeByURL(*i); |
658 if (node) { | 657 if (node) { |
659 // Got an updated favicon, for a URL, do a new request. | 658 // Got an updated favicon, for a URL, do a new request. |
660 node->InvalidateFavicon(); | 659 node->InvalidateFavicon(); |
661 CancelPendingFavIconLoadRequests(node); | 660 CancelPendingFavIconLoadRequests(node); |
662 FOR_EACH_OBSERVER(BookmarkBarModelObserver, observers_, | 661 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
663 BookmarkNodeChanged(this, node)); | 662 BookmarkNodeChanged(this, node)); |
664 } | 663 } |
665 } | 664 } |
666 break; | 665 break; |
667 } | 666 } |
668 | 667 |
669 case NOTIFY_HISTORY_LOADED: { | 668 case NOTIFY_HISTORY_LOADED: { |
670 if (waiting_for_history_load_) { | 669 if (waiting_for_history_load_) { |
671 waiting_for_history_load_ = false; | 670 waiting_for_history_load_ = false; |
672 NotificationService::current()->RemoveObserver( | 671 NotificationService::current()->RemoveObserver( |
673 this, NOTIFY_HISTORY_LOADED, Source<Profile>(profile_)); | 672 this, NOTIFY_HISTORY_LOADED, Source<Profile>(profile_)); |
674 OnHistoryDone(); | 673 OnHistoryDone(); |
675 } else { | 674 } else { |
676 NOTREACHED(); | 675 NOTREACHED(); |
677 } | 676 } |
678 break; | 677 break; |
679 } | 678 } |
680 | 679 |
681 default: | 680 default: |
682 NOTREACHED(); | 681 NOTREACHED(); |
683 break; | 682 break; |
684 } | 683 } |
685 } | 684 } |
686 | 685 |
687 void BookmarkBarModel::PopulateNodesByURL(BookmarkBarNode* node) { | 686 void BookmarkModel::PopulateNodesByURL(BookmarkNode* node) { |
688 // NOTE: this is called with url_lock_ already held. As such, this doesn't | 687 // NOTE: this is called with url_lock_ already held. As such, this doesn't |
689 // explicitly grab the lock. | 688 // explicitly grab the lock. |
690 if (node->is_url()) | 689 if (node->is_url()) |
691 nodes_ordered_by_url_set_.insert(node); | 690 nodes_ordered_by_url_set_.insert(node); |
692 for (int i = 0; i < node->GetChildCount(); ++i) | 691 for (int i = 0; i < node->GetChildCount(); ++i) |
693 PopulateNodesByURL(node->GetChild(i)); | 692 PopulateNodesByURL(node->GetChild(i)); |
694 } | 693 } |
OLD | NEW |