MIDI cut&paste round two (not done yet); a small region trim fix from lincoln s.
authorPaul Davis <paul@linuxaudiosystems.com>
Thu, 13 Aug 2009 01:57:03 +0000 (01:57 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Thu, 13 Aug 2009 01:57:03 +0000 (01:57 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@5517 d708f5d6-7413-0410-9779-e7cbd77b26cf

13 files changed:
gtk2_ardour/audio_region_view.cc
gtk2_ardour/editor_ops.cc
gtk2_ardour/midi_cut_buffer.cc [new file with mode: 0644]
gtk2_ardour/midi_cut_buffer.h [new file with mode: 0644]
gtk2_ardour/midi_region_view.cc
gtk2_ardour/midi_region_view.h
gtk2_ardour/midi_selection.h
gtk2_ardour/route_time_axis.cc
gtk2_ardour/selection.cc
gtk2_ardour/selection.h
gtk2_ardour/wscript
libs/evoral/evoral/Sequence.hpp
libs/evoral/src/Sequence.cpp

index f5dd4da3d1807e7f0771ddb5ac64f41a1ec01511..d4e846aec50174c6a8f5e9a637159ce8ce4bb2cc 100644 (file)
@@ -614,6 +614,9 @@ AudioRegionView::reset_fade_in_shape_width (nframes_t width)
        
        fade_in_shape->property_points() = *points;
        delete points;
+       
+       /* ensure trim handle stays on top */
+       frame_handle_start->raise_to_top();
 }
 
 void
@@ -702,6 +705,9 @@ AudioRegionView::reset_fade_out_shape_width (nframes_t width)
 
        fade_out_shape->property_points() = *points;
        delete points;
+       
+       /* ensure trim handle stays on top */
+       frame_handle_end->raise_to_top();
 }
 
 void
index 0a7543b214a4ae6ce233a47bd7fbd5a06c253a07..72a8d7bdf609a69f0e7f111153ab71668054f939 100644 (file)
@@ -4011,9 +4011,9 @@ Editor::cut_copy_points (CutCopyOp op)
 void
 Editor::cut_copy_midi (CutCopyOp op)
 {
-       cerr << "CCM: there are " << selection->midi.size() << " MRV's to work on\n";
+       cerr << "CCM: there are " << selection->midi_regions.size() << " MRV's to work on\n";
 
-       for (MidiSelection::iterator i = selection->midi.begin(); i != selection->midi.end(); ++i) {
+       for (MidiRegionSelection::iterator i = selection->midi_regions.begin(); i != selection->midi_regions.end(); ++i) {
                MidiRegionView* mrv = *i;
                mrv->cut_copy_clear (op);
        }
@@ -4318,8 +4318,14 @@ Editor::paste_internal (nframes64_t position, float times)
 {
        bool commit = false;
 
-       if (cut_buffer->empty()) {
-               return;
+       if (internal_editing()) {
+               if (cut_buffer->midi_notes.empty()) {
+                       return;
+               } 
+       } else {
+               if (cut_buffer->empty()) {
+                       return;
+               }
        }
 
        if (position == max_frames) {
@@ -4341,13 +4347,38 @@ Editor::paste_internal (nframes64_t position, float times)
                ts.push_back (entered_track);
        }
 
+
+       cerr << "Paste into " << ts.size() << " tracks\n";
+
        for (nth = 0, i = ts.begin(); i != ts.end(); ++i, ++nth) {
 
-               /* undo/redo is handled by individual tracks */
+               /* undo/redo is handled by individual tracks/regions */
 
-               if ((*i)->paste (position, times, *cut_buffer, nth)) {
-                       commit = true;
-               }
+               if (internal_editing()) {
+                       
+                       RegionSelection rs;
+                       RegionSelection::iterator r;
+                       MidiNoteSelection::iterator cb;
+
+                       get_regions_at (rs, position, ts);
+                       
+
+                       cerr << " We have " << cut_buffer->midi_notes.size() << " MIDI cut buffers\n";
+
+                       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, **cb);
+                                       ++cb;
+                               }
+                       }
+
+               } else {
+
+                       if ((*i)->paste (position, times, *cut_buffer, nth)) {
+                               commit = true;
+                       }
+               } 
        }
        
        if (commit) {
diff --git a/gtk2_ardour/midi_cut_buffer.cc b/gtk2_ardour/midi_cut_buffer.cc
new file mode 100644 (file)
index 0000000..008597b
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+    Copyright (C) 2009 Paul Davis
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "midi_cut_buffer.h"
+
+using namespace ARDOUR;
+
+MidiCutBuffer::MidiCutBuffer (Session& s)
+       : AutomatableSequence<MidiModel::TimeType> (s, 0)
+       , _origin (0)
+{
+
+}
+
+MidiCutBuffer::~MidiCutBuffer ()
+{
+}
+
+void
+MidiCutBuffer::set_origin (MidiCutBuffer::TimeType when)
+{
+       _origin = when;
+}
+
+void
+MidiCutBuffer::set (const Evoral::Sequence<MidiCutBuffer::TimeType>::Notes& notes)
+{
+       set_notes (notes);
+}
diff --git a/gtk2_ardour/midi_cut_buffer.h b/gtk2_ardour/midi_cut_buffer.h
new file mode 100644 (file)
index 0000000..279d34d
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+    Copyright (C) 2009 Paul Davis
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef __gtk_ardour_midi_cut_buffer_h__
+#define __gtk_ardour_midi_cut_buffer_h__
+
+#include "ardour/midi_model.h"
+
+namespace ARDOUR {
+       class Session;
+}
+
+class MidiCutBuffer : public ARDOUR::AutomatableSequence<ARDOUR::MidiModel::TimeType> 
+{
+  public:
+       typedef ARDOUR::MidiModel::TimeType TimeType;
+
+       MidiCutBuffer (ARDOUR::Session&);
+       ~MidiCutBuffer();
+
+       TimeType origin() const { return _origin; }
+       void set_origin (TimeType);
+       
+       void set (const Evoral::Sequence<TimeType>::Notes&);
+
+  private:
+       TimeType _origin;
+};
+
+#endif /* __gtk_ardour_midi_cut_buffer_h__ */
index 9b9be486a3d57fbb18761a0baa7c283451ed3687..7482981b717b91e619b30b4f91f8788b03caa29d 100644 (file)
@@ -47,6 +47,7 @@
 #include "ghostregion.h"
 #include "gui_thread.h"
 #include "keyboard.h"
+#include "midi_cut_buffer.h"
 #include "midi_region_view.h"
 #include "midi_streamview.h"
 #include "midi_time_axis.h"
@@ -660,7 +661,6 @@ MidiRegionView::~MidiRegionView ()
        }
 
        _selection.clear();
-       _cut_buffer.clear ();
        clear_events();
        delete _note_group;
        delete _delta_command;
@@ -1669,17 +1669,25 @@ MidiRegionView::cut_copy_clear (Editing::CutCopyOp op)
                return;
        }
 
-       _cut_buffer.clear ();
+       PublicEditor& editor (trackview.editor());
 
+       switch (op) {
+       case Cut:
+       case Copy:
+               cerr << "Cut/Copy: get selection as CB\n";
+               editor.get_cut_buffer().add (selection_as_cut_buffer());
+               break;
+       default:
+               break;
+       }
+               
        start_delta_command();
 
        for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) {
                switch (op) {
                case Copy:
-                       _cut_buffer.push_back (NoteType (*((*i)->note().get())));
                        break;
                case Cut:
-                       _cut_buffer.push_back (NoteType (*(*i)->note().get()));
                        command_remove_note (*i);
                        break;
                case Clear:
@@ -1690,3 +1698,33 @@ MidiRegionView::cut_copy_clear (Editing::CutCopyOp op)
        apply_command();
 }
 
+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, const MidiCutBuffer& mcb)
+{
+       MidiModel::DeltaCommand* cmd = _model->new_delta_command("paste");
+       for (Evoral::Sequence<MidiModel::TimeType>::Notes::const_iterator i = mcb.notes().begin(); i != mcb.notes().end(); ++i) {
+               cmd->add (boost::shared_ptr<NoteType> (new NoteType (*((*i).get()))));
+       }
+       _model->apply_command(trackview.session(), cmd);
+       
+
+}
index 01d5a305cb65ab729f639f7ea92def0eb074ef0f..1d234e0d1af8cd0f6124e639beb328b3499bf89a 100644 (file)
@@ -57,6 +57,7 @@ class MidiTimeAxisView;
 class GhostRegion;
 class AutomationTimeAxisView;
 class AutomationRegionView;
+class MidiCutBuffer;
 
 class MidiRegionView : public RegionView
 {
@@ -100,7 +101,8 @@ class MidiRegionView : public RegionView
        void resolve_note(uint8_t note_num, double end_time);
 
        void cut_copy_clear (Editing::CutCopyOp);
-       
+       void paste (nframes64_t pos, const MidiCutBuffer&);
+
        struct PCEvent {
                PCEvent(double a_time, uint8_t a_value, uint8_t a_channel) 
                        : time(a_time), value(a_value), channel(a_channel) {}
@@ -255,23 +257,26 @@ class MidiRegionView : public RegionView
        
        /** Convert a timestamp in frames to beats (both relative to region start) */
        double frames_to_beats(nframes64_t beats) const;
+
+       /** Return the current selection as a MidiModel or null if there is no selection */
+       ARDOUR::MidiModel* selection_as_model () const;
        
   protected:
-    /** Allows derived types to specify their visibility requirements
-     * to the TimeAxisViewItem parent class.
-     */
-    MidiRegionView (ArdourCanvas::Group *,
+       /** Allows derived types to specify their visibility requirements
+        * to the TimeAxisViewItem parent class.
+        */
+       MidiRegionView (ArdourCanvas::Group *,
                        RouteTimeAxisView&,
                        boost::shared_ptr<ARDOUR::MidiRegion>,
                        double samples_per_unit,
                        Gdk::Color& basic_color,
                        TimeAxisViewItem::Visibility);
-
-    void region_resized (ARDOUR::Change);
-
-    void set_flags (XMLNode *);
-    void store_flags ();
-
+       
+       void region_resized (ARDOUR::Change);
+       
+       void set_flags (XMLNode *);
+       void store_flags ();
+       
        void reset_width_dependent_items (double pixel_width);
 
   private:
@@ -333,9 +338,8 @@ class MidiRegionView : public RegionView
        typedef std::set<ArdourCanvas::CanvasNoteEvent*> Selection;
        /// Currently selected CanvasNoteEvents
        Selection _selection;
-       /// the cut buffer for this region view
-       typedef std::list<NoteType> CutBuffer;
-       CutBuffer _cut_buffer;
+
+       MidiCutBuffer* selection_as_cut_buffer () const;
 
        /** New notes (created in the current command) which should be selected
         * when they appear after the command is applied. */
index 27b8ef73526173283c5e94a22510b016eaaed12f..bd6851870e14166808911eac22f3bf452eb75cba 100644 (file)
@@ -23,7 +23,9 @@
 #include <list>
 
 class MidiRegionView;
+class MidiCutBuffer;
 
-struct MidiSelection : std::list<MidiRegionView*> {};
+struct MidiRegionSelection : std::list<MidiRegionView*> {};
+struct MidiNoteSelection   : std::list<MidiCutBuffer*> {};
 
 #endif /* __ardour_gtk_midi_selection_h__ */
index 87d0d0743327618b477af33233d97a7a70a2648c..d8cbfbc3eaa72d8605385919ed454684eec161ea 100644 (file)
@@ -1462,8 +1462,9 @@ RouteTimeAxisView::paste (nframes_t pos, float times, Selection& selection, size
                return false;
        }
 
-       if (get_diskstream()->speed() != 1.0f)
+       if (get_diskstream()->speed() != 1.0f) {
                pos = session_frame_to_track_frame(pos, get_diskstream()->speed() );
+       }
        
        XMLNode &before = playlist->get_state();
        playlist->paste (*p, pos, times);
index be7552b0bd6109d58318f3f813e897ac3414c504..b5454c4a123ca6afcad970f79657b2eef1f9476b 100644 (file)
@@ -53,7 +53,8 @@ Selection::operator= (const Selection& other)
                tracks = other.tracks;
                time = other.time;
                lines = other.lines;
-               midi = other.midi;
+               midi_regions = other.midi_regions;
+               midi_notes = other.midi_notes;
        }
        return *this;
 }
@@ -68,7 +69,8 @@ operator== (const Selection& a, const Selection& b)
                a.time == b.time &&
                a.lines == b.lines &&
                a.playlists == b.playlists &&
-               a.midi == b.midi;
+               a.midi_notes == b.midi_notes &&
+               a.midi_regions == b.midi_regions;
 }
 
 /** Clear everything from the Selection */
@@ -81,7 +83,8 @@ Selection::clear ()
        clear_lines();
        clear_time ();
        clear_playlists ();
-       clear_midi ();
+       clear_midi_notes ();
+       clear_midi_regions ();
 }
 
 void
@@ -113,11 +116,20 @@ Selection::clear_tracks ()
 }
 
 void
-Selection::clear_midi ()
+Selection::clear_midi_notes ()
 {
-       if (!midi.empty()) {
-               midi.clear ();
-               MidiChanged ();
+       if (!midi_notes.empty()) {
+               midi_notes.clear ();
+               MidiNotesChanged ();
+       }
+}
+
+void
+Selection::clear_midi_regions ()
+{
+       if (!midi_regions.empty()) {
+               midi_regions.clear ();
+               MidiRegionsChanged ();
        }
 }
 
@@ -185,7 +197,7 @@ void
 Selection::toggle (const list<TimeAxisView*>& track_list)
 {
        for (list<TimeAxisView*>::const_iterator i = track_list.begin(); i != track_list.end(); ++i) {
-               toggle ( (*i) );
+               toggle ((*i));
        }
 }
 
@@ -205,6 +217,29 @@ Selection::toggle (TimeAxisView* track)
        TracksChanged();
 }
 
+void
+Selection::toggle (const MidiNoteSelection& midi_note_list)
+{
+       for (MidiNoteSelection::const_iterator i = midi_note_list.begin(); i != midi_note_list.end(); ++i) {
+               toggle ((*i));
+       }
+}
+
+void
+Selection::toggle (MidiCutBuffer* midi)
+{
+       MidiNoteSelection::iterator i;
+       
+       if ((i = find (midi_notes.begin(), midi_notes.end(), midi)) == midi_notes.end()) {
+               midi_notes.push_back (midi);
+       } else {
+               midi_notes.erase (i);
+       }
+       
+       MidiNotesChanged();
+}
+
+
 void
 Selection::toggle (RegionView* r)
 {
@@ -222,15 +257,15 @@ Selection::toggle (RegionView* r)
 void
 Selection::toggle (MidiRegionView* mrv)
 {
-       MidiSelection::iterator i;
+       MidiRegionSelection::iterator i;
 
-       if ((i = find (midi.begin(), midi.end(), mrv)) == midi.end()) {
+       if ((i = find (midi_regions.begin(), midi_regions.end(), mrv)) == midi_regions.end()) {
                add (mrv);
        } else {
-               midi.erase (i);
+               midi_regions.erase (i);
        }
 
-       MidiChanged ();
+       MidiRegionsChanged ();
 }
 
 void
@@ -319,6 +354,27 @@ Selection::add (TimeAxisView* track)
        }
 }
 
+void
+Selection::add (const MidiNoteSelection& midi_list)
+{
+       const MidiNoteSelection::const_iterator b = midi_list.begin();
+       const MidiNoteSelection::const_iterator e = midi_list.end();
+
+       if (!midi_list.empty()) {
+               midi_notes.insert (midi_notes.end(), b, e);
+               MidiNotesChanged ();
+       }
+}
+
+void
+Selection::add (MidiCutBuffer* midi)
+{
+       if (find (midi_notes.begin(), midi_notes.end(), midi) == midi_notes.end()) {
+               midi_notes.push_back (midi);
+               MidiNotesChanged ();
+       }
+}
+
 void
 Selection::add (vector<RegionView*>& v)
 {
@@ -378,15 +434,15 @@ Selection::add (RegionView* r)
 void
 Selection::add (MidiRegionView* mrv)
 {
-       if (find (midi.begin(), midi.end(), mrv) == midi.end()) {
-               midi.push_back (mrv);
+       if (find (midi_regions.begin(), midi_regions.end(), mrv) == midi_regions.end()) {
+               midi_regions.push_back (mrv);
                /* XXX should we do this? */
 #if 0
                if (Config->get_link_region_and_track_selection()) {
                        add (&mrv->get_trackview());
                }
 #endif
-               MidiChanged ();
+               MidiRegionsChanged ();
        }
 }
 
@@ -472,6 +528,37 @@ Selection::remove (const list<TimeAxisView*>& track_list)
        }
 }
 
+void
+Selection::remove (const MidiNoteSelection& midi_list)
+{
+       bool changed = false;
+
+       for (MidiNoteSelection::const_iterator i = midi_list.begin(); i != midi_list.end(); ++i) {
+
+               MidiNoteSelection::iterator x;
+
+               if ((x = find (midi_notes.begin(), midi_notes.end(), (*i))) != midi_notes.end()) {
+                       midi_notes.erase (x);
+                       changed = true;
+               }
+       }
+
+       if (changed) {
+               MidiNotesChanged();
+       }
+}
+
+void
+Selection::remove (MidiCutBuffer* midi)
+{
+       MidiNoteSelection::iterator x;
+       
+       if ((x = find (midi_notes.begin(), midi_notes.end(), midi)) != midi_notes.end()) {
+               midi_notes.erase (x);
+               MidiNotesChanged ();
+       }
+}
+
 void
 Selection::remove (boost::shared_ptr<Playlist> track)
 {
@@ -517,11 +604,11 @@ Selection::remove (RegionView* r)
 void
 Selection::remove (MidiRegionView* mrv)
 {
-       MidiSelection::iterator x;
+       MidiRegionSelection::iterator x;
 
-       if ((x = find (midi.begin(), midi.end(), mrv)) != midi.end()) {
-               midi.erase (x);
-               MidiChanged ();
+       if ((x = find (midi_regions.begin(), midi_regions.end(), mrv)) != midi_regions.end()) {
+               midi_regions.erase (x);
+               MidiRegionsChanged ();
        }
 
 #if 0
@@ -579,6 +666,13 @@ Selection::set (const list<TimeAxisView*>& track_list)
        add (track_list);
 }
 
+void
+Selection::set (const MidiNoteSelection& midi_list)
+{
+       clear_midi_notes ();
+       add (midi_list);
+}
+
 void
 Selection::set (boost::shared_ptr<Playlist> playlist)
 {
@@ -604,7 +698,7 @@ Selection::set (const RegionSelection& rs)
 void
 Selection::set (MidiRegionView* mrv) 
 {
-       clear_midi ();
+       clear_midi_regions ();
        add (mrv);
 }
 
@@ -690,17 +784,28 @@ Selection::selected (RegionView* rv)
 }
 
 bool
-Selection::empty ()
+Selection::empty (bool internal_selection)
 {
-       return regions.empty () &&
+       bool object_level_empty =  regions.empty () &&
                tracks.empty () &&
                points.empty () && 
                playlists.empty () && 
                lines.empty () &&
                time.empty () &&
                playlists.empty () &&
-               markers.empty()
+               markers.empty() &&
+               midi_regions.empty()
                ;
+
+       if (!internal_selection) {
+               return object_level_empty;
+       }
+
+       /* this is intended to really only apply when using a Selection
+          as a cut buffer.
+       */
+
+       return object_level_empty && midi_notes.empty();
 }
 
 void
index 9278935e31b6c3f15025a94e2fcd38bcb91f8b94..288c832178618507e6d10ed01d78b6003b495d6d 100644 (file)
@@ -79,7 +79,8 @@ class Selection : public sigc::trackable
        PlaylistSelection    playlists;
        PointSelection       points;
        MarkerSelection      markers;
-       MidiSelection        midi;
+       MidiRegionSelection  midi_regions;
+       MidiNoteSelection    midi_notes;
 
        Selection (PublicEditor const * e) : editor (e), next_time_id (0) {
                clear();
@@ -94,10 +95,11 @@ class Selection : public sigc::trackable
        sigc::signal<void> PlaylistsChanged;
        sigc::signal<void> PointsChanged;
        sigc::signal<void> MarkersChanged;
-       sigc::signal<void> MidiChanged;
+       sigc::signal<void> MidiNotesChanged;
+       sigc::signal<void> MidiRegionsChanged;
 
        void clear ();
-       bool empty();
+       bool empty (bool internal_selection = false);
 
        void dump_region_layers();
 
@@ -111,6 +113,7 @@ class Selection : public sigc::trackable
        
        void set (TimeAxisView*);
        void set (const std::list<TimeAxisView*>&);
+       void set (const MidiNoteSelection&);
        void set (RegionView*, bool also_clear_tracks = true);
        void set (MidiRegionView*);
        void set (std::vector<RegionView*>&);
@@ -124,8 +127,10 @@ class Selection : public sigc::trackable
 
        void toggle (TimeAxisView*);
        void toggle (const std::list<TimeAxisView*>&);
+       void toggle (const MidiNoteSelection&);
        void toggle (RegionView*);
        void toggle (MidiRegionView*);
+       void toggle (MidiCutBuffer*);
        void toggle (std::vector<RegionView*>&);
        long toggle (nframes_t, nframes_t);
        void toggle (ARDOUR::AutomationList*);
@@ -136,8 +141,10 @@ class Selection : public sigc::trackable
 
        void add (TimeAxisView*);
        void add (const std::list<TimeAxisView*>&);
+       void add (const MidiNoteSelection&);
        void add (RegionView*);
        void add (MidiRegionView*);
+       void add (MidiCutBuffer*);
        void add (std::vector<RegionView*>&);
        long add (nframes_t, nframes_t);
        void add (boost::shared_ptr<Evoral::ControlList>);
@@ -148,8 +155,10 @@ class Selection : public sigc::trackable
        void add (const RegionSelection&);
        void remove (TimeAxisView*);
        void remove (const std::list<TimeAxisView*>&);
+       void remove (const MidiNoteSelection&);
        void remove (RegionView*);
        void remove (MidiRegionView*);
+       void remove (MidiCutBuffer*);
        void remove (uint32_t selection_id);
        void remove (nframes_t, nframes_t);
        void remove (boost::shared_ptr<ARDOUR::AutomationList>);
@@ -167,7 +176,8 @@ class Selection : public sigc::trackable
        void clear_playlists ();
        void clear_points ();
        void clear_markers ();
-       void clear_midi ();
+       void clear_midi_notes ();
+       void clear_midi_regions ();
 
        void foreach_region (void (ARDOUR::Region::*method)(void));
        void foreach_regionview (void (RegionView::*method)(void));
index 592b48efd0dd4aaa311c449c8c06ff003cf27b1f..87503ff2d3a22a970c03d4b2b50c7708d0dd9fec 100644 (file)
@@ -126,6 +126,7 @@ gtk2_ardour_sources = [
        'main.cc',
        'marker.cc',
        'midi_channel_selector.cc',
+       'midi_cut_buffer.cc',
        'midi_port_dialog.cc',
        'midi_region_view.cc',
        'midi_scroomer.cc',
index 6a1fe5ab87eaca82e42d8f448cec08f62e0ce730..b059f4e231ff0aee1d535bb8ea301a4818ad39d9 100644 (file)
@@ -104,6 +104,8 @@ public:
        inline       Notes& notes()       { return _notes; }
        inline const Notes& notes() const { return _notes; }
 
+        void set_notes (const std::vector<boost::shared_ptr<Note<Time> > >&);
+
        typedef std::vector< boost::shared_ptr< Event<Time> > > SysExes;
        inline       SysExes& sysexes()       { return _sysexes; }
        inline const SysExes& sysexes() const { return _sysexes; }
index 312b416150d5603aa050eefaf37091b509ccbdb2..39772e6a6e218e31f8a5d171c936b2972ac00378 100644 (file)
@@ -780,6 +780,13 @@ Sequence<Time>::remove_note_unlocked(const boost::shared_ptr< const Note<Time> >
        }
 }
 
+template<typename Time>
+void
+Sequence<Time>::set_notes (const Sequence<Time>::Notes& n)
+{
+       _notes = n;
+}
+
 template class Sequence<double>;
 
 } // namespace Evoral