diff options
-rw-r--r-- | gtk2_ardour/ardour.menus.in | 4 | ||||
-rw-r--r-- | gtk2_ardour/editor.cc | 100 | ||||
-rw-r--r-- | gtk2_ardour/editor.h | 11 | ||||
-rw-r--r-- | gtk2_ardour/editor_actions.cc | 3 | ||||
-rw-r--r-- | gtk2_ardour/editor_drag.cc | 6 | ||||
-rw-r--r-- | gtk2_ardour/editor_mouse.cc | 4 | ||||
-rw-r--r-- | gtk2_ardour/editor_ops.cc | 7 | ||||
-rw-r--r-- | gtk2_ardour/editor_selection.cc | 67 | ||||
-rw-r--r-- | gtk2_ardour/selection.cc | 1 |
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 (); |