LibrePCB Developers Documentation
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...
 
uint getUniqueStateId () const noexcept
 Get a unique identification of the current state. 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...
 
bool 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...
 
bool appendToCmdGroup (UndoCommand *cmd)
 Append a new command to the currently active command group. More...
 
bool 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 librepcb::editor::UndoStack and librepcb::editor::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 thrown in an librepcb::editor::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:
See also
librepcb::editor::UndoCommand, librepcb::editor::UndoCommandGroup

Constructor & Destructor Documentation

◆ UndoStack() [1/2]

UndoStack ( const UndoStack other)
delete

◆ UndoStack() [2/2]

UndoStack ( )
noexcept

The default constructor.

◆ ~UndoStack()

~UndoStack ( )
noexcept

The destructor (will also call clear())

Member Function Documentation

◆ operator=()

UndoStack& operator= ( const UndoStack rhs)
delete

◆ getUndoText()

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)

◆ getRedoText()

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)

◆ canUndo()

bool canUndo ( ) const
noexcept

Check if undo is possible.

Returns
true | false

◆ canRedo()

bool canRedo ( ) const
noexcept

Check if redo is possible.

Returns
true | false

◆ getUniqueStateId()

uint getUniqueStateId ( ) const
noexcept

Get a unique identification of the current state.

Useful to detect if there were any changes made between to different points in time.

Returns
The current state identification
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ isClean()

bool isClean ( ) const
noexcept

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

This is used to determine 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:

◆ isCommandGroupActive()

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:

◆ setClean()

void setClean ( )
noexcept

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

+ Here is the caller graph for this function:

◆ execCmd()

bool 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!
Return values
trueIf the command has done some changes
falseIf the command has done nothing
Exceptions
ExceptionIf the command is not executed successfully, this method throws an exception and tries to keep the state of the stack consistent (as the passed command did never exist).
Note
If you try to execute a command with that method while another command is active (see isCommandGroupActive()), this method will throw an exception.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ beginCmdGroup()

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 caller graph for this function:

◆ appendToCmdGroup()

bool 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()!)
Return values
trueIf the command has done some changes
falseIf the command has done nothing
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 caller graph for this function:

◆ commitCmdGroup()

bool commitCmdGroup ( )

End the currently active command group and keep the changes.

Return values
trueIf the command group has done some changes
falseIf the command group has done nothing
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 caller graph for this function:

◆ abortCmdGroup()

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:

◆ undo()

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:

◆ redo()

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:

◆ clear()

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 caller graph for this function:

◆ undoTextChanged

void undoTextChanged ( const QString &  text)
signal
+ Here is the caller graph for this function:

◆ redoTextChanged

void redoTextChanged ( const QString &  text)
signal
+ Here is the caller graph for this function:

◆ canUndoChanged

void canUndoChanged ( bool  canUndo)
signal
+ Here is the caller graph for this function:

◆ canRedoChanged

void canRedoChanged ( bool  canRedo)
signal
+ Here is the caller graph for this function:

◆ cleanChanged

void cleanChanged ( bool  clean)
signal
+ Here is the caller graph for this function:

◆ commandGroupEnded

void commandGroupEnded ( )
signal

◆ commandGroupAborted

void commandGroupAborted ( )
signal

◆ stateModified

void stateModified ( )
signal
+ Here is the caller graph for this function:

Member Data Documentation

◆ mCommands

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).

◆ mCurrentIndex

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.

◆ mCleanIndex

int mCleanIndex
private

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

◆ mActiveCommandGroup

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: