annotate base/CommandHistory.h @ 299:576be0d0d218

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