Audacity 3.2.0
UndoManager.h
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 UndoManager.h
6
7 Dominic Mazzoni
8
9 After each operation, call UndoManager's PushState, pass it
10 the entire track hierarchy. The UndoManager makes a duplicate
11 of every single track using its Duplicate method, which should
12 increment reference counts. If we were not at the top of
13 the stack when this is called, DELETE above first.
14
15 If a minor change is made, for example changing the visual
16 display of a track or changing the selection, you can call
17 ModifyState, which replaces the current state with the
18 one you give it, without deleting everything above it.
19
20 Each action has a long description and a short description
21 associated with it. The long description appears in the
22 History window and should be a complete sentence in the
23 past tense, for example, "Deleted 2 seconds.". The short
24 description should be one or two words at most, all
25 capitalized, and should represent the name of the command.
26 It will be appended on the end of the word "Undo" or "Redo",
27 for example the short description of "Deleted 2 seconds."
28 would just be "Delete", resulting in menu titles
29 "Undo Delete" and "Redo Delete".
30
31 UndoManager can also automatically consolidate actions into
32 a single state change. If the "consolidate" argument to
33 PushState is true, then NEW changes may accumulate into the most
34 recent Undo state, if descriptions match and if no Undo or Redo or rollback
35 operation intervened since that state was pushed.
36
37 Undo() temporarily moves down one state and returns the track
38 hierarchy. If another PushState is called, the redo information
39 is lost.
40
41 Redo()
42
43 UndoAvailable()
44
45 RedoAvailable()
46
47**********************************************************************/
48
49#ifndef __AUDACITY_UNDOMANAGER__
50#define __AUDACITY_UNDOMANAGER__
51
52#include <functional>
53#include <memory>
54#include <vector>
55#include "ClientData.h"
56#include "Observer.h"
57#include "SelectedRegion.h"
58
60
62 const enum Type {
63 Pushed,
65 Modified,
67 Renamed,
72 Reset,
76
77 // Eagerly sent messages (not waiting for idle time)
81
83 const size_t begin = 0, end = 0;
84};
85
86class AudacityProject;
87class Track;
88class TrackList;
89
91class PROJECT_HISTORY_API UndoStateExtension {
92public:
94
97};
98
99class PROJECT_HISTORY_API UndoRedoExtensionRegistry {
100public:
102
103 using Saver =
104 std::function<std::shared_ptr<UndoStateExtension>(AudacityProject&)>;
105
107 struct PROJECT_HISTORY_API Entry {
108 Entry(const Saver &saver);
109 };
110};
111
112struct UndoState {
113 using Extensions = std::vector<std::shared_ptr<UndoStateExtension>>;
114
116 std::shared_ptr<TrackList> &&tracks_,
117 const SelectedRegion &selectedRegion_)
118 : extensions(std::move(extensions))
119 , tracks(std::move(tracks_)), selectedRegion(selectedRegion_)
120 {}
121
123 std::shared_ptr<TrackList> tracks;
125};
126
128
130 std::shared_ptr<TrackList> &&tracks_,
131 const TranslatableString &description_,
132 const TranslatableString &shortDescription_,
133 const SelectedRegion &selectedRegion_)
134 : state(std::move(extensions), std::move(tracks_), selectedRegion_)
135 , description(description_)
136 , shortDescription(shortDescription_)
137 {
138 }
139
143};
144
145using UndoStack = std::vector <std::unique_ptr<UndoStackElem>>;
146
147// These flags control what extra to do on a PushState
148// Default is AUTOSAVE
149// Frequent/faster actions use CONSOLIDATE
150enum class UndoPush : unsigned char {
151 NONE = 0,
152 CONSOLIDATE = 1 << 0,
153 NOAUTOSAVE = 1 << 1
154};
155
157{ return static_cast<UndoPush>(static_cast<int>(a) | static_cast<int>(b)); }
159{ return static_cast<UndoPush>(static_cast<int>(a) & static_cast<int>(b)); }
160
162
163class PROJECT_HISTORY_API UndoManager final
164 : public ClientData::Base
165 , public Observer::Publisher<UndoRedoMessage>
166 , public std::enable_shared_from_this<UndoManager>
167{
168 public:
169 static UndoManager &Get( AudacityProject &project );
170 static const UndoManager &Get( const AudacityProject &project );
171
172 explicit
173 UndoManager( AudacityProject &project );
174 ~UndoManager();
175
176 UndoManager( const UndoManager& ) = delete;
177 UndoManager& operator = ( const UndoManager& ) = delete;
178
179 void PushState(const TrackList &l,
180 const SelectedRegion &selectedRegion,
181 const TranslatableString &longDescription,
182 const TranslatableString &shortDescription,
183 UndoPush flags = UndoPush::NONE);
184 void ModifyState(const TrackList &l,
185 const SelectedRegion &selectedRegion);
186 void RenameState( int state,
187 const TranslatableString &longDescription,
188 const TranslatableString &shortDescription);
189 void AbandonRedo();
190 void ClearStates();
191 void RemoveStates(
192 size_t begin,
193 size_t end
194 );
195 unsigned int GetNumStates();
196 unsigned int GetCurrentState();
197
198 void StopConsolidating() { mayConsolidate = false; }
199
200 void GetShortDescription(unsigned int n, TranslatableString *desc);
201 void SetLongDescription(unsigned int n, const TranslatableString &desc);
202
203 // These functions accept a callback that uses the state,
204 // and then they send to the project Reset or UndoOrRedo when
205 // that has finished.
206 using Consumer = std::function< void( const UndoStackElem & ) >;
207 void SetStateTo(unsigned int n, const Consumer &consumer);
208 void Undo(const Consumer &consumer);
209 void Redo(const Consumer &consumer);
210
212 void VisitStates( const Consumer &consumer, bool newestFirst );
214
215 void VisitStates(
216 const Consumer &consumer, size_t begin, size_t end );
217
218 bool UndoAvailable();
219 bool RedoAvailable();
220
221 bool UnsavedChanges() const;
222 int GetSavedState() const;
223 void StateSaved();
224
225 // void Debug(); // currently unused
226
227 private:
228 void EnqueueMessage(UndoRedoMessage message);
229 void RemoveStateAt(int n);
230
232
234 int saved;
235
238
240 bool mayConsolidate { false };
241};
242
243#endif
Utility ClientData::Site to register hooks into a host class that attach client data.
const TranslatableString desc
Definition: ExportPCM.cpp:58
UndoPush operator&(UndoPush a, UndoPush b)
Definition: UndoManager.h:158
UndoPush
Definition: UndoManager.h:150
UndoPush operator|(UndoPush a, UndoPush b)
Definition: UndoManager.h:156
std::vector< std::unique_ptr< UndoStackElem > > UndoStack
Definition: UndoManager.h:145
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:89
An object that sends messages to an open-ended list of subscribed callbacks.
Definition: Observer.h:108
Defines a selected portion of a project.
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:225
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
Definition: Track.h:1338
Holds a msgid for the translation catalog; may also bind format arguments.
Maintain a non-persistent list of states of the project, to support undo and redo commands.
Definition: UndoManager.h:167
AudacityProject & mProject
Definition: UndoManager.h:231
UndoManager(const UndoManager &)=delete
void StopConsolidating()
Definition: UndoManager.h:198
TranslatableString lastAction
Definition: UndoManager.h:239
UndoStack stack
Definition: UndoManager.h:237
std::function< void(const UndoStackElem &) > Consumer
Definition: UndoManager.h:206
std::function< std::shared_ptr< UndoStateExtension >(AudacityProject &)> Saver
Type of function that produces an UndoStateExtension object when saving state of a project.
Definition: UndoManager.h:104
Base class for extra information attached to undo/redo states.
Definition: UndoManager.h:91
virtual void RestoreUndoRedoState(AudacityProject &)=0
Modify the project when undoing or redoing to some state in history.
virtual ~UndoStateExtension()
Services * Get()
Fetch the global instance, or nullptr if none is yet installed.
Definition: BasicUI.cpp:194
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:150
STL namespace.
A convenient default parameter for class template Site.
Definition: ClientData.h:28
Typically statically constructed.
Definition: UndoManager.h:107
Type of message published by UndoManager.
Definition: UndoManager.h:61
const size_t end
Definition: UndoManager.h:83
const size_t begin
Only significant for BeginPurge messages.
Definition: UndoManager.h:83
@ EndPurge
End elimination of old undo states.
Definition: UndoManager.h:79
@ Purge
Undo or redo states eliminated.
Definition: UndoManager.h:75
@ BeginPurge
Begin elimination of old undo states.
Definition: UndoManager.h:78
enum UndoRedoMessage::Type type
Holds one item with description and time range for the UndoManager.
Definition: UndoManager.h:127
TranslatableString description
Definition: UndoManager.h:141
TranslatableString shortDescription
Definition: UndoManager.h:142
UndoState state
Definition: UndoManager.h:140
UndoStackElem(UndoState::Extensions extensions, std::shared_ptr< TrackList > &&tracks_, const TranslatableString &description_, const TranslatableString &shortDescription_, const SelectedRegion &selectedRegion_)
Definition: UndoManager.h:129
std::vector< std::shared_ptr< UndoStateExtension > > Extensions
Definition: UndoManager.h:113
std::shared_ptr< TrackList > tracks
Definition: UndoManager.h:123
UndoState(Extensions extensions, std::shared_ptr< TrackList > &&tracks_, const SelectedRegion &selectedRegion_)
Definition: UndoManager.h:115
Extensions extensions
Definition: UndoManager.h:122
SelectedRegion selectedRegion
Definition: UndoManager.h:124