summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Fugal <hans@fugal.net>2006-08-04 03:46:07 +0000
committerHans Fugal <hans@fugal.net>2006-08-04 03:46:07 +0000
commitdca612e82af4f89dad4f15454cbbb15694fa077c (patch)
tree5ab9e96d4e4314554a818b541bbc8e0e5f0c3e70
parentaacae5f32b63f2847730eebc3b556f061ac5f6f1 (diff)
parent5756373841675a879833f98bb4008dd0c40714d3 (diff)
Merging undo branch into trunk. It compiles and works for limited tests. Keep
your eye on it. Actual serialization is still not there, but the next step. git-svn-id: svn://localhost/ardour2/trunk@758 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r--gtk2_ardour/audio_region_view.cc11
-rw-r--r--gtk2_ardour/audio_time_axis.cc1
-rw-r--r--gtk2_ardour/automation_line.cc25
-rw-r--r--gtk2_ardour/automation_line.h5
-rw-r--r--gtk2_ardour/automation_time_axis.cc19
-rw-r--r--gtk2_ardour/editor.cc8
-rw-r--r--gtk2_ardour/editor.h3
-rw-r--r--gtk2_ardour/editor_audio_import.cc5
-rw-r--r--gtk2_ardour/editor_keyboard.cc6
-rw-r--r--gtk2_ardour/editor_markers.cc36
-rw-r--r--gtk2_ardour/editor_mouse.cc102
-rw-r--r--gtk2_ardour/editor_ops.cc182
-rw-r--r--gtk2_ardour/editor_tempodisplay.cc30
-rw-r--r--gtk2_ardour/editor_timefx.cc6
-rw-r--r--gtk2_ardour/gain_automation_time_axis.cc6
-rw-r--r--gtk2_ardour/location_ui.cc16
-rw-r--r--gtk2_ardour/pan_automation_time_axis.cc6
-rw-r--r--gtk2_ardour/redirect_automation_time_axis.cc6
-rw-r--r--gtk2_ardour/region_editor.h2
-rw-r--r--gtk2_ardour/region_gain_line.cc15
-rw-r--r--gtk2_ardour/route_time_axis.cc12
-rw-r--r--gtk2_ardour/route_ui.cc48
-rw-r--r--libs/ardour/SConscript1
-rw-r--r--libs/ardour/ardour/automation_event.h5
-rw-r--r--libs/ardour/ardour/session.h74
-rw-r--r--libs/ardour/audio_diskstream.cc6
-rw-r--r--libs/ardour/automation_event.cc14
-rw-r--r--libs/ardour/session_command.cc93
-rw-r--r--libs/ardour/session_state.cc22
-rw-r--r--libs/ardour/session_transport.cc7
-rw-r--r--libs/pbd/SConscript1
-rw-r--r--libs/pbd/command.cc10
-rw-r--r--libs/pbd/pbd/command.h36
-rw-r--r--libs/pbd/pbd/memento_command.h94
-rw-r--r--libs/pbd/pbd/serializable.h33
-rw-r--r--libs/pbd/pbd/undo.h27
-rw-r--r--libs/pbd/undo.cc71
37 files changed, 751 insertions, 293 deletions
diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc
index feb8f4fd0b..bdea3d39a2 100644
--- a/gtk2_ardour/audio_region_view.cc
+++ b/gtk2_ardour/audio_region_view.cc
@@ -30,6 +30,7 @@
#include <ardour/audioregion.h>
#include <ardour/audiosource.h>
#include <ardour/audio_diskstream.h>
+#include <pbd/memento_command.h>
#include "streamview.h"
#include "audio_region_view.h"
@@ -898,18 +899,20 @@ AudioRegionView::add_gain_point_event (ArdourCanvas::Item *item, GdkEvent *ev)
gain_line->view_to_model_y (y);
trackview.session().begin_reversible_command (_("add gain control point"));
- trackview.session().add_undo (audio_region().envelope().get_memento());
+ XMLNode &before = audio_region().envelope().get_state();
if (!audio_region().envelope_active()) {
- trackview.session().add_undo( bind( mem_fun(audio_region(), &AudioRegion::set_envelope_active), false) );
+ XMLNode &before = audio_region().get_state();
audio_region().set_envelope_active(true);
- trackview.session().add_redo( bind( mem_fun(audio_region(), &AudioRegion::set_envelope_active), true) );
+ XMLNode &after = audio_region().get_state();
+ trackview.session().add_command (new MementoCommand<AudioRegion>(audio_region(), before, after));
}
audio_region().envelope().add (fx, y);
- trackview.session().add_redo_no_execute (audio_region().envelope().get_memento());
+ XMLNode &after = audio_region().envelope().get_state();
+ trackview.session().add_command (new MementoCommand<Curve>(audio_region().envelope(), before, after));
trackview.session().commit_reversible_command ();
}
diff --git a/gtk2_ardour/audio_time_axis.cc b/gtk2_ardour/audio_time_axis.cc
index 376e05aa4c..9ae94d1fe0 100644
--- a/gtk2_ardour/audio_time_axis.cc
+++ b/gtk2_ardour/audio_time_axis.cc
@@ -31,6 +31,7 @@
#include <pbd/error.h>
#include <pbd/stl_delete.h>
#include <pbd/whitespace.h>
+#include <pbd/memento_command.h>
#include <gtkmm2ext/gtk_ui.h>
#include <gtkmm2ext/selector.h>
diff --git a/gtk2_ardour/automation_line.cc b/gtk2_ardour/automation_line.cc
index b87a71ca87..4cf6779c98 100644
--- a/gtk2_ardour/automation_line.cc
+++ b/gtk2_ardour/automation_line.cc
@@ -23,6 +23,7 @@
#include <vector>
#include <pbd/stl_delete.h>
+#include <pbd/memento_command.h>
#include <ardour/automation_event.h>
#include <ardour/curve.h>
@@ -887,7 +888,7 @@ AutomationLine::start_drag (ControlPoint* cp, float fraction)
}
trackview.editor.current_session()->begin_reversible_command (str);
- trackview.editor.current_session()->add_undo (get_memento());
+ trackview.editor.current_session()->add_command (new MementoUndoCommand<AutomationLine>(*this, get_state()));
first_drag_fraction = fraction;
last_drag_fraction = fraction;
@@ -936,7 +937,7 @@ AutomationLine::end_drag (ControlPoint* cp)
update_pending = false;
- trackview.editor.current_session()->add_redo_no_execute (get_memento());
+ trackview.editor.current_session()->add_command (new MementoRedoCommand<AutomationLine>(*this, get_state()));
trackview.editor.current_session()->commit_reversible_command ();
trackview.editor.current_session()->set_dirty ();
}
@@ -1013,11 +1014,11 @@ AutomationLine::remove_point (ControlPoint& cp)
model_representation (cp, mr);
trackview.editor.current_session()->begin_reversible_command (_("remove control point"));
- trackview.editor.current_session()->add_undo (get_memento());
+ XMLNode &before = get_state();
alist.erase (mr.start, mr.end);
- trackview.editor.current_session()->add_redo_no_execute (get_memento());
+ trackview.editor.current_session()->add_command(new MementoCommand<AutomationLine>(*this, before, get_state()));
trackview.editor.current_session()->commit_reversible_command ();
trackview.editor.current_session()->set_dirty ();
}
@@ -1225,9 +1226,9 @@ void
AutomationLine::clear ()
{
/* parent must create command */
- trackview.editor.current_session()->add_undo (get_memento());
+ XMLNode &before = get_state();
alist.clear();
- trackview.editor.current_session()->add_redo_no_execute (get_memento());
+ trackview.editor.current_session()->add_command (new MementoCommand<AutomationLine>(*this, before, get_state()));
trackview.editor.current_session()->commit_reversible_command ();
trackview.editor.current_session()->set_dirty ();
}
@@ -1266,3 +1267,15 @@ AutomationLine::hide_all_but_selected_control_points ()
}
}
}
+
+XMLNode &AutomationLine::get_state(void)
+{
+ // TODO
+ return alist.get_state();
+}
+
+int AutomationLine::set_state(const XMLNode &node)
+{
+ // TODO
+ alist.set_state(node);
+}
diff --git a/gtk2_ardour/automation_line.h b/gtk2_ardour/automation_line.h
index e922de6c80..9c6b932dfd 100644
--- a/gtk2_ardour/automation_line.h
+++ b/gtk2_ardour/automation_line.h
@@ -94,7 +94,7 @@ class ControlPoint
ShapeType _shape;
};
-class AutomationLine : public sigc::trackable
+class AutomationLine : public sigc::trackable, public Stateful
{
public:
AutomationLine (const string & name, TimeAxisView&, ArdourCanvas::Group&, ARDOUR::AutomationList&);
@@ -158,6 +158,9 @@ class AutomationLine : public sigc::trackable
bool is_last_point (ControlPoint &);
bool is_first_point (ControlPoint &);
+ XMLNode& get_state (void);
+ int set_state (const XMLNode&);
+
protected:
string _name;
guint32 _height;
diff --git a/gtk2_ardour/automation_time_axis.cc b/gtk2_ardour/automation_time_axis.cc
index cdeed5cc4d..6e2a93889f 100644
--- a/gtk2_ardour/automation_time_axis.cc
+++ b/gtk2_ardour/automation_time_axis.cc
@@ -1,4 +1,5 @@
#include <ardour/route.h>
+#include <pbd/memento_command.h>
#include "ardour_ui.h"
#include "automation_time_axis.h"
@@ -476,13 +477,13 @@ AutomationTimeAxisView::cut_copy_clear_one (AutomationLine& line, Selection& sel
AutomationList& alist (line.the_list());
bool ret = false;
- _session.add_undo (alist.get_memento());
+ XMLNode &before = alist.get_state();
switch (op) {
case Cut:
if ((what_we_got = alist.cut (selection.time.front().start, selection.time.front().end)) != 0) {
editor.get_cut_buffer().add (what_we_got);
- _session.add_redo_no_execute (alist.get_memento());
+ _session.add_command(new MementoCommand<AutomationList>(alist, before, alist.get_state()));
ret = true;
}
break;
@@ -494,7 +495,7 @@ AutomationTimeAxisView::cut_copy_clear_one (AutomationLine& line, Selection& sel
case Clear:
if ((what_we_got = alist.cut (selection.time.front().start, selection.time.front().end)) != 0) {
- _session.add_redo_no_execute (alist.get_memento());
+ _session.add_command(new MementoCommand<AutomationList>(alist, before, alist.get_state()));
delete what_we_got;
what_we_got = 0;
ret = true;
@@ -526,7 +527,7 @@ AutomationTimeAxisView::reset_objects_one (AutomationLine& line, PointSelection&
{
AutomationList& alist (line.the_list());
- _session.add_undo (alist.get_memento());
+ _session.add_command (new MementoUndoCommand<AutomationList>(alist, alist.get_state()));
for (PointSelection::iterator i = selection.begin(); i != selection.end(); ++i) {
@@ -557,7 +558,7 @@ AutomationTimeAxisView::cut_copy_clear_objects_one (AutomationLine& line, PointS
AutomationList& alist (line.the_list());
bool ret = false;
- _session.add_undo (alist.get_memento());
+ XMLNode &before = alist.get_state();
for (PointSelection::iterator i = selection.begin(); i != selection.end(); ++i) {
@@ -569,7 +570,7 @@ AutomationTimeAxisView::cut_copy_clear_objects_one (AutomationLine& line, PointS
case Cut:
if ((what_we_got = alist.cut ((*i).start, (*i).end)) != 0) {
editor.get_cut_buffer().add (what_we_got);
- _session.add_redo_no_execute (alist.get_memento());
+ _session.add_command (new MementoCommand<AutomationList>(alist, before, alist.get_state()));
ret = true;
}
break;
@@ -581,7 +582,7 @@ AutomationTimeAxisView::cut_copy_clear_objects_one (AutomationLine& line, PointS
case Clear:
if ((what_we_got = alist.cut ((*i).start, (*i).end)) != 0) {
- _session.add_redo_no_execute (alist.get_memento());
+ _session.add_command (new MementoCommand<AutomationList>(alist, before, alist.get_state()));
delete what_we_got;
what_we_got = 0;
ret = true;
@@ -638,9 +639,9 @@ AutomationTimeAxisView::paste_one (AutomationLine& line, jack_nframes_t pos, flo
(*x)->value = foo;
}
- _session.add_undo (alist.get_memento());
+ XMLNode &before = alist.get_state();
alist.paste (copy, pos, times);
- _session.add_redo_no_execute (alist.get_memento());
+ _session.add_command (new MementoCommand<AutomationList>(alist, before, alist.get_state()));
return true;
}
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index 518ef7217a..513251085c 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -28,6 +28,7 @@
#include <pbd/convert.h>
#include <pbd/error.h>
+#include <pbd/memento_command.h>
#include <gtkmm/image.h>
#include <gdkmm/color.h>
@@ -2878,8 +2879,8 @@ void
Editor::begin_reversible_command (string name)
{
if (session) {
- UndoAction ua = get_memento();
- session->begin_reversible_command (name, &ua);
+ before = &get_state();
+ session->begin_reversible_command (name);
}
}
@@ -2887,8 +2888,7 @@ void
Editor::commit_reversible_command ()
{
if (session) {
- UndoAction ua = get_memento();
- session->commit_reversible_command (&ua);
+ session->commit_reversible_command (new MementoCommand<Editor>(*this, *before, get_state()));
}
}
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index a1e69e2ad1..c31dfd5ede 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -1596,13 +1596,14 @@ class Editor : public PublicEditor
UndoAction get_memento() const;
+ XMLNode *before; /* used in *_reversible_command */
void begin_reversible_command (string cmd_name);
void commit_reversible_command ();
/* visual history */
UndoHistory visual_history;
- UndoCommand current_visual_command;
+ UndoTransaction current_visual_command;
void begin_reversible_visual_command (const string & cmd_name);
void commit_reversible_visual_command ();
diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc
index f8c632f08a..7524f9605c 100644
--- a/gtk2_ardour/editor_audio_import.cc
+++ b/gtk2_ardour/editor_audio_import.cc
@@ -31,6 +31,7 @@
#include <ardour/audio_track.h>
#include <ardour/audioplaylist.h>
#include <ardour/audiofilesource.h>
+#include <pbd/memento_command.h>
#include "ardour_ui.h"
#include "editor.h"
@@ -320,9 +321,9 @@ Editor::finish_bringing_in_audio (AudioRegion& region, uint32_t in_chans, uint32
AudioRegion* copy = new AudioRegion (region);
begin_reversible_command (_("insert sndfile"));
- session->add_undo (playlist->get_memento());
+ XMLNode &before = playlist->get_state();
playlist->add_region (*copy, pos);
- session->add_redo_no_execute (playlist->get_memento());
+ session->add_command (new MementoCommand<Playlist>(*playlist, before, playlist->get_state()));
commit_reversible_command ();
pos += region.length();
diff --git a/gtk2_ardour/editor_keyboard.cc b/gtk2_ardour/editor_keyboard.cc
index d2b7c1160e..f48d860d15 100644
--- a/gtk2_ardour/editor_keyboard.cc
+++ b/gtk2_ardour/editor_keyboard.cc
@@ -20,6 +20,7 @@
#include <ardour/audioregion.h>
#include <ardour/playlist.h>
+#include <pbd/memento_command.h>
#include "editor.h"
#include "region_view.h"
@@ -102,11 +103,12 @@ Editor::kbd_mute_unmute_region ()
{
if (entered_regionview) {
begin_reversible_command (_("mute region"));
- session->add_undo (entered_regionview->region().playlist()->get_memento());
+ XMLNode &before = entered_regionview->region().playlist()->get_state();
entered_regionview->region().set_muted (!entered_regionview->region().muted());
- session->add_redo_no_execute (entered_regionview->region().playlist()->get_memento());
+ XMLNode &after = entered_regionview->region().playlist()->get_state();
+ session->add_command (new MementoCommand<ARDOUR::Playlist>(*(entered_regionview->region().playlist()), before, after));
commit_reversible_command();
}
}
diff --git a/gtk2_ardour/editor_markers.cc b/gtk2_ardour/editor_markers.cc
index f34b8590a4..ccc1415888 100644
--- a/gtk2_ardour/editor_markers.cc
+++ b/gtk2_ardour/editor_markers.cc
@@ -26,6 +26,7 @@
#include <gtkmm2ext/gtk_ui.h>
#include <ardour/location.h>
+#include <pbd/memento_command.h>
#include "editor.h"
#include "marker.h"
@@ -290,9 +291,10 @@ Editor::mouse_add_new_marker (jack_nframes_t where)
if (session) {
Location *location = new Location (where, where, "mark", Location::IsMark);
session->begin_reversible_command (_("add marker"));
- session->add_undo (session->locations()->get_memento());
+ XMLNode &before = session->locations()->get_state();
session->locations()->add (location, true);
- session->add_redo_no_execute (session->locations()->get_memento());
+ XMLNode &after = session->locations()->get_state();
+ session->add_command (new MementoCommand<Locations>(*(session->locations()), before, after));
session->commit_reversible_command ();
}
}
@@ -329,9 +331,10 @@ gint
Editor::really_remove_marker (Location* loc)
{
session->begin_reversible_command (_("remove marker"));
- session->add_undo (session->locations()->get_memento());
+ XMLNode &before = session->locations()->get_state();
session->locations()->remove (loc);
- session->add_redo_no_execute (session->locations()->get_memento());
+ XMLNode &after = session->locations()->get_state();
+ session->add_command (new MementoCommand<Locations>(*(session->locations()), before, after));
session->commit_reversible_command ();
return FALSE;
}
@@ -838,12 +841,13 @@ Editor::marker_menu_rename ()
}
begin_reversible_command ( _("rename marker") );
- session->add_undo( session->locations()->get_memento() );
+ XMLNode &before = session->locations()->get_state();
dialog.get_result(txt);
loc->set_name (txt);
- session->add_redo_no_execute( session->locations()->get_memento() );
+ XMLNode &after = session->locations()->get_state();
+ session->add_command (new MementoCommand<Locations>(*(session->locations()), before, after));
commit_reversible_command ();
}
@@ -868,16 +872,18 @@ Editor::new_transport_marker_menu_set_loop ()
if ((tll = transport_loop_location()) == 0) {
Location* loc = new Location (temp_location->start(), temp_location->end(), _("Loop"), Location::IsAutoLoop);
- session->add_undo (session->locations()->get_memento());
+ XMLNode &before = session->locations()->get_state();
session->locations()->add (loc, true);
session->set_auto_loop_location (loc);
- session->add_redo_no_execute (session->locations()->get_memento());
+ XMLNode &after = session->locations()->get_state();
+ session->add_command (new MementoCommand<Locations>(*(session->locations()), before, after));
}
else {
- session->add_undo (retype_return<void>(bind (mem_fun (*tll, &Location::set), tll->start(), tll->end())));
- session->add_redo (retype_return<void>(bind (mem_fun (*tll, &Location::set), temp_location->start(), temp_location->end())));
+ XMLNode &before = tll->get_state();
tll->set_hidden (false, this);
tll->set (temp_location->start(), temp_location->end());
+ XMLNode &after = tll->get_state();
+ session->add_command (new MementoCommand<Location>(*tll, before, after));
}
commit_reversible_command ();
@@ -894,15 +900,17 @@ Editor::new_transport_marker_menu_set_punch ()
if ((tpl = transport_punch_location()) == 0) {
tpl = new Location (temp_location->start(), temp_location->end(), _("Punch"), Location::IsAutoPunch);
- session->add_undo (session->locations()->get_memento());
+ XMLNode &before = session->locations()->get_state();
session->locations()->add (tpl, true);
session->set_auto_punch_location (tpl);
- session->add_redo_no_execute (session->locations()->get_memento());
+ XMLNode &after = session->locations()->get_state();
+ session->add_command (new MementoCommand<Locations>(*(session->locations()), before, after));
} else {
- session->add_undo (retype_return<void>(bind (mem_fun (*tpl, &Location::set), tpl->start(), tpl->end())));
- session->add_redo (retype_return<void>(bind (mem_fun (*tpl, &Location::set), temp_location->start(), temp_location->end())));
+ XMLNode &before = tpl->get_state();
tpl->set_hidden(false, this);
tpl->set(temp_location->start(), temp_location->end());
+ XMLNode &after = tpl->get_state();
+ session->add_command (new MementoCommand<Location>(*tpl, before, after));
}
commit_reversible_command ();
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index 7e9af2dcb0..18c7f0727d 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -28,6 +28,7 @@
#include <pbd/error.h>
#include <gtkmm2ext/utils.h>
+#include <pbd/memento_command.h>
#include "ardour_ui.h"
#include "editor.h"
@@ -1817,9 +1818,14 @@ Editor::fade_in_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* even
}
begin_reversible_command (_("change fade in length"));
- session->add_undo (arv->region().get_memento());
+ XMLNode &before = arv->audio_region().get_state();
+
arv->audio_region().set_fade_in_length (fade_length);
- session->add_redo_no_execute (arv->region().get_memento());
+
+ XMLNode &after = arv->audio_region().get_state();
+ session->add_command(new MementoCommand<ARDOUR::AudioRegion>(arv->audio_region(),
+ before,
+ after));
commit_reversible_command ();
fade_in_drag_motion_callback (item, event);
}
@@ -1909,9 +1915,12 @@ Editor::fade_out_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* eve
}
begin_reversible_command (_("change fade out length"));
- session->add_undo (arv->region().get_memento());
+ XMLNode &before = arv->region().get_state();
+
arv->audio_region().set_fade_out_length (fade_length);
- session->add_redo_no_execute (arv->region().get_memento());
+
+ XMLNode &after = arv->region().get_state();
+ session->add_command(new MementoCommand<ARDOUR::Region>(arv->region(), before, after));
commit_reversible_command ();
fade_out_drag_motion_callback (item, event);
@@ -2153,7 +2162,7 @@ Editor::marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
begin_reversible_command ( _("move marker") );
- session->add_undo( session->locations()->get_memento() );
+ XMLNode &before = session->locations()->get_state();
Location * location = find_location_from_marker (marker, is_start);
@@ -2165,7 +2174,8 @@ Editor::marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
}
}
- session->add_redo_no_execute( session->locations()->get_memento() );
+ XMLNode &after = session->locations()->get_state();
+ session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
commit_reversible_command ();
marker_drag_line->hide();
@@ -2279,9 +2289,10 @@ Editor::meter_marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent*
if (drag_info.copy == true) {
begin_reversible_command (_("copy meter mark"));
- session->add_undo (map.get_memento());
+ XMLNode &before = map.get_state();
map.add_meter (marker->meter(), when);
- session->add_redo_no_execute (map.get_memento());
+ XMLNode &after = map.get_state();
+ session->add_command(new MementoCommand<TempoMap>(map, before, after));
commit_reversible_command ();
// delete the dummy marker we used for visual representation of copying.
@@ -2289,9 +2300,10 @@ Editor::meter_marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent*
delete marker;
} else {
begin_reversible_command (_("move meter mark"));
- session->add_undo (map.get_memento());
+ XMLNode &before = map.get_state();
map.move_meter (marker->meter(), when);
- session->add_redo_no_execute (map.get_memento());
+ XMLNode &after = map.get_state();
+ session->add_command(new MementoCommand<TempoMap>(map, before, after));
commit_reversible_command ();
}
}
@@ -2406,12 +2418,13 @@ Editor::tempo_marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent*
TempoMap& map (session->tempo_map());
map.bbt_time (drag_info.last_pointer_frame, when);
-
+
if (drag_info.copy == true) {
begin_reversible_command (_("copy tempo mark"));
- session->add_undo (map.get_memento());
+ XMLNode &before = map.get_state();
map.add_tempo (marker->tempo(), when);
- session->add_redo_no_execute (map.get_memento());
+ XMLNode &after = map.get_state();
+ session->add_command (new MementoCommand<TempoMap>(map, before, after));
commit_reversible_command ();
// delete the dummy marker we used for visual representation of copying.
@@ -2419,9 +2432,10 @@ Editor::tempo_marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent*
delete marker;
} else {
begin_reversible_command (_("move tempo mark"));
- session->add_undo (map.get_memento());
+ XMLNode &before = map.get_state();
map.move_tempo (marker->tempo(), when);
- session->add_redo_no_execute (map.get_memento());
+ XMLNode &after = map.get_state();
+ session->add_command (new MementoCommand<TempoMap>(map, before, after));
commit_reversible_command ();
}
}
@@ -2785,7 +2799,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
insert_result = affected_playlists.insert (to_playlist);
if (insert_result.second) {
- session->add_undo (to_playlist->get_memento ());
+ session->add_command (new MementoUndoCommand<Playlist>(*to_playlist, to_playlist->get_state()));
}
latest_regionview = 0;
@@ -3221,7 +3235,7 @@ Editor::region_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
insert_result = motion_frozen_playlists.insert (pl);
if (insert_result.second) {
pl->freeze();
- session->add_undo(pl->get_memento());
+ session->add_command(new MementoUndoCommand<Playlist>(*pl, pl->get_state()));
}
}
}
@@ -3349,7 +3363,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
insert_result = motion_frozen_playlists.insert(to_playlist);
if (insert_result.second) {
to_playlist->freeze();
- session->add_undo(to_playlist->get_memento());
+ session->add_command(new MementoUndoCommand<Playlist>(*to_playlist, to_playlist->get_state()));
}
}
@@ -3431,7 +3445,7 @@ Editor::region_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
out:
for (set<Playlist*>::iterator p = motion_frozen_playlists.begin(); p != motion_frozen_playlists.end(); ++p) {
(*p)->thaw ();
- session->add_redo_no_execute ((*p)->get_memento());
+ session->add_command (new MementoRedoCommand<Playlist>(*(*p), (*p)->get_state()));
}
motion_frozen_playlists.clear ();
@@ -3626,9 +3640,10 @@ Editor::start_selection_grab (ArdourCanvas::Item* item, GdkEvent* event)
Playlist* playlist = clicked_trackview->playlist();
- session->add_undo (playlist->get_memento ());
+ before = &(playlist->get_state());
clicked_trackview->playlist()->add_region (*region, selection->time[clicked_selection].start);
- session->add_redo_no_execute (playlist->get_memento ());
+ XMLNode &after = playlist->get_state();
+ session->add_command(new MementoCommand<Playlist>(*playlist, *before, after));
commit_reversible_command ();
@@ -3995,7 +4010,7 @@ Editor::trim_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
Playlist * pl = (*i)->region().playlist();
insert_result = motion_frozen_playlists.insert (pl);
if (insert_result.second) {
- session->add_undo (pl->get_memento());
+ session->add_command(new MementoUndoCommand<Playlist>(*pl, pl->get_state()));
}
}
}
@@ -4185,8 +4200,8 @@ Editor::trim_finished_callback (ArdourCanvas::Item* item, GdkEvent* event)
for (set<Playlist*>::iterator p = motion_frozen_playlists.begin(); p != motion_frozen_playlists.end(); ++p) {
//(*p)->thaw ();
- session->add_redo_no_execute ((*p)->get_memento());
- }
+ session->add_command (new MementoRedoCommand<Playlist>(*(*p), (*p)->get_state()));
+ }
motion_frozen_playlists.clear ();
@@ -4219,18 +4234,22 @@ Editor::point_trim (GdkEvent* event)
i != selection->regions.by_layer().end(); ++i)
{
if (!(*i)->region().locked()) {
- session->add_undo ((*i)->region().playlist()->get_memento());
+ Playlist *pl = (*i)->region().playlist();
+ XMLNode &before = pl->get_state();
(*i)->region().trim_front (new_bound, this);
- session->add_redo_no_execute ((*i)->region().playlist()->get_memento());
+ XMLNode &after = pl->get_state();
+ session->add_command(new MementoCommand<Playlist>(*pl, before, after));
}
}
} else {
if (!rv->region().locked()) {
- session->add_undo (rv->region().playlist()->get_memento());
+ Playlist *pl = rv->region().playlist();
+ XMLNode &before = pl->get_state();
rv->region().trim_front (new_bound, this);
- session->add_redo_no_execute (rv->region().playlist()->get_memento());
+ XMLNode &after = pl->get_state();
+ session->add_command(new MementoCommand<Playlist>(*pl, before, after));
}
}
@@ -4246,18 +4265,22 @@ Editor::point_trim (GdkEvent* event)
for (list<RegionView*>::const_iterator i = selection->regions.by_layer().begin(); i != selection->regions.by_layer().end(); ++i)
{
if (!(*i)->region().locked()) {
- session->add_undo ((*i)->region().playlist()->get_memento());
+ Playlist *pl = (*i)->region().playlist();
+ XMLNode &before = pl->get_state();
(*i)->region().trim_end (new_bound, this);
- session->add_redo_no_execute ((*i)->region().playlist()->get_memento());
+ XMLNode &after = pl->get_state();
+ session->add_command(new MementoCommand<Playlist>(*pl, before, after));
}
}
} else {
if (!rv->region().locked()) {
- session->add_undo (rv->region().playlist()->get_memento());
+ Playlist *pl = rv->region().playlist();
+ XMLNode &before = pl->get_state();
rv->region().trim_end (new_bound, this);
- session->add_redo_no_execute (rv->region().playlist()->get_memento());
+ XMLNode &after = pl->get_state();
+ session->add_command (new MementoCommand<Playlist>(*pl, before, after));
}
}
@@ -4279,7 +4302,8 @@ Editor::thaw_region_after_trim (RegionView& rv)
}
region.thaw (_("trimmed region"));
- session->add_redo_no_execute (region.playlist()->get_memento());
+ XMLNode &after = region.playlist()->get_state();
+ session->add_command (new MementoRedoCommand<Playlist>(*(region.playlist()), after));
AudioRegionView* arv = dynamic_cast<AudioRegionView*>(&rv);
if (arv)
@@ -4418,16 +4442,19 @@ Editor::end_range_markerbar_op (ArdourCanvas::Item* item, GdkEvent* event)
switch (range_marker_op) {
case CreateRangeMarker:
+ {
begin_reversible_command (_("new range marker"));
- session->add_undo (session->locations()->get_memento());
+ XMLNode &before = session->locations()->get_state();
newloc = new Location(temp_location->start(), temp_location->end(), "unnamed", Location::IsRangeMarker);
session->locations()->add (newloc, true);
- session->add_redo_no_execute (session->locations()->get_memento());
+ XMLNode &after = session->locations()->get_state();
+ session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
commit_reversible_command ();
range_bar_drag_rect->hide();
range_marker_drag_rect->hide();
break;
+ }
case CreateTransportMarker:
// popup menu to pick loop or punch
@@ -4801,9 +4828,10 @@ Editor::mouse_brush_insert_region (RegionView* rv, jack_nframes_t pos)
Playlist* playlist = atv->playlist();
double speed = atv->get_diskstream()->speed();
- session->add_undo (playlist->get_memento());
+ XMLNode &before = playlist->get_state();
playlist->add_region (*(new AudioRegion (arv->audio_region())), (jack_nframes_t) (pos * speed));
- session->add_redo_no_execute (playlist->get_memento());
+ XMLNode &after = playlist->get_state();
+ session->add_command(new MementoCommand<Playlist>(*playlist, before, after));
// playlist is frozen, so we have to update manually
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index bdaeb5aa97..1e5f336e52 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -28,6 +28,7 @@
#include <pbd/error.h>
#include <pbd/basename.h>
#include <pbd/pthread_utils.h>
+#include <pbd/memento_command.h>
#include <gtkmm2ext/utils.h>
#include <gtkmm2ext/choice.h>
@@ -209,9 +210,10 @@ Editor::split_regions_at (jack_nframes_t where, RegionSelection& regions)
_new_regionviews_show_envelope = arv->envelope_visible();
if (pl) {
- session->add_undo (pl->get_memento());
+ XMLNode &before = pl->get_state();
pl->split_region ((*a)->region(), where);
- session->add_redo_no_execute (pl->get_memento());
+ XMLNode &after = pl->get_state();
+ session->add_command(new MementoCommand<Playlist>(*pl, before, after));
}
a = tmp;
@@ -231,9 +233,10 @@ Editor::remove_clicked_region ()
Playlist* playlist = clicked_audio_trackview->playlist();
begin_reversible_command (_("remove region"));
- session->add_undo (playlist->get_memento());
+ XMLNode &before = playlist->get_state();
playlist->remove_region (&clicked_regionview->region());
- session->add_redo_no_execute (playlist->get_memento());
+ XMLNode &after = playlist->get_state();
+ session->add_command(new MementoCommand<Playlist>(*playlist, before, after));
commit_reversible_command ();
}
@@ -406,9 +409,10 @@ Editor::nudge_forward (bool next)
distance = next_distance;
}
- session->add_undo (r.playlist()->get_memento());
+ XMLNode &before = r.playlist()->get_state();
r.set_position (r.position() + distance, this);
- session->add_redo_no_execute (r.playlist()->get_memento());
+ XMLNode &after = r.playlist()->get_state();
+ session->add_command (new MementoCommand<Playlist>(*(r.playlist()), before, after));
}
commit_reversible_command ();
@@ -440,14 +444,15 @@ Editor::nudge_backward (bool next)
distance = next_distance;
}
- session->add_undo (r.playlist()->get_memento());
+ XMLNode &before = r.playlist()->get_state();
if (r.position() > distance) {
r.set_position (r.position() - distance, this);
} else {
r.set_position (0, this);
}
- session->add_redo_no_execute (r.playlist()->get_memento());
+ XMLNode &after = r.playlist()->get_state();
+ session->add_command(new MementoCommand<Playlist>(*(r.playlist()), before, after));
}
commit_reversible_command ();
@@ -480,9 +485,10 @@ Editor::nudge_forward_capture_offset ()
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
Region& r ((*i)->region());
- session->add_undo (r.playlist()->get_memento());
+ XMLNode &before = r.playlist()->get_state();
r.set_position (r.position() + distance, this);
- session->add_redo_no_execute (r.playlist()->get_memento());
+ XMLNode &after = r.playlist()->get_state();
+ session->add_command(new MementoCommand<Playlist>(*(r.playlist()), before, after));
}
commit_reversible_command ();
@@ -506,14 +512,15 @@ Editor::nudge_backward_capture_offset ()
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
Region& r ((*i)->region());
- session->add_undo (r.playlist()->get_memento());
+ XMLNode &before = r.playlist()->get_state();
if (r.position() > distance) {
r.set_position (r.position() - distance, this);
} else {
r.set_position (0, this);
}
- session->add_redo_no_execute (r.playlist()->get_memento());
+ XMLNode &after = r.playlist()->get_state();
+ session->add_command(new MementoCommand<Playlist>(*(r.playlist()), before, after));
}
commit_reversible_command ();
@@ -1290,9 +1297,10 @@ Editor::add_location_from_selection ()
Location *location = new Location (start, end, "selection");
session->begin_reversible_command (_("add marker"));
- session->add_undo (session->locations()->get_memento());
+ XMLNode &before = session->locations()->get_state();
session->locations()->add (location, true);
- session->add_redo_no_execute (session->locations()->get_memento());
+ XMLNode &after = session->locations()->get_state();
+ session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
session->commit_reversible_command ();
}
@@ -1303,9 +1311,10 @@ Editor::add_location_from_playhead_cursor ()
Location *location = new Location (where, where, "mark", Location::IsMark);
session->begin_reversible_command (_("add marker"));
- session->add_undo (session->locations()->get_memento());
+ XMLNode &before = session->locations()->get_state();
session->locations()->add (location, true);
- session->add_redo_no_execute (session->locations()->get_memento());
+ XMLNode &after = session->locations()->get_state();
+ session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
session->commit_reversible_command ();
}
@@ -1321,9 +1330,10 @@ Editor::add_location_from_audio_region ()
Location *location = new Location (region.position(), region.last_frame(), region.name());
session->begin_reversible_command (_("add marker"));
- session->add_undo (session->locations()->get_memento());
+ XMLNode &before = session->locations()->get_state();
session->locations()->add (location, true);
- session->add_redo_no_execute (session->locations()->get_memento());
+ XMLNode &after = session->locations()->get_state();
+ session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
session->commit_reversible_command ();
}
@@ -1739,9 +1749,10 @@ Editor::clear_markers ()
{
if (session) {
session->begin_reversible_command (_("clear markers"));
- session->add_undo (session->locations()->get_memento());
+ XMLNode &before = session->locations()->get_state();
session->locations()->clear_markers ();
- session->add_redo_no_execute (session->locations()->get_memento());
+ XMLNode &after = session->locations()->get_state();
+ session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
session->commit_reversible_command ();
}
}
@@ -1751,7 +1762,7 @@ Editor::clear_ranges ()
{
if (session) {
session->begin_reversible_command (_("clear ranges"));
- session->add_undo (session->locations()->get_memento());
+ XMLNode &before = session->locations()->get_state();
Location * looploc = session->locations()->auto_loop_location();
Location * punchloc = session->locations()->auto_punch_location();
@@ -1761,7 +1772,8 @@ Editor::clear_ranges ()
if (looploc) session->locations()->add (looploc);
if (punchloc) session->locations()->add (punchloc);
- session->add_redo_no_execute (session->locations()->get_memento());
+ XMLNode &after = session->locations()->get_state();
+ session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
session->commit_reversible_command ();
}
}
@@ -1770,9 +1782,10 @@ void
Editor::clear_locations ()
{
session->begin_reversible_command (_("clear locations"));
- session->add_undo (session->locations()->get_memento());
+ XMLNode &before = session->locations()->get_state();
session->locations()->clear ();
- session->add_redo_no_execute (session->locations()->get_memento());
+ XMLNode &after = session->locations()->get_state();
+ session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
session->commit_reversible_command ();
session->locations()->clear ();
}
@@ -1820,9 +1833,9 @@ Editor::insert_region_list_drag (AudioRegion& region, int x, int y)
snap_to (where);
begin_reversible_command (_("insert dragged region"));
- session->add_undo (playlist->get_memento());
+ XMLNode &before = playlist->get_state();
playlist->add_region (*(new AudioRegion (region)), where, 1.0);
- session->add_redo_no_execute (playlist->get_memento());
+ session->add_command(new MementoCommand<Playlist>(*playlist, before, playlist->get_state()));
commit_reversible_command ();
}
@@ -1856,9 +1869,9 @@ Editor::insert_region_list_selection (float times)
Region* region = (*i)[region_list_columns.region];
begin_reversible_command (_("insert region"));
- session->add_undo (playlist->get_memento());
+ XMLNode &before = playlist->get_state();
playlist->add_region (*(createRegion (*region)), edit_cursor->current_frame, times);
- session->add_redo_no_execute (playlist->get_memento());
+ session->add_command(new MementoCommand<Playlist>(*playlist, before, playlist->get_state()));
commit_reversible_command ();
}
@@ -2282,7 +2295,9 @@ Editor::separate_region_from_selection ()
begin_reversible_command (_("separate"));
doing_undo = true;
}
- if (doing_undo) session->add_undo ((playlist)->get_memento());
+ XMLNode *before;
+ if (doing_undo)
+ before = &(playlist->get_state());
/* XXX need to consider musical time selections here at some point */
@@ -2292,7 +2307,8 @@ Editor::separate_region_from_selection ()
playlist->partition ((jack_nframes_t)((*t).start * speed), (jack_nframes_t)((*t).end * speed), true);
}
- if (doing_undo) session->add_redo_no_execute (playlist->get_memento());
+ if (doing_undo)
+ session->add_command(new MementoCommand<Playlist>(*playlist, *before, playlist->get_state()));
}
}
}
@@ -2327,11 +2343,14 @@ Editor::separate_regions_using_location (Location& loc)
if (atv->is_audio_track()) {
if ((playlist = atv->playlist()) != 0) {
+ XMLNode *before;
if (!doing_undo) {
begin_reversible_command (_("separate"));
doing_undo = true;
}
- if (doing_undo) session->add_undo ((playlist)->get_memento());
+ if (doing_undo)
+ before = &(playlist->get_state());
+
/* XXX need to consider musical time selections here at some point */
@@ -2339,7 +2358,8 @@ Editor::separate_regions_using_location (Location& loc)
playlist->partition ((jack_nframes_t)(loc.start() * speed), (jack_nframes_t)(loc.end() * speed), true);
- if (doing_undo) session->add_redo_no_execute (playlist->get_memento());
+ if (doing_undo)
+ session->add_command(new MementoCommand<Playlist>(*playlist, *before, playlist->get_state()));
}
}
}
@@ -2410,9 +2430,10 @@ Editor::crop_region_to_selection ()
end = min (selection->time.end_frame(), start + region->length() - 1);
cnt = end - start + 1;
- session->add_undo ((*i)->get_memento());
+ XMLNode &before = (*i)->get_state();
region->trim_to (start, cnt, this);
- session->add_redo_no_execute ((*i)->get_memento());
+ XMLNode &after = (*i)->get_state();
+ session->add_command (new MementoCommand<Playlist>(*(*i), before, after));
}
commit_reversible_command ();
@@ -2453,9 +2474,9 @@ Editor::region_fill_track ()
return;
}
- session->add_undo (pl->get_memento());
+ XMLNode &before = pl->get_state();
pl->add_region (*(new AudioRegion (*ar)), ar->last_frame(), times);
- session->add_redo_no_execute (pl->get_memento());
+ session->add_command (new MementoCommand<Playlist>(*pl, before, pl->get_state()));
}
commit_reversible_command ();
@@ -2503,9 +2524,9 @@ Editor::region_fill_selection ()
continue;
}
- session->add_undo (playlist->get_memento());
+ XMLNode &before = playlist->get_state();
playlist->add_region (*(createRegion (*region)), start, times);
- session->add_redo_no_execute (playlist->get_memento());
+ session->add_command (new MementoCommand<Playlist>(*playlist, before, playlist->get_state()));
}
commit_reversible_command ();
@@ -2520,9 +2541,10 @@ Editor::set_a_regions_sync_position (Region& region, jack_nframes_t position)
return;
}
begin_reversible_command (_("set region sync position"));
- session->add_undo (region.playlist()->get_memento());
+ XMLNode &before = region.playlist()->get_state();
region.set_sync_position (position);
- session->add_redo_no_execute (region.playlist()->get_memento());
+ XMLNode &after = region.playlist()->get_state();
+ session->add_command(new MementoCommand<Playlist>(*(region.playlist()), before, after));
commit_reversible_command ();
}
@@ -2540,9 +2562,10 @@ Editor::set_region_sync_from_edit_cursor ()
Region& region (clicked_regionview->region());
begin_reversible_command (_("set sync from edit cursor"));
- session->add_undo (region.playlist()->get_memento());
+ XMLNode &before = region.playlist()->get_state();
region.set_sync_position (edit_cursor->current_frame);
- session->add_redo_no_execute (region.playlist()->get_memento());
+ XMLNode &after = region.playlist()->get_state();
+ session->add_command(new MementoCommand<Playlist>(*(region.playlist()), before, after));
commit_reversible_command ();
}
@@ -2552,9 +2575,10 @@ Editor::remove_region_sync ()
if (clicked_regionview) {
Region& region (clicked_regionview->region());
begin_reversible_command (_("remove sync"));
- session->add_undo (region.playlist()->get_memento());
+ XMLNode &before = region.playlist()->get_state();
region.clear_sync_position ();
- session->add_redo_no_execute (region.playlist()->get_memento());
+ XMLNode &after = region.playlist()->get_state();
+ session->add_command(new MementoCommand<Playlist>(*(region.playlist()), before, after));
commit_reversible_command ();
}
}
@@ -2567,9 +2591,10 @@ Editor::naturalize ()
}
begin_reversible_command (_("naturalize"));
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
- session->add_undo ((*i)->region().get_memento());
+ XMLNode &before = (*i)->region().get_state();
(*i)->region().move_to_natural_position (this);
- session->add_redo_no_execute ((*i)->region().get_memento());
+ XMLNode &after = (*i)->region().get_state();
+ session->add_command (new MementoCommand<Region>((*i)->region(), before, after));
}
commit_reversible_command ();
}
@@ -2635,7 +2660,7 @@ Editor::align_selection_relative (RegionPoint point, jack_nframes_t position)
Region& region ((*i)->region());
- session->add_undo (region.playlist()->get_memento());
+ XMLNode &before = region.playlist()->get_state();
if (dir > 0) {
region.set_position (region.position() + distance, this);
@@ -2643,7 +2668,8 @@ Editor::align_selection_relative (RegionPoint point, jack_nframes_t position)
region.set_position (region.position() - distance, this);
}
- session->add_redo_no_execute (region.playlist()->get_memento());
+ XMLNode &after = region.playlist()->get_state();
+ session->add_command(new MementoCommand<Playlist>(*(region.playlist()), before, after));
}
@@ -2677,7 +2703,7 @@ Editor::align_region (Region& region, RegionPoint point, jack_nframes_t position
void
Editor::align_region_internal (Region& region, RegionPoint point, jack_nframes_t position)
{
- session->add_undo (region.playlist()->get_memento());
+ XMLNode &before = region.playlist()->get_state();
switch (point) {
case SyncPoint:
@@ -2695,7 +2721,8 @@ Editor::align_region_internal (Region& region, RegionPoint point, jack_nframes_t
break;
}
- session->add_redo_no_execute (region.playlist()->get_memento());
+ XMLNode &after = region.playlist()->get_state();
+ session->add_command(new MementoCommand<Playlist>(*(region.playlist()), before, after));
}
void
@@ -2717,9 +2744,10 @@ Editor::trim_region_to_edit_cursor ()
}
begin_reversible_command (_("trim to edit"));
- session->add_undo (region.playlist()->get_memento());
+ XMLNode &before = region.playlist()->get_state();
region.trim_end( session_frame_to_track_frame(edit_cursor->current_frame, speed), this);
- session->add_redo_no_execute (region.playlist()->get_memento());
+ XMLNode &after = region.playlist()->get_state();
+ session->add_command(new MementoCommand<Playlist>(*(region.playlist()), before, after));
commit_reversible_command ();
}
@@ -2742,9 +2770,10 @@ Editor::trim_region_from_edit_cursor ()
}
begin_reversible_command (_("trim to edit"));
- session->add_undo (region.playlist()->get_memento());
+ XMLNode &before = region.playlist()->get_state();
region.trim_front ( session_frame_to_track_frame(edit_cursor->current_frame, speed), this);
- session->add_redo_no_execute (region.playlist()->get_memento());
+ XMLNode &after = region.playlist()->get_state();
+ session->add_command(new MementoCommand<Playlist>(*(region.playlist()), before, after));
commit_reversible_command ();
}
@@ -2856,9 +2885,10 @@ Editor::bounce_range_selection ()
itt.cancel = false;
itt.progress = false;
- session->add_undo (playlist->get_memento());
+ XMLNode &before = playlist->get_state();
atv->audio_track()->bounce_range (start, cnt, itt);
- session->add_redo_no_execute (playlist->get_memento());
+ XMLNode &after = playlist->get_state();
+ session->add_command (new MementoCommand<Playlist> (*playlist, before, after));
}
commit_reversible_command ();
@@ -2976,7 +3006,7 @@ Editor::cut_copy_regions (CutCopyOp op)
insert_result = freezelist.insert (pl);
if (insert_result.second) {
pl->freeze ();
- session->add_undo (pl->get_memento());
+ session->add_command (new MementoUndoCommand<Playlist>(*pl, pl->get_state()));
}
}
}
@@ -3040,7 +3070,7 @@ Editor::cut_copy_regions (CutCopyOp op)
for (set<Playlist*>::iterator pl = freezelist.begin(); pl != freezelist.end(); ++pl) {
(*pl)->thaw ();
- session->add_redo_no_execute ((*pl)->get_memento());
+ session->add_command (new MementoRedoCommand<Playlist>(*(*pl), (*pl)->get_state()));
}
}
@@ -3153,9 +3183,9 @@ Editor::paste_named_selection (float times)
tmp = chunk;
++tmp;
- session->add_undo (apl->get_memento());
+ XMLNode &before = apl->get_state();
apl->paste (**chunk, edit_cursor->current_frame, times);
- session->add_redo_no_execute (apl->get_memento());
+ session->add_command(new MementoCommand<AudioPlaylist>(*apl, before, apl->get_state()));
if (tmp != ns->playlists.end()) {
chunk = tmp;
@@ -3184,9 +3214,9 @@ Editor::duplicate_some_regions (RegionSelection& regions, float times)
sigc::connection c = atv->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
playlist = (*i)->region().playlist();
- session->add_undo (playlist->get_memento());
+ XMLNode &before = playlist->get_state();
playlist->duplicate (r, r.last_frame(), times);
- session->add_redo_no_execute (playlist->get_memento());
+ session->add_command(new MementoCommand<Playlist>(*playlist, before, playlist->get_state()));
c.disconnect ();
@@ -3224,9 +3254,10 @@ Editor::duplicate_selection (float times)
if ((playlist = (*i)->playlist()) == 0) {
continue;
}
- session->add_undo (playlist->get_memento());
+ XMLNode &before = playlist->get_state();
playlist->duplicate (**ri, selection->time[clicked_selection].end, times);
- session->add_redo_no_execute (playlist->get_memento());
+ XMLNode &after = playlist->get_state();
+ session->add_command (new MementoCommand<Playlist>(*playlist, before, after));
++ri;
if (ri == new_regions.end()) {
@@ -3274,9 +3305,10 @@ void
Editor::clear_playlist (Playlist& playlist)
{
begin_reversible_command (_("clear playlist"));
- session->add_undo (playlist.get_memento());
+ XMLNode &before = playlist.get_state();
playlist.clear ();
- session->add_redo_no_execute (playlist.get_memento());
+ XMLNode &after = playlist.get_state();
+ session->add_command (new MementoCommand<Playlist>(playlist, before, after));
commit_reversible_command ();
}
@@ -3310,9 +3342,10 @@ Editor::nudge_track (bool use_edit_cursor, bool forwards)
continue;
}
- session->add_undo (playlist->get_memento());
+ XMLNode &before = playlist->get_state();
playlist->nudge_after (start, distance, forwards);
- session->add_redo_no_execute (playlist->get_memento());
+ XMLNode &after = playlist->get_state();
+ session->add_command (new MementoCommand<Playlist>(*playlist, before, after));
}
commit_reversible_command ();
@@ -3366,9 +3399,9 @@ Editor::normalize_region ()
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r);
if (!arv)
continue;
- session->add_undo (arv->region().get_memento());
+ XMLNode &before = arv->region().get_state();
arv->audio_region().normalize_to (0.0f);
- session->add_redo_no_execute (arv->region().get_memento());
+ session->add_command (new MementoCommand<Region>(arv->region(), before, arv->region().get_state()));
}
commit_reversible_command ();
@@ -3393,9 +3426,9 @@ Editor::denormalize_region ()
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r);
if (!arv)
continue;
- session->add_undo (arv->region().get_memento());
+ XMLNode &before = arv->region().get_state();
arv->audio_region().set_scale_amplitude (1.0f);
- session->add_redo_no_execute (arv->region().get_memento());
+ session->add_command (new MementoCommand<Region>(arv->region(), before, arv->region().get_state()));
}
commit_reversible_command ();
@@ -3439,9 +3472,10 @@ Editor::apply_filter (AudioFilter& filter, string command)
if (arv->audio_region().apply (filter) == 0) {
- session->add_undo (playlist->get_memento());
+ XMLNode &before = playlist->get_state();
playlist->replace_region (arv->region(), *(filter.results.front()), arv->region().position());
- session->add_redo_no_execute (playlist->get_memento());
+ XMLNode &after = playlist->get_state();
+ session->add_command(new MementoCommand<Playlist>(*playlist, before, after));
} else {
goto out;
}
diff --git a/gtk2_ardour/editor_tempodisplay.cc b/gtk2_ardour/editor_tempodisplay.cc
index 5f998ada9f..9f7fe7cf09 100644
--- a/gtk2_ardour/editor_tempodisplay.cc
+++ b/gtk2_ardour/editor_tempodisplay.cc
@@ -27,6 +27,7 @@
#include <libgnomecanvasmm.h>
#include <pbd/error.h>
+#include <pbd/memento_command.h>
#include <gtkmm2ext/utils.h>
#include <gtkmm2ext/gtk_ui.h>
@@ -273,9 +274,10 @@ Editor::mouse_add_new_tempo_event (jack_nframes_t frame)
tempo_dialog.get_bbt_time (requested);
begin_reversible_command (_("add tempo mark"));
- session->add_undo (map.get_memento());
+ XMLNode &before = map.get_state();
map.add_tempo (Tempo (bpm), requested);
- session->add_redo_no_execute (map.get_memento());
+ XMLNode &after = map.get_state();
+ session->add_command(new MementoCommand<TempoMap>(map, before, after));
commit_reversible_command ();
map.dump (cerr);
@@ -313,9 +315,9 @@ Editor::mouse_add_new_meter_event (jack_nframes_t frame)
meter_dialog.get_bbt_time (requested);
begin_reversible_command (_("add meter mark"));
- session->add_undo (map.get_memento());
+ XMLNode &before = map.get_state();
map.add_meter (Meter (bpb, note_type), requested);
- session->add_redo_no_execute (map.get_memento());
+ session->add_command(new MementoCommand<TempoMap>(map, before, map.get_state()));
commit_reversible_command ();
map.dump (cerr);
@@ -364,9 +366,10 @@ Editor::edit_meter_section (MeterSection* section)
double note_type = meter_dialog.get_note_type ();
begin_reversible_command (_("replace tempo mark"));
- session->add_undo (session->tempo_map().get_memento());
+ XMLNode &before = session->tempo_map().get_state();
session->tempo_map().replace_meter (*section, Meter (bpb, note_type));
- session->add_redo_no_execute (session->tempo_map().get_memento());
+ XMLNode &after = session->tempo_map().get_state();
+ session->add_command(new MementoCommand<TempoMap>(session->tempo_map(), before, after));
commit_reversible_command ();
}
@@ -392,10 +395,11 @@ Editor::edit_tempo_section (TempoSection* section)
bpm = max (0.01, bpm);
begin_reversible_command (_("replace tempo mark"));
- session->add_undo (session->tempo_map().get_memento());
+ XMLNode &before = session->tempo_map().get_state();
session->tempo_map().replace_tempo (*section, Tempo (bpm));
session->tempo_map().move_tempo (*section, when);
- session->add_redo_no_execute (session->tempo_map().get_memento());
+ XMLNode &after = session->tempo_map().get_state();
+ session->add_command (new MementoCommand<TempoMap>(session->tempo_map(), before, after));
commit_reversible_command ();
}
@@ -441,9 +445,10 @@ gint
Editor::real_remove_tempo_marker (TempoSection *section)
{
begin_reversible_command (_("remove tempo mark"));
- session->add_undo (session->tempo_map().get_memento());
+ XMLNode &before = session->tempo_map().get_state();
session->tempo_map().remove_tempo (*section);
- session->add_redo_no_execute (session->tempo_map().get_memento());
+ XMLNode &after = session->tempo_map().get_state();
+ session->add_command(new MementoCommand<TempoMap>(session->tempo_map(), before, after));
commit_reversible_command ();
return FALSE;
@@ -474,9 +479,10 @@ gint
Editor::real_remove_meter_marker (MeterSection *section)
{
begin_reversible_command (_("remove tempo mark"));
- session->add_undo (session->tempo_map().get_memento());
+ XMLNode &before = session->tempo_map().get_state();
session->tempo_map().remove_meter (*section);
- session->add_redo_no_execute (session->tempo_map().get_memento());
+ XMLNode &after = session->tempo_map().get_state();
+ session->add_command(new MementoCommand<TempoMap>(session->tempo_map(), before, after));
commit_reversible_command ();
return FALSE;
}
diff --git a/gtk2_ardour/editor_timefx.cc b/gtk2_ardour/editor_timefx.cc
index 79772090f6..3fe0023d07 100644
--- a/gtk2_ardour/editor_timefx.cc
+++ b/gtk2_ardour/editor_timefx.cc
@@ -25,6 +25,7 @@
#include <pbd/error.h>
#include <pbd/pthread_utils.h>
+#include <pbd/memento_command.h>
#include "editor.h"
#include "audio_time_axis.h"
@@ -206,9 +207,10 @@ Editor::do_timestretch (TimeStretchDialog& dialog)
return;
}
- session->add_undo (playlist->get_memento());
+ XMLNode &before = playlist->get_state();
playlist->replace_region (region, *new_region, region.position());
- session->add_redo_no_execute (playlist->get_memento());
+ XMLNode &after = playlist->get_state();
+ session->add_command (new MementoCommand<Playlist>(*playlist, before, after));
i = tmp;
}
diff --git a/gtk2_ardour/gain_automation_time_axis.cc b/gtk2_ardour/gain_automation_time_axis.cc
index 5352015f11..c86c1390f3 100644
--- a/gtk2_ardour/gain_automation_time_axis.cc
+++ b/gtk2_ardour/gain_automation_time_axis.cc
@@ -20,6 +20,7 @@
#include <ardour/curve.h>
#include <ardour/route.h>
+#include <pbd/memento_command.h>
#include "gain_automation_time_axis.h"
#include "automation_line.h"
@@ -63,9 +64,10 @@ GainAutomationTimeAxisView::add_automation_event (ArdourCanvas::Item* item, GdkE
_session.begin_reversible_command (_("add gain automation event"));
- _session.add_undo (curve.get_memento());
+ XMLNode &before = curve.get_state();
curve.add (when, y);
- _session.add_redo_no_execute (curve.get_memento());
+ XMLNode &after = curve.get_state();
+ _session.add_command(new MementoCommand<ARDOUR::Curve>(curve, before, after));
_session.commit_reversible_command ();
_session.set_dirty ();
}
diff --git a/gtk2_ardour/location_ui.cc b/gtk2_ardour/location_ui.cc
index f0fe230b57..deb4c1da36 100644
--- a/gtk2_ardour/location_ui.cc
+++ b/gtk2_ardour/location_ui.cc
@@ -27,6 +27,7 @@
#include <ardour/utils.h>
#include <ardour/configuration.h>
#include <ardour/session.h>
+#include <pbd/memento_command.h>
#include "ardour_ui.h"
#include "prompter.h"
@@ -654,9 +655,10 @@ gint LocationUI::do_location_remove (ARDOUR::Location *loc)
}
session->begin_reversible_command (_("remove marker"));
- session->add_undo (session->locations()->get_memento());
+ XMLNode &before = session->locations()->get_state();
session->locations()->remove (loc);
- session->add_redo_no_execute (session->locations()->get_memento());
+ XMLNode &after = session->locations()->get_state();
+ session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
session->commit_reversible_command ();
return FALSE;
@@ -772,9 +774,10 @@ LocationUI::add_new_location()
jack_nframes_t where = session->audible_frame();
Location *location = new Location (where, where, "mark", Location::IsMark);
session->begin_reversible_command (_("add marker"));
- session->add_undo (session->locations()->get_memento());
+ XMLNode &before = session->locations()->get_state();
session->locations()->add (location, true);
- session->add_redo_no_execute (session->locations()->get_memento());
+ XMLNode &after = session->locations()->get_state();
+ session->add_command (new MementoCommand<Locations>(*(session->locations()), before, after));
session->commit_reversible_command ();
}
@@ -788,9 +791,10 @@ LocationUI::add_new_range()
Location *location = new Location (where, where, "unnamed",
Location::IsRangeMarker);
session->begin_reversible_command (_("add range marker"));
- session->add_undo (session->locations()->get_memento());
+ XMLNode &before = session->locations()->get_state();
session->locations()->add (location, true);
- session->add_redo_no_execute (session->locations()->get_memento());
+ XMLNode &after = session->locations()->get_state();
+ session->add_command (new MementoCommand<Locations>(*(session->locations()), before, after));
session->commit_reversible_command ();
}
}
diff --git a/gtk2_ardour/pan_automation_time_axis.cc b/gtk2_ardour/pan_automation_time_axis.cc
index 34426c127f..3169f65059 100644
--- a/gtk2_ardour/pan_automation_time_axis.cc
+++ b/gtk2_ardour/pan_automation_time_axis.cc
@@ -23,6 +23,7 @@
#include <ardour/panner.h>
#include <gtkmm2ext/popup.h>
+#include <pbd/memento_command.h>
#include "pan_automation_time_axis.h"
#include "automation_line.h"
@@ -88,9 +89,10 @@ PanAutomationTimeAxisView::add_automation_event (ArdourCanvas::Item* item, GdkEv
AutomationList& alist (lines[line_index]->the_list());
_session.begin_reversible_command (_("add pan automation event"));
- _session.add_undo (alist.get_memento());
+ XMLNode &before = alist.get_state();
alist.add (when, y);
- _session.add_redo_no_execute (alist.get_memento());
+ XMLNode &after = alist.get_state();
+ _session.add_command(new MementoCommand<AutomationList>(alist, before, after));
_session.commit_reversible_command ();
_session.set_dirty ();
}
diff --git a/gtk2_ardour/redirect_automation_time_axis.cc b/gtk2_ardour/redirect_automation_time_axis.cc
index a53c1a20e4..e527fd1d5e 100644
--- a/gtk2_ardour/redirect_automation_time_axis.cc
+++ b/gtk2_ardour/redirect_automation_time_axis.cc
@@ -21,6 +21,7 @@
#include <ardour/redirect.h>
#include <ardour/session.h>
#include <cstdlib>
+#include <pbd/memento_command.h>
#include "redirect_automation_time_axis.h"
#include "automation_line.h"
@@ -98,9 +99,10 @@ RedirectAutomationTimeAxisView::add_automation_event (ArdourCanvas::Item* item,
lines.front()->view_to_model_y (y);
_session.begin_reversible_command (description);
- _session.add_undo (alist.get_memento());
+ XMLNode &before = alist.get_state();
alist.add (when, y);
- _session.add_redo_no_execute (alist.get_memento());
+ XMLNode &after = alist.get_state();
+ _session.add_command(new MementoCommand<AutomationList>(alist, before, after));
_session.commit_reversible_command ();
_session.set_dirty ();
}
diff --git a/gtk2_ardour/region_editor.h b/gtk2_ardour/region_editor.h
index 176ced0792..70590b0db5 100644
--- a/gtk2_ardour/region_editor.h
+++ b/gtk2_ardour/region_editor.h
@@ -15,7 +15,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id: region_editor.h 231 2006-01-03 14:16:27Z karstenweise $
+ $Id: /local/undo/gtk2_ardour/region_editor.h 5 2006-05-31T02:48:48.738745Z paul $
*/
#ifndef __gtk_ardour_region_edit_h__
diff --git a/gtk2_ardour/region_gain_line.cc b/gtk2_ardour/region_gain_line.cc
index a542be054e..0a4a3d29ea 100644
--- a/gtk2_ardour/region_gain_line.cc
+++ b/gtk2_ardour/region_gain_line.cc
@@ -1,5 +1,6 @@
#include <ardour/curve.h>
#include <ardour/audioregion.h>
+#include <pbd/memento_command.h>
#include "region_gain_line.h"
#include "audio_region_view.h"
@@ -47,7 +48,8 @@ AudioRegionGainLine::start_drag (ControlPoint* cp, float fraction)
{
AutomationLine::start_drag(cp,fraction);
if (!rv.audio_region().envelope_active()) {
- trackview.session().add_undo( bind( mem_fun(rv.audio_region(), &AudioRegion::set_envelope_active), false) );
+ trackview.session().add_command(new MementoUndoCommand<AudioRegion>(rv.audio_region(), rv.audio_region().get_state()));
+ rv.audio_region().set_envelope_active(false);
}
}
@@ -60,17 +62,18 @@ AudioRegionGainLine::remove_point (ControlPoint& cp)
model_representation (cp, mr);
trackview.editor.current_session()->begin_reversible_command (_("remove control point"));
- trackview.editor.current_session()->add_undo (get_memento());
+ XMLNode &before = get_state();
if (!rv.audio_region().envelope_active()) {
- trackview.session().add_undo( bind( mem_fun(rv.audio_region(), &AudioRegion::set_envelope_active), false) );
- trackview.session().add_redo( bind( mem_fun(rv.audio_region(), &AudioRegion::set_envelope_active), true) );
+ XMLNode &before = rv.audio_region().get_state();
rv.audio_region().set_envelope_active(true);
+ XMLNode &after = rv.audio_region().get_state();
+ trackview.session().add_command(new MementoCommand<AudioRegion>(rv.audio_region(), before, after));
}
alist.erase (mr.start, mr.end);
- trackview.editor.current_session()->add_redo_no_execute (get_memento());
+ trackview.editor.current_session()->add_command (new MementoCommand<AudioRegionGainLine>(*this, before, get_state()));
trackview.editor.current_session()->commit_reversible_command ();
trackview.editor.current_session()->set_dirty ();
}
@@ -79,8 +82,8 @@ void
AudioRegionGainLine::end_drag (ControlPoint* cp)
{
if (!rv.audio_region().envelope_active()) {
- trackview.session().add_redo( bind( mem_fun(rv.audio_region(), &AudioRegion::set_envelope_active), true) );
rv.audio_region().set_envelope_active(true);
+ trackview.session().add_command(new MementoRedoCommand<AudioRegion>(rv.audio_region(), rv.audio_region().get_state()));
}
AutomationLine::end_drag(cp);
}
diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc
index 8dca7be480..82d5b53cba 100644
--- a/gtk2_ardour/route_time_axis.cc
+++ b/gtk2_ardour/route_time_axis.cc
@@ -29,6 +29,7 @@
#include <pbd/error.h>
#include <pbd/stl_delete.h>
#include <pbd/whitespace.h>
+#include <pbd/memento_command.h>
#include <gtkmm/menu.h>
#include <gtkmm/menuitem.h>
@@ -1050,12 +1051,12 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
}
}
+ XMLNode &before = playlist->get_state();
switch (op) {
case Cut:
- _session.add_undo (playlist->get_memento());
if ((what_we_got = playlist->cut (time)) != 0) {
editor.get_cut_buffer().add (what_we_got);
- _session.add_redo_no_execute (playlist->get_memento());
+ _session.add_command( new MementoCommand<Playlist>(*playlist, before, playlist->get_state()));
ret = true;
}
break;
@@ -1066,9 +1067,8 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op)
break;
case Clear:
- _session.add_undo (playlist->get_memento());
if ((what_we_got = playlist->cut (time)) != 0) {
- _session.add_redo_no_execute (playlist->get_memento());
+ _session.add_command( new MementoCommand<Playlist>(*playlist, before, playlist->get_state()));
what_we_got->unref ();
ret = true;
}
@@ -1097,9 +1097,9 @@ RouteTimeAxisView::paste (jack_nframes_t pos, float times, Selection& selection,
if (get_diskstream()->speed() != 1.0f)
pos = session_frame_to_track_frame(pos, get_diskstream()->speed() );
- _session.add_undo (playlist->get_memento());
+ XMLNode &before = playlist->get_state();
playlist->paste (**p, pos, times);
- _session.add_redo_no_execute (playlist->get_memento());
+ _session.add_command( new MementoCommand<Playlist>(*playlist, before, playlist->get_state()));
return true;
}
diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc
index eaf28470da..863e73d33e 100644
--- a/gtk2_ardour/route_ui.cc
+++ b/gtk2_ardour/route_ui.cc
@@ -25,6 +25,7 @@
#include <gtkmm2ext/bindable_button.h>
#include <ardour/route_group.h>
+#include <pbd/memento_command.h>
#include "route_ui.h"
#include "keyboard.h"
@@ -128,9 +129,10 @@ RouteUI::mute_press(GdkEventButton* ev)
/* ctrl-shift-click applies change to all routes */
_session.begin_reversible_command (_("mute change"));
- _session.add_undo (_session.global_mute_memento(this));
+ Session::GlobalMuteStateCommand *cmd = new Session::GlobalMuteStateCommand(_session, this);
_session.set_all_mute (!_route->muted());
- _session.add_redo_no_execute (_session.global_mute_memento(this));
+ cmd->mark();
+ _session.add_command(cmd);
_session.commit_reversible_command ();
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
@@ -203,9 +205,10 @@ RouteUI::solo_press(GdkEventButton* ev)
/* ctrl-shift-click applies change to all routes */
_session.begin_reversible_command (_("solo change"));
- _session.add_undo (_session.global_solo_memento(this));
+ Session::GlobalSoloStateCommand *cmd = new Session::GlobalSoloStateCommand(_session, this);
_session.set_all_solo (!_route->soloed());
- _session.add_redo_no_execute (_session.global_solo_memento(this));
+ cmd->mark();
+ _session.add_command (cmd);
_session.commit_reversible_command ();
} else if (Keyboard::modifier_state_contains (ev->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Alt))) {
@@ -213,10 +216,11 @@ RouteUI::solo_press(GdkEventButton* ev)
// ctrl-alt-click: exclusively solo this track, not a toggle */
_session.begin_reversible_command (_("solo change"));
- _session.add_undo (_session.global_solo_memento(this));
+ Session::GlobalSoloStateCommand *cmd = new Session::GlobalSoloStateCommand (_session, this);
_session.set_all_solo (false);
_route->set_solo (true, this);
- _session.add_redo_no_execute (_session.global_solo_memento(this));
+ cmd->mark();
+ _session.add_command(cmd);
_session.commit_reversible_command ();
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Shift)) {
@@ -276,7 +280,7 @@ RouteUI::rec_enable_press(GdkEventButton* ev)
else if (Keyboard::modifier_state_equals (ev->state, Keyboard::ModifierMask (Keyboard::Control|Keyboard::Shift))) {
_session.begin_reversible_command (_("rec-enable change"));
- _session.add_undo (_session.global_record_enable_memento(this));
+ Session::GlobalRecordEnableStateCommand *cmd = new Session::GlobalRecordEnableStateCommand(_session, this);
if (rec_enable_button->get_active()) {
_session.record_disenable_all ();
@@ -284,7 +288,8 @@ RouteUI::rec_enable_press(GdkEventButton* ev)
_session.record_enable_all ();
}
- _session.add_redo_no_execute (_session.global_record_enable_memento(this));
+ cmd->mark();
+ _session.add_command(cmd);
_session.commit_reversible_command ();
} else if (Keyboard::modifier_state_equals (ev->state, Keyboard::Control)) {
@@ -553,9 +558,10 @@ RouteUI::set_mix_group_solo(boost::shared_ptr<Route> route, bool yn)
if((mix_group = route->mix_group()) != 0){
_session.begin_reversible_command (_("mix group solo change"));
- _session.add_undo (_session.global_solo_memento (this));
+ Session::GlobalSoloStateCommand *cmd = new Session::GlobalSoloStateCommand(_session, this);
mix_group->apply(&Route::set_solo, yn, this);
- _session.add_redo_no_execute (_session.global_solo_memento(this));
+ cmd->mark();
+ _session.add_command (cmd);
_session.commit_reversible_command ();
} else {
reversibly_apply_route_boolean ("solo change", &Route::set_solo, !route->soloed(), this);
@@ -566,8 +572,10 @@ void
RouteUI::reversibly_apply_route_boolean (string name, void (Route::*func)(bool, void *), bool yn, void *arg)
{
_session.begin_reversible_command (name);
- _session.add_undo (bind (mem_fun (*_route, func), !yn, (void *) arg));
- _session.add_redo (bind (mem_fun (*_route, func), yn, (void *) arg));
+ XMLNode &before = _route->get_state();
+ bind(mem_fun(*_route, func), yn, arg)();
+ XMLNode &after = _route->get_state();
+ _session.add_command (new MementoCommand<Route>(*_route, before, after));
_session.commit_reversible_command ();
}
@@ -575,8 +583,10 @@ void
RouteUI::reversibly_apply_audio_track_boolean (string name, void (AudioTrack::*func)(bool, void *), bool yn, void *arg)
{
_session.begin_reversible_command (name);
- _session.add_undo (bind (mem_fun (*audio_track(), func), !yn, (void *) arg));
- _session.add_redo (bind (mem_fun (*audio_track(), func), yn, (void *) arg));
+ XMLNode &before = audio_track()->get_state();
+ bind (mem_fun (*audio_track(), func), yn, arg)();
+ XMLNode &after = audio_track()->get_state();
+ _session.add_command (new MementoCommand<AudioTrack>(*audio_track(), before, after));
_session.commit_reversible_command ();
}
@@ -587,9 +597,10 @@ RouteUI::set_mix_group_mute(boost::shared_ptr<Route> route, bool yn)
if((mix_group = route->mix_group()) != 0){
_session.begin_reversible_command (_("mix group mute change"));
- _session.add_undo (_session.global_mute_memento (this));
+ Session::GlobalMuteStateCommand *cmd = new Session::GlobalMuteStateCommand (_session, this);
mix_group->apply(&Route::set_mute, yn, this);
- _session.add_redo_no_execute (_session.global_mute_memento(this));
+ cmd->mark();
+ _session.add_command(cmd);
_session.commit_reversible_command ();
} else {
reversibly_apply_route_boolean ("mute change", &Route::set_mute, !route->muted(), this);
@@ -603,9 +614,10 @@ RouteUI::set_mix_group_rec_enable(boost::shared_ptr<Route> route, bool yn)
if((mix_group = route->mix_group()) != 0){
_session.begin_reversible_command (_("mix group rec-enable change"));
- _session.add_undo (_session.global_record_enable_memento (this));
+ Session::GlobalRecordEnableStateCommand *cmd = new Session::GlobalRecordEnableStateCommand(_session, this);
mix_group->apply (&Route::set_record_enable, yn, this);
- _session.add_redo_no_execute (_session.global_record_enable_memento(this));
+ cmd->mark();
+ _session.add_command(cmd);
_session.commit_reversible_command ();
} else {
reversibly_apply_route_boolean ("rec-enable change", &Route::set_record_enable, !_route->record_enabled(), this);
diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript
index 0c76699aef..44cec8638c 100644
--- a/libs/ardour/SConscript
+++ b/libs/ardour/SConscript
@@ -77,6 +77,7 @@ send.cc
session.cc
session_butler.cc
session_click.cc
+session_command.cc
session_events.cc
session_export.cc
session_midi.cc
diff --git a/libs/ardour/ardour/automation_event.h b/libs/ardour/ardour/automation_event.h
index 78daa531dd..1fa29d4adf 100644
--- a/libs/ardour/ardour/automation_event.h
+++ b/libs/ardour/ardour/automation_event.h
@@ -51,7 +51,7 @@ struct ControlEvent {
};
-class AutomationList : public StateManager
+class AutomationList : public StateManager, public Stateful
{
public:
typedef std::list<ControlEvent*> AutomationEventList;
@@ -153,6 +153,9 @@ class AutomationList : public StateManager
virtual void store_state (XMLNode& node) const;
virtual void load_state (const XMLNode&);
+ XMLNode &get_state(void);
+ int set_state (const XMLNode &s);
+
void set_max_xval (double);
double get_max_xval() const { return max_xval; }
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 8d10d9f598..0c53cc32e7 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -489,7 +489,7 @@ class Session : public sigc::trackable, public Stateful
static vector<string*>* possible_states(string path);
XMLNode& get_state();
- int set_state(const XMLNode& node);
+ int set_state(const XMLNode& node); // not idempotent
XMLNode& get_template();
void add_instant_xml (XMLNode&, const std::string& dir);
@@ -830,23 +830,65 @@ class Session : public sigc::trackable, public Stateful
string next_undo() const { return history.next_undo(); }
string next_redo() const { return history.next_redo(); }
- void begin_reversible_command (string cmd_name, UndoAction *private_undo = 0);
- void commit_reversible_command (UndoAction* private_redo = 0);
+ void begin_reversible_command (string cmd_name);
+ void commit_reversible_command (Command* cmd = 0);
- void add_undo (const UndoAction& ua) {
- current_cmd.add_undo (ua);
- }
- void add_redo (const UndoAction& ua) {
- current_cmd.add_redo (ua);
- }
- void add_redo_no_execute (const UndoAction& ua) {
- current_cmd.add_redo_no_execute (ua);
+ void add_command (Command *const cmd) {
+ current_trans.add_command (cmd);
}
- UndoAction global_solo_memento (void *src);
- UndoAction global_mute_memento (void *src);
- UndoAction global_record_enable_memento (void *src);
- UndoAction global_metering_memento (void *src);
+ // these commands are implemented in libs/ardour/session_command.cc
+ class GlobalSoloStateCommand : public Command
+ {
+ GlobalRouteBooleanState before, after;
+ void *src;
+ Session &sess;
+ public:
+ GlobalSoloStateCommand(Session &, void *src);
+ void operator()();
+ void undo();
+ XMLNode &serialize();
+ void mark();
+ };
+
+ class GlobalMuteStateCommand : public Command
+ {
+ GlobalRouteBooleanState before, after;
+ void *src;
+ Session &sess;
+ public:
+ GlobalMuteStateCommand(Session &, void *src);
+ void operator()();
+ void undo();
+ XMLNode &serialize();
+ void mark();
+ };
+
+ class GlobalRecordEnableStateCommand : public Command
+ {
+ GlobalRouteBooleanState before, after;
+ void *src;
+ Session &sess;
+ public:
+ GlobalRecordEnableStateCommand(Session &, void *src);
+ void operator()();
+ void undo();
+ XMLNode &serialize();
+ void mark();
+ };
+
+ class GlobalMeteringStateCommand : public Command
+ {
+ GlobalRouteMeterState before, after;
+ void *src;
+ Session &sess;
+ public:
+ GlobalMeteringStateCommand(Session &, void *src);
+ void operator()();
+ void undo();
+ XMLNode &serialize();
+ void mark();
+ };
/* edit mode */
@@ -1624,7 +1666,7 @@ class Session : public sigc::trackable, public Stateful
void reverse_diskstream_buffers ();
UndoHistory history;
- UndoCommand current_cmd;
+ UndoTransaction current_trans;
GlobalRouteBooleanState get_global_route_boolean (bool (Route::*method)(void) const);
GlobalRouteMeterState get_global_route_metering ();
diff --git a/libs/ardour/audio_diskstream.cc b/libs/ardour/audio_diskstream.cc
index 7f0cb55821..7d2a2103bb 100644
--- a/libs/ardour/audio_diskstream.cc
+++ b/libs/ardour/audio_diskstream.cc
@@ -34,6 +34,7 @@
#include <pbd/basename.h>
#include <glibmm/thread.h>
#include <pbd/xml++.h>
+#include <pbd/memento_command.h>
#include <ardour/ardour.h>
#include <ardour/audioengine.h>
@@ -1594,7 +1595,7 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
// cerr << _name << ": there are " << capture_info.size() << " capture_info records\n";
- _session.add_undo (_playlist->get_memento());
+ XMLNode &before = _playlist->get_state();
_playlist->freeze ();
for (buffer_position = channels[0].write_source->last_capture_start_frame(), ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
@@ -1625,7 +1626,8 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
}
_playlist->thaw ();
- _session.add_redo_no_execute (_playlist->get_memento());
+ XMLNode &after = _playlist->get_state();
+ _session.add_command (new MementoCommand<Playlist>(*_playlist, before, after));
}
mark_write_completed = true;
diff --git a/libs/ardour/automation_event.cc b/libs/ardour/automation_event.cc
index 63492b375b..dc1767d1e7 100644
--- a/libs/ardour/automation_event.cc
+++ b/libs/ardour/automation_event.cc
@@ -1246,3 +1246,17 @@ AutomationList::load_state (const XMLNode& node)
add (x, y);
}
}
+
+XMLNode &AutomationList::get_state ()
+{
+ XMLNode *node = new XMLNode("AutomationList");
+ store_state(*node);
+ return *node;
+}
+
+int AutomationList::set_state(const XMLNode &s)
+{
+ load_state(s);
+ return 0;
+}
+
diff --git a/libs/ardour/session_command.cc b/libs/ardour/session_command.cc
new file mode 100644
index 0000000000..6482de41fb
--- /dev/null
+++ b/libs/ardour/session_command.cc
@@ -0,0 +1,93 @@
+#include <ardour/session.h>
+#include <ardour/route.h>
+
+namespace ARDOUR {
+// solo
+Session::GlobalSoloStateCommand::GlobalSoloStateCommand(Session &sess, void *src)
+ : sess(sess), src(src)
+{
+ after = before = sess.get_global_route_boolean(&Route::soloed);
+}
+void Session::GlobalSoloStateCommand::mark()
+{
+ after = sess.get_global_route_boolean(&Route::soloed);
+}
+void Session::GlobalSoloStateCommand::operator()()
+{
+ sess.set_global_solo(after, src);
+}
+void Session::GlobalSoloStateCommand::undo()
+{
+ sess.set_global_solo(before, src);
+}
+XMLNode &Session::GlobalSoloStateCommand::serialize()
+{
+}
+
+// mute
+Session::GlobalMuteStateCommand::GlobalMuteStateCommand(Session &sess, void *src)
+ : sess(sess), src(src)
+{
+ after = before = sess.get_global_route_boolean(&Route::muted);
+}
+void Session::GlobalMuteStateCommand::mark()
+{
+ after = sess.get_global_route_boolean(&Route::muted);
+}
+void Session::GlobalMuteStateCommand::operator()()
+{
+ sess.set_global_mute(after, src);
+}
+void Session::GlobalMuteStateCommand::undo()
+{
+ sess.set_global_mute(before, src);
+}
+XMLNode &Session::GlobalMuteStateCommand::serialize()
+{
+}
+
+// record enable
+Session::GlobalRecordEnableStateCommand::GlobalRecordEnableStateCommand(Session &sess, void *src)
+ : sess(sess), src(src)
+{
+ after = before = sess.get_global_route_boolean(&Route::record_enabled);
+}
+void Session::GlobalRecordEnableStateCommand::mark()
+{
+ after = sess.get_global_route_boolean(&Route::record_enabled);
+}
+void Session::GlobalRecordEnableStateCommand::operator()()
+{
+ sess.set_global_record_enable(after, src);
+}
+void Session::GlobalRecordEnableStateCommand::undo()
+{
+ sess.set_global_record_enable(before, src);
+}
+XMLNode &Session::GlobalRecordEnableStateCommand::serialize()
+{
+}
+
+// metering
+Session::GlobalMeteringStateCommand::GlobalMeteringStateCommand(Session &sess, void *src)
+ : sess(sess), src(src)
+{
+ after = before = sess.get_global_route_metering();
+}
+void Session::GlobalMeteringStateCommand::mark()
+{
+ after = sess.get_global_route_metering();
+}
+void Session::GlobalMeteringStateCommand::operator()()
+{
+ sess.set_global_route_metering(after, src);
+}
+void Session::GlobalMeteringStateCommand::undo()
+{
+ sess.set_global_route_metering(before, src);
+}
+XMLNode &Session::GlobalMeteringStateCommand::serialize()
+{
+}
+
+} // namespace ARDOUR
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index c90fd91d73..9619e77ad1 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -2569,29 +2569,25 @@ Session::set_meter_falloff (float val)
void
-Session::begin_reversible_command (string name, UndoAction* private_undo)
+Session::begin_reversible_command (string name)
{
- current_cmd.clear ();
- current_cmd.set_name (name);
-
- if (private_undo) {
- current_cmd.add_undo (*private_undo);
- }
+ current_trans.clear ();
+ current_trans.set_name (name);
}
void
-Session::commit_reversible_command (UndoAction* private_redo)
+Session::commit_reversible_command (Command *cmd)
{
struct timeval now;
- if (private_redo) {
- current_cmd.add_redo_no_execute (*private_redo);
+ if (cmd) {
+ current_trans.add_command (cmd);
}
gettimeofday (&now, 0);
- current_cmd.set_timestamp (now);
+ current_trans.set_timestamp (now);
- history.add (current_cmd);
+ history.add (current_trans);
}
Session::GlobalRouteBooleanState
@@ -2670,6 +2666,7 @@ Session::set_global_record_enable (GlobalRouteBooleanState s, void* src)
set_global_route_boolean (s, &Route::set_record_enable, src);
}
+#if 0
UndoAction
Session::global_mute_memento (void* src)
{
@@ -2693,6 +2690,7 @@ Session::global_record_enable_memento (void* src)
{
return sigc::bind (mem_fun (*this, &Session::set_global_record_enable), get_global_route_boolean (&Route::record_enabled), src);
}
+#endif
static bool
template_filter (const string &str, void *arg)
diff --git a/libs/ardour/session_transport.cc b/libs/ardour/session_transport.cc
index d850fb94c8..3bd54aa69c 100644
--- a/libs/ardour/session_transport.cc
+++ b/libs/ardour/session_transport.cc
@@ -29,6 +29,7 @@
#include <pbd/error.h>
#include <glibmm/thread.h>
#include <pbd/pthread_utils.h>
+#include <pbd/memento_command.h>
#include <midi++/mmc.h>
#include <midi++/port.h>
@@ -320,8 +321,10 @@ Session::non_realtime_stop (bool abort)
}
if (change_end) {
- add_undo (sigc::retype_return<void>(sigc::bind (mem_fun (*loc, &Location::set_end), loc->end())));
- add_redo (sigc::retype_return<void>(sigc::bind (mem_fun (*loc, &Location::set_end), _transport_frame)));
+ XMLNode &before = loc->get_state();
+ loc->set_end(_transport_frame);
+ XMLNode &after = loc->get_state();
+ add_command (new MementoCommand<Location>(*loc, before, after));
}
_end_location_is_free = false;
diff --git a/libs/pbd/SConscript b/libs/pbd/SConscript
index 36fb02885f..4b15dd70d1 100644
--- a/libs/pbd/SConscript
+++ b/libs/pbd/SConscript
@@ -21,6 +21,7 @@ pbd_files = Split("""
basename.cc
base_ui.cc
convert.cc
+command.cc
controllable.cc
dmalloc.cc
error.cc
diff --git a/libs/pbd/command.cc b/libs/pbd/command.cc
new file mode 100644
index 0000000000..3f5aca8e51
--- /dev/null
+++ b/libs/pbd/command.cc
@@ -0,0 +1,10 @@
+#include <pbd/command.h>
+
+class XMLNode;
+
+XMLNode &Command::serialize()
+{
+ XMLNode *node = new XMLNode ("Command");
+ // TODO
+ return *node;
+}
diff --git a/libs/pbd/pbd/command.h b/libs/pbd/pbd/command.h
new file mode 100644
index 0000000000..35ae011530
--- /dev/null
+++ b/libs/pbd/pbd/command.h
@@ -0,0 +1,36 @@
+/*
+ Copyright (C) 2006 Hans Fugal & Paul Davis
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ 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 80 2006-06-22T22:37:01.079855Z fugalh $
+*/
+
+#ifndef __lib_pbd_command_h__
+#define __lib_pbd_command_h__
+
+#include <pbd/serializable.h>
+
+class Command : public Serializable
+{
+ public:
+ virtual ~Command() {}
+ virtual void operator() () = 0;
+ virtual void undo() = 0;
+ virtual void redo() { (*this)(); }
+ virtual XMLNode &serialize();
+};
+
+#endif // __lib_pbd_command_h_
diff --git a/libs/pbd/pbd/memento_command.h b/libs/pbd/pbd/memento_command.h
new file mode 100644
index 0000000000..c8bfe5de4c
--- /dev/null
+++ b/libs/pbd/pbd/memento_command.h
@@ -0,0 +1,94 @@
+/*
+ Copyright (C) 2006 Hans Fugal & Paul Davis
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ 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 <pbd/command.h>
+#include <sigc++/slot.h>
+
+/** This command class is initialized with before and after mementos
+ * (from Stateful::get_state()), so undo becomes restoring the before
+ * memento, and redo is restoring the after memento.
+ */
+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 &serialize() {}
+ //{
+ // obj.id
+ // key is "MementoCommand" or something
+ // before and after mementos
+ //}
+ // 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 &serialize() {}
+ //{
+ // obj.id
+ // key is "MementoCommand" or something
+ // before and after mementos
+ //}
+protected:
+ obj_T &obj;
+ XMLNode &before;
+};
+
+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 &serialize() {}
+ //{
+ // obj.id
+ // key is "MementoCommand" or something
+ // before and after mementos
+ //}
+protected:
+ obj_T &obj;
+ XMLNode &after;
+};
+
+#endif // __lib_pbd_memento_h__
diff --git a/libs/pbd/pbd/serializable.h b/libs/pbd/pbd/serializable.h
new file mode 100644
index 0000000000..f6ac4e92fb
--- /dev/null
+++ b/libs/pbd/pbd/serializable.h
@@ -0,0 +1,33 @@
+/*
+ Copyright (C) 2006 Paul Davis
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ 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 59 2006-06-15T18:16:20.960977Z fugalh $
+*/
+
+#ifndef __lib_pbd_serializable_h__
+#define __lib_pbd_serializable_h__
+
+#include <pbd/xml++.h>
+
+class Serializable
+{
+public:
+ virtual XMLNode &serialize() = 0;
+ virtual ~Serializable() {}
+};
+
+#endif // __lib_pbd_serializable_h__
diff --git a/libs/pbd/pbd/undo.h b/libs/pbd/pbd/undo.h
index f067635ed3..33577ed4d7 100644
--- a/libs/pbd/pbd/undo.h
+++ b/libs/pbd/pbd/undo.h
@@ -23,29 +23,33 @@
#include <string>
#include <list>
+#include <map>
#include <sigc++/slot.h>
+#include <sigc++/bind.h>
#include <sys/time.h>
+#include <pbd/command.h>
using std::string;
using std::list;
typedef sigc::slot<void> UndoAction;
-class UndoCommand
+class UndoTransaction : public Command
{
public:
- UndoCommand ();
- UndoCommand (const UndoCommand&);
- UndoCommand& operator= (const UndoCommand&);
+ UndoTransaction ();
+ UndoTransaction (const UndoTransaction&);
+ UndoTransaction& operator= (const UndoTransaction&);
void clear ();
- void add_undo (const UndoAction&);
- void add_redo (const UndoAction&);
- void add_redo_no_execute (const UndoAction&);
+ void add_command (Command *const);
+ void operator() ();
void undo();
void redo();
+
+ XMLNode &serialize();
void set_name (const string& str) {
_name = str;
@@ -61,8 +65,7 @@ class UndoCommand
}
private:
- list<UndoAction> redo_actions;
- list<UndoAction> undo_actions;
+ list<Command*> actions;
struct timeval _timestamp;
string _name;
};
@@ -73,7 +76,7 @@ class UndoHistory
UndoHistory() {}
~UndoHistory() {}
- void add (UndoCommand uc);
+ void add (UndoTransaction ut);
void undo (unsigned int n);
void redo (unsigned int n);
@@ -88,8 +91,8 @@ class UndoHistory
void clear_redo ();
private:
- list<UndoCommand> UndoList;
- list<UndoCommand> RedoList;
+ list<UndoTransaction> UndoList;
+ list<UndoTransaction> RedoList;
};
diff --git a/libs/pbd/undo.cc b/libs/pbd/undo.cc
index f2f11b1c5c..aa27f95789 100644
--- a/libs/pbd/undo.cc
+++ b/libs/pbd/undo.cc
@@ -25,77 +25,74 @@
using namespace std;
using namespace sigc;
-UndoCommand::UndoCommand ()
+UndoTransaction::UndoTransaction ()
{
}
-UndoCommand::UndoCommand (const UndoCommand& rhs)
+UndoTransaction::UndoTransaction (const UndoTransaction& rhs)
{
_name = rhs._name;
clear ();
- undo_actions.insert(undo_actions.end(),rhs.undo_actions.begin(),rhs.undo_actions.end());
- redo_actions.insert(redo_actions.end(),rhs.redo_actions.begin(),rhs.redo_actions.end());
+ actions.insert(actions.end(),rhs.actions.begin(),rhs.actions.end());
}
-UndoCommand&
-UndoCommand::operator= (const UndoCommand& rhs)
+UndoTransaction&
+UndoTransaction::operator= (const UndoTransaction& rhs)
{
if (this == &rhs) return *this;
_name = rhs._name;
clear ();
- undo_actions.insert(undo_actions.end(),rhs.undo_actions.begin(),rhs.undo_actions.end());
- redo_actions.insert(redo_actions.end(),rhs.redo_actions.begin(),rhs.redo_actions.end());
+ actions.insert(actions.end(),rhs.actions.begin(),rhs.actions.end());
return *this;
}
void
-UndoCommand::add_undo (const UndoAction& action)
+UndoTransaction::add_command (Command *const action)
{
- undo_actions.push_back (action);
+ actions.push_back (action);
}
void
-UndoCommand::add_redo (const UndoAction& action)
+UndoTransaction::clear ()
{
- redo_actions.push_back (action);
- redo_actions.back()(); // operator()
+ actions.clear ();
}
void
-UndoCommand::add_redo_no_execute (const UndoAction& action)
+UndoTransaction::operator() ()
{
- redo_actions.push_back (action);
-}
-
-void
-UndoCommand::clear ()
-{
- undo_actions.clear ();
- redo_actions.clear ();
+ for (list<Command*>::iterator i = actions.begin(); i != actions.end(); ++i) {
+ (*(*i))();
+ }
}
void
-UndoCommand::undo ()
+UndoTransaction::undo ()
{
cerr << "Undo " << _name << endl;
- for (list<UndoAction>::reverse_iterator i = undo_actions.rbegin(); i != undo_actions.rend(); ++i) {
- (*i)();
+ for (list<Command*>::reverse_iterator i = actions.rbegin(); i != actions.rend(); ++i) {
+ (*i)->undo();
}
}
void
-UndoCommand::redo ()
+UndoTransaction::redo ()
{
cerr << "Redo " << _name << endl;
- for (list<UndoAction>::iterator i = redo_actions.begin(); i != redo_actions.end(); ++i) {
- (*i)();
- }
+ (*this)();
+}
+
+XMLNode &UndoTransaction::serialize()
+{
+ XMLNode *node = new XMLNode ("UndoTransaction");
+ // TODO
+ return *node;
}
void
-UndoHistory::add (UndoCommand uc)
+UndoHistory::add (UndoTransaction ut)
{
- UndoList.push_back (uc);
+ UndoList.push_back (ut);
}
void
@@ -105,10 +102,10 @@ UndoHistory::undo (unsigned int n)
if (UndoList.size() == 0) {
return;
}
- UndoCommand uc = UndoList.back ();
+ UndoTransaction ut = UndoList.back ();
UndoList.pop_back ();
- uc.undo ();
- RedoList.push_back (uc);
+ ut.undo ();
+ RedoList.push_back (ut);
}
}
@@ -119,10 +116,10 @@ UndoHistory::redo (unsigned int n)
if (RedoList.size() == 0) {
return;
}
- UndoCommand cmd = RedoList.back ();
+ UndoTransaction ut = RedoList.back ();
RedoList.pop_back ();
- cmd.redo ();
- UndoList.push_back (cmd);
+ ut.redo ();
+ UndoList.push_back (ut);
}
}