diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 3bdb9fbb13..48d6cf0c92 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -1200,7 +1200,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD void region_from_selection (); void create_region_from_selection (std::vector >&); - void cut_copy_region_from_selection (RegionSelection& new_regions, RouteTimeAxisView* rtv, bool follow_track_selection = false, bool copy = false); + void cut_copy_region_from_selection (RegionSelection& new_regions, bool copy = false); void play_from_start (); void play_from_edit_point (); @@ -1412,7 +1412,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD void start_create_region_grab (ArdourCanvas::Item*, GdkEvent*); void add_region_copy_drag (ArdourCanvas::Item*, GdkEvent*, RegionView*); void add_region_brush_drag (ArdourCanvas::Item*, GdkEvent*, RegionView*); - void start_selection_grab (ArdourCanvas::Item*, RouteTimeAxisView*, GdkEvent*, bool copy = false); + void start_selection_grab (ArdourCanvas::Item*, GdkEvent*, bool copy = false); void region_view_item_click (AudioRegionView&, GdkEventButton*); diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 8da223c431..c5da7ee0c7 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -4240,24 +4240,24 @@ SelectionDrag::motion (GdkEvent* event, bool first_move) if (_add) { /* adding to the selection */ - _editor->set_selected_track_as_side_effect (Selection::Add); - _editor->clicked_selection = _editor->selection->add (start, end); + // GZ: Waves TracksLive gives no possibility (by PRD) to add multiple time ranges + // but there used to be such possibility. + // kept the flag "_add" in case if we need it again _add = false; - } else { - - /* new selection */ - - if (_editor->clicked_axisview && !_editor->selection->selected (_editor->clicked_axisview)) { - _editor->set_selected_track_as_side_effect (Selection::Set); - } - - _editor->clicked_selection = _editor->selection->set (start, end); } + + /* new selection range selection */ + _editor->selection->time.tracks_in_range.clear(); + if (_editor->clicked_axisview ) { + _editor->selection->time.tracks_in_range.push_back (_editor->clicked_axisview ); + } + + _editor->clicked_selection = _editor->selection->set (start, end); } /* select all tracks within the rectangle that we've marked out so far */ - TrackViewList new_selection; + TrackViewList& tracks_in_range = _editor->selection->time.tracks_in_range; TrackViewList& all_tracks (_editor->track_views); ArdourCanvas::Coord const top = grab_y(); @@ -4267,37 +4267,35 @@ SelectionDrag::motion (GdkEvent* event, bool first_move) //first, find the tracks that are covered in the y range selection for (TrackViewList::const_iterator i = all_tracks.begin(); i != all_tracks.end(); ++i) { - if ((*i)->covered_by_y_range (top, bottom)) { - new_selection.push_back (*i); + if ((*i)->covered_by_y_range (top, bottom) && !tracks_in_range.contains(*i) ) { + + tracks_in_range.push_back (*i); } } - + +// GZ: Waves TrackLive does not support custom groups now, +// but we may need this in future versions +#if 0 //now find any tracks that are GROUPED with the tracks we selected - TrackViewList grouped_add = new_selection; - for (TrackViewList::const_iterator i = new_selection.begin(); i != new_selection.end(); ++i) { + TrackViewList grouped_tracks_to_add; + for (TrackViewList::const_iterator i = tracks_in_range.begin(); i != tracks_in_range.end(); ++i) { RouteTimeAxisView *n = dynamic_cast(*i); - if ( n && n->route()->route_group() && n->route()->route_group()->is_active() && n->route()->route_group()->enabled_property (ARDOUR::Properties::select.property_id) ) { - for (TrackViewList::const_iterator j = all_tracks.begin(); j != all_tracks.end(); ++j) { - RouteTimeAxisView *check = dynamic_cast(*j); - if ( check && (n != check) && (check->route()->route_group() == n->route()->route_group()) ) - grouped_add.push_back (*j); + if ( n && n->route()->route_group() && n->route()->route_group()->is_active() ) { + + boost::shared_ptr grouped_routes; + grouped_routes = n->route()->route_group()->route_list(); + RouteList::iterator j = grouped_routes->begin(); + for (; j != grouped_routes->end(); ++j) { + + RouteTimeAxisView *check = _editor->axis_view_from_route(*j); + if ( check && (n != check) ) + grouped_tracks_to_add.push_back(check); } } } - - //now compare our list with the current selection, and add or remove as necessary - //( NOTE: most mouse moves don't change the selection so we can't just SET it for every mouse move; it gets clunky ) - TrackViewList tracks_to_add; - TrackViewList tracks_to_remove; - for (TrackViewList::const_iterator i = grouped_add.begin(); i != grouped_add.end(); ++i) - if ( !_editor->selection->tracks.contains ( *i ) ) - tracks_to_add.push_back ( *i ); - for (TrackViewList::const_iterator i = _editor->selection->tracks.begin(); i != _editor->selection->tracks.end(); ++i) - if ( !grouped_add.contains ( *i ) ) - tracks_to_remove.push_back ( *i ); - _editor->selection->add(tracks_to_add); - _editor->selection->remove(tracks_to_remove); - + + tracks_in_range.add(grouped_tracks_to_add); +#endif } } break; @@ -4412,10 +4410,6 @@ SelectionDrag::finished (GdkEvent* event, bool movement_occurred) } } } - - if (_editor->clicked_axisview && !_editor->selection->selected (_editor->clicked_axisview)) { - _editor->selection->set (_editor->clicked_axisview); - } if (s && s->get_play_range () && s->transport_rolling()) { s->request_stop (false, false); diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index d5eff23491..e99f95886c 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -778,8 +778,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT separate-drag the selection. Well actually, Igor@Waves decided this, so here it is. */ - RouteTimeAxisView* rtv = dynamic_cast (tvp.first); - start_selection_grab (item, rtv, event, copy); + start_selection_grab (item, event, copy); return true; } } @@ -900,8 +899,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT separate-drag the selection. Well actually, Igor@Waves decided this, so here it is. */ - RouteTimeAxisView* rtv = dynamic_cast (tvp.first); - start_selection_grab (item, rtv, event, copy); + start_selection_grab (item, event, copy); return true; } } @@ -2458,13 +2456,13 @@ Editor::add_region_brush_drag (ArdourCanvas::Item* item, GdkEvent*, RegionView* * the section of the clicked region that lies within the time range. */ void -Editor::start_selection_grab (ArdourCanvas::Item* item, RouteTimeAxisView* rtv, GdkEvent* event, bool copy/*=false*/) +Editor::start_selection_grab (ArdourCanvas::Item* item, GdkEvent* event, bool copy/*=false*/) { /* lets try to create new Region for the selection */ begin_reversible_command (_("new region for selection drag")); RegionSelection new_regions; - cut_copy_region_from_selection (new_regions, rtv, true, copy); + cut_copy_region_from_selection (new_regions, copy); commit_reversible_command (); diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 7618886df7..5d5c019453 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -2714,24 +2714,19 @@ Editor::create_region_from_selection (vector >& new_re } void -Editor::cut_copy_region_from_selection (RegionSelection& new_regions, RouteTimeAxisView* rtv, bool follow_track_selection/*=false*/, bool copy /*=false*/) +Editor::cut_copy_region_from_selection (RegionSelection& new_regions, bool copy /*=false*/) { new_regions.clear(); - if (selection->time.empty() || selection->tracks.empty() ) { + if (selection->time.empty() || selection->time.tracks_in_range.empty() ) { return; } - TrackViewList ts; - if (follow_track_selection) { - ts = selection->tracks.filter_to_unique_playlists (); - sort_track_selection (ts); - } else { - if (rtv) { - ts.push_back(rtv); - } - } + // get track views associated with time selection + TrackViewList ts = selection->time.tracks_in_range.filter_to_unique_playlists (); + sort_track_selection (ts); + // latest_regionviews contains latest processed regions latest_regionviews.clear(); for (TrackSelection::iterator i = ts.begin(); i != ts.end(); ++i) { @@ -2741,11 +2736,15 @@ Editor::cut_copy_region_from_selection (RegionSelection& new_regions, RouteTimeA continue; } + // form selection object to get new cut/copied regions Selection new_items(this); - route_view->cut_copy_range(*selection, copy, new_items); + route_view->cut_copy_region_from_range(*selection, copy, new_items); + // connect this collect_new_region_view method to RegionViewAdded signal + // to collect newly pasted regions in latest_regionviews container sigc::connection c = route_view->view()->RegionViewAdded.connect (sigc::mem_fun(*this, &Editor::collect_new_region_view)); + // paste cut/copied regions back AudioRange range = selection->time[clicked_selection]; route_view->paste(range.start, 1, new_items, 0); @@ -4373,7 +4372,7 @@ Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs) void Editor::cut_copy_ranges (CutCopyOp op) { - TrackViewList ts = selection->tracks.filter_to_unique_playlists (); + TrackViewList ts = selection->time.tracks_in_range.filter_to_unique_playlists (); /* Sort the track selection now, so that it if is used, the playlists selected by the calls below to cut_copy_clear are in the order that diff --git a/gtk2_ardour/editor_selection.cc b/gtk2_ardour/editor_selection.cc index 12c62eec4d..fb9ba921f1 100644 --- a/gtk2_ardour/editor_selection.cc +++ b/gtk2_ardour/editor_selection.cc @@ -1005,13 +1005,6 @@ Editor::track_selection_changed () (*j)->set_selected (std::find (selection->tracks.begin(), selection->tracks.end(), j->get()) != selection->tracks.end()); } - if (yn) { - (*i)->reshow_selection (selection->time); - } else { - (*i)->hide_selection (); - } - - if (yn) { RouteTimeAxisView* rtav = dynamic_cast (*i); if (rtav) { @@ -1060,9 +1053,13 @@ Editor::time_selection_changed () (*i)->hide_selection (); } - for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) { - (*i)->show_selection (selection->time); - } + { // Now show time range selection on all affected tracks + TrackViewList& track_to_process = selection->time.tracks_in_range; + TrackViewList::iterator i = track_to_process.begin(); + for (; i != track_to_process.end(); ++i) { + (*i)->show_selection (selection->time); + } + } if (selection->time.empty()) { ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false); diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc index e88bfbeb71..6eb9574c43 100644 --- a/gtk2_ardour/route_time_axis.cc +++ b/gtk2_ardour/route_time_axis.cc @@ -1454,12 +1454,13 @@ RouteTimeAxisView::fade_range (TimeSelection& selection) vector cmds; playlist->rdiff (cmds); _session->add_commands (cmds); + _session->add_command (new StatefulDiffCommand (playlist)); } void -RouteTimeAxisView::cut_copy_range (Selection& selection, bool copy, Selection& new_items) +RouteTimeAxisView::cut_copy_region_from_range (Selection& selection, bool copy, Selection& new_items) { new_items.clear(); @@ -1498,11 +1499,18 @@ RouteTimeAxisView::cut_copy_range (Selection& selection, bool copy, Selection& n new_items.set (what_we_got); if (Config->get_edit_mode() == Ripple) playlist->ripple(time.start(), -time.length(), NULL); + + vector cmds; + playlist->rdiff (cmds); + _session->add_commands (cmds); + + _session->add_command (new StatefulDiffCommand (playlist)); } } } + void RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op) { @@ -1526,8 +1534,8 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op) } } - playlist->clear_changes (); - playlist->clear_owned_changes (); + playlist->clear_changes (); + playlist->clear_owned_changes (); switch (op) { case Delete: @@ -1536,11 +1544,11 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op) playlist->ripple(time.start(), -time.length(), NULL); // no need to exclude any regions from rippling here - vector cmds; - playlist->rdiff (cmds); - _session->add_commands (cmds); - - _session->add_command (new StatefulDiffCommand (playlist)); + vector cmds; + playlist->rdiff (cmds); + _session->add_commands (cmds); + + _session->add_command (new StatefulDiffCommand (playlist)); } break; @@ -1551,11 +1559,11 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op) playlist->ripple(time.start(), -time.length(), NULL); // no need to exclude any regions from rippling here - vector cmds; - playlist->rdiff (cmds); - _session->add_commands (cmds); + vector cmds; + playlist->rdiff (cmds); + _session->add_commands (cmds); - _session->add_command (new StatefulDiffCommand (playlist)); + _session->add_command (new StatefulDiffCommand (playlist)); } break; case Copy: @@ -1570,10 +1578,12 @@ RouteTimeAxisView::cut_copy_clear (Selection& selection, CutCopyOp op) playlist->ripple(time.start(), -time.length(), NULL); // no need to exclude any regions from rippling here - vector cmds; - playlist->rdiff (cmds); + vector cmds; + playlist->rdiff (cmds); _session->add_commands (cmds); - _session->add_command (new StatefulDiffCommand (playlist)); + + _session->add_command (new StatefulDiffCommand (playlist)); + what_we_got->release (); } break; diff --git a/gtk2_ardour/route_time_axis.h b/gtk2_ardour/route_time_axis.h index 399728044a..9656d9e280 100644 --- a/gtk2_ardour/route_time_axis.h +++ b/gtk2_ardour/route_time_axis.h @@ -111,7 +111,7 @@ public: void uncombine_region (RegionView*); void toggle_automation_track (const Evoral::Parameter& param); void fade_range (TimeSelection&); - void cut_copy_range (Selection& selection, bool copy, Selection& new_items); + void cut_copy_region_from_range (Selection& selection, bool copy, Selection& new_items); /* The editor calls these when mapping an operation across multiple tracks */ void use_new_playlist (bool prompt, std::vector > const &); diff --git a/gtk2_ardour/selection.cc b/gtk2_ardour/selection.cc index 5207de35ec..c092347986 100644 --- a/gtk2_ardour/selection.cc +++ b/gtk2_ardour/selection.cc @@ -140,7 +140,8 @@ void Selection::clear_time () { time.clear(); - + time.tracks_in_range.clear(); + TimeChanged (); } diff --git a/gtk2_ardour/time_axis_view.cc b/gtk2_ardour/time_axis_view.cc index e25b78d6ac..4d8a20f430 100644 --- a/gtk2_ardour/time_axis_view.cc +++ b/gtk2_ardour/time_axis_view.cc @@ -709,9 +709,9 @@ TimeAxisView::popup_display_menu (guint32 when) void TimeAxisView::set_selected (bool yn) { - if (can_edit_name() && name_entry.get_visible()) { - end_name_edit (RESPONSE_CANCEL); - } + if (can_edit_name() && name_entry.get_visible()) { + end_name_edit (RESPONSE_CANCEL); + } if (yn == _selected) { return; @@ -721,9 +721,9 @@ TimeAxisView::set_selected (bool yn) if (_selected) { controls_event_box.set_state (Gtk::STATE_ACTIVE); + } else { controls_event_box.set_state (Gtk::STATE_NORMAL); - hide_selection (); /* children will be set for the yn=true case. but when deselecting the editor only has a list of top-level trackviews, so we @@ -775,6 +775,10 @@ TimeAxisView::hide_timestretch () void TimeAxisView::show_selection (TimeSelection& ts) { + if (!ts.tracks_in_range.contains(this) ) { + return; + } + double x1; double x2; double y2; diff --git a/gtk2_ardour/time_selection.h b/gtk2_ardour/time_selection.h index 413cb75de6..9d381bc71d 100644 --- a/gtk2_ardour/time_selection.h +++ b/gtk2_ardour/time_selection.h @@ -22,6 +22,7 @@ #include #include "ardour/types.h" +#include "track_view_list.h" namespace ARDOUR { class RouteGroup; @@ -32,11 +33,13 @@ class TimeSelection : public std::list public: ARDOUR::AudioRange& operator[](uint32_t); - ARDOUR::framepos_t start(); - ARDOUR::framepos_t end_frame(); - ARDOUR::framepos_t length(); - + ARDOUR::framepos_t start(); + ARDOUR::framepos_t end_frame(); + ARDOUR::framepos_t length(); + bool consolidate (); + + TrackViewList tracks_in_range; };