Support recursive undo events.

Code can now call begin_reversible_command and commit_reversible_command around a region
of code which itself calls those functions (and so on), areas contained within enclosing
regions will be added as sub-commands of the current command (i.e. it's a stack).

Fixes mantix issue #0002558.


git-svn-id: svn://localhost/ardour2/branches/3.0@5051 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
David Robillard 2009-05-05 01:53:30 +00:00
parent 90c82a97a7
commit 83c27fa888
5 changed files with 32 additions and 25 deletions

View File

@ -400,13 +400,13 @@ Editor::mouse_add_new_marker (nframes64_t where, bool is_cd, bool is_xrun)
if (session) {
session->locations()->next_available_name(markername, markerprefix);
if (!is_xrun && !choose_new_marker_name(markername)) {
return;
return;
}
Location *location = new Location (where, where, markername, (Location::Flags) flags);
session->begin_reversible_command (_("add marker"));
XMLNode &before = session->locations()->get_state();
XMLNode &before = session->locations()->get_state();
session->locations()->add (location, true);
XMLNode &after = session->locations()->get_state();
XMLNode &after = session->locations()->get_state();
session->add_command (new MementoCommand<Locations>(*(session->locations()), &before, &after));
session->commit_reversible_command ();
@ -1042,7 +1042,7 @@ Editor::marker_menu_rename ()
loc = find_location_from_marker (marker, is_start);
if (!loc) return;
ArdourPrompter dialog (true);
string txt;
@ -1075,12 +1075,12 @@ Editor::marker_menu_rename ()
}
begin_reversible_command ( _("rename marker") );
XMLNode &before = session->locations()->get_state();
XMLNode &before = session->locations()->get_state();
dialog.get_result(txt);
loc->set_name (txt);
XMLNode &after = session->locations()->get_state();
XMLNode &after = session->locations()->get_state();
session->add_command (new MementoCommand<Locations>(*(session->locations()), &before, &after));
commit_reversible_command ();
}

View File

@ -337,7 +337,7 @@ Editor::edit_tempo_section (TempoSection* section)
tempo_dialog.set_position (Gtk::WIN_POS_MOUSE);
ensure_float (tempo_dialog);
switch (tempo_dialog.run ()) {
case RESPONSE_ACCEPT:
break;
@ -350,16 +350,16 @@ Editor::edit_tempo_section (TempoSection* section)
BBT_Time when;
tempo_dialog.get_bbt_time(when);
bpm = max (0.01, bpm);
cerr << "Editing tempo section to be at " << when << endl;
session->tempo_map().dump (cerr);
begin_reversible_command (_("replace tempo mark"));
XMLNode &before = session->tempo_map().get_state();
XMLNode &before = session->tempo_map().get_state();
session->tempo_map().replace_tempo (*section, Tempo (bpm,nt));
session->tempo_map().dump (cerr);
session->tempo_map().move_tempo (*section, when);
session->tempo_map().dump (cerr);
XMLNode &after = session->tempo_map().get_state();
XMLNode &after = session->tempo_map().get_state();
session->add_command (new MementoCommand<TempoMap>(session->tempo_map(), &before, &after));
commit_reversible_command ();
}

View File

@ -406,8 +406,8 @@ RhythmFerret::do_split_action ()
i = tmp;
}
session->commit_reversible_command ();
}
void

View File

@ -838,7 +838,8 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable
void commit_reversible_command (Command* cmd = 0);
void add_command (Command *const cmd) {
current_trans->add_command (cmd);
assert(!_current_trans.empty ());
_current_trans.top()->add_command (cmd);
}
std::map<PBD::ID, PBD::StatefulThingWithGoingAway*> registry;
@ -1613,8 +1614,8 @@ class Session : public PBD::StatefulDestructible, public boost::noncopyable
void reverse_diskstream_buffers ();
UndoHistory _history;
UndoTransaction* current_trans;
UndoHistory _history;
std::stack<UndoTransaction*> _current_trans;
GlobalRouteBooleanState get_global_route_boolean (bool (Route::*method)(void) const);
GlobalRouteMeterState get_global_route_metering ();

View File

@ -205,7 +205,6 @@ Session::first_stage_init (string fullpath, string snapshot_name)
_npan_buffers = 0;
pending_abort = false;
destructive_index = 0;
current_trans = 0;
first_file_data_format_reset = true;
first_file_header_format_reset = true;
butler_thread = (pthread_t) 0;
@ -2251,29 +2250,36 @@ Session::edit_group_by_name (string name)
}
void
Session::begin_reversible_command (const string& name)
Session::begin_reversible_command(const string& name)
{
current_trans = new UndoTransaction;
current_trans->set_name (name);
UndoTransaction* trans = new UndoTransaction();
trans->set_name(name);
if (!_current_trans.empty()) {
_current_trans.top()->add_command(trans);
}
_current_trans.push(trans);
}
void
Session::commit_reversible_command (Command *cmd)
Session::commit_reversible_command(Command *cmd)
{
assert(!_current_trans.empty());
struct timeval now;
if (cmd) {
current_trans->add_command (cmd);
_current_trans.top()->add_command(cmd);
}
if (current_trans->empty()) {
if (_current_trans.top()->empty()) {
_current_trans.pop();
return;
}
gettimeofday (&now, 0);
current_trans->set_timestamp (now);
gettimeofday(&now, 0);
_current_trans.top()->set_timestamp(now);
_history.add (current_trans);
_history.add(_current_trans.top());
_current_trans.pop();
}
Session::GlobalRouteBooleanState