Small cleanups to port matrix context menu.
[ardour.git] / gtk2_ardour / editor_ops.cc
index d9491a21b0fde3ab5646ca9d09fad74fad765582..0dfaecf4fd75b759eb8de02a3e55dedf8a9539c2 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2000-2004 Paul Davis 
+    Copyright (C) 2000-2004 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
@@ -35,7 +35,6 @@
 
 #include <gtkmm2ext/utils.h>
 #include <gtkmm2ext/choice.h>
-#include <gtkmm2ext/window_title.h>
 #include <gtkmm2ext/popup.h>
 
 #include "ardour/audioengine.h"
@@ -45,7 +44,6 @@
 #include "ardour/audio_diskstream.h"
 #include "ardour/utils.h"
 #include "ardour/location.h"
-#include "ardour/named_selection.h"
 #include "ardour/audio_track.h"
 #include "ardour/audioplaylist.h"
 #include "ardour/region_factory.h"
@@ -79,6 +77,7 @@
 #include "strip_silence_dialog.h"
 #include "editor_routes.h"
 #include "editor_regions.h"
+#include "quantize_dialog.h"
 
 #include "i18n.h"
 
@@ -125,7 +124,7 @@ Editor::split_regions_at (nframes64_t where, RegionSelection& regions)
        // region boundaries, don't pay attention to them
 
        if (regions.size() == 1) {
-               switch (snap_type) {
+               switch (_snap_type) {
                case SnapToRegionStart:
                case SnapToRegionSync:
                case SnapToRegionEnd:
@@ -144,7 +143,7 @@ Editor::split_regions_at (nframes64_t where, RegionSelection& regions)
                /* XXX this test needs to be more complicated, to make sure we really
                   have something to split.
                */
-               
+
                if (!(*a)->region()->covers (where)) {
                        ++a;
                        continue;
@@ -158,7 +157,7 @@ Editor::split_regions_at (nframes64_t where, RegionSelection& regions)
                if (! pl->frozen()) {
                        /* we haven't seen this playlist before */
 
-                       /* remember used playlists so we can thaw them later */ 
+                       /* remember used playlists so we can thaw them later */
                        used_playlists.push_back(pl);
                        pl->freeze();
                }
@@ -167,7 +166,7 @@ Editor::split_regions_at (nframes64_t where, RegionSelection& regions)
                if (arv) {
                        _new_regionviews_show_envelope = arv->envelope_visible();
                }
-               
+
                if (pl) {
                        XMLNode &before = pl->get_state();
                        pl->split_region ((*a)->region(), where);
@@ -183,7 +182,7 @@ Editor::split_regions_at (nframes64_t where, RegionSelection& regions)
                (*i)->thaw();
                used_playlists.pop_front();
        }
-       
+
        commit_reversible_command ();
        _new_regionviews_show_envelope = false;
 }
@@ -196,14 +195,14 @@ Editor::select_region_for_operation (int /*dir*/, TimeAxisView **tv)
        nframes64_t start = 0;
 
        if (selection->time.start () == selection->time.end_frame ()) {
-               
+
                /* no current selection-> is there a selected regionview? */
 
                if (selection->regions.empty()) {
                        return region;
                }
 
-       } 
+       }
 
        if (!selection->regions.empty()) {
 
@@ -219,18 +218,18 @@ Editor::select_region_for_operation (int /*dir*/, TimeAxisView **tv)
 
                if ((rtv = dynamic_cast<RouteTimeAxisView*> (*tv)) != 0) {
                        boost::shared_ptr<Playlist> pl;
-                       
+
                        if ((pl = rtv->playlist()) == 0) {
                                return region;
                        }
-                       
+
                        region = pl->top_region_at (start);
                }
-       } 
-       
+       }
+
        return region;
 }
-       
+
 void
 Editor::extend_selection_to_end_of_region (bool next)
 {
@@ -277,7 +276,7 @@ Editor::extend_selection_to_start_of_region (bool previous)
        }
 
        /* Try to leave the selection with the same route if possible */
-       
+
        if ((tv = selection->time.track) == 0) {
                return;
        }
@@ -315,19 +314,19 @@ Editor::nudge_forward (bool next, bool force_playhead)
 {
        nframes64_t distance;
        nframes64_t next_distance;
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
        if (!session) return;
-       
+
        if (!force_playhead && !rs.empty()) {
 
                begin_reversible_command (_("nudge regions forward"));
 
                for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
                        boost::shared_ptr<Region> r ((*i)->region());
-                       
+
                        distance = get_nudge_distance (r->position(), next_distance);
 
                        if (next) {
@@ -342,21 +341,21 @@ Editor::nudge_forward (bool next, bool force_playhead)
 
                commit_reversible_command ();
 
-               
+
        } else if (!force_playhead && !selection->markers.empty()) {
 
                bool is_start;
 
                begin_reversible_command (_("nudge location forward"));
-               
+
                for (MarkerSelection::iterator i = selection->markers.begin(); i != selection->markers.end(); ++i) {
-                       
+
                        Location* loc = find_location_from_marker ((*i), is_start);
-                       
+
                        if (loc) {
-                               
+
                                XMLNode& before (loc->get_state());
-                               
+
                                if (is_start) {
                                        distance = get_nudge_distance (loc->start(), next_distance);
                                        if (next) {
@@ -382,26 +381,26 @@ Editor::nudge_forward (bool next, bool force_playhead)
                                session->add_command (new MementoCommand<Location>(*loc, &before, &after));
                        }
                }
-               
+
                commit_reversible_command ();
-               
+
        } else {
                distance = get_nudge_distance (playhead_cursor->current_frame, next_distance);
                session->request_locate (playhead_cursor->current_frame + distance);
        }
 }
-               
+
 void
 Editor::nudge_backward (bool next, bool force_playhead)
 {
        nframes64_t distance;
        nframes64_t next_distance;
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
        if (!session) return;
-       
+
        if (!force_playhead && !rs.empty()) {
 
                begin_reversible_command (_("nudge regions backward"));
@@ -410,13 +409,13 @@ Editor::nudge_backward (bool next, bool force_playhead)
                        boost::shared_ptr<Region> r ((*i)->region());
 
                        distance = get_nudge_distance (r->position(), next_distance);
-                       
+
                        if (next) {
                                distance = next_distance;
                        }
 
                         XMLNode &before = r->playlist()->get_state();
-                       
+
                        if (r->position() > distance) {
                                r->set_position (r->position() - distance, this);
                        } else {
@@ -437,11 +436,11 @@ Editor::nudge_backward (bool next, bool force_playhead)
                for (MarkerSelection::iterator i = selection->markers.begin(); i != selection->markers.end(); ++i) {
 
                        Location* loc = find_location_from_marker ((*i), is_start);
-                       
+
                        if (loc) {
-                               
+
                                XMLNode& before (loc->get_state());
-                       
+
                                if (is_start) {
                                        distance = get_nudge_distance (loc->start(), next_distance);
                                        if (next) {
@@ -454,25 +453,25 @@ Editor::nudge_backward (bool next, bool force_playhead)
                                        }
                                } else {
                                        distance = get_nudge_distance (loc->end(), next_distance);
-                                       
+
                                        if (next) {
                                                distance = next_distance;
                                        }
-                                       
+
                                        if (distance < loc->end() - loc->length()) {
                                                loc->set_end (loc->end() - distance);
                                        } else {
                                                loc->set_end (loc->length());
                                        }
                                }
-                               
+
                                XMLNode& after (loc->get_state());
                                session->add_command (new MementoCommand<Location>(*loc, &before, &after));
                        }
                }
 
                commit_reversible_command ();
-                       
+
        } else {
 
                distance = get_nudge_distance (playhead_cursor->current_frame, next_distance);
@@ -489,12 +488,12 @@ void
 Editor::nudge_forward_capture_offset ()
 {
        nframes64_t distance;
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
        if (!session) return;
-       
+
        if (!rs.empty()) {
 
                begin_reversible_command (_("nudge forward"));
@@ -503,7 +502,7 @@ Editor::nudge_forward_capture_offset ()
 
                for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
                        boost::shared_ptr<Region> r ((*i)->region());
-                       
+
                        XMLNode &before = r->playlist()->get_state();
                        r->set_position (r->position() + distance, this);
                        XMLNode &after = r->playlist()->get_state();
@@ -512,19 +511,19 @@ Editor::nudge_forward_capture_offset ()
 
                commit_reversible_command ();
 
-       } 
+       }
 }
-               
+
 void
 Editor::nudge_backward_capture_offset ()
 {
        nframes64_t distance;
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
        if (!session) return;
-       
+
        if (!rs.empty()) {
 
                begin_reversible_command (_("nudge forward"));
@@ -535,7 +534,7 @@ Editor::nudge_backward_capture_offset ()
                        boost::shared_ptr<Region> r ((*i)->region());
 
                         XMLNode &before = r->playlist()->get_state();
-                       
+
                        if (r->position() > distance) {
                                r->set_position (r->position() - distance, this);
                        } else {
@@ -578,27 +577,27 @@ Editor::build_region_boundary_cache ()
        if (session == 0) {
                return;
        }
-       
-       switch (snap_type) {
+
+       switch (_snap_type) {
        case SnapToRegionStart:
                interesting_points.push_back (Start);
                break;
        case SnapToRegionEnd:
                interesting_points.push_back (End);
-               break;  
+               break;
        case SnapToRegionSync:
                interesting_points.push_back (SyncPoint);
-               break;  
+               break;
        case SnapToRegionBoundary:
                interesting_points.push_back (Start);
                interesting_points.push_back (End);
-               break;  
+               break;
        default:
-               fatal << string_compose (_("build_region_boundary_cache called with snap_type = %1"), snap_type) << endmsg;
+               fatal << string_compose (_("build_region_boundary_cache called with snap_type = %1"), _snap_type) << endmsg;
                /*NOTREACHED*/
                return;
        }
-       
+
        TimeAxisView *ontrack = 0;
        TrackViewList tlist;
 
@@ -630,7 +629,7 @@ Editor::build_region_boundary_cache ()
 
                        case End:
                                rpos = r->last_frame();
-                               break;  
+                               break;
 
                        case SyncPoint:
                                rpos = r->sync_position ();
@@ -640,16 +639,16 @@ Editor::build_region_boundary_cache ()
                        default:
                                break;
                        }
-                       
+
                        float speed = 1.0f;
                        RouteTimeAxisView *rtav;
-                       
+
                        if (ontrack != 0 && (rtav = dynamic_cast<RouteTimeAxisView*>(ontrack)) != 0 ) {
                                if (rtav->get_diskstream() != 0) {
                                        speed = rtav->get_diskstream()->speed();
                                }
                        }
-                       
+
                        rpos = track_frame_to_session_frame (rpos, speed);
 
                        if (rpos < lpos) {
@@ -660,8 +659,8 @@ Editor::build_region_boundary_cache ()
                           to sort later.
                        */
 
-                       vector<nframes64_t>::iterator ri; 
-                       
+                       vector<nframes64_t>::iterator ri;
+
                        for (ri = region_boundary_cache.begin(); ri != region_boundary_cache.end(); ++ri) {
                                if (*ri == rpos) {
                                        break;
@@ -697,7 +696,7 @@ Editor::find_next_region (nframes64_t frame, RegionPoint point, int32_t dir, Tra
 
                nframes64_t distance;
                boost::shared_ptr<Region> r;
-               
+
                track_speed = 1.0f;
                if ( (rtav = dynamic_cast<RouteTimeAxisView*>(*i)) != 0 ) {
                        if (rtav->get_diskstream()!=0)
@@ -773,7 +772,7 @@ Editor::find_next_region_boundary (nframes64_t pos, int32_t dir, const TrackView
                        distance = d;
                }
        }
-       
+
        return current_nearest;
 }
 
@@ -786,11 +785,11 @@ Editor::get_region_boundary (nframes64_t pos, int32_t dir, bool with_selection,
        if (with_selection && Config->get_region_boundaries_from_selected_tracks()) {
 
                if (!selection->tracks.empty()) {
-                       
+
                        target = find_next_region_boundary (pos, dir, selection->tracks);
-                       
+
                } else {
-                       
+
                        if (only_onscreen || Config->get_region_boundaries_from_onscreen_tracks()) {
                                get_onscreen_tracks (tvl);
                                target = find_next_region_boundary (pos, dir, tvl);
@@ -798,7 +797,7 @@ Editor::get_region_boundary (nframes64_t pos, int32_t dir, bool with_selection,
                                target = find_next_region_boundary (pos, dir, track_views);
                        }
                }
-               
+
        } else {
 
                if (only_onscreen || Config->get_region_boundaries_from_onscreen_tracks()) {
@@ -808,7 +807,7 @@ Editor::get_region_boundary (nframes64_t pos, int32_t dir, bool with_selection,
                        target = find_next_region_boundary (pos, dir, track_views);
                }
        }
-       
+
        return target;
 }
 
@@ -864,25 +863,25 @@ Editor::cursor_to_region_point (EditorCursor* cursor, RegionPoint point, int32_t
                pos+=dir;
 
        if (!selection->tracks.empty()) {
-               
+
                r = find_next_region (pos, point, dir, selection->tracks, &ontrack);
-               
+
        } else if (clicked_axisview) {
-               
+
                TrackViewList t;
                t.push_back (clicked_axisview);
-               
+
                r = find_next_region (pos, point, dir, t, &ontrack);
-               
+
        } else {
-               
+
                r = find_next_region (pos, point, dir, track_views, &ontrack);
        }
 
        if (r == 0) {
                return;
        }
-       
+
        switch (point){
        case Start:
                pos = r->first_frame ();
@@ -895,9 +894,9 @@ Editor::cursor_to_region_point (EditorCursor* cursor, RegionPoint point, int32_t
        case SyncPoint:
                pos = r->sync_position ();
                // r->adjust_to_sync (r->first_frame());
-               break;  
+               break;
        }
-       
+
        float speed = 1.0f;
        RouteTimeAxisView *rtav;
 
@@ -908,7 +907,7 @@ Editor::cursor_to_region_point (EditorCursor* cursor, RegionPoint point, int32_t
        }
 
        pos = track_frame_to_session_frame(pos, speed);
-       
+
        if (cursor == playhead_cursor) {
                session->request_locate (pos);
        } else {
@@ -932,7 +931,7 @@ void
 Editor::cursor_to_selection_start (EditorCursor *cursor)
 {
        nframes64_t pos = 0;
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
@@ -964,7 +963,7 @@ void
 Editor::cursor_to_selection_end (EditorCursor *cursor)
 {
        nframes64_t pos = 0;
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
@@ -1010,7 +1009,7 @@ Editor::selected_marker_to_region_boundary (bool with_selection, int32_t dir)
                if (!mouse_frame (mouse, ignored)) {
                        return;
                }
-               
+
                add_location_mark (mouse);
        }
 
@@ -1069,18 +1068,18 @@ Editor::selected_marker_to_region_point (RegionPoint point, int32_t dir)
                pos+=dir;
 
        if (!selection->tracks.empty()) {
-               
+
                r = find_next_region (pos, point, dir, selection->tracks, &ontrack);
-               
+
        } else {
-               
+
                r = find_next_region (pos, point, dir, track_views, &ontrack);
        }
 
        if (r == 0) {
                return;
        }
-       
+
        switch (point){
        case Start:
                pos = r->first_frame ();
@@ -1092,9 +1091,9 @@ Editor::selected_marker_to_region_point (RegionPoint point, int32_t dir)
 
        case SyncPoint:
                pos = r->adjust_to_sync (r->first_frame());
-               break;  
+               break;
        }
-       
+
        float speed = 1.0f;
        RouteTimeAxisView *rtav;
 
@@ -1136,7 +1135,7 @@ Editor::selected_marker_to_selection_start ()
                return;
        }
 
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
@@ -1175,7 +1174,7 @@ Editor::selected_marker_to_selection_end ()
                return;
        }
 
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
@@ -1214,13 +1213,13 @@ Editor::scroll_playhead (bool forward)
                        pos += delta ;
                } else {
                        pos = max_frames;
-               } 
+               }
 
        } else {
 
                if (pos == 0) {
                        return;
-               } 
+               }
 
                if (pos > delta) {
                        pos -= delta;
@@ -1257,7 +1256,7 @@ Editor::playhead_backward ()
        } else {
                pos -= cnt;
        }
-       
+
        /* XXX this is completely insane. with the current buffering
           design, we'll force a complete track buffer flush and
           reload, just to move 1 sample !!!
@@ -1285,7 +1284,7 @@ Editor::playhead_forward ()
        }
 
        pos = playhead_cursor->current_frame;
-       
+
        /* XXX this is completely insane. with the current buffering
           design, we'll force a complete track buffer flush and
           reload, just to move 1 sample !!!
@@ -1306,17 +1305,17 @@ Editor::cursor_align (bool playhead_to_edit)
                if (selection->markers.empty()) {
                        return;
                }
-               
+
                session->request_locate (selection->markers.front()->position(), session->transport_rolling());
-       
+
        } else {
                /* move selected markers to playhead */
-               
+
                for (MarkerSelection::iterator i = selection->markers.begin(); i != selection->markers.end(); ++i) {
                        bool ignored;
-                       
+
                        Location* loc = find_location_from_marker (*i, ignored);
-                       
+
                        if (loc->is_mark()) {
                                loc->set_start (playhead_cursor->current_frame);
                        } else {
@@ -1354,7 +1353,7 @@ Editor::edit_cursor_backward ()
        } else {
                pos -= cnt;
        }
-       
+
        // EDIT CURSOR edit_cursor->set_position (pos);
 }
 
@@ -1408,7 +1407,7 @@ Editor::scroll_backward (float pages)
        bool was_floating;
        float prefix;
        nframes64_t cnt;
-       
+
        if (get_prefix (prefix, was_floating)) {
                cnt = (nframes64_t) floor (pages * one_page);
        } else {
@@ -1436,7 +1435,7 @@ Editor::scroll_forward (float pages)
        bool was_floating;
        float prefix;
        nframes64_t cnt;
-       
+
        if (get_prefix (prefix, was_floating)) {
                cnt = (nframes64_t) floor (pages * one_page);
        } else {
@@ -1519,7 +1518,7 @@ void
 Editor::tav_zoom_step (bool coarser)
 {
        ENSURE_GUI_THREAD (bind (mem_fun (*this, &Editor::temporal_zoom_step), coarser));
-       
+
        _routes->suspend_redisplay ();
 
        for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
@@ -1528,7 +1527,7 @@ Editor::tav_zoom_step (bool coarser)
        }
 
        _routes->resume_redisplay ();
-}      
+}
 
 void
 Editor::temporal_zoom_step (bool coarser)
@@ -1538,21 +1537,21 @@ Editor::temporal_zoom_step (bool coarser)
        double nfpu;
 
        nfpu = frames_per_unit;
-       
-       if (coarser) { 
+
+       if (coarser) {
                nfpu *= 1.61803399;
-       } else { 
+       } else {
                nfpu = max(1.0,(nfpu/1.61803399));
        }
 
        temporal_zoom (nfpu);
-}      
+}
 
 void
 Editor::temporal_zoom (gdouble fpu)
 {
        if (!session) return;
-       
+
        nframes64_t current_page = current_page_frames();
        nframes64_t current_leftmost = leftmost_frame;
        nframes64_t current_rightmost;
@@ -1572,7 +1571,7 @@ Editor::temporal_zoom (gdouble fpu)
        }
 
        nfpu = fpu;
-       
+
        new_page_size = (nframes64_t) floor (_canvas_width * nfpu);
        half_page_size = new_page_size / 2;
 
@@ -1580,7 +1579,7 @@ Editor::temporal_zoom (gdouble fpu)
        case ZoomFocusLeft:
                leftmost_after_zoom = current_leftmost;
                break;
-               
+
        case ZoomFocusRight:
                current_rightmost = leftmost_frame + current_page;
                if (current_rightmost < new_page_size) {
@@ -1589,26 +1588,26 @@ Editor::temporal_zoom (gdouble fpu)
                        leftmost_after_zoom = current_rightmost - new_page_size;
                }
                break;
-               
+
        case ZoomFocusCenter:
-               current_center = current_leftmost + (current_page/2); 
+               current_center = current_leftmost + (current_page/2);
                if (current_center < half_page_size) {
                        leftmost_after_zoom = 0;
                } else {
                        leftmost_after_zoom = current_center - half_page_size;
                }
                break;
-               
+
        case ZoomFocusPlayhead:
                /* try to keep the playhead in the same place */
 
                where = playhead_cursor->current_frame;
-               
+
                l = - ((new_page_size * ((where - current_leftmost)/(double)current_page)) - where);
 
                if (l < 0) {
                        leftmost_after_zoom = 0;
-               } else if (l > max_frames) { 
+               } else if (l > max_frames) {
                        leftmost_after_zoom = max_frames - new_page_size;
                } else {
                        leftmost_after_zoom = (nframes64_t) l;
@@ -1634,7 +1633,7 @@ Editor::temporal_zoom (gdouble fpu)
 
                        if (l < 0) {
                                leftmost_after_zoom = 0;
-                       } else if (l > max_frames) { 
+                       } else if (l > max_frames) {
                                leftmost_after_zoom = max_frames - new_page_size;
                        } else {
                                leftmost_after_zoom = (nframes64_t) l;
@@ -1653,7 +1652,7 @@ Editor::temporal_zoom (gdouble fpu)
 
                        if (l < 0) {
                                leftmost_after_zoom = 0;
-                       } else if (l > max_frames) { 
+                       } else if (l > max_frames) {
                                leftmost_after_zoom = max_frames - new_page_size;
                        } else {
                                leftmost_after_zoom = (nframes64_t) l;
@@ -1664,13 +1663,13 @@ Editor::temporal_zoom (gdouble fpu)
                        return;
                }
                break;
-               
+
        }
+
        // leftmost_after_zoom = min (leftmost_after_zoom, session->current_end_frame());
 
        reposition_and_zoom (leftmost_after_zoom, nfpu);
-}      
+}
 
 void
 Editor::temporal_zoom_region (bool both_axes)
@@ -1678,7 +1677,7 @@ Editor::temporal_zoom_region (bool both_axes)
 
        nframes64_t start = max_frames;
        nframes64_t end = 0;
-       RegionSelection rs; 
+       RegionSelection rs;
        set<TimeAxisView*> tracks;
 
        get_regions_for_action (rs);
@@ -1723,7 +1722,7 @@ Editor::temporal_zoom_region (bool both_axes)
                start -= extra_samples;
        } else {
                start = 0;
-       } 
+       }
 
        if (max_frames - extra_samples > end) {
                end += extra_samples;
@@ -1743,13 +1742,13 @@ Editor::temporal_zoom_region (bool both_axes)
 
        if (both_axes) {
                uint32_t per_track_height = (uint32_t) floor ((_canvas_height - canvas_timebars_vsize - 10.0) / tracks.size());
-               
+
                /* set visible track heights appropriately */
-               
+
                for (set<TimeAxisView*>::iterator t = tracks.begin(); t != tracks.end(); ++t) {
                        (*t)->set_height (per_track_height);
                }
-               
+
                /* hide irrelevant tracks */
 
                _routes->suspend_redisplay ();
@@ -1766,25 +1765,20 @@ Editor::temporal_zoom_region (bool both_axes)
                no_save_visual = false;
        }
 
-       zoomed_to_region = true;
        redo_visual_stack.push_back (current_visual_state());
 }
 
 void
-Editor::toggle_zoom_region (bool both_axes)
+Editor::zoom_to_region (bool both_axes)
 {
-       if (zoomed_to_region) {
-               swap_visual_state ();
-       } else {
-               temporal_zoom_region (both_axes);
-       }
+       temporal_zoom_region (both_axes);
 }
 
 void
 Editor::temporal_zoom_selection ()
 {
        if (!selection) return;
-       
+
        if (selection->time.empty()) {
                return;
        }
@@ -1817,7 +1811,7 @@ Editor::temporal_zoom_by_frame (nframes64_t start, nframes64_t end, const string
        nframes64_t range = end - start;
 
        double new_fpu = (double)range / (double)_canvas_width;
-       
+
        nframes64_t new_page = (nframes64_t) floor (_canvas_width * new_fpu);
        nframes64_t middle = (nframes64_t) floor( (double)start + ((double)range / 2.0f ));
        nframes64_t new_leftmost = (nframes64_t) floor( (double)middle - ((double)new_page/2.0f));
@@ -1829,7 +1823,7 @@ Editor::temporal_zoom_by_frame (nframes64_t start, nframes64_t end, const string
        reposition_and_zoom (new_leftmost, new_fpu);
 }
 
-void 
+void
 Editor::temporal_zoom_to_frame (bool coarser, nframes64_t frame)
 {
        if (!session) {
@@ -1837,13 +1831,13 @@ Editor::temporal_zoom_to_frame (bool coarser, nframes64_t frame)
        }
        double range_before = frame - leftmost_frame;
        double new_fpu;
-       
+
        new_fpu = frames_per_unit;
-       
-       if (coarser) { 
+
+       if (coarser) {
                new_fpu *= 1.61803399;
                range_before *= 1.61803399;
-       } else { 
+       } else {
                new_fpu = max(1.0,(new_fpu/1.61803399));
                range_before /= 1.61803399;
        }
@@ -1878,10 +1872,7 @@ Editor::choose_new_marker_name(string &name) {
 
        dialog.set_prompt (_("New Name:"));
 
-       WindowTitle title(Glib::get_application_name());
-       title += _("Name New Location Marker");
-
-       dialog.set_title(title.get_string());
+       dialog.set_title (_("New Location Marker"));
 
        dialog.set_name ("MarkNameWindow");
        dialog.set_size_request (250, -1);
@@ -1898,7 +1889,7 @@ Editor::choose_new_marker_name(string &name) {
        default:
                return false;
        }
-       
+
        dialog.get_result(name);
        return true;
 
@@ -1961,7 +1952,7 @@ Editor::add_location_from_playhead_cursor ()
 void
 Editor::add_locations_from_audio_region ()
 {
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
@@ -1971,15 +1962,15 @@ Editor::add_locations_from_audio_region ()
 
        session->begin_reversible_command (rs.size () > 1 ? _("add markers") : _("add marker"));
        XMLNode &before = session->locations()->get_state();
-       
+
        cerr << "Add locations\n";
 
        for (RegionSelection::iterator i = rs.begin (); i != rs.end (); ++i) {
-               
+
                boost::shared_ptr<Region> region = (*i)->region ();
-       
+
                Location *location = new Location (region->position(), region->last_frame(), region->name(), Location::IsRangeMarker);
-               
+
                session->locations()->add (location, true);
        }
 
@@ -1991,7 +1982,7 @@ Editor::add_locations_from_audio_region ()
 void
 Editor::add_location_from_audio_region ()
 {
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
@@ -2011,14 +2002,14 @@ Editor::add_location_from_audio_region ()
                boost::shared_ptr<Region> region = rv->region();
                markername = region->name();
        }
-               
+
        if (!choose_new_marker_name(markername)) {
                return;
        }
 
        cerr << "Add location\n";
 
-       // single range spanning all selected 
+       // single range spanning all selected
        Location *location = new Location (rs.start(), rs.end_frame(), markername, Location::IsRangeMarker);
        session->locations()->add (location, true);
 
@@ -2045,7 +2036,7 @@ Editor::amplitude_zoom_step (bool in)
 #ifdef FIX_FOR_CANVAS
        /* XXX DO SOMETHING */
 #endif
-}      
+}
 
 
 /* DELETION */
@@ -2088,7 +2079,7 @@ Editor::jump_forward_to_mark ()
        if (!session) {
                return;
        }
-       
+
        Location *location = session->locations()->first_location_after (playhead_cursor->current_frame);
 
        if (location) {
@@ -2106,7 +2097,7 @@ Editor::jump_backward_to_mark ()
        }
 
        Location *location = session->locations()->first_location_before (playhead_cursor->current_frame);
-       
+
        if (location) {
                session->request_locate (location->start(), session->transport_rolling());
        } else {
@@ -2158,15 +2149,15 @@ Editor::clear_ranges ()
        if (session) {
                session->begin_reversible_command (_("clear ranges"));
                 XMLNode &before = session->locations()->get_state();
-               
+
                Location * looploc = session->locations()->auto_loop_location();
                Location * punchloc = session->locations()->auto_punch_location();
-               
+
                session->locations()->clear_ranges ();
                // re-add these
                if (looploc) session->locations()->add (looploc);
                if (punchloc) session->locations()->add (punchloc);
-               
+
                 XMLNode &after = session->locations()->get_state();
                session->add_command(new MementoCommand<Locations>(*(session->locations()), &before, &after));
                session->commit_reversible_command ();
@@ -2201,7 +2192,7 @@ Editor::unhide_ranges ()
 {
        for (LocationMarkerMap::iterator i = location_markers.begin(); i != location_markers.end(); ++i) {
                Location *l = (*i).first;
-               if (l->is_hidden() && l->is_range_marker()) { 
+               if (l->is_hidden() && l->is_range_marker()) {
                        l->set_hidden(false, this);
                }
        }
@@ -2217,7 +2208,7 @@ Editor::insert_region_list_drag (boost::shared_ptr<Region> region, int x, int y)
        nframes64_t where;
        RouteTimeAxisView *rtv = 0;
        boost::shared_ptr<Playlist> playlist;
-       
+
        track_canvas->window_to_world (x, y, wx, wy);
        //wx += horizontal_adjustment.get_value();
        //wy += vertical_adjustment.get_value();
@@ -2226,7 +2217,7 @@ Editor::insert_region_list_drag (boost::shared_ptr<Region> region, int x, int y)
        event.type = GDK_BUTTON_RELEASE;
        event.button.x = wx;
        event.button.y = wy;
-       
+
        where = event_frame (&event, &cx, &cy);
 
        if (where < leftmost_frame || where > leftmost_frame + current_page_frames()) {
@@ -2238,7 +2229,7 @@ Editor::insert_region_list_drag (boost::shared_ptr<Region> region, int x, int y)
        if (tv.first == 0) {
                return;
        }
-       
+
        if ((rtv = dynamic_cast<RouteTimeAxisView*> (tv.first)) == 0) {
                return;
        }
@@ -2246,9 +2237,9 @@ Editor::insert_region_list_drag (boost::shared_ptr<Region> region, int x, int y)
        if ((playlist = rtv->playlist()) == 0) {
                return;
        }
-       
+
        snap_to (where);
-       
+
        begin_reversible_command (_("insert dragged region"));
         XMLNode &before = playlist->get_state();
        playlist->add_region (RegionFactory::create (region), where, 1.0);
@@ -2284,13 +2275,13 @@ Editor::insert_route_list_drag (boost::shared_ptr<Route> route, int x, int y) {
                return;
        }
 
-       /* use this drag source to add underlay to a track. But we really don't care 
+       /* use this drag source to add underlay to a track. But we really don't care
           about the Route, only the view of the route, so find it first */
        for(TrackViewList::iterator it = track_views.begin(); it != track_views.end(); ++it) {
                if((source_rtv = dynamic_cast<RouteTimeAxisView*>(*it)) == 0) {
                        continue;
                }
-               
+
                if(source_rtv->route() == route && source_rtv != dest_rtv) {
                        dest_rtv->add_underlay(source_rtv->view());
                        break;
@@ -2326,7 +2317,7 @@ Editor::insert_region_list_selection (float times)
        if (region == 0) {
                return;
        }
-               
+
        begin_reversible_command (_("insert region"));
        XMLNode &before = playlist->get_state();
        playlist->add_region ((RegionFactory::create (region)), get_preferred_edit_position(), times);
@@ -2358,52 +2349,22 @@ Editor::transition_to_rolling (bool fwd)
                return;
        }
 
-       switch (Config->get_slave_source()) {
-       case None:
-       case JACK:
-               break;
-       default:
-               /* transport controlled by the master */
-               return;
+       if (session->config.get_external_sync()) {
+               switch (session->config.get_sync_source()) {
+               case JACK:
+                       break;
+               default:
+                       /* transport controlled by the master */
+                       return;
+               }
        }
 
        if (session->is_auditioning()) {
                session->cancel_audition ();
                return;
        }
-       
-       session->request_transport_speed (fwd ? 1.0f : -1.0f);
-}
 
-void
-Editor::toggle_playback (bool with_abort)
-{
-       if (!session) {
-               return;
-       }
-
-       switch (Config->get_slave_source()) {
-       case None:
-       case JACK:
-               break;
-       default:
-               /* transport controlled by the master */
-               return;
-       }
-
-       if (session->is_auditioning()) {
-               session->cancel_audition ();
-               return;
-       }
-       
-       if (session->transport_rolling()) {
-               session->request_stop (with_abort);
-               if (session->get_play_loop()) {
-                       session->request_play_loop (false);
-               }
-       } else {
-               session->request_transport_speed (1.0f);
-       }
+       session->request_transport_speed (fwd ? 1.0f : -1.0f);
 }
 
 void
@@ -2449,13 +2410,13 @@ Editor::play_selection ()
                return;
        }
 
-       session->request_play_range (true);
+       session->request_play_range (&selection->time, true);
 }
 
 void
 Editor::loop_selected_region ()
 {
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
@@ -2466,7 +2427,7 @@ Editor::loop_selected_region ()
                if ((tll = transport_loop_location()) != 0)  {
 
                        tll->set (rv->region()->position(), rv->region()->last_frame());
-                       
+
                        // enable looping, reposition and start rolling
 
                        session->request_play_loop (true);
@@ -2535,10 +2496,17 @@ Editor::edit_region ()
        selection->foreach_regionview (&RegionView::show_region_editor);
 }
 
+/** Show the midi list editor for the selected MIDI regions */
+void
+Editor::show_midi_list_editor ()
+{
+       selection->foreach_midi_regionview (&MidiRegionView::show_list_editor);
+}
+
 void
 Editor::rename_region()
 {
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
@@ -2546,10 +2514,7 @@ Editor::rename_region()
                return;
        }
 
-       WindowTitle title (Glib::get_application_name());
-       title += _("Rename Region");
-
-       ArdourDialog d (*this, title.get_string(), true, false);
+       ArdourDialog d (*this, _("Rename Region"), true, false);
        Entry entry;
        Label label (_("New name:"));
        HBox hbox;
@@ -2571,9 +2536,9 @@ Editor::rename_region()
        entry.select_region (0, -1);
 
        entry.signal_activate().connect (bind (mem_fun (d, &Dialog::response), RESPONSE_OK));
-       
+
        d.show_all ();
-       
+
        entry.grab_focus();
 
        int ret = d.run();
@@ -2595,7 +2560,7 @@ Editor::audition_playlist_region_via_route (boost::shared_ptr<Region> region, Ro
 {
        if (session->is_auditioning()) {
                session->cancel_audition ();
-       } 
+       }
 
        // note: some potential for creativity here, because region doesn't
        // have to belong to the playlist that Route is handling
@@ -2603,9 +2568,9 @@ Editor::audition_playlist_region_via_route (boost::shared_ptr<Region> region, Ro
        // bool was_soloed = route.soloed();
 
        route.set_solo (true, this);
-       
+
        session->request_bounded_roll (region->position(), region->position() + region->length());
-       
+
        /* XXX how to unset the solo state ? */
 }
 
@@ -2625,10 +2590,10 @@ Editor::play_selected_region ()
 {
        nframes64_t start = max_frames;
        nframes64_t end = 0;
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
-        
+
        if (rs.empty()) {
                return;
        }
@@ -2642,7 +2607,6 @@ Editor::play_selected_region ()
                }
        }
 
-       session->request_stop ();
        session->request_bounded_roll (start, end);
 }
 
@@ -2658,7 +2622,7 @@ Editor::build_interthread_progress_window ()
        interthread_progress_window = new ArdourDialog (X_("interthread progress"), true);
 
        interthread_progress_bar.set_orientation (Gtk::PROGRESS_LEFT_TO_RIGHT);
-       
+
        interthread_progress_window->set_border_width (12);
        interthread_progress_window->get_vbox()->set_spacing (6);
 
@@ -2702,7 +2666,7 @@ Editor::region_from_selection ()
        TrackSelection tracks = get_tracks_for_range_action ();
 
        nframes64_t selection_cnt = end - start + 1;
-       
+
        for (TrackSelection::iterator i = tracks.begin(); i != tracks.end(); ++i) {
                boost::shared_ptr<Region> current;
                boost::shared_ptr<Playlist> pl;
@@ -2722,7 +2686,7 @@ Editor::region_from_selection ()
                boost::shared_ptr<Region> region (RegionFactory::create (current,
                                internal_start, selection_cnt, new_name));
        }
-}      
+}
 
 void
 Editor::create_region_from_selection (vector<boost::shared_ptr<Region> >& new_regions)
@@ -2733,7 +2697,7 @@ Editor::create_region_from_selection (vector<boost::shared_ptr<Region> >& new_re
 
        nframes64_t start = selection->time[clicked_selection].start;
        nframes64_t end = selection->time[clicked_selection].end;
-       
+
        sort_track_selection ();
 
        for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
@@ -2761,7 +2725,7 @@ Editor::create_region_from_selection (vector<boost::shared_ptr<Region> >& new_re
 void
 Editor::split_multichannel_region ()
 {
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
@@ -2804,9 +2768,9 @@ TrackSelection
 Editor::get_tracks_for_range_action () const
 {
        TrackSelection t;
-       
+
        if (selection->tracks.empty()) {
-               
+
                /* use tracks with selected regions */
 
                RegionSelection rs = selection->regions;
@@ -2855,7 +2819,7 @@ Editor::separate_regions_between (const TimeSelection& ts)
                                if (rtv->track()->diskstream()->destructive()) {
                                        continue;
                                }
-                                       
+
                                if ((playlist = rtv->playlist()) != 0) {
 
                                        XMLNode *before;
@@ -2881,21 +2845,21 @@ Editor::separate_regions_between (const TimeSelection& ts)
                                                c.disconnect ();
 
                                                if (!latest_regionviews.empty()) {
-                                                       
+
                                                        got_some = true;
 
                                                        rtv->view()->foreach_regionview (bind (
                                                                                sigc::ptr_fun (add_if_covered),
                                                                                &(*t), &new_selection));
-                                                       
+
                                                        if (!in_command) {
                                                                begin_reversible_command (_("separate"));
                                                                in_command = true;
                                                        }
-                                                       
+
                                                        session->add_command(new MementoCommand<Playlist>(
                                                                        *playlist, before, &playlist->get_state()));
-                                               } 
+                                               }
                                        }
 
                                        if (!got_some) {
@@ -2934,9 +2898,9 @@ Editor::separate_region_from_selection ()
 
                nframes64_t start;
                nframes64_t end;
-               
+
                if (get_edit_op_range (start, end)) {
-                       
+
                        AudioRange ar (start, end, 1);
                        TimeSelection ts;
                        ts.push_back (ar);
@@ -2995,8 +2959,8 @@ Editor::crop_region_to_selection ()
                        crop_region_to (start, end);
                }
        }
-               
-}              
+
+}
 
 void
 Editor::crop_region_to (nframes64_t start, nframes64_t end)
@@ -3011,17 +2975,17 @@ Editor::crop_region_to (nframes64_t start, nframes64_t end)
                sort_track_selection ();
                ts = &selection->tracks;
        }
-       
+
        for (TrackSelection::iterator i = ts->begin(); i != ts->end(); ++i) {
-               
+
                RouteTimeAxisView* rtv;
-               
+
                if ((rtv = dynamic_cast<RouteTimeAxisView*> ((*i))) != 0) {
 
                        boost::shared_ptr<Track> t = rtv->track();
 
                        if (t != 0 && ! t->diskstream()->destructive()) {
-                               
+
                                if ((playlist = rtv->playlist()) != 0) {
                                        playlists.push_back (playlist);
                                }
@@ -3032,27 +2996,27 @@ Editor::crop_region_to (nframes64_t start, nframes64_t end)
        if (playlists.empty()) {
                return;
        }
-               
+
        nframes64_t the_start;
        nframes64_t the_end;
        nframes64_t cnt;
-       
+
        begin_reversible_command (_("trim to selection"));
-       
+
        for (vector<boost::shared_ptr<Playlist> >::iterator i = playlists.begin(); i != playlists.end(); ++i) {
-               
+
                boost::shared_ptr<Region> region;
-       
+
                the_start = start;
-       
+
                if ((region = (*i)->top_region_at(the_start)) == 0) {
                        continue;
                }
-               
+
                /* now adjust lengths to that we do the right thing
                   if the selection extends beyond the region
                */
-               
+
                the_start = max (the_start, (nframes64_t) region->position());
                if (max_frames - the_start < region->length()) {
                        the_end = the_start + region->length() - 1;
@@ -3061,21 +3025,21 @@ Editor::crop_region_to (nframes64_t start, nframes64_t end)
                }
                the_end = min (end, the_end);
                cnt = the_end - the_start + 1;
-               
+
                XMLNode &before = (*i)->get_state();
                region->trim_to (the_start, cnt, this);
                XMLNode &after = (*i)->get_state();
                session->add_command (new MementoCommand<Playlist>(*(*i), &before, &after));
        }
-       
+
        commit_reversible_command ();
-}              
+}
 
 void
 Editor::region_fill_track ()
 {
        nframes64_t end;
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
@@ -3090,10 +3054,6 @@ Editor::region_fill_track ()
        for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
 
                boost::shared_ptr<Region> region ((*i)->region());
-               
-               // FIXME
-               boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>(region);
-               assert(ar);
 
                boost::shared_ptr<Playlist> pl = region->playlist();
 
@@ -3108,7 +3068,7 @@ Editor::region_fill_track ()
                }
 
                XMLNode &before = pl->get_state();
-               pl->add_region (RegionFactory::create (ar), ar->last_frame(), times);
+               pl->add_region (RegionFactory::create (region), region->last_frame(), times);
                session->add_command (new MementoCommand<Playlist>(*pl, &before, &pl->get_state()));
        }
 
@@ -3118,7 +3078,7 @@ Editor::region_fill_track ()
 void
 Editor::region_fill_selection ()
 {
-       if (clicked_routeview == 0 || !clicked_routeview->is_audio_track()) {
+       if (clicked_routeview == 0 || !clicked_routeview->is_audio_track()) {
                return;
        }
 
@@ -3134,7 +3094,7 @@ Editor::region_fill_selection ()
        nframes64_t start = selection->time[clicked_selection].start;
        nframes64_t end = selection->time[clicked_selection].end;
 
-       boost::shared_ptr<Playlist> playlist; 
+       boost::shared_ptr<Playlist> playlist;
 
        if (selection->tracks.empty()) {
                return;
@@ -3142,21 +3102,21 @@ Editor::region_fill_selection ()
 
        nframes64_t selection_length = end - start;
        float times = (float)selection_length / region->length();
-       
+
        begin_reversible_command (_("fill selection"));
-       
+
        for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
 
                if ((playlist = (*i)->playlist()) == 0) {
                        continue;
-               }               
-               
+               }
+
                 XMLNode &before = playlist->get_state();
                playlist->add_region (RegionFactory::create (region), start, times);
                session->add_command (new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
        }
-       
-       commit_reversible_command ();                   
+
+       commit_reversible_command ();
 }
 
 void
@@ -3174,7 +3134,7 @@ Editor::set_sync_point (nframes64_t where, const RegionSelection& rs)
        bool in_command = false;
 
        for (RegionSelection::const_iterator r = rs.begin(); r != rs.end(); ++r) {
-               
+
                if (!(*r)->region()->covers (where)) {
                        continue;
                }
@@ -3187,7 +3147,7 @@ Editor::set_sync_point (nframes64_t where, const RegionSelection& rs)
                }
 
                XMLNode &before = region->playlist()->get_state();
-               region->set_sync_position (get_preferred_edit_position());
+               region->set_sync_position (where);
                XMLNode &after = region->playlist()->get_state();
                session->add_command(new MementoCommand<Playlist>(*(region->playlist()), &before, &after));
        }
@@ -3201,7 +3161,7 @@ Editor::set_sync_point (nframes64_t where, const RegionSelection& rs)
 void
 Editor::remove_region_sync ()
 {
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
@@ -3223,7 +3183,7 @@ Editor::remove_region_sync ()
 void
 Editor::naturalize ()
 {
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
@@ -3244,7 +3204,7 @@ Editor::naturalize ()
 void
 Editor::align (RegionPoint what)
 {
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
        nframes64_t where = get_preferred_edit_position();
@@ -3263,13 +3223,13 @@ void
 Editor::align_relative (RegionPoint what)
 {
        nframes64_t where = get_preferred_edit_position();
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
        if (!rs.empty()) {
                align_selection_relative (what, where, rs);
-       } 
+       }
 }
 
 struct RegionSortByTime {
@@ -3304,7 +3264,7 @@ Editor::align_selection_relative (RegionPoint point, nframes64_t position, const
                        dir = -1;
                }
                break;
-               
+
        case End:
                if (position > r->last_frame()) {
                        distance = position - r->last_frame();
@@ -3324,7 +3284,7 @@ Editor::align_selection_relative (RegionPoint point, nframes64_t position, const
                        distance = r->position() - pos;
                        dir = -1;
                }
-               break;  
+               break;
        }
 
        if (pos == r->position()) {
@@ -3341,15 +3301,15 @@ Editor::align_selection_relative (RegionPoint point, nframes64_t position, const
        session->add_command(new MementoCommand<Playlist>(*(r->playlist()), &before, &after));
 
        /* move rest by the same amount */
-       
+
        sorted.pop_front();
-       
+
        for (list<RegionView*>::iterator i = sorted.begin(); i != sorted.end(); ++i) {
 
                boost::shared_ptr<Region> region ((*i)->region());
 
                 XMLNode &before = region->playlist()->get_state();
-               
+
                if (dir > 0) {
                        region->set_position (region->position() + distance, this);
                } else {
@@ -3411,7 +3371,7 @@ Editor::align_region_internal (boost::shared_ptr<Region> region, RegionPoint poi
 
        XMLNode &after = region->playlist()->get_state();
        session->add_command(new MementoCommand<Playlist>(*(region->playlist()), &before, &after));
-}      
+}
 
 void
 Editor::trim_region_front ()
@@ -3444,9 +3404,9 @@ Editor::trim_region (bool front)
                        boost::shared_ptr<Playlist> pl = (*i)->region()->playlist();
                        XMLNode &before = pl->get_state();
                        if (front) {
-                               (*i)->region()->trim_front (where, this);       
+                               (*i)->region()->trim_front (where, this);
                        } else {
-                               (*i)->region()->trim_end (where, this); 
+                               (*i)->region()->trim_end (where, this);
                        }
                        XMLNode &after = pl->get_state();
                        session->add_command(new MementoCommand<Playlist>(*pl.get(), &before, &after));
@@ -3495,7 +3455,7 @@ Editor::trim_region_to_location (const Location& loc, const char* str)
                default:
                        continue;
                }
-                               
+
                RouteTimeAxisView* tav = dynamic_cast<RouteTimeAxisView*> (&rv->get_time_axis_view());
                if (!tav) {
                        return;
@@ -3508,7 +3468,7 @@ Editor::trim_region_to_location (const Location& loc, const char* str)
                if (tav->get_diskstream() != 0) {
                        speed = tav->get_diskstream()->speed();
                }
-               
+
                start = session_frame_to_track_frame (loc.start(), speed);
                end = session_frame_to_track_frame (loc.end(), speed);
 
@@ -3526,7 +3486,7 @@ void
 Editor::trim_region_to_edit_point ()
 {
        RegionSelection rs;
-       
+
        get_regions_for_action (rs);
 
        nframes64_t where = get_preferred_edit_position();
@@ -3558,7 +3518,7 @@ Editor::trim_region_to_edit_point ()
                session->add_command(new MementoCommand<Playlist>(
                                *(rv->region()->playlist()), &before, &after));
        }
-               
+
        commit_reversible_command ();
 }
 
@@ -3598,7 +3558,7 @@ Editor::trim_region_from_edit_point ()
                session->add_command(new MementoCommand<Playlist>(
                                *(rv->region()->playlist()), &before, &after));
        }
-               
+
        commit_reversible_command ();
 }
 
@@ -3645,10 +3605,10 @@ Editor::trim_to_region(bool forward)
                        speed = atav->get_diskstream()->speed();
                }
 
-               
+
                boost::shared_ptr<Region> region = arv->region();
                boost::shared_ptr<Playlist> playlist (region->playlist());
-               
+
                XMLNode &before = playlist->get_state();
 
                if(forward){
@@ -3670,7 +3630,7 @@ Editor::trim_to_region(bool forward)
                        continue;
                    }
 
-                   region->trim_front((nframes64_t) ((next_region->last_frame() + 1) * speed), this);              
+                   region->trim_front((nframes64_t) ((next_region->last_frame() + 1) * speed), this);
                    arv->region_changed (Change (LengthChanged|PositionChanged|StartChanged));
                }
 
@@ -3687,7 +3647,7 @@ Editor::unfreeze_route ()
        if (clicked_routeview == 0 || !clicked_routeview->is_track()) {
                return;
        }
-       
+
        clicked_routeview->track()->unfreeze ();
 }
 
@@ -3719,16 +3679,14 @@ Editor::freeze_route ()
        if (clicked_routeview == 0 || !clicked_routeview->is_audio_track()) {
                return;
        }
-       
+
        InterThreadInfo itt;
 
        if (interthread_progress_window == 0) {
                build_interthread_progress_window ();
        }
 
-       WindowTitle title(Glib::get_application_name());
-       title += _("Freeze");
-       interthread_progress_window->set_title (title.get_string());
+       interthread_progress_window->set_title (_("Freeze"));
        interthread_progress_window->set_position (Gtk::WIN_POS_MOUSE);
        interthread_progress_window->show_all ();
        interthread_progress_bar.set_fraction (0.0f);
@@ -3736,13 +3694,13 @@ Editor::freeze_route ()
        interthread_cancel_label.set_text (_("Cancel Freeze"));
        current_interthread_info = &itt;
 
-       interthread_progress_connection = 
+       interthread_progress_connection =
          Glib::signal_timeout().connect (bind (mem_fun(*this, &Editor::freeze_progress_timeout), (gpointer) 0), 100);
 
        itt.done = false;
        itt.cancel = false;
        itt.progress = 0.0f;
-       
+
        pthread_attr_t attr;
        pthread_attr_init(&attr);
        pthread_attr_setstacksize(&attr, 500000);
@@ -3785,22 +3743,22 @@ Editor::bounce_range_selection (bool replace, bool enable_processing)
                if ((rtv = dynamic_cast<RouteTimeAxisView*> (*i)) == 0) {
                        continue;
                }
-               
+
                boost::shared_ptr<Playlist> playlist;
-               
+
                if ((playlist = rtv->playlist()) == 0) {
                        return;
                }
 
                InterThreadInfo itt;
-               
+
                itt.done = false;
                itt.cancel = false;
                itt.progress = false;
 
                 XMLNode &before = playlist->get_state();
                boost::shared_ptr<Region> r = rtv->track()->bounce_range (start, start+cnt, itt, enable_processing);
-               
+
                if (replace) {
                        list<AudioRange> ranges;
                        ranges.push_back (AudioRange (start, start+cnt, 0));
@@ -3811,7 +3769,7 @@ Editor::bounce_range_selection (bool replace, bool enable_processing)
                 XMLNode &after = playlist->get_state();
                session->add_command (new MementoCommand<Playlist> (*playlist, &before, &after));
        }
-       
+
        commit_reversible_command ();
 }
 
@@ -3835,19 +3793,19 @@ bool
 Editor::can_cut_copy () const
 {
        switch (current_mouse_mode()) {
-               
+
        case MouseObject:
                if (!selection->regions.empty() || !selection->points.empty()) {
                        return true;
                }
                break;
-               
+
        case MouseRange:
                if (!selection->time.empty()) {
                        return true;
                }
                break;
-               
+
        default:
                break;
        }
@@ -3859,7 +3817,7 @@ Editor::can_cut_copy () const
 /** Cut, copy or clear selected regions, automation points or a time range.
  * @param op Operation (Cut, Copy or Clear)
  */
-void 
+void
 Editor::cut_copy (CutCopyOp op)
 {
        /* only cancel selection if cut/copy is successful.*/
@@ -3891,7 +3849,7 @@ Editor::cut_copy (CutCopyOp op)
                        _drag = 0;
                }
        }
-       
+
        cut_buffer->clear ();
 
        if (entered_marker) {
@@ -3922,26 +3880,26 @@ Editor::cut_copy (CutCopyOp op)
                default:
                        break;
                }
+
        } else {
-               
-               RegionSelection rs; 
-               
+
+               RegionSelection rs;
+
                /* we only want to cut regions if some are selected */
-               
+
                if (!selection->regions.empty()) {
                        get_regions_for_action (rs, false, false);
                }
 
                switch (current_mouse_mode()) {
-               case MouseObject: 
+               case MouseObject:
                        if (!rs.empty() || !selection->points.empty()) {
 
                                begin_reversible_command (opname + _(" objects"));
 
                                if (!rs.empty()) {
                                        cut_copy_regions (op, rs);
-                               
+
                                        if (op == Cut) {
                                                selection->clear_regions ();
                                        }
@@ -3955,15 +3913,15 @@ Editor::cut_copy (CutCopyOp op)
                                        }
                                }
 
-                               commit_reversible_command ();   
+                               commit_reversible_command ();
                                break; // terminate case statement here
-                       } 
+                       }
                        if (!selection->time.empty()) {
                                /* don't cause suprises */
                                break;
                        }
                        // fall thru if there was nothing selected
-               
+
                case MouseRange:
                        if (selection->time.empty()) {
                                nframes64_t start, end;
@@ -3972,22 +3930,22 @@ Editor::cut_copy (CutCopyOp op)
                                }
                                selection->set ((TimeAxisView*) 0, start, end);
                        }
-                       
+
                        begin_reversible_command (opname + _(" range"));
                        cut_copy_ranges (op);
                        commit_reversible_command ();
-               
+
                        if (op == Cut) {
                                selection->clear_time ();
                        }
 
                        break;
-               
+
                default:
                        break;
                }
        }
-               
+
        if (op == Cut || op == Clear) {
                break_drag ();
                delete _drag;
@@ -4007,7 +3965,7 @@ Editor::cut_copy_points (CutCopyOp op)
 
                if (atv) {
                        atv->cut_copy_clear_objects (selection->points, op);
-               } 
+               }
        }
 }
 
@@ -4033,8 +3991,8 @@ struct lt_playlist {
            return a.playlist < b.playlist;
     }
 };
-       
-struct PlaylistMapping { 
+
+struct PlaylistMapping {
     TimeAxisView* tv;
     boost::shared_ptr<Playlist> pl;
 
@@ -4050,7 +4008,7 @@ Editor::remove_clicked_region ()
        }
 
        boost::shared_ptr<Playlist> playlist = clicked_routeview->playlist();
-       
+
        begin_reversible_command (_("remove region"));
         XMLNode &before = playlist->get_state();
        playlist->remove_region (clicked_regionview->region());
@@ -4064,9 +4022,9 @@ Editor::remove_clicked_region ()
 void
 Editor::remove_selected_regions ()
 {
-       RegionSelection rs; 
+       RegionSelection rs;
        get_regions_for_action (rs);
-       
+
        if (!session) {
                return;
        }
@@ -4088,12 +4046,12 @@ Editor::remove_selected_regions ()
                // so, first iterate over the regions to be removed from rs and
                // add them to the regions_to_remove list, and then
                // iterate over the list to actually remove them.
-               
+
                regions_to_remove.push_back ((*i)->region());
        }
 
        vector<PlaylistState> playlists;
-       
+
        for (list<boost::shared_ptr<Region> >::iterator rl = regions_to_remove.begin(); rl != regions_to_remove.end(); ++rl) {
 
                boost::shared_ptr<Playlist> playlist = (*rl)->playlist();
@@ -4122,7 +4080,7 @@ Editor::remove_selected_regions ()
                        playlists.push_back(before);
                }
 
-               playlist->remove_region (*rl);          
+               playlist->remove_region (*rl);
        }
 
        vector<PlaylistState>::iterator pl;
@@ -4148,12 +4106,12 @@ Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs)
        vector<PlaylistMapping> pmap;
 
        nframes64_t first_position = max_frames;
-       
+
        set<PlaylistState, lt_playlist> freezelist;
        pair<set<PlaylistState, lt_playlist>::iterator,bool> insert_result;
-       
+
        /* get ordering correct before we cut/copy */
-       
+
        rs.sort_by_position_and_track ();
 
        for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) {
@@ -4172,7 +4130,7 @@ Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs)
                                                break;
                                        }
                                }
-               
+
                                if (fl == freezelist.end()) {
                                        PlaylistState before;
                                        before.playlist = pl;
@@ -4191,7 +4149,7 @@ Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs)
                                break;
                        }
                }
-               
+
                if (z == pmap.end()) {
                        pmap.push_back (PlaylistMapping (tv));
                }
@@ -4200,7 +4158,7 @@ Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs)
        for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ) {
 
                boost::shared_ptr<Playlist> pl = (*x)->region()->playlist();
-               
+
                if (!pl) {
                        /* impossible, but this handles it for the future */
                        continue;
@@ -4209,20 +4167,20 @@ Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs)
                TimeAxisView& tv = (*x)->get_trackview();
                boost::shared_ptr<Playlist> npl;
                RegionSelection::iterator tmp;
-               
+
                tmp = x;
                ++tmp;
 
                vector<PlaylistMapping>::iterator z;
-               
+
                for (z = pmap.begin(); z != pmap.end(); ++z) {
                        if ((*z).tv == &tv) {
                                break;
                        }
                }
-               
+
                assert (z != pmap.end());
-               
+
                if (!(*z).pl) {
                        npl = PlaylistFactory::create (pl->data_type(), *session, "cutlist", true);
                        npl->freeze();
@@ -4230,7 +4188,7 @@ Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs)
                } else {
                        npl = (*z).pl;
                }
-               
+
                boost::shared_ptr<Region> r = (*x)->region();
                boost::shared_ptr<Region> _xx;
 
@@ -4242,12 +4200,12 @@ Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs)
                        npl->add_region (_xx, r->position() - first_position);
                        pl->remove_region (r);
                        break;
-                       
+
                case Copy:
                        /* copy region before adding, so we're not putting same object into two different playlists */
                        npl->add_region (RegionFactory::create (r), r->position() - first_position);
                        break;
-                       
+
                case Clear:
                        pl->remove_region (r);
                        break;
@@ -4255,16 +4213,16 @@ Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs)
 
                x = tmp;
        }
-       
+
        list<boost::shared_ptr<Playlist> > foo;
-       
+
        /* the pmap is in the same order as the tracks in which selected regions occured */
-       
+
        for (vector<PlaylistMapping>::iterator i = pmap.begin(); i != pmap.end(); ++i) {
                (*i).pl->thaw();
                foo.push_back ((*i).pl);
        }
-       
+
 
        if (!foo.empty()) {
                cut_buffer->set (foo);
@@ -4325,7 +4283,7 @@ Editor::paste_internal (nframes64_t position, float times)
        if (internal_editing()) {
                if (cut_buffer->midi_notes.empty()) {
                        return;
-               } 
+               }
        } else {
                if (cut_buffer->empty()) {
                        return;
@@ -4356,14 +4314,14 @@ Editor::paste_internal (nframes64_t position, float times)
                /* undo/redo is handled by individual tracks/regions */
 
                if (internal_editing()) {
-                       
+
                        RegionSelection rs;
                        RegionSelection::iterator r;
                        MidiNoteSelection::iterator cb;
 
                        get_regions_at (rs, position, ts);
 
-                       for (cb = cut_buffer->midi_notes.begin(), r = rs.begin(); 
+                       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) {
@@ -4377,74 +4335,18 @@ Editor::paste_internal (nframes64_t position, float times)
                        if ((*i)->paste (position, times, *cut_buffer, nth)) {
                                commit = true;
                        }
-               } 
+               }
        }
-       
+
        if (commit) {
                commit_reversible_command ();
        }
 }
 
-void
-Editor::paste_named_selection (float times)
-{
-       TrackSelection::iterator t;
-
-       Glib::RefPtr<TreeSelection> selected = named_selection_display.get_selection();
-
-       if (selected->count_selected_rows() != 1 || selection->tracks.empty()) {
-               return;
-       }
-
-       TreeModel::iterator i = selected->get_selected();
-       NamedSelection* ns = (*i)[named_selection_columns.selection];
-
-       list<boost::shared_ptr<Playlist> >::iterator chunk;
-       list<boost::shared_ptr<Playlist> >::iterator tmp;
-
-       chunk = ns->playlists.begin();
-               
-       begin_reversible_command (_("paste chunk"));
-       
-       sort_track_selection ();
-
-       for (t = selection->tracks.begin(); t != selection->tracks.end(); ++t) {
-               
-               RouteTimeAxisView* rtv;
-               boost::shared_ptr<Playlist> pl;
-               boost::shared_ptr<AudioPlaylist> apl;
-
-               if ((rtv = dynamic_cast<RouteTimeAxisView*> (*t)) == 0) {
-                       continue;
-               }
-
-               if ((pl = rtv->playlist()) == 0) {
-                       continue;
-               }
-               
-               if ((apl = boost::dynamic_pointer_cast<AudioPlaylist> (pl)) == 0) {
-                       continue;
-               }
-
-               tmp = chunk;
-               ++tmp;
-
-               XMLNode &before = apl->get_state();
-               apl->paste (*chunk, get_preferred_edit_position(), times);
-               session->add_command(new MementoCommand<AudioPlaylist>(*apl, &before, &apl->get_state()));
-
-               if (tmp != ns->playlists.end()) {
-                       chunk = tmp;
-               }
-       }
-
-       commit_reversible_command();
-}
-
 void
 Editor::duplicate_some_regions (RegionSelection& regions, float times)
 {
-       boost::shared_ptr<Playlist> playlist; 
+       boost::shared_ptr<Playlist> playlist;
        RegionSelection sel = regions; // clear (below) may  clear the argument list if its the current region selection
        RegionSelection foo;
 
@@ -4460,14 +4362,14 @@ Editor::duplicate_some_regions (RegionSelection& regions, float times)
                RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (&tv);
                latest_regionviews.clear ();
                sigc::connection c = rtv->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
-               
+
                playlist = (*i)->region()->playlist();
                 XMLNode &before = playlist->get_state();
                playlist->duplicate (r, r->last_frame(), times);
                session->add_command(new MementoCommand<Playlist>(*playlist, &before, &playlist->get_state()));
 
                c.disconnect ();
-               
+
                foo.insert (foo.end(), latest_regionviews.begin(), latest_regionviews.end());
        }
 
@@ -4485,16 +4387,16 @@ Editor::duplicate_selection (float times)
                return;
        }
 
-       boost::shared_ptr<Playlist> playlist; 
+       boost::shared_ptr<Playlist> playlist;
        vector<boost::shared_ptr<Region> > new_regions;
        vector<boost::shared_ptr<Region> >::iterator ri;
-               
+
        create_region_from_selection (new_regions);
 
        if (new_regions.empty()) {
                return;
        }
-       
+
        begin_reversible_command (_("duplicate selection"));
 
        ri = new_regions.begin();
@@ -4523,12 +4425,12 @@ Editor::reset_point_selection ()
        /* reset all selected points to the relevant default value */
 
        for (PointSelection::iterator i = selection->points.begin(); i != selection->points.end(); ++i) {
-               
+
                AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*>(&(*i).track);
-               
+
                if (atv) {
                        atv->reset_objects (selection->points);
-               } 
+               }
        }
 }
 
@@ -4560,7 +4462,7 @@ Editor::clear_playlist (boost::shared_ptr<Playlist> playlist)
 void
 Editor::nudge_track (bool use_edit, bool forwards)
 {
-       boost::shared_ptr<Playlist> playlist; 
+       boost::shared_ptr<Playlist> playlist;
        nframes64_t distance;
        nframes64_t next_distance;
        nframes64_t start;
@@ -4574,26 +4476,26 @@ Editor::nudge_track (bool use_edit, bool forwards)
        if ((distance = get_nudge_distance (start, next_distance)) == 0) {
                return;
        }
-       
+
        if (selection->tracks.empty()) {
                return;
        }
-       
+
        begin_reversible_command (_("nudge track"));
-       
+
        for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
 
                if ((playlist = (*i)->playlist()) == 0) {
                        continue;
-               }               
-               
+               }
+
                 XMLNode &before = playlist->get_state();
                playlist->nudge_after (start, distance, forwards);
                 XMLNode &after = playlist->get_state();
                session->add_command (new MementoCommand<Playlist>(*playlist, &before, &after));
        }
-       
-       commit_reversible_command ();                   
+
+       commit_reversible_command ();
 }
 
 void
@@ -4601,7 +4503,7 @@ Editor::remove_last_capture ()
 {
        vector<string> choices;
        string prompt;
-       
+
        if (!session) {
                return;
        }
@@ -4612,9 +4514,9 @@ Editor::remove_last_capture ()
 
                choices.push_back (_("No, do nothing."));
                choices.push_back (_("Yes, destroy it."));
-               
+
                Gtkmm2ext::Choice prompter (prompt, choices);
-               
+
                if (prompter.run () == 1) {
                        session->remove_last_capture ();
                }
@@ -4631,13 +4533,13 @@ Editor::normalize_region ()
                return;
        }
 
-       RegionSelection rs; 
+       RegionSelection rs;
        get_regions_for_action (rs);
 
        if (rs.empty()) {
                return;
        }
-       
+
        Dialog dialog (rs.size() > 1 ? _("Normalize regions") : _("Normalize region"));
        HBox hbox;
        hbox.pack_start (*manage (new Label (_("Normalize to:"))));
@@ -4679,13 +4581,13 @@ Editor::normalize_region ()
 
 
 void
-Editor::denormalize_region ()
+Editor::reset_region_scale_amplitude ()
 {
        if (!session) {
                return;
        }
 
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
@@ -4693,7 +4595,7 @@ Editor::denormalize_region ()
                return;
        }
 
-       begin_reversible_command ("denormalize");
+       begin_reversible_command ("reset gain");
 
        for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) {
                AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r);
@@ -4714,7 +4616,7 @@ Editor::adjust_region_scale_amplitude (bool up)
                return;
        }
 
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
@@ -4729,9 +4631,9 @@ Editor::adjust_region_scale_amplitude (bool up)
                if (!arv)
                        continue;
                XMLNode &before = arv->region()->get_state();
-               
+
                double fraction = gain_to_slider_position (arv->audio_region()->scale_amplitude ());
-               
+
                if (up) {
                        fraction += 0.05;
                        fraction = min (fraction, 1.0);
@@ -4749,7 +4651,7 @@ Editor::adjust_region_scale_amplitude (bool up)
                if (up && fraction >= 2.0) {
                        continue;
                }
-               
+
                arv->audio_region()->set_scale_amplitude (fraction);
                session->add_command (new MementoCommand<Region>(*(arv->region().get()), &before, &arv->region()->get_state()));
        }
@@ -4784,14 +4686,14 @@ Editor::strip_region_silence ()
        }
 
        std::list<boost::shared_ptr<AudioRegion> > ar;
-       
+
        for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
                AudioRegionView* const arv = dynamic_cast<AudioRegionView*> (*i);
                if (arv) {
                        ar.push_back (arv->audio_region ());
                }
        }
-       
+
        StripSilenceDialog d (ar);
        int const r = d.run ();
 
@@ -4801,6 +4703,52 @@ Editor::strip_region_silence ()
        }
 }
 
+Command*
+Editor::apply_midi_note_edit_op_to_region (MidiOperator& op, MidiRegionView& mrv)
+{
+       Evoral::Sequence<Evoral::MusicalTime>::Notes selected;
+       mrv.selection_as_notelist (selected);
+
+       vector<Evoral::Sequence<Evoral::MusicalTime>::Notes> v;
+       v.push_back (selected);
+
+       return op (mrv.midi_region()->model(), v);
+}
+
+void
+Editor::apply_midi_note_edit_op (MidiOperator& op)
+{
+       RegionSelection rs;
+       Command* cmd;
+
+       get_regions_for_action (rs);
+
+       if (rs.empty()) {
+               return;
+       }
+
+       begin_reversible_command (op.name ());
+
+       for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ) {
+               RegionSelection::iterator tmp = r;
+               ++tmp;
+
+               MidiRegionView* const mrv = dynamic_cast<MidiRegionView*> (*r);
+
+               if (mrv) {
+                       cmd = apply_midi_note_edit_op_to_region (op, *mrv);
+                       if (cmd) {
+                               (*cmd)();
+                               session->add_command (cmd);
+                       }
+               }
+
+               r = tmp;
+       }
+
+       commit_reversible_command ();
+       rs.clear ();
+}
 
 void
 Editor::quantize_region ()
@@ -4809,15 +4757,26 @@ Editor::quantize_region ()
                return;
        }
 
-       // FIXME: varying meter?
-       Quantize quant (*session, snap_length_beats(0));
-       apply_filter (quant, _("quantize regions"));
+       QuantizeDialog* qd = new QuantizeDialog (*this);
+
+       qd->present ();
+       const int r = qd->run ();
+       qd->hide ();
+
+       if (r == Gtk::RESPONSE_OK) {
+               Quantize quant (*session, Plain,
+                               qd->snap_start(), qd->snap_end(),
+                               qd->start_grid_size(), qd->end_grid_size(),
+                               qd->strength(), qd->swing(), qd->threshold());
+
+               apply_midi_note_edit_op (quant);
+       }
 }
 
 void
 Editor::apply_filter (Filter& filter, string command)
 {
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
@@ -4834,13 +4793,6 @@ Editor::apply_filter (Filter& filter, string command)
                RegionSelection::iterator tmp = r;
                ++tmp;
 
-               MidiRegionView* const mrv = dynamic_cast<MidiRegionView*>(*r);
-               if (mrv) {
-                       if (mrv->midi_region()->apply(filter) == 0) {
-                               mrv->redisplay_model();
-                       }
-               }
-
                AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r);
                if (arv) {
                        boost::shared_ptr<Playlist> playlist = arv->region()->playlist();
@@ -4853,7 +4805,7 @@ Editor::apply_filter (Filter& filter, string command)
 
                                        /* no regions returned; remove the old one */
                                        playlist->remove_region (arv->region ());
-                                       
+
                                } else {
 
                                        std::vector<boost::shared_ptr<Region> >::iterator res = filter.results.begin ();
@@ -4867,7 +4819,7 @@ Editor::apply_filter (Filter& filter, string command)
                                                playlist->add_region (*res, (*res)->position());
                                                ++res;
                                        }
-                                       
+
                                }
 
                                XMLNode &after = playlist->get_state();
@@ -4925,7 +4877,7 @@ void
 Editor::brush (nframes64_t pos)
 {
        RegionSelection sel;
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
@@ -4997,7 +4949,7 @@ Editor::toggle_gain_envelope_active ()
        if (!session || rs.empty()) {
                return;
        }
-       
+
        session->begin_reversible_command (_("region gain envelope active"));
 
        for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
@@ -5021,7 +4973,7 @@ Editor::toggle_region_lock ()
        if (!session || rs.empty()) {
                return;
        }
-       
+
        session->begin_reversible_command (_("region lock"));
 
        for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
@@ -5042,7 +4994,7 @@ Editor::set_region_lock_style (Region::PositionLockStyle ps)
        if (!session || rs.empty()) {
                return;
        }
-       
+
        session->begin_reversible_command (_("region lock style"));
 
        for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
@@ -5064,7 +5016,7 @@ Editor::toggle_region_mute ()
        if (!session || rs.empty()) {
                return;
        }
-       
+
        session->begin_reversible_command (_("region mute"));
 
        for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
@@ -5085,7 +5037,7 @@ Editor::toggle_region_opaque ()
        if (!session || rs.empty()) {
                return;
        }
-       
+
        session->begin_reversible_command (_("region opacity"));
 
        for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
@@ -5123,7 +5075,7 @@ Editor::toggle_record_enable ()
 void
 Editor::set_fade_length (bool in)
 {
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs, true);
 
@@ -5138,7 +5090,7 @@ Editor::set_fade_length (bool in)
        nframes64_t pos = get_preferred_edit_position();
        nframes64_t len;
        char* cmd;
-       
+
        if (pos > rv->region()->last_frame() || pos < rv->region()->first_frame()) {
                /* edit point is outside the relevant region */
                return;
@@ -5185,7 +5137,7 @@ Editor::set_fade_length (bool in)
                        tmp->audio_region()->set_fade_out_length (len);
                        tmp->audio_region()->set_fade_out_active (true);
                }
-               
+
                XMLNode &after = alist->get_state();
                session->add_command(new MementoCommand<AutomationList>(*alist, &before, &after));
        }
@@ -5196,7 +5148,7 @@ Editor::set_fade_length (bool in)
 void
 Editor::toggle_fade_active (bool in)
 {
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
@@ -5212,7 +5164,7 @@ Editor::toggle_fade_active (bool in)
 
        for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) {
                AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*x);
-               
+
                if (!tmp) {
                        return;
                }
@@ -5220,7 +5172,7 @@ Editor::toggle_fade_active (bool in)
                boost::shared_ptr<AudioRegion> region (tmp->audio_region());
 
                /* make the behaviour consistent across all regions */
-               
+
                if (!have_switch) {
                        if (in) {
                                yn = region->fade_in_active();
@@ -5246,7 +5198,7 @@ Editor::toggle_fade_active (bool in)
 void
 Editor::set_fade_in_shape (AudioRegion::FadeShape shape)
 {
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
@@ -5267,19 +5219,19 @@ Editor::set_fade_in_shape (AudioRegion::FadeShape shape)
                XMLNode &before = alist->get_state();
 
                tmp->audio_region()->set_fade_in_shape (shape);
-               
+
                XMLNode &after = alist->get_state();
                session->add_command(new MementoCommand<AutomationList>(*alist.get(), &before, &after));
        }
 
        commit_reversible_command ();
-               
+
 }
 
 void
 Editor::set_fade_out_shape (AudioRegion::FadeShape shape)
 {
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
@@ -5300,7 +5252,7 @@ Editor::set_fade_out_shape (AudioRegion::FadeShape shape)
                XMLNode &before = alist->get_state();
 
                tmp->audio_region()->set_fade_out_shape (shape);
-               
+
                XMLNode &after = alist->get_state();
                session->add_command(new MementoCommand<AutomationList>(*alist.get(), &before, &after));
        }
@@ -5311,7 +5263,7 @@ Editor::set_fade_out_shape (AudioRegion::FadeShape shape)
 void
 Editor::set_fade_in_active (bool yn)
 {
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
@@ -5334,7 +5286,7 @@ Editor::set_fade_in_active (bool yn)
                XMLNode &before = ar->get_state();
 
                ar->set_fade_in_active (yn);
-               
+
                XMLNode &after = ar->get_state();
                session->add_command(new MementoCommand<AudioRegion>(*ar, &before, &after));
        }
@@ -5345,7 +5297,7 @@ Editor::set_fade_in_active (bool yn)
 void
 Editor::set_fade_out_active (bool yn)
 {
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
@@ -5367,7 +5319,7 @@ Editor::set_fade_out_active (bool yn)
                XMLNode &before = ar->get_state();
 
                ar->set_fade_out_active (yn);
-               
+
                XMLNode &after = ar->get_state();
                session->add_command(new MementoCommand<AudioRegion>(*ar, &before, &after));
        }
@@ -5384,7 +5336,7 @@ Editor::toggle_selected_region_fades (int dir)
        bool yn;
 
        get_regions_for_action (rs);
-       
+
        if (rs.empty()) {
                return;
        }
@@ -5444,7 +5396,7 @@ void
 Editor::update_xfade_visibility ()
 {
        _xfade_visibility = session->config.get_xfades_visible ();
-       
+
        for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
                AudioTimeAxisView* v = dynamic_cast<AudioTimeAxisView*>(*i);
                if (v) {
@@ -5466,11 +5418,11 @@ Editor::set_edit_point ()
        if (!mouse_frame (where, ignored)) {
                return;
        }
-       
+
        snap_to (where);
 
        if (selection->markers.empty()) {
-               
+
                mouse_add_new_marker (where);
 
        } else {
@@ -5496,9 +5448,9 @@ Editor::set_playhead_cursor ()
                if (!mouse_frame (where, ignored)) {
                        return;
                }
-                       
+
                snap_to (where);
-               
+
                if (session) {
                        session->request_locate (where, session->transport_rolling());
                }
@@ -5508,8 +5460,8 @@ Editor::set_playhead_cursor ()
 void
 Editor::split ()
 {
-       RegionSelection rs; 
-       
+       RegionSelection rs;
+
        get_regions_for_action (rs, true);
 
        nframes64_t where = get_preferred_edit_position();
@@ -5648,7 +5600,7 @@ Editor::set_loop_from_selection (bool play)
 
        nframes64_t start = selection->time[clicked_selection].start;
        nframes64_t end = selection->time[clicked_selection].end;
-       
+
        set_loop_range (start, end,  _("set loop range from selection"));
 
        if (play) {
@@ -5666,7 +5618,7 @@ Editor::set_loop_from_edit_range (bool play)
 
        nframes64_t start;
        nframes64_t end;
-       
+
        if (!get_edit_op_range (start, end)) {
                return;
        }
@@ -5685,7 +5637,7 @@ Editor::set_loop_from_region (bool play)
        nframes64_t start = max_frames;
        nframes64_t end = 0;
 
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
@@ -5719,7 +5671,7 @@ Editor::set_punch_from_selection ()
 
        nframes64_t start = selection->time[clicked_selection].start;
        nframes64_t end = selection->time[clicked_selection].end;
-       
+
        set_punch_range (start, end,  _("set punch range from selection"));
 }
 
@@ -5732,7 +5684,7 @@ Editor::set_punch_from_edit_range ()
 
        nframes64_t start;
        nframes64_t end;
-       
+
        if (!get_edit_op_range (start, end)) {
                return;
        }
@@ -5746,7 +5698,7 @@ Editor::set_punch_from_region ()
        nframes64_t start = max_frames;
        nframes64_t end = 0;
 
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
@@ -5769,17 +5721,17 @@ Editor::set_punch_from_region ()
 void
 Editor::pitch_shift_regions ()
 {
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
-       
+
        if (rs.empty()) {
                return;
        }
 
        pitch_shift (rs, 1.2);
 }
-       
+
 void
 Editor::use_region_as_bar ()
 {
@@ -5787,7 +5739,7 @@ Editor::use_region_as_bar ()
                return;
        }
 
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
@@ -5813,7 +5765,7 @@ void
 Editor::define_one_bar (nframes64_t start, nframes64_t end)
 {
        nframes64_t length = end - start;
-       
+
        const Meter& m (session->tempo_map().meter_at (start));
 
        /* length = 1 bar */
@@ -5823,14 +5775,14 @@ Editor::define_one_bar (nframes64_t start, nframes64_t end)
        */
 
        double frames_per_beat = length / m.beats_per_bar();
-       
+
        /* beats per minute = */
 
        double beats_per_minute = (session->frame_rate() * 60.0) / frames_per_beat;
 
        /* now decide whether to:
 
-           (a) set global tempo 
+           (a) set global tempo
            (b) add a new tempo marker
 
        */
@@ -5840,7 +5792,7 @@ Editor::define_one_bar (nframes64_t start, nframes64_t end)
        bool do_global = false;
 
        if ((session->tempo_map().n_tempos() == 1) && (session->tempo_map().n_meters() == 1)) {
-               
+
                /* only 1 tempo & 1 meter: ask if the user wants to set the tempo
                   at the start, or create a new marker
                */
@@ -5869,7 +5821,7 @@ Editor::define_one_bar (nframes64_t start, nframes64_t end)
 
                /* more than 1 tempo and/or meter section already, go ahead do the "usual":
                   if the marker is at the region starter, change it, otherwise add
-                  a new tempo marker 
+                  a new tempo marker
                */
        }
 
@@ -5899,7 +5851,7 @@ Editor::split_region_at_transients ()
                return;
        }
 
-       RegionSelection rs; 
+       RegionSelection rs;
 
        get_regions_for_action (rs);
 
@@ -5917,12 +5869,12 @@ Editor::split_region_at_transients ()
                ++tmp;
 
                boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> ((*i)->region());
-               
+
                if (ar && (ar->get_transients (positions) == 0)) {
                        split_region_at_points ((*i)->region(), positions, true);
                        positions.clear ();
                }
-               
+
                i = tmp;
        }
 
@@ -5936,11 +5888,11 @@ Editor::split_region_at_points (boost::shared_ptr<Region> r, AnalysisFeatureList
        bool use_rhythmic_rodent = false;
 
        boost::shared_ptr<Playlist> pl = r->playlist();
-       
+
        if (!pl) {
                return;
        }
-       
+
        if (positions.empty()) {
                return;
        }
@@ -5975,44 +5927,44 @@ Editor::split_region_at_points (boost::shared_ptr<Region> r, AnalysisFeatureList
                        return;
                }
        }
-       
+
        if (use_rhythmic_rodent) {
                show_rhythm_ferret ();
                return;
        }
 
-       AnalysisFeatureList::const_iterator x;  
-       
+       AnalysisFeatureList::const_iterator x;
+
        nframes64_t pos = r->position();
 
        XMLNode& before (pl->get_state());
-       
+
        x = positions.begin();
-       
+
        while (x != positions.end()) {
                if ((*x) > pos) {
                        break;
                }
                ++x;
        }
-       
+
        if (x == positions.end()) {
                return;
        }
-       
+
        pl->freeze ();
        pl->remove_region (r);
-       
+
        while (x != positions.end()) {
-               
-               /* file start = original start + how far we from the initial position ? 
+
+               /* file start = original start + how far we from the initial position ?
                 */
-               
+
                nframes64_t file_start = r->start() + (pos - r->position());
 
                /* length = next position - current position
                 */
-               
+
                nframes64_t len = (*x) - pos;
 
                /* XXX we do we really want to allow even single-sample regions?
@@ -6022,13 +5974,13 @@ Editor::split_region_at_points (boost::shared_ptr<Region> r, AnalysisFeatureList
                if (len <= 0) {
                        break;
                }
-               
+
                string new_name;
-               
+
                if (session->region_name (new_name, r->name())) {
                        break;
                }
-               
+
                /* do NOT announce new regions 1 by one, just wait till they are all done */
 
                boost::shared_ptr<Region> nr = RegionFactory::create (r->sources(), file_start, len, new_name, 0, Region::DefaultFlags, false);
@@ -6040,7 +5992,7 @@ Editor::split_region_at_points (boost::shared_ptr<Region> r, AnalysisFeatureList
                if (*x > r->last_frame()) {
 
                        /* add final fragment */
-                       
+
                        file_start = r->start() + (pos - r->position());
                        len = r->last_frame() - pos;
 
@@ -6049,12 +6001,12 @@ Editor::split_region_at_points (boost::shared_ptr<Region> r, AnalysisFeatureList
 
                        break;
                }
-       } 
+       }
 
        pl->thaw ();
 
        XMLNode& after (pl->get_state());
-       
+
        session->add_command (new MementoCommand<Playlist>(*pl, &before, &after));
 }
 
@@ -6081,7 +6033,7 @@ Editor::tab_to_transient (bool forward)
                                        boost::shared_ptr<Playlist> pl = rtv->get_diskstream()->playlist ();
                                        if (pl) {
                                                nframes64_t result = pl->find_next_transient (pos, forward ? 1 : -1);
-                                               
+
                                                if (result >= 0) {
                                                        positions.push_back (result);
                                                }
@@ -6091,15 +6043,15 @@ Editor::tab_to_transient (bool forward)
                }
 
        } else {
-               
-               RegionSelection rs; 
+
+               RegionSelection rs;
 
                get_regions_for_action (rs);
-       
+
                if (rs.empty()) {
                        return;
                }
-               
+
                for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) {
                        (*r)->region()->get_transients (positions);
                }
@@ -6221,7 +6173,7 @@ Editor::remove_tracks ()
                }
                routes.push_back (rtv->_route);
        }
-       
+
        if (ntracks + nbusses == 0) {
                return;
        }
@@ -6283,7 +6235,7 @@ Editor::do_insert_time ()
        ArdourDialog d (*this, _("Insert Time"));
 
        nframes64_t const pos = get_preferred_edit_position ();
-       
+
        d.get_vbox()->set_border_width (12);
        d.get_vbox()->set_spacing (4);
 
@@ -6296,7 +6248,7 @@ Editor::do_insert_time ()
        AudioClock clock ("insertTimeClock", true, X_("InsertTimeClock"), true, true, true);
        clock.set (0);
        clock.set_session (session);
-       clock.set_bbt_reference (pos);  
+       clock.set_bbt_reference (pos);
        table.attach (clock, 1, 2, 0, 1);
 
        Label intersected_label (_("Intersected regions should:"));
@@ -6317,7 +6269,7 @@ Editor::do_insert_time ()
        d.get_vbox()->pack_start (move_markers);
        CheckButton move_tempos (_("Move tempo and meter changes"));
        d.get_vbox()->pack_start (move_tempos);
-       
+
        d.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
        d.add_button (_("Insert time"), Gtk::RESPONSE_OK);
        d.show_all ();
@@ -6352,7 +6304,7 @@ Editor::do_insert_time ()
 }
 
 void
-Editor::insert_time (nframes64_t pos, nframes64_t frames, InsertTimeOption opt, 
+Editor::insert_time (nframes64_t pos, nframes64_t frames, InsertTimeOption opt,
                     bool ignore_music_glue, bool markers_too, bool tempo_too)
 {
        bool commit = false;
@@ -6366,23 +6318,23 @@ Editor::insert_time (nframes64_t pos, nframes64_t frames, InsertTimeOption opt,
        for (TrackSelection::iterator x = selection->tracks.begin(); x != selection->tracks.end(); ++x) {
                /* regions */
                boost::shared_ptr<Playlist> pl = (*x)->playlist();
-               
+
                if (pl) {
 
                        XMLNode &before = pl->get_state();
-                       
+
                        if (opt == SplitIntersected) {
                                pl->split (pos);
                        }
-                       
+
                        pl->shift (pos, frames, (opt == MoveIntersected), ignore_music_glue);
-                       
+
                        XMLNode &after = pl->get_state();
-                       
+
                        session->add_command (new MementoCommand<Playlist> (*pl, &before, &after));
                        commit = true;
                }
-                       
+
                /* automation */
                RouteTimeAxisView* rtav = dynamic_cast<RouteTimeAxisView*> (*x);
                if (rtav) {
@@ -6398,7 +6350,7 @@ Editor::insert_time (nframes64_t pos, nframes64_t frames, InsertTimeOption opt,
                Locations::LocationList copy (session->locations()->list());
 
                for (Locations::LocationList::iterator i = copy.begin(); i != copy.end(); ++i) {
-                       
+
                        Locations::LocationList::const_iterator tmp;
 
                        if ((*i)->start() >= pos) {
@@ -6459,9 +6411,9 @@ Editor::fit_tracks (TrackSelection & tracks)
        }
 
        undo_visual_stack.push_back (current_visual_state());
-       
+
        /* operate on all tracks, hide unselected ones that are in the middle of selected ones */
-       
+
        bool prev_was_selected = false;
        bool is_selected = tracks.contains (track_views.front());
        bool next_is_selected;
@@ -6469,10 +6421,10 @@ Editor::fit_tracks (TrackSelection & tracks)
        for (TrackViewList::iterator t = track_views.begin(); t != track_views.end(); ++t) {
 
                TrackViewList::iterator next;
-               
+
                next = t;
                ++next;
-               
+
                if (next != track_views.end()) {
                        next_is_selected = tracks.contains (*next);
                } else {
@@ -6492,10 +6444,10 @@ Editor::fit_tracks (TrackSelection & tracks)
                is_selected = next_is_selected;
        }
 
-       /* 
-          set the controls_layout height now, because waiting for its size 
-          request signal handler will cause the vertical adjustment setting to fail 
-       */ 
+       /*
+          set the controls_layout height now, because waiting for its size
+          request signal handler will cause the vertical adjustment setting to fail
+       */
 
        controls_layout.property_height () = full_canvas_height - canvas_timebars_vsize;
        vertical_adjustment.set_value (first_y_pos);
@@ -6533,10 +6485,8 @@ Editor::goto_visual_state (uint32_t n)
 void
 Editor::start_visual_state_op (uint32_t n)
 {
-       cerr << "Start visual op\n";
        if (visual_state_op_connection.empty()) {
                visual_state_op_connection = Glib::signal_timeout().connect (bind (mem_fun (*this, &Editor::end_visual_state_op), n), 1000);
-               cerr << "\tqueued new timeout\n";
        }
 }
 
@@ -6544,11 +6494,13 @@ void
 Editor::cancel_visual_state_op (uint32_t n)
 {
        if (!visual_state_op_connection.empty()) {
-               cerr << "cancel visual op, time to goto\n";
                visual_state_op_connection.disconnect();
                goto_visual_state (n);
-       } else {
-               cerr << "cancel visual op, do nothing\n";
+       }  else {
+               //we land here if called from the menu OR if end_visual_state_op has been called
+               //so check if we are already in visual state n
+               // XXX not yet checking it at all, but redoing does not hurt
+               goto_visual_state (n);
        }
 }
 
@@ -6557,7 +6509,7 @@ Editor::end_visual_state_op (uint32_t n)
 {
        visual_state_op_connection.disconnect();
        save_visual_state (n);
-       
+
        PopUp* pup = new PopUp (WIN_POS_MOUSE, 1000, true);
        char buf[32];
        snprintf (buf, sizeof (buf), _("Saved view %u"), n+1);