Loading...
Searching...
No Matches
CommandStack.hpp
1#pragma once
2#include <score/tools/Debug.hpp>
3#include <score/command/Command.hpp>
4#include <score/command/Validity/ValidityChecker.hpp>
5
6#include <QObject>
7#include <QStack>
8#include <QString>
9
10#include <verdigris>
11
12namespace score
13{
14class Document;
15
26class SCORE_LIB_BASE_EXPORT CommandStack final : public QObject
27{
28 W_OBJECT(CommandStack)
29
30 friend class CommandBackupFile;
31 friend struct CommandStackBackup;
32
33public:
34 explicit CommandStack(const score::Document& ctx, QObject* parent = nullptr);
36
44 void enableActions();
45
50 void disableActions();
51
52 bool canUndo() const;
53
54 bool canRedo() const;
55
57 QString undoText() const;
58
60 QString redoText() const;
61
62 int size() const;
63
64 const score::Command* command(int index) const;
65 int currentIndex() const;
66
67 void markCurrentIndexAsSaved();
68
69 bool isAtSavedIndex() const;
70
71 QStack<score::Command*>& undoable() { return m_undoable; }
72 QStack<score::Command*>& redoable() { return m_redoable; }
73 const QStack<score::Command*>& undoable() const { return m_undoable; }
74 const QStack<score::Command*>& redoable() const { return m_redoable; }
75
76 const score::DocumentContext& context() const { return m_ctx; }
77
83 E_SIGNAL(SCORE_LIB_BASE_EXPORT, localCommand, cmd)
84
85
88 void localUndo() E_SIGNAL(SCORE_LIB_BASE_EXPORT, localUndo)
89
93 void localRedo() E_SIGNAL(SCORE_LIB_BASE_EXPORT, localRedo)
94
95 void localIndexChanged(int v) E_SIGNAL(SCORE_LIB_BASE_EXPORT, localIndexChanged, v)
96
97 void canUndoChanged(bool b) E_SIGNAL(SCORE_LIB_BASE_EXPORT, canUndoChanged, b)
98 void canRedoChanged(bool b) E_SIGNAL(SCORE_LIB_BASE_EXPORT, canRedoChanged, b)
99
100 void undoTextChanged(QString b) E_SIGNAL(SCORE_LIB_BASE_EXPORT, undoTextChanged, b)
101 void redoTextChanged(QString b) E_SIGNAL(SCORE_LIB_BASE_EXPORT, redoTextChanged, b)
102
103 void indexChanged(int b) E_SIGNAL(SCORE_LIB_BASE_EXPORT, indexChanged, b)
104
105 void stackChanged() E_SIGNAL(SCORE_LIB_BASE_EXPORT, stackChanged)
106
107 void saveIndexChanged(bool b) E_SIGNAL(SCORE_LIB_BASE_EXPORT, saveIndexChanged, b)
108
109 // These signals are low-level and are sent on each operation that
110 // affects the stacks
111 void sig_undo() E_SIGNAL(SCORE_LIB_BASE_EXPORT, sig_undo)
112 void sig_redo() E_SIGNAL(SCORE_LIB_BASE_EXPORT, sig_redo)
113 void sig_push() E_SIGNAL(SCORE_LIB_BASE_EXPORT, sig_push)
114 void sig_indexChanged() E_SIGNAL(SCORE_LIB_BASE_EXPORT, sig_indexChanged)
115
116 void setIndex(int index);
117 W_INVOKABLE(setIndex)
118 void setIndexQuiet(int index);
119 W_INVOKABLE(setIndexQuiet)
120
121 // These ones do not send signals
122 void undoQuiet();
123 W_INVOKABLE(undoQuiet)
124 void redoQuiet();
125 W_INVOKABLE(redoQuiet)
126
133 void redoAndPush(score::Command* cmd);
134 W_INVOKABLE(redoAndPush)
135
142 void push(score::Command* cmd);
143 W_INVOKABLE(push)
144
149 void redoAndPushQuiet(score::Command* cmd);
150 W_INVOKABLE(redoAndPushQuiet)
151 void pushQuiet(score::Command* cmd);
152 W_INVOKABLE(pushQuiet)
153
154 void undo()
155 {
156 SCORE_ASSERT(canUndo());
157 undoQuiet();
158 localUndo();
159 }
160 W_INVOKABLE(undo)
161
162 void redo()
163 {
164 SCORE_ASSERT(canRedo());
165 redoQuiet();
166 localRedo();
167 }
168 W_INVOKABLE(redo)
169
170public:
171 template <typename Callable>
179 void updateStack(Callable&& c)
180 {
181 bool pre_canUndo{canUndo()}, pre_canRedo{canRedo()};
182
183 m_checker();
184 c();
185 m_checker();
186
187 if(pre_canUndo != canUndo())
188 canUndoChanged(canUndo());
189
190 if(pre_canRedo != canRedo())
191 canRedoChanged(canRedo());
192
193 if(canUndo())
194 undoTextChanged(m_undoable.top()->description());
195 else
196 undoTextChanged("");
197
198 if(canRedo())
199 redoTextChanged(m_redoable.top()->description());
200 else
201 redoTextChanged("");
202
203 indexChanged(m_undoable.size() - 1);
204 stackChanged();
205 }
206
207 void setSavedIndex(int index);
208
209 void validateDocument() const;
210
211private:
212 QStack<score::Command*> m_undoable;
213 QStack<score::Command*> m_redoable;
214
215 int m_savedIndex{};
216
217 DocumentValidator m_checker;
218 const score::DocumentContext& m_ctx;
219};
220}
221W_REGISTER_ARGTYPE(score::Command*)
Abstraction over the backup of commands.
Definition CommandBackupFile.hpp:34
The Command class.
Definition Command.hpp:34
Definition CommandStack.hpp:27
void updateStack(Callable &&c)
updateStack Updates the undo / redo stack
Definition CommandStack.hpp:179
void localCommand(score::Command *cmd)
Emitted when a command was pushed on the stack.
The Document class is the central part of the software.
Definition Document.hpp:51
Base toolkit upon which the software is built.
Definition Application.cpp:97
Serialized command stack data for backup / restore.
Definition CommandBackupFile.hpp:17
Definition DocumentContext.hpp:18