+void
+Editor::track_canvas_drag_data_received (const RefPtr<Gdk::DragContext>& context,
+ int x, int y,
+ const SelectionData& data,
+ guint info, guint time)
+{
+ if (data.get_target() == "regions") {
+ drop_regions (context, x, y, data, info, time);
+ } else {
+ drop_paths (context, x, y, data, info, time);
+ }
+}
+
+void
+Editor::drop_paths (const RefPtr<Gdk::DragContext>& context,
+ int x, int y,
+ const SelectionData& data,
+ guint info, guint time)
+{
+ TimeAxisView* tvp;
+ AudioTimeAxisView* tv;
+ double cy;
+ vector<ustring> paths;
+ string spath;
+ GdkEvent ev;
+ jack_nframes_t frame;
+
+ if (convert_drop_to_paths (paths, context, x, y, data, info, time)) {
+ goto out;
+ }
+
+ /* D-n-D coordinates are window-relative, so convert to "world" coordinates
+ */
+
+ double wx;
+ double wy;
+
+ track_canvas.window_to_world (x, y, wx, wy);
+ wx += horizontal_adjustment.get_value();
+ wy += vertical_adjustment.get_value();
+
+ ev.type = GDK_BUTTON_RELEASE;
+ ev.button.x = wx;
+ ev.button.y = wy;
+
+ frame = event_frame (&ev, 0, &cy);
+
+ snap_to (frame);
+
+ if ((tvp = trackview_by_y_position (cy)) == 0) {
+
+ /* drop onto canvas background: create new tracks */
+
+ jack_nframes_t pos = 0;
+ do_embed (paths, false, ImportAsTrack, 0, pos, false);
+
+ } else if ((tv = dynamic_cast<AudioTimeAxisView*>(tvp)) != 0) {
+
+ /* check that its an audio track, not a bus */
+
+ if (tv->get_diskstream()) {
+ do_embed (paths, false, ImportToTrack, tv->audio_track(), frame, true);
+ }
+ }
+
+ out:
+ context->drag_finish (true, false, time);
+}
+
+void
+Editor::drop_regions (const RefPtr<Gdk::DragContext>& context,
+ int x, int y,
+ const SelectionData& data,
+ guint info, guint time)
+{
+ const DnDTreeView::SerializedObjectPointers* sr = reinterpret_cast<const DnDTreeView::SerializedObjectPointers*> (data.get_data());
+
+ for (uint32_t i = 0; i < sr->cnt; ++i) {
+
+ Region* r = reinterpret_cast<Region*> (sr->ptr[i]);
+ AudioRegion* ar;
+
+ if ((ar = dynamic_cast<AudioRegion*>(r)) != 0) {
+ insert_region_list_drag (*ar, x, y);
+ }
+ }
+
+ context->drag_finish (true, false, time);
+}
+