+MidiCutBuffer*
+MidiRegionView::selection_as_cut_buffer () const
+{
+ Evoral::Sequence<MidiModel::TimeType>::Notes notes;
+
+ for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) {
+ notes.push_back (boost::shared_ptr<NoteType> (new NoteType (*((*i)->note().get()))));
+ }
+
+ /* sort them into time order */
+
+ sort (notes.begin(), notes.end(), Evoral::Sequence<MidiModel::TimeType>::note_time_comparator);
+
+ MidiCutBuffer* cb = new MidiCutBuffer (trackview.session());
+ cb->set (notes);
+
+ return cb;
+}
+
+void
+MidiRegionView::paste (nframes64_t pos, float times, const MidiCutBuffer& mcb)
+{
+ if (mcb.empty()) {
+ return;
+ }
+
+ start_delta_command (_("paste"));
+
+ MidiModel::TimeType beat_delta;
+ MidiModel::TimeType paste_pos_beats;
+ MidiModel::TimeType duration;
+
+ duration = mcb.notes().back()->end_time() - mcb.notes().front()->time();
+ paste_pos_beats = frames_to_beats (pos);
+ beat_delta = mcb.notes().front()->time() - paste_pos_beats;
+ paste_pos_beats = 0;
+
+ _selection.clear ();
+
+ for (int n = 0; n < (int) times; ++n) {
+
+ for (Evoral::Sequence<MidiModel::TimeType>::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);
+
+ /* make all newly added notes selected */
+
+ command_add_note (copied_note, true);
+ }
+
+ paste_pos_beats += duration;
+ }
+
+ apply_command ();
+}