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