Chris@16
|
1 /* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@16
|
2
|
Chris@16
|
3 /*
|
Chris@16
|
4 A waveform viewer and audio annotation editor.
|
Chris@16
|
5 Chris Cannam, Queen Mary University of London, 2005-2006
|
Chris@16
|
6
|
Chris@16
|
7 This is experimental software. Not for distribution.
|
Chris@16
|
8 */
|
Chris@16
|
9
|
Chris@16
|
10 /*
|
Chris@16
|
11 This is a modified version of a source file from the Rosegarden
|
Chris@16
|
12 MIDI and audio sequencer and notation editor, copyright 2000-2006
|
Chris@16
|
13 Chris Cannam, distributed under the GNU General Public License.
|
Chris@16
|
14
|
Chris@16
|
15 This file contains traces of the KCommandHistory class from the KDE
|
Chris@16
|
16 project, copyright 2000 Werner Trobin and David Faure and
|
Chris@16
|
17 distributed under the GNU Lesser General Public License.
|
Chris@16
|
18 */
|
Chris@16
|
19
|
Chris@16
|
20 #ifndef _MULTI_VIEW_COMMAND_HISTORY_H_
|
Chris@16
|
21 #define _MULTI_VIEW_COMMAND_HISTORY_H_
|
Chris@16
|
22
|
Chris@16
|
23 #include <QObject>
|
Chris@16
|
24 #include <QString>
|
Chris@16
|
25
|
Chris@16
|
26 #include <stack>
|
Chris@16
|
27 #include <set>
|
Chris@16
|
28 #include <map>
|
Chris@16
|
29
|
Chris@16
|
30 class Command;
|
Chris@44
|
31 class MacroCommand;
|
Chris@16
|
32 class QAction;
|
Chris@16
|
33 class QMenu;
|
Chris@16
|
34 class QToolBar;
|
Chris@47
|
35 class QTimer;
|
Chris@16
|
36
|
Chris@16
|
37 /**
|
Chris@17
|
38 * The CommandHistory class stores a list of executed commands and
|
Chris@17
|
39 * maintains Undo and Redo actions synchronised with those commands.
|
Chris@16
|
40 *
|
Chris@17
|
41 * CommandHistory allows you to associate more than one Undo and Redo
|
Chris@17
|
42 * menu or toolbar with the same command history, and it keeps them
|
Chris@17
|
43 * all up-to-date at once. This makes it effective in systems where
|
Chris@17
|
44 * multiple views may be editing the same data.
|
Chris@16
|
45 */
|
Chris@16
|
46
|
Chris@17
|
47 class CommandHistory : public QObject
|
Chris@16
|
48 {
|
Chris@16
|
49 Q_OBJECT
|
Chris@16
|
50
|
Chris@16
|
51 public:
|
Chris@17
|
52 virtual ~CommandHistory();
|
Chris@17
|
53
|
Chris@17
|
54 static CommandHistory *getInstance();
|
Chris@16
|
55
|
Chris@16
|
56 void clear();
|
Chris@16
|
57
|
Chris@16
|
58 void registerMenu(QMenu *menu);
|
Chris@16
|
59 void registerToolbar(QToolBar *toolbar);
|
Chris@16
|
60
|
Chris@47
|
61 /**
|
Chris@47
|
62 * Add a command to the command history.
|
Chris@47
|
63 *
|
Chris@47
|
64 * If execute is true, the command will be executed before being
|
Chris@47
|
65 * added. Otherwise it will be assumed to have been already
|
Chris@47
|
66 * executed -- a command should not be added to the history unless
|
Chris@47
|
67 * its work has actually been done somehow!
|
Chris@47
|
68 *
|
Chris@47
|
69 * If a compound operation is in use (see startCompoundOperation
|
Chris@47
|
70 * below), the execute status of the compound operation will
|
Chris@47
|
71 * override any value of execute passed to this method.
|
Chris@47
|
72 *
|
Chris@47
|
73 * If bundle is true, the command will be a candidate for bundling
|
Chris@47
|
74 * with any adjacent bundeable commands that have the same name,
|
Chris@47
|
75 * into a single compound command. This is useful for small
|
Chris@47
|
76 * commands that may be executed repeatedly altering the same data
|
Chris@47
|
77 * (e.g. type text, set a parameter) whose number and extent is
|
Chris@47
|
78 * not known in advance. The bundle parameter will be ignored if
|
Chris@47
|
79 * a compound operation is already in use.
|
Chris@47
|
80 */
|
Chris@47
|
81 void addCommand(Command *command, bool execute = true, bool bundle = false);
|
Chris@16
|
82
|
Chris@16
|
83 /// Return the maximum number of items in the undo history.
|
Chris@46
|
84 int getUndoLimit() const { return m_undoLimit; }
|
Chris@16
|
85
|
Chris@16
|
86 /// Set the maximum number of items in the undo history.
|
Chris@16
|
87 void setUndoLimit(int limit);
|
Chris@16
|
88
|
Chris@16
|
89 /// Return the maximum number of items in the redo history.
|
Chris@46
|
90 int getRedoLimit() const { return m_redoLimit; }
|
Chris@16
|
91
|
Chris@16
|
92 /// Set the maximum number of items in the redo history.
|
Chris@16
|
93 void setRedoLimit(int limit);
|
Chris@16
|
94
|
Chris@46
|
95 /// Return the maximum number of items visible in undo and redo menus.
|
Chris@46
|
96 int getMenuLimit() const { return m_menuLimit; }
|
Chris@46
|
97
|
Chris@46
|
98 /// Set the maximum number of items in the menus.
|
Chris@46
|
99 void setMenuLimit(int limit);
|
Chris@46
|
100
|
Chris@47
|
101 /// Return the time after which a bundle will be closed if nothing is added.
|
Chris@47
|
102 int getBundleTimeout() const { return m_bundleTimeout; }
|
Chris@47
|
103
|
Chris@47
|
104 /// Set the time after which a bundle will be closed if nothing is added.
|
Chris@47
|
105 void setBundleTimeout(int msec);
|
Chris@47
|
106
|
Chris@44
|
107 /// Start recording commands to batch up into a single compound command.
|
Chris@44
|
108 void startCompoundOperation(QString name, bool execute);
|
Chris@44
|
109
|
Chris@44
|
110 /// Finish recording commands and store the compound command.
|
Chris@44
|
111 void endCompoundOperation();
|
Chris@44
|
112
|
Chris@16
|
113 public slots:
|
Chris@16
|
114 /**
|
Chris@16
|
115 * Checkpoint function that should be called when the document is
|
Chris@16
|
116 * saved. If the undo/redo stack later returns to the point at
|
Chris@16
|
117 * which the document was saved, the documentRestored signal will
|
Chris@16
|
118 * be emitted.
|
Chris@16
|
119 */
|
Chris@16
|
120 virtual void documentSaved();
|
Chris@16
|
121
|
Chris@17
|
122 /**
|
Chris@17
|
123 * Add a command to the history that has already been executed,
|
Chris@17
|
124 * without executing it again. Equivalent to addCommand(command, false).
|
Chris@17
|
125 */
|
Chris@17
|
126 void addExecutedCommand(Command *);
|
Chris@17
|
127
|
Chris@17
|
128 /**
|
Chris@17
|
129 * Add a command to the history and also execute it. Equivalent
|
Chris@17
|
130 * to addCommand(command, true).
|
Chris@17
|
131 */
|
Chris@17
|
132 void addCommandAndExecute(Command *);
|
Chris@17
|
133
|
Chris@16
|
134 protected slots:
|
Chris@16
|
135 void undo();
|
Chris@16
|
136 void redo();
|
Chris@16
|
137 void undoActivated(QAction *);
|
Chris@16
|
138 void redoActivated(QAction *);
|
Chris@47
|
139 void bundleTimerTimeout();
|
Chris@47
|
140
|
Chris@16
|
141 signals:
|
Chris@16
|
142 /**
|
Chris@17
|
143 * Emitted whenever a command has just been executed or
|
Chris@17
|
144 * unexecuted, whether by addCommand, undo, or redo.
|
Chris@17
|
145 */
|
Chris@17
|
146 void commandExecuted();
|
Chris@17
|
147
|
Chris@17
|
148 /**
|
Chris@16
|
149 * Emitted whenever a command has just been executed, whether by
|
Chris@17
|
150 * addCommand or redo.
|
Chris@16
|
151 */
|
Chris@16
|
152 void commandExecuted(Command *);
|
Chris@16
|
153
|
Chris@16
|
154 /**
|
Chris@17
|
155 * Emitted whenever a command has just been unexecuted, whether by
|
Chris@17
|
156 * addCommand or undo.
|
Chris@16
|
157 */
|
Chris@17
|
158 void commandUnexecuted(Command *);
|
Chris@16
|
159
|
Chris@16
|
160 /**
|
Chris@16
|
161 * Emitted when the undo/redo stack has reached the same state at
|
Chris@16
|
162 * which the documentSaved slot was last called.
|
Chris@16
|
163 */
|
Chris@16
|
164 void documentRestored();
|
Chris@16
|
165
|
Chris@17
|
166 protected:
|
Chris@17
|
167 CommandHistory();
|
Chris@17
|
168 static CommandHistory *m_instance;
|
Chris@17
|
169
|
Chris@16
|
170 QAction *m_undoAction;
|
Chris@16
|
171 QAction *m_redoAction;
|
Chris@17
|
172 QAction *m_undoMenuAction;
|
Chris@17
|
173 QAction *m_redoMenuAction;
|
Chris@16
|
174 QMenu *m_undoMenu;
|
Chris@16
|
175 QMenu *m_redoMenu;
|
Chris@16
|
176
|
Chris@16
|
177 std::map<QAction *, int> m_actionCounts;
|
Chris@16
|
178
|
Chris@16
|
179 typedef std::stack<Command *> CommandStack;
|
Chris@16
|
180 CommandStack m_undoStack;
|
Chris@16
|
181 CommandStack m_redoStack;
|
Chris@16
|
182
|
Chris@16
|
183 int m_undoLimit;
|
Chris@16
|
184 int m_redoLimit;
|
Chris@46
|
185 int m_menuLimit;
|
Chris@16
|
186 int m_savedAt;
|
Chris@16
|
187
|
Chris@47
|
188 MacroCommand *m_currentCompound;
|
Chris@47
|
189 bool m_executeCompound;
|
Chris@47
|
190 void addToCompound(Command *command);
|
Chris@47
|
191
|
Chris@47
|
192 MacroCommand *m_currentBundle;
|
Chris@47
|
193 QString m_currentBundleName;
|
Chris@47
|
194 QTimer *m_bundleTimer;
|
Chris@47
|
195 int m_bundleTimeout;
|
Chris@47
|
196 void addToBundle(Command *command, bool execute);
|
Chris@47
|
197 void closeBundle();
|
Chris@44
|
198
|
Chris@16
|
199 void updateActions();
|
Chris@16
|
200
|
Chris@16
|
201 void clipCommands();
|
Chris@16
|
202
|
Chris@16
|
203 void clipStack(CommandStack &stack, int limit);
|
Chris@16
|
204 void clearStack(CommandStack &stack);
|
Chris@16
|
205 };
|
Chris@16
|
206
|
Chris@16
|
207
|
Chris@16
|
208 #endif
|