summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/ardour.menus.in4
-rw-r--r--gtk2_ardour/editor.cc100
-rw-r--r--gtk2_ardour/editor.h11
-rw-r--r--gtk2_ardour/editor_actions.cc3
-rw-r--r--gtk2_ardour/editor_drag.cc6
-rw-r--r--gtk2_ardour/editor_mouse.cc4
-rw-r--r--gtk2_ardour/editor_ops.cc7
-rw-r--r--gtk2_ardour/editor_selection.cc67
-rw-r--r--gtk2_ardour/selection.cc1
9 files changed, 177 insertions, 26 deletions
diff --git a/gtk2_ardour/ardour.menus.in b/gtk2_ardour/ardour.menus.in
index 53eeb745d5..e713f99c6e 100644
--- a/gtk2_ardour/ardour.menus.in
+++ b/gtk2_ardour/ardour.menus.in
@@ -151,6 +151,10 @@
<menu name='Edit' action='Edit'>
<menuitem action='undo'/>
<menuitem action='redo'/>
+ <separator/>
+ <menuitem action='undo-last-selection-op'/>
+ <menuitem action='redo-last-selection-op'/>
+ <separator/>
<menuitem action='editor-cut'/>
<menuitem action='editor-copy'/>
<menuitem action='editor-paste'/>
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index 93bbbd6805..3598642dfd 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -284,6 +284,8 @@ Editor::Editor ()
, _tools_tearoff (0)
, _toolbar_viewport (*manage (new Gtk::Adjustment (0, 0, 1e10)), *manage (new Gtk::Adjustment (0, 0, 1e10)))
+ , selection_op_cmd_depth (0)
+ , selection_op_history_it (0)
/* nudge */
@@ -309,6 +311,7 @@ Editor::Editor ()
selection = new Selection (this);
cut_buffer = new Selection (this);
_selection_memento = new SelectionMemento ();
+ selection_op_history.clear();
before.clear();
clicked_regionview = 0;
@@ -3312,6 +3315,95 @@ Editor::map_transport_state ()
/* UNDO/REDO */
void
+Editor::begin_selection_op_history ()
+{
+ selection_op_cmd_depth = 0;
+ selection_op_history_it = 0;
+ selection_op_history.clear();
+ selection_undo_action->set_sensitive (false);
+ selection_redo_action->set_sensitive (false);
+ selection_op_history.push_front (&_selection_memento->get_state ());
+}
+
+void
+Editor::begin_reversible_selection_op (string name)
+{
+ if (_session) {
+ //cerr << name << endl;
+ /* begin/commit pairs can be nested */
+ selection_op_cmd_depth++;
+ }
+}
+
+void
+Editor::commit_reversible_selection_op ()
+{
+ if (_session) {
+ if (selection_op_cmd_depth == 1) {
+
+ if (selection_op_history_it > 0 && selection_op_history_it < selection_op_history.size()) {
+ list<XMLNode *>::iterator it = selection_op_history.begin();
+ advance (it, selection_op_history_it);
+ selection_op_history.erase (selection_op_history.begin(), it);
+ }
+ selection_op_history.push_front (&_selection_memento->get_state ());
+ selection_op_history_it = 0;
+ }
+
+ if (selection_op_cmd_depth > 0) {
+ selection_op_cmd_depth--;
+ }
+
+ selection_undo_action->set_sensitive (true);
+ selection_redo_action->set_sensitive (false);
+ }
+}
+
+void
+Editor::undo_reversible_selection_op ()
+{
+ if (_session) {
+ selection_op_history_it++;
+ uint32_t n = 0;
+ for (std::list<XMLNode *>::iterator i = selection_op_history.begin(); i != selection_op_history.end(); ++i) {
+ if (n == selection_op_history_it) {
+ _selection_memento->set_state (*(*i), Stateful::current_state_version);
+ selection_redo_action->set_sensitive (true);
+ }
+ ++n;
+
+ }
+ /* is there an earlier entry? */
+ if ((selection_op_history_it + 1) >= selection_op_history.size()) {
+ selection_undo_action->set_sensitive (false);
+ }
+ }
+}
+
+void
+Editor::redo_reversible_selection_op ()
+{
+ if (_session) {
+ if (selection_op_history_it > 0) {
+ selection_op_history_it--;
+ }
+ uint32_t n = 0;
+ for (std::list<XMLNode *>::iterator i = selection_op_history.begin(); i != selection_op_history.end(); ++i) {
+ if (n == selection_op_history_it) {
+ _selection_memento->set_state (*(*i), Stateful::current_state_version);
+ selection_undo_action->set_sensitive (true);
+ }
+ ++n;
+
+ }
+
+ if (selection_op_history_it == 0) {
+ selection_redo_action->set_sensitive (false);
+ }
+ }
+}
+
+void
Editor::begin_reversible_command (string name)
{
if (_session) {
@@ -3335,9 +3427,12 @@ Editor::commit_reversible_command ()
if (_session) {
if (before.size() == 1) {
_session->add_command (new MementoCommand<SelectionMemento>(*(_selection_memento), before.front(), &_selection_memento->get_state ()));
+ begin_selection_op_history ();
}
- if (!before.empty()) {
+ if (before.empty()) {
+ cerr << "Please call begin_reversible_command() before commit_reversible_command()." << endl;
+ } else {
before.pop_back();
}
@@ -4922,6 +5017,9 @@ Editor::first_idle ()
_routes->redisplay ();
delete dialog;
+
+ begin_selection_op_history ();
+
_have_idled = true;
}
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 4addfadb60..4740fbf2c5 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -440,6 +440,11 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
ARDOUR::RoundMode direction = ARDOUR::RoundNearest,
bool for_mark = false);
+ void begin_selection_op_history ();
+ void begin_reversible_selection_op (std::string cmd_name);
+ void commit_reversible_selection_op ();
+ void undo_reversible_selection_op ();
+ void redo_reversible_selection_op ();
void begin_reversible_command (std::string cmd_name);
void begin_reversible_command (GQuark);
void commit_reversible_command ();
@@ -1941,6 +1946,10 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void write_selection ();
+ uint32_t selection_op_cmd_depth;
+ uint32_t selection_op_history_it;
+
+ std::list<XMLNode *> selection_op_history; /* used in *_reversible_selection_op */
std::list<XMLNode *> before; /* used in *_reversible_command */
void update_title ();
@@ -2066,6 +2075,8 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
Glib::RefPtr<Gtk::Action> undo_action;
Glib::RefPtr<Gtk::Action> redo_action;
+ Glib::RefPtr<Gtk::Action> selection_undo_action;
+ Glib::RefPtr<Gtk::Action> selection_redo_action;
void history_changed ();
diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc
index 8f24a4b91b..c7bda7c25e 100644
--- a/gtk2_ardour/editor_actions.cc
+++ b/gtk2_ardour/editor_actions.cc
@@ -317,6 +317,9 @@ Editor::register_actions ()
redo_action = reg_sens (editor_actions, "alternate-redo", _("Redo"), sigc::bind (sigc::mem_fun(*this, &Editor::redo), 1U));
redo_action = reg_sens (editor_actions, "alternate-alternate-redo", _("Redo"), sigc::bind (sigc::mem_fun(*this, &Editor::redo), 1U));
+ selection_undo_action = reg_sens (editor_actions, "undo-last-selection-op", _("Undo Last Selection Op"), sigc::mem_fun(*this, &Editor::undo_reversible_selection_op));
+ selection_redo_action = reg_sens (editor_actions, "redo-last-selection-op", _("Redo Last Selection Op"), sigc::mem_fun(*this, &Editor::redo_reversible_selection_op));
+
reg_sens (editor_actions, "export-audio", _("Export Audio"), sigc::mem_fun(*this, &Editor::export_audio));
reg_sens (editor_actions, "export-range", _("Export Range"), sigc::mem_fun(*this, &Editor::export_range));
diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc
index b86c265610..965092e65f 100644
--- a/gtk2_ardour/editor_drag.cc
+++ b/gtk2_ardour/editor_drag.cc
@@ -4379,6 +4379,7 @@ SelectionDrag::finished (GdkEvent* event, bool movement_occurred)
{
Session* s = _editor->session();
+ _editor->begin_reversible_selection_op (_("Change Time Selection"));
if (movement_occurred) {
motion (event, false);
/* XXX this is not object-oriented programming at all. ick */
@@ -4435,6 +4436,7 @@ SelectionDrag::finished (GdkEvent* event, bool movement_occurred)
_editor->stop_canvas_autoscroll ();
_editor->clicked_selection = 0;
+ _editor->commit_reversible_selection_op ();
}
void
@@ -5192,11 +5194,11 @@ EditorRubberbandSelectDrag::select_things (int button_state, framepos_t x1, fram
Selection::Operation op = ArdourKeyboard::selection_type (button_state);
- _editor->begin_reversible_command (_("rubberband selection"));
+ _editor->begin_reversible_selection_op (_("rubberband selection"));
_editor->select_all_within (x1, x2 - 1, y1, y2, _editor->track_views, op, false);
- _editor->commit_reversible_command ();
+ _editor->commit_reversible_selection_op ();
}
void
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index 51b6795b1a..e093eb5426 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -1465,7 +1465,11 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
}
/* do any (de)selection operations that should occur on button release */
+
+ begin_reversible_selection_op (_("Button Select"));
button_selection (item, event, item_type);
+ commit_reversible_selection_op ();
+
return true;
break;
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index 625579d6a8..a99da327db 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -122,6 +122,8 @@ Editor::undo (uint32_t n)
if (_session) {
_session->undo (n);
+ redo_action->set_sensitive(true);
+ begin_selection_op_history ();
}
}
@@ -134,6 +136,11 @@ Editor::redo (uint32_t n)
if (_session) {
_session->redo (n);
+ cerr << "redo depth is : " << _session->redo_depth() << endl;
+ if (_session->redo_depth() == 0) {
+ redo_action->set_sensitive(false);
+ }
+ begin_selection_op_history ();
}
}
diff --git a/gtk2_ardour/editor_selection.cc b/gtk2_ardour/editor_selection.cc
index 002785e6dc..962d7dc8c9 100644
--- a/gtk2_ardour/editor_selection.cc
+++ b/gtk2_ardour/editor_selection.cc
@@ -270,6 +270,8 @@ Editor::set_selected_track_as_side_effect (Selection::Operation op)
void
Editor::set_selected_track (TimeAxisView& view, Selection::Operation op, bool no_remove)
{
+ begin_reversible_selection_op(_("Set Selected Track"));
+
switch (op) {
case Selection::Toggle:
if (selection->selected (&view)) {
@@ -295,6 +297,8 @@ Editor::set_selected_track (TimeAxisView& view, Selection::Operation op, bool no
extend_selection_to_track (view);
break;
}
+
+ commit_reversible_selection_op ();
}
void
@@ -892,7 +896,7 @@ Editor::set_selected_regionview_from_region_list (boost::shared_ptr<Region> regi
return;
}
- begin_reversible_command (_("set selected regions"));
+ begin_reversible_selection_op (_("set selected regions"));
switch (op) {
case Selection::Toggle:
@@ -910,7 +914,7 @@ Editor::set_selected_regionview_from_region_list (boost::shared_ptr<Region> regi
break;
}
- commit_reversible_command () ;
+ commit_reversible_selection_op () ;
}
bool
@@ -935,11 +939,11 @@ Editor::set_selected_regionview_from_map_event (GdkEventAny* /*ev*/, StreamView*
return true;
}
- begin_reversible_command (_("set selected regions"));
+ begin_reversible_selection_op (_("set selected regions"));
selection->set (rv);
- commit_reversible_command () ;
+ commit_reversible_selection_op () ;
return true;
}
@@ -1348,6 +1352,8 @@ Editor::select_all_in_track (Selection::Operation op)
return;
}
+ begin_reversible_selection_op(_("Select All in Track"));
+
clicked_routeview->get_selectables (0, max_framepos, 0, DBL_MAX, touched);
switch (op) {
@@ -1364,6 +1370,8 @@ Editor::select_all_in_track (Selection::Operation op)
selection->add (touched);
break;
}
+
+ commit_reversible_selection_op ();
}
bool
@@ -1408,7 +1416,7 @@ Editor::select_all_objects (Selection::Operation op)
}
- begin_reversible_command (_("select all"));
+ begin_reversible_selection_op (_("select all"));
switch (op) {
case Selection::Add:
selection->add (touched);
@@ -1423,7 +1431,7 @@ Editor::select_all_objects (Selection::Operation op)
/* meaningless, because we're selecting everything */
break;
}
- commit_reversible_command ();
+ commit_reversible_selection_op ();
}
void
@@ -1435,8 +1443,10 @@ Editor::invert_selection_in_track ()
return;
}
+ begin_reversible_selection_op(_("Invert Selection in Track"));
clicked_routeview->get_inverted_selectables (*selection, touched);
selection->set (touched);
+ commit_reversible_selection_op ();
}
void
@@ -1461,7 +1471,9 @@ Editor::invert_selection ()
(*iter)->get_inverted_selectables (*selection, touched);
}
+ begin_reversible_selection_op(_("Invert Selection"));
selection->set (touched);
+ commit_reversible_selection_op ();
}
/** @param start Start time in session frames.
@@ -1502,7 +1514,7 @@ Editor::select_all_within (framepos_t start, framepos_t end, double top, double
}
}
- begin_reversible_command (_("select all within"));
+ begin_reversible_selection_op (_("select all within"));
switch (op) {
case Selection::Add:
selection->add (found);
@@ -1518,7 +1530,7 @@ Editor::select_all_within (framepos_t start, framepos_t end, double top, double
break;
}
- commit_reversible_command ();
+ commit_reversible_selection_op ();
}
void
@@ -1560,9 +1572,9 @@ Editor::set_selection_from_loop()
void
Editor::set_selection_from_range (Location& loc)
{
- begin_reversible_command (_("set selection from range"));
+ begin_reversible_selection_op (_("set selection from range"));
selection->set (loc.start(), loc.end());
- commit_reversible_command ();
+ commit_reversible_selection_op ();
if (!Profile->get_sae()) {
set_mouse_mode (Editing::MouseRange, false);
@@ -1600,9 +1612,9 @@ Editor::select_all_selectables_using_time_selection ()
(*iter)->get_selectables (start, end - 1, 0, DBL_MAX, touched);
}
- begin_reversible_command (_("select all from range"));
+ begin_reversible_selection_op (_("select all from range"));
selection->set (touched);
- commit_reversible_command ();
+ commit_reversible_selection_op ();
}
@@ -1631,9 +1643,9 @@ Editor::select_all_selectables_using_punch()
}
(*iter)->get_selectables (location->start(), location->end() - 1, 0, DBL_MAX, touched);
}
- begin_reversible_command (_("select all from punch"));
+ begin_reversible_selection_op (_("select all from punch"));
selection->set (touched);
- commit_reversible_command ();
+ commit_reversible_selection_op ();
}
@@ -1662,9 +1674,9 @@ Editor::select_all_selectables_using_loop()
}
(*iter)->get_selectables (location->start(), location->end() - 1, 0, DBL_MAX, touched);
}
- begin_reversible_command (_("select all from loop"));
+ begin_reversible_selection_op (_("select all from loop"));
selection->set (touched);
- commit_reversible_command ();
+ commit_reversible_selection_op ();
}
@@ -1698,9 +1710,9 @@ Editor::select_all_selectables_using_cursor (EditorCursor *cursor, bool after)
}
if (after) {
- begin_reversible_command (_("select all after cursor"));
+ begin_reversible_selection_op (_("select all after cursor"));
} else {
- begin_reversible_command (_("select all before cursor"));
+ begin_reversible_selection_op (_("select all before cursor"));
}
TrackViewList* ts;
@@ -1718,7 +1730,7 @@ Editor::select_all_selectables_using_cursor (EditorCursor *cursor, bool after)
(*iter)->get_selectables (start, end, 0, DBL_MAX, touched);
}
selection->set (touched);
- commit_reversible_command ();
+ commit_reversible_selection_op ();
}
void
@@ -1749,9 +1761,9 @@ Editor::select_all_selectables_using_edit (bool after)
}
if (after) {
- begin_reversible_command (_("select all after edit"));
+ begin_reversible_selection_op (_("select all after edit"));
} else {
- begin_reversible_command (_("select all before edit"));
+ begin_reversible_selection_op (_("select all before edit"));
}
TrackViewList* ts;
@@ -1769,7 +1781,7 @@ Editor::select_all_selectables_using_edit (bool after)
(*iter)->get_selectables (start, end, 0, DBL_MAX, touched);
}
selection->set (touched);
- commit_reversible_command ();
+ commit_reversible_selection_op ();
}
void
@@ -1806,7 +1818,9 @@ Editor::select_all_selectables_between (bool /*within*/)
(*iter)->get_selectables (start, end, 0, DBL_MAX, touched);
}
+ begin_reversible_selection_op(_("Select all Selectables Between"));
selection->set (touched);
+ commit_reversible_selection_op ();
}
void
@@ -1823,8 +1837,10 @@ Editor::select_range_between ()
return;
}
+ begin_reversible_selection_op(_("Select Range Between"));
set_mouse_mode (MouseRange);
selection->set (start, end);
+ commit_reversible_selection_op ();
}
bool
@@ -1931,13 +1947,18 @@ Editor::get_edit_op_range (framepos_t& start, framepos_t& end) const
void
Editor::deselect_all ()
{
+ begin_reversible_selection_op(_("Clear Selection"));
selection->clear ();
+ commit_reversible_selection_op ();
}
long
Editor::select_range (framepos_t s, framepos_t e)
{
+ begin_reversible_selection_op(_("Select Range"));
selection->add (clicked_axisview);
selection->time.clear ();
- return selection->set (s, e);
+ long ret = selection->set (s, e);
+ commit_reversible_selection_op ();
+ return ret;
}
diff --git a/gtk2_ardour/selection.cc b/gtk2_ardour/selection.cc
index ae00c4f8c4..6d07564f2c 100644
--- a/gtk2_ardour/selection.cc
+++ b/gtk2_ardour/selection.cc
@@ -1261,6 +1261,7 @@ Selection::set_state (XMLNode const & node, int)
}
clear_regions ();
+ clear_points ();
clear_time ();
clear_tracks ();
clear_markers ();