Fix MIDI note cut/copy/paste.
authorDavid Robillard <d@drobilla.net>
Fri, 14 Nov 2014 22:33:02 +0000 (17:33 -0500)
committerDavid Robillard <d@drobilla.net>
Sat, 15 Nov 2014 01:04:19 +0000 (20:04 -0500)
gtk2_ardour/editor_ops.cc
gtk2_ardour/midi_region_view.cc

index b8e13bc196160506a231b78e7b38da572f3cd3ec..98235e58610388659bff09f5341ca496e0a7bbaf 100644 (file)
@@ -4003,12 +4003,13 @@ Editor::cut_copy_midi (CutCopyOp op)
                MidiRegionView* mrv = dynamic_cast<MidiRegionView*>(*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<MidiRegionView*> (*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<MidiRegionView*> (*r);
+                       if (mrv) {
+                               mrv->paste (position, times, **cb);
+                               ++cb;
                        }
                }
 
index 81248c958598fda27de5183c9882c7c11f574964..b560367c5cb5a60d9128c2af3dff7a8a0aef9394 100644 (file)
@@ -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<NoteType> 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 */