| 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_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 "base/gfx/png_decoder.h" | 8 #include "base/gfx/png_decoder.h" |
| 9 #include "base/scoped_vector.h" | 9 #include "base/scoped_vector.h" |
| 10 #include "build/build_config.h" | 10 #include "build/build_config.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 | 28 |
| 29 } // anonymous namespace | 29 } // anonymous namespace |
| 30 | 30 |
| 31 // BookmarkNode --------------------------------------------------------------- | 31 // BookmarkNode --------------------------------------------------------------- |
| 32 | 32 |
| 33 BookmarkNode::BookmarkNode(const GURL& url) | 33 BookmarkNode::BookmarkNode(const GURL& url) |
| 34 : url_(url) { | 34 : url_(url) { |
| 35 Initialize(0); | 35 Initialize(0); |
| 36 } | 36 } |
| 37 | 37 |
| 38 BookmarkNode::BookmarkNode(int id, const GURL& url) | 38 BookmarkNode::BookmarkNode(int64 id, const GURL& url) |
| 39 : url_(url){ | 39 : url_(url){ |
| 40 Initialize(id); | 40 Initialize(id); |
| 41 } | 41 } |
| 42 | 42 |
| 43 void BookmarkNode::Initialize(int id) { | 43 void BookmarkNode::Initialize(int64 id) { |
| 44 id_ = id; | 44 id_ = id; |
| 45 loaded_favicon_ = false; | 45 loaded_favicon_ = false; |
| 46 favicon_load_handle_ = 0; | 46 favicon_load_handle_ = 0; |
| 47 type_ = !url_.is_empty() ? URL : BOOKMARK_BAR; | 47 type_ = !url_.is_empty() ? URL : BOOKMARK_BAR; |
| 48 date_added_ = Time::Now(); | 48 date_added_ = Time::Now(); |
| 49 } | 49 } |
| 50 | 50 |
| 51 void BookmarkNode::Reset(const history::StarredEntry& entry) { | 51 void BookmarkNode::Reset(const history::StarredEntry& entry) { |
| 52 DCHECK(entry.type != history::StarredEntry::URL || entry.url == url_); | 52 DCHECK(entry.type != history::StarredEntry::URL || entry.url == url_); |
| 53 | 53 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 70 } | 70 } |
| 71 date_added_ = entry.date_added; | 71 date_added_ = entry.date_added; |
| 72 date_group_modified_ = entry.date_group_modified; | 72 date_group_modified_ = entry.date_group_modified; |
| 73 SetTitle(entry.title); | 73 SetTitle(entry.title); |
| 74 } | 74 } |
| 75 | 75 |
| 76 // BookmarkModel -------------------------------------------------------------- | 76 // BookmarkModel -------------------------------------------------------------- |
| 77 | 77 |
| 78 namespace { | 78 namespace { |
| 79 | 79 |
| 80 // Constant for persist IDs prefernece. | |
| 81 const wchar_t kPrefPersistIDs[] = L"bookmarks.persist_ids"; | |
| 82 | |
| 83 // Comparator used when sorting bookmarks. Folders are sorted first, then | 80 // Comparator used when sorting bookmarks. Folders are sorted first, then |
| 84 // bookmarks. | 81 // bookmarks. |
| 85 class SortComparator : public std::binary_function<const BookmarkNode*, | 82 class SortComparator : public std::binary_function<const BookmarkNode*, |
| 86 const BookmarkNode*, | 83 const BookmarkNode*, |
| 87 bool> { | 84 bool> { |
| 88 public: | 85 public: |
| 89 explicit SortComparator(Collator* collator) : collator_(collator) { } | 86 explicit SortComparator(Collator* collator) : collator_(collator) { } |
| 90 | 87 |
| 91 // Returns true if lhs preceeds rhs. | 88 // Returns true if lhs preceeds rhs. |
| 92 bool operator() (const BookmarkNode* n1, const BookmarkNode* n2) { | 89 bool operator() (const BookmarkNode* n1, const BookmarkNode* n2) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 103 | 100 |
| 104 private: | 101 private: |
| 105 Collator* collator_; | 102 Collator* collator_; |
| 106 }; | 103 }; |
| 107 | 104 |
| 108 } // namespace | 105 } // namespace |
| 109 | 106 |
| 110 BookmarkModel::BookmarkModel(Profile* profile) | 107 BookmarkModel::BookmarkModel(Profile* profile) |
| 111 : profile_(profile), | 108 : profile_(profile), |
| 112 loaded_(false), | 109 loaded_(false), |
| 113 persist_ids_(false), | |
| 114 file_changed_(false), | 110 file_changed_(false), |
| 115 root_(GURL()), | 111 root_(GURL()), |
| 116 bookmark_bar_node_(NULL), | 112 bookmark_bar_node_(NULL), |
| 117 other_node_(NULL), | 113 other_node_(NULL), |
| 118 next_node_id_(1), | 114 next_node_id_(1), |
| 119 observers_(ObserverList<BookmarkModelObserver>::NOTIFY_EXISTING_ONLY), | 115 observers_(ObserverList<BookmarkModelObserver>::NOTIFY_EXISTING_ONLY), |
| 120 loaded_signal_(TRUE, FALSE) { | 116 loaded_signal_(TRUE, FALSE) { |
| 121 if (!profile_) { | 117 if (!profile_) { |
| 122 // Profile is null during testing. | 118 // Profile is null during testing. |
| 123 DoneLoading(CreateLoadDetails()); | 119 DoneLoading(CreateLoadDetails()); |
| 124 } | 120 } |
| 125 RegisterPreferences(); | |
| 126 LoadPreferences(); | |
| 127 } | 121 } |
| 128 | 122 |
| 129 BookmarkModel::~BookmarkModel() { | 123 BookmarkModel::~BookmarkModel() { |
| 130 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 124 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 131 BookmarkModelBeingDeleted(this)); | 125 BookmarkModelBeingDeleted(this)); |
| 132 | 126 |
| 133 if (store_) { | 127 if (store_) { |
| 134 // The store maintains a reference back to us. We need to tell it we're gone | 128 // The store maintains a reference back to us. We need to tell it we're gone |
| 135 // so that it doesn't try and invoke a method back on us again. | 129 // so that it doesn't try and invoke a method back on us again. |
| 136 store_->BookmarkModelDeleted(); | 130 store_->BookmarkModelDeleted(); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 urls->push_back(*url); | 269 urls->push_back(*url); |
| 276 last_url = url; | 270 last_url = url; |
| 277 } | 271 } |
| 278 } | 272 } |
| 279 | 273 |
| 280 bool BookmarkModel::IsBookmarked(const GURL& url) { | 274 bool BookmarkModel::IsBookmarked(const GURL& url) { |
| 281 AutoLock url_lock(url_lock_); | 275 AutoLock url_lock(url_lock_); |
| 282 return IsBookmarkedNoLock(url); | 276 return IsBookmarkedNoLock(url); |
| 283 } | 277 } |
| 284 | 278 |
| 285 const BookmarkNode* BookmarkModel::GetNodeByID(int id) { | 279 const BookmarkNode* BookmarkModel::GetNodeByID(int64 id) { |
| 286 // TODO(sky): TreeNode needs a method that visits all nodes using a predicate. | 280 // TODO(sky): TreeNode needs a method that visits all nodes using a predicate. |
| 287 return GetNodeByID(&root_, id); | 281 return GetNodeByID(&root_, id); |
| 288 } | 282 } |
| 289 | 283 |
| 290 const BookmarkNode* BookmarkModel::AddGroup(const BookmarkNode* parent, | 284 const BookmarkNode* BookmarkModel::AddGroup(const BookmarkNode* parent, |
| 291 int index, | 285 int index, |
| 292 const std::wstring& title) { | 286 const std::wstring& title) { |
| 293 if (!loaded_ || parent == &root_ || !IsValidIndex(parent, index, true)) { | 287 if (!loaded_ || parent == &root_ || !IsValidIndex(parent, index, true)) { |
| 294 // Can't add to the root. | 288 // Can't add to the root. |
| 295 NOTREACHED(); | 289 NOTREACHED(); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 return; | 395 return; |
| 402 | 396 |
| 403 index_->GetBookmarksWithTitlesMatching(text, max_count, matches); | 397 index_->GetBookmarksWithTitlesMatching(text, max_count, matches); |
| 404 } | 398 } |
| 405 | 399 |
| 406 void BookmarkModel::ClearStore() { | 400 void BookmarkModel::ClearStore() { |
| 407 registrar_.RemoveAll(); | 401 registrar_.RemoveAll(); |
| 408 store_ = NULL; | 402 store_ = NULL; |
| 409 } | 403 } |
| 410 | 404 |
| 411 void BookmarkModel::SetPersistIDs(bool value) { | |
| 412 if (value == persist_ids_) | |
| 413 return; | |
| 414 persist_ids_ = value; | |
| 415 if (profile_) { | |
| 416 PrefService* pref_service = profile_->GetPrefs(); | |
| 417 pref_service->SetBoolean(kPrefPersistIDs, persist_ids_); | |
| 418 } | |
| 419 // Need to save the bookmark data if the value of persist IDs changes. | |
| 420 if (store_.get()) | |
| 421 store_->ScheduleSave(); | |
| 422 } | |
| 423 | |
| 424 bool BookmarkModel::IsBookmarkedNoLock(const GURL& url) { | 405 bool BookmarkModel::IsBookmarkedNoLock(const GURL& url) { |
| 425 BookmarkNode tmp_node(url); | 406 BookmarkNode tmp_node(url); |
| 426 return (nodes_ordered_by_url_set_.find(&tmp_node) != | 407 return (nodes_ordered_by_url_set_.find(&tmp_node) != |
| 427 nodes_ordered_by_url_set_.end()); | 408 nodes_ordered_by_url_set_.end()); |
| 428 } | 409 } |
| 429 | 410 |
| 430 void BookmarkModel::FavIconLoaded(const BookmarkNode* node) { | 411 void BookmarkModel::FavIconLoaded(const BookmarkNode* node) { |
| 431 // Send out notification to the observer. | 412 // Send out notification to the observer. |
| 432 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 413 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 433 BookmarkNodeFavIconLoaded(this, node)); | 414 BookmarkNodeFavIconLoaded(this, node)); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 // We should only ever be loaded once. | 451 // We should only ever be loaded once. |
| 471 NOTREACHED(); | 452 NOTREACHED(); |
| 472 return; | 453 return; |
| 473 } | 454 } |
| 474 | 455 |
| 475 bookmark_bar_node_ = details->bb_node(); | 456 bookmark_bar_node_ = details->bb_node(); |
| 476 other_node_ = details->other_folder_node(); | 457 other_node_ = details->other_folder_node(); |
| 477 next_node_id_ = details->max_id(); | 458 next_node_id_ = details->max_id(); |
| 478 if (details->computed_checksum() != details->stored_checksum()) | 459 if (details->computed_checksum() != details->stored_checksum()) |
| 479 SetFileChanged(); | 460 SetFileChanged(); |
| 461 if (details->computed_checksum() != details->stored_checksum() || |
| 462 details->ids_reassigned()) { |
| 463 // If bookmarks file changed externally, the IDs may have changed |
| 464 // externally. In that case, the decoder may have reassigned IDs to make |
| 465 // them unique. So when the file has changed externally, we should save the |
| 466 // bookmarks file to persist new IDs. |
| 467 if (store_.get()) |
| 468 store_->ScheduleSave(); |
| 469 } |
| 480 index_.reset(details->index()); | 470 index_.reset(details->index()); |
| 481 details->release(); | 471 details->release(); |
| 482 | 472 |
| 483 // WARNING: order is important here, various places assume bookmark bar then | 473 // WARNING: order is important here, various places assume bookmark bar then |
| 484 // other node. | 474 // other node. |
| 485 root_.Add(0, bookmark_bar_node_); | 475 root_.Add(0, bookmark_bar_node_); |
| 486 root_.Add(1, other_node_); | 476 root_.Add(1, other_node_); |
| 487 | 477 |
| 488 { | 478 { |
| 489 AutoLock url_lock(url_lock_); | 479 AutoLock url_lock(url_lock_); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 580 Details<history::URLsStarredDetails>(&details)); | 570 Details<history::URLsStarredDetails>(&details)); |
| 581 } | 571 } |
| 582 return node; | 572 return node; |
| 583 } | 573 } |
| 584 | 574 |
| 585 void BookmarkModel::BlockTillLoaded() { | 575 void BookmarkModel::BlockTillLoaded() { |
| 586 loaded_signal_.Wait(); | 576 loaded_signal_.Wait(); |
| 587 } | 577 } |
| 588 | 578 |
| 589 const BookmarkNode* BookmarkModel::GetNodeByID(const BookmarkNode* node, | 579 const BookmarkNode* BookmarkModel::GetNodeByID(const BookmarkNode* node, |
| 590 int id) { | 580 int64 id) { |
| 591 if (node->id() == id) | 581 if (node->id() == id) |
| 592 return node; | 582 return node; |
| 593 | 583 |
| 594 for (int i = 0, child_count = node->GetChildCount(); i < child_count; ++i) { | 584 for (int i = 0, child_count = node->GetChildCount(); i < child_count; ++i) { |
| 595 const BookmarkNode* result = GetNodeByID(node->GetChild(i), id); | 585 const BookmarkNode* result = GetNodeByID(node->GetChild(i), id); |
| 596 if (result) | 586 if (result) |
| 597 return result; | 587 return result; |
| 598 } | 588 } |
| 599 return NULL; | 589 return NULL; |
| 600 } | 590 } |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 718 | 708 |
| 719 void BookmarkModel::PopulateNodesByURL(BookmarkNode* node) { | 709 void BookmarkModel::PopulateNodesByURL(BookmarkNode* node) { |
| 720 // NOTE: this is called with url_lock_ already held. As such, this doesn't | 710 // NOTE: this is called with url_lock_ already held. As such, this doesn't |
| 721 // explicitly grab the lock. | 711 // explicitly grab the lock. |
| 722 if (node->is_url()) | 712 if (node->is_url()) |
| 723 nodes_ordered_by_url_set_.insert(node); | 713 nodes_ordered_by_url_set_.insert(node); |
| 724 for (int i = 0; i < node->GetChildCount(); ++i) | 714 for (int i = 0; i < node->GetChildCount(); ++i) |
| 725 PopulateNodesByURL(node->GetChild(i)); | 715 PopulateNodesByURL(node->GetChild(i)); |
| 726 } | 716 } |
| 727 | 717 |
| 728 int BookmarkModel::generate_next_node_id() { | 718 int64 BookmarkModel::generate_next_node_id() { |
| 729 return next_node_id_++; | 719 return next_node_id_++; |
| 730 } | 720 } |
| 731 | 721 |
| 732 void BookmarkModel::SetFileChanged() { | 722 void BookmarkModel::SetFileChanged() { |
| 733 file_changed_ = true; | 723 file_changed_ = true; |
| 734 // If bookmarks file changed externally, the IDs may have changed externally. | |
| 735 // in that case, the decoder may have reassigned IDs to make them unique. | |
| 736 // So when the file has changed externally and IDs are persisted, we should | |
| 737 // save the bookmarks file to persist new IDs. | |
| 738 if (persist_ids_ && store_.get()) | |
| 739 store_->ScheduleSave(); | |
| 740 } | 724 } |
| 741 | 725 |
| 742 BookmarkStorage::LoadDetails* BookmarkModel::CreateLoadDetails() { | 726 BookmarkStorage::LoadDetails* BookmarkModel::CreateLoadDetails() { |
| 743 BookmarkNode* bb_node = CreateBookmarkNode(); | 727 BookmarkNode* bb_node = CreateBookmarkNode(); |
| 744 BookmarkNode* other_folder_node = CreateOtherBookmarksNode(); | 728 BookmarkNode* other_folder_node = CreateOtherBookmarksNode(); |
| 745 return new BookmarkStorage::LoadDetails( | 729 return new BookmarkStorage::LoadDetails( |
| 746 bb_node, other_folder_node, new BookmarkIndex(), next_node_id_); | 730 bb_node, other_folder_node, new BookmarkIndex(), next_node_id_); |
| 747 } | 731 } |
| 748 | |
| 749 void BookmarkModel::RegisterPreferences() { | |
| 750 if (!profile_) | |
| 751 return; | |
| 752 PrefService* pref_service = profile_->GetPrefs(); | |
| 753 if (!pref_service->IsPrefRegistered(kPrefPersistIDs)) | |
| 754 pref_service->RegisterBooleanPref(kPrefPersistIDs, false); | |
| 755 } | |
| 756 | |
| 757 void BookmarkModel::LoadPreferences() { | |
| 758 if (!profile_) | |
| 759 return; | |
| 760 PrefService* pref_service = profile_->GetPrefs(); | |
| 761 persist_ids_ = pref_service->GetBoolean(kPrefPersistIDs); | |
| 762 } | |
| OLD | NEW |