Remove unused function
[ardour.git] / gtk2_ardour / midi_region_view.cc
index ed1708a7a9048f28b0cbef43ad0209df0203b298..db3f4760bc3c1bfa5a8d46ae63de004eefaf6c32 100644 (file)
@@ -43,7 +43,7 @@
 #include "evoral/Control.hpp"
 #include "evoral/midi_util.h"
 
-#include "canvas/pixbuf.h"
+#include "canvas/debug.h"
 
 #include "automation_region_view.h"
 #include "automation_time_axis.h"
@@ -89,7 +89,7 @@ PBD::Signal1<void, MidiRegionView *> MidiRegionView::SelectionCleared;
 #define MIDI_BP_ZERO ((Config->get_first_midi_bank_is_zero())?0:1)
 
 MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv,
-                                boost::shared_ptr<MidiRegion> r, double spu, Gdk::Color const & basic_color)
+                                boost::shared_ptr<MidiRegion> r, double spu, uint32_t basic_color)
        : RegionView (parent, tv, r, spu, basic_color)
        , _current_range_min(0)
        , _current_range_max(0)
@@ -114,6 +114,7 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
        , pre_press_cursor (0)
        , _note_player (0)
 {
+       CANVAS_DEBUG_NAME (_note_group, string_compose ("note group for %1", get_item_name()));
        _note_group->raise_to_top();
        PublicEditor::DropDownKeys.connect (sigc::mem_fun (*this, &MidiRegionView::drop_down_keys));
 
@@ -124,7 +125,7 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
 }
 
 MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &tv,
-                                boost::shared_ptr<MidiRegion> r, double spu, Gdk::Color& basic_color,
+                                boost::shared_ptr<MidiRegion> r, double spu, uint32_t basic_color,
                                 TimeAxisViewItem::Visibility visibility)
        : RegionView (parent, tv, r, spu, basic_color, false, visibility)
        , _current_range_min(0)
@@ -150,7 +151,9 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
        , pre_press_cursor (0)
        , _note_player (0)
 {
+       CANVAS_DEBUG_NAME (_note_group, string_compose ("note group for %1", get_item_name()));
        _note_group->raise_to_top();
+
        PublicEditor::DropDownKeys.connect (sigc::mem_fun (*this, &MidiRegionView::drop_down_keys));
 
        connect_to_diskstream ();
@@ -161,7 +164,7 @@ MidiRegionView::MidiRegionView (ArdourCanvas::Group *parent, RouteTimeAxisView &
 void
 MidiRegionView::parameter_changed (std::string const & p)
 {
-       if (p == "diplay-first-midi-bank-as-zero") {
+       if (p == "display-first-midi-bank-as-zero") {
                if (_enable_display) {
                        redisplay_model();
                }
@@ -194,13 +197,7 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other)
        , pre_press_cursor (0)
        , _note_player (0)
 {
-       Gdk::Color c;
-       int r,g,b,a;
-
-       UINT_TO_RGBA (other.fill_color, &r, &g, &b, &a);
-       c.set_rgb_p (r/255.0, g/255.0, b/255.0);
-
-       init (c, false);
+       init (false);
 }
 
 MidiRegionView::MidiRegionView (const MidiRegionView& other, boost::shared_ptr<MidiRegion> region)
@@ -228,17 +225,11 @@ MidiRegionView::MidiRegionView (const MidiRegionView& other, boost::shared_ptr<M
        , pre_press_cursor (0)
        , _note_player (0)
 {
-       Gdk::Color c;
-       int r,g,b,a;
-
-       UINT_TO_RGBA (other.fill_color, &r, &g, &b, &a);
-       c.set_rgb_p (r/255.0, g/255.0, b/255.0);
-
-       init (c, true);
+       init (true);
 }
 
 void
-MidiRegionView::init (Gdk::Color const & basic_color, bool wfd)
+MidiRegionView::init (bool wfd)
 {
        PublicEditor::DropDownKeys.connect (sigc::mem_fun (*this, &MidiRegionView::drop_down_keys));
 
@@ -253,9 +244,7 @@ MidiRegionView::init (Gdk::Color const & basic_color, bool wfd)
        _model = midi_region()->midi_source(0)->model();
        _enable_display = false;
 
-       RegionView::init (basic_color, false);
-
-       compute_colors (basic_color);
+       RegionView::init (false);
 
        set_height (trackview.current_height());
 
@@ -276,8 +265,6 @@ MidiRegionView::init (Gdk::Color const & basic_color, bool wfd)
        reset_width_dependent_items (_pixel_width);
 
        group->raise_to_top();
-       group->Event.connect (sigc::mem_fun (this, &MidiRegionView::canvas_event));
-
 
        midi_view()->midi_track()->PlaybackChannelModeChanged.connect (_channel_mode_changed_connection, invalidator (*this),
                                                                       boost::bind (&MidiRegionView::midi_channel_mode_changed, this),
@@ -319,7 +306,7 @@ MidiRegionView::connect_to_diskstream ()
 }
 
 bool
-MidiRegionView::canvas_event(GdkEvent* ev)
+MidiRegionView::canvas_group_event(GdkEvent* ev)
 {
        bool r;
 
@@ -349,8 +336,8 @@ MidiRegionView::canvas_event(GdkEvent* ev)
        if ((!trackview.editor().internal_editing() && trackview.editor().current_mouse_mode() != MouseGain) ||
                (trackview.editor().current_mouse_mode() == MouseTimeFX) ||
                (trackview.editor().current_mouse_mode() == MouseZoom)) {
-               // handle non-draw modes elsewhere
-               return false;
+               // handle non-internal-edit/non-draw modes elsewhere
+               return RegionView::canvas_group_event (ev);
        }
 
        switch (ev->type) {
@@ -385,14 +372,7 @@ MidiRegionView::canvas_event(GdkEvent* ev)
                break;
        }
 
-       return false;
-}
-
-void
-MidiRegionView::remove_ghost_note ()
-{
-       delete _ghost_note;
-       _ghost_note = 0;
+       return trackview.editor().canvas_region_view_event (ev, group, this);
 }
 
 bool
@@ -530,7 +510,7 @@ MidiRegionView::button_release (GdkEventButton* ev)
                                        group->canvas_to_item (event_x, event_y);
 
                                        bool success;
-                                       Evoral::MusicalTime beats = editor.get_grid_type_as_beats (success, editor.pixel_to_frame (event_x));
+                                       Evoral::MusicalTime beats = editor.get_grid_type_as_beats (success, editor.pixel_to_sample (event_x));
 
                                        if (!success) {
                                                beats = 1;
@@ -541,7 +521,7 @@ MidiRegionView::button_release (GdkEventButton* ev)
                                        */
                                        beats -= 1.0 / Timecode::BBT_Time::ticks_per_beat;
 
-                                       create_note_at (editor.pixel_to_frame (event_x), event_y, beats, true);
+                                       create_note_at (editor.pixel_to_sample (event_x), event_y, beats, true);
                                }
 
                                break;
@@ -549,7 +529,7 @@ MidiRegionView::button_release (GdkEventButton* ev)
                case MouseDraw:
                        {
                                bool success;
-                               Evoral::MusicalTime beats = editor.get_grid_type_as_beats (success, editor.pixel_to_frame (event_x));
+                               Evoral::MusicalTime beats = editor.get_grid_type_as_beats (success, editor.pixel_to_sample (event_x));
 
                                if (!success) {
                                        beats = 1;
@@ -560,7 +540,7 @@ MidiRegionView::button_release (GdkEventButton* ev)
                                */
                                beats -= 1.0 / Timecode::BBT_Time::ticks_per_beat;
                                
-                               create_note_at (editor.pixel_to_frame (event_x), event_y, beats, true);
+                               create_note_at (editor.pixel_to_sample (event_x), event_y, beats, true);
 
                                break;
                        }
@@ -626,7 +606,6 @@ MidiRegionView::motion (GdkEventMotion* ev)
                        MouseMode m = editor.current_mouse_mode();
                        
                        if (m == MouseDraw || (m == MouseObject && Keyboard::modifier_state_contains (ev->state, Keyboard::insert_note_modifier()))) {
-                       
                                editor.drags()->set (new NoteCreateDrag (dynamic_cast<Editor *> (&editor), group, this), (GdkEvent *) ev);
                                _mouse_state = AddDragging;
                                remove_ghost_note ();
@@ -657,9 +636,13 @@ MidiRegionView::motion (GdkEventMotion* ev)
 
        default:
                break;
+
        }
 
-       return false;
+       /* we may be dragging some non-note object (eg. patch-change, sysex) 
+        */
+
+       return editor.drags()->motion_handler ((GdkEvent *) ev, false);
 }
 
 
@@ -1118,6 +1101,8 @@ MidiRegionView::redisplay_model()
        MidiModel::Notes& notes (_model->notes());
        _optimization_iterator = _events.begin();
 
+       bool empty_when_starting = _events.empty();
+
        for (MidiModel::Notes::iterator n = notes.begin(); n != notes.end(); ++n) {
 
                boost::shared_ptr<NoteType> note (*n);
@@ -1125,8 +1110,8 @@ MidiRegionView::redisplay_model()
                bool visible;
 
                if (note_in_region_range (note, visible)) {
-
-                       if ((cne = find_canvas_note (note)) != 0) {
+                       
+                       if (!empty_when_starting && (cne = find_canvas_note (note)) != 0) {
 
                                cne->validate ();
 
@@ -1151,8 +1136,8 @@ MidiRegionView::redisplay_model()
                        }
 
                } else {
-
-                       if ((cne = find_canvas_note (note)) != 0) {
+                       
+                       if (!empty_when_starting && (cne = find_canvas_note (note)) != 0) {
                                cne->validate ();
                                cne->hide ();
                        }
@@ -1162,21 +1147,23 @@ MidiRegionView::redisplay_model()
 
        /* remove note items that are no longer valid */
 
-       for (Events::iterator i = _events.begin(); i != _events.end(); ) {
-               if (!(*i)->valid ()) {
-
-                       for (vector<GhostRegion*>::iterator j = ghosts.begin(); j != ghosts.end(); ++j) {
-                               MidiGhostRegion* gr = dynamic_cast<MidiGhostRegion*> (*j);
-                               if (gr) {
-                                       gr->remove_note (*i);
+       if (!empty_when_starting) {
+               for (Events::iterator i = _events.begin(); i != _events.end(); ) {
+                       if (!(*i)->valid ()) {
+                               
+                               for (vector<GhostRegion*>::iterator j = ghosts.begin(); j != ghosts.end(); ++j) {
+                                       MidiGhostRegion* gr = dynamic_cast<MidiGhostRegion*> (*j);
+                                       if (gr) {
+                                               gr->remove_note (*i);
+                                       }
                                }
+                               
+                               delete *i;
+                               i = _events.erase (i);
+                               
+                       } else {
+                               ++i;
                        }
-                       
-                       delete *i;
-                       i = _events.erase (i);
-                       
-               } else {
-                       ++i;
                }
        }
 
@@ -1290,7 +1277,7 @@ MidiRegionView::display_sysexes()
                }
                string text = str.str();
 
-               const double x = trackview.editor().frame_to_pixel(source_beats_to_region_frames(time));
+               const double x = trackview.editor().sample_to_pixel(source_beats_to_region_frames(time));
 
                double height = midi_stream_view()->contents_height();
 
@@ -1360,16 +1347,13 @@ MidiRegionView::reset_width_dependent_items (double pixel_width)
                redisplay_model();
        }
 
-// CAIROCANVAS
-#if 0
        for (PatchChanges::iterator x = _patch_changes.begin(); x != _patch_changes.end(); ++x) {
-               if ((*x)->width() >= _pixel_width) {
+               if ((*x)->canvas_item()->width() >= _pixel_width) {
                        (*x)->hide();
                } else {
                        (*x)->show();
                }
        }
-#endif
 
        move_step_edit_cursor (_step_edit_cursor_position);
        set_step_edit_cursor_width (_step_edit_cursor_width);
@@ -1378,17 +1362,15 @@ MidiRegionView::reset_width_dependent_items (double pixel_width)
 void
 MidiRegionView::set_height (double height)
 {
-       static const double FUDGE = 2.0;
-       const double old_height = _height;
+       double old_height = _height;
        RegionView::set_height(height);
-       _height = height - FUDGE;
 
-       apply_note_range(midi_stream_view()->lowest_note(),
-                        midi_stream_view()->highest_note(),
-                        height != old_height + FUDGE);
+       apply_note_range (midi_stream_view()->lowest_note(),
+                         midi_stream_view()->highest_note(),
+                         height != old_height);
 
-       if (name_pixbuf) {
-               name_pixbuf->raise_to_top();
+       if (name_text) {
+               name_text->raise_to_top();
        }
 
        for (PatchChanges::iterator x = _patch_changes.begin(); x != _patch_changes.end(); ++x) {
@@ -1438,10 +1420,7 @@ MidiRegionView::apply_note_range (uint8_t min, uint8_t max, bool force)
                        cnote->set_y1 (y1);
 
                } else if (Hit* chit = dynamic_cast<Hit*>(event)) {
-
-                       const double diamond_size = update_hit (chit);
-
-                       chit->set_height (diamond_size);
+                       update_hit (chit);
                }
        }
 }
@@ -1451,7 +1430,7 @@ MidiRegionView::add_ghost (TimeAxisView& tv)
 {
        Note* note;
 
-       double unit_position = _region->position () / frames_per_pixel;
+       double unit_position = _region->position () / samples_per_pixel;
        MidiTimeAxisView* mtv = dynamic_cast<MidiTimeAxisView*>(&tv);
        MidiGhostRegion* ghost;
 
@@ -1471,7 +1450,7 @@ MidiRegionView::add_ghost (TimeAxisView& tv)
        }
 
        ghost->set_height ();
-       ghost->set_duration (_region->length() / frames_per_pixel);
+       ghost->set_duration (_region->length() / samples_per_pixel);
        ghosts.push_back (ghost);
 
        GhostRegion::CatchDeletion.connect (*this, invalidator (*this), boost::bind (&RegionView::remove_ghost, this, _1), gui_context());
@@ -1524,9 +1503,10 @@ MidiRegionView::resolve_note(uint8_t note, double end_time)
                */
                const framepos_t end_time_frames = region_beats_to_region_frames(end_time);
 
-               _active_notes[note]->set_x1 (trackview.editor().frame_to_pixel(end_time_frames));
-               _active_notes[note]->set_outline_what (0xf);
+               _active_notes[note]->set_x1 (trackview.editor().sample_to_pixel(end_time_frames));
+               _active_notes[note]->set_outline_all ();
                _active_notes[note] = 0;
+
        }
 }
 
@@ -1542,7 +1522,7 @@ MidiRegionView::extend_active_notes()
 
        for (unsigned i=0; i < 128; ++i) {
                if (_active_notes[i]) {
-                       _active_notes[i]->set_x1 (trackview.editor().frame_to_pixel(_region->length()));
+                       _active_notes[i]->set_x1 (trackview.editor().sample_to_pixel(_region->length()));
                }
        }
 }
@@ -1631,7 +1611,7 @@ void
 MidiRegionView::update_note (Note* ev, bool update_ghost_regions)
 {
        boost::shared_ptr<NoteType> note = ev->note();
-       const double x = trackview.editor().frame_to_pixel (source_beats_to_region_frames (note->time()));
+       const double x = trackview.editor().sample_to_pixel (source_beats_to_region_frames (note->time()));
        const double y0 = midi_stream_view()->note_to_y(note->note());
 
        ev->set_x0 (x);
@@ -1641,9 +1621,9 @@ MidiRegionView::update_note (Note* ev, bool update_ghost_regions)
 
        if (note->length() > 0) {
                const framepos_t note_end_frames = min (source_beats_to_region_frames (note->end_time()), _region->length());
-               ev->set_x1 (trackview.editor().frame_to_pixel (note_end_frames));
+               ev->set_x1 (trackview.editor().sample_to_pixel (note_end_frames));
        } else {
-               ev->set_x1 (trackview.editor().frame_to_pixel (_region->length()));
+               ev->set_x1 (trackview.editor().sample_to_pixel (_region->length()));
        }
 
        ev->set_y1 (y0 + floor(midi_stream_view()->note_height()));
@@ -1656,15 +1636,18 @@ MidiRegionView::update_note (Note* ev, bool update_ghost_regions)
                                Note* const old_rect = _active_notes[note->note()];
                                boost::shared_ptr<NoteType> old_note = old_rect->note();
                                old_rect->set_x1 (x);
-                               old_rect->set_outline_what (0xF);
+                               old_rect->set_outline_all ();
                        }
                        _active_notes[note->note()] = ev;
                }
                /* outline all but right edge */
-               ev->set_outline_what (0x1 & 0x4 & 0x8);
+               ev->set_outline_what (ArdourCanvas::Rectangle::What (
+                                             ArdourCanvas::Rectangle::TOP|
+                                             ArdourCanvas::Rectangle::LEFT|
+                                             ArdourCanvas::Rectangle::BOTTOM));
        } else {
                /* outline all edges */
-               ev->set_outline_what (0xF);
+               ev->set_outline_all ();
        }
        
        if (update_ghost_regions) {
@@ -1677,19 +1660,18 @@ MidiRegionView::update_note (Note* ev, bool update_ghost_regions)
        }
 }
 
-double
+void
 MidiRegionView::update_hit (Hit* ev)
 {
        boost::shared_ptr<NoteType> note = ev->note();
 
        const framepos_t note_start_frames = source_beats_to_region_frames(note->time());
-       const double x = trackview.editor().frame_to_pixel(note_start_frames);
-       const double diamond_size = midi_stream_view()->note_height() / 2.0;
-       const double y = midi_stream_view()->note_to_y(note->note()) + ((diamond_size-2) / 4.0);
+       const double x = trackview.editor().sample_to_pixel(note_start_frames);
+       const double diamond_size = midi_stream_view()->note_height();
+       const double y = midi_stream_view()->note_to_y(note->note()) + (diamond_size/2.0);
 
        ev->set_position (ArdourCanvas::Duple (x, y));
-
-       return diamond_size;
+       ev->set_height (diamond_size);
 }
 
 /** Add a MIDI note to the view (with length).
@@ -1703,8 +1685,6 @@ MidiRegionView::add_note(const boost::shared_ptr<NoteType> note, bool visible)
 {
        NoteBase* event = 0;
 
-       //ArdourCanvas::Group* const group = (ArdourCanvas::Group*) get_canvas_group();
-
        if (midi_view()->note_mode() == Sustained) {
 
                Note* ev_rect = new Note (*this, _note_group, note);
@@ -1805,7 +1785,7 @@ void
 MidiRegionView::add_canvas_patch_change (MidiModel::PatchChangePtr patch, const string& displaytext, bool /*active_channel*/)
 {
        framecnt_t region_frames = source_beats_to_region_frames (patch->time());
-       const double x = trackview.editor().frame_to_pixel (region_frames);
+       const double x = trackview.editor().sample_to_pixel (region_frames);
 
        double const height = midi_stream_view()->contents_height();
 
@@ -2134,32 +2114,39 @@ MidiRegionView::invert_selection ()
 void
 MidiRegionView::select_matching_notes (uint8_t notenum, uint16_t channel_mask, bool add, bool extend)
 {
+       bool have_selection = !_selection.empty();
        uint8_t low_note = 127;
        uint8_t high_note = 0;
        MidiModel::Notes& notes (_model->notes());
        _optimization_iterator = _events.begin();
+       
+       if (extend && !have_selection) {
+               extend = false;
+       }
 
+       /* scan existing selection to get note range */
+       
+       for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) {
+               if ((*i)->note()->note() < low_note) {
+                       low_note = (*i)->note()->note();
+               }
+               if ((*i)->note()->note() > high_note) {
+                       high_note = (*i)->note()->note();
+               }
+       }
+       
        if (!add) {
                clear_selection ();
-       }
 
-       if (extend && _selection.empty()) {
-               extend = false;
+               if (!extend && (low_note == high_note) && (high_note == notenum)) {
+                       /* only note previously selected is the one we are
+                        * reselecting. treat this as cancelling the selection.
+                        */
+                       return;
+               }
        }
 
        if (extend) {
-
-               /* scan existing selection to get note range */
-
-               for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) {
-                       if ((*i)->note()->note() < low_note) {
-                               low_note = (*i)->note()->note();
-                       }
-                       if ((*i)->note()->note() > high_note) {
-                               high_note = (*i)->note()->note();
-                       }
-               }
-
                low_note = min (low_note, notenum);
                high_note = max (high_note, notenum);
        }
@@ -2471,10 +2458,10 @@ MidiRegionView::note_dropped(NoteBase *, frameoffset_t dt, int8_t dnote)
  *  @return Snapped frame relative to the region position.
  */
 framepos_t
-MidiRegionView::snap_pixel_to_frame(double x)
+MidiRegionView::snap_pixel_to_sample(double x)
 {
        PublicEditor& editor (trackview.editor());
-       return snap_frame_to_frame (editor.pixel_to_frame (x));
+       return snap_frame_to_frame (editor.pixel_to_sample (x));
 }
 
 /** @param x Pixel relative to the region position.
@@ -2483,21 +2470,21 @@ MidiRegionView::snap_pixel_to_frame(double x)
 double
 MidiRegionView::snap_to_pixel(double x)
 {
-       return (double) trackview.editor().frame_to_pixel(snap_pixel_to_frame(x));
+       return (double) trackview.editor().sample_to_pixel(snap_pixel_to_sample(x));
 }
 
 double
 MidiRegionView::get_position_pixels()
 {
        framepos_t region_frame = get_position();
-       return trackview.editor().frame_to_pixel(region_frame);
+       return trackview.editor().sample_to_pixel(region_frame);
 }
 
 double
 MidiRegionView::get_end_position_pixels()
 {
        framepos_t frame = get_position() + get_duration ();
-       return trackview.editor().frame_to_pixel(frame);
+       return trackview.editor().sample_to_pixel(frame);
 }
 
 framepos_t
@@ -2553,7 +2540,7 @@ MidiRegionView::begin_resizing (bool /*at_front*/)
 
                        // calculate the colors: get the color settings
                        uint32_t fill_color = UINT_RGBA_CHANGE_A(
-                               ARDOUR_UI::config()->canvasvar_MidiNoteSelected.get(),
+                               ARDOUR_UI::config()->get_canvasvar_MidiNoteSelected(),
                                128);
 
                        // make the resize preview notes more transparent and bright
@@ -2566,7 +2553,7 @@ MidiRegionView::begin_resizing (bool /*at_front*/)
                                0.85));
 
                        resize_rect->set_outline_color (NoteBase::calculate_outline (
-                                                               ARDOUR_UI::config()->canvasvar_MidiNoteSelected.get()));
+                                                               ARDOUR_UI::config()->get_canvasvar_MidiNoteSelected()));
 
                        resize_data->resize_rect = resize_rect;
                        _resize_data.push_back(resize_data);
@@ -2618,7 +2605,7 @@ MidiRegionView::update_resizing (NoteBase* primary, bool at_front, double delta_
                if (!cursor_set) {
                        double beats;
 
-                       beats = snap_pixel_to_frame (current_x);
+                       beats = snap_pixel_to_sample (current_x);
                        beats = region_frames_to_region_beats (beats);
 
                        double len;
@@ -2682,7 +2669,7 @@ MidiRegionView::commit_resizing (NoteBase* primary, bool at_front, double delta_
                }
 
                /* Convert that to a frame within the source */
-               current_x = snap_pixel_to_frame (current_x) + _region->start ();
+               current_x = snap_pixel_to_sample (current_x) + _region->start ();
 
                /* and then to beats */
                current_x = region_frames_to_region_beats (current_x);
@@ -3072,7 +3059,7 @@ MidiRegionView::nudge_notes (bool forward)
                return;
        }
 
-       Evoral::MusicalTime delta = region_frames_to_region_beats (fabs (distance));
+       Evoral::MusicalTime delta = region_frames_to_region_beats (fabs ((double)distance));
 
        if (!forward) {
                delta = -delta;
@@ -3204,9 +3191,9 @@ MidiRegionView::set_frame_color()
        }
 
        if (_selected) {
-               f = ARDOUR_UI::config()->canvasvar_SelectedFrameBase.get();
+               f = ARDOUR_UI::config()->get_canvasvar_SelectedFrameBase();
        } else if (high_enough_for_name) {
-               f= ARDOUR_UI::config()->canvasvar_MidiFrameBase.get();
+               f= ARDOUR_UI::config()->get_canvasvar_MidiFrameBase();
        } else {
                f = fill_color;
        }
@@ -3290,7 +3277,7 @@ MidiRegionView::selection_as_cut_buffer () const
 {
        Notes notes;
 
-       for (Selection::iterator i = _selection.begin(); i != _selection.end(); ++i) {
+       for (Selection::const_iterator i = _selection.begin(); i != _selection.end(); ++i) {
                NoteType* n = (*i)->note().get();
                notes.insert (boost::shared_ptr<NoteType> (new NoteType (*n)));
        }
@@ -3494,7 +3481,7 @@ MidiRegionView::update_ghost_note (double x, double y)
 
        PublicEditor& editor = trackview.editor ();
        
-       framepos_t const unsnapped_frame = editor.pixel_to_frame (x);
+       framepos_t const unsnapped_frame = editor.pixel_to_sample (x);
        framecnt_t grid_frames;
        framepos_t const f = snap_frame_to_grid_underneath (unsnapped_frame, grid_frames);
 
@@ -3540,6 +3527,13 @@ MidiRegionView::create_ghost_note (double x, double y)
        show_verbose_cursor (_ghost_note->note ());
 }
 
+void
+MidiRegionView::remove_ghost_note ()
+{
+       delete _ghost_note;
+       _ghost_note = 0;
+}
+
 void
 MidiRegionView::snap_changed ()
 {
@@ -3635,7 +3629,7 @@ MidiRegionView::move_step_edit_cursor (Evoral::MusicalTime pos)
        _step_edit_cursor_position = pos;
 
        if (_step_edit_cursor) {
-               double pixel = trackview.editor().frame_to_pixel (region_beats_to_region_frames (pos));
+               double pixel = trackview.editor().sample_to_pixel (region_beats_to_region_frames (pos));
                _step_edit_cursor->set_x0 (pixel);
                set_step_edit_cursor_width (_step_edit_cursor_width);
        }
@@ -3655,7 +3649,7 @@ MidiRegionView::set_step_edit_cursor_width (Evoral::MusicalTime beats)
        _step_edit_cursor_width = beats;
 
        if (_step_edit_cursor) {
-               _step_edit_cursor->set_x1 (_step_edit_cursor->x0() + trackview.editor().frame_to_pixel (region_beats_to_region_frames (beats)));
+               _step_edit_cursor->set_x1 (_step_edit_cursor->x0() + trackview.editor().sample_to_pixel (region_beats_to_region_frames (beats)));
        }
 }
 
@@ -3754,8 +3748,6 @@ MidiRegionView::edit_patch_change (PatchChange* pc)
 {
        PatchChangeDialog d (&_source_relative_time_converter, trackview.session(), *pc->patch (), instrument_info(), Gtk::Stock::APPLY, true);
 
-        d.set_position (Gtk::WIN_POS_MOUSE);
-       
        int response = d.run();
 
        switch (response) {
@@ -3820,6 +3812,7 @@ MidiRegionView::show_verbose_cursor (string const & text, double xoffset, double
 {
        double wx, wy;
 
+       trackview.editor().verbose_cursor()->set_text (text);
        trackview.editor().get_pointer_position (wx, wy);
 
        wx += xoffset;
@@ -3827,13 +3820,17 @@ MidiRegionView::show_verbose_cursor (string const & text, double xoffset, double
 
        /* Flip the cursor above the mouse pointer if it would overlap the bottom of the canvas */
 
-       ArdourCanvas::Rect bb = trackview.editor().verbose_cursor()->item().bounding_box().get();
+       boost::optional<ArdourCanvas::Rect> bbo = trackview.editor().verbose_cursor()->item().bounding_box();
+
+       assert (bbo);
+       
+       ArdourCanvas::Rect bb = bbo.get();
 
        if ((wy + bb.y1 - bb.y0) > trackview.editor().visible_canvas_height()) {
                wy -= (bb.y1 - bb.y0) + 2 * yoffset;
        }
 
-       trackview.editor().verbose_cursor()->set (text, wx, wy);
+       trackview.editor().verbose_cursor()->set_position (wx, wy);
        trackview.editor().verbose_cursor()->show ();
 }