/*
- Copyright (C) 2006 Hans Fugal & Paul Davis
+ Copyright (C) 2006 Paul Davis
+ Author: Hans Fugal
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id: /local/undo/libs/pbd3/pbd/undo.h 132 2006-06-29T18:45:16.609763Z fugalh $
*/
#ifndef __lib_pbd_memento_command_h__
#define __lib_pbd_memento_command_h__
+#include <iostream>
+
#include <pbd/command.h>
+#include <pbd/stacktrace.h>
#include <pbd/xml++.h>
+#include <pbd/shiva.h>
+
#include <sigc++/slot.h>
+#include <typeinfo>
/** This command class is initialized with before and after mementos
* (from Stateful::get_state()), so undo becomes restoring the before
*/
template <class obj_T>
class MementoCommand : public Command
-{
- public:
- MementoCommand(obj_T &obj,
- XMLNode &before,
- XMLNode &after
- )
- : obj(obj), before(before), after(after) {}
- void operator() () { obj.set_state(after); }
- void undo() { obj.set_state(before); }
- virtual XMLNode &get_state()
- {
- XMLNode *node = new XMLNode("MementoCommand");
- node->add_property("obj_id", obj.id().to_s());
- node->add_child_nocopy(before);
- node->add_child_nocopy(after);
- return *node;
- }
- // TODO does this need a copy constructor?
- protected:
- obj_T &obj;
- XMLNode &before, &after;
-};
-
-template <class obj_T>
-class MementoUndoCommand : public Command
{
public:
- MementoUndoCommand(obj_T &obj,
- XMLNode &before)
- : obj(obj), before(before) {}
- void operator() () { /* noop */ }
- void undo() { obj.set_state(before); }
- virtual XMLNode &get_state()
- {
- XMLNode *node = new XMLNode("MementoUndoCommand");
- node->add_property("obj_id", obj.id().to_s());
- node->add_child_nocopy(before);
- return *node;
- }
-protected:
- obj_T &obj;
- XMLNode &before;
-};
+ MementoCommand(obj_T &object, XMLNode *before, XMLNode *after)
+ : obj(object), before(before), after(after)
+ {
+ /* catch destruction of the object */
+ new PBD::PairedShiva<obj_T,MementoCommand<obj_T> > (object, *this);
+ }
+
+ ~MementoCommand ()
+ {
+ GoingAway(); /* EMIT SIGNAL */
+
+ if (before)
+ delete before;
+
+ if (after)
+ delete after;
+ }
+
+ void operator() ()
+ {
+ if (after)
+ obj.set_state(*after);
+ }
+
+ void undo()
+ {
+ if (before)
+ obj.set_state(*before);
+ }
+
+ virtual XMLNode &get_state()
+ {
+ string name;
+ if (before && after)
+ name = "MementoCommand";
+ else if (before)
+ name = "MementoUndoCommand";
+ else
+ name = "MementoRedoCommand";
+
+ XMLNode *node = new XMLNode(name);
+
+ node->add_property("obj_id", obj.id().to_s());
+ node->add_property("type_name", typeid(obj).name());
+
+ if (before)
+ node->add_child_copy(*before);
+
+ if (after)
+ node->add_child_copy(*after);
+
+ return *node;
+ }
-template <class obj_T>
-class MementoRedoCommand : public Command
-{
-public:
- MementoRedoCommand(obj_T &obj,
- XMLNode &after)
- : obj(obj), after(after) {}
- void operator() () { obj.set_state(after); }
- void undo() { /* noop */ }
- virtual XMLNode &get_state()
- {
- XMLNode *node = new XMLNode("MementoRedoCommand");
- node->add_property("obj_id", obj.id().to_s());
- node->add_child_nocopy(after);
- return *node;
- }
protected:
- obj_T &obj;
- XMLNode &after;
+ obj_T &obj;
+ XMLNode *before, *after;
};
#endif // __lib_pbd_memento_h__