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