LibrePCB Developers Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
UndoStack Class Referencefinal

The UndoStack class holds UndoCommand objects and provides undo/redo commands. More...

#include <undostack.h>

Inherits QObject.

+ Collaboration diagram for UndoStack:

Signals

void undoTextChanged (const QString &text)
 
void redoTextChanged (const QString &text)
 
void canUndoChanged (bool canUndo)
 
void canRedoChanged (bool canRedo)
 
void cleanChanged (bool clean)
 
void commandGroupEnded ()
 
void commandGroupAborted ()
 
void stateModified ()
 

Public Member Functions

 UndoStack (const UndoStack &other)=delete
 
UndoStackoperator= (const UndoStack &rhs)=delete
 
 UndoStack () noexcept
 The default constructor. More...
 
 ~UndoStack () noexcept
 The destructor (will also call clear()) More...
 
QString getUndoText () const noexcept
 Get the text for the undo action. More...
 
QString getRedoText () const noexcept
 Get the text for the redo action. More...
 
bool canUndo () const noexcept
 Check if undo is possible. More...
 
bool canRedo () const noexcept
 Check if redo is possible. More...
 
bool isClean () const noexcept
 Check if the stack is in a clean state (the state of the last setClean()) More...
 
bool isCommandGroupActive () const noexcept
 Check if a command group is active at the moment (see mActiveCommandGroup) More...
 
void setClean () noexcept
 Set the current state as the clean state (see also isClean()) More...
 
void execCmd (UndoCommand *cmd, bool forceKeepCmd=false)
 Execute a command and push it to the stack (similar to QUndoStack::push()) More...
 
void beginCmdGroup (const QString &text)
 Begin building a new command group that consists of multiple commands step by step (over a "long" time) More...
 
void appendToCmdGroup (UndoCommand *cmd)
 Append a new command to the currently active command group. More...
 
void commitCmdGroup ()
 End the currently active command group and keep the changes. More...
 
void abortCmdGroup ()
 End the currently active command group and revert the changes. More...
 
void undo ()
 Undo the last command. More...
 
void redo ()
 Redo the last undoed command. More...
 
void clear () noexcept
 Clear the whole stack (delete all UndoCommand objects) More...
 

Private Attributes

QList< UndoCommand * > mCommands
 This list holds all commands of the undo stack. More...
 
int mCurrentIndex
 This attribute holds the current position in the undo stack mCommands. More...
 
int mCleanIndex
 The index of the command list where the stack was cleaned the last time. More...
 
UndoCommandGroupmActiveCommandGroup
 If a command group is active at the moment, this is the pointer to it. More...
 

Detailed Description

The UndoStack class holds UndoCommand objects and provides undo/redo commands.

Instead of the Qt classes QUndoStack and QUndoCommand we use our own undo classes UndoStack and #UndoCommand because of the better exception handling and more flexibility.

Note
Our classes work very similar to the equivalent classes of Qt, so please read the documentation of "Qt's Undo Framework" and classes QUndoStack and QUndoCommand. There is also a more detailed description here: The undo/redo system (Command Design Pattern)

Compared with QUndoStack, the biggest differences are the following:

  • Support for exceptions: If an exception is throwed in a #UndoCommand object, this undo stack always tries to keep the whole stack consistent (update the index only if the last undo/redo was successful, try to rollback failed changes, ...).
  • Removed support for nested macros (QUndoStack::beginMacro() and QUndoStack::endMacro()): I think we do need this feature (but we have a similar mechanism, see next line)...
  • Added support for exclusive macro command creation:
    Todo:
    Don't sure if this is a good way, we need some tests first... If the tests are successful, we should complete this documentation (explain how this feature works).
See Also
#UndoCommand, #UndoCommandGroup
Author
ubruhin
Date
2014-08-20
Todo:
This class is not yet tested very well. Does it work correctly when destroying an UndoStack object while the current index is not the index of the last command?

Constructor & Destructor Documentation

UndoStack ( const UndoStack other)
delete
UndoStack ( )
noexcept

The default constructor.

~UndoStack ( )
noexcept

The destructor (will also call clear())

+ Here is the call graph for this function:

Member Function Documentation

UndoStack& operator= ( const UndoStack rhs)
delete
QString getUndoText ( ) const
noexcept

Get the text for the undo action.

Returns
The text in the user's language ("Undo" if undo is not possible)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

QString getRedoText ( ) const
noexcept

Get the text for the redo action.

Returns
The text in the user's language ("Redo" if redo is not possible)

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool canUndo ( ) const
noexcept

Check if undo is possible.

Returns
true | false

+ Here is the caller graph for this function:

bool canRedo ( ) const
noexcept

Check if redo is possible.

Returns
true | false

+ Here is the caller graph for this function:

bool isClean ( ) const
noexcept

Check if the stack is in a clean state (the state of the last setClean())

This is used to detemine if the document/project/whatever has changed since the last time it was saved. You need to call setClean() when you save it.

Returns
true | false

+ Here is the caller graph for this function:

bool isCommandGroupActive ( ) const
noexcept

Check if a command group is active at the moment (see mActiveCommandGroup)

Returns
True if a command group is currently active

+ Here is the caller graph for this function:

void setClean ( )
noexcept

Set the current state as the clean state (see also isClean())

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void execCmd ( UndoCommand cmd,
bool  forceKeepCmd = false 
)

Execute a command and push it to the stack (similar to QUndoStack::push())

Parameters
cmdThe command to execute (must NOT be executed already). The stack will ALWAYS take the ownership over this command, even if this method throws an exception because of an error. In case of an exception, the command will be deleted directly in this method, so you must not make other things with the UndoCommand object after passing it to this method.
forceKeepCmdOnly for internal use!
Exceptions
ExceptionIf the command is not executed successfully, this method throws an exception and tries to keep the state of the stack consistend (as the passed command did never exist).
Note
If you try to execute a command with that method while another command is active (see #isCommandActive()), this method will throw an exception.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void beginCmdGroup ( const QString &  text)

Begin building a new command group that consists of multiple commands step by step (over a "long" time)

Parameters
textThe text of the whole command group (see UndoCommand::getText())
Exceptions
ExceptionThis method throws an exception if there is already another command group active (isCommandGroupActive()) or if an error occurs.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void appendToCmdGroup ( UndoCommand cmd)

Append a new command to the currently active command group.

This method must only be called between beginCmdGroup() and commitCmdGroup() or abortCmdGroup().

Parameters
cmdThe command to execute (same conditions as for execCmd()!)
Exceptions
ExceptionThis method throws an exception if there is no command group active at the moment (isCommandGroupActive()) or if an error occurs.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void commitCmdGroup ( )

End the currently active command group and keep the changes.

Exceptions
ExceptionThis method throws an exception if there is no command group active at the moment (isCommandGroupActive()) or if an error occurs.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void abortCmdGroup ( )

End the currently active command group and revert the changes.

Exceptions
ExceptionThis method throws an exception if there is no command group active at the moment (isCommandGroupActive()) or if an error occurs.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void undo ( )

Undo the last command.

Note
If you call this method while another command group is currently active (isCommandGroupActive()), this method will do nothing.
Exceptions
ExceptionIf an error occurs, this class tries to revert all changes to restore the state of BEFORE calling this method. But there is no guarantee that this will work correctly...

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void redo ( )

Redo the last undoed command.

Exceptions
ExceptionIf an error occurs, this class tries to revert all changes to restore the state of BEFORE calling this method. But there is no guarantee that this will work correctly...

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void clear ( )
noexcept

Clear the whole stack (delete all UndoCommand objects)

All UndoCommand objects will be deleted in the reverse order of their creation (the newest first, the oldest at last).

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void undoTextChanged ( const QString &  text)
signal

+ Here is the caller graph for this function:

void redoTextChanged ( const QString &  text)
signal

+ Here is the caller graph for this function:

void canUndoChanged ( bool  canUndo)
signal

+ Here is the caller graph for this function:

void canRedoChanged ( bool  canRedo)
signal

+ Here is the caller graph for this function:

void cleanChanged ( bool  clean)
signal

+ Here is the caller graph for this function:

void commandGroupEnded ( )
signal

+ Here is the caller graph for this function:

void commandGroupAborted ( )
signal

+ Here is the caller graph for this function:

void stateModified ( )
signal

+ Here is the caller graph for this function:

Member Data Documentation

QList<UndoCommand*> mCommands
private

This list holds all commands of the undo stack.

The first (oldest) command is at index zero (bottom of the stack), the last (newest) command is at index "count-1" (top of the stack).

int mCurrentIndex
private

This attribute holds the current position in the undo stack mCommands.

The value of this variable points to the index which the NEXT pushed command will have in the list mCommands. So if the list is empty, this variable has the value zero.

int mCleanIndex
private

The index of the command list where the stack was cleaned the last time.

UndoCommandGroup* mActiveCommandGroup
private

If a command group is active at the moment, this is the pointer to it.

This pointer is only valid between calls to beginCmdGroup() and commitCmdGroup() or abortCmdGroup(). Otherwise, the variable contains the nullptr.


The documentation for this class was generated from the following files: