diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 8a23208cf6..f1da5c6dcf 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -1920,40 +1920,44 @@ Editor::add_selection_context_items (Menu_Helpers::MenuList& edit_items) { using namespace Menu_Helpers; - edit_items.push_back (MenuElem (_("Play range"), mem_fun(*this, &Editor::play_selection))); - edit_items.push_back (MenuElem (_("Loop range"), bind (mem_fun(*this, &Editor::set_loop_from_selection), true))); + edit_items.push_back (MenuElem (_("Play Range"), mem_fun(*this, &Editor::play_selection))); + edit_items.push_back (MenuElem (_("Loop Range"), bind (mem_fun(*this, &Editor::set_loop_from_selection), true))); edit_items.push_back (SeparatorElem()); edit_items.push_back (MenuElem (_("Spectral Analysis"), mem_fun(*this, &Editor::analyze_range_selection))); - - edit_items.push_back (SeparatorElem()); - edit_items.push_back (MenuElem (_("Extend Range to End of Region"), bind (mem_fun(*this, &Editor::extend_selection_to_end_of_region), false))); - edit_items.push_back (MenuElem (_("Extend Range to Start of Region"), bind (mem_fun(*this, &Editor::extend_selection_to_start_of_region), false))); + + if (!selection->regions.empty()) { + edit_items.push_back (SeparatorElem()); + edit_items.push_back (MenuElem (_("Extend Range to End of Region"), bind (mem_fun(*this, &Editor::extend_selection_to_end_of_region), false))); + edit_items.push_back (MenuElem (_("Extend Range to Start of Region"), bind (mem_fun(*this, &Editor::extend_selection_to_start_of_region), false))); + } edit_items.push_back (SeparatorElem()); - edit_items.push_back (MenuElem (_("Convert to region in-place"), mem_fun(*this, &Editor::separate_region_from_selection))); - edit_items.push_back (MenuElem (_("Convert to region in region list"), mem_fun(*this, &Editor::new_region_from_selection))); + edit_items.push_back (MenuElem (_("Silence Range"), mem_fun(*this, &Editor::separate_region_from_selection))); + edit_items.push_back (MenuElem (_("Convert to Region in Region List"), mem_fun(*this, &Editor::new_region_from_selection))); edit_items.push_back (SeparatorElem()); - edit_items.push_back (MenuElem (_("Select all in range"), mem_fun(*this, &Editor::select_all_selectables_using_time_selection))); + edit_items.push_back (MenuElem (_("Select All in Range"), mem_fun(*this, &Editor::select_all_selectables_using_time_selection))); edit_items.push_back (SeparatorElem()); - edit_items.push_back (MenuElem (_("Set loop from selection"), bind (mem_fun(*this, &Editor::set_loop_from_selection), false))); - edit_items.push_back (MenuElem (_("Set punch from selection"), mem_fun(*this, &Editor::set_punch_from_selection))); + edit_items.push_back (MenuElem (_("Set Loop from Range"), bind (mem_fun(*this, &Editor::set_loop_from_selection), false))); + edit_items.push_back (MenuElem (_("Set Punch from Range"), mem_fun(*this, &Editor::set_punch_from_selection))); edit_items.push_back (SeparatorElem()); edit_items.push_back (MenuElem (_("Add Range Markers"), mem_fun (*this, &Editor::add_location_from_selection))); + edit_items.push_back (SeparatorElem()); - edit_items.push_back (MenuElem (_("Crop region to range"), mem_fun(*this, &Editor::crop_region_to_selection))); - edit_items.push_back (MenuElem (_("Fill range with region"), mem_fun(*this, &Editor::region_fill_selection))); - edit_items.push_back (MenuElem (_("Duplicate range"), bind (mem_fun(*this, &Editor::duplicate_dialog), false))); - edit_items.push_back (MenuElem (_("Create chunk from range"), mem_fun(*this, &Editor::create_named_selection))); + edit_items.push_back (MenuElem (_("Crop Region to Range"), mem_fun(*this, &Editor::crop_region_to_selection))); + edit_items.push_back (MenuElem (_("Fill Range with Region"), mem_fun(*this, &Editor::region_fill_selection))); + edit_items.push_back (MenuElem (_("Duplicate Range"), bind (mem_fun(*this, &Editor::duplicate_dialog), false))); + edit_items.push_back (MenuElem (_("Create Chunk from Range"), mem_fun(*this, &Editor::create_named_selection))); + edit_items.push_back (SeparatorElem()); - edit_items.push_back (MenuElem (_("Consolidate range"), bind (mem_fun(*this, &Editor::bounce_range_selection), true, false))); - edit_items.push_back (MenuElem (_("Consolidate range with processing"), bind (mem_fun(*this, &Editor::bounce_range_selection), true, true))); - edit_items.push_back (MenuElem (_("Bounce range to region list"), bind (mem_fun(*this, &Editor::bounce_range_selection), false, false))); - edit_items.push_back (MenuElem (_("Bounce range to region list with processing"), bind (mem_fun(*this, &Editor::bounce_range_selection), false, true))); - edit_items.push_back (MenuElem (_("Export range"), mem_fun(*this, &Editor::export_range))); + edit_items.push_back (MenuElem (_("Consolidate Range"), bind (mem_fun(*this, &Editor::bounce_range_selection), true, false))); + edit_items.push_back (MenuElem (_("Consolidate Range With Processing"), bind (mem_fun(*this, &Editor::bounce_range_selection), true, true))); + edit_items.push_back (MenuElem (_("Bounce Range to Region List"), bind (mem_fun(*this, &Editor::bounce_range_selection), false, false))); + edit_items.push_back (MenuElem (_("Bounce Range to Region List With Processing"), bind (mem_fun(*this, &Editor::bounce_range_selection), false, true))); + edit_items.push_back (MenuElem (_("Export Range"), mem_fun(*this, &Editor::export_range))); } @@ -4590,6 +4594,11 @@ Editor::set_punch_range (nframes64_t start, nframes64_t end, string cmd) commit_reversible_command (); } +/** Find regions which exist at a given time, and optionally on a given list of tracks. + * @param rs List to which found regions are added. + * @param where Time to look at. + * @param ts Tracks to look on; if this is empty, all tracks are examined. + */ void Editor::get_regions_at (RegionSelection& rs, nframes64_t where, const TrackSelection& ts) const { @@ -4662,11 +4671,21 @@ Editor::get_regions_after (RegionSelection& rs, nframes64_t where, const TrackSe } } +/** Find all regions which are either: + * - selected or + * - the entered_regionview (if allow_entered == true) or + * - under the preferred edit position AND on a selected track, or on a track + * which is in the same active edit-enable route group as a selected region. + * @param rs Returned region list. + * @param allow_entered true to include the entered_regionview in the list. + */ void Editor::get_regions_for_action (RegionSelection& rs, bool allow_entered) { + /* Start with selected regions */ rs = selection->regions; + /* Add the entered_regionview, if requested */ if (allow_entered && entered_regionview) { rs.add (entered_regionview); } @@ -4675,13 +4694,19 @@ Editor::get_regions_for_action (RegionSelection& rs, bool allow_entered) RegionSelection to_map = rs; + /* tracks is currently the set of selected tracks; add any other tracks that + * have regions that are in the same edit-activated route group as one of + * our regions */ for (RegionSelection::iterator i = to_map.begin (); i != to_map.end(); ++i) { RouteGroup* g = (*i)->get_time_axis_view().route_group (); if (g && g->active_property (RouteGroup::Edit)) { tracks.add (axis_views_from_routes (g->route_list())); } + } + /* now find regions that are at the edit position on those tracks */ + for (RegionSelection::iterator i = to_map.begin (); i != to_map.end(); ++i) { nframes64_t const where = get_preferred_edit_position (); get_regions_at (rs, where, tracks); } @@ -4690,7 +4715,6 @@ Editor::get_regions_for_action (RegionSelection& rs, bool allow_entered) void Editor::get_regions_corresponding_to (boost::shared_ptr region, vector& regions) { - for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { RouteTimeAxisView* tatv; diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index b1478d3922..5e2bb980e1 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -973,6 +973,8 @@ class Editor : public PublicEditor TimeAxisView* axis_view_from_route (ARDOUR::Route *) const; TrackSelection axis_views_from_routes (std::list) const; + TrackSelection get_tracks_for_range_action () const; + static Gdk::Cursor* cross_hair_cursor; static Gdk::Cursor* trimmer_cursor; static Gdk::Cursor* selector_cursor; diff --git a/gtk2_ardour/editor_markers.cc b/gtk2_ardour/editor_markers.cc index 019dd1757a..83a3beabc5 100644 --- a/gtk2_ardour/editor_markers.cc +++ b/gtk2_ardour/editor_markers.cc @@ -638,10 +638,9 @@ Editor::build_range_marker_menu (bool loop_or_punch) items.push_back (MenuElem (_("Hide Range"), mem_fun(*this, &Editor::marker_menu_hide))); items.push_back (MenuElem (_("Rename Range"), mem_fun(*this, &Editor::marker_menu_rename))); items.push_back (MenuElem (_("Remove Range"), mem_fun(*this, &Editor::marker_menu_remove))); + items.push_back (SeparatorElem()); } - items.push_back (SeparatorElem()); - items.push_back (MenuElem (_("Separate Regions in Range"), mem_fun(*this, &Editor::marker_menu_separate_regions_using_location))); items.push_back (MenuElem (_("Select All in Range"), mem_fun(*this, &Editor::marker_menu_select_all_selectables_using_range))); if (!Profile->get_sae()) { diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 1ab7d74645..55382bbaca 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -2693,9 +2693,11 @@ Editor::region_from_selection () nframes64_t start = selection->time[clicked_selection].start; nframes64_t end = selection->time[clicked_selection].end; + TrackSelection tracks = get_tracks_for_range_action (); + nframes64_t selection_cnt = end - start + 1; - for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) { + for (TrackSelection::iterator i = tracks.begin(); i != tracks.end(); ++i) { boost::shared_ptr current; boost::shared_ptr pl; nframes64_t internal_start; @@ -2786,41 +2788,52 @@ add_if_covered (RegionView* rv, const AudioRange* ar, RegionSelection* rs) } } +/** Return either: + * - selected tracks, or if there are none... + * - tracks containing selected regions, or if there are none... + * - all tracks + * @return tracks. + */ +TrackSelection +Editor::get_tracks_for_range_action () const +{ + TrackSelection t; + + if (selection->tracks.empty()) { + + /* use tracks with selected regions */ + + RegionSelection rs = selection->regions; + + for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) { + TimeAxisView* tv = &(*i)->get_time_axis_view(); + + if (!t.contains (tv)) { + t.push_back (tv); + } + } + + if (t.empty()) { + /* no regions and no tracks: use all tracks */ + t = track_views; + } + + } else { + + t = selection->tracks; + } + + return t; +} + void Editor::separate_regions_between (const TimeSelection& ts) { bool in_command = false; boost::shared_ptr playlist; RegionSelection new_selection; - TrackSelection tmptracks; - - if (selection->tracks.empty()) { - - /* use tracks with selected regions */ - - RegionSelection rs; - - get_regions_for_action (rs); - - for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) { - TimeAxisView* tv = &(*i)->get_time_axis_view(); - - if (find (tmptracks.begin(), tmptracks.end(), tv) == tmptracks.end()) { - tmptracks.push_back (tv); - } - } - - if (tmptracks.empty()) { - /* no regions selected: do nothing */ - return; - } - - } else { - - tmptracks = selection->tracks; - - } + TrackSelection tmptracks = get_tracks_for_range_action (); sort_track_selection (&tmptracks); for (TrackSelection::iterator i = tmptracks.begin(); i != tmptracks.end(); ++i) { @@ -2895,6 +2908,10 @@ Editor::separate_regions_between (const TimeSelection& ts) } } +/** Take tracks from get_tracks_for_range_action and cut any regions + * on those tracks so that the tracks are empty over the time + * selection. + */ void Editor::separate_region_from_selection () {