cygprofile: increase timeouts to allow showing web contents
[chromium-blink-merge.git] / components / undo / bookmark_undo_service.cc
blob28fd451d7b080d5f6fe434629ab07f14c538ee20
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/undo/bookmark_undo_service.h"
7 #include "components/bookmarks/browser/bookmark_model.h"
8 #include "components/bookmarks/browser/bookmark_node_data.h"
9 #include "components/bookmarks/browser/bookmark_utils.h"
10 #include "components/bookmarks/browser/scoped_group_bookmark_actions.h"
11 #include "components/undo/bookmark_renumber_observer.h"
12 #include "components/undo/undo_operation.h"
13 #include "grit/components_strings.h"
15 using bookmarks::BookmarkModel;
16 using bookmarks::BookmarkNode;
17 using bookmarks::BookmarkNodeData;
19 namespace {
21 // BookmarkUndoOperation ------------------------------------------------------
23 // Base class for all bookmark related UndoOperations that facilitates access to
24 // the BookmarkUndoService.
25 class BookmarkUndoOperation : public UndoOperation,
26 public BookmarkRenumberObserver {
27 public:
28 BookmarkUndoOperation(BookmarkModel* bookmark_model,
29 BookmarkRenumberObserver* undo_renumber_observer)
30 : bookmark_model_(bookmark_model),
31 undo_renumber_observer_(undo_renumber_observer) {}
32 ~BookmarkUndoOperation() override {}
34 BookmarkModel* bookmark_model() { return bookmark_model_; }
36 BookmarkRenumberObserver* undo_renumber_observer() {
37 return undo_renumber_observer_;
40 private:
41 BookmarkModel* bookmark_model_;
42 BookmarkRenumberObserver* undo_renumber_observer_;
45 // BookmarkAddOperation -------------------------------------------------------
47 // Handles the undo of the insertion of a bookmark or folder.
48 class BookmarkAddOperation : public BookmarkUndoOperation {
49 public:
50 BookmarkAddOperation(BookmarkModel* bookmark_model,
51 BookmarkRenumberObserver* undo_renumber_observer,
52 const BookmarkNode* parent,
53 int index);
54 ~BookmarkAddOperation() override {}
56 // UndoOperation:
57 void Undo() override;
58 int GetUndoLabelId() const override;
59 int GetRedoLabelId() const override;
61 // BookmarkRenumberObserver:
62 void OnBookmarkRenumbered(int64 old_id, int64 new_id) override;
64 private:
65 int64 parent_id_;
66 const int index_;
68 DISALLOW_COPY_AND_ASSIGN(BookmarkAddOperation);
71 BookmarkAddOperation::BookmarkAddOperation(
72 BookmarkModel* bookmark_model,
73 BookmarkRenumberObserver* undo_renumber_observer,
74 const BookmarkNode* parent,
75 int index)
76 : BookmarkUndoOperation(bookmark_model, undo_renumber_observer),
77 parent_id_(parent->id()),
78 index_(index) {
81 void BookmarkAddOperation::Undo() {
82 BookmarkModel* model = bookmark_model();
83 const BookmarkNode* parent =
84 bookmarks::GetBookmarkNodeByID(model, parent_id_);
85 DCHECK(parent);
87 model->Remove(parent->GetChild(index_));
90 int BookmarkAddOperation::GetUndoLabelId() const {
91 return IDS_BOOKMARK_BAR_UNDO_ADD;
94 int BookmarkAddOperation::GetRedoLabelId() const {
95 return IDS_BOOKMARK_BAR_REDO_DELETE;
98 void BookmarkAddOperation::OnBookmarkRenumbered(int64 old_id, int64 new_id) {
99 if (parent_id_ == old_id)
100 parent_id_ = new_id;
103 // BookmarkRemoveOperation ----------------------------------------------------
105 // Handles the undo of the deletion of a bookmark node. For a bookmark folder,
106 // the information for all descendant bookmark nodes is maintained.
108 // The BookmarkModel allows only single bookmark node to be removed.
109 class BookmarkRemoveOperation : public BookmarkUndoOperation {
110 public:
111 BookmarkRemoveOperation(BookmarkModel* bookmark_model,
112 BookmarkRenumberObserver* undo_renumber_observer,
113 const BookmarkNode* parent,
114 int old_index,
115 const BookmarkNode* node);
116 ~BookmarkRemoveOperation() override {}
118 // UndoOperation:
119 void Undo() override;
120 int GetUndoLabelId() const override;
121 int GetRedoLabelId() const override;
123 // BookmarkRenumberObserver:
124 void OnBookmarkRenumbered(int64 old_id, int64 new_id) override;
126 private:
127 void UpdateBookmarkIds(const BookmarkNodeData::Element& element,
128 const BookmarkNode* parent,
129 int index_added_at);
131 int64 parent_id_;
132 const int old_index_;
133 BookmarkNodeData removed_node_;
135 DISALLOW_COPY_AND_ASSIGN(BookmarkRemoveOperation);
138 BookmarkRemoveOperation::BookmarkRemoveOperation(
139 BookmarkModel* bookmark_model,
140 BookmarkRenumberObserver* undo_renumber_observer,
141 const BookmarkNode* parent,
142 int old_index,
143 const BookmarkNode* node)
144 : BookmarkUndoOperation(bookmark_model, undo_renumber_observer),
145 parent_id_(parent->id()),
146 old_index_(old_index),
147 removed_node_(node) {
150 void BookmarkRemoveOperation::Undo() {
151 DCHECK(removed_node_.is_valid());
152 BookmarkModel* model = bookmark_model();
153 const BookmarkNode* parent =
154 bookmarks::GetBookmarkNodeByID(model, parent_id_);
155 DCHECK(parent);
157 bookmarks::CloneBookmarkNode(
158 model, removed_node_.elements, parent, old_index_, false);
159 UpdateBookmarkIds(removed_node_.elements[0], parent, old_index_);
162 int BookmarkRemoveOperation::GetUndoLabelId() const {
163 return IDS_BOOKMARK_BAR_UNDO_DELETE;
166 int BookmarkRemoveOperation::GetRedoLabelId() const {
167 return IDS_BOOKMARK_BAR_REDO_ADD;
170 void BookmarkRemoveOperation::UpdateBookmarkIds(
171 const BookmarkNodeData::Element& element,
172 const BookmarkNode* parent,
173 int index_added_at) {
174 const BookmarkNode* node = parent->GetChild(index_added_at);
175 if (element.id() != node->id())
176 undo_renumber_observer()->OnBookmarkRenumbered(element.id(), node->id());
177 if (!element.is_url) {
178 for (int i = 0; i < static_cast<int>(element.children.size()); ++i)
179 UpdateBookmarkIds(element.children[i], node, i);
183 void BookmarkRemoveOperation::OnBookmarkRenumbered(int64 old_id, int64 new_id) {
184 if (parent_id_ == old_id)
185 parent_id_ = new_id;
188 // BookmarkEditOperation ------------------------------------------------------
190 // Handles the undo of the modification of a bookmark node.
191 class BookmarkEditOperation : public BookmarkUndoOperation {
192 public:
193 BookmarkEditOperation(BookmarkModel* bookmark_model,
194 BookmarkRenumberObserver* undo_renumber_observer,
195 const BookmarkNode* node);
196 ~BookmarkEditOperation() override {}
198 // UndoOperation:
199 void Undo() override;
200 int GetUndoLabelId() const override;
201 int GetRedoLabelId() const override;
203 // BookmarkRenumberObserver:
204 void OnBookmarkRenumbered(int64 old_id, int64 new_id) override;
206 private:
207 int64 node_id_;
208 BookmarkNodeData original_bookmark_;
210 DISALLOW_COPY_AND_ASSIGN(BookmarkEditOperation);
213 BookmarkEditOperation::BookmarkEditOperation(
214 BookmarkModel* bookmark_model,
215 BookmarkRenumberObserver* undo_renumber_observer,
216 const BookmarkNode* node)
217 : BookmarkUndoOperation(bookmark_model, undo_renumber_observer),
218 node_id_(node->id()),
219 original_bookmark_(node) {
222 void BookmarkEditOperation::Undo() {
223 DCHECK(original_bookmark_.is_valid());
224 BookmarkModel* model = bookmark_model();
225 const BookmarkNode* node = bookmarks::GetBookmarkNodeByID(model, node_id_);
226 DCHECK(node);
228 model->SetTitle(node, original_bookmark_.elements[0].title);
229 if (original_bookmark_.elements[0].is_url)
230 model->SetURL(node, original_bookmark_.elements[0].url);
233 int BookmarkEditOperation::GetUndoLabelId() const {
234 return IDS_BOOKMARK_BAR_UNDO_EDIT;
237 int BookmarkEditOperation::GetRedoLabelId() const {
238 return IDS_BOOKMARK_BAR_REDO_EDIT;
241 void BookmarkEditOperation::OnBookmarkRenumbered(int64 old_id, int64 new_id) {
242 if (node_id_ == old_id)
243 node_id_ = new_id;
246 // BookmarkMoveOperation ------------------------------------------------------
248 // Handles the undo of a bookmark being moved to a new location.
249 class BookmarkMoveOperation : public BookmarkUndoOperation {
250 public:
251 BookmarkMoveOperation(BookmarkModel* bookmark_model,
252 BookmarkRenumberObserver* undo_renumber_observer,
253 const BookmarkNode* old_parent,
254 int old_index,
255 const BookmarkNode* new_parent,
256 int new_index);
257 ~BookmarkMoveOperation() override {}
258 int GetUndoLabelId() const override;
259 int GetRedoLabelId() const override;
261 // UndoOperation:
262 void Undo() override;
264 // BookmarkRenumberObserver:
265 void OnBookmarkRenumbered(int64 old_id, int64 new_id) override;
267 private:
268 int64 old_parent_id_;
269 int64 new_parent_id_;
270 int old_index_;
271 int new_index_;
273 DISALLOW_COPY_AND_ASSIGN(BookmarkMoveOperation);
276 BookmarkMoveOperation::BookmarkMoveOperation(
277 BookmarkModel* bookmark_model,
278 BookmarkRenumberObserver* undo_renumber_observer,
279 const BookmarkNode* old_parent,
280 int old_index,
281 const BookmarkNode* new_parent,
282 int new_index)
283 : BookmarkUndoOperation(bookmark_model, undo_renumber_observer),
284 old_parent_id_(old_parent->id()),
285 new_parent_id_(new_parent->id()),
286 old_index_(old_index),
287 new_index_(new_index) {
290 void BookmarkMoveOperation::Undo() {
291 BookmarkModel* model = bookmark_model();
292 const BookmarkNode* old_parent =
293 bookmarks::GetBookmarkNodeByID(model, old_parent_id_);
294 const BookmarkNode* new_parent =
295 bookmarks::GetBookmarkNodeByID(model, new_parent_id_);
296 DCHECK(old_parent);
297 DCHECK(new_parent);
299 const BookmarkNode* node = new_parent->GetChild(new_index_);
300 int destination_index = old_index_;
302 // If the bookmark was moved up within the same parent then the destination
303 // index needs to be incremented since the old index did not account for the
304 // moved bookmark.
305 if (old_parent == new_parent && new_index_ < old_index_)
306 ++destination_index;
308 model->Move(node, old_parent, destination_index);
311 int BookmarkMoveOperation::GetUndoLabelId() const {
312 return IDS_BOOKMARK_BAR_UNDO_MOVE;
315 int BookmarkMoveOperation::GetRedoLabelId() const {
316 return IDS_BOOKMARK_BAR_REDO_MOVE;
319 void BookmarkMoveOperation::OnBookmarkRenumbered(int64 old_id, int64 new_id) {
320 if (old_parent_id_ == old_id)
321 old_parent_id_ = new_id;
322 if (new_parent_id_ == old_id)
323 new_parent_id_ = new_id;
326 // BookmarkReorderOperation ---------------------------------------------------
328 // Handle the undo of reordering of bookmarks that can happen as a result of
329 // sorting a bookmark folder by name or the undo of that operation. The change
330 // of order is not recursive so only the order of the immediate children of the
331 // folder need to be restored.
332 class BookmarkReorderOperation : public BookmarkUndoOperation {
333 public:
334 BookmarkReorderOperation(BookmarkModel* bookmark_model,
335 BookmarkRenumberObserver* undo_renumber_observer,
336 const BookmarkNode* parent);
337 ~BookmarkReorderOperation() override;
339 // UndoOperation:
340 void Undo() override;
341 int GetUndoLabelId() const override;
342 int GetRedoLabelId() const override;
344 // BookmarkRenumberObserver:
345 void OnBookmarkRenumbered(int64 old_id, int64 new_id) override;
347 private:
348 int64 parent_id_;
349 std::vector<int64> ordered_bookmarks_;
351 DISALLOW_COPY_AND_ASSIGN(BookmarkReorderOperation);
354 BookmarkReorderOperation::BookmarkReorderOperation(
355 BookmarkModel* bookmark_model,
356 BookmarkRenumberObserver* undo_renumber_observer,
357 const BookmarkNode* parent)
358 : BookmarkUndoOperation(bookmark_model, undo_renumber_observer),
359 parent_id_(parent->id()) {
360 ordered_bookmarks_.resize(parent->child_count());
361 for (int i = 0; i < parent->child_count(); ++i)
362 ordered_bookmarks_[i] = parent->GetChild(i)->id();
365 BookmarkReorderOperation::~BookmarkReorderOperation() {
368 void BookmarkReorderOperation::Undo() {
369 BookmarkModel* model = bookmark_model();
370 const BookmarkNode* parent =
371 bookmarks::GetBookmarkNodeByID(model, parent_id_);
372 DCHECK(parent);
374 std::vector<const BookmarkNode*> ordered_nodes;
375 for (size_t i = 0; i < ordered_bookmarks_.size(); ++i) {
376 ordered_nodes.push_back(
377 bookmarks::GetBookmarkNodeByID(model, ordered_bookmarks_[i]));
380 model->ReorderChildren(parent, ordered_nodes);
383 int BookmarkReorderOperation::GetUndoLabelId() const {
384 return IDS_BOOKMARK_BAR_UNDO_REORDER;
387 int BookmarkReorderOperation::GetRedoLabelId() const {
388 return IDS_BOOKMARK_BAR_REDO_REORDER;
391 void BookmarkReorderOperation::OnBookmarkRenumbered(int64 old_id,
392 int64 new_id) {
393 if (parent_id_ == old_id)
394 parent_id_ = new_id;
395 for (size_t i = 0; i < ordered_bookmarks_.size(); ++i) {
396 if (ordered_bookmarks_[i] == old_id)
397 ordered_bookmarks_[i] = new_id;
401 } // namespace
403 // BookmarkUndoService --------------------------------------------------------
405 BookmarkUndoService::BookmarkUndoService() : scoped_observer_(this) {
408 BookmarkUndoService::~BookmarkUndoService() {
411 void BookmarkUndoService::Start(BookmarkModel* model) {
412 scoped_observer_.Add(model);
415 void BookmarkUndoService::Shutdown() {
416 scoped_observer_.RemoveAll();
419 void BookmarkUndoService::BookmarkModelLoaded(BookmarkModel* model,
420 bool ids_reassigned) {
421 undo_manager_.RemoveAllOperations();
424 void BookmarkUndoService::BookmarkModelBeingDeleted(BookmarkModel* model) {
425 undo_manager_.RemoveAllOperations();
428 void BookmarkUndoService::BookmarkNodeMoved(BookmarkModel* model,
429 const BookmarkNode* old_parent,
430 int old_index,
431 const BookmarkNode* new_parent,
432 int new_index) {
433 scoped_ptr<UndoOperation> op(new BookmarkMoveOperation(
434 model, this, old_parent, old_index, new_parent, new_index));
435 undo_manager()->AddUndoOperation(op.Pass());
438 void BookmarkUndoService::BookmarkNodeAdded(BookmarkModel* model,
439 const BookmarkNode* parent,
440 int index) {
441 scoped_ptr<UndoOperation> op(
442 new BookmarkAddOperation(model, this, parent, index));
443 undo_manager()->AddUndoOperation(op.Pass());
446 void BookmarkUndoService::OnWillRemoveBookmarks(BookmarkModel* model,
447 const BookmarkNode* parent,
448 int old_index,
449 const BookmarkNode* node) {
450 scoped_ptr<UndoOperation> op(
451 new BookmarkRemoveOperation(model, this, parent, old_index, node));
452 undo_manager()->AddUndoOperation(op.Pass());
455 void BookmarkUndoService::OnWillRemoveAllUserBookmarks(BookmarkModel* model) {
456 bookmarks::ScopedGroupBookmarkActions merge_removes(model);
457 for (int i = 0; i < model->root_node()->child_count(); ++i) {
458 const BookmarkNode* permanent_node = model->root_node()->GetChild(i);
459 for (int j = permanent_node->child_count() - 1; j >= 0; --j) {
460 scoped_ptr<UndoOperation> op(new BookmarkRemoveOperation(
461 model, this, permanent_node, j, permanent_node->GetChild(j)));
462 undo_manager()->AddUndoOperation(op.Pass());
467 void BookmarkUndoService::OnWillChangeBookmarkNode(BookmarkModel* model,
468 const BookmarkNode* node) {
469 scoped_ptr<UndoOperation> op(new BookmarkEditOperation(model, this, node));
470 undo_manager()->AddUndoOperation(op.Pass());
473 void BookmarkUndoService::OnWillReorderBookmarkNode(BookmarkModel* model,
474 const BookmarkNode* node) {
475 scoped_ptr<UndoOperation> op(new BookmarkReorderOperation(model, this, node));
476 undo_manager()->AddUndoOperation(op.Pass());
479 void BookmarkUndoService::GroupedBookmarkChangesBeginning(
480 BookmarkModel* model) {
481 undo_manager()->StartGroupingActions();
484 void BookmarkUndoService::GroupedBookmarkChangesEnded(BookmarkModel* model) {
485 undo_manager()->EndGroupingActions();
488 void BookmarkUndoService::OnBookmarkRenumbered(int64 old_id, int64 new_id) {
489 std::vector<UndoOperation*> all_operations =
490 undo_manager()->GetAllUndoOperations();
491 for (UndoOperation* op : all_operations) {
492 static_cast<BookmarkUndoOperation*>(op)
493 ->OnBookmarkRenumbered(old_id, new_id);