Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(766)

Side by Side Diff: chrome/browser/bookmark_bar_model.cc

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

Powered by Google App Engine
This is Rietveld 408576698