+ if (new_regionviews.empty()) {
+ return;
+ }
+
+ /* reset selection to new regionviews. This will not set selection visual status for
+ these regionviews since they don't belong to a track, so do that by hand too.
+ */
+
+ selection->set (new_regionviews);
+
+ for (vector<RegionView*>::iterator i = new_regionviews.begin(); i != new_regionviews.end(); ++i) {
+ (*i)->set_selected (true);
+ }
+
+ /* reset drag_info data to reflect the fact that we are dragging the copies */
+
+ drag_info.data = new_regionviews.front();
+
+ swap_grab (new_regionviews.front()->get_canvas_group (), 0, event->motion.time);
+ }
+}
+
+bool
+Editor::check_region_drag_possible (AudioTimeAxisView** tv)
+{
+ /* Which trackview is this ? */
+
+ TimeAxisView* tvp = trackview_by_y_position (drag_info.current_pointer_y);
+ (*tv) = dynamic_cast<AudioTimeAxisView*>(tvp);
+
+ /* The region motion is only processed if the pointer is over
+ an audio track.
+ */
+
+ if (!(*tv) || !(*tv)->is_audio_track()) {
+ /* To make sure we hide the verbose canvas cursor when the mouse is
+ not held over and audiotrack.
+ */
+ hide_verbose_canvas_cursor ();
+ return false;
+ }
+
+ return true;
+}
+
+struct RegionSelectionByPosition {
+ bool operator() (RegionView*a, RegionView* b) {
+ return a->region()->position () < b->region()->position();
+ }
+};
+
+void
+Editor::region_drag_splice_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
+{
+ AudioTimeAxisView* tv;
+
+ if (!check_region_drag_possible (&tv)) {
+ return;
+ }
+
+ if (!drag_info.move_threshold_passed) {
+ return;
+ }
+
+ int dir;
+
+ if (drag_info.current_pointer_x - drag_info.grab_x > 0) {
+ dir = 1;
+ } else {
+ dir = -1;
+ }
+
+ RegionSelection copy (selection->regions);
+
+ RegionSelectionByPosition cmp;
+ copy.sort (cmp);
+
+ for (RegionSelection::iterator i = copy.begin(); i != copy.end(); ++i) {
+
+ AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (&(*i)->get_time_axis_view());
+
+ if (!atv) {
+ continue;
+ }
+
+ boost::shared_ptr<Playlist> playlist;
+
+ if ((playlist = atv->playlist()) == 0) {
+ continue;
+ }
+
+ if (!playlist->region_is_shuffle_constrained ((*i)->region())) {
+ continue;
+ }
+
+ if (dir > 0) {
+ if (drag_info.current_pointer_frame < (*i)->region()->last_frame() + 1) {
+ continue;
+ }
+ } else {
+ if (drag_info.current_pointer_frame > (*i)->region()->first_frame()) {
+ continue;
+ }