158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// found in the LICENSE file.
458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/undo/bookmark_undo_service.h"
658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model_factory.h"
858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/profiles/profile.h"
958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/undo/bookmark_renumber_observer.h"
1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/undo/bookmark_undo_service_factory.h"
1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/browser/undo/undo_operation.h"
1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/grit/generated_resources.h"
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/bookmarks/browser/bookmark_model.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/bookmarks/browser/bookmark_node_data.h"
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/bookmarks/browser/bookmark_utils.h"
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/bookmarks/browser/scoped_group_bookmark_actions.h"
1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)using bookmarks::BookmarkNodeData;
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)namespace {
2158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// BookmarkUndoOperation ------------------------------------------------------
2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Base class for all bookmark related UndoOperations that facilitates access to
2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// the BookmarkUndoService.
2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class BookmarkUndoOperation : public UndoOperation,
2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                              public BookmarkRenumberObserver {
2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public:
2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  explicit BookmarkUndoOperation(Profile* profile);
3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual ~BookmarkUndoOperation() {}
3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BookmarkModel* GetBookmarkModel() const;
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BookmarkRenumberObserver* GetUndoRenumberObserver() const;
3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private:
3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  Profile* profile_;
3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)BookmarkUndoOperation::BookmarkUndoOperation(Profile* profile)
4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    : profile_(profile) {
4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)BookmarkModel* BookmarkUndoOperation::GetBookmarkModel() const {
4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return BookmarkModelFactory::GetForProfile(profile_);
4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)BookmarkRenumberObserver* BookmarkUndoOperation::GetUndoRenumberObserver()
4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const {
4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  return BookmarkUndoServiceFactory::GetForProfile(profile_);
5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// BookmarkAddOperation -------------------------------------------------------
5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Handles the undo of the insertion of a bookmark or folder.
5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class BookmarkAddOperation : public BookmarkUndoOperation {
5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public:
5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BookmarkAddOperation(Profile* profile, const BookmarkNode* parent, int index);
5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual ~BookmarkAddOperation() {}
5958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // UndoOperation:
6158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void Undo() OVERRIDE;
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual int GetUndoLabelId() const OVERRIDE;
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual int GetRedoLabelId() const OVERRIDE;
6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // BookmarkRenumberObserver:
6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void OnBookmarkRenumbered(int64 old_id, int64 new_id) OVERRIDE;
6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private:
6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int64 parent_id_;
7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const int index_;
7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BookmarkAddOperation);
7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
7458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)BookmarkAddOperation::BookmarkAddOperation(Profile* profile,
7658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                           const BookmarkNode* parent,
7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                           int index)
7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  : BookmarkUndoOperation(profile),
7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    parent_id_(parent->id()),
8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    index_(index) {
8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
8258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void BookmarkAddOperation::Undo() {
8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BookmarkModel* model = GetBookmarkModel();
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const BookmarkNode* parent =
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      bookmarks::GetBookmarkNodeByID(model, parent_id_);
8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(parent);
8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  model->Remove(parent, index_);
9058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
9158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int BookmarkAddOperation::GetUndoLabelId() const {
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return IDS_BOOKMARK_BAR_UNDO_ADD;
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int BookmarkAddOperation::GetRedoLabelId() const {
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return IDS_BOOKMARK_BAR_REDO_DELETE;
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
10058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void BookmarkAddOperation::OnBookmarkRenumbered(int64 old_id, int64 new_id) {
10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (parent_id_ == old_id)
10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    parent_id_ = new_id;
10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// BookmarkRemoveOperation ----------------------------------------------------
10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Handles the undo of the deletion of a bookmark node. For a bookmark folder,
10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// the information for all descendant bookmark nodes is maintained.
10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)//
11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// The BookmarkModel allows only single bookmark node to be removed.
11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class BookmarkRemoveOperation : public BookmarkUndoOperation {
11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public:
11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BookmarkRemoveOperation(Profile* profile,
11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                          const BookmarkNode* parent,
11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                          int old_index,
11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                          const BookmarkNode* node);
11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual ~BookmarkRemoveOperation() {}
11858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
11958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // UndoOperation:
12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void Undo() OVERRIDE;
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual int GetUndoLabelId() const OVERRIDE;
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual int GetRedoLabelId() const OVERRIDE;
12358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
12458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // BookmarkRenumberObserver:
12558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void OnBookmarkRenumbered(int64 old_id, int64 new_id) OVERRIDE;
12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private:
12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  void UpdateBookmarkIds(const BookmarkNodeData::Element& element,
12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                         const BookmarkNode* parent,
13058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                         int index_added_at) const;
13158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
13258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int64 parent_id_;
13358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const int old_index_;
13458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BookmarkNodeData removed_node_;
13558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
13658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BookmarkRemoveOperation);
13758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
13858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
13958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)BookmarkRemoveOperation::BookmarkRemoveOperation(Profile* profile,
14058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                 const BookmarkNode* parent,
14158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                 int old_index,
14258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                 const BookmarkNode* node)
14358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  : BookmarkUndoOperation(profile),
14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    parent_id_(parent->id()),
14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    old_index_(old_index),
14658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    removed_node_(node) {
14758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
14858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void BookmarkRemoveOperation::Undo() {
15058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(removed_node_.is_valid());
15158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BookmarkModel* model = GetBookmarkModel();
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const BookmarkNode* parent =
153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      bookmarks::GetBookmarkNodeByID(model, parent_id_);
15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(parent);
15558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bookmarks::CloneBookmarkNode(
157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      model, removed_node_.elements, parent, old_index_, false);
15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  UpdateBookmarkIds(removed_node_.elements[0], parent, old_index_);
15958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
16058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int BookmarkRemoveOperation::GetUndoLabelId() const {
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return IDS_BOOKMARK_BAR_UNDO_DELETE;
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int BookmarkRemoveOperation::GetRedoLabelId() const {
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return IDS_BOOKMARK_BAR_REDO_ADD;
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
16958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void BookmarkRemoveOperation::UpdateBookmarkIds(
17058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const BookmarkNodeData::Element& element,
17158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const BookmarkNode* parent,
17258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    int index_added_at) const {
17358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const BookmarkNode* node = parent->GetChild(index_added_at);
17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (element.id() != node->id())
17558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    GetUndoRenumberObserver()->OnBookmarkRenumbered(element.id(), node->id());
17658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!element.is_url) {
17758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    for (int i = 0; i < static_cast<int>(element.children.size()); ++i)
17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      UpdateBookmarkIds(element.children[i], node, 0);
17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
18058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
18158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
18258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void BookmarkRemoveOperation::OnBookmarkRenumbered(int64 old_id, int64 new_id) {
18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (parent_id_ == old_id)
18458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    parent_id_ = new_id;
18558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
18658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
18758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// BookmarkEditOperation ------------------------------------------------------
18858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
18958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Handles the undo of the modification of a bookmark node.
19058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class BookmarkEditOperation : public BookmarkUndoOperation {
19158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public:
19258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BookmarkEditOperation(Profile* profile,
19358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        const BookmarkNode* node);
19458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual ~BookmarkEditOperation() {}
19558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
19658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // UndoOperation:
19758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void Undo() OVERRIDE;
1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual int GetUndoLabelId() const OVERRIDE;
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual int GetRedoLabelId() const OVERRIDE;
20058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
20158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // BookmarkRenumberObserver:
20258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void OnBookmarkRenumbered(int64 old_id, int64 new_id) OVERRIDE;
20358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
20458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private:
20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int64 node_id_;
20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BookmarkNodeData original_bookmark_;
20758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
20858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BookmarkEditOperation);
20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
21058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
21158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)BookmarkEditOperation::BookmarkEditOperation(Profile* profile,
21258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                             const BookmarkNode* node)
21358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    : BookmarkUndoOperation(profile),
21458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      node_id_(node->id()),
21558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      original_bookmark_(node) {
21658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
21758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
21858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void BookmarkEditOperation::Undo() {
21958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(original_bookmark_.is_valid());
22058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BookmarkModel* model = GetBookmarkModel();
221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const BookmarkNode* node = bookmarks::GetBookmarkNodeByID(model, node_id_);
22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(node);
22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
22458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  model->SetTitle(node, original_bookmark_.elements[0].title);
22558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (original_bookmark_.elements[0].is_url)
22658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    model->SetURL(node, original_bookmark_.elements[0].url);
22758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
22858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int BookmarkEditOperation::GetUndoLabelId() const {
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return IDS_BOOKMARK_BAR_UNDO_EDIT;
2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int BookmarkEditOperation::GetRedoLabelId() const {
2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return IDS_BOOKMARK_BAR_REDO_EDIT;
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
23758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void BookmarkEditOperation::OnBookmarkRenumbered(int64 old_id, int64 new_id) {
23858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (node_id_ == old_id)
23958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    node_id_ = new_id;
24058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
24158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
24258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// BookmarkMoveOperation ------------------------------------------------------
24358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
24458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Handles the undo of a bookmark being moved to a new location.
24558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class BookmarkMoveOperation : public BookmarkUndoOperation {
24658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public:
24758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BookmarkMoveOperation(Profile* profile,
24858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        const BookmarkNode* old_parent,
24958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        int old_index,
25058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        const BookmarkNode* new_parent,
25158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                        int new_index);
25258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual ~BookmarkMoveOperation() {}
2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual int GetUndoLabelId() const OVERRIDE;
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual int GetRedoLabelId() const OVERRIDE;
25558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
25658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // UndoOperation:
25758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void Undo() OVERRIDE;
25858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
25958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // BookmarkRenumberObserver:
26058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void OnBookmarkRenumbered(int64 old_id, int64 new_id) OVERRIDE;
26158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
26258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private:
26358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int64 old_parent_id_;
26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int64 new_parent_id_;
26558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int old_index_;
26658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int new_index_;
26758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
26858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BookmarkMoveOperation);
26958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
27058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
27158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)BookmarkMoveOperation::BookmarkMoveOperation(Profile* profile,
27258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                             const BookmarkNode* old_parent,
27358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                             int old_index,
27458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                             const BookmarkNode* new_parent,
27558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                             int new_index)
27658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    : BookmarkUndoOperation(profile),
27758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      old_parent_id_(old_parent->id()),
27858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      new_parent_id_(new_parent->id()),
27958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      old_index_(old_index),
28058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      new_index_(new_index) {
28158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
28258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
28358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void BookmarkMoveOperation::Undo() {
28458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BookmarkModel* model = GetBookmarkModel();
285116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const BookmarkNode* old_parent =
286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      bookmarks::GetBookmarkNodeByID(model, old_parent_id_);
287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const BookmarkNode* new_parent =
288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      bookmarks::GetBookmarkNodeByID(model, new_parent_id_);
28958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(old_parent);
29058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(new_parent);
29158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
29258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const BookmarkNode* node = new_parent->GetChild(new_index_);
29358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int destination_index = old_index_;
29458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
29558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // If the bookmark was moved up within the same parent then the destination
29658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // index needs to be incremented since the old index did not account for the
29758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // moved bookmark.
29858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (old_parent == new_parent && new_index_ < old_index_)
29958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ++destination_index;
30058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
30158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  model->Move(node, old_parent, destination_index);
30258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
30358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int BookmarkMoveOperation::GetUndoLabelId() const {
3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return IDS_BOOKMARK_BAR_UNDO_MOVE;
3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int BookmarkMoveOperation::GetRedoLabelId() const {
3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return IDS_BOOKMARK_BAR_REDO_MOVE;
3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
31258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void BookmarkMoveOperation::OnBookmarkRenumbered(int64 old_id, int64 new_id) {
31358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (old_parent_id_ == old_id)
31458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    old_parent_id_ = new_id;
31558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (new_parent_id_ == old_id)
31658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    new_parent_id_ = new_id;
31758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
31858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
31958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// BookmarkReorderOperation ---------------------------------------------------
32058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
32158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Handle the undo of reordering of bookmarks that can happen as a result of
32258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// sorting a bookmark folder by name or the undo of that operation.  The change
32358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// of order is not recursive so only the order of the immediate children of the
32458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// folder need to be restored.
32558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)class BookmarkReorderOperation : public BookmarkUndoOperation {
32658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) public:
32758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BookmarkReorderOperation(Profile* profile,
32858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                           const BookmarkNode* parent);
32958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual ~BookmarkReorderOperation();
33058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
33158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // UndoOperation:
33258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void Undo() OVERRIDE;
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual int GetUndoLabelId() const OVERRIDE;
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual int GetRedoLabelId() const OVERRIDE;
33558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
33658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // BookmarkRenumberObserver:
33758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual void OnBookmarkRenumbered(int64 old_id, int64 new_id) OVERRIDE;
33858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
33958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) private:
34058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  int64 parent_id_;
34158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::vector<int64> ordered_bookmarks_;
34258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
34358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BookmarkReorderOperation);
34458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)};
34558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
34658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)BookmarkReorderOperation::BookmarkReorderOperation(Profile* profile,
34758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                   const BookmarkNode* parent)
34858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    : BookmarkUndoOperation(profile),
34958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      parent_id_(parent->id()) {
35058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ordered_bookmarks_.resize(parent->child_count());
35158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (int i = 0; i < parent->child_count(); ++i)
35258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    ordered_bookmarks_[i] = parent->GetChild(i)->id();
35358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
35458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
35558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)BookmarkReorderOperation::~BookmarkReorderOperation() {
35658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
35758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
35858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void BookmarkReorderOperation::Undo() {
35958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BookmarkModel* model = GetBookmarkModel();
360116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const BookmarkNode* parent =
361116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      bookmarks::GetBookmarkNodeByID(model, parent_id_);
36258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DCHECK(parent);
36358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
36458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  std::vector<const BookmarkNode*> ordered_nodes;
365116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  for (size_t i = 0; i < ordered_bookmarks_.size(); ++i) {
366116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ordered_nodes.push_back(
367116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        bookmarks::GetBookmarkNodeByID(model, ordered_bookmarks_[i]));
368116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
36958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
37058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  model->ReorderChildren(parent, ordered_nodes);
37158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
37258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int BookmarkReorderOperation::GetUndoLabelId() const {
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return IDS_BOOKMARK_BAR_UNDO_REORDER;
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int BookmarkReorderOperation::GetRedoLabelId() const {
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return IDS_BOOKMARK_BAR_REDO_REORDER;
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
38158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void BookmarkReorderOperation::OnBookmarkRenumbered(int64 old_id,
38258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                    int64 new_id) {
38358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (parent_id_ == old_id)
38458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    parent_id_ = new_id;
38558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (size_t i = 0; i < ordered_bookmarks_.size(); ++i) {
38658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    if (ordered_bookmarks_[i] == old_id)
38758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      ordered_bookmarks_[i] = new_id;
38858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
38958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
39058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
39158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}  // namespace
39258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
39358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// BookmarkUndoService --------------------------------------------------------
39458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
39558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)BookmarkUndoService::BookmarkUndoService(Profile* profile) : profile_(profile) {
39658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
39758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
39858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)BookmarkUndoService::~BookmarkUndoService() {
39958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  BookmarkModelFactory::GetForProfile(profile_)->RemoveObserver(this);
40058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
40158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void BookmarkUndoService::BookmarkModelLoaded(BookmarkModel* model,
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                              bool ids_reassigned) {
40458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  undo_manager_.RemoveAllOperations();
40558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
40658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
40758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void BookmarkUndoService::BookmarkModelBeingDeleted(BookmarkModel* model) {
40858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  undo_manager_.RemoveAllOperations();
40958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
41058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
41158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void BookmarkUndoService::BookmarkNodeMoved(BookmarkModel* model,
41258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                            const BookmarkNode* old_parent,
41358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                            int old_index,
41458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                            const BookmarkNode* new_parent,
41558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                            int new_index) {
41658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<UndoOperation> op(new BookmarkMoveOperation(profile_,
41758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                         old_parent,
41858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                         old_index,
41958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                         new_parent,
42058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                         new_index));
42158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  undo_manager()->AddUndoOperation(op.Pass());
42258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
42358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
42458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void BookmarkUndoService::BookmarkNodeAdded(BookmarkModel* model,
42558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                            const BookmarkNode* parent,
42658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                            int index) {
42758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<UndoOperation> op(new BookmarkAddOperation(profile_,
42858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                        parent,
42958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                        index));
43058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  undo_manager()->AddUndoOperation(op.Pass());
43158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
43258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
43358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void BookmarkUndoService::OnWillRemoveBookmarks(BookmarkModel* model,
43458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                const BookmarkNode* parent,
43558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                int old_index,
43658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                const BookmarkNode* node) {
43758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<UndoOperation> op(new BookmarkRemoveOperation(profile_,
43858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                           parent,
43958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                           old_index,
44058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                           node));
44158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  undo_manager()->AddUndoOperation(op.Pass());
44258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
44358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
444f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void BookmarkUndoService::OnWillRemoveAllUserBookmarks(BookmarkModel* model) {
445cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bookmarks::ScopedGroupBookmarkActions merge_removes(model);
44658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  for (int i = 0; i < model->root_node()->child_count(); ++i) {
44758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    const BookmarkNode* permanent_node = model->root_node()->GetChild(i);
44858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    for (int j = permanent_node->child_count() - 1; j >= 0; --j) {
44958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      scoped_ptr<UndoOperation> op(new BookmarkRemoveOperation(profile_,
45058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          permanent_node, j, permanent_node->GetChild(j)));
45158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      undo_manager()->AddUndoOperation(op.Pass());
45258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }
45358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
45458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
45558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
45658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void BookmarkUndoService::OnWillChangeBookmarkNode(BookmarkModel* model,
45758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                   const BookmarkNode* node) {
45858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<UndoOperation> op(new BookmarkEditOperation(profile_, node));
45958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  undo_manager()->AddUndoOperation(op.Pass());
46058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
46158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
46258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void BookmarkUndoService::OnWillReorderBookmarkNode(BookmarkModel* model,
46358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                                    const BookmarkNode* node) {
46458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  scoped_ptr<UndoOperation> op(new BookmarkReorderOperation(profile_, node));
46558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  undo_manager()->AddUndoOperation(op.Pass());
46658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
467a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
468a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BookmarkUndoService::GroupedBookmarkChangesBeginning(
469a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    BookmarkModel* model) {
470a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  undo_manager()->StartGroupingActions();
471a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
472a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
473a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BookmarkUndoService::GroupedBookmarkChangesEnded(BookmarkModel* model) {
474a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  undo_manager()->EndGroupingActions();
475a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
476a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
477a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void BookmarkUndoService::OnBookmarkRenumbered(int64 old_id, int64 new_id) {
478a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::vector<UndoOperation*> all_operations =
479a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      undo_manager()->GetAllUndoOperations();
480a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (std::vector<UndoOperation*>::iterator it = all_operations.begin();
481a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       it != all_operations.end(); ++it) {
482a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    static_cast<BookmarkUndoOperation*>(*it)->OnBookmarkRenumbered(old_id,
483a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                                   new_id);
484a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
485a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
486