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