/
UndoSystem.h
130 lines (93 loc) · 3.3 KB
/
UndoSystem.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#pragma once
#include <map>
#include <set>
#include <functional>
#include "iundo.h"
#include "icommandsystem.h"
#include "imap.h"
#include "Stack.h"
#include "StackFiller.h"
namespace undo
{
/**
* greebo: The UndoSystem (interface: iundo.h) is maintaining two internal
* stacks of Operations (one for Undo, one for Redo), each containing a list
* of Undoables plus their snapshot data.
*
* The Undoables are responsible of submitting their data to the UndoSystem
* before their data is changed, not knowing which or whether an operation is
* currently active. If there actually is an Undo Operation in the works,
* this system is handling all of the paperwork.
*
* On undo or redo, the Undoables are called to re-import the states
* as stored in their UndoMementos. When undoing operations, the Undoables
* themselves are again responsible for submitting their data to the UndoSystem
* such that it can record the changes and store them in the RedoStack.
*
* The RedoStack is discarded as soon as a new Undoable Operation is recorded
* and pushed to the UndoStack.
*/
class UndoSystem :
public IUndoSystem
{
private:
// The undo and redo stacks
UndoStack _undoStack;
UndoStack _redoStack;
UndoStack* _activeUndoStack;
typedef std::map<IUndoable*, UndoStackFiller> UndoablesMap;
UndoablesMap _undoables;
std::size_t _undoLevels;
typedef std::set<Tracker*> Trackers;
Trackers _trackers;
sigc::signal<void> _signalPostUndo;
sigc::signal<void> _signalPostRedo;
public:
// Constructor
UndoSystem();
virtual ~UndoSystem();
IUndoStateSaver* getStateSaver(IUndoable& undoable, IMapFileChangeTracker& tracker) override;
void releaseStateSaver(IUndoable& undoable) override;
std::size_t size() const override;
void start() override;
// greebo: This finishes the current operation and
// removes it instantly from the stack
void cancel() override;
void finish(const std::string& command) override;
void undo() override;
void redo() override;
void clear() override;
sigc::signal<void>& signal_postUndo() override;
// Emitted after a redo operation is fully completed, allows objects to refresh their state
sigc::signal<void>& signal_postRedo() override;
void attachTracker(Tracker& tracker) override;
void detachTracker(Tracker& tracker) override;
// RegisterableModule implementation
const std::string& getName() const override;
const StringSet& getDependencies() const override;
void initialiseModule(const ApplicationContext& ctx) override;
private:
// This is connected to the CommandSystem
void undoCmd(const cmd::ArgumentList& args);
// This is connected to the CommandSystem
void redoCmd(const cmd::ArgumentList& args);
// Gets called as soon as the observed registry key is changed
void keyChanged();
void onMapEvent(IMap::MapEvent ev);
// Sets the size of the undoStack
void setLevels(std::size_t levels);
std::size_t getLevels() const;
void startUndo();
bool finishUndo(const std::string& command);
void startRedo();
bool finishRedo(const std::string& command);
// Assigns the given stack to all of the Undoables listed in the map
void setActiveUndoStack(UndoStack* stack);
void foreachTracker(const std::function<void(Tracker&)>& functor) const;
void trackersClear() const;
void trackersBegin() const;
void trackersUndo() const;
void trackersRedo() const;
void constructPreferences();
};
}