Chromium Code Reviews| Index: components/bookmarks/browser/bookmark_model.cc |
| diff --git a/components/bookmarks/browser/bookmark_model.cc b/components/bookmarks/browser/bookmark_model.cc |
| index 5709533dba2d0be60f7f29ded432599ba10be75a..d584e2da5e37ba49d5640bcebc5cc1ea003825ba 100644 |
| --- a/components/bookmarks/browser/bookmark_model.cc |
| +++ b/components/bookmarks/browser/bookmark_model.cc |
| @@ -21,6 +21,7 @@ |
| #include "components/bookmarks/browser/bookmark_model_observer.h" |
| #include "components/bookmarks/browser/bookmark_node_data.h" |
| #include "components/bookmarks/browser/bookmark_storage.h" |
| +#include "components/bookmarks/browser/bookmark_undo_delegate.h" |
| #include "components/bookmarks/browser/bookmark_utils.h" |
| #include "components/favicon_base/favicon_types.h" |
| #include "grit/components_strings.h" |
| @@ -104,7 +105,8 @@ BookmarkModel::BookmarkModel(BookmarkClient* client) |
| observers_( |
| base::ObserverList<BookmarkModelObserver>::NOTIFY_EXISTING_ONLY), |
| loaded_signal_(true, false), |
| - extensive_changes_(0) { |
| + extensive_changes_(0), |
| + undo_delegate_(nullptr) { |
| DCHECK(client_); |
| } |
| @@ -200,6 +202,7 @@ void BookmarkModel::Remove(const BookmarkNode* node) { |
| void BookmarkModel::RemoveAllUserBookmarks() { |
| std::set<GURL> removed_urls; |
| ScopedVector<BookmarkNode> removed_nodes; |
| + std::vector<std::pair<const BookmarkNode*, int>> removed_node_data; |
| FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| OnWillRemoveAllUserBookmarks(this)); |
| @@ -218,8 +221,9 @@ void BookmarkModel::RemoveAllUserBookmarks() { |
| for (int j = permanent_node->child_count() - 1; j >= 0; --j) { |
| BookmarkNode* child_node = permanent_node->GetChild(j); |
| - removed_nodes.push_back(child_node); |
| RemoveNodeAndGetRemovedUrls(child_node, &removed_urls); |
| + removed_nodes.push_back(child_node); |
|
sky
2015/10/08 15:20:00
You shouldn't need both removed_nodes and removed_
jianli
2015/10/08 23:37:40
Done.
|
| + removed_node_data.push_back(std::make_pair(permanent_node, j)); |
|
sky
2015/10/08 15:20:00
Please add test coverage here as permanent_node is
jianli
2015/10/08 23:37:40
I've updated BookmarkModelTest.RemoveAllUserBookma
sky
2015/10/09 16:01:19
Also add coverage that the undodelegate is in fact
jianli
2015/10/09 21:51:16
Done.
|
| } |
| } |
| } |
| @@ -229,6 +233,17 @@ void BookmarkModel::RemoveAllUserBookmarks() { |
| FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| BookmarkAllUserNodesRemoved(this, removed_urls)); |
| + |
| + if (undo_delegate_) { |
|
sky
2015/10/08 15:20:00
Again, always have an undo_delegate_ so that it al
jianli
2015/10/08 23:37:40
Done.
|
| + BeginGroupedChanges(); |
| + for (size_t i = 0; i < removed_nodes.size(); ++i) { |
| + undo_delegate_->OnBookmarkNodeDeleted( |
| + this, this, removed_node_data[i].first, removed_node_data[i].second, |
| + scoped_ptr<BookmarkNode>(removed_nodes[i])); |
| + } |
| + EndGroupedChanges(); |
| + removed_nodes.weak_clear(); |
| + } |
| } |
| void BookmarkModel::Move(const BookmarkNode* node, |
| @@ -718,6 +733,35 @@ const BookmarkPermanentNode* BookmarkModel::PermanentNode( |
| } |
| } |
| +void BookmarkModel::RestoreRemovedNode(const BookmarkNode* parent, |
| + int index, |
| + scoped_ptr<BookmarkNode> scoped_node) { |
| + BookmarkNode* node = scoped_node.release(); |
| + AsMutable(parent)->Add(node, index); |
|
sky
2015/10/08 15:20:00
Use AddNode for the common parts.
jianli
2015/10/08 23:37:40
Done.
|
| + |
| + if (store_.get()) |
| + store_->ScheduleSave(); |
| + |
| + { |
| + base::AutoLock url_lock(url_lock_); |
| + AddNodeToInternalMaps(node); |
| + } |
| + |
| + // We might be restoring a folder node that have already contained a set of |
| + // child nodes. We need to notify all of them. |
| + FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| + BookmarkNodeAdded(this, parent, index)); |
| + NotifyNodeAddedForAllDescendents(node); |
| +} |
| + |
| +void BookmarkModel::NotifyNodeAddedForAllDescendents(const BookmarkNode* node) { |
| + for (int i = 0; i < node->child_count(); ++i) { |
| + FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| + BookmarkNodeAdded(this, node, i)); |
| + NotifyNodeAddedForAllDescendents(node->GetChild(i)); |
| + } |
| +} |
| + |
| bool BookmarkModel::IsBookmarkedNoLock(const GURL& url) { |
| BookmarkNode tmp_node(url); |
| return (nodes_ordered_by_url_set_.find(&tmp_node) != |
| @@ -859,6 +903,11 @@ void BookmarkModel::RemoveAndDeleteNode(BookmarkNode* delete_me) { |
| BookmarkModelObserver, |
| observers_, |
| BookmarkNodeRemoved(this, parent, index, node.get(), removed_urls)); |
| + |
| + if (undo_delegate_) { |
| + undo_delegate_->OnBookmarkNodeDeleted( |
| + this, this, parent, index, node.Pass()); |
| + } |
| } |
| void BookmarkModel::RemoveNodeFromInternalMaps(BookmarkNode* node) { |
| @@ -909,11 +958,9 @@ BookmarkNode* BookmarkModel::AddNode(BookmarkNode* parent, |
| if (store_.get()) |
| store_->ScheduleSave(); |
| - if (node->type() == BookmarkNode::URL) { |
| + { |
| base::AutoLock url_lock(url_lock_); |
| AddNodeToInternalMaps(node); |
| - } else { |
| - index_->Add(node); |
| } |
| FOR_EACH_OBSERVER(BookmarkModelObserver, observers_, |
| @@ -923,9 +970,13 @@ BookmarkNode* BookmarkModel::AddNode(BookmarkNode* parent, |
| } |
| void BookmarkModel::AddNodeToInternalMaps(BookmarkNode* node) { |
| - index_->Add(node); |
| url_lock_.AssertAcquired(); |
| - nodes_ordered_by_url_set_.insert(node); |
| + if (node->is_url()) { |
| + index_->Add(node); |
| + nodes_ordered_by_url_set_.insert(node); |
| + } |
| + for (int i = 0; i < node->child_count(); ++i) |
| + AddNodeToInternalMaps(node->GetChild(i)); |
| } |
| bool BookmarkModel::IsValidIndex(const BookmarkNode* parent, |