| 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() ? history::StarredEntry::URL : | 47 type_ = !url_.is_empty() ? history::StarredEntry::URL : |
| 48 history::StarredEntry::BOOKMARK_BAR; | 48 history::StarredEntry::BOOKMARK_BAR; |
| 49 date_added_ = Time::Now(); | 49 date_added_ = Time::Now(); |
| 50 } | 50 } |
| 51 | 51 |
| 52 void BookmarkNode::Reset(const history::StarredEntry& entry) { | 52 void BookmarkNode::Reset(const history::StarredEntry& entry) { |
| 53 DCHECK(entry.type != history::StarredEntry::URL || | 53 DCHECK(entry.type != history::StarredEntry::URL || |
| 54 entry.url == url_); | 54 entry.url == url_); |
| 55 | 55 |
| 56 favicon_ = SkBitmap(); | 56 favicon_ = SkBitmap(); |
| 57 type_ = entry.type; | 57 type_ = entry.type; |
| 58 date_added_ = entry.date_added; | 58 date_added_ = entry.date_added; |
| 59 date_group_modified_ = entry.date_group_modified; | 59 date_group_modified_ = entry.date_group_modified; |
| 60 SetTitle(entry.title); | 60 SetTitle(entry.title); |
| 61 } | 61 } |
| 62 | 62 |
| 63 // BookmarkModel -------------------------------------------------------------- | 63 // BookmarkModel -------------------------------------------------------------- |
| 64 | 64 |
| 65 namespace { | 65 namespace { |
| 66 | 66 |
| 67 // Constant for persist IDs prefernece. | |
| 68 const wchar_t kPrefPersistIDs[] = L"bookmarks.persist_ids"; | |
| 69 | |
| 70 // Comparator used when sorting bookmarks. Folders are sorted first, then | 67 // Comparator used when sorting bookmarks. Folders are sorted first, then |
| 71 // bookmarks. | 68 // bookmarks. |
| 72 class SortComparator : public std::binary_function<const BookmarkNode*, | 69 class SortComparator : public std::binary_function<const BookmarkNode*, |
| 73 const BookmarkNode*, | 70 const BookmarkNode*, |
| 74 bool> { | 71 bool> { |
| 75 public: | 72 public: |
| 76 explicit SortComparator(Collator* collator) : collator_(collator) { } | 73 explicit SortComparator(Collator* collator) : collator_(collator) { } |
| 77 | 74 |
| 78 // Returns true if lhs preceeds rhs. | 75 // Returns true if lhs preceeds rhs. |
| 79 bool operator() (const BookmarkNode* n1, const BookmarkNode* n2) { | 76 bool operator() (const BookmarkNode* n1, const BookmarkNode* n2) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 90 | 87 |
| 91 private: | 88 private: |
| 92 Collator* collator_; | 89 Collator* collator_; |
| 93 }; | 90 }; |
| 94 | 91 |
| 95 } // namespace | 92 } // namespace |
| 96 | 93 |
| 97 BookmarkModel::BookmarkModel(Profile* profile) | 94 BookmarkModel::BookmarkModel(Profile* profile) |
| 98 : profile_(profile), | 95 : profile_(profile), |
| 99 loaded_(false), | 96 loaded_(false), |
| 100 persist_ids_(false), | |
| 101 file_changed_(false), | 97 file_changed_(false), |
| 102 root_(GURL()), | 98 root_(GURL()), |
| 103 bookmark_bar_node_(NULL), | 99 bookmark_bar_node_(NULL), |
| 104 other_node_(NULL), | 100 other_node_(NULL), |
| 105 next_node_id_(1), | 101 next_node_id_(1), |
| 106 observers_(ObserverList<BookmarkModelObserver>::NOTIFY_EXISTING_ONLY), | 102 observers_(ObserverList<BookmarkModelObserver>::NOTIFY_EXISTING_ONLY), |
| 107 loaded_signal_(TRUE, FALSE) { | 103 loaded_signal_(TRUE, FALSE) { |
| 108 if (!profile_) { | 104 if (!profile_) { |
| 109 // Profile is null during testing. | 105 // Profile is null during testing. |
| 110 DoneLoading(CreateLoadDetails()); | 106 DoneLoading(CreateLoadDetails()); |
| 111 } | 107 } |
| 112 RegisterPreferences(); | |
| 113 LoadPreferences(); | |
| 114 } | 108 } |
| 115 | 109 |
| 116 BookmarkModel::~BookmarkModel() { | 110 BookmarkModel::~BookmarkModel() { |
| 117 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 111 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 118 BookmarkModelBeingDeleted(this)); | 112 BookmarkModelBeingDeleted(this)); |
| 119 | 113 |
| 120 if (store_) { | 114 if (store_) { |
| 121 // The store maintains a reference back to us. We need to tell it we're gone | 115 // The store maintains a reference back to us. We need to tell it we're gone |
| 122 // so that it doesn't try and invoke a method back on us again. | 116 // so that it doesn't try and invoke a method back on us again. |
| 123 store_->BookmarkModelDeleted(); | 117 store_->BookmarkModelDeleted(); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 urls->push_back(*url); | 256 urls->push_back(*url); |
| 263 last_url = url; | 257 last_url = url; |
| 264 } | 258 } |
| 265 } | 259 } |
| 266 | 260 |
| 267 bool BookmarkModel::IsBookmarked(const GURL& url) { | 261 bool BookmarkModel::IsBookmarked(const GURL& url) { |
| 268 AutoLock url_lock(url_lock_); | 262 AutoLock url_lock(url_lock_); |
| 269 return IsBookmarkedNoLock(url); | 263 return IsBookmarkedNoLock(url); |
| 270 } | 264 } |
| 271 | 265 |
| 272 const BookmarkNode* BookmarkModel::GetNodeByID(int id) { | 266 const BookmarkNode* BookmarkModel::GetNodeByID(int64 id) { |
| 273 // TODO(sky): TreeNode needs a method that visits all nodes using a predicate. | 267 // TODO(sky): TreeNode needs a method that visits all nodes using a predicate. |
| 274 return GetNodeByID(&root_, id); | 268 return GetNodeByID(&root_, id); |
| 275 } | 269 } |
| 276 | 270 |
| 277 const BookmarkNode* BookmarkModel::AddGroup(const BookmarkNode* parent, | 271 const BookmarkNode* BookmarkModel::AddGroup(const BookmarkNode* parent, |
| 278 int index, | 272 int index, |
| 279 const std::wstring& title) { | 273 const std::wstring& title) { |
| 280 if (!loaded_ || parent == &root_ || !IsValidIndex(parent, index, true)) { | 274 if (!loaded_ || parent == &root_ || !IsValidIndex(parent, index, true)) { |
| 281 // Can't add to the root. | 275 // Can't add to the root. |
| 282 NOTREACHED(); | 276 NOTREACHED(); |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 return; | 382 return; |
| 389 | 383 |
| 390 index_->GetBookmarksWithTitlesMatching(text, max_count, matches); | 384 index_->GetBookmarksWithTitlesMatching(text, max_count, matches); |
| 391 } | 385 } |
| 392 | 386 |
| 393 void BookmarkModel::ClearStore() { | 387 void BookmarkModel::ClearStore() { |
| 394 registrar_.RemoveAll(); | 388 registrar_.RemoveAll(); |
| 395 store_ = NULL; | 389 store_ = NULL; |
| 396 } | 390 } |
| 397 | 391 |
| 398 void BookmarkModel::SetPersistIDs(bool value) { | |
| 399 if (value == persist_ids_) | |
| 400 return; | |
| 401 persist_ids_ = value; | |
| 402 if (profile_) { | |
| 403 PrefService* pref_service = profile_->GetPrefs(); | |
| 404 pref_service->SetBoolean(kPrefPersistIDs, persist_ids_); | |
| 405 } | |
| 406 // Need to save the bookmark data if the value of persist IDs changes. | |
| 407 if (store_.get()) | |
| 408 store_->ScheduleSave(); | |
| 409 } | |
| 410 | |
| 411 bool BookmarkModel::IsBookmarkedNoLock(const GURL& url) { | 392 bool BookmarkModel::IsBookmarkedNoLock(const GURL& url) { |
| 412 BookmarkNode tmp_node(url); | 393 BookmarkNode tmp_node(url); |
| 413 return (nodes_ordered_by_url_set_.find(&tmp_node) != | 394 return (nodes_ordered_by_url_set_.find(&tmp_node) != |
| 414 nodes_ordered_by_url_set_.end()); | 395 nodes_ordered_by_url_set_.end()); |
| 415 } | 396 } |
| 416 | 397 |
| 417 void BookmarkModel::FavIconLoaded(const BookmarkNode* node) { | 398 void BookmarkModel::FavIconLoaded(const BookmarkNode* node) { |
| 418 // Send out notification to the observer. | 399 // Send out notification to the observer. |
| 419 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 400 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| 420 BookmarkNodeFavIconLoaded(this, node)); | 401 BookmarkNodeFavIconLoaded(this, node)); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 // We should only ever be loaded once. | 438 // We should only ever be loaded once. |
| 458 NOTREACHED(); | 439 NOTREACHED(); |
| 459 return; | 440 return; |
| 460 } | 441 } |
| 461 | 442 |
| 462 bookmark_bar_node_ = details->bb_node(); | 443 bookmark_bar_node_ = details->bb_node(); |
| 463 other_node_ = details->other_folder_node(); | 444 other_node_ = details->other_folder_node(); |
| 464 next_node_id_ = details->max_id(); | 445 next_node_id_ = details->max_id(); |
| 465 if (details->computed_checksum() != details->stored_checksum()) | 446 if (details->computed_checksum() != details->stored_checksum()) |
| 466 SetFileChanged(); | 447 SetFileChanged(); |
| 448 if (details->computed_checksum() != details->stored_checksum() || |
| 449 details->ids_reassigned()) { |
| 450 // If bookmarks file changed externally, the IDs may have changed |
| 451 // externally. In that case, the decoder may have reassigned IDs to make |
| 452 // them unique. So when the file has changed externally, we should save the |
| 453 // bookmarks file to persist new IDs. |
| 454 if (store_.get()) |
| 455 store_->ScheduleSave(); |
| 456 } |
| 467 index_.reset(details->index()); | 457 index_.reset(details->index()); |
| 468 details->release(); | 458 details->release(); |
| 469 | 459 |
| 470 // WARNING: order is important here, various places assume bookmark bar then | 460 // WARNING: order is important here, various places assume bookmark bar then |
| 471 // other node. | 461 // other node. |
| 472 root_.Add(0, bookmark_bar_node_); | 462 root_.Add(0, bookmark_bar_node_); |
| 473 root_.Add(1, other_node_); | 463 root_.Add(1, other_node_); |
| 474 | 464 |
| 475 { | 465 { |
| 476 AutoLock url_lock(url_lock_); | 466 AutoLock url_lock(url_lock_); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 Details<history::URLsStarredDetails>(&details)); | 557 Details<history::URLsStarredDetails>(&details)); |
| 568 } | 558 } |
| 569 return node; | 559 return node; |
| 570 } | 560 } |
| 571 | 561 |
| 572 void BookmarkModel::BlockTillLoaded() { | 562 void BookmarkModel::BlockTillLoaded() { |
| 573 loaded_signal_.Wait(); | 563 loaded_signal_.Wait(); |
| 574 } | 564 } |
| 575 | 565 |
| 576 const BookmarkNode* BookmarkModel::GetNodeByID(const BookmarkNode* node, | 566 const BookmarkNode* BookmarkModel::GetNodeByID(const BookmarkNode* node, |
| 577 int id) { | 567 int64 id) { |
| 578 if (node->id() == id) | 568 if (node->id() == id) |
| 579 return node; | 569 return node; |
| 580 | 570 |
| 581 for (int i = 0; i < node->GetChildCount(); ++i) { | 571 for (int i = 0; i < node->GetChildCount(); ++i) { |
| 582 const BookmarkNode* result = GetNodeByID(node->GetChild(i), id); | 572 const BookmarkNode* result = GetNodeByID(node->GetChild(i), id); |
| 583 if (result) | 573 if (result) |
| 584 return result; | 574 return result; |
| 585 } | 575 } |
| 586 return NULL; | 576 return NULL; |
| 587 } | 577 } |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 | 695 |
| 706 void BookmarkModel::PopulateNodesByURL(BookmarkNode* node) { | 696 void BookmarkModel::PopulateNodesByURL(BookmarkNode* node) { |
| 707 // NOTE: this is called with url_lock_ already held. As such, this doesn't | 697 // NOTE: this is called with url_lock_ already held. As such, this doesn't |
| 708 // explicitly grab the lock. | 698 // explicitly grab the lock. |
| 709 if (node->is_url()) | 699 if (node->is_url()) |
| 710 nodes_ordered_by_url_set_.insert(node); | 700 nodes_ordered_by_url_set_.insert(node); |
| 711 for (int i = 0; i < node->GetChildCount(); ++i) | 701 for (int i = 0; i < node->GetChildCount(); ++i) |
| 712 PopulateNodesByURL(node->GetChild(i)); | 702 PopulateNodesByURL(node->GetChild(i)); |
| 713 } | 703 } |
| 714 | 704 |
| 715 int BookmarkModel::generate_next_node_id() { | 705 int64 BookmarkModel::generate_next_node_id() { |
| 716 return next_node_id_++; | 706 return next_node_id_++; |
| 717 } | 707 } |
| 718 | 708 |
| 719 void BookmarkModel::SetFileChanged() { | 709 void BookmarkModel::SetFileChanged() { |
| 720 file_changed_ = true; | 710 file_changed_ = true; |
| 721 // If bookmarks file changed externally, the IDs may have changed externally. | |
| 722 // in that case, the decoder may have reassigned IDs to make them unique. | |
| 723 // So when the file has changed externally and IDs are persisted, we should | |
| 724 // save the bookmarks file to persist new IDs. | |
| 725 if (persist_ids_ && store_.get()) | |
| 726 store_->ScheduleSave(); | |
| 727 } | 711 } |
| 728 | 712 |
| 729 BookmarkStorage::LoadDetails* BookmarkModel::CreateLoadDetails() { | 713 BookmarkStorage::LoadDetails* BookmarkModel::CreateLoadDetails() { |
| 730 BookmarkNode* bb_node = CreateBookmarkNode(); | 714 BookmarkNode* bb_node = CreateBookmarkNode(); |
| 731 BookmarkNode* other_folder_node = CreateOtherBookmarksNode(); | 715 BookmarkNode* other_folder_node = CreateOtherBookmarksNode(); |
| 732 return new BookmarkStorage::LoadDetails( | 716 return new BookmarkStorage::LoadDetails( |
| 733 bb_node, other_folder_node, new BookmarkIndex(), next_node_id_); | 717 bb_node, other_folder_node, new BookmarkIndex(), next_node_id_); |
| 734 } | 718 } |
| 735 | |
| 736 void BookmarkModel::RegisterPreferences() { | |
| 737 if (!profile_) | |
| 738 return; | |
| 739 PrefService* pref_service = profile_->GetPrefs(); | |
| 740 if (!pref_service->IsPrefRegistered(kPrefPersistIDs)) | |
| 741 pref_service->RegisterBooleanPref(kPrefPersistIDs, false); | |
| 742 } | |
| 743 | |
| 744 void BookmarkModel::LoadPreferences() { | |
| 745 if (!profile_) | |
| 746 return; | |
| 747 PrefService* pref_service = profile_->GetPrefs(); | |
| 748 persist_ids_ = pref_service->GetBoolean(kPrefPersistIDs); | |
| 749 } | |
| OLD | NEW |