OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/bookmarks/browser/bookmark_model.h" | 5 #include "components/bookmarks/browser/bookmark_model.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <functional> | 8 #include <functional> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
47 class VisibilityComparator | 47 class VisibilityComparator |
48 : public std::binary_function<const BookmarkPermanentNode*, | 48 : public std::binary_function<const BookmarkPermanentNode*, |
49 const BookmarkPermanentNode*, | 49 const BookmarkPermanentNode*, |
50 bool> { | 50 bool> { |
51 public: | 51 public: |
52 explicit VisibilityComparator(BookmarkClient* client) : client_(client) {} | 52 explicit VisibilityComparator(BookmarkClient* client) : client_(client) {} |
53 | 53 |
54 // Returns true if |n1| preceeds |n2|. | 54 // Returns true if |n1| preceeds |n2|. |
55 bool operator()(const BookmarkPermanentNode* n1, | 55 bool operator()(const BookmarkPermanentNode* n1, |
56 const BookmarkPermanentNode* n2) { | 56 const BookmarkPermanentNode* n2) { |
57 bool n1_visible = client_->IsPermanentNodeVisible(n1->type()); | 57 bool n1_visible = client_->IsPermanentNodeVisible(n1); |
58 bool n2_visible = client_->IsPermanentNodeVisible(n2->type()); | 58 bool n2_visible = client_->IsPermanentNodeVisible(n2); |
59 return n1_visible != n2_visible && n1_visible; | 59 return n1_visible != n2_visible && n1_visible; |
60 } | 60 } |
61 | 61 |
62 private: | 62 private: |
63 BookmarkClient* client_; | 63 BookmarkClient* client_; |
64 }; | 64 }; |
65 | 65 |
66 // Comparator used when sorting bookmarks. Folders are sorted first, then | 66 // Comparator used when sorting bookmarks. Folders are sorted first, then |
67 // bookmarks. | 67 // bookmarks. |
68 class SortComparator : public std::binary_function<const BookmarkNode*, | 68 class SortComparator : public std::binary_function<const BookmarkNode*, |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
205 OnWillRemoveAllBookmarks(this)); | 205 OnWillRemoveAllBookmarks(this)); |
206 | 206 |
207 BeginExtensiveChanges(); | 207 BeginExtensiveChanges(); |
208 // Skip deleting permanent nodes. Permanent bookmark nodes are the root and | 208 // Skip deleting permanent nodes. Permanent bookmark nodes are the root and |
209 // its immediate children. For removing all non permanent nodes just remove | 209 // its immediate children. For removing all non permanent nodes just remove |
210 // all children of non-root permanent nodes. | 210 // all children of non-root permanent nodes. |
211 { | 211 { |
212 base::AutoLock url_lock(url_lock_); | 212 base::AutoLock url_lock(url_lock_); |
213 for (int i = 0; i < root_.child_count(); ++i) { | 213 for (int i = 0; i < root_.child_count(); ++i) { |
214 BookmarkNode* permanent_node = root_.GetChild(i); | 214 BookmarkNode* permanent_node = root_.GetChild(i); |
215 | |
216 if (!client_->CanRemoveNode(permanent_node)) | |
217 continue; | |
218 | |
215 for (int j = permanent_node->child_count() - 1; j >= 0; --j) { | 219 for (int j = permanent_node->child_count() - 1; j >= 0; --j) { |
216 BookmarkNode* child_node = permanent_node->GetChild(j); | 220 BookmarkNode* child_node = permanent_node->GetChild(j); |
217 removed_nodes.push_back(child_node); | 221 removed_nodes.push_back(child_node); |
218 RemoveNodeAndGetRemovedUrls(child_node, &removed_urls); | 222 RemoveNodeAndGetRemovedUrls(child_node, &removed_urls); |
219 } | 223 } |
220 } | 224 } |
221 } | 225 } |
222 EndExtensiveChanges(); | 226 EndExtensiveChanges(); |
223 if (store_.get()) | 227 if (store_.get()) |
224 store_->ScheduleSave(); | 228 store_->ScheduleSave(); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
312 | 316 |
313 void BookmarkModel::SetTitle(const BookmarkNode* node, | 317 void BookmarkModel::SetTitle(const BookmarkNode* node, |
314 const base::string16& title) { | 318 const base::string16& title) { |
315 if (!node) { | 319 if (!node) { |
316 NOTREACHED(); | 320 NOTREACHED(); |
317 return; | 321 return; |
318 } | 322 } |
319 if (node->GetTitle() == title) | 323 if (node->GetTitle() == title) |
320 return; | 324 return; |
321 | 325 |
322 if (is_permanent_node(node)) { | 326 if (is_permanent_node(node) && !client_->CanSetTitle(node)) { |
323 NOTREACHED(); | 327 NOTREACHED(); |
324 return; | 328 return; |
325 } | 329 } |
326 | 330 |
327 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 331 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
328 OnWillChangeBookmarkNode(this, node)); | 332 OnWillChangeBookmarkNode(this, node)); |
329 | 333 |
330 // The title index doesn't support changing the title, instead we remove then | 334 // The title index doesn't support changing the title, instead we remove then |
331 // add it back. | 335 // add it back. |
332 index_->Remove(node); | 336 index_->Remove(node); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
424 if (AsMutable(node)->DeleteMetaInfo(key) && store_.get()) | 428 if (AsMutable(node)->DeleteMetaInfo(key) && store_.get()) |
425 store_->ScheduleSave(); | 429 store_->ScheduleSave(); |
426 | 430 |
427 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 431 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
428 BookmarkMetaInfoChanged(this, node)); | 432 BookmarkMetaInfoChanged(this, node)); |
429 } | 433 } |
430 | 434 |
431 void BookmarkModel::SetNodeSyncTransactionVersion( | 435 void BookmarkModel::SetNodeSyncTransactionVersion( |
432 const BookmarkNode* node, | 436 const BookmarkNode* node, |
433 int64 sync_transaction_version) { | 437 int64 sync_transaction_version) { |
438 DCHECK(client_->CanSyncNode(node)); | |
439 | |
434 if (sync_transaction_version == node->sync_transaction_version()) | 440 if (sync_transaction_version == node->sync_transaction_version()) |
435 return; | 441 return; |
436 | 442 |
437 AsMutable(node)->set_sync_transaction_version(sync_transaction_version); | 443 AsMutable(node)->set_sync_transaction_version(sync_transaction_version); |
438 if (store_.get()) | 444 if (store_.get()) |
439 store_->ScheduleSave(); | 445 store_->ScheduleSave(); |
440 } | 446 } |
441 | 447 |
442 void BookmarkModel::OnFaviconChanged(const std::set<GURL>& urls) { | 448 void BookmarkModel::OnFaviconChanged(const std::set<GURL>& urls) { |
443 // Ignore events if |Load| has not been called yet. | 449 // Ignore events if |Load| has not been called yet. |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
607 { | 613 { |
608 // Only hold the lock for the duration of the insert. | 614 // Only hold the lock for the duration of the insert. |
609 base::AutoLock url_lock(url_lock_); | 615 base::AutoLock url_lock(url_lock_); |
610 nodes_ordered_by_url_set_.insert(new_node); | 616 nodes_ordered_by_url_set_.insert(new_node); |
611 } | 617 } |
612 | 618 |
613 return AddNode(AsMutable(parent), index, new_node); | 619 return AddNode(AsMutable(parent), index, new_node); |
614 } | 620 } |
615 | 621 |
616 void BookmarkModel::SortChildren(const BookmarkNode* parent) { | 622 void BookmarkModel::SortChildren(const BookmarkNode* parent) { |
623 DCHECK(client_->CanReorderChildren(parent)); | |
624 | |
617 if (!parent || !parent->is_folder() || is_root_node(parent) || | 625 if (!parent || !parent->is_folder() || is_root_node(parent) || |
618 parent->child_count() <= 1) { | 626 parent->child_count() <= 1) { |
619 return; | 627 return; |
620 } | 628 } |
621 | 629 |
622 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 630 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
623 OnWillReorderBookmarkNode(this, parent)); | 631 OnWillReorderBookmarkNode(this, parent)); |
624 | 632 |
625 UErrorCode error = U_ZERO_ERROR; | 633 UErrorCode error = U_ZERO_ERROR; |
626 scoped_ptr<icu::Collator> collator(icu::Collator::createInstance(error)); | 634 scoped_ptr<icu::Collator> collator(icu::Collator::createInstance(error)); |
627 if (U_FAILURE(error)) | 635 if (U_FAILURE(error)) |
628 collator.reset(NULL); | 636 collator.reset(NULL); |
629 BookmarkNode* mutable_parent = AsMutable(parent); | 637 BookmarkNode* mutable_parent = AsMutable(parent); |
630 std::sort(mutable_parent->children().begin(), | 638 std::sort(mutable_parent->children().begin(), |
631 mutable_parent->children().end(), | 639 mutable_parent->children().end(), |
632 SortComparator(collator.get())); | 640 SortComparator(collator.get())); |
633 | 641 |
634 if (store_.get()) | 642 if (store_.get()) |
635 store_->ScheduleSave(); | 643 store_->ScheduleSave(); |
636 | 644 |
637 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 645 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
638 BookmarkNodeChildrenReordered(this, parent)); | 646 BookmarkNodeChildrenReordered(this, parent)); |
639 } | 647 } |
640 | 648 |
641 void BookmarkModel::ReorderChildren( | 649 void BookmarkModel::ReorderChildren( |
642 const BookmarkNode* parent, | 650 const BookmarkNode* parent, |
643 const std::vector<const BookmarkNode*>& ordered_nodes) { | 651 const std::vector<const BookmarkNode*>& ordered_nodes) { |
652 DCHECK(client_->CanReorderChildren(parent)); | |
653 | |
644 // Ensure that all children in |parent| are in |ordered_nodes|. | 654 // Ensure that all children in |parent| are in |ordered_nodes|. |
645 DCHECK_EQ(static_cast<size_t>(parent->child_count()), ordered_nodes.size()); | 655 DCHECK_EQ(static_cast<size_t>(parent->child_count()), ordered_nodes.size()); |
646 for (size_t i = 0; i < ordered_nodes.size(); ++i) | 656 for (size_t i = 0; i < ordered_nodes.size(); ++i) |
647 DCHECK_EQ(parent, ordered_nodes[i]->parent()); | 657 DCHECK_EQ(parent, ordered_nodes[i]->parent()); |
648 | 658 |
649 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, | 659 FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
650 OnWillReorderBookmarkNode(this, parent)); | 660 OnWillReorderBookmarkNode(this, parent)); |
651 | 661 |
652 AsMutable(parent)->SetChildren( | 662 AsMutable(parent)->SetChildren( |
653 *(reinterpret_cast<const std::vector<BookmarkNode*>*>(&ordered_nodes))); | 663 *(reinterpret_cast<const std::vector<BookmarkNode*>*>(&ordered_nodes))); |
(...skipping 27 matching lines...) Expand all Loading... | |
681 | 691 |
682 index_->GetBookmarksMatching(text, max_count, matches); | 692 index_->GetBookmarksMatching(text, max_count, matches); |
683 } | 693 } |
684 | 694 |
685 void BookmarkModel::ClearStore() { | 695 void BookmarkModel::ClearStore() { |
686 store_ = NULL; | 696 store_ = NULL; |
687 } | 697 } |
688 | 698 |
689 void BookmarkModel::SetPermanentNodeVisible(BookmarkNode::Type type, | 699 void BookmarkModel::SetPermanentNodeVisible(BookmarkNode::Type type, |
690 bool value) { | 700 bool value) { |
691 AsMutable(PermanentNode(type))->set_visible( | 701 BookmarkPermanentNode* node = AsMutable(PermanentNode(type)); |
692 value || client_->IsPermanentNodeVisible(type)); | 702 node->set_visible(value || client_->IsPermanentNodeVisible(node)); |
693 } | 703 } |
694 | 704 |
695 const BookmarkPermanentNode* BookmarkModel::PermanentNode( | 705 const BookmarkPermanentNode* BookmarkModel::PermanentNode( |
696 BookmarkNode::Type type) { | 706 BookmarkNode::Type type) { |
697 DCHECK(loaded_); | 707 DCHECK(loaded_); |
698 switch (type) { | 708 switch (type) { |
699 case BookmarkNode::BOOKMARK_BAR: | 709 case BookmarkNode::BOOKMARK_BAR: |
700 return bookmark_bar_node_; | 710 return bookmark_bar_node_; |
701 case BookmarkNode::OTHER_NODE: | 711 case BookmarkNode::OTHER_NODE: |
702 return other_node_; | 712 return other_node_; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
751 // them unique. So when the file has changed externally, we should save the | 761 // them unique. So when the file has changed externally, we should save the |
752 // bookmarks file to persist new IDs. | 762 // bookmarks file to persist new IDs. |
753 if (store_.get()) | 763 if (store_.get()) |
754 store_->ScheduleSave(); | 764 store_->ScheduleSave(); |
755 } | 765 } |
756 bookmark_bar_node_ = details->release_bb_node(); | 766 bookmark_bar_node_ = details->release_bb_node(); |
757 other_node_ = details->release_other_folder_node(); | 767 other_node_ = details->release_other_folder_node(); |
758 mobile_node_ = details->release_mobile_folder_node(); | 768 mobile_node_ = details->release_mobile_folder_node(); |
759 index_.reset(details->release_index()); | 769 index_.reset(details->release_index()); |
760 | 770 |
771 // Get any extra nodes and take ownership of them at the |root_|. | |
772 std::vector<BookmarkPermanentNode*> extra_nodes; | |
773 details->release_extra_nodes(&extra_nodes); | |
774 | |
775 // Let the client get handles to the extra permanent nodes on the main thread. | |
776 client_->ExtraNodesLoaded(extra_nodes); | |
sky
2014/06/04 20:39:52
Can this be nuked and instead use BookmarkModelLoa
Joao da Silva
2014/06/04 22:35:58
BookmarkModelLoaded() comes a tad too late, becaus
| |
777 | |
761 // WARNING: order is important here, various places assume the order is | 778 // WARNING: order is important here, various places assume the order is |
762 // constant (but can vary between embedders with the initial visibility | 779 // constant (but can vary between embedders with the initial visibility |
763 // of permanent nodes). | 780 // of permanent nodes). |
764 BookmarkPermanentNode* root_children[] = { | 781 std::vector<BookmarkPermanentNode*> root_children; |
765 bookmark_bar_node_, other_node_, mobile_node_, | 782 root_children.push_back(bookmark_bar_node_); |
766 }; | 783 root_children.push_back(other_node_); |
767 std::stable_sort(root_children, | 784 root_children.push_back(mobile_node_); |
768 root_children + arraysize(root_children), | 785 for (size_t i = 0; i < extra_nodes.size(); ++i) |
786 root_children.push_back(extra_nodes[i]); | |
787 std::stable_sort(root_children.begin(), | |
788 root_children.end(), | |
769 VisibilityComparator(client_)); | 789 VisibilityComparator(client_)); |
770 for (size_t i = 0; i < arraysize(root_children); ++i) { | 790 for (size_t i = 0; i < root_children.size(); ++i) |
771 root_.Add(root_children[i], static_cast<int>(i)); | 791 root_.Add(root_children[i], static_cast<int>(i)); |
772 } | |
773 | 792 |
774 root_.SetMetaInfoMap(details->model_meta_info_map()); | 793 root_.SetMetaInfoMap(details->model_meta_info_map()); |
775 root_.set_sync_transaction_version(details->model_sync_transaction_version()); | 794 root_.set_sync_transaction_version(details->model_sync_transaction_version()); |
776 | 795 |
777 { | 796 { |
778 base::AutoLock url_lock(url_lock_); | 797 base::AutoLock url_lock(url_lock_); |
779 // Update nodes_ordered_by_url_set_ from the nodes. | 798 // Update nodes_ordered_by_url_set_ from the nodes. |
780 PopulateNodesByURL(&root_); | 799 PopulateNodesByURL(&root_); |
781 } | 800 } |
782 | 801 |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
876 (allow_end && index == parent->child_count())))); | 895 (allow_end && index == parent->child_count())))); |
877 } | 896 } |
878 | 897 |
879 BookmarkPermanentNode* BookmarkModel::CreatePermanentNode( | 898 BookmarkPermanentNode* BookmarkModel::CreatePermanentNode( |
880 BookmarkNode::Type type) { | 899 BookmarkNode::Type type) { |
881 DCHECK(type == BookmarkNode::BOOKMARK_BAR || | 900 DCHECK(type == BookmarkNode::BOOKMARK_BAR || |
882 type == BookmarkNode::OTHER_NODE || | 901 type == BookmarkNode::OTHER_NODE || |
883 type == BookmarkNode::MOBILE); | 902 type == BookmarkNode::MOBILE); |
884 BookmarkPermanentNode* node = | 903 BookmarkPermanentNode* node = |
885 new BookmarkPermanentNode(generate_next_node_id()); | 904 new BookmarkPermanentNode(generate_next_node_id()); |
886 node->set_visible(client_->IsPermanentNodeVisible(type)); | 905 node->set_type(type); |
906 node->set_visible(client_->IsPermanentNodeVisible(node)); | |
887 | 907 |
888 int title_id; | 908 int title_id; |
889 switch (type) { | 909 switch (type) { |
890 case BookmarkNode::BOOKMARK_BAR: | 910 case BookmarkNode::BOOKMARK_BAR: |
891 title_id = IDS_BOOKMARK_BAR_FOLDER_NAME; | 911 title_id = IDS_BOOKMARK_BAR_FOLDER_NAME; |
892 break; | 912 break; |
893 case BookmarkNode::OTHER_NODE: | 913 case BookmarkNode::OTHER_NODE: |
894 title_id = IDS_BOOKMARK_BAR_OTHER_FOLDER_NAME; | 914 title_id = IDS_BOOKMARK_BAR_OTHER_FOLDER_NAME; |
895 break; | 915 break; |
896 case BookmarkNode::MOBILE: | 916 case BookmarkNode::MOBILE: |
897 title_id = IDS_BOOKMARK_BAR_MOBILE_FOLDER_NAME; | 917 title_id = IDS_BOOKMARK_BAR_MOBILE_FOLDER_NAME; |
898 break; | 918 break; |
899 default: | 919 default: |
900 NOTREACHED(); | 920 NOTREACHED(); |
901 title_id = IDS_BOOKMARK_BAR_FOLDER_NAME; | 921 title_id = IDS_BOOKMARK_BAR_FOLDER_NAME; |
902 break; | 922 break; |
903 } | 923 } |
904 node->SetTitle(l10n_util::GetStringUTF16(title_id)); | 924 node->SetTitle(l10n_util::GetStringUTF16(title_id)); |
905 node->set_type(type); | |
906 return node; | 925 return node; |
907 } | 926 } |
908 | 927 |
909 void BookmarkModel::OnFaviconDataAvailable( | 928 void BookmarkModel::OnFaviconDataAvailable( |
910 BookmarkNode* node, | 929 BookmarkNode* node, |
911 favicon_base::IconType icon_type, | 930 favicon_base::IconType icon_type, |
912 const favicon_base::FaviconImageResult& image_result) { | 931 const favicon_base::FaviconImageResult& image_result) { |
913 DCHECK(node); | 932 DCHECK(node); |
914 node->set_favicon_load_task_id(base::CancelableTaskTracker::kBadTaskId); | 933 node->set_favicon_load_task_id(base::CancelableTaskTracker::kBadTaskId); |
915 node->set_favicon_state(BookmarkNode::LOADED_FAVICON); | 934 node->set_favicon_state(BookmarkNode::LOADED_FAVICON); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
977 BookmarkPermanentNode* bb_node = | 996 BookmarkPermanentNode* bb_node = |
978 CreatePermanentNode(BookmarkNode::BOOKMARK_BAR); | 997 CreatePermanentNode(BookmarkNode::BOOKMARK_BAR); |
979 BookmarkPermanentNode* other_node = | 998 BookmarkPermanentNode* other_node = |
980 CreatePermanentNode(BookmarkNode::OTHER_NODE); | 999 CreatePermanentNode(BookmarkNode::OTHER_NODE); |
981 BookmarkPermanentNode* mobile_node = | 1000 BookmarkPermanentNode* mobile_node = |
982 CreatePermanentNode(BookmarkNode::MOBILE); | 1001 CreatePermanentNode(BookmarkNode::MOBILE); |
983 return scoped_ptr<BookmarkLoadDetails>(new BookmarkLoadDetails( | 1002 return scoped_ptr<BookmarkLoadDetails>(new BookmarkLoadDetails( |
984 bb_node, | 1003 bb_node, |
985 other_node, | 1004 other_node, |
986 mobile_node, | 1005 mobile_node, |
1006 client_->GetLoadExtraNodesCallback(), | |
987 new BookmarkIndex(client_, index_urls_, accept_languages), | 1007 new BookmarkIndex(client_, index_urls_, accept_languages), |
988 next_node_id_)); | 1008 next_node_id_)); |
989 } | 1009 } |
OLD | NEW |