Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

231 lines
10KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2013 - Raw Material Software Ltd.
  5. Permission is granted to use this software under the terms of either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. #ifndef JUCE_UNDOMANAGER_H_INCLUDED
  18. #define JUCE_UNDOMANAGER_H_INCLUDED
  19. //==============================================================================
  20. /**
  21. Manages a list of undo/redo commands.
  22. An UndoManager object keeps a list of past actions and can use these actions
  23. to move backwards and forwards through an undo history.
  24. To use it, create subclasses of UndoableAction which perform all the
  25. actions you need, then when you need to actually perform an action, create one
  26. and pass it to the UndoManager's perform() method.
  27. The manager also uses the concept of 'transactions' to group the actions
  28. together - all actions performed between calls to beginNewTransaction() are
  29. grouped together and are all undone/redone as a group.
  30. The UndoManager is a ChangeBroadcaster, so listeners can register to be told
  31. when actions are performed or undone.
  32. @see UndoableAction
  33. */
  34. class JUCE_API UndoManager : public ChangeBroadcaster
  35. {
  36. public:
  37. //==============================================================================
  38. /** Creates an UndoManager.
  39. @param maxNumberOfUnitsToKeep each UndoableAction object returns a value
  40. to indicate how much storage it takes up
  41. (UndoableAction::getSizeInUnits()), so this
  42. lets you specify the maximum total number of
  43. units that the undomanager is allowed to
  44. keep in memory before letting the older actions
  45. drop off the end of the list.
  46. @param minimumTransactionsToKeep this specifies the minimum number of transactions
  47. that will be kept, even if this involves exceeding
  48. the amount of space specified in maxNumberOfUnitsToKeep
  49. */
  50. UndoManager (int maxNumberOfUnitsToKeep = 30000,
  51. int minimumTransactionsToKeep = 30);
  52. /** Destructor. */
  53. ~UndoManager();
  54. //==============================================================================
  55. /** Deletes all stored actions in the list. */
  56. void clearUndoHistory();
  57. /** Returns the current amount of space to use for storing UndoableAction objects.
  58. @see setMaxNumberOfStoredUnits
  59. */
  60. int getNumberOfUnitsTakenUpByStoredCommands() const;
  61. /** Sets the amount of space that can be used for storing UndoableAction objects.
  62. @param maxNumberOfUnitsToKeep each UndoableAction object returns a value
  63. to indicate how much storage it takes up
  64. (UndoableAction::getSizeInUnits()), so this
  65. lets you specify the maximum total number of
  66. units that the undomanager is allowed to
  67. keep in memory before letting the older actions
  68. drop off the end of the list.
  69. @param minimumTransactionsToKeep this specifies the minimum number of transactions
  70. that will be kept, even if this involves exceeding
  71. the amount of space specified in maxNumberOfUnitsToKeep
  72. @see getNumberOfUnitsTakenUpByStoredCommands
  73. */
  74. void setMaxNumberOfStoredUnits (int maxNumberOfUnitsToKeep,
  75. int minimumTransactionsToKeep);
  76. //==============================================================================
  77. /** Performs an action and adds it to the undo history list.
  78. @param action the action to perform - this will be deleted by the UndoManager
  79. when no longer needed
  80. @param actionName if this string is non-empty, the current transaction will be
  81. given this name; if it's empty, the current transaction name will
  82. be left unchanged. See setCurrentTransactionName()
  83. @returns true if the command succeeds - see UndoableAction::perform
  84. @see beginNewTransaction
  85. */
  86. bool perform (UndoableAction* action,
  87. const String& actionName = String::empty);
  88. /** Starts a new group of actions that together will be treated as a single transaction.
  89. All actions that are passed to the perform() method between calls to this
  90. method are grouped together and undone/redone together by a single call to
  91. undo() or redo().
  92. @param actionName a description of the transaction that is about to be
  93. performed
  94. */
  95. void beginNewTransaction (const String& actionName = String::empty);
  96. /** Changes the name stored for the current transaction.
  97. Each transaction is given a name when the beginNewTransaction() method is
  98. called, but this can be used to change that name without starting a new
  99. transaction.
  100. */
  101. void setCurrentTransactionName (const String& newName);
  102. //==============================================================================
  103. /** Returns true if there's at least one action in the list to undo.
  104. @see getUndoDescription, undo, canRedo
  105. */
  106. bool canUndo() const;
  107. /** Returns the description of the transaction that would be next to get undone.
  108. The description returned is the one that was passed into beginNewTransaction
  109. before the set of actions was performed.
  110. @see undo
  111. */
  112. String getUndoDescription() const;
  113. /** Tries to roll-back the last transaction.
  114. @returns true if the transaction can be undone, and false if it fails, or
  115. if there aren't any transactions to undo
  116. */
  117. bool undo();
  118. /** Tries to roll-back any actions that were added to the current transaction.
  119. This will perform an undo() only if there are some actions in the undo list
  120. that were added after the last call to beginNewTransaction().
  121. This is useful because it lets you call beginNewTransaction(), then
  122. perform an operation which may or may not actually perform some actions, and
  123. then call this method to get rid of any actions that might have been done
  124. without it rolling back the previous transaction if nothing was actually
  125. done.
  126. @returns true if any actions were undone.
  127. */
  128. bool undoCurrentTransactionOnly();
  129. /** Returns a list of the UndoableAction objects that have been performed during the
  130. transaction that is currently open.
  131. Effectively, this is the list of actions that would be undone if undoCurrentTransactionOnly()
  132. were to be called now.
  133. The first item in the list is the earliest action performed.
  134. */
  135. void getActionsInCurrentTransaction (Array <const UndoableAction*>& actionsFound) const;
  136. /** Returns the number of UndoableAction objects that have been performed during the
  137. transaction that is currently open.
  138. @see getActionsInCurrentTransaction
  139. */
  140. int getNumActionsInCurrentTransaction() const;
  141. /** Returns the time to which the state would be restored if undo() was to be called.
  142. If an undo isn't currently possible, it'll return Time().
  143. */
  144. Time getTimeOfUndoTransaction() const;
  145. /** Returns the time to which the state would be restored if redo() was to be called.
  146. If a redo isn't currently possible, it'll return Time::getCurrentTime().
  147. */
  148. Time getTimeOfRedoTransaction() const;
  149. //==============================================================================
  150. /** Returns true if there's at least one action in the list to redo.
  151. @see getRedoDescription, redo, canUndo
  152. */
  153. bool canRedo() const;
  154. /** Returns the description of the transaction that would be next to get redone.
  155. The description returned is the one that was passed into beginNewTransaction
  156. before the set of actions was performed.
  157. @see redo
  158. */
  159. String getRedoDescription() const;
  160. /** Tries to redo the last transaction that was undone.
  161. @returns true if the transaction can be redone, and false if it fails, or
  162. if there aren't any transactions to redo
  163. */
  164. bool redo();
  165. private:
  166. //==============================================================================
  167. struct ActionSet;
  168. friend struct ContainerDeletePolicy<ActionSet>;
  169. OwnedArray<ActionSet> transactions;
  170. String currentTransactionName;
  171. int totalUnitsStored, maxNumUnitsToKeep, minimumTransactionsToKeep, nextIndex;
  172. bool newTransaction, reentrancyCheck;
  173. ActionSet* getCurrentSet() const noexcept;
  174. ActionSet* getNextSet() const noexcept;
  175. void clearFutureTransactions();
  176. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (UndoManager)
  177. };
  178. #endif // JUCE_UNDOMANAGER_H_INCLUDED