annotate widgets/CommandHistory.h @ 1420:2e0d9e68343d

Merge
author Chris Cannam
date Thu, 14 Feb 2019 13:12:44 +0000
parents 05d614f6e46d
children
rev   line source
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@1407 25 #ifndef SV_MULTI_VIEW_COMMAND_HISTORY_H
Chris@1407 26 #define SV_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