| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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_model.h" | 5 #include "chrome/browser/bookmarks/bookmark_model.h" |
| 6 | 6 |
| 7 #include "app/l10n_util.h" | 7 #include "app/l10n_util.h" |
| 8 #include "app/l10n_util_collator.h" | 8 #include "app/l10n_util_collator.h" |
| 9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/scoped_vector.h" | 10 #include "base/scoped_vector.h" |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 return; | 287 return; |
| 288 } | 288 } |
| 289 | 289 |
| 290 if (url == node->GetURL()) | 290 if (url == node->GetURL()) |
| 291 return; | 291 return; |
| 292 | 292 |
| 293 AsMutable(node)->InvalidateFavicon(); | 293 AsMutable(node)->InvalidateFavicon(); |
| 294 CancelPendingFavIconLoadRequests(AsMutable(node)); | 294 CancelPendingFavIconLoadRequests(AsMutable(node)); |
| 295 | 295 |
| 296 { | 296 { |
| 297 AutoLock url_lock(url_lock_); | 297 base::AutoLock url_lock(url_lock_); |
| 298 NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.find( | 298 NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.find( |
| 299 AsMutable(node)); | 299 AsMutable(node)); |
| 300 DCHECK(i != nodes_ordered_by_url_set_.end()); | 300 DCHECK(i != nodes_ordered_by_url_set_.end()); |
| 301 // i points to the first node with the URL, advance until we find the | 301 // i points to the first node with the URL, advance until we find the |
| 302 // node we're removing. | 302 // node we're removing. |
| 303 while (*i != node) | 303 while (*i != node) |
| 304 ++i; | 304 ++i; |
| 305 nodes_ordered_by_url_set_.erase(i); | 305 nodes_ordered_by_url_set_.erase(i); |
| 306 | 306 |
| 307 AsMutable(node)->SetURL(url); | 307 AsMutable(node)->SetURL(url); |
| 308 nodes_ordered_by_url_set_.insert(AsMutable(node)); | 308 nodes_ordered_by_url_set_.insert(AsMutable(node)); |
| 309 } | 309 } |
| 310 | 310 |
| 311 if (store_.get()) | 311 if (store_.get()) |
| 312 store_->ScheduleSave(); | 312 store_->ScheduleSave(); |
| 313 | 313 |
| 314 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 314 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 315 BookmarkNodeChanged(this, node)); | 315 BookmarkNodeChanged(this, node)); |
| 316 } | 316 } |
| 317 | 317 |
| 318 bool BookmarkModel::IsLoaded() { | 318 bool BookmarkModel::IsLoaded() { |
| 319 return loaded_; | 319 return loaded_; |
| 320 } | 320 } |
| 321 | 321 |
| 322 void BookmarkModel::GetNodesByURL(const GURL& url, | 322 void BookmarkModel::GetNodesByURL(const GURL& url, |
| 323 std::vector<const BookmarkNode*>* nodes) { | 323 std::vector<const BookmarkNode*>* nodes) { |
| 324 AutoLock url_lock(url_lock_); | 324 base::AutoLock url_lock(url_lock_); |
| 325 BookmarkNode tmp_node(url); | 325 BookmarkNode tmp_node(url); |
| 326 NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.find(&tmp_node); | 326 NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.find(&tmp_node); |
| 327 while (i != nodes_ordered_by_url_set_.end() && (*i)->GetURL() == url) { | 327 while (i != nodes_ordered_by_url_set_.end() && (*i)->GetURL() == url) { |
| 328 nodes->push_back(*i); | 328 nodes->push_back(*i); |
| 329 ++i; | 329 ++i; |
| 330 } | 330 } |
| 331 } | 331 } |
| 332 | 332 |
| 333 const BookmarkNode* BookmarkModel::GetMostRecentlyAddedNodeForURL( | 333 const BookmarkNode* BookmarkModel::GetMostRecentlyAddedNodeForURL( |
| 334 const GURL& url) { | 334 const GURL& url) { |
| 335 std::vector<const BookmarkNode*> nodes; | 335 std::vector<const BookmarkNode*> nodes; |
| 336 GetNodesByURL(url, &nodes); | 336 GetNodesByURL(url, &nodes); |
| 337 if (nodes.empty()) | 337 if (nodes.empty()) |
| 338 return NULL; | 338 return NULL; |
| 339 | 339 |
| 340 std::sort(nodes.begin(), nodes.end(), &bookmark_utils::MoreRecentlyAdded); | 340 std::sort(nodes.begin(), nodes.end(), &bookmark_utils::MoreRecentlyAdded); |
| 341 return nodes.front(); | 341 return nodes.front(); |
| 342 } | 342 } |
| 343 | 343 |
| 344 void BookmarkModel::GetBookmarks(std::vector<GURL>* urls) { | 344 void BookmarkModel::GetBookmarks(std::vector<GURL>* urls) { |
| 345 AutoLock url_lock(url_lock_); | 345 base::AutoLock url_lock(url_lock_); |
| 346 const GURL* last_url = NULL; | 346 const GURL* last_url = NULL; |
| 347 for (NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.begin(); | 347 for (NodesOrderedByURLSet::iterator i = nodes_ordered_by_url_set_.begin(); |
| 348 i != nodes_ordered_by_url_set_.end(); ++i) { | 348 i != nodes_ordered_by_url_set_.end(); ++i) { |
| 349 const GURL* url = &((*i)->GetURL()); | 349 const GURL* url = &((*i)->GetURL()); |
| 350 // Only add unique URLs. | 350 // Only add unique URLs. |
| 351 if (!last_url || *url != *last_url) | 351 if (!last_url || *url != *last_url) |
| 352 urls->push_back(*url); | 352 urls->push_back(*url); |
| 353 last_url = url; | 353 last_url = url; |
| 354 } | 354 } |
| 355 } | 355 } |
| 356 | 356 |
| 357 bool BookmarkModel::HasBookmarks() { | 357 bool BookmarkModel::HasBookmarks() { |
| 358 AutoLock url_lock(url_lock_); | 358 base::AutoLock url_lock(url_lock_); |
| 359 return !nodes_ordered_by_url_set_.empty(); | 359 return !nodes_ordered_by_url_set_.empty(); |
| 360 } | 360 } |
| 361 | 361 |
| 362 bool BookmarkModel::IsBookmarked(const GURL& url) { | 362 bool BookmarkModel::IsBookmarked(const GURL& url) { |
| 363 AutoLock url_lock(url_lock_); | 363 base::AutoLock url_lock(url_lock_); |
| 364 return IsBookmarkedNoLock(url); | 364 return IsBookmarkedNoLock(url); |
| 365 } | 365 } |
| 366 | 366 |
| 367 const BookmarkNode* BookmarkModel::GetNodeByID(int64 id) { | 367 const BookmarkNode* BookmarkModel::GetNodeByID(int64 id) { |
| 368 // TODO(sky): TreeNode needs a method that visits all nodes using a predicate. | 368 // TODO(sky): TreeNode needs a method that visits all nodes using a predicate. |
| 369 return GetNodeByID(&root_, id); | 369 return GetNodeByID(&root_, id); |
| 370 } | 370 } |
| 371 | 371 |
| 372 const BookmarkNode* BookmarkModel::AddGroup(const BookmarkNode* parent, | 372 const BookmarkNode* BookmarkModel::AddGroup(const BookmarkNode* parent, |
| 373 int index, | 373 int index, |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 | 410 |
| 411 SetDateGroupModified(parent, creation_time); | 411 SetDateGroupModified(parent, creation_time); |
| 412 | 412 |
| 413 BookmarkNode* new_node = new BookmarkNode(generate_next_node_id(), url); | 413 BookmarkNode* new_node = new BookmarkNode(generate_next_node_id(), url); |
| 414 new_node->SetTitle(title); | 414 new_node->SetTitle(title); |
| 415 new_node->set_date_added(creation_time); | 415 new_node->set_date_added(creation_time); |
| 416 new_node->set_type(BookmarkNode::URL); | 416 new_node->set_type(BookmarkNode::URL); |
| 417 | 417 |
| 418 { | 418 { |
| 419 // Only hold the lock for the duration of the insert. | 419 // Only hold the lock for the duration of the insert. |
| 420 AutoLock url_lock(url_lock_); | 420 base::AutoLock url_lock(url_lock_); |
| 421 nodes_ordered_by_url_set_.insert(new_node); | 421 nodes_ordered_by_url_set_.insert(new_node); |
| 422 } | 422 } |
| 423 | 423 |
| 424 return AddNode(AsMutable(parent), index, new_node, was_bookmarked); | 424 return AddNode(AsMutable(parent), index, new_node, was_bookmarked); |
| 425 } | 425 } |
| 426 | 426 |
| 427 void BookmarkModel::SortChildren(const BookmarkNode* parent) { | 427 void BookmarkModel::SortChildren(const BookmarkNode* parent) { |
| 428 if (!parent || !parent->is_folder() || is_root(parent) || | 428 if (!parent || !parent->is_folder() || is_root(parent) || |
| 429 parent->GetChildCount() <= 1) { | 429 parent->GetChildCount() <= 1) { |
| 430 return; | 430 return; |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 bookmark_bar_node_ = details->release_bb_node(); | 565 bookmark_bar_node_ = details->release_bb_node(); |
| 566 other_node_ = details->release_other_folder_node(); | 566 other_node_ = details->release_other_folder_node(); |
| 567 index_.reset(details->release_index()); | 567 index_.reset(details->release_index()); |
| 568 | 568 |
| 569 // WARNING: order is important here, various places assume bookmark bar then | 569 // WARNING: order is important here, various places assume bookmark bar then |
| 570 // other node. | 570 // other node. |
| 571 root_.Add(0, bookmark_bar_node_); | 571 root_.Add(0, bookmark_bar_node_); |
| 572 root_.Add(1, other_node_); | 572 root_.Add(1, other_node_); |
| 573 | 573 |
| 574 { | 574 { |
| 575 AutoLock url_lock(url_lock_); | 575 base::AutoLock url_lock(url_lock_); |
| 576 // Update nodes_ordered_by_url_set_ from the nodes. | 576 // Update nodes_ordered_by_url_set_ from the nodes. |
| 577 PopulateNodesByURL(&root_); | 577 PopulateNodesByURL(&root_); |
| 578 } | 578 } |
| 579 | 579 |
| 580 loaded_ = true; | 580 loaded_ = true; |
| 581 | 581 |
| 582 loaded_signal_.Signal(); | 582 loaded_signal_.Signal(); |
| 583 | 583 |
| 584 // Notify our direct observers. | 584 // Notify our direct observers. |
| 585 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, Loaded(this)); | 585 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, Loaded(this)); |
| 586 | 586 |
| 587 // And generic notification. | 587 // And generic notification. |
| 588 NotificationService::current()->Notify( | 588 NotificationService::current()->Notify( |
| 589 NotificationType::BOOKMARK_MODEL_LOADED, | 589 NotificationType::BOOKMARK_MODEL_LOADED, |
| 590 Source<Profile>(profile_), | 590 Source<Profile>(profile_), |
| 591 NotificationService::NoDetails()); | 591 NotificationService::NoDetails()); |
| 592 } | 592 } |
| 593 | 593 |
| 594 void BookmarkModel::RemoveAndDeleteNode(BookmarkNode* delete_me) { | 594 void BookmarkModel::RemoveAndDeleteNode(BookmarkNode* delete_me) { |
| 595 scoped_ptr<BookmarkNode> node(delete_me); | 595 scoped_ptr<BookmarkNode> node(delete_me); |
| 596 | 596 |
| 597 BookmarkNode* parent = AsMutable(node->GetParent()); | 597 BookmarkNode* parent = AsMutable(node->GetParent()); |
| 598 DCHECK(parent); | 598 DCHECK(parent); |
| 599 int index = parent->IndexOfChild(node.get()); | 599 int index = parent->IndexOfChild(node.get()); |
| 600 parent->Remove(index); | 600 parent->Remove(index); |
| 601 history::URLsStarredDetails details(false); | 601 history::URLsStarredDetails details(false); |
| 602 { | 602 { |
| 603 AutoLock url_lock(url_lock_); | 603 base::AutoLock url_lock(url_lock_); |
| 604 RemoveNode(node.get(), &details.changed_urls); | 604 RemoveNode(node.get(), &details.changed_urls); |
| 605 | 605 |
| 606 // RemoveNode adds an entry to changed_urls for each node of type URL. As we | 606 // RemoveNode adds an entry to changed_urls for each node of type URL. As we |
| 607 // allow duplicates we need to remove any entries that are still bookmarked. | 607 // allow duplicates we need to remove any entries that are still bookmarked. |
| 608 for (std::set<GURL>::iterator i = details.changed_urls.begin(); | 608 for (std::set<GURL>::iterator i = details.changed_urls.begin(); |
| 609 i != details.changed_urls.end(); ) { | 609 i != details.changed_urls.end(); ) { |
| 610 if (IsBookmarkedNoLock(*i)) { | 610 if (IsBookmarkedNoLock(*i)) { |
| 611 // When we erase the iterator pointing at the erasee is | 611 // When we erase the iterator pointing at the erasee is |
| 612 // invalidated, so using i++ here within the "erase" call is | 612 // invalidated, so using i++ here within the "erase" call is |
| 613 // important as it advances the iterator before passing the | 613 // important as it advances the iterator before passing the |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 820 void BookmarkModel::SetFileChanged() { | 820 void BookmarkModel::SetFileChanged() { |
| 821 file_changed_ = true; | 821 file_changed_ = true; |
| 822 } | 822 } |
| 823 | 823 |
| 824 BookmarkLoadDetails* BookmarkModel::CreateLoadDetails() { | 824 BookmarkLoadDetails* BookmarkModel::CreateLoadDetails() { |
| 825 BookmarkNode* bb_node = CreateBookmarkNode(); | 825 BookmarkNode* bb_node = CreateBookmarkNode(); |
| 826 BookmarkNode* other_folder_node = CreateOtherBookmarksNode(); | 826 BookmarkNode* other_folder_node = CreateOtherBookmarksNode(); |
| 827 return new BookmarkLoadDetails( | 827 return new BookmarkLoadDetails( |
| 828 bb_node, other_folder_node, new BookmarkIndex(profile()), next_node_id_); | 828 bb_node, other_folder_node, new BookmarkIndex(profile()), next_node_id_); |
| 829 } | 829 } |
| OLD | NEW |