diff --git a/gtk2_ardour/ardour.keys.in b/gtk2_ardour/ardour.keys.in index a298625cef..1d368d06e1 100644 --- a/gtk2_ardour/ardour.keys.in +++ b/gtk2_ardour/ardour.keys.in @@ -464,7 +464,8 @@ This mode provides many different operations on both regions and control points, @notes|Notes/add-select-previous|<@PRIMARY@><@TERTIARY@>Tab|Add previous note to selection @notes|Notes/alt-add-select-next|<@TERTIARY@>ISO_Left_Tab|Add next note to selection @notes|Notes/alt-add-select-previous|<@PRIMARY@><@TERTIARY@>ISO_Left_Tab|Add previous note to selection - +@notes|Notes/extend-selection|<@PRIMARY@>e|Extend selection to end of region +@notes|Notes/invert-selection|<@PRIMARY@>i|Invert note selection @rec|Recorder/arm-all|<@PRIMARY@>r|record arm all tracks @rec|Recorder/arm-none|<@PRIMARY@><@TERTIARY@>r|disable record arm of all tracks diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc index 0d56ab6774..be6867ae99 100644 --- a/gtk2_ardour/editor_actions.cc +++ b/gtk2_ardour/editor_actions.cc @@ -739,6 +739,8 @@ Editor::register_midi_actions (Bindings* midi_bindings) ActionManager::register_action (_midi_actions, X_("alt-delete"), _("Delete Selection (alternate)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::delete_selection)); ActionManager::register_action (_midi_actions, X_("clear-selection"), _("Clear Note Selection"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::clear_note_selection)); + ActionManager::register_action (_midi_actions, X_("invert-selection"), _("Invert Note Selection"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::invert_selection)); + ActionManager::register_action (_midi_actions, X_("extend-selection"), _("Extend Note Selection"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::extend_selection)); ActionManager::register_action (_midi_actions, X_("move-starts-earlier-fine"), _("Move Note Start Earlier (fine)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::move_note_starts_earlier_fine)); ActionManager::register_action (_midi_actions, X_("move-starts-earlier"), _("Move Note Start Earlier"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::move_note_starts_earlier)); ActionManager::register_action (_midi_actions, X_("move-ends-later-fine"), _("Move Note Ends Later (fine)"), sigc::bind (sigc::mem_fun (*this, &Editor::midi_action), &MidiRegionView::move_note_ends_later_fine)); diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 73abdbaa64..17cc9009cc 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -2184,6 +2184,34 @@ MidiRegionView::select_range (samplepos_t start, samplepos_t end) } } +void +MidiRegionView::extend_selection () +{ + if (_selection.empty()) { + return; + } + + PBD::Unwinder uw (_no_sound_notes, true); + + /* find end of current selection */ + + samplepos_t last_note_end = 0; + + for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) { + samplepos_t e = source_beats_to_absolute_samples ((*i)->note()->end_time()); + if (e > last_note_end) { + last_note_end = e; + } + } + + for (Events::iterator i = _events.begin(); i != _events.end(); ++i) { + samplepos_t t = source_beats_to_absolute_samples(i->first->time()); + if (t >= last_note_end) { + add_to_selection (i->second); + } + } +} + void MidiRegionView::invert_selection () { diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h index 2fb21311c6..50c8666f49 100644 --- a/gtk2_ardour/midi_region_view.h +++ b/gtk2_ardour/midi_region_view.h @@ -207,6 +207,7 @@ public: void select_all_notes (); void select_range(samplepos_t start, samplepos_t end); void invert_selection (); + void extend_selection (); Temporal::Beats earliest_in_selection (); void move_selection(double dx, double dy, double cumulative_dy); @@ -371,6 +372,8 @@ public: friend class Editor; void clear_note_selection (); + void invert_note_selection (); + void extend_note_selection (); void move_note_starts_earlier_fine () { change_note_lengths (true, false, Temporal::Beats(), true, false); } void move_note_starts_earlier () { change_note_lengths (false, false, Temporal::Beats(), true, false); }