#include <iostream>
#include <string>
#include <sstream>
+#include <time.h>
-#include <pbd/undo.h>
-#include <pbd/xml++.h>
-#include <pbd/shiva.h>
+#include "pbd/undo.h"
+#include "pbd/xml++.h"
#include <sigc++/bind.h>
UndoTransaction::UndoTransaction ()
: _clearing(false)
{
+ gettimeofday (&_timestamp, 0);
}
UndoTransaction::UndoTransaction (const UndoTransaction& rhs)
: Command(rhs._name)
+ , PBD::ScopedConnectionList ()
, _clearing(false)
{
clear ();
UndoTransaction::~UndoTransaction ()
{
- GoingAway ();
+ drop_references ();
clear ();
}
void
UndoTransaction::add_command (Command *const action)
{
- /* catch death */
- new PBD::ProxyShiva<Command,UndoTransaction> (*action, *this, &command_death);
+ /* catch death of command (e.g. caused by death of object to
+ which it refers. command_death() is a normal static function
+ so there is no need to manage this connection.
+ */
+
+ action->DropReferences.connect_same_thread (*this, boost::bind (&command_death, this, action));
actions.push_back (action);
}
UndoHistory::UndoHistory ()
{
_clearing = false;
+ _depth = 0;
+}
+
+void
+UndoHistory::set_depth (uint32_t d)
+{
+ UndoTransaction* ut;
+ uint32_t current_depth = UndoList.size();
+
+ _depth = d;
+
+ if (d > current_depth) {
+ /* not even transactions to meet request */
+ return;
+ }
+
+ if (_depth > 0) {
+
+ uint32_t cnt = current_depth - d;
+
+ while (cnt--) {
+ ut = UndoList.front();
+ UndoList.pop_front ();
+ delete ut;
+ }
+ }
}
void
UndoHistory::add (UndoTransaction* const ut)
{
- ut->GoingAway.connect (bind (mem_fun (*this, &UndoHistory::remove), ut));
+ uint32_t current_depth = UndoList.size();
+
+ ut->DropReferences.connect_same_thread (*this, boost::bind (&UndoHistory::remove, this, ut));
+
+ /* if the current undo history is larger than or equal to the currently
+ requested depth, then pop off at least 1 element to make space
+ at the back for new one.
+ */
+
+ if ((_depth > 0) && current_depth && (current_depth >= _depth)) {
+
+ uint32_t cnt = 1 + (current_depth - _depth);
+
+ while (cnt--) {
+ UndoTransaction* ut;
+ ut = UndoList.front ();
+ UndoList.pop_front ();
+ delete ut;
+ }
+ }
+
UndoList.push_back (ut);
- /* we are now owners of the transaction */
+ /* we are now owners of the transaction and must delete it when finished with it */
Changed (); /* EMIT SIGNAL */
}
}
XMLNode&
-UndoHistory::get_state (uint32_t depth)
+UndoHistory::get_state (int32_t depth)
{
XMLNode *node = new XMLNode ("UndoHistory");
if (depth == 0) {
+
+ return (*node);
+
+ } else if (depth < 0) {
+
/* everything */
for (list<UndoTransaction*>::iterator it = UndoList.begin(); it != UndoList.end(); ++it) {
node->add_child_nocopy((*it)->get_state());
}
-
+
} else {
/* just the last "depth" transactions */
return *node;
}
+
+