From 31b6b051258c49fcf5a56fb4fd9f6a7e01b3ee1b Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 14 Nov 2014 17:33:02 -0500 Subject: Fix MIDI note cut/copy/paste. --- gtk2_ardour/editor_ops.cc | 31 ++++++++++++++++--------------- gtk2_ardour/midi_region_view.cc | 33 ++++++++++++++------------------- 2 files changed, 30 insertions(+), 34 deletions(-) (limited to 'gtk2_ardour') diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index b8e13bc196..98235e5861 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -4003,12 +4003,13 @@ Editor::cut_copy_midi (CutCopyOp op) MidiRegionView* mrv = dynamic_cast(*i); if (mrv) { mrv->cut_copy_clear (op); + + /* XXX: not ideal, as there may be more than one track involved in the selection */ + _last_cut_copy_source_track = &mrv->get_time_axis_view(); } } } - - struct lt_playlist { bool operator () (const PlaylistState& a, const PlaylistState& b) { return a.playlist < b.playlist; @@ -4372,6 +4373,9 @@ Editor::paste_internal (framepos_t position, float times) if (_edit_point == Editing::EditAtMouse && entered_track) { /* With the mouse edit point, paste onto the track under the mouse */ ts.push_back (entered_track); + } else if (_edit_point == Editing::EditAtMouse && entered_regionview) { + /* With the mouse edit point, paste onto the track of the region under the mouse */ + ts.push_back (&entered_regionview->get_time_axis_view()); } else if (!selection->tracks.empty()) { /* Otherwise, if there are some selected tracks, paste to them */ ts = selection->tracks.filter_to_unique_playlists (); @@ -4387,21 +4391,18 @@ Editor::paste_internal (framepos_t position, float times) /* undo/redo is handled by individual tracks/regions */ - for (nth = 0, i = ts.begin(); i != ts.end(); ++i, ++nth) { - - RegionSelection rs; - RegionSelection::iterator r; - MidiNoteSelection::iterator cb; + RegionSelection rs; + RegionSelection::iterator r; + MidiNoteSelection::iterator cb; - get_regions_at (rs, position, ts); + get_regions_at (rs, position, ts); - for (cb = cut_buffer->midi_notes.begin(), r = rs.begin(); - cb != cut_buffer->midi_notes.end() && r != rs.end(); ++r) { - MidiRegionView* mrv = dynamic_cast (*r); - if (mrv) { - mrv->paste (position, times, **cb); - ++cb; - } + for (cb = cut_buffer->midi_notes.begin(), r = rs.begin(); + cb != cut_buffer->midi_notes.end() && r != rs.end(); ++r) { + MidiRegionView* mrv = dynamic_cast (*r); + if (mrv) { + mrv->paste (position, times, **cb); + ++cb; } } diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 81248c9585..b560367c5c 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -366,9 +366,13 @@ MidiRegionView::canvas_group_event(GdkEvent* ev) return r; case GDK_ENTER_NOTIFY: + // set entered_regionview (among other things) + trackview.editor().canvas_region_view_event (ev, group, this); return enter_notify (&ev->crossing); case GDK_LEAVE_NOTIFY: + // reset entered_regionview (among other things) + trackview.editor().canvas_region_view_event (ev, group, this); return leave_notify (&ev->crossing); case GDK_MOTION_NOTIFY: @@ -3323,27 +3327,20 @@ MidiRegionView::paste (framepos_t pos, float times, const MidiCutBuffer& mcb) return; } - DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("MIDI paste @ %1 times %2\n", pos, times)); - trackview.session()->begin_reversible_command (_("paste")); start_note_diff_command (_("paste")); - Evoral::MusicalTime beat_delta; - Evoral::MusicalTime paste_pos_beats; - Evoral::MusicalTime duration; - Evoral::MusicalTime end_point = 0; - - duration = (*mcb.notes().rbegin())->end_time() - (*mcb.notes().begin())->time(); - paste_pos_beats = absolute_frames_to_source_beats (pos); - beat_delta = (*mcb.notes().begin())->time() - paste_pos_beats; - paste_pos_beats = 0; + const Evoral::MusicalTime pos_beats = absolute_frames_to_source_beats (pos); + const Evoral::MusicalTime first_time = (*mcb.notes().begin())->time(); + const Evoral::MusicalTime last_time = (*mcb.notes().rbegin())->end_time(); + Evoral::MusicalTime end_point = 0; - DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("Paste data spans from %1 to %2 (%3) ; paste pos beats = %4 (based on %5 - %6 ; beat delta = %7\n", - (*mcb.notes().begin())->time(), - (*mcb.notes().rbegin())->end_time(), - duration, pos, _region->position(), - paste_pos_beats, beat_delta)); + DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("Paste data spans from %1 to %2 (%3) ; paste pos beats = %4 (based on %5 - %6)\n", + first_time, + last_time, + last_time - first_time, pos, _region->position(), + pos_beats)); clear_selection (); @@ -3352,15 +3349,13 @@ MidiRegionView::paste (framepos_t pos, float times, const MidiCutBuffer& mcb) for (Notes::const_iterator i = mcb.notes().begin(); i != mcb.notes().end(); ++i) { boost::shared_ptr copied_note (new NoteType (*((*i).get()))); - copied_note->set_time (paste_pos_beats + copied_note->time() - beat_delta); + copied_note->set_time (pos_beats + copied_note->time() - first_time); /* make all newly added notes selected */ note_diff_add_note (copied_note, true); end_point = copied_note->end_time(); } - - paste_pos_beats += duration; } /* if we pasted past the current end of the region, extend the region */ -- cgit v1.2.3