Chris@49: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@16: Chris@16: /* Chris@52: Sonic Visualiser Chris@52: An audio file viewer and annotation editor. Chris@52: Centre for Digital Music, Queen Mary, University of London. Chris@16: Chris@52: This program is free software; you can redistribute it and/or Chris@52: modify it under the terms of the GNU General Public License as Chris@52: published by the Free Software Foundation; either version 2 of the Chris@52: License, or (at your option) any later version. See the file Chris@52: COPYING included with this distribution for more information. Chris@16: */ Chris@16: Chris@16: /* Chris@16: This is a modified version of a source file from the Rosegarden Chris@16: MIDI and audio sequencer and notation editor, copyright 2000-2006 Chris@16: Chris Cannam, distributed under the GNU General Public License. Chris@16: Chris@16: This file contains traces of the KCommandHistory class from the KDE Chris@16: project, copyright 2000 Werner Trobin and David Faure and Chris@16: distributed under the GNU Lesser General Public License. Chris@16: */ Chris@16: Chris@16: #ifndef _MULTI_VIEW_COMMAND_HISTORY_H_ Chris@16: #define _MULTI_VIEW_COMMAND_HISTORY_H_ Chris@16: Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: class Command; Chris@44: class MacroCommand; Chris@16: class QAction; Chris@16: class QMenu; Chris@16: class QToolBar; Chris@47: class QTimer; Chris@16: Chris@16: /** Chris@17: * The CommandHistory class stores a list of executed commands and Chris@17: * maintains Undo and Redo actions synchronised with those commands. Chris@16: * Chris@17: * CommandHistory allows you to associate more than one Undo and Redo Chris@17: * menu or toolbar with the same command history, and it keeps them Chris@17: * all up-to-date at once. This makes it effective in systems where Chris@17: * multiple views may be editing the same data. Chris@16: */ Chris@16: Chris@17: class CommandHistory : public QObject Chris@16: { Chris@16: Q_OBJECT Chris@16: Chris@16: public: Chris@17: virtual ~CommandHistory(); Chris@17: Chris@17: static CommandHistory *getInstance(); Chris@16: Chris@16: void clear(); Chris@16: Chris@16: void registerMenu(QMenu *menu); Chris@16: void registerToolbar(QToolBar *toolbar); Chris@16: Chris@47: /** Chris@47: * Add a command to the command history. Chris@47: * Chris@47: * If execute is true, the command will be executed before being Chris@47: * added. Otherwise it will be assumed to have been already Chris@47: * executed -- a command should not be added to the history unless Chris@47: * its work has actually been done somehow! Chris@47: * Chris@47: * If a compound operation is in use (see startCompoundOperation Chris@47: * below), the execute status of the compound operation will Chris@47: * override any value of execute passed to this method. Chris@47: * Chris@47: * If bundle is true, the command will be a candidate for bundling Chris@47: * with any adjacent bundeable commands that have the same name, Chris@47: * into a single compound command. This is useful for small Chris@47: * commands that may be executed repeatedly altering the same data Chris@47: * (e.g. type text, set a parameter) whose number and extent is Chris@47: * not known in advance. The bundle parameter will be ignored if Chris@47: * a compound operation is already in use. Chris@47: */ Chris@47: void addCommand(Command *command, bool execute = true, bool bundle = false); Chris@16: Chris@16: /// Return the maximum number of items in the undo history. Chris@46: int getUndoLimit() const { return m_undoLimit; } Chris@16: Chris@16: /// Set the maximum number of items in the undo history. Chris@16: void setUndoLimit(int limit); Chris@16: Chris@16: /// Return the maximum number of items in the redo history. Chris@46: int getRedoLimit() const { return m_redoLimit; } Chris@16: Chris@16: /// Set the maximum number of items in the redo history. Chris@16: void setRedoLimit(int limit); Chris@16: Chris@46: /// Return the maximum number of items visible in undo and redo menus. Chris@46: int getMenuLimit() const { return m_menuLimit; } Chris@46: Chris@46: /// Set the maximum number of items in the menus. Chris@46: void setMenuLimit(int limit); Chris@46: Chris@47: /// Return the time after which a bundle will be closed if nothing is added. Chris@47: int getBundleTimeout() const { return m_bundleTimeout; } Chris@47: Chris@47: /// Set the time after which a bundle will be closed if nothing is added. Chris@47: void setBundleTimeout(int msec); Chris@47: Chris@44: /// Start recording commands to batch up into a single compound command. Chris@44: void startCompoundOperation(QString name, bool execute); Chris@44: Chris@44: /// Finish recording commands and store the compound command. Chris@44: void endCompoundOperation(); Chris@44: Chris@16: public slots: Chris@16: /** Chris@16: * Checkpoint function that should be called when the document is Chris@16: * saved. If the undo/redo stack later returns to the point at Chris@16: * which the document was saved, the documentRestored signal will Chris@16: * be emitted. Chris@16: */ Chris@16: virtual void documentSaved(); Chris@16: Chris@17: /** Chris@17: * Add a command to the history that has already been executed, Chris@17: * without executing it again. Equivalent to addCommand(command, false). Chris@17: */ Chris@17: void addExecutedCommand(Command *); Chris@17: Chris@17: /** Chris@17: * Add a command to the history and also execute it. Equivalent Chris@17: * to addCommand(command, true). Chris@17: */ Chris@17: void addCommandAndExecute(Command *); Chris@17: Chris@16: protected slots: Chris@16: void undo(); Chris@16: void redo(); Chris@16: void undoActivated(QAction *); Chris@16: void redoActivated(QAction *); Chris@47: void bundleTimerTimeout(); Chris@47: Chris@16: signals: Chris@16: /** Chris@17: * Emitted whenever a command has just been executed or Chris@17: * unexecuted, whether by addCommand, undo, or redo. Chris@17: */ Chris@17: void commandExecuted(); Chris@17: Chris@17: /** Chris@16: * Emitted whenever a command has just been executed, whether by Chris@17: * addCommand or redo. Chris@16: */ Chris@16: void commandExecuted(Command *); Chris@16: Chris@16: /** Chris@17: * Emitted whenever a command has just been unexecuted, whether by Chris@17: * addCommand or undo. Chris@16: */ Chris@17: void commandUnexecuted(Command *); Chris@16: Chris@16: /** Chris@16: * Emitted when the undo/redo stack has reached the same state at Chris@16: * which the documentSaved slot was last called. Chris@16: */ Chris@16: void documentRestored(); Chris@16: Chris@17: protected: Chris@17: CommandHistory(); Chris@17: static CommandHistory *m_instance; Chris@17: Chris@16: QAction *m_undoAction; Chris@16: QAction *m_redoAction; Chris@17: QAction *m_undoMenuAction; Chris@17: QAction *m_redoMenuAction; Chris@16: QMenu *m_undoMenu; Chris@16: QMenu *m_redoMenu; Chris@16: Chris@16: std::map m_actionCounts; Chris@16: Chris@16: typedef std::stack CommandStack; Chris@16: CommandStack m_undoStack; Chris@16: CommandStack m_redoStack; Chris@16: Chris@16: int m_undoLimit; Chris@16: int m_redoLimit; Chris@46: int m_menuLimit; Chris@16: int m_savedAt; Chris@16: Chris@47: MacroCommand *m_currentCompound; Chris@47: bool m_executeCompound; Chris@47: void addToCompound(Command *command); Chris@47: Chris@47: MacroCommand *m_currentBundle; Chris@47: QString m_currentBundleName; Chris@47: QTimer *m_bundleTimer; Chris@47: int m_bundleTimeout; Chris@47: void addToBundle(Command *command, bool execute); Chris@47: void closeBundle(); Chris@44: Chris@16: void updateActions(); Chris@16: Chris@16: void clipCommands(); Chris@16: Chris@16: void clipStack(CommandStack &stack, int limit); Chris@16: void clearStack(CommandStack &stack); Chris@16: }; Chris@16: Chris@16: Chris@16: #endif