OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013 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_tag_model.h" | |
6 | |
7 #include "base/json/json_string_value_serializer.h" | |
8 #include "base/observer_list.h" | |
9 #include "base/strings/string_util.h" | |
10 #include "base/strings/utf_string_conversions.h" | |
11 #include "chrome/browser/bookmarks/bookmark_model_factory.h" | |
12 #include "chrome/browser/bookmarks/bookmark_tag_model_observer.h" | |
13 #include "ui/base/models/tree_node_iterator.h" | |
14 | |
15 namespace { | |
16 // The key used to store the tag list in the metainfo of a bookmark. | |
17 const char* TAG_KEY = "TAG_KEY"; | |
18 | |
19 // Predicates to sort bookmarks. | |
20 bool CompareBookmarkTitles(const BookmarkNode* a, const BookmarkNode* b) { | |
21 return a->GetTitle() < b->GetTitle(); | |
22 } | |
23 bool CompareBookmarkUrl(const BookmarkNode* a, const BookmarkNode* b) { | |
24 return a->url() < b->url(); | |
25 } | |
26 bool CompareBookmarkCreation(const BookmarkNode* a, const BookmarkNode* b) { | |
27 return a->date_added() < b->date_added(); | |
28 } | |
29 | |
30 // Comparator to sort tags by usage. | |
31 struct TagComparator { | |
32 TagComparator(std::map<BookmarkTag, unsigned int>& tags) : tags_(tags) { | |
33 } | |
34 ~TagComparator() {} | |
35 | |
36 bool operator()(BookmarkTag a, BookmarkTag b) { | |
37 return (tags_[a] < tags_[b]); | |
38 } | |
39 | |
40 std::map<BookmarkTag, unsigned int>& tags_; | |
41 }; | |
42 } // namespace | |
43 | |
44 BookmarkTagModel::BookmarkTagModel(BookmarkModel* bookmark_model) | |
45 : bookmark_model_(bookmark_model), | |
46 loaded_(false), | |
47 observers_(ObserverList<BookmarkTagModelObserver>::NOTIFY_EXISTING_ONLY), | |
48 inhibit_change_notifications_(false) { | |
49 bookmark_model_->AddObserver(this); | |
50 if (bookmark_model_->loaded()) | |
51 Load(); | |
52 } | |
53 | |
54 BookmarkTagModel::~BookmarkTagModel() { | |
55 if (bookmark_model_) | |
Yaron
2013/10/11 10:50:41
Can this ever fail? Seems like the c-tor guarantee
noyau (Ping after 24h)
2013/10/11 12:09:21
The bookmark model notifies its observer when it i
| |
56 bookmark_model_->RemoveObserver(this); | |
57 } | |
58 | |
59 #pragma mark BookmarkModel forwarding. | |
60 | |
61 void BookmarkTagModel::AddObserver(BookmarkTagModelObserver* observer) { | |
62 observers_.AddObserver(observer); | |
63 } | |
64 | |
65 void BookmarkTagModel::RemoveObserver(BookmarkTagModelObserver* observer) { | |
66 observers_.RemoveObserver(observer); | |
67 } | |
68 | |
69 void BookmarkTagModel::BeginExtensiveChanges() { | |
70 DCHECK(bookmark_model_); | |
Yaron
2013/10/11 10:50:41
These DCHECKS all seem unnecessary for reasons abo
noyau (Ping after 24h)
2013/10/11 12:09:21
These DCHECK are necessary for reasons above :)
| |
71 bookmark_model_->BeginExtensiveChanges(); | |
72 } | |
73 | |
74 void BookmarkTagModel::EndExtensiveChanges() { | |
75 DCHECK(bookmark_model_); | |
76 bookmark_model_->EndExtensiveChanges(); | |
77 } | |
78 | |
79 bool BookmarkTagModel::IsDoingExtensiveChanges() const { | |
80 DCHECK(bookmark_model_); | |
81 return bookmark_model_->IsDoingExtensiveChanges(); | |
82 } | |
83 | |
84 void BookmarkTagModel::Remove(const BookmarkNode* bookmark) { | |
85 DCHECK(bookmark_model_); | |
86 DCHECK(loaded_); | |
87 const BookmarkNode *parent = bookmark->parent(); | |
88 bookmark_model_->Remove(parent, parent->GetIndexOf(bookmark)); | |
89 } | |
90 | |
91 void BookmarkTagModel::RemoveAll() { | |
92 DCHECK(bookmark_model_); | |
93 DCHECK(loaded_); | |
94 bookmark_model_->RemoveAll(); | |
95 } | |
96 | |
97 const gfx::Image& BookmarkTagModel::GetFavicon(const BookmarkNode* bookmark) { | |
98 DCHECK(bookmark_model_); | |
99 DCHECK(loaded_); | |
100 return bookmark_model_->GetFavicon(bookmark); | |
101 } | |
102 | |
103 void BookmarkTagModel::SetTitle(const BookmarkNode* bookmark, | |
104 const string16& title) { | |
105 DCHECK(bookmark_model_); | |
106 DCHECK(loaded_); | |
107 bookmark_model_->SetTitle(bookmark, title); | |
108 } | |
109 | |
110 void BookmarkTagModel::SetURL(const BookmarkNode* bookmark, const GURL& url) { | |
111 DCHECK(bookmark_model_); | |
112 DCHECK(loaded_); | |
113 bookmark_model_->SetURL(bookmark, url); | |
114 } | |
115 | |
116 void BookmarkTagModel::SetDateAdded(const BookmarkNode* bookmark, | |
117 base::Time date_added) { | |
118 DCHECK(bookmark_model_); | |
119 DCHECK(loaded_); | |
120 bookmark_model_->SetDateAdded(bookmark, date_added); | |
121 } | |
122 | |
123 const BookmarkNode* | |
124 BookmarkTagModel::GetMostRecentlyAddedBookmarkForURL(const GURL& url) { | |
125 DCHECK(bookmark_model_); | |
126 DCHECK(loaded_); | |
127 return bookmark_model_->GetMostRecentlyAddedNodeForURL(url); | |
128 } | |
129 | |
130 #pragma mark Tags. | |
131 | |
132 const BookmarkNode* BookmarkTagModel::AddURL( | |
133 const string16& title, | |
134 const GURL& url, | |
135 const std::set<BookmarkTag>& tags) { | |
136 DCHECK(bookmark_model_); | |
137 DCHECK(loaded_); | |
138 | |
139 inhibit_change_notifications_ = true; | |
140 const BookmarkNode* parent = bookmark_model_->GetParentForNewNodes(); | |
141 const BookmarkNode* bookmark = bookmark_model_->AddURL( | |
Yaron
2013/10/11 10:50:41
I'm pretty sure the underlying BookmarkModel will
noyau (Ping after 24h)
2013/10/11 12:09:21
Yes, it will, and should. This class relies on the
| |
142 parent, 0, title, url); | |
143 AddTagsToBookmark(tags, bookmark); | |
144 inhibit_change_notifications_ = false; | |
145 | |
146 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
147 BookmarkNodeAdded(this, bookmark)); | |
148 | |
149 return bookmark; | |
150 } | |
151 | |
152 std::set<BookmarkTag> | |
153 BookmarkTagModel::AllTagsForBookmark(const BookmarkNode* bookmark) { | |
154 DCHECK(loaded_); | |
155 return bookmark_to_tags_[bookmark]; | |
156 } | |
157 | |
158 void BookmarkTagModel::AddTagsToBookmark( | |
159 const std::set<BookmarkTag>& tags, const BookmarkNode* bookmark) { | |
160 std::set<BookmarkTag> all_tags(AllTagsForBookmark(bookmark)); | |
161 for (std::set<BookmarkTag>::iterator it = tags.begin(); | |
162 it != tags.end(); ++it) { | |
163 BookmarkTag trimmed_tag = CollapseWhitespace(*it, true); | |
164 if (trimmed_tag.empty()) | |
165 continue; | |
166 all_tags.insert(trimmed_tag); | |
167 } | |
168 ReplaceTagsOnBookmark(all_tags, bookmark); | |
169 } | |
170 | |
171 void BookmarkTagModel::AddTagsToBookmarks( | |
172 const std::set<BookmarkTag>& tags, | |
173 const std::set<const BookmarkNode*>& bookmarks) { | |
174 for (std::set<const BookmarkNode*>::iterator it = bookmarks.begin(); | |
175 it != bookmarks.end(); ++it) { | |
176 AddTagsToBookmark(tags, *it); | |
177 } | |
178 } | |
179 | |
180 void BookmarkTagModel::RemoveTagsFromBookmark( | |
181 const std::set<BookmarkTag>& tags, | |
182 const BookmarkNode* bookmark) { | |
183 std::set<BookmarkTag> all_tags(AllTagsForBookmark(bookmark)); | |
184 for (std::set<BookmarkTag>::iterator it = tags.begin(); | |
185 it != tags.end(); ++it) { | |
186 all_tags.erase(*it); | |
187 } | |
188 ReplaceTagsOnBookmark(all_tags, bookmark); | |
189 } | |
190 | |
191 void BookmarkTagModel::RemoveTagsFromBookmarks( | |
192 const std::set<BookmarkTag>& tags, | |
193 const std::set<const BookmarkNode*>& bookmarks){ | |
194 for (std::set<const BookmarkNode*>::iterator it = bookmarks.begin(); | |
195 it != bookmarks.end(); ++it) { | |
196 RemoveTagsFromBookmark(tags, *it); | |
197 } | |
198 } | |
199 | |
200 std::vector<const BookmarkNode*> BookmarkTagModel::BookmarksForTags( | |
201 const std::set<BookmarkTag>& tags, | |
202 BookmarkTagModel::BookmarkOrdering ordering) { | |
203 DCHECK(loaded_); | |
204 std::set<const BookmarkNode*> bookmarks; | |
205 for (std::set<BookmarkTag>::iterator it = tags.begin(); | |
206 it != tags.end(); ++it) { | |
207 const std::set<const BookmarkNode*> subset(tag_to_bookmarks_[*it]); | |
208 bookmarks.insert(subset.begin(), subset.end()); | |
noyau (Ping after 24h)
2013/10/11 12:09:21
GCC on Android fail to compile this insert() with
| |
209 } | |
210 | |
211 std::vector<const BookmarkNode*> sorted_bookmarks(bookmarks.begin(), | |
212 bookmarks.end()); | |
213 switch (ordering) { | |
214 case UNSORTED_BOOKMARK_ORDERING: | |
215 break; | |
216 case TITLE_BOOKMARK_ORDERING: | |
217 std::sort(sorted_bookmarks.begin(), sorted_bookmarks.end(), | |
218 CompareBookmarkTitles); | |
219 break; | |
220 case URL_BOOKMARK_ORDERING: | |
221 std::sort(sorted_bookmarks.begin(), sorted_bookmarks.end(), | |
222 CompareBookmarkUrl); | |
223 break; | |
224 case CREATION_TIME_BOOKMARK_ORDERING: | |
225 std::sort(sorted_bookmarks.begin(), sorted_bookmarks.end(), | |
226 CompareBookmarkCreation); | |
227 break; | |
228 default: | |
229 NOTREACHED(); | |
230 } | |
231 return sorted_bookmarks; | |
232 } | |
233 | |
234 std::vector<const BookmarkNode*> BookmarkTagModel::BookmarksForTag( | |
235 const BookmarkTag& tag, BookmarkOrdering ordering) { | |
236 DCHECK(!tag.empty()); | |
237 std::set<BookmarkTag> tagset; | |
238 tagset.insert(tag); | |
239 return BookmarksForTags(tagset, ordering); | |
240 } | |
241 | |
242 std::vector<BookmarkTag> BookmarkTagModel::TagsRelatedToTag( | |
243 const BookmarkTag& tag, BookmarkTagModel::TagOrdering ordering) { | |
244 DCHECK(loaded_); | |
245 std::map<BookmarkTag, unsigned int> tags; | |
246 | |
247 if (tag.empty()) { | |
248 // Returns all the tags. | |
249 for (std::map<const BookmarkTag, std::set<const BookmarkNode*> >::iterator | |
250 it = tag_to_bookmarks_.begin(); it != tag_to_bookmarks_.end(); ++it) { | |
251 tags[it->first] = it->second.size(); | |
252 } | |
253 } else { | |
254 std::vector<const BookmarkNode*> bookmarks( | |
255 BookmarksForTag(tag, UNSORTED_BOOKMARK_ORDERING)); | |
256 | |
257 for (std::vector<const BookmarkNode*>::iterator it = bookmarks.begin(); | |
258 it != bookmarks.end(); ++it) { | |
259 std::set<BookmarkTag> subset(bookmark_to_tags_[*it]); | |
260 for (std::set<BookmarkTag>::iterator tag_it = subset.begin(); | |
261 tag_it != subset.end(); ++tag_it) { | |
262 tags[*tag_it] += 1; | |
263 } | |
264 } | |
265 tags.erase(tag); // A tag is not related to itself. | |
266 } | |
267 | |
268 // There is no keys() method on std::map. Nobody thought it might be useful? | |
269 std::vector<BookmarkTag> sorted_tags; | |
270 for (std::map<BookmarkTag, unsigned int>::iterator it = tags.begin(); | |
271 it != tags.end(); ++it) { | |
272 sorted_tags.push_back(it->first); | |
273 } | |
274 | |
275 switch (ordering) { | |
276 case UNSORTED_TAG_ORDERING: | |
277 case ALPHABETICAL_TAG_ORDERING: | |
278 break; // std::map is already sorting its keys. | |
279 case MOST_USED_TAG_ORDERING: | |
280 std::sort(sorted_tags.begin(), sorted_tags.end(), TagComparator(tags)); | |
281 break; | |
282 default: | |
283 NOTREACHED(); | |
284 } | |
285 return sorted_tags; | |
286 } | |
287 | |
288 #pragma mark Private methods. | |
rlarocque
2013/10/11 18:06:25
What does this do?
noyau (Ping after 24h)
2013/10/14 23:59:39
Mac tools read those and use the text as a separat
| |
289 | |
290 std::set<BookmarkTag> BookmarkTagModel::ExtractTagsFromBookmark( | |
291 const BookmarkNode *bookmark) { | |
292 DCHECK(bookmark_model_); | |
293 // This is awful BTW. Metainfo is itself an encoded JSON, and here we decode | |
294 // another layer. | |
295 | |
296 // Retrieve the encodedData from the bookmark. If there is no encoded data | |
297 // at all returns the name of all the ancestors as separate tags. | |
298 std::string encoded; | |
299 if (!bookmark->GetMetaInfo(TAG_KEY, &encoded)) { | |
300 std::set<BookmarkTag> tags; | |
301 const BookmarkNode* folder = bookmark->parent(); | |
302 while (folder && folder->type() == BookmarkNode::FOLDER) { | |
303 BookmarkTag trimmed_tag = CollapseWhitespace(folder->GetTitle(), true); | |
304 if (!trimmed_tag.empty()) | |
305 tags.insert(trimmed_tag); | |
306 folder = folder->parent(); | |
307 } | |
308 return tags; | |
309 } | |
310 | |
311 // Decode into a base::Value. If the data is not encoded properly as a list | |
312 // return an empty result. | |
313 JSONStringValueSerializer serializer(&encoded); | |
314 int error_code = 0; | |
315 std::string error_message; | |
316 base::Value* result = serializer.Deserialize(&error_code, &error_message); | |
noyau (Ping after 24h)
2013/10/11 12:09:21
Memory leak fixed (Thanks memory bot!)
| |
317 | |
318 if (error_code || !result->IsType(base::Value::TYPE_LIST)) | |
319 return std::set<BookmarkTag>(); | |
320 | |
321 base::ListValue* list = NULL; | |
322 if (!result->GetAsList(&list) || list->empty()) | |
323 return std::set<BookmarkTag>(); | |
324 | |
325 // Build the set. | |
326 std::set<BookmarkTag> return_value; | |
327 | |
328 for (base::ListValue::iterator it = list->begin(); | |
329 it != list->end(); ++it) { | |
330 base::Value* item = *it; | |
331 BookmarkTag tag; | |
332 if (!item->GetAsString(&tag)) | |
333 continue; | |
334 return_value.insert(tag); | |
335 } | |
336 return return_value; | |
337 } | |
338 | |
339 void BookmarkTagModel::ReplaceTagsOnBookmark( | |
340 const std::set<BookmarkTag>& tags, const BookmarkNode *bookmark) { | |
341 DCHECK(bookmark_model_); | |
342 DCHECK(loaded_); | |
343 | |
344 // Build a ListValue. | |
345 std::vector<BookmarkTag> tag_vector(tags.begin(), tags.end()); | |
346 base::ListValue list; | |
347 list.AppendStrings(tag_vector); | |
348 | |
349 // Encodes it. | |
350 std::string encoded; | |
351 JSONStringValueSerializer serializer(&encoded); | |
352 | |
353 // Pushes it in the bookmark's metainfo. | |
354 serializer.Serialize(list); | |
355 bookmark_model_->SetNodeMetaInfo(bookmark, TAG_KEY, encoded); | |
356 } | |
357 | |
358 void BookmarkTagModel::Load() { | |
359 DCHECK(bookmark_model_); | |
360 DCHECK(!loaded_); | |
361 ui::TreeNodeIterator<const BookmarkNode> iterator( | |
362 bookmark_model_->root_node()); | |
363 while (iterator.has_next()) | |
364 LoadBookmark(iterator.Next()); | |
365 loaded_ = true; | |
366 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
367 Loaded(this)); | |
368 } | |
369 | |
370 void BookmarkTagModel::LoadBookmark(const BookmarkNode* bookmark) { | |
371 DCHECK(bookmark_model_); | |
372 if (bookmark->is_url()) { | |
373 std::set<BookmarkTag> tags(ExtractTagsFromBookmark(bookmark)); | |
374 | |
375 bookmark_to_tags_[bookmark] = tags; | |
376 for (std::set<BookmarkTag>::iterator it = tags.begin(); | |
377 it != tags.end(); ++it) { | |
378 tag_to_bookmarks_[*it].insert(bookmark); | |
379 } | |
380 } | |
381 } | |
382 | |
383 void BookmarkTagModel::RemoveBookmark(const BookmarkNode* bookmark) { | |
384 DCHECK(bookmark_model_); | |
385 if (bookmark->is_url()) { | |
386 std::set<BookmarkTag> tags(bookmark_to_tags_[bookmark]); | |
387 bookmark_to_tags_.erase(bookmark); | |
388 | |
389 for (std::set<BookmarkTag>::iterator it = tags.begin(); | |
390 it != tags.end(); ++it) { | |
391 tag_to_bookmarks_[*it].erase(bookmark); | |
392 // Remove the tags no longer used. | |
393 if (!tag_to_bookmarks_[*it].size()) | |
394 tag_to_bookmarks_.erase(*it); | |
395 } | |
396 } | |
397 } | |
398 | |
399 #pragma mark BookmarkModelObserver. | |
400 | |
401 // Invoked when the model has finished loading. | |
402 void BookmarkTagModel::Loaded(BookmarkModel* model, bool ids_reassigned) { | |
403 Load(); | |
404 }; | |
405 | |
406 // Invoked from the destructor of the BookmarkModel. | |
407 void BookmarkTagModel::BookmarkModelBeingDeleted(BookmarkModel* model) { | |
408 DCHECK(bookmark_model_); | |
409 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
410 BookmarkTagModelBeingDeleted(this)); | |
411 bookmark_model_ = NULL; | |
412 observers_.Clear(); | |
413 } | |
414 | |
415 // Invoked when a node has moved. | |
416 void BookmarkTagModel::BookmarkNodeMoved(BookmarkModel* model, | |
417 const BookmarkNode* old_parent, | |
418 int old_index, | |
419 const BookmarkNode* new_parent, | |
420 int new_index) { | |
421 DCHECK(loaded_); | |
422 const BookmarkNode* bookmark = new_parent->GetChild(new_index); | |
423 std::string encoded; | |
424 if (!bookmark->GetMetaInfo(TAG_KEY, &encoded)) { | |
425 // The bookmark moved and the system currently use its ancestors name as a | |
426 // poor approximation for tags. | |
427 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
428 OnWillChangeBookmarkTags(this, bookmark)); | |
429 RemoveBookmark(bookmark); | |
430 LoadBookmark(bookmark); | |
431 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
432 BookmarkTagsChanged(this, bookmark)); | |
433 } | |
434 }; | |
435 | |
436 // Invoked when a node has been added. | |
437 void BookmarkTagModel::BookmarkNodeAdded(BookmarkModel* model, | |
438 const BookmarkNode* parent, | |
439 int index) { | |
440 DCHECK(loaded_); | |
441 const BookmarkNode* bookmark = parent->GetChild(index); | |
442 if (!bookmark->is_url()) | |
443 return; | |
444 LoadBookmark(bookmark); | |
445 | |
446 if (!inhibit_change_notifications_) | |
447 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
448 BookmarkNodeAdded(this, bookmark)); | |
449 } | |
450 | |
451 // Invoked before a node is removed. | |
452 // |parent| the parent of the node that will be removed. | |
453 // |old_index| the index of the node about to be removed in |parent|. | |
454 // |node| is the node to be removed. | |
455 void BookmarkTagModel::OnWillRemoveBookmarks(BookmarkModel* model, | |
456 const BookmarkNode* parent, | |
457 int old_index, | |
458 const BookmarkNode* node) { | |
459 DCHECK(loaded_); | |
460 RemoveBookmark(node); | |
461 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
462 OnWillRemoveBookmarks(this, node)); | |
463 } | |
464 | |
465 // Invoked when a node has been removed, the item may still be starred though. | |
466 // |parent| the parent of the node that was removed. | |
467 // |old_index| the index of the removed node in |parent| before it was | |
468 // removed. | |
469 // |node| is the node that was removed. | |
470 void BookmarkTagModel::BookmarkNodeRemoved(BookmarkModel* model, | |
471 const BookmarkNode* parent, | |
472 int old_index, | |
473 const BookmarkNode* node) { | |
474 DCHECK(loaded_); | |
475 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
476 BookmarkNodeRemoved(this, node)); | |
477 } | |
478 | |
479 // Invoked before the title or url of a node is changed. | |
480 void BookmarkTagModel::OnWillChangeBookmarkNode(BookmarkModel* model, | |
481 const BookmarkNode* node) { | |
482 DCHECK(loaded_); | |
483 if (!inhibit_change_notifications_) | |
484 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
485 OnWillChangeBookmarkNode(this, node)); | |
486 } | |
487 | |
488 // Invoked when the title or url of a node changes. | |
489 void BookmarkTagModel::BookmarkNodeChanged(BookmarkModel* model, | |
490 const BookmarkNode* node) { | |
491 DCHECK(loaded_); | |
492 if (!inhibit_change_notifications_) | |
493 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
494 BookmarkNodeChanged(this, node)); | |
495 } | |
496 | |
497 // Invoked before the metainfo of a node is changed. | |
498 void BookmarkTagModel::OnWillChangeBookmarkMetaInfo(BookmarkModel* model, | |
499 const BookmarkNode* node) { | |
500 DCHECK(loaded_); | |
501 if (!inhibit_change_notifications_) | |
502 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
503 OnWillChangeBookmarkTags(this, node)); | |
504 } | |
505 | |
506 // Invoked when the metainfo on a node changes. | |
507 void BookmarkTagModel::BookmarkMetaInfoChanged(BookmarkModel* model, | |
508 const BookmarkNode* node) { | |
509 DCHECK(loaded_); | |
510 RemoveBookmark(node); | |
511 LoadBookmark(node); | |
512 if (!inhibit_change_notifications_) | |
513 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
514 BookmarkTagsChanged(this, node)); | |
515 } | |
516 | |
517 // Invoked when a favicon has been loaded or changed. | |
518 void BookmarkTagModel::BookmarkNodeFaviconChanged(BookmarkModel* model, | |
519 const BookmarkNode* node) { | |
520 DCHECK(loaded_); | |
521 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
522 BookmarkNodeFaviconChanged(this, node)); | |
523 } | |
524 | |
525 // Invoked before the direct children of |node| have been reordered in some | |
526 // way, such as sorted. | |
527 void BookmarkTagModel::OnWillReorderBookmarkNode(BookmarkModel* model, | |
528 const BookmarkNode* node) { | |
529 // This model doesn't care. | |
530 } | |
531 | |
532 // Invoked when the children (just direct children, not descendants) of | |
533 // |node| have been reordered in some way, such as sorted. | |
534 void BookmarkTagModel::BookmarkNodeChildrenReordered(BookmarkModel* model, | |
535 const BookmarkNode* node) { | |
536 // This model doesn't care. | |
537 } | |
538 | |
539 // Invoked before an extensive set of model changes is about to begin. | |
540 // This tells UI intensive observers to wait until the updates finish to | |
541 // update themselves. | |
542 // These methods should only be used for imports and sync. | |
543 // Observers should still respond to BookmarkNodeRemoved immediately, | |
544 // to avoid holding onto stale node pointers. | |
545 void BookmarkTagModel::ExtensiveBookmarkChangesBeginning(BookmarkModel* model) { | |
546 DCHECK(loaded_); | |
547 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
548 ExtensiveBookmarkChangesBeginning(this)); | |
549 } | |
550 | |
551 // Invoked after an extensive set of model changes has ended. | |
552 // This tells observers to update themselves if they were waiting for the | |
553 // update to finish. | |
554 void BookmarkTagModel::ExtensiveBookmarkChangesEnded(BookmarkModel* model) { | |
555 DCHECK(loaded_); | |
556 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
557 ExtensiveBookmarkChangesEnded(this)); | |
558 } | |
559 | |
560 // Invoked before all non-permanent bookmark nodes are removed. | |
561 void BookmarkTagModel::OnWillRemoveAllBookmarks(BookmarkModel* model) { | |
562 DCHECK(loaded_); | |
563 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
564 OnWillRemoveAllBookmarks(this)); | |
565 } | |
566 | |
567 // Invoked when all non-permanent bookmark nodes have been removed. | |
568 void BookmarkTagModel::BookmarkAllNodesRemoved(BookmarkModel* model){ | |
569 DCHECK(loaded_); | |
570 tag_to_bookmarks_.clear(); | |
571 bookmark_to_tags_.clear(); | |
572 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
573 BookmarkAllNodesRemoved(this)); | |
574 } | |
OLD | NEW |