How to use QT-Undo framework in constructor

243 views Asked by At

Lets say i have a QUndoCommand for creating a Object and for changing the color.

class ObjectInterface{
    QColor color;
}

class CommandCreateObject : public QUndoCommand {
public:
    CommandCreateObject(QString const& objectName );
    void undo() Q_DECL_OVERRIDE;
    void redo() Q_DECL_OVERRIDE;  
}

class CommandChangeColor : public QUndoCommand{
public:
    CommandCreateObject(QString const& objectName );
    void undo() Q_DECL_OVERRIDE;
    void redo() Q_DECL_OVERRIDE;  
}

Now the object created by CommandCreateObject is a differet class every time cause it is calling a factorymethode.

So the created object itself is setting his values in contructor. lets say its sets his Color to blue. Cause changing the color itself is a Command i would also call it a as Command.

// lets also say there is a Model from wich all Commands are triggered
class Model {
    static QundoStack *undoStack;

    static void changeColor(ObjectInterface *target, QColor const& color) {
        undoStack->beginMacro("Change Color");
        undoStack->push( new CommandChangeColor(target,color));
        undoStack->endMacro();
    }
    staic void createObject(QString const& objectName) {
        undoStack->beginMacro("Create Object");
        undoStack->push( new CommandCreateObject(objectName));
        undoStack->endMacro();
    }
}



class BlueObject : public ObjectInterface {
    BlueObject() {
         Model::changeColor(this,Qt::blue);
    };
}

Now to the problem:

If i create the object the undostack looks like:

  1. create Object -> change Color

than Undo the create which triggers:

  1. change Color Back

  2. delte Object

and than Redo the Command

  1. create Object -> change color (called by constructor)
  2. change color (called from undostack)

and the second change color is my problem. so there is one already in stack but cause its in the contructor its called/created a second time.

Of course i can just call the color change without command stack, but i like to have idea of having all things done as commands. Otherwise i have to write them two times which seems kind a dirty and i have to maintainance both versions of color change.

The colorchange is just an example, i my case its creating childObject. Also its keeping track of every Object by uuids.

So is there a smart way to handle such structures?

1

There are 1 answers

0
Steeve On

How about adding a little modification to your Model class to include commands which do not get added to the undo stack, e.g.:

static void changeColor(ObjectInterface *target, QColor const& color, bool undoable = true) {
    if (undoable) {
        undoStack->beginMacro("Change Color");
        undoStack->push( new CommandChangeColor(target,color));
        undoStack->endMacro();
    } else {
        QUndoCommand *cmd = new CommandChangeColor(target, color);
        cmd->redo();
        delete cmd;
    }
}

Then you can do:

class BlueObject : public ObjectInterface {
    BlueObject() {
         Model::changeColor(this,Qt::blue, false); // false to skip adding it to the undo stack
    };
}