Index: gtk2_ardour/SConscript
===================================================================
--- gtk2_ardour/SConscript	(Revision 3144)
+++ gtk2_ardour/SConscript	(Arbeitskopie)
@@ -127,6 +127,7 @@
 axis_view.cc
 bundle_manager.cc
 canvas-midi-event.cc
+canvas-note.cc
 canvas-simpleline.c
 canvas-simplerect.c
 canvas-waveview.c
Index: gtk2_ardour/canvas-note.h
===================================================================
--- gtk2_ardour/canvas-note.h	(Revision 3144)
+++ gtk2_ardour/canvas-note.h	(Arbeitskopie)
@@ -1,6 +1,7 @@
 /*
-    Copyright (C) 2007 Paul Davis 
+    Copyright (C) 2007 Paul Davis
     Author: Dave Robillard
+    Author: Hans Baier
 
     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
@@ -38,16 +39,34 @@
 		: SimpleRect(group), CanvasMidiEvent(region, this, note)
 	{
 	}
-	
+
 	double x1() { return property_x1(); }
 	double y1() { return property_y1(); }
 	double x2() { return property_x2(); }
 	double y2() { return property_y2(); }
-	
+
 	void set_outline_color(uint32_t c) { property_outline_color_rgba() = c; }
 	void set_fill_color(uint32_t c) { property_fill_color_rgba() = c; }
-	
-	bool on_event(GdkEvent* ev) { return CanvasMidiEvent::on_event(ev); }
+
+	bool on_event(GdkEvent* ev);
+
+	enum NoteEnd {
+		NOTE_ON,
+		NOTE_OFF
+	};
+
+	enum Mouse2State {
+		None,
+		RelativeResize,
+		AbsoluteResize
+	};
+
+protected:
+	Mouse2State _mouse2_state;
+
+private:
+	// single click resizing with mouse-2
+	void resize_note(double pressed_x, double event_x, double middle_point);
 };
 
 } // namespace Gnome
Index: gtk2_ardour/canvas-midi-event.cc
===================================================================
--- gtk2_ardour/canvas-midi-event.cc	(Revision 3144)
+++ gtk2_ardour/canvas-midi-event.cc	(Arbeitskopie)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2007 Paul Davis 
+    Copyright (C) 2007 Paul Davis
     Author: Dave Robillard
 
     This program is free software; you can redistribute it and/or modify
@@ -38,7 +38,7 @@
 	, _state(None)
 	, _note(note)
 	, _selected(false)
-{	
+{
 }
 
 
@@ -75,22 +75,19 @@
 
 	switch (ev->type) {
 	case GDK_KEY_PRESS:
-		cerr << "EV KEY PRESS\n";
 		if (_note && ev->key.keyval == GDK_Delete) {
-			cerr << "EV DELETE KEY\n";
 			selected(true);
 			_region.start_delta_command();
 			_region.command_remove_note(this);
 		}
 		break;
-	
+
 	case GDK_KEY_RELEASE:
-		cerr << "EV KEY RELEASE\n";
 		if (ev->key.keyval == GDK_Delete) {
 			_region.apply_command();
 		}
 		break;
-	
+
 	case GDK_ENTER_NOTIFY:
 		_region.note_entered(this);
 		_item->grab_focus();
@@ -103,13 +100,14 @@
 		break;
 
 	case GDK_BUTTON_PRESS:
-		_state = Pressed;
+		if (ev->button.button == 1) {
+			_state = Pressed;
+		}
 		return true;
 
 	case GDK_MOTION_NOTIFY:
 		event_x = ev->motion.x;
 		event_y = ev->motion.y;
-		//cerr << "MOTION @ " << event_x << ", " << event_y << endl;
 		_item->property_parent().get_value()->w2i(event_x, event_y);
 
 		switch (_state) {
@@ -135,7 +133,7 @@
 				event_x = t_x;
 				event_y = t_y;
 			}
-			
+
 			// Snap
 			event_frame = _region.midi_view()->editor.pixel_to_frame(event_x);
 			_region.midi_view()->editor.snap_to(event_frame);
@@ -143,7 +141,7 @@
 
 			dx = event_x - last_x;
 			dy = event_y - last_y;
-			
+
 			last_x = event_x;
 
 			drag_delta_x += dx;
@@ -169,7 +167,7 @@
 			break;
 		}
 		break;
-	
+
 	case GDK_BUTTON_RELEASE:
 		select_mod = (ev->motion.state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK));
 		event_x = ev->button.x;
Index: gtk2_ardour/midi_region_view.h
===================================================================
--- gtk2_ardour/midi_region_view.h	(Revision 3144)
+++ gtk2_ardour/midi_region_view.h	(Arbeitskopie)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2001-2007 Paul Davis 
+    Copyright (C) 2001-2007 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
@@ -51,16 +51,16 @@
 class MidiRegionView : public RegionView
 {
   public:
-	MidiRegionView (ArdourCanvas::Group *, 
+	MidiRegionView (ArdourCanvas::Group *,
 	                RouteTimeAxisView&,
 	                boost::shared_ptr<ARDOUR::MidiRegion>,
 	                double initial_samples_per_unit,
 	                Gdk::Color& basic_color);
 
 	~MidiRegionView ();
-	
+
 	virtual void init (Gdk::Color& basic_color, bool wfd);
-	
+
 	inline const boost::shared_ptr<ARDOUR::MidiRegion> midi_region() const
 		{ return boost::dynamic_pointer_cast<ARDOUR::MidiRegion>(_region); }
 
@@ -69,9 +69,9 @@
 
 	inline MidiStreamView* midi_stream_view() const
 		{ return midi_view()->midi_view(); }
-	
+
 	void set_y_position_and_height (double, double);
-	
+
 	void set_frame_color();
 
 	void redisplay_model();
@@ -95,7 +95,7 @@
 		if (!_delta_command)
 			_delta_command = _model->new_delta_command();
 	}
-	
+
 	void command_add_note(const boost::shared_ptr<ARDOUR::Note> note) {
 		if (_delta_command)
 			_delta_command->add(note);
@@ -121,7 +121,7 @@
 		}
 		midi_view()->midi_track()->diskstream()->playlist_modified();
 	}
-	
+
 	void   note_entered(ArdourCanvas::CanvasMidiEvent* ev);
 	void   unique_select(ArdourCanvas::CanvasMidiEvent* ev);
 	void   note_selected(ArdourCanvas::CanvasMidiEvent* ev, bool add);
@@ -131,29 +131,39 @@
 
 	void move_selection(double dx, double dy);
 	void note_dropped(ArdourCanvas::CanvasMidiEvent* ev, double dt, uint8_t dnote);
-	
+
+	void  begin_resizing(ArdourCanvas::CanvasNote::NoteEnd note_end);
+	void update_resizing(ArdourCanvas::CanvasNote::NoteEnd note_end, double dx, bool relative);
+	void commit_resizing(ArdourCanvas::CanvasNote::NoteEnd note_end, double event_x, bool relative);
+
 	enum MouseState { None, Pressed, SelectTouchDragging, SelectRectDragging, AddDragging, EraseTouchDragging };
 	MouseState mouse_state() const { return _mouse_state; }
-	
+
+	struct NoteResizeData {
+		ArdourCanvas::CanvasNote  *canvas_note;
+		ArdourCanvas::SimpleRect  *resize_rect;
+		double                     current_x;
+	};
+
   protected:
 
     /* this constructor allows derived types
        to specify their visibility requirements
        to the TimeAxisViewItem parent class
     */
-    
-    MidiRegionView (ArdourCanvas::Group *, 
+
+    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 reset_width_dependent_items (double pixel_width);
 
   private:
@@ -163,10 +173,11 @@
 
 	bool canvas_event(GdkEvent* ev);
 	bool note_canvas_event(GdkEvent* ev);
-	
+
 	void clear_selection_except(ArdourCanvas::CanvasMidiEvent* ev);
 	void clear_selection() { clear_selection_except(NULL); }
 	void update_drag_selection(double last_x, double x, double last_y, double y);
+	double snap_to(double x);
 
 	double _default_note_length;
 
@@ -175,12 +186,14 @@
 	ArdourCanvas::CanvasNote**                  _active_notes;
 	ArdourCanvas::Group*                        _note_group;
 	ARDOUR::MidiModel::DeltaCommand*            _delta_command;
-		
+
 	MouseState _mouse_state;
 	int _pressed_button;
 
 	typedef std::set<ArdourCanvas::CanvasMidiEvent*> Selection;
 	Selection _selection;
+
+	std::vector<NoteResizeData *> _resize_data;
 };
 
 #endif /* __gtk_ardour_midi_region_view_h__ */
Index: gtk2_ardour/canvas-note.cc
===================================================================
--- gtk2_ardour/canvas-note.cc	(Revision 0)
+++ gtk2_ardour/canvas-note.cc	(Revision 0)
@@ -0,0 +1,91 @@
+#include "canvas-note.h"
+#include "midi_region_view.h"
+#include "public_editor.h"
+#include "ardour/note.h"
+
+using namespace ARDOUR;
+
+namespace Gnome {
+namespace Canvas {
+
+bool
+CanvasNote::on_event(GdkEvent* ev)
+{
+	double          event_x;
+	static double   middle_point, pressed_x, last_x;
+	Gdk::Cursor     cursor;
+	static NoteEnd  note_end;
+
+	switch(ev->type) {
+	case GDK_BUTTON_PRESS:
+		if (ev->button.button == 2) {
+			event_x = ev->button.x;
+			middle_point = x1() + (x2() - x1()) / 2.0L;
+
+			if(event_x <= middle_point) {
+				cursor = Gdk::Cursor(Gdk::LEFT_SIDE);
+				last_x = x1();
+				note_end = NOTE_ON;
+			} else {
+				cursor = Gdk::Cursor(Gdk::RIGHT_SIDE);
+				last_x = x2();
+				note_end = NOTE_OFF;
+			}
+
+			_item->grab(GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, cursor, ev->motion.time);
+
+			if (_region.mouse_state() == MidiRegionView::SelectTouchDragging) {
+				_mouse2_state = AbsoluteResize;
+			} else {
+				_mouse2_state = RelativeResize;
+			}
+
+			pressed_x = event_x;
+
+			_region.note_selected(this, true);
+			_region.begin_resizing(note_end);
+
+			return true;
+		}
+
+	case GDK_MOTION_NOTIFY:
+		event_x = ev->motion.x;
+
+		if (_mouse2_state == RelativeResize) {
+			_region.update_resizing(note_end, event_x - last_x, true);
+			last_x = event_x;
+			return true;
+		}
+
+		if (_mouse2_state == AbsoluteResize) {
+			_region.update_resizing(note_end, event_x, false);
+			return true;
+		}
+
+	case GDK_BUTTON_RELEASE:
+		event_x = ev->button.x;
+
+		switch (_mouse2_state) {
+		case RelativeResize: // Clicked
+			_item->ungrab(ev->button.time);
+			_region.commit_resizing(note_end, event_x, true);
+			_mouse2_state = None;
+			return true;
+
+		case AbsoluteResize: // Clicked
+			_item->ungrab(ev->button.time);
+			_region.commit_resizing(note_end, event_x, false);
+			_mouse2_state = None;
+			return true;
+
+		default:
+			return CanvasMidiEvent::on_event(ev);
+		}
+
+	default:
+		return CanvasMidiEvent::on_event(ev);
+	}
+}
+
+} // namespace Gnome
+} // namespace Canvas
Index: gtk2_ardour/midi_region_view.cc
===================================================================
--- gtk2_ardour/midi_region_view.cc	(Revision 3144)
+++ gtk2_ardour/midi_region_view.cc	(Arbeitskopie)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2001-2007 Paul Davis 
+    Copyright (C) 2001-2007 Paul Davis
     Author: Dave Robillard
 
     This program is free software; you can redistribute it and/or modify
@@ -39,7 +39,6 @@
 #include "midi_region_view.h"
 #include "midi_streamview.h"
 #include "midi_time_axis.h"
-#include "simplerect.h"
 #include "simpleline.h"
 #include "canvas-hit.h"
 #include "public_editor.h"
@@ -92,7 +91,7 @@
 {
 	if (wfd)
 		midi_region()->midi_source(0)->load_model();
-	
+
 	const Meter& m = trackview.session().tempo_map().meter_at(_region->position());
 	const Tempo& t = trackview.session().tempo_map().tempo_at(_region->position());
 	_default_note_length = m.frames_per_bar(t, trackview.session().frame_rate())
@@ -100,7 +99,7 @@
 
 	_model = midi_region()->midi_source(0)->model();
 	_enable_display = false;
-	
+
 	RegionView::init(basic_color, false);
 
 	compute_colors (basic_color);
@@ -127,7 +126,7 @@
 	}
 
 	midi_region()->midi_source(0)->Switched.connect(sigc::mem_fun(this, &MidiRegionView::switch_source));
-	
+
 	group->signal_event().connect (mem_fun (this, &MidiRegionView::canvas_event), false);
 
 }
@@ -144,12 +143,12 @@
 	nframes_t event_frame = 0;
 
 	static ArdourCanvas::SimpleRect* drag_rect = NULL;
-	
+
 	if (trackview.editor.current_mouse_mode() != MouseNote)
 		return false;
 
 	// Mmmm, spaghetti
-	
+
 	switch (ev->type) {
 	case GDK_KEY_PRESS:
 		if (ev->key.keyval == GDK_Delete && !delete_mod) {
@@ -164,7 +163,7 @@
 			return true;
 		}
 		return false;
-	
+
 	case GDK_KEY_RELEASE:
 		if (ev->key.keyval == GDK_Delete) {
 			if (_mouse_state == EraseTouchDragging) {
@@ -187,18 +186,18 @@
 			_mouse_state = Pressed;
 		_pressed_button = ev->button.button;
 		return true;
-	
+
 	case GDK_ENTER_NOTIFY:
 		/* FIXME: do this on switch to note tool, too, if the pointer is already in */
 		Keyboard::magic_widget_grab_focus();
 		group->grab_focus();
 		break;
-	
+
 	case GDK_MOTION_NOTIFY:
 		event_x = ev->motion.x;
 		event_y = ev->motion.y;
 		group->w2i(event_x, event_y);
-				
+
 		event_frame = trackview.editor.pixel_to_frame(event_x);
 		trackview.editor.snap_to(event_frame);
 
@@ -239,7 +238,7 @@
 
 				drag_rect = new ArdourCanvas::SimpleRect(*group);
 				drag_rect->property_x1() = trackview.editor.frame_to_pixel(event_frame);
-				
+
 				drag_rect->property_y1() = midi_stream_view()->note_to_y(midi_stream_view()->y_to_note(event_y));
 				drag_rect->property_x2() = event_x;
 				drag_rect->property_y2() = drag_rect->property_y1() + floor(midi_stream_view()->note_height());
@@ -279,7 +278,7 @@
 					drag_rect->property_y2() = event_y;
 				else
 					drag_rect->property_y1() = event_y;
-				
+
 				update_drag_selection(drag_start_x, event_x, drag_start_y, event_y);
 			}
 
@@ -294,7 +293,7 @@
 			break;
 		}
 		break;
-	
+
 	case GDK_BUTTON_RELEASE:
 		event_x = ev->motion.x;
 		event_y = ev->motion.y;
@@ -336,7 +335,7 @@
 		default:
 			break;
 		}
-	
+
 	default:
 		break;
 	}
@@ -367,13 +366,13 @@
 
 	// Add a 1 beat long note (for now)
 	const boost::shared_ptr<Note> new_note(new Note(0, stamp, dur, (uint8_t)note, 0x40));
-	
+
 	view->update_bounds(new_note->note());
 
 	MidiModel::DeltaCommand* cmd = _model->new_delta_command("add note");
 	cmd->add(new_note);
 	_model->apply_command(cmd);
-	
+
 	//add_note(new_note);
 }
 
@@ -413,12 +412,12 @@
 	// Don't redisplay the model if we're currently recording and displaying that
 	if (_active_notes)
 		return;
-	
+
 	if (_model) {
 
 		clear_events();
 		begin_write();
-		
+
 		_model->read_lock();
 
 		for (size_t i=0; i < _model->n_notes(); ++i)
@@ -437,7 +436,7 @@
 				continue;
 
 			Gdk::Color col = midi_stream_view()->get_region_color();
-				
+
 			boost::shared_ptr<AutomationRegionView> arv;
 
 			{
@@ -454,7 +453,7 @@
 
 			_automation_children.insert(std::make_pair(i->second->parameter(), arv));
 		}*/
-		
+
 		_model->read_unlock();
 
 	} else {
@@ -466,9 +465,9 @@
 MidiRegionView::~MidiRegionView ()
 {
 	in_destructor = true;
-	
+
 	RegionViewGoingAway (this); /* EMIT_SIGNAL */
-	
+
 	if (_active_notes)
 		end_write();
 
@@ -485,18 +484,18 @@
 	RegionView::region_resized(what_changed);
 
 	if (what_changed & ARDOUR::PositionChanged) {
-	
+
 		if (_enable_display)
 			redisplay_model();
-	
+
 	} else if (what_changed & Change (StartChanged)) {
 
 		//cerr << "MIDI RV START CHANGED" << endl;
 
 	} else if (what_changed & Change (LengthChanged)) {
-		
+
 		//cerr << "MIDI RV LENGTH CHANGED" << endl;
-	
+
 	}
 }
 
@@ -505,7 +504,7 @@
 {
 	RegionView::reset_width_dependent_items(pixel_width);
 	assert(_pixel_width == pixel_width);
-		
+
 	if (_enable_display)
 		redisplay_model();
 }
@@ -516,7 +515,7 @@
 	RegionView::set_y_position_and_height(y, h - 1);
 
 	if (_enable_display) {
-		
+
 		_model->read_lock();
 
 		for (std::vector<CanvasMidiEvent*>::const_iterator i = _events.begin(); i != _events.end(); ++i) {
@@ -531,7 +530,7 @@
 				else {
 					const double y1 = midi_stream_view()->note_to_y(note->note()->note());
 					const double y2 = y1 + floor(midi_stream_view()->note_height());
-					
+
 					if (!canvas_item_visible(note)) {
 						note->show();
 					}
@@ -541,7 +540,7 @@
 				}
 			}
 		}
-		
+
 		_model->read_unlock();
 	}
 
@@ -654,9 +653,9 @@
 	assert(midi_view()->note_mode() == Sustained || midi_view()->note_mode() == Percussive);
 
 	ArdourCanvas::Group* const group = (ArdourCanvas::Group*)get_canvas_group();
-	
+
 	if (midi_view()->note_mode() == Sustained) {
-	
+
 		//cerr << "MRV::add_note sustained " << note->note() << " @ " << note->time()
 		//	<< " .. " << note->end_time() << endl;
 
@@ -682,12 +681,12 @@
 			/* outline all edges */
 			ev_rect->property_outline_what() = (guint32) 0xF;
 		}
-		
+
 		ev_rect->show();
 		_events.push_back(ev_rect);
 
 		MidiGhostRegion* gr;
-		
+
 		for (vector<GhostRegion*>::iterator g = ghosts.begin(); g != ghosts.end(); ++g) {
 			if ((gr = dynamic_cast<MidiGhostRegion*>(*g)) != 0) {
 				gr->add_note(ev_rect);
@@ -695,10 +694,10 @@
 		}
 
 	} else if (midi_view()->note_mode() == Percussive) {
-		
+
 		//cerr << "MRV::add_note percussive " << note->note() << " @ " << note->time()
 		//	<< " .. " << note->end_time() << endl;
-		
+
 		const double diamond_size = midi_stream_view()->note_height() / 2.0;
 		const double x = trackview.editor.frame_to_pixel((nframes_t)note->time());
 		const double y = midi_stream_view()->note_to_y(note->note()) + ((diamond_size-2) / 4.0);
@@ -709,7 +708,7 @@
 		ev_diamond->property_fill_color_rgba() = note_fill_color(note->velocity());
 		ev_diamond->property_outline_color_rgba() = note_outline_color(note->velocity());
 		_events.push_back(ev_diamond);
-	
+
 	}
 }
 
@@ -744,19 +743,19 @@
 
 	_selection.clear();
 	_selection.insert(ev);
-	
+
 	if ( ! ev->selected())
 		ev->selected(true);
 }
-	
+
 void
 MidiRegionView::note_selected(ArdourCanvas::CanvasMidiEvent* ev, bool add)
 {
 	if ( ! add)
 		clear_selection_except(ev);
-	
+
 	_selection.insert(ev);
-	
+
 	if ( ! ev->selected())
 		ev->selected(true);
 }
@@ -767,9 +766,9 @@
 {
 	if ( ! add)
 		clear_selection_except(ev);
-	
+
 	_selection.erase(ev);
-	
+
 	if (ev->selected())
 		ev->selected(false);
 }
@@ -780,7 +779,7 @@
 {
 	const double last_y = std::min(y1, y2);
 	const double y      = std::max(y1, y2);
-	
+
 	// FIXME: so, so, so much slower than this should be
 
 	if (x1 < x2) {
@@ -806,7 +805,7 @@
 	}
 }
 
-	
+
 void
 MidiRegionView::move_selection(double dx, double dy)
 {
@@ -827,7 +826,7 @@
 			++next;
 
 			command_remove_note(*i);
-			const boost::shared_ptr<Note> copy(new Note(*(*i)->note().get())); 
+			const boost::shared_ptr<Note> copy(new Note(*(*i)->note().get()));
 
 			copy->set_time((*i)->note()->time() + dt);
 			copy->set_note((*i)->note()->note() + dnote);
@@ -840,9 +839,125 @@
 		apply_command();
 	}
 }
-	
 
 void
+MidiRegionView::begin_resizing(CanvasNote::NoteEnd note_end)
+{
+	_resize_data.clear();
+
+	for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) {
+		CanvasNote *note = dynamic_cast<CanvasNote *> (*i);
+
+		// only insert CanvasNotes into the map
+		if(note) {
+			NoteResizeData *resize_data = new NoteResizeData();
+			resize_data->canvas_note = note;
+
+			SimpleRect *resize_rect = new SimpleRect(*group, note->x1(), note->y1(), note->x2(), note->y2());
+
+			uint fill_color = UINT_RGBA_CHANGE_A(ARDOUR_UI::config()->canvasvar_MidiNoteSelectedOutline.get(), 128);
+			fill_color = UINT_INTERPOLATE(fill_color, 0xFFFFFF40, 0.5);
+
+			resize_rect->property_fill_color_rgba() =
+				UINT_INTERPOLATE(
+					note_fill_color(note->note()->velocity()),
+					fill_color,
+					0.85);
+
+			resize_rect->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_MidiNoteSelectedOutline.get();
+			resize_data->resize_rect = resize_rect;
+
+			if(note_end == CanvasNote::NOTE_ON) {
+				resize_data->current_x = note->x1();
+			} else { // NOTE_OFF
+				resize_data->current_x = note->x2();
+			}
+
+			_resize_data.push_back(resize_data);
+		}
+	}
+}
+
+double
+MidiRegionView::snap_to(double x)
+{
+	PublicEditor &editor = trackview.editor;
+
+	nframes_t frame = editor.pixel_to_frame(x);
+	editor.snap_to(frame);
+	return (double) editor.frame_to_pixel(frame);
+}
+
+void
+MidiRegionView::update_resizing(CanvasNote::NoteEnd note_end, double dx, bool relative)
+{
+
+
+	for (std::vector<NoteResizeData *>::iterator i = _resize_data.begin(); i != _resize_data.end(); ++i) {
+		SimpleRect     *resize_rect = (*i)->resize_rect;
+		CanvasNote     *canvas_note = (*i)->canvas_note;
+
+		if(relative) {
+			(*i)->current_x = (*i)->current_x + dx;
+		} else {
+			(*i)->current_x = dx;
+		}
+
+		double current_x = (*i)->current_x;
+
+		if(note_end == CanvasNote::NOTE_ON) {
+			resize_rect->property_x1() = snap_to(current_x);
+			resize_rect->property_x2() = canvas_note->x2();
+		} else {
+			resize_rect->property_x2() = snap_to(current_x);
+			resize_rect->property_x1() = canvas_note->x1();
+		}
+	}
+}
+
+void
+MidiRegionView::commit_resizing(CanvasNote::NoteEnd note_end, double event_x, bool relative)
+{
+	start_delta_command();
+
+	for (std::vector<NoteResizeData *>::iterator i = _resize_data.begin(); i != _resize_data.end(); ++i) {
+		CanvasNote *canvas_note = (*i)->canvas_note;
+		SimpleRect *resize_rect = (*i)->resize_rect;
+		double      current_x   = (*i)->current_x;
+
+
+		if(!relative) {
+			current_x = event_x;
+		}
+
+		nframes_t current_frame = trackview.editor.pixel_to_frame(current_x);
+		trackview.editor.snap_to(current_frame);
+
+		const boost::shared_ptr<Note> copy(new Note(*(canvas_note->note().get())));
+
+		// resize beginning of note
+		if (note_end == CanvasNote::NOTE_ON && current_frame < copy->end_time()) {
+			command_remove_note(canvas_note);
+			copy->on_event().time() = current_frame;
+			command_add_note(copy);
+		}
+		// resize end of note
+		if (note_end == CanvasNote::NOTE_OFF && current_frame > copy->time()) {
+			command_remove_note(canvas_note);
+			copy->off_event().time() = current_frame;
+			command_add_note(copy);
+		}
+
+		delete resize_rect;
+		delete (*i);
+	}
+
+	_resize_data.clear();
+	apply_command();
+	clear_selection();
+}
+
+void
 MidiRegionView::note_entered(ArdourCanvas::CanvasMidiEvent* ev)
 {
 	if (ev->note() && _mouse_state == EraseTouchDragging) {
@@ -853,8 +968,8 @@
 		note_selected(ev, true);
 	}
 }
-	
 
+
 void
 MidiRegionView::switch_source(boost::shared_ptr<Source> src)
 {
