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. 4 5 #ifndef COMPONENTS_UNDO_UNDO_MANAGER_H_ 6 #define COMPONENTS_UNDO_UNDO_MANAGER_H_ 7 8 #include <stddef.h> 9 10 #include <memory> 11 #include <vector> 12 13 #include "base/macros.h" 14 #include "base/observer_list.h" 15 #include "base/strings/string16.h" 16 17 class UndoManagerObserver; 18 class UndoOperation; 19 20 // UndoGroup ------------------------------------------------------------------ 21 22 // UndoGroup represents a user action and stores all the operations that 23 // make that action. Typically there is only one operation per UndoGroup. 24 class UndoGroup { 25 public: 26 UndoGroup(); 27 ~UndoGroup(); 28 29 void AddOperation(std::unique_ptr<UndoOperation> operation); undo_operations()30 const std::vector<std::unique_ptr<UndoOperation>>& undo_operations() { 31 return operations_; 32 } 33 void Undo(); 34 35 // The resource string id describing the undo and redo action. get_undo_label_id()36 int get_undo_label_id() const { return undo_label_id_; } set_undo_label_id(int label_id)37 void set_undo_label_id(int label_id) { undo_label_id_ = label_id; } 38 get_redo_label_id()39 int get_redo_label_id() const { return redo_label_id_; } set_redo_label_id(int label_id)40 void set_redo_label_id(int label_id) { redo_label_id_ = label_id; } 41 42 private: 43 std::vector<std::unique_ptr<UndoOperation>> operations_; 44 45 // The resource string id describing the undo and redo action. 46 int undo_label_id_; 47 int redo_label_id_; 48 49 DISALLOW_COPY_AND_ASSIGN(UndoGroup); 50 }; 51 52 // UndoManager ---------------------------------------------------------------- 53 54 // Maintains user actions as a group of operations that store enough info to 55 // undo and redo those operations. 56 class UndoManager { 57 public: 58 UndoManager(); 59 ~UndoManager(); 60 61 // Perform an undo or redo operation. 62 void Undo(); 63 void Redo(); 64 undo_count()65 size_t undo_count() const { return undo_actions_.size(); } redo_count()66 size_t redo_count() const { return redo_actions_.size(); } 67 68 base::string16 GetUndoLabel() const; 69 base::string16 GetRedoLabel() const; 70 71 void AddUndoOperation(std::unique_ptr<UndoOperation> operation); 72 73 // Group multiple operations into one undoable action. 74 void StartGroupingActions(); 75 void EndGroupingActions(); 76 77 // Suspend undo tracking while processing non-user initiated changes such as 78 // profile synchonization. 79 void SuspendUndoTracking(); 80 void ResumeUndoTracking(); 81 bool IsUndoTrakingSuspended() const; 82 83 // Remove all undo and redo operations. Note that grouping of actions and 84 // suspension of undo tracking states are left unchanged. 85 void RemoveAllOperations(); 86 87 // Observers are notified when the internal state of this class changes. 88 void AddObserver(UndoManagerObserver* observer); 89 void RemoveObserver(UndoManagerObserver* observer); 90 91 private: 92 friend class UndoManagerTestApi; 93 94 void Undo(bool* performing_indicator, 95 std::vector<std::unique_ptr<UndoGroup>>* active_undo_group); is_user_action()96 bool is_user_action() const { return !performing_undo_ && !performing_redo_; } 97 98 // Notifies the observers that the undo manager's state has changed. 99 void NotifyOnUndoManagerStateChange(); 100 101 // Handle the addition of |new_undo_group| to the active undo group container. 102 void AddUndoGroup(UndoGroup* new_undo_group); 103 104 // Returns the undo or redo UndoGroup container that should store the next 105 // change taking into account if an undo or redo is being executed. 106 std::vector<std::unique_ptr<UndoGroup>>* GetActiveUndoGroup(); 107 108 // Containers of user actions ready for an undo or redo treated as a stack. 109 std::vector<std::unique_ptr<UndoGroup>> undo_actions_; 110 std::vector<std::unique_ptr<UndoGroup>> redo_actions_; 111 112 // The observers to notify when internal state changes. 113 base::ObserverList<UndoManagerObserver>::Unchecked observers_; 114 115 // Supports grouping operations into a single undo action. 116 int group_actions_count_; 117 118 // The container that is used when actions are grouped. 119 std::unique_ptr<UndoGroup> pending_grouped_action_; 120 121 // The action that is in the process of being undone. 122 UndoGroup* undo_in_progress_action_; 123 124 // Supports the suspension of undo tracking. 125 int undo_suspended_count_; 126 127 // Set when executing Undo or Redo so that incoming changes are correctly 128 // processed. 129 bool performing_undo_; 130 bool performing_redo_; 131 132 DISALLOW_COPY_AND_ASSIGN(UndoManager); 133 }; 134 135 #endif // COMPONENTS_UNDO_UNDO_MANAGER_H_ 136