123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421 |
- // Copyright 2013 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "components/undo/bookmark_undo_service.h"
- #include <stddef.h>
- #include <stdint.h>
- #include <memory>
- #include <utility>
- #include "base/memory/raw_ptr.h"
- #include "components/bookmarks/browser/bookmark_node_data.h"
- #include "components/bookmarks/browser/bookmark_undo_provider.h"
- #include "components/bookmarks/browser/bookmark_utils.h"
- #include "components/bookmarks/browser/scoped_group_bookmark_actions.h"
- #include "components/strings/grit/components_strings.h"
- #include "components/undo/undo_operation.h"
- using bookmarks::BookmarkModel;
- using bookmarks::BookmarkNode;
- using bookmarks::BookmarkNodeData;
- using bookmarks::BookmarkUndoProvider;
- namespace {
- // BookmarkUndoOperation ------------------------------------------------------
- // Base class for all bookmark related UndoOperations that facilitates access to
- // the BookmarkUndoService.
- class BookmarkUndoOperation : public UndoOperation {
- public:
- explicit BookmarkUndoOperation(BookmarkModel* bookmark_model)
- : bookmark_model_(bookmark_model) {}
- ~BookmarkUndoOperation() override {}
- BookmarkModel* bookmark_model() { return bookmark_model_; }
- private:
- raw_ptr<BookmarkModel> bookmark_model_;
- };
- // BookmarkAddOperation -------------------------------------------------------
- // Handles the undo of the insertion of a bookmark or folder.
- class BookmarkAddOperation : public BookmarkUndoOperation {
- public:
- BookmarkAddOperation(BookmarkModel* bookmark_model,
- const BookmarkNode* parent,
- size_t index);
- BookmarkAddOperation(const BookmarkAddOperation&) = delete;
- BookmarkAddOperation& operator=(const BookmarkAddOperation&) = delete;
- ~BookmarkAddOperation() override {}
- // UndoOperation:
- void Undo() override;
- int GetUndoLabelId() const override;
- int GetRedoLabelId() const override;
- private:
- int64_t parent_id_;
- const size_t index_;
- };
- BookmarkAddOperation::BookmarkAddOperation(BookmarkModel* bookmark_model,
- const BookmarkNode* parent,
- size_t index)
- : BookmarkUndoOperation(bookmark_model),
- parent_id_(parent->id()),
- index_(index) {}
- void BookmarkAddOperation::Undo() {
- BookmarkModel* model = bookmark_model();
- const BookmarkNode* parent =
- bookmarks::GetBookmarkNodeByID(model, parent_id_);
- DCHECK(parent);
- model->Remove(parent->children()[index_].get());
- }
- int BookmarkAddOperation::GetUndoLabelId() const {
- return IDS_BOOKMARK_BAR_UNDO_ADD;
- }
- int BookmarkAddOperation::GetRedoLabelId() const {
- return IDS_BOOKMARK_BAR_REDO_DELETE;
- }
- // BookmarkRemoveOperation ----------------------------------------------------
- // Handles the undo of the deletion of a bookmark node. For a bookmark folder,
- // the information for all descendant bookmark nodes is maintained.
- //
- // The BookmarkModel allows only single bookmark node to be removed.
- class BookmarkRemoveOperation : public BookmarkUndoOperation {
- public:
- BookmarkRemoveOperation(BookmarkModel* model,
- BookmarkUndoProvider* undo_provider,
- const BookmarkNode* parent,
- size_t index,
- std::unique_ptr<BookmarkNode> node);
- BookmarkRemoveOperation(const BookmarkRemoveOperation&) = delete;
- BookmarkRemoveOperation& operator=(const BookmarkRemoveOperation&) = delete;
- ~BookmarkRemoveOperation() override;
- // UndoOperation:
- void Undo() override;
- int GetUndoLabelId() const override;
- int GetRedoLabelId() const override;
- private:
- raw_ptr<BookmarkUndoProvider> undo_provider_;
- const int64_t parent_node_id_;
- const size_t index_;
- std::unique_ptr<BookmarkNode> node_;
- };
- BookmarkRemoveOperation::BookmarkRemoveOperation(
- BookmarkModel* model,
- BookmarkUndoProvider* undo_provider,
- const BookmarkNode* parent,
- size_t index,
- std::unique_ptr<BookmarkNode> node)
- : BookmarkUndoOperation(model),
- undo_provider_(undo_provider),
- parent_node_id_(parent->id()),
- index_(index),
- node_(std::move(node)) {}
- BookmarkRemoveOperation::~BookmarkRemoveOperation() {
- }
- void BookmarkRemoveOperation::Undo() {
- DCHECK(node_);
- const BookmarkNode* parent = bookmarks::GetBookmarkNodeByID(
- bookmark_model(), parent_node_id_);
- DCHECK(parent);
- undo_provider_->RestoreRemovedNode(parent, index_, std::move(node_));
- }
- int BookmarkRemoveOperation::GetUndoLabelId() const {
- return IDS_BOOKMARK_BAR_UNDO_DELETE;
- }
- int BookmarkRemoveOperation::GetRedoLabelId() const {
- return IDS_BOOKMARK_BAR_REDO_ADD;
- }
- // BookmarkEditOperation ------------------------------------------------------
- // Handles the undo of the modification of a bookmark node.
- class BookmarkEditOperation : public BookmarkUndoOperation {
- public:
- BookmarkEditOperation(BookmarkModel* bookmark_model,
- const BookmarkNode* node);
- BookmarkEditOperation(const BookmarkEditOperation&) = delete;
- BookmarkEditOperation& operator=(const BookmarkEditOperation&) = delete;
- ~BookmarkEditOperation() override {}
- // UndoOperation:
- void Undo() override;
- int GetUndoLabelId() const override;
- int GetRedoLabelId() const override;
- private:
- int64_t node_id_;
- BookmarkNodeData original_bookmark_;
- };
- BookmarkEditOperation::BookmarkEditOperation(
- BookmarkModel* bookmark_model,
- const BookmarkNode* node)
- : BookmarkUndoOperation(bookmark_model),
- node_id_(node->id()),
- original_bookmark_(node) {
- }
- void BookmarkEditOperation::Undo() {
- DCHECK(original_bookmark_.is_valid());
- BookmarkModel* model = bookmark_model();
- const BookmarkNode* node = bookmarks::GetBookmarkNodeByID(model, node_id_);
- DCHECK(node);
- model->SetTitle(node, original_bookmark_.elements[0].title);
- if (original_bookmark_.elements[0].is_url)
- model->SetURL(node, original_bookmark_.elements[0].url);
- }
- int BookmarkEditOperation::GetUndoLabelId() const {
- return IDS_BOOKMARK_BAR_UNDO_EDIT;
- }
- int BookmarkEditOperation::GetRedoLabelId() const {
- return IDS_BOOKMARK_BAR_REDO_EDIT;
- }
- // BookmarkMoveOperation ------------------------------------------------------
- // Handles the undo of a bookmark being moved to a new location.
- class BookmarkMoveOperation : public BookmarkUndoOperation {
- public:
- BookmarkMoveOperation(BookmarkModel* bookmark_model,
- const BookmarkNode* old_parent,
- size_t old_index,
- const BookmarkNode* new_parent,
- size_t new_index);
- BookmarkMoveOperation(const BookmarkMoveOperation&) = delete;
- BookmarkMoveOperation& operator=(const BookmarkMoveOperation&) = delete;
- ~BookmarkMoveOperation() override {}
- int GetUndoLabelId() const override;
- int GetRedoLabelId() const override;
- // UndoOperation:
- void Undo() override;
- private:
- int64_t old_parent_id_;
- int64_t new_parent_id_;
- size_t old_index_;
- size_t new_index_;
- };
- BookmarkMoveOperation::BookmarkMoveOperation(BookmarkModel* bookmark_model,
- const BookmarkNode* old_parent,
- size_t old_index,
- const BookmarkNode* new_parent,
- size_t new_index)
- : BookmarkUndoOperation(bookmark_model),
- old_parent_id_(old_parent->id()),
- new_parent_id_(new_parent->id()),
- old_index_(old_index),
- new_index_(new_index) {}
- void BookmarkMoveOperation::Undo() {
- BookmarkModel* model = bookmark_model();
- const BookmarkNode* old_parent =
- bookmarks::GetBookmarkNodeByID(model, old_parent_id_);
- const BookmarkNode* new_parent =
- bookmarks::GetBookmarkNodeByID(model, new_parent_id_);
- DCHECK(old_parent);
- DCHECK(new_parent);
- const BookmarkNode* node = new_parent->children()[new_index_].get();
- size_t destination_index = old_index_;
- // If the bookmark was moved up within the same parent then the destination
- // index needs to be incremented since the old index did not account for the
- // moved bookmark.
- if (old_parent == new_parent && new_index_ < old_index_)
- ++destination_index;
- model->Move(node, old_parent, destination_index);
- }
- int BookmarkMoveOperation::GetUndoLabelId() const {
- return IDS_BOOKMARK_BAR_UNDO_MOVE;
- }
- int BookmarkMoveOperation::GetRedoLabelId() const {
- return IDS_BOOKMARK_BAR_REDO_MOVE;
- }
- // BookmarkReorderOperation ---------------------------------------------------
- // Handle the undo of reordering of bookmarks that can happen as a result of
- // sorting a bookmark folder by name or the undo of that operation. The change
- // of order is not recursive so only the order of the immediate children of the
- // folder need to be restored.
- class BookmarkReorderOperation : public BookmarkUndoOperation {
- public:
- BookmarkReorderOperation(BookmarkModel* bookmark_model,
- const BookmarkNode* parent);
- BookmarkReorderOperation(const BookmarkReorderOperation&) = delete;
- BookmarkReorderOperation& operator=(const BookmarkReorderOperation&) = delete;
- ~BookmarkReorderOperation() override;
- // UndoOperation:
- void Undo() override;
- int GetUndoLabelId() const override;
- int GetRedoLabelId() const override;
- private:
- int64_t parent_id_;
- std::vector<int64_t> ordered_bookmarks_;
- };
- BookmarkReorderOperation::BookmarkReorderOperation(
- BookmarkModel* bookmark_model,
- const BookmarkNode* parent)
- : BookmarkUndoOperation(bookmark_model),
- parent_id_(parent->id()) {
- ordered_bookmarks_.resize(parent->children().size());
- std::transform(parent->children().cbegin(), parent->children().cend(),
- ordered_bookmarks_.begin(),
- [](const auto& child) { return child->id(); });
- }
- BookmarkReorderOperation::~BookmarkReorderOperation() {
- }
- void BookmarkReorderOperation::Undo() {
- BookmarkModel* model = bookmark_model();
- const BookmarkNode* parent =
- bookmarks::GetBookmarkNodeByID(model, parent_id_);
- DCHECK(parent);
- std::vector<const BookmarkNode*> ordered_nodes;
- for (size_t i = 0; i < ordered_bookmarks_.size(); ++i) {
- ordered_nodes.push_back(
- bookmarks::GetBookmarkNodeByID(model, ordered_bookmarks_[i]));
- }
- model->ReorderChildren(parent, ordered_nodes);
- }
- int BookmarkReorderOperation::GetUndoLabelId() const {
- return IDS_BOOKMARK_BAR_UNDO_REORDER;
- }
- int BookmarkReorderOperation::GetRedoLabelId() const {
- return IDS_BOOKMARK_BAR_REDO_REORDER;
- }
- } // namespace
- // BookmarkUndoService --------------------------------------------------------
- BookmarkUndoService::BookmarkUndoService() : model_(nullptr) {}
- BookmarkUndoService::~BookmarkUndoService() {
- }
- void BookmarkUndoService::Start(BookmarkModel* model) {
- DCHECK(!model_);
- model_ = model;
- scoped_observation_.Observe(model);
- model->SetUndoDelegate(this);
- }
- void BookmarkUndoService::Shutdown() {
- DCHECK(model_);
- DCHECK(scoped_observation_.IsObserving());
- scoped_observation_.Reset();
- model_->SetUndoDelegate(nullptr);
- }
- void BookmarkUndoService::BookmarkModelLoaded(BookmarkModel* model,
- bool ids_reassigned) {
- undo_manager_.RemoveAllOperations();
- }
- void BookmarkUndoService::BookmarkModelBeingDeleted(BookmarkModel* model) {
- undo_manager_.RemoveAllOperations();
- }
- void BookmarkUndoService::BookmarkNodeMoved(BookmarkModel* model,
- const BookmarkNode* old_parent,
- size_t old_index,
- const BookmarkNode* new_parent,
- size_t new_index) {
- std::unique_ptr<UndoOperation> op(new BookmarkMoveOperation(
- model, old_parent, old_index, new_parent, new_index));
- undo_manager()->AddUndoOperation(std::move(op));
- }
- void BookmarkUndoService::BookmarkNodeAdded(BookmarkModel* model,
- const BookmarkNode* parent,
- size_t index) {
- std::unique_ptr<UndoOperation> op(
- new BookmarkAddOperation(model, parent, index));
- undo_manager()->AddUndoOperation(std::move(op));
- }
- void BookmarkUndoService::OnWillChangeBookmarkNode(BookmarkModel* model,
- const BookmarkNode* node) {
- std::unique_ptr<UndoOperation> op(new BookmarkEditOperation(model, node));
- undo_manager()->AddUndoOperation(std::move(op));
- }
- void BookmarkUndoService::OnWillReorderBookmarkNode(BookmarkModel* model,
- const BookmarkNode* node) {
- std::unique_ptr<UndoOperation> op(new BookmarkReorderOperation(model, node));
- undo_manager()->AddUndoOperation(std::move(op));
- }
- void BookmarkUndoService::GroupedBookmarkChangesBeginning(
- BookmarkModel* model) {
- undo_manager()->StartGroupingActions();
- }
- void BookmarkUndoService::GroupedBookmarkChangesEnded(BookmarkModel* model) {
- undo_manager()->EndGroupingActions();
- }
- void BookmarkUndoService::SetUndoProvider(BookmarkUndoProvider* undo_provider) {
- undo_provider_ = undo_provider;
- }
- void BookmarkUndoService::OnBookmarkNodeRemoved(
- BookmarkModel* model,
- const BookmarkNode* parent,
- size_t index,
- std::unique_ptr<BookmarkNode> node) {
- DCHECK(undo_provider_);
- std::unique_ptr<UndoOperation> op(new BookmarkRemoveOperation(
- model, undo_provider_, parent, index, std::move(node)));
- undo_manager()->AddUndoOperation(std::move(op));
- }
|