name = session->name();
}
session->restore_state (name);
+ session->restore_history (name);
}
}
XMLNode &before = audio_region().get_state();
audio_region().set_envelope_active(true);
XMLNode &after = audio_region().get_state();
- trackview.session().add_command (new MementoCommand<AudioRegion>(audio_region(), before, after));
+ trackview.session().add_command (new MementoCommand<AudioRegion>(audio_region(), &before, &after));
}
audio_region().envelope().add (fx, y);
XMLNode &after = audio_region().envelope().get_state();
- trackview.session().add_command (new MementoCommand<Curve>(audio_region().envelope(), before, after));
+ trackview.session().add_command (new MementoCommand<Curve>(audio_region().envelope(), &before, &after));
trackview.session().commit_reversible_command ();
}
line->signal_event().connect (mem_fun (*this, &AutomationLine::event_handler));
alist.StateChanged.connect (mem_fun(*this, &AutomationLine::list_changed));
+
+ trackview.session().register_with_memento_command_factory(_id, this);
+
}
AutomationLine::~AutomationLine ()
}
trackview.editor.current_session()->begin_reversible_command (str);
- trackview.editor.current_session()->add_command (new MementoUndoCommand<AutomationLine>(*this, get_state()));
+ trackview.editor.current_session()->add_command (new MementoCommand<AutomationLine>(*this, &get_state(), 0));
first_drag_fraction = fraction;
last_drag_fraction = fraction;
update_pending = false;
- trackview.editor.current_session()->add_command (new MementoRedoCommand<AutomationLine>(*this, get_state()));
+ trackview.editor.current_session()->add_command (new MementoCommand<AutomationLine>(*this, 0, &get_state()));
trackview.editor.current_session()->commit_reversible_command ();
trackview.editor.current_session()->set_dirty ();
}
alist.erase (mr.start, mr.end);
- trackview.editor.current_session()->add_command(new MementoCommand<AutomationLine>(*this, before, get_state()));
+ 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 ();
}
/* parent must create command */
XMLNode &before = get_state();
alist.clear();
- trackview.editor.current_session()->add_command (new MementoCommand<AutomationLine>(*this, before, get_state()));
+ 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 ();
}
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_command(new MementoCommand<AutomationList>(alist, before, alist.get_state()));
+ _session.add_command(new MementoCommand<AutomationList>(alist, &before, &alist.get_state()));
ret = true;
}
break;
case Clear:
if ((what_we_got = alist.cut (selection.time.front().start, selection.time.front().end)) != 0) {
- _session.add_command(new MementoCommand<AutomationList>(alist, before, alist.get_state()));
+ _session.add_command(new MementoCommand<AutomationList>(alist, &before, &alist.get_state()));
delete what_we_got;
what_we_got = 0;
ret = true;
{
AutomationList& alist (line.the_list());
- _session.add_command (new MementoUndoCommand<AutomationList>(alist, alist.get_state()));
+ _session.add_command (new MementoCommand<AutomationList>(alist, &alist.get_state(), 0));
for (PointSelection::iterator i = selection.begin(); i != selection.end(); ++i) {
case Cut:
if ((what_we_got = alist.cut ((*i).start, (*i).end)) != 0) {
editor.get_cut_buffer().add (what_we_got);
- _session.add_command (new MementoCommand<AutomationList>(alist, before, alist.get_state()));
+ _session.add_command (new MementoCommand<AutomationList>(alist, &before, &alist.get_state()));
ret = true;
}
break;
case Clear:
if ((what_we_got = alist.cut ((*i).start, (*i).end)) != 0) {
- _session.add_command (new MementoCommand<AutomationList>(alist, before, alist.get_state()));
+ _session.add_command (new MementoCommand<AutomationList>(alist, &before, &alist.get_state()));
delete what_we_got;
what_we_got = 0;
ret = true;
XMLNode &before = alist.get_state();
alist.paste (copy, pos, times);
- _session.add_command (new MementoCommand<AutomationList>(alist, before, alist.get_state()));
+ _session.add_command (new MementoCommand<AutomationList>(alist, &before, &alist.get_state()));
return true;
}
ControlProtocol::ScrollTimeline.connect (mem_fun (*this, &Editor::control_scroll));
constructed = true;
instant_save ();
+
}
Editor::~Editor()
no_route_list_redisplay = false;
redisplay_route_list ();
}
+
+ /* register for undo history */
+ session->register_with_memento_command_factory(_id, this);
}
void
Editor::commit_reversible_command ()
{
if (session) {
- session->commit_reversible_command (new MementoCommand<Editor>(*this, *before, get_state()));
+ session->commit_reversible_command (new MementoCommand<Editor>(*this, before, &get_state()));
}
}
begin_reversible_command (_("insert sndfile"));
XMLNode &before = playlist->get_state();
playlist->add_region (*copy, pos);
- session->add_command (new MementoCommand<Playlist>(*playlist, before, playlist->get_state()));
+ session->add_command (new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
commit_reversible_command ();
pos += region.length();
entered_regionview->region().set_muted (!entered_regionview->region().muted());
XMLNode &after = entered_regionview->region().playlist()->get_state();
- session->add_command (new MementoCommand<ARDOUR::Playlist>(*(entered_regionview->region().playlist()), before, after));
+ session->add_command (new MementoCommand<ARDOUR::Playlist>(*(entered_regionview->region().playlist()), &before, &after));
commit_reversible_command();
}
}
XMLNode &before = session->locations()->get_state();
session->locations()->add (location, true);
XMLNode &after = session->locations()->get_state();
- session->add_command (new MementoCommand<Locations>(*(session->locations()), before, after));
+ session->add_command (new MementoCommand<Locations>(*(session->locations()), &before, &after));
session->commit_reversible_command ();
}
}
XMLNode &before = session->locations()->get_state();
session->locations()->remove (loc);
XMLNode &after = session->locations()->get_state();
- session->add_command (new MementoCommand<Locations>(*(session->locations()), before, after));
+ session->add_command (new MementoCommand<Locations>(*(session->locations()), &before, &after));
session->commit_reversible_command ();
return FALSE;
}
loc->set_name (txt);
XMLNode &after = session->locations()->get_state();
- session->add_command (new MementoCommand<Locations>(*(session->locations()), before, after));
+ session->add_command (new MementoCommand<Locations>(*(session->locations()), &before, &after));
commit_reversible_command ();
}
session->locations()->add (loc, true);
session->set_auto_loop_location (loc);
XMLNode &after = session->locations()->get_state();
- session->add_command (new MementoCommand<Locations>(*(session->locations()), before, after));
+ session->add_command (new MementoCommand<Locations>(*(session->locations()), &before, &after));
}
else {
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));
+ session->add_command (new MementoCommand<Location>(*tll, &before, &after));
}
commit_reversible_command ();
session->locations()->add (tpl, true);
session->set_auto_punch_location (tpl);
XMLNode &after = session->locations()->get_state();
- session->add_command (new MementoCommand<Locations>(*(session->locations()), before, after));
+ session->add_command (new MementoCommand<Locations>(*(session->locations()), &before, &after));
} else {
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));
+ session->add_command (new MementoCommand<Location>(*tpl, &before, &after));
}
commit_reversible_command ();
XMLNode &after = arv->audio_region().get_state();
session->add_command(new MementoCommand<ARDOUR::AudioRegion>(arv->audio_region(),
- before,
- after));
+ &before,
+ &after));
commit_reversible_command ();
fade_in_drag_motion_callback (item, event);
}
arv->audio_region().set_fade_out_length (fade_length);
XMLNode &after = arv->region().get_state();
- session->add_command(new MementoCommand<ARDOUR::Region>(arv->region(), before, after));
+ session->add_command(new MementoCommand<ARDOUR::Region>(arv->region(), &before, &after));
commit_reversible_command ();
fade_out_drag_motion_callback (item, event);
}
XMLNode &after = session->locations()->get_state();
- session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
+ session->add_command(new MementoCommand<Locations>(*(session->locations()), &before, &after));
commit_reversible_command ();
marker_drag_line->hide();
XMLNode &before = map.get_state();
map.add_meter (marker->meter(), when);
XMLNode &after = map.get_state();
- session->add_command(new MementoCommand<TempoMap>(map, before, after));
+ session->add_command(new MementoCommand<TempoMap>(map, &before, &after));
commit_reversible_command ();
// delete the dummy marker we used for visual representation of copying.
XMLNode &before = map.get_state();
map.move_meter (marker->meter(), when);
XMLNode &after = map.get_state();
- session->add_command(new MementoCommand<TempoMap>(map, before, after));
+ session->add_command(new MementoCommand<TempoMap>(map, &before, &after));
commit_reversible_command ();
}
}
XMLNode &before = map.get_state();
map.add_tempo (marker->tempo(), when);
XMLNode &after = map.get_state();
- session->add_command (new MementoCommand<TempoMap>(map, before, after));
+ session->add_command (new MementoCommand<TempoMap>(map, &before, &after));
commit_reversible_command ();
// delete the dummy marker we used for visual representation of copying.
XMLNode &before = map.get_state();
map.move_tempo (marker->tempo(), when);
XMLNode &after = map.get_state();
- session->add_command (new MementoCommand<TempoMap>(map, before, after));
+ session->add_command (new MementoCommand<TempoMap>(map, &before, &after));
commit_reversible_command ();
}
}
insert_result = affected_playlists.insert (to_playlist);
if (insert_result.second) {
- session->add_command (new MementoUndoCommand<Playlist>(*to_playlist, to_playlist->get_state()));
+ session->add_command (new MementoCommand<Playlist>(*to_playlist, &to_playlist->get_state(), 0));
}
latest_regionview = 0;
insert_result = motion_frozen_playlists.insert (pl);
if (insert_result.second) {
pl->freeze();
- session->add_command(new MementoUndoCommand<Playlist>(*pl, pl->get_state()));
+ session->add_command(new MementoCommand<Playlist>(*pl, &pl->get_state(), 0));
}
}
}
insert_result = motion_frozen_playlists.insert(to_playlist);
if (insert_result.second) {
to_playlist->freeze();
- session->add_command(new MementoUndoCommand<Playlist>(*to_playlist, to_playlist->get_state()));
+ session->add_command(new MementoCommand<Playlist>(*to_playlist, &to_playlist->get_state(), 0));
}
}
out:
for (set<Playlist*>::iterator p = motion_frozen_playlists.begin(); p != motion_frozen_playlists.end(); ++p) {
(*p)->thaw ();
- session->add_command (new MementoRedoCommand<Playlist>(*(*p), (*p)->get_state()));
+ session->add_command (new MementoCommand<Playlist>(*(*p), 0, & (*p)->get_state()));
}
motion_frozen_playlists.clear ();
Playlist* playlist = clicked_trackview->playlist();
- before = &(playlist->get_state());
+ XMLNode *before = &(playlist->get_state());
clicked_trackview->playlist()->add_region (*region, selection->time[clicked_selection].start);
- XMLNode &after = playlist->get_state();
- session->add_command(new MementoCommand<Playlist>(*playlist, *before, after));
+ XMLNode *after = &(playlist->get_state());
+ session->add_command(new MementoCommand<Playlist>(*playlist, before, after));
commit_reversible_command ();
Playlist * pl = (*i)->region().playlist();
insert_result = motion_frozen_playlists.insert (pl);
if (insert_result.second) {
- session->add_command(new MementoUndoCommand<Playlist>(*pl, pl->get_state()));
+ session->add_command(new MementoCommand<Playlist>(*pl, &pl->get_state(), 0));
}
}
}
for (set<Playlist*>::iterator p = motion_frozen_playlists.begin(); p != motion_frozen_playlists.end(); ++p) {
//(*p)->thaw ();
- session->add_command (new MementoRedoCommand<Playlist>(*(*p), (*p)->get_state()));
+ session->add_command (new MementoCommand<Playlist>(*(*p), 0, &(*p)->get_state()));
}
motion_frozen_playlists.clear ();
XMLNode &before = pl->get_state();
(*i)->region().trim_front (new_bound, this);
XMLNode &after = pl->get_state();
- session->add_command(new MementoCommand<Playlist>(*pl, before, after));
+ session->add_command(new MementoCommand<Playlist>(*pl, &before, &after));
}
}
XMLNode &before = pl->get_state();
rv->region().trim_front (new_bound, this);
XMLNode &after = pl->get_state();
- session->add_command(new MementoCommand<Playlist>(*pl, before, after));
+ session->add_command(new MementoCommand<Playlist>(*pl, &before, &after));
}
}
XMLNode &before = pl->get_state();
(*i)->region().trim_end (new_bound, this);
XMLNode &after = pl->get_state();
- session->add_command(new MementoCommand<Playlist>(*pl, before, after));
+ session->add_command(new MementoCommand<Playlist>(*pl, &before, &after));
}
}
XMLNode &before = pl->get_state();
rv->region().trim_end (new_bound, this);
XMLNode &after = pl->get_state();
- session->add_command (new MementoCommand<Playlist>(*pl, before, after));
+ session->add_command (new MementoCommand<Playlist>(*pl, &before, &after));
}
}
region.thaw (_("trimmed region"));
XMLNode &after = region.playlist()->get_state();
- session->add_command (new MementoRedoCommand<Playlist>(*(region.playlist()), after));
+ session->add_command (new MementoCommand<Playlist>(*(region.playlist()), 0, &after));
AudioRegionView* arv = dynamic_cast<AudioRegionView*>(&rv);
if (arv)
newloc = new Location(temp_location->start(), temp_location->end(), "unnamed", Location::IsRangeMarker);
session->locations()->add (newloc, true);
XMLNode &after = session->locations()->get_state();
- session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
+ session->add_command(new MementoCommand<Locations>(*(session->locations()), &before, &after));
commit_reversible_command ();
range_bar_drag_rect->hide();
XMLNode &before = playlist->get_state();
playlist->add_region (*(new AudioRegion (arv->audio_region())), (jack_nframes_t) (pos * speed));
XMLNode &after = playlist->get_state();
- session->add_command(new MementoCommand<Playlist>(*playlist, before, after));
+ session->add_command(new MementoCommand<Playlist>(*playlist, &before, &after));
// playlist is frozen, so we have to update manually
XMLNode &before = pl->get_state();
pl->split_region ((*a)->region(), where);
XMLNode &after = pl->get_state();
- session->add_command(new MementoCommand<Playlist>(*pl, before, after));
+ session->add_command(new MementoCommand<Playlist>(*pl, &before, &after));
}
a = tmp;
XMLNode &before = playlist->get_state();
playlist->remove_region (&clicked_regionview->region());
XMLNode &after = playlist->get_state();
- session->add_command(new MementoCommand<Playlist>(*playlist, before, after));
+ session->add_command(new MementoCommand<Playlist>(*playlist, &before, &after));
commit_reversible_command ();
}
XMLNode &before = r.playlist()->get_state();
r.set_position (r.position() + distance, this);
XMLNode &after = r.playlist()->get_state();
- session->add_command (new MementoCommand<Playlist>(*(r.playlist()), before, after));
+ session->add_command (new MementoCommand<Playlist>(*(r.playlist()), &before, &after));
}
commit_reversible_command ();
r.set_position (0, this);
}
XMLNode &after = r.playlist()->get_state();
- session->add_command(new MementoCommand<Playlist>(*(r.playlist()), before, after));
+ session->add_command(new MementoCommand<Playlist>(*(r.playlist()), &before, &after));
}
commit_reversible_command ();
XMLNode &before = r.playlist()->get_state();
r.set_position (r.position() + distance, this);
XMLNode &after = r.playlist()->get_state();
- session->add_command(new MementoCommand<Playlist>(*(r.playlist()), before, after));
+ session->add_command(new MementoCommand<Playlist>(*(r.playlist()), &before, &after));
}
commit_reversible_command ();
r.set_position (0, this);
}
XMLNode &after = r.playlist()->get_state();
- session->add_command(new MementoCommand<Playlist>(*(r.playlist()), before, after));
+ session->add_command(new MementoCommand<Playlist>(*(r.playlist()), &before, &after));
}
commit_reversible_command ();
XMLNode &before = session->locations()->get_state();
session->locations()->add (location, true);
XMLNode &after = session->locations()->get_state();
- session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
+ session->add_command(new MementoCommand<Locations>(*(session->locations()), &before, &after));
session->commit_reversible_command ();
}
XMLNode &before = session->locations()->get_state();
session->locations()->add (location, true);
XMLNode &after = session->locations()->get_state();
- session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
+ session->add_command(new MementoCommand<Locations>(*(session->locations()), &before, &after));
session->commit_reversible_command ();
}
XMLNode &before = session->locations()->get_state();
session->locations()->add (location, true);
XMLNode &after = session->locations()->get_state();
- session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
+ session->add_command(new MementoCommand<Locations>(*(session->locations()), &before, &after));
session->commit_reversible_command ();
}
XMLNode &before = session->locations()->get_state();
session->locations()->clear_markers ();
XMLNode &after = session->locations()->get_state();
- session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
+ session->add_command(new MementoCommand<Locations>(*(session->locations()), &before, &after));
session->commit_reversible_command ();
}
}
if (punchloc) session->locations()->add (punchloc);
XMLNode &after = session->locations()->get_state();
- session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
+ session->add_command(new MementoCommand<Locations>(*(session->locations()), &before, &after));
session->commit_reversible_command ();
}
}
XMLNode &before = session->locations()->get_state();
session->locations()->clear ();
XMLNode &after = session->locations()->get_state();
- session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
+ session->add_command(new MementoCommand<Locations>(*(session->locations()), &before, &after));
session->commit_reversible_command ();
session->locations()->clear ();
}
begin_reversible_command (_("insert dragged region"));
XMLNode &before = playlist->get_state();
playlist->add_region (*(new AudioRegion (region)), where, 1.0);
- session->add_command(new MementoCommand<Playlist>(*playlist, before, playlist->get_state()));
+ session->add_command(new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
commit_reversible_command ();
}
begin_reversible_command (_("insert region"));
XMLNode &before = playlist->get_state();
playlist->add_region (*(createRegion (*region)), edit_cursor->current_frame, times);
- session->add_command(new MementoCommand<Playlist>(*playlist, before, playlist->get_state()));
+ session->add_command(new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
commit_reversible_command ();
}
}
if (doing_undo)
- session->add_command(new MementoCommand<Playlist>(*playlist, *before, playlist->get_state()));
+ session->add_command(new MementoCommand<Playlist>(*playlist, before, &playlist->get_state()));
}
}
}
playlist->partition ((jack_nframes_t)(loc.start() * speed), (jack_nframes_t)(loc.end() * speed), true);
if (doing_undo)
- session->add_command(new MementoCommand<Playlist>(*playlist, *before, playlist->get_state()));
+ session->add_command(new MementoCommand<Playlist>(*playlist, before, &playlist->get_state()));
}
}
}
XMLNode &before = (*i)->get_state();
region->trim_to (start, cnt, this);
XMLNode &after = (*i)->get_state();
- session->add_command (new MementoCommand<Playlist>(*(*i), before, after));
+ session->add_command (new MementoCommand<Playlist>(*(*i), &before, &after));
}
commit_reversible_command ();
XMLNode &before = pl->get_state();
pl->add_region (*(new AudioRegion (*ar)), ar->last_frame(), times);
- session->add_command (new MementoCommand<Playlist>(*pl, before, pl->get_state()));
+ session->add_command (new MementoCommand<Playlist>(*pl, &before, &pl->get_state()));
}
commit_reversible_command ();
XMLNode &before = playlist->get_state();
playlist->add_region (*(createRegion (*region)), start, times);
- session->add_command (new MementoCommand<Playlist>(*playlist, before, playlist->get_state()));
+ session->add_command (new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
}
commit_reversible_command ();
XMLNode &before = region.playlist()->get_state();
region.set_sync_position (position);
XMLNode &after = region.playlist()->get_state();
- session->add_command(new MementoCommand<Playlist>(*(region.playlist()), before, after));
+ session->add_command(new MementoCommand<Playlist>(*(region.playlist()), &before, &after));
commit_reversible_command ();
}
XMLNode &before = region.playlist()->get_state();
region.set_sync_position (edit_cursor->current_frame);
XMLNode &after = region.playlist()->get_state();
- session->add_command(new MementoCommand<Playlist>(*(region.playlist()), before, after));
+ session->add_command(new MementoCommand<Playlist>(*(region.playlist()), &before, &after));
commit_reversible_command ();
}
XMLNode &before = region.playlist()->get_state();
region.clear_sync_position ();
XMLNode &after = region.playlist()->get_state();
- session->add_command(new MementoCommand<Playlist>(*(region.playlist()), before, after));
+ session->add_command(new MementoCommand<Playlist>(*(region.playlist()), &before, &after));
commit_reversible_command ();
}
}
XMLNode &before = (*i)->region().get_state();
(*i)->region().move_to_natural_position (this);
XMLNode &after = (*i)->region().get_state();
- session->add_command (new MementoCommand<Region>((*i)->region(), before, after));
+ session->add_command (new MementoCommand<Region>((*i)->region(), &before, &after));
}
commit_reversible_command ();
}
}
XMLNode &after = region.playlist()->get_state();
- session->add_command(new MementoCommand<Playlist>(*(region.playlist()), before, after));
+ session->add_command(new MementoCommand<Playlist>(*(region.playlist()), &before, &after));
}
}
XMLNode &after = region.playlist()->get_state();
- session->add_command(new MementoCommand<Playlist>(*(region.playlist()), before, after));
+ session->add_command(new MementoCommand<Playlist>(*(region.playlist()), &before, &after));
}
void
XMLNode &before = region.playlist()->get_state();
region.trim_end( session_frame_to_track_frame(edit_cursor->current_frame, speed), this);
XMLNode &after = region.playlist()->get_state();
- session->add_command(new MementoCommand<Playlist>(*(region.playlist()), before, after));
+ session->add_command(new MementoCommand<Playlist>(*(region.playlist()), &before, &after));
commit_reversible_command ();
}
XMLNode &before = region.playlist()->get_state();
region.trim_front ( session_frame_to_track_frame(edit_cursor->current_frame, speed), this);
XMLNode &after = region.playlist()->get_state();
- session->add_command(new MementoCommand<Playlist>(*(region.playlist()), before, after));
+ session->add_command(new MementoCommand<Playlist>(*(region.playlist()), &before, &after));
commit_reversible_command ();
}
XMLNode &before = playlist->get_state();
atv->audio_track()->bounce_range (start, cnt, itt);
XMLNode &after = playlist->get_state();
- session->add_command (new MementoCommand<Playlist> (*playlist, before, after));
+ session->add_command (new MementoCommand<Playlist> (*playlist, &before, &after));
}
commit_reversible_command ();
insert_result = freezelist.insert (pl);
if (insert_result.second) {
pl->freeze ();
- session->add_command (new MementoUndoCommand<Playlist>(*pl, pl->get_state()));
+ session->add_command (new MementoCommand<Playlist>(*pl, &pl->get_state(), 0));
}
}
}
for (set<Playlist*>::iterator pl = freezelist.begin(); pl != freezelist.end(); ++pl) {
(*pl)->thaw ();
- session->add_command (new MementoRedoCommand<Playlist>(*(*pl), (*pl)->get_state()));
+ session->add_command (new MementoCommand<Playlist>(*(*pl), 0, &(*pl)->get_state()));
}
}
XMLNode &before = apl->get_state();
apl->paste (**chunk, edit_cursor->current_frame, times);
- session->add_command(new MementoCommand<AudioPlaylist>(*apl, before, apl->get_state()));
+ session->add_command(new MementoCommand<AudioPlaylist>(*apl, &before, &apl->get_state()));
if (tmp != ns->playlists.end()) {
chunk = tmp;
playlist = (*i)->region().playlist();
XMLNode &before = playlist->get_state();
playlist->duplicate (r, r.last_frame(), times);
- session->add_command(new MementoCommand<Playlist>(*playlist, before, playlist->get_state()));
+ session->add_command(new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
c.disconnect ();
XMLNode &before = playlist->get_state();
playlist->duplicate (**ri, selection->time[clicked_selection].end, times);
XMLNode &after = playlist->get_state();
- session->add_command (new MementoCommand<Playlist>(*playlist, before, after));
+ session->add_command (new MementoCommand<Playlist>(*playlist, &before, &after));
++ri;
if (ri == new_regions.end()) {
XMLNode &before = playlist.get_state();
playlist.clear ();
XMLNode &after = playlist.get_state();
- session->add_command (new MementoCommand<Playlist>(playlist, before, after));
+ session->add_command (new MementoCommand<Playlist>(playlist, &before, &after));
commit_reversible_command ();
}
XMLNode &before = playlist->get_state();
playlist->nudge_after (start, distance, forwards);
XMLNode &after = playlist->get_state();
- session->add_command (new MementoCommand<Playlist>(*playlist, before, after));
+ session->add_command (new MementoCommand<Playlist>(*playlist, &before, &after));
}
commit_reversible_command ();
continue;
XMLNode &before = arv->region().get_state();
arv->audio_region().normalize_to (0.0f);
- session->add_command (new MementoCommand<Region>(arv->region(), before, arv->region().get_state()));
+ session->add_command (new MementoCommand<Region>(arv->region(), &before, &arv->region().get_state()));
}
commit_reversible_command ();
continue;
XMLNode &before = arv->region().get_state();
arv->audio_region().set_scale_amplitude (1.0f);
- session->add_command (new MementoCommand<Region>(arv->region(), before, arv->region().get_state()));
+ session->add_command (new MementoCommand<Region>(arv->region(), &before, &arv->region().get_state()));
}
commit_reversible_command ();
XMLNode &before = playlist->get_state();
playlist->replace_region (arv->region(), *(filter.results.front()), arv->region().position());
XMLNode &after = playlist->get_state();
- session->add_command(new MementoCommand<Playlist>(*playlist, before, after));
+ session->add_command(new MementoCommand<Playlist>(*playlist, &before, &after));
} else {
goto out;
}
XMLNode &before = map.get_state();
map.add_tempo (Tempo (bpm), requested);
XMLNode &after = map.get_state();
- session->add_command(new MementoCommand<TempoMap>(map, before, after));
+ session->add_command(new MementoCommand<TempoMap>(map, &before, &after));
commit_reversible_command ();
map.dump (cerr);
begin_reversible_command (_("add meter mark"));
XMLNode &before = map.get_state();
map.add_meter (Meter (bpb, note_type), requested);
- session->add_command(new MementoCommand<TempoMap>(map, before, map.get_state()));
+ session->add_command(new MementoCommand<TempoMap>(map, &before, &map.get_state()));
commit_reversible_command ();
map.dump (cerr);
XMLNode &before = session->tempo_map().get_state();
session->tempo_map().replace_meter (*section, Meter (bpb, note_type));
XMLNode &after = session->tempo_map().get_state();
- session->add_command(new MementoCommand<TempoMap>(session->tempo_map(), before, after));
+ session->add_command(new MementoCommand<TempoMap>(session->tempo_map(), &before, &after));
commit_reversible_command ();
}
session->tempo_map().replace_tempo (*section, Tempo (bpm));
session->tempo_map().move_tempo (*section, when);
XMLNode &after = session->tempo_map().get_state();
- session->add_command (new MementoCommand<TempoMap>(session->tempo_map(), before, after));
+ session->add_command (new MementoCommand<TempoMap>(session->tempo_map(), &before, &after));
commit_reversible_command ();
}
XMLNode &before = session->tempo_map().get_state();
session->tempo_map().remove_tempo (*section);
XMLNode &after = session->tempo_map().get_state();
- session->add_command(new MementoCommand<TempoMap>(session->tempo_map(), before, after));
+ session->add_command(new MementoCommand<TempoMap>(session->tempo_map(), &before, &after));
commit_reversible_command ();
return FALSE;
XMLNode &before = session->tempo_map().get_state();
session->tempo_map().remove_meter (*section);
XMLNode &after = session->tempo_map().get_state();
- session->add_command(new MementoCommand<TempoMap>(session->tempo_map(), before, after));
+ session->add_command(new MementoCommand<TempoMap>(session->tempo_map(), &before, &after));
commit_reversible_command ();
return FALSE;
}
XMLNode &before = playlist->get_state();
playlist->replace_region (region, *new_region, region.position());
XMLNode &after = playlist->get_state();
- session->add_command (new MementoCommand<Playlist>(*playlist, before, after));
+ session->add_command (new MementoCommand<Playlist>(*playlist, &before, &after));
i = tmp;
}
XMLNode &before = curve.get_state();
curve.add (when, y);
XMLNode &after = curve.get_state();
- _session.add_command(new MementoCommand<ARDOUR::Curve>(curve, before, after));
+ _session.add_command(new MementoCommand<ARDOUR::Curve>(curve, &before, &after));
_session.commit_reversible_command ();
_session.set_dirty ();
}
XMLNode &before = session->locations()->get_state();
session->locations()->remove (loc);
XMLNode &after = session->locations()->get_state();
- session->add_command(new MementoCommand<Locations>(*(session->locations()), before, after));
+ session->add_command(new MementoCommand<Locations>(*(session->locations()), &before, &after));
session->commit_reversible_command ();
return FALSE;
XMLNode &before = session->locations()->get_state();
session->locations()->add (location, true);
XMLNode &after = session->locations()->get_state();
- session->add_command (new MementoCommand<Locations>(*(session->locations()), before, after));
+ session->add_command (new MementoCommand<Locations>(*(session->locations()), &before, &after));
session->commit_reversible_command ();
}
XMLNode &before = session->locations()->get_state();
session->locations()->add (location, true);
XMLNode &after = session->locations()->get_state();
- session->add_command (new MementoCommand<Locations>(*(session->locations()), before, after));
+ session->add_command (new MementoCommand<Locations>(*(session->locations()), &before, &after));
session->commit_reversible_command ();
}
}
XMLNode &before = alist.get_state();
alist.add (when, y);
XMLNode &after = alist.get_state();
- _session.add_command(new MementoCommand<AutomationList>(alist, before, after));
+ _session.add_command(new MementoCommand<AutomationList>(alist, &before, &after));
_session.commit_reversible_command ();
_session.set_dirty ();
}
XMLNode &before = alist.get_state();
alist.add (when, y);
XMLNode &after = alist.get_state();
- _session.add_command(new MementoCommand<AutomationList>(alist, before, after));
+ _session.add_command(new MementoCommand<AutomationList>(alist, &before, &after));
_session.commit_reversible_command ();
_session.set_dirty ();
}
{
AutomationLine::start_drag(cp,fraction);
if (!rv.audio_region().envelope_active()) {
- trackview.session().add_command(new MementoUndoCommand<AudioRegion>(rv.audio_region(), rv.audio_region().get_state()));
+ trackview.session().add_command(new MementoCommand<AudioRegion>(rv.audio_region(), &rv.audio_region().get_state(), 0));
rv.audio_region().set_envelope_active(false);
}
}
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));
+ trackview.session().add_command(new MementoCommand<AudioRegion>(rv.audio_region(), &before, &after));
}
alist.erase (mr.start, mr.end);
- trackview.editor.current_session()->add_command (new MementoCommand<AudioRegionGainLine>(*this, before, get_state()));
+ 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 ();
}
{
if (!rv.audio_region().envelope_active()) {
rv.audio_region().set_envelope_active(true);
- trackview.session().add_command(new MementoRedoCommand<AudioRegion>(rv.audio_region(), rv.audio_region().get_state()));
+ trackview.session().add_command(new MementoCommand<AudioRegion>(rv.audio_region(), 0, &rv.audio_region().get_state()));
}
AutomationLine::end_drag(cp);
}
case Cut:
if ((what_we_got = playlist->cut (time)) != 0) {
editor.get_cut_buffer().add (what_we_got);
- _session.add_command( new MementoCommand<Playlist>(*playlist, before, playlist->get_state()));
+ _session.add_command( new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
ret = true;
}
break;
case Clear:
if ((what_we_got = playlist->cut (time)) != 0) {
- _session.add_command( new MementoCommand<Playlist>(*playlist, before, playlist->get_state()));
+ _session.add_command( new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
what_we_got->unref ();
ret = true;
}
XMLNode &before = playlist->get_state();
playlist->paste (**p, pos, times);
- _session.add_command( new MementoCommand<Playlist>(*playlist, before, playlist->get_state()));
+ _session.add_command( new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
return true;
}
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.add_command (new MementoCommand<Route>(*_route, &before, &after));
_session.commit_reversible_command ();
}
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.add_command (new MementoCommand<AudioTrack>(*audio_track(), &before, &after));
_session.commit_reversible_command ();
}
}
};
+ static sigc::signal<void, AutomationList*> AutomationListCreated;
+
protected:
PBD::ID _id;
struct State : public ARDOUR::StateManager::State {
AutomationEventList::iterator closest_control_point_after (double xval);
void solve ();
+
+ static sigc::signal<void, Curve*> CurveCreated;
protected:
ControlEvent* point_factory (double,double) const;
XMLNode& get_state (void);
int set_state (const XMLNode&);
PBD::ID id() { return _id; }
+ Location *get_location_by_id(PBD::ID);
Location* auto_loop_location () const;
Location* auto_punch_location () const;
template<class T, class A> void foreach_route (T *obj, void (T::*func)(Route&, A), A arg);
boost::shared_ptr<Route> route_by_name (string);
+ boost::shared_ptr<Route> route_by_id (PBD::ID);
boost::shared_ptr<Route> route_by_remote_id (uint32_t id);
bool route_name_unique (string) const;
int restore_state (string snapshot_name);
int save_template (string template_name);
int save_history (string snapshot_name = "");
+ int restore_history (string snapshot_name);
static int rename_template (string old_name, string new_name);
sigc::signal<void> NamedSelectionAdded;
sigc::signal<void> NamedSelectionRemoved;
+ /* Curves and AutomationLists (TODO when they go away) */
+ void add_curve(Curve*);
+ void add_automation_list(AutomationList*);
+
/* fade curves */
float get_default_fade_length () const { return default_fade_msecs; }
// these commands are implemented in libs/ardour/session_command.cc
Command *memento_command_factory(XMLNode *n);
+ void register_with_memento_command_factory(PBD::ID, Stateful *);
class GlobalSoloStateCommand : public Command
{
GlobalRouteBooleanState before, after;
NamedSelection *named_selection_factory (string name);
NamedSelection *XMLNamedSelectionFactory (const XMLNode&);
+ /* CURVES and AUTOMATION LISTS */
+ std::map<PBD::ID, Curve*> curves;
+ std::map<PBD::ID, AutomationList*> automation_lists;
+
/* DEFAULT FADE CURVES */
float default_fade_steepness;
_playlist->thaw ();
XMLNode &after = _playlist->get_state();
- _session.add_command (new MementoCommand<Playlist>(*_playlist, before, after));
+ _session.add_command (new MementoCommand<Playlist>(*_playlist, &before, &after));
}
mark_write_completed = true;
if (!no_state) {
save_state (_("initial"));
}
+
+ AutomationListCreated(this);
}
AutomationList::AutomationList (const AutomationList& other)
}
mark_dirty ();
+ AutomationListCreated(this);
}
AutomationList::AutomationList (const AutomationList& other, double start, double end)
delete section;
mark_dirty ();
+ AutomationListCreated(this);
}
AutomationList::~AutomationList()
{
min_yval = minv;
max_yval = maxv;
+ CurveCreated(this);
}
Curve::Curve (const Curve& other)
{
min_yval = other.min_yval;
max_yval = other.max_yval;
+ CurveCreated(this);
}
Curve::Curve (const Curve& other, double start, double end)
{
min_yval = other.min_yval;
max_yval = other.max_yval;
+ CurveCreated(this);
}
Curve::~Curve ()
return shared_ptr<Route> ((Route*) 0);
}
+shared_ptr<Route>
+Session::route_by_id (PBD::ID id)
+{
+ shared_ptr<RouteList> r = routes.reader ();
+
+ for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
+ if ((*i)->id() == id) {
+ return *i;
+ }
+ }
+
+ return shared_ptr<Route> ((Route*) 0);
+}
+
shared_ptr<Route>
Session::route_by_remote_id (uint32_t id)
{
}
}
+void
+Session::add_curve(Curve *curve)
+{
+ curves[curve->id()] = curve;
+}
+
+void
+Session::add_automation_list(AutomationList *al)
+{
+ automation_lists[al->id()] = al;
+}
#include <ardour/route.h>
#include <pbd/memento_command.h>
#include <ardour/diskstream.h>
+#include <ardour/playlist.h>
+#include <ardour/tempo.h>
+#include <ardour/audiosource.h>
+#include <ardour/audioregion.h>
+#include <pbd/error.h>
+using namespace PBD;
+#include "i18n.h"
+
namespace ARDOUR {
+static map<PBD::ID, Stateful*> registry;
+
+void Session::register_with_memento_command_factory(PBD::ID id, Stateful *ptr)
+{
+ registry[id] = ptr;
+}
+
Command *Session::memento_command_factory(XMLNode *n)
{
PBD::ID id;
- XMLNode *before, *after;
+ XMLNode *before = 0, *after = 0;
+
+ /* get id */
+ id = PBD::ID(n->property("obj_id")->value());
+
+ /* get before/after */
+ if (n->name() == "MementoCommand")
+ {
+ before = n->children().front();
+ after = n->children().back();
+ } else if (n->name() == "MementoUndoCommand")
+ before = n->children().front();
+ else if (n->name() == "MementoRedoCommand")
+ after = n->children().front();
- /* get obj_id */
- /* get before and/or after */
+ /* create command */
+ string obj_T = n->children().front()->name();
+ if (obj_T == "AudioRegion" || obj_T == "Region")
+ {
+ if (audio_regions.count(id))
+ return new MementoCommand<AudioRegion>(*audio_regions[id], before, after);
+ }
+ else if (obj_T == "AudioSource")
+ {
+ if (audio_sources.count(id))
+ return new MementoCommand<AudioSource>(*audio_sources[id], before, after);
+ }
+ else if (obj_T == "Location")
+ return new MementoCommand<Location>(*_locations.get_location_by_id(id), before, after);
+ else if (obj_T == "Locations")
+ return new MementoCommand<Locations>(_locations, before, after);
+ else if (obj_T == "TempoMap")
+ return new MementoCommand<TempoMap>(*_tempo_map, before, after);
+ else if (obj_T == "Playlist" || obj_T == "AudioPlaylist")
+ {
+ if (Playlist *pl = playlist_by_name(before->property("name")->value()))
+ return new MementoCommand<Playlist>(*pl, before, after);
+ }
+ else if (obj_T == "Route") // inlcudes AudioTrack
+ return new MementoCommand<Route>(*route_by_id(id), before, after);
+ // For Editor and AutomationLine which are off-limits here
+ else if (registry.count(id))
+ return new MementoCommand<Stateful>(*registry[id], before, after);
+ else if (obj_T == "Curve")
+ {
+ if (curves.count(id))
+ return new MementoCommand<Curve>(*curves[id], before, after);
+ }
+ else if (obj_T == "AutomationList")
+ {
+ if (automation_lists.count(id))
+ return new MementoCommand<AutomationList>(*automation_lists[id], before, after);
+ }
- /* get an object by id by trial and error, and use it to construct an
- * appropriate memento command */
- // e.g.
- if (Diskstream *obj = diskstream_by_id(id))
- return new MementoCommand<Diskstream>(*obj, *before, *after);
- // etc.
+ /* we failed */
+ error << _("could not reconstitute MementoCommand from XMLNode. id=") << id.to_s() << endmsg;
+ return 0;
}
// solo
Redirect::RedirectCreated.connect (mem_fun (*this, &Session::add_redirect));
AudioDiskstream::DiskstreamCreated.connect (mem_fun (*this, &Session::add_diskstream));
NamedSelection::NamedSelectionCreated.connect (mem_fun (*this, &Session::add_named_selection));
+ Curve::CurveCreated.connect (mem_fun (*this, &Session::add_curve));
+ AutomationList::AutomationListCreated.connect (mem_fun (*this, &Session::add_automation_list));
Controllable::Created.connect (mem_fun (*this, &Session::add_controllable));
Controllable::GoingAway.connect (mem_fun (*this, &Session::remove_controllable));
return 0;
}
+
+int
+Session::restore_history (string snapshot_name)
+{
+ XMLTree tree;
+ string xmlpath;
+
+ /* read xml */
+ xmlpath = _path + snapshot_name + ".history";
+
+ if (access (xmlpath.c_str(), F_OK)) {
+ error << string_compose(_("%1: session history file \"%2\" doesn't exist!"), _name, xmlpath) << endmsg;
+ return 1;
+ }
+
+ if (!tree.read (xmlpath)) {
+ error << string_compose(_("Could not understand ardour file %1"), xmlpath) << endmsg;
+ return -1;
+ }
+
+ /* replace history */
+ history.clear();
+ for (XMLNodeConstIterator it = tree.root()->children().begin();
+ it != tree.root()->children().end();
+ it++)
+ {
+ XMLNode *t = *it;
+ UndoTransaction ut;
+ struct timeval tv;
+
+ ut.set_name(t->property("name")->value());
+ stringstream ss(t->property("tv_sec")->value());
+ ss >> tv.tv_sec;
+ ss.str(t->property("tv_usec")->value());
+ ss >> tv.tv_usec;
+ ut.set_timestamp(tv);
+
+ for (XMLNodeConstIterator child_it = t->children().begin();
+ child_it != t->children().end();
+ child_it++)
+ {
+ XMLNode *n = *child_it;
+ Command *c;
+ if (n->name() == "MementoCommand" ||
+ n->name() == "MementoUndoCommand" ||
+ n->name() == "MementoRedoCommand")
+ {
+ c = memento_command_factory(n);
+ if (c)
+ ut.add_command(c);
+ }
+ else
+ {
+ error << string_compose(_("Couldn't figure out how to make a Command out of a %1 XMLNode."), n->name()) << endmsg;
+ }
+ }
+ history.add(ut);
+ }
+ return 0;
+}
XMLNode &before = loc->get_state();
loc->set_end(_transport_frame);
XMLNode &after = loc->get_state();
- add_command (new MementoCommand<Location>(*loc, before, after));
+ add_command (new MementoCommand<Location>(*loc, &before, &after));
}
_end_location_is_free = false;
public:
MementoCommand(XMLNode &state);
MementoCommand(obj_T &obj,
- XMLNode &before,
- XMLNode &after
+ XMLNode *before,
+ XMLNode *after
)
: obj(obj), before(before), after(after) {}
- void operator() () { obj.set_state(after); }
- void undo() { obj.set_state(before); }
+ void operator() ()
+ {
+ if (after)
+ obj.set_state(*after);
+ }
+ void undo()
+ {
+ if (before)
+ obj.set_state(*before);
+ }
virtual XMLNode &get_state()
{
- XMLNode *node = new XMLNode("MementoCommand");
+ string name;
+ if (before && after)
+ name = "MementoCommand";
+ else if (before)
+ name = "MementoUndoCommand";
+ else
+ name = "MementoRedoCommand";
+
+ XMLNode *node = new XMLNode(name);
node->add_property("obj_id", obj.id().to_s());
node->add_property("type_name", typeid(obj).name());
- node->add_child_copy(before);
- node->add_child_copy(after);
+
+ if (before)
+ node->add_child_copy(*before);
+ if (after)
+ node->add_child_copy(*after);
+
return *node;
}
protected:
obj_T &obj;
- XMLNode &before, &after;
-};
-
-template <class obj_T>
-class MementoUndoCommand : public Command
-{
-public:
- MementoUndoCommand(XMLNode &state);
- MementoUndoCommand(obj_T &obj,
- XMLNode &before)
- : obj(obj), before(before) {}
- void operator() () { /* noop */ }
- void undo() { obj.set_state(before); }
- virtual XMLNode &get_state()
- {
- XMLNode *node = new XMLNode("MementoUndoCommand");
- node->add_property("obj_id", obj.id().to_s());
- node->add_property("type_name", typeid(obj).name());
- node->add_child_copy(before);
- return *node;
- }
-protected:
- obj_T &obj;
- XMLNode &before;
-};
-
-template <class obj_T>
-class MementoRedoCommand : public Command
-{
-public:
- MementoRedoCommand(XMLNode &state);
- MementoRedoCommand(obj_T &obj,
- XMLNode &after)
- : obj(obj), after(after) {}
- void operator() () { obj.set_state(after); }
- void undo() { /* noop */ }
- virtual XMLNode &get_state()
- {
- XMLNode *node = new XMLNode("MementoRedoCommand");
- node->add_property("obj_id", obj.id().to_s());
- node->add_property("type_name", typeid(obj).name());
- node->add_child_copy(after);
- return *node;
- }
-protected:
- obj_T &obj;
- XMLNode &after;
+ XMLNode *before, *after;
};
#endif // __lib_pbd_memento_h__
#define __pbd_stateful_h__
#include <string>
+#include <pbd/id.h>
class XMLNode;
virtual void add_instant_xml (XMLNode&, const std::string& dir);
XMLNode *instant_xml (const std::string& str, const std::string& dir);
+ PBD::ID id() { return _id; }
protected:
XMLNode *_extra_xml;
XMLNode *_instant_xml;
+ PBD::ID _id;
};
#endif /* __pbd_stateful_h__ */
#include <pbd/undo.h>
#include <pbd/xml++.h>
#include <string>
+#include <sstream>
using namespace std;
using namespace sigc;
XMLNode &UndoTransaction::get_state()
{
XMLNode *node = new XMLNode ("UndoTransaction");
+ stringstream ss;
+ ss << _timestamp.tv_sec;
+ node->add_property("tv_sec", ss.str());
+ ss.str("");
+ ss << _timestamp.tv_usec;
+ node->add_property("tv_usec", ss.str());
+ node->add_property("name", _name);
list<Command*>::iterator it;
for (it=actions.begin(); it!=actions.end(); it++)