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) { | |
sky
2013/10/11 21:57:41
const BookmarkTag& ?
noyau (Ping after 24h)
2013/10/14 23:59:39
Done.
| |
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_) | |
56 bookmark_model_->RemoveObserver(this); | |
57 } | |
58 | |
59 // 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_); | |
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 // Tags specific code. | |
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; | |
sky
2013/10/11 21:57:41
Use Autoreset.
noyau (Ping after 24h)
2013/10/14 23:59:39
Done.
| |
140 const BookmarkNode* parent = bookmark_model_->GetParentForNewNodes(); | |
141 const BookmarkNode* bookmark = bookmark_model_->AddURL( | |
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) { | |
sky
2013/10/11 21:57:41
nit: wrap
noyau (Ping after 24h)
2013/10/14 23:59:39
Done.
| |
160 std::set<BookmarkTag> all_tags(AllTagsForBookmark(bookmark)); | |
161 for (std::set<BookmarkTag>::const_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*>::const_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>::const_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*>::const_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>::const_iterator it = tags.begin(); | |
206 it != tags.end(); ++it) { | |
207 const std::set<const BookmarkNode*> subset(tag_to_bookmarks_[*it]); | |
sky
2013/10/11 21:57:41
const std::<...>& subset
noyau (Ping after 24h)
2013/10/14 23:59:39
Done.
| |
208 for (std::set<const BookmarkNode*>::const_iterator tag_it = subset.begin(); | |
sky
2013/10/11 21:57:41
bookmarks.insert(subset.begin(), subset.end())
noyau (Ping after 24h)
2013/10/14 23:59:39
I've tried this code (see patch 1) but it failed t
| |
209 tag_it != subset.end(); ++tag_it) { | |
210 bookmarks.insert(*tag_it); | |
211 } | |
212 } | |
213 | |
214 std::vector<const BookmarkNode*> sorted_bookmarks(bookmarks.begin(), | |
215 bookmarks.end()); | |
216 switch (ordering) { | |
217 case UNSORTED_BOOKMARK_ORDERING: | |
218 break; | |
219 case TITLE_BOOKMARK_ORDERING: | |
220 std::sort(sorted_bookmarks.begin(), sorted_bookmarks.end(), | |
221 CompareBookmarkTitles); | |
222 break; | |
223 case URL_BOOKMARK_ORDERING: | |
224 std::sort(sorted_bookmarks.begin(), sorted_bookmarks.end(), | |
225 CompareBookmarkUrl); | |
226 break; | |
227 case CREATION_TIME_BOOKMARK_ORDERING: | |
228 std::sort(sorted_bookmarks.begin(), sorted_bookmarks.end(), | |
229 CompareBookmarkCreation); | |
230 break; | |
231 default: | |
232 NOTREACHED(); | |
233 } | |
234 return sorted_bookmarks; | |
235 } | |
236 | |
237 std::vector<const BookmarkNode*> BookmarkTagModel::BookmarksForTag( | |
238 const BookmarkTag& tag, BookmarkOrdering ordering) { | |
sky
2013/10/11 21:57:41
nit: one line per param, and indent 2 more.
noyau (Ping after 24h)
2013/10/14 23:59:39
Done.
| |
239 DCHECK(!tag.empty()); | |
240 std::set<BookmarkTag> tagset; | |
241 tagset.insert(tag); | |
242 return BookmarksForTags(tagset, ordering); | |
243 } | |
244 | |
245 std::vector<BookmarkTag> BookmarkTagModel::TagsRelatedToTag( | |
246 const BookmarkTag& tag, BookmarkTagModel::TagOrdering ordering) { | |
247 DCHECK(loaded_); | |
248 std::map<BookmarkTag, unsigned int> tags; | |
249 | |
250 if (tag.empty()) { | |
251 // Returns all the tags. | |
252 for (std::map<const BookmarkTag, std::set<const BookmarkNode*> >::iterator | |
253 it = tag_to_bookmarks_.begin(); it != tag_to_bookmarks_.end(); ++it) { | |
254 tags[it->first] = it->second.size(); | |
255 } | |
256 } else { | |
257 std::vector<const BookmarkNode*> bookmarks( | |
258 BookmarksForTag(tag, UNSORTED_BOOKMARK_ORDERING)); | |
259 | |
260 for (std::vector<const BookmarkNode*>::iterator it = bookmarks.begin(); | |
261 it != bookmarks.end(); ++it) { | |
262 std::set<BookmarkTag> subset(bookmark_to_tags_[*it]); | |
sky
2013/10/11 21:57:41
const std::set...&
noyau (Ping after 24h)
2013/10/14 23:59:39
Done.
| |
263 for (std::set<BookmarkTag>::iterator tag_it = subset.begin(); | |
264 tag_it != subset.end(); ++tag_it) { | |
265 tags[*tag_it] += 1; | |
266 } | |
267 } | |
268 tags.erase(tag); // A tag is not related to itself. | |
269 } | |
270 | |
271 // There is no keys() method on std::map. Nobody thought it might be useful? | |
272 std::vector<BookmarkTag> sorted_tags; | |
273 for (std::map<BookmarkTag, unsigned int>::iterator it = tags.begin(); | |
274 it != tags.end(); ++it) { | |
275 sorted_tags.push_back(it->first); | |
276 } | |
277 | |
278 switch (ordering) { | |
279 case UNSORTED_TAG_ORDERING: | |
280 case ALPHABETICAL_TAG_ORDERING: | |
281 break; // std::map is already sorting its keys. | |
282 case MOST_USED_TAG_ORDERING: | |
283 std::sort(sorted_tags.begin(), sorted_tags.end(), TagComparator(tags)); | |
284 break; | |
285 default: | |
286 NOTREACHED(); | |
287 } | |
288 return sorted_tags; | |
289 } | |
290 | |
291 // Private methods. | |
292 | |
293 std::set<BookmarkTag> BookmarkTagModel::ExtractTagsFromBookmark( | |
294 const BookmarkNode *bookmark) { | |
295 DCHECK(bookmark_model_); | |
296 // This is awful BTW. Metainfo is itself an encoded JSON, and here we decode | |
297 // another layer. | |
298 | |
299 // Retrieve the encodedData from the bookmark. If there is no encoded data | |
300 // at all returns the name of all the ancestors as separate tags. | |
301 std::string encoded; | |
sky
2013/10/11 21:57:41
Could you extract this into a function and put in
noyau (Ping after 24h)
2013/10/14 23:59:39
Done.
| |
302 if (!bookmark->GetMetaInfo(TAG_KEY, &encoded)) { | |
303 std::set<BookmarkTag> tags; | |
304 const BookmarkNode* folder = bookmark->parent(); | |
305 while (folder && folder->type() == BookmarkNode::FOLDER) { | |
306 BookmarkTag trimmed_tag = CollapseWhitespace(folder->GetTitle(), true); | |
307 if (!trimmed_tag.empty()) | |
308 tags.insert(trimmed_tag); | |
309 folder = folder->parent(); | |
310 } | |
311 return tags; | |
312 } | |
313 | |
314 // Decode into a base::Value. If the data is not encoded properly as a list | |
315 // return an empty result. | |
316 JSONStringValueSerializer serializer(&encoded); | |
317 int error_code = 0; | |
318 std::string error_message; | |
319 scoped_ptr<base::Value> result(serializer.Deserialize(&error_code, | |
320 &error_message)); | |
321 | |
322 if (error_code || !result->IsType(base::Value::TYPE_LIST)) | |
323 return std::set<BookmarkTag>(); | |
324 | |
325 base::ListValue* list = NULL; | |
326 if (!result->GetAsList(&list) || list->empty()) | |
327 return std::set<BookmarkTag>(); | |
328 | |
329 // Build the set. | |
330 std::set<BookmarkTag> return_value; | |
331 | |
332 for (base::ListValue::iterator it = list->begin(); | |
333 it != list->end(); ++it) { | |
334 base::Value* item = *it; | |
335 BookmarkTag tag; | |
336 if (!item->GetAsString(&tag)) | |
337 continue; | |
338 return_value.insert(tag); | |
339 } | |
340 return return_value; | |
341 } | |
342 | |
343 void BookmarkTagModel::ReplaceTagsOnBookmark( | |
344 const std::set<BookmarkTag>& tags, const BookmarkNode *bookmark) { | |
345 DCHECK(bookmark_model_); | |
346 DCHECK(loaded_); | |
347 | |
348 // Build a ListValue. | |
349 std::vector<BookmarkTag> tag_vector(tags.begin(), tags.end()); | |
350 base::ListValue list; | |
351 list.AppendStrings(tag_vector); | |
352 | |
353 // Encodes it. | |
354 std::string encoded; | |
355 JSONStringValueSerializer serializer(&encoded); | |
356 | |
357 // Pushes it in the bookmark's metainfo. | |
358 serializer.Serialize(list); | |
359 bookmark_model_->SetNodeMetaInfo(bookmark, TAG_KEY, encoded); | |
sky
2013/10/11 21:57:41
Does encoded result in an empty string if tags is
sky
2013/10/11 21:57:41
Can you also add a comment that internal mappings
noyau (Ping after 24h)
2013/10/14 23:59:39
Done.
noyau (Ping after 24h)
2013/10/14 23:59:39
Actually no, if this is turned into an empty strin
| |
360 } | |
361 | |
362 void BookmarkTagModel::Load() { | |
363 DCHECK(bookmark_model_); | |
364 DCHECK(!loaded_); | |
365 ui::TreeNodeIterator<const BookmarkNode> iterator( | |
366 bookmark_model_->root_node()); | |
367 while (iterator.has_next()) | |
368 LoadBookmark(iterator.Next()); | |
369 loaded_ = true; | |
370 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
371 Loaded(this)); | |
372 } | |
373 | |
374 void BookmarkTagModel::LoadBookmark(const BookmarkNode* bookmark) { | |
375 DCHECK(bookmark_model_); | |
376 if (bookmark->is_url()) { | |
377 std::set<BookmarkTag> tags(ExtractTagsFromBookmark(bookmark)); | |
378 | |
379 bookmark_to_tags_[bookmark] = tags; | |
380 for (std::set<BookmarkTag>::iterator it = tags.begin(); | |
381 it != tags.end(); ++it) { | |
382 tag_to_bookmarks_[*it].insert(bookmark); | |
383 } | |
384 } | |
385 } | |
386 | |
387 void BookmarkTagModel::RemoveBookmark(const BookmarkNode* bookmark) { | |
388 DCHECK(bookmark_model_); | |
389 if (bookmark->is_url()) { | |
390 std::set<BookmarkTag> tags(bookmark_to_tags_[bookmark]); | |
391 bookmark_to_tags_.erase(bookmark); | |
392 | |
393 for (std::set<BookmarkTag>::iterator it = tags.begin(); | |
394 it != tags.end(); ++it) { | |
395 tag_to_bookmarks_[*it].erase(bookmark); | |
396 // Remove the tags no longer used. | |
397 if (!tag_to_bookmarks_[*it].size()) | |
398 tag_to_bookmarks_.erase(*it); | |
399 } | |
400 } | |
401 } | |
402 | |
403 // BookmarkModelObserver methods. | |
404 | |
405 // Invoked when the model has finished loading. | |
406 void BookmarkTagModel::Loaded(BookmarkModel* model, bool ids_reassigned) { | |
sky
2013/10/11 21:57:41
Make order match header.
| |
407 Load(); | |
408 }; | |
sky
2013/10/11 21:57:41
nit: no ;
| |
409 | |
410 // Invoked from the destructor of the BookmarkModel. | |
411 void BookmarkTagModel::BookmarkModelBeingDeleted(BookmarkModel* model) { | |
412 DCHECK(bookmark_model_); | |
413 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
414 BookmarkTagModelBeingDeleted(this)); | |
415 bookmark_model_ = NULL; | |
416 observers_.Clear(); | |
sky
2013/10/11 21:57:41
Why do you clear the observers here?
| |
417 } | |
418 | |
419 // Invoked when a node has moved. | |
420 void BookmarkTagModel::BookmarkNodeMoved(BookmarkModel* model, | |
421 const BookmarkNode* old_parent, | |
422 int old_index, | |
423 const BookmarkNode* new_parent, | |
424 int new_index) { | |
425 DCHECK(loaded_); | |
426 const BookmarkNode* bookmark = new_parent->GetChild(new_index); | |
427 std::string encoded; | |
428 if (!bookmark->GetMetaInfo(TAG_KEY, &encoded)) { | |
429 // The bookmark moved and the system currently use its ancestors name as a | |
430 // poor approximation for tags. | |
431 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
432 OnWillChangeBookmarkTags(this, bookmark)); | |
433 RemoveBookmark(bookmark); | |
434 LoadBookmark(bookmark); | |
435 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
436 BookmarkTagsChanged(this, bookmark)); | |
437 } | |
438 }; | |
439 | |
440 // Invoked when a node has been added. | |
441 void BookmarkTagModel::BookmarkNodeAdded(BookmarkModel* model, | |
442 const BookmarkNode* parent, | |
443 int index) { | |
444 DCHECK(loaded_); | |
445 const BookmarkNode* bookmark = parent->GetChild(index); | |
446 if (!bookmark->is_url()) | |
447 return; | |
448 LoadBookmark(bookmark); | |
449 | |
450 if (!inhibit_change_notifications_) | |
451 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
452 BookmarkNodeAdded(this, bookmark)); | |
453 } | |
454 | |
455 // Invoked before a node is removed. | |
456 // |parent| the parent of the node that will be removed. | |
457 // |old_index| the index of the node about to be removed in |parent|. | |
458 // |node| is the node to be removed. | |
459 void BookmarkTagModel::OnWillRemoveBookmarks(BookmarkModel* model, | |
460 const BookmarkNode* parent, | |
461 int old_index, | |
462 const BookmarkNode* node) { | |
463 DCHECK(loaded_); | |
464 RemoveBookmark(node); | |
465 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
466 OnWillRemoveBookmarks(this, node)); | |
467 } | |
468 | |
469 // Invoked when a node has been removed, the item may still be starred though. | |
470 // |parent| the parent of the node that was removed. | |
471 // |old_index| the index of the removed node in |parent| before it was | |
472 // removed. | |
473 // |node| is the node that was removed. | |
474 void BookmarkTagModel::BookmarkNodeRemoved(BookmarkModel* model, | |
475 const BookmarkNode* parent, | |
476 int old_index, | |
477 const BookmarkNode* node) { | |
478 DCHECK(loaded_); | |
479 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
480 BookmarkNodeRemoved(this, node)); | |
481 } | |
482 | |
483 // Invoked before the title or url of a node is changed. | |
484 void BookmarkTagModel::OnWillChangeBookmarkNode(BookmarkModel* model, | |
485 const BookmarkNode* node) { | |
486 DCHECK(loaded_); | |
487 if (!inhibit_change_notifications_) | |
488 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
489 OnWillChangeBookmarkNode(this, node)); | |
490 } | |
491 | |
492 // Invoked when the title or url of a node changes. | |
sky
2013/10/11 21:57:41
Might this effect the tags of all desendants if no
| |
493 void BookmarkTagModel::BookmarkNodeChanged(BookmarkModel* model, | |
494 const BookmarkNode* node) { | |
495 DCHECK(loaded_); | |
496 if (!inhibit_change_notifications_) | |
497 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
498 BookmarkNodeChanged(this, node)); | |
499 } | |
500 | |
501 // Invoked before the metainfo of a node is changed. | |
502 void BookmarkTagModel::OnWillChangeBookmarkMetaInfo(BookmarkModel* model, | |
503 const BookmarkNode* node) { | |
504 DCHECK(loaded_); | |
505 if (!inhibit_change_notifications_) | |
506 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
507 OnWillChangeBookmarkTags(this, node)); | |
508 } | |
509 | |
510 // Invoked when the metainfo on a node changes. | |
511 void BookmarkTagModel::BookmarkMetaInfoChanged(BookmarkModel* model, | |
512 const BookmarkNode* node) { | |
sky
2013/10/11 21:57:41
nit: alignment here (and many other places below).
| |
513 DCHECK(loaded_); | |
514 RemoveBookmark(node); | |
515 LoadBookmark(node); | |
516 if (!inhibit_change_notifications_) | |
517 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
518 BookmarkTagsChanged(this, node)); | |
519 } | |
520 | |
521 // Invoked when a favicon has been loaded or changed. | |
522 void BookmarkTagModel::BookmarkNodeFaviconChanged(BookmarkModel* model, | |
523 const BookmarkNode* node) { | |
524 DCHECK(loaded_); | |
525 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
526 BookmarkNodeFaviconChanged(this, node)); | |
527 } | |
528 | |
529 // Invoked before the direct children of |node| have been reordered in some | |
530 // way, such as sorted. | |
531 void BookmarkTagModel::OnWillReorderBookmarkNode(BookmarkModel* model, | |
532 const BookmarkNode* node) { | |
533 // This model doesn't care. | |
534 } | |
535 | |
536 // Invoked when the children (just direct children, not descendants) of | |
537 // |node| have been reordered in some way, such as sorted. | |
538 void BookmarkTagModel::BookmarkNodeChildrenReordered(BookmarkModel* model, | |
539 const BookmarkNode* node) { | |
540 // This model doesn't care. | |
541 } | |
542 | |
543 // Invoked before an extensive set of model changes is about to begin. | |
544 // This tells UI intensive observers to wait until the updates finish to | |
545 // update themselves. | |
546 // These methods should only be used for imports and sync. | |
547 // Observers should still respond to BookmarkNodeRemoved immediately, | |
548 // to avoid holding onto stale node pointers. | |
549 void BookmarkTagModel::ExtensiveBookmarkChangesBeginning(BookmarkModel* model) { | |
550 DCHECK(loaded_); | |
551 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
552 ExtensiveBookmarkChangesBeginning(this)); | |
553 } | |
554 | |
555 // Invoked after an extensive set of model changes has ended. | |
556 // This tells observers to update themselves if they were waiting for the | |
557 // update to finish. | |
558 void BookmarkTagModel::ExtensiveBookmarkChangesEnded(BookmarkModel* model) { | |
559 DCHECK(loaded_); | |
560 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
561 ExtensiveBookmarkChangesEnded(this)); | |
562 } | |
563 | |
564 // Invoked before all non-permanent bookmark nodes are removed. | |
565 void BookmarkTagModel::OnWillRemoveAllBookmarks(BookmarkModel* model) { | |
566 DCHECK(loaded_); | |
567 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
568 OnWillRemoveAllBookmarks(this)); | |
569 } | |
570 | |
571 // Invoked when all non-permanent bookmark nodes have been removed. | |
572 void BookmarkTagModel::BookmarkAllNodesRemoved(BookmarkModel* model){ | |
573 DCHECK(loaded_); | |
574 tag_to_bookmarks_.clear(); | |
575 bookmark_to_tags_.clear(); | |
576 FOR_EACH_OBSERVER(BookmarkTagModelObserver, observers_, | |
577 BookmarkAllNodesRemoved(this)); | |
578 } | |
OLD | NEW |