summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2009-08-13 01:57:03 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2009-08-13 01:57:03 +0000
commit0178875021916feea05a830325c25e9a7db81d34 (patch)
treeda01be83db51399e179d08814e3fb1e0a3bff183 /gtk2_ardour
parent677bb36f5c012ac6d429a1d1fce0a726616160d4 (diff)
MIDI cut&paste round two (not done yet); a small region trim fix from lincoln s.
git-svn-id: svn://localhost/ardour2/branches/3.0@5517 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour')
-rw-r--r--gtk2_ardour/audio_region_view.cc6
-rw-r--r--gtk2_ardour/editor_ops.cc47
-rw-r--r--gtk2_ardour/midi_cut_buffer.cc44
-rw-r--r--gtk2_ardour/midi_cut_buffer.h45
-rw-r--r--gtk2_ardour/midi_region_view.cc46
-rw-r--r--gtk2_ardour/midi_region_view.h32
-rw-r--r--gtk2_ardour/midi_selection.h4
-rw-r--r--gtk2_ardour/route_time_axis.cc3
-rw-r--r--gtk2_ardour/selection.cc151
-rw-r--r--gtk2_ardour/selection.h18
-rw-r--r--gtk2_ardour/wscript1
11 files changed, 342 insertions, 55 deletions
diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc
index f5dd4da3d1..d4e846aec5 100644
--- a/gtk2_ardour/audio_region_view.cc
+++ b/gtk2_ardour/audio_region_view.cc
@@ -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
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index 0a7543b214..72a8d7bdf6 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -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
index 0000000000..008597bc84
--- /dev/null
+++ b/gtk2_ardour/midi_cut_buffer.cc
@@ -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
index 0000000000..279d34d244
--- /dev/null
+++ b/gtk2_ardour/midi_cut_buffer.h
@@ -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__ */
diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc
index 9b9be486a3..7482981b71 100644
--- a/gtk2_ardour/midi_region_view.cc
+++ b/gtk2_ardour/midi_region_view.cc
@@ -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);
+
+
+}
diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h
index 01d5a305cb..1d234e0d1a 100644
--- a/gtk2_ardour/midi_region_view.h
+++ b/gtk2_ardour/midi_region_view.h
@@ -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. */
diff --git a/gtk2_ardour/midi_selection.h b/gtk2_ardour/midi_selection.h
index 27b8ef7352..bd6851870e 100644
--- a/gtk2_ardour/midi_selection.h
+++ b/gtk2_ardour/midi_selection.h
@@ -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__ */
diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc
index 87d0d07433..d8cbfbc3ea 100644
--- a/gtk2_ardour/route_time_axis.cc
+++ b/gtk2_ardour/route_time_axis.cc
@@ -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);
diff --git a/gtk2_ardour/selection.cc b/gtk2_ardour/selection.cc
index be7552b0bd..b5454c4a12 100644
--- a/gtk2_ardour/selection.cc
+++ b/gtk2_ardour/selection.cc
@@ -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));
}
}
@@ -206,6 +218,29 @@ Selection::toggle (TimeAxisView* track)
}
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)
{
RegionSelection::iterator i;
@@ -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
@@ -320,6 +355,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)
{
/* XXX This method or the add (const RegionSelection&) needs to go
@@ -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 ();
}
}
@@ -473,6 +529,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)
{
list<boost::shared_ptr<Playlist> >::iterator i;
@@ -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
@@ -580,6 +667,13 @@ Selection::set (const list<TimeAxisView*>& track_list)
}
void
+Selection::set (const MidiNoteSelection& midi_list)
+{
+ clear_midi_notes ();
+ add (midi_list);
+}
+
+void
Selection::set (boost::shared_ptr<Playlist> playlist)
{
clear_playlists ();
@@ -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
diff --git a/gtk2_ardour/selection.h b/gtk2_ardour/selection.h
index 9278935e31..288c832178 100644
--- a/gtk2_ardour/selection.h
+++ b/gtk2_ardour/selection.h
@@ -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));
diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript
index 592b48efd0..87503ff2d3 100644
--- a/gtk2_ardour/wscript
+++ b/gtk2_ardour/wscript
@@ -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',