Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(878)

Unified Diff: components/bookmarks/browser/bookmark_model.cc

Issue 1379983002: Supporting undoing bookmark deletion without creating new ID. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address more feedback Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..8799ec2e21dbadaac403a6de7f6ea5d557de3358 100644
--- a/components/bookmarks/browser/bookmark_model.cc
+++ b/components/bookmarks/browser/bookmark_model.cc
@@ -15,12 +15,14 @@
#include "base/metrics/histogram_macros.h"
#include "base/profiler/scoped_tracker.h"
#include "base/strings/string_util.h"
+#include "base/tuple.h"
#include "components/bookmarks/browser/bookmark_expanded_state_tracker.h"
#include "components/bookmarks/browser/bookmark_index.h"
#include "components/bookmarks/browser/bookmark_match.h"
#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"
@@ -89,6 +91,23 @@ class SortComparator : public std::binary_function<const BookmarkNode*,
icu::Collator* collator_;
};
+// Delegate that does nothing.
+class EmptyUndoDelegate : public BookmarkUndoDelegate {
+ public:
+ EmptyUndoDelegate() {}
+ ~EmptyUndoDelegate() override {}
+
+ private:
+ // BookmarkUndoDelegate:
+ void SetUndoProvider(BookmarkUndoProvider* provider) override {}
+ void OnBookmarkNodeRemoved(BookmarkModel* model,
+ const BookmarkNode* parent,
+ int index,
+ scoped_ptr<BookmarkNode> node) override {}
+
+ DISALLOW_COPY_AND_ASSIGN(EmptyUndoDelegate);
+};
+
} // namespace
// BookmarkModel --------------------------------------------------------------
@@ -104,7 +123,9 @@ BookmarkModel::BookmarkModel(BookmarkClient* client)
observers_(
base::ObserverList<BookmarkModelObserver>::NOTIFY_EXISTING_ONLY),
loaded_signal_(true, false),
- extensive_changes_(0) {
+ extensive_changes_(0),
+ undo_delegate_(nullptr),
+ empty_undo_delegate_(new EmptyUndoDelegate) {
DCHECK(client_);
}
@@ -199,7 +220,8 @@ void BookmarkModel::Remove(const BookmarkNode* node) {
void BookmarkModel::RemoveAllUserBookmarks() {
std::set<GURL> removed_urls;
- ScopedVector<BookmarkNode> removed_nodes;
+ std::vector<base::Tuple<const BookmarkNode*, int, BookmarkNode*>>
sky 2015/10/09 16:01:19 Using a tuple certainly works, but it's not partic
jianli 2015/10/09 21:51:16 Done.
+ removed_node_data;
FOR_EACH_OBSERVER(BookmarkModelObserver, observers_,
OnWillRemoveAllUserBookmarks(this));
@@ -211,15 +233,16 @@ void BookmarkModel::RemoveAllUserBookmarks() {
{
base::AutoLock url_lock(url_lock_);
for (int i = 0; i < root_.child_count(); ++i) {
- BookmarkNode* permanent_node = root_.GetChild(i);
+ const BookmarkNode* permanent_node = root_.GetChild(i);
if (!client_->CanBeEditedByUser(permanent_node))
continue;
for (int j = permanent_node->child_count() - 1; j >= 0; --j) {
- BookmarkNode* child_node = permanent_node->GetChild(j);
- removed_nodes.push_back(child_node);
+ BookmarkNode* child_node = AsMutable(permanent_node->GetChild(j));
RemoveNodeAndGetRemovedUrls(child_node, &removed_urls);
+ removed_node_data.push_back(
+ base::MakeTuple(permanent_node, j, child_node));
}
}
}
@@ -229,6 +252,16 @@ void BookmarkModel::RemoveAllUserBookmarks() {
FOR_EACH_OBSERVER(BookmarkModelObserver, observers_,
BookmarkAllUserNodesRemoved(this, removed_urls));
+
+ BeginGroupedChanges();
+ for (const auto& tuple : removed_node_data) {
+ undo_delegate()->OnBookmarkNodeRemoved(
+ this,
+ base::get<0>(tuple),
+ base::get<1>(tuple),
+ scoped_ptr<BookmarkNode>(base::get<2>(tuple)));
+ }
+ EndGroupedChanges();
}
void BookmarkModel::Move(const BookmarkNode* node,
@@ -718,6 +751,25 @@ const BookmarkPermanentNode* BookmarkModel::PermanentNode(
}
}
+void BookmarkModel::RestoreRemovedNode(const BookmarkNode* parent,
+ int index,
+ scoped_ptr<BookmarkNode> scoped_node) {
+ BookmarkNode* node = scoped_node.release();
+ AddNode(AsMutable(parent), index, node);
+
+ // We might be restoring a folder node that have already contained a set of
+ // child nodes. We need to notify all of them.
+ 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 +911,8 @@ void BookmarkModel::RemoveAndDeleteNode(BookmarkNode* delete_me) {
BookmarkModelObserver,
observers_,
BookmarkNodeRemoved(this, parent, index, node.get(), removed_urls));
+
+ undo_delegate()->OnBookmarkNodeRemoved(this, parent, index, node.Pass());
}
void BookmarkModel::RemoveNodeFromInternalMaps(BookmarkNode* node) {
@@ -909,11 +963,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 +975,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,
@@ -1048,4 +1104,14 @@ scoped_ptr<BookmarkLoadDetails> BookmarkModel::CreateLoadDetails(
next_node_id_));
}
+void BookmarkModel::set_undo_delegate(BookmarkUndoDelegate* undo_delegate) {
+ undo_delegate_ = undo_delegate;
+ if (undo_delegate_)
+ undo_delegate_->SetUndoProvider(this);
+}
+
+BookmarkUndoDelegate* BookmarkModel::undo_delegate() const {
+ return undo_delegate_ ? undo_delegate_ : empty_undo_delegate_.get();
+}
+
} // namespace bookmarks

Powered by Google App Engine
This is Rietveld 408576698