Speed up track deletion when Editor-Mixer is visible
[ardour.git] / gtk2_ardour / editor_ops.cc
index 86ff4cd045b17a8e7602b225aac9eebb1fff046f..25d1c7376667e32c7051281f5dd16ab042c8c52b 100644 (file)
@@ -82,6 +82,7 @@
 #include "item_counts.h"
 #include "keyboard.h"
 #include "midi_region_view.h"
+#include "mixer_ui.h"
 #include "mixer_strip.h"
 #include "mouse_cursors.h"
 #include "normalize_dialog.h"
@@ -165,7 +166,8 @@ Editor::redo (uint32_t n)
 }
 
 void
-Editor::split_regions_at (framepos_t where, RegionSelection& regions, const int32_t sub_num)
+Editor::split_regions_at (framepos_t where, RegionSelection& regions, const int32_t sub_num,
+                          bool snap_frame)
 {
        bool frozen = false;
 
@@ -191,10 +193,14 @@ Editor::split_regions_at (framepos_t where, RegionSelection& regions, const int3
                case SnapToRegionEnd:
                        break;
                default:
-                       snap_to (where);
+                       if (snap_frame) {
+                               snap_to (where);
+                       }
                }
        } else {
-               snap_to (where);
+               if (snap_frame) {
+                       snap_to (where);
+               }
 
                frozen = true;
                EditorFreeze(); /* Emit Signal */
@@ -1709,25 +1715,43 @@ Editor::tav_zoom_smooth (bool coarser, bool force_all)
 }
 
 void
-Editor::temporal_zoom_step_mouse_focus (bool coarser)
+Editor::temporal_zoom_step_mouse_focus_scale (bool zoom_out, double scale)
 {
        Editing::ZoomFocus temp_focus = zoom_focus;
        zoom_focus = Editing::ZoomFocusMouse;
-       temporal_zoom_step (coarser);
+       temporal_zoom_step_scale (zoom_out, scale);
        zoom_focus = temp_focus;
 }
 
 void
-Editor::temporal_zoom_step (bool coarser)
+Editor::temporal_zoom_step_mouse_focus (bool zoom_out)
+{
+       temporal_zoom_step_mouse_focus_scale (zoom_out, 2.0);
+}
+
+void
+Editor::temporal_zoom_step (bool zoom_out)
 {
-       ENSURE_GUI_THREAD (*this, &Editor::temporal_zoom_step, coarser)
+       temporal_zoom_step_scale (zoom_out, 2.0);
+}
+
+void
+Editor::temporal_zoom_step_scale (bool zoom_out, double scale)
+{
+       ENSURE_GUI_THREAD (*this, &Editor::temporal_zoom_step, zoom_out, scale)
 
        framecnt_t nspp = samples_per_pixel;
 
-       if (coarser) {
-               nspp *= 2;
+       if (zoom_out) {
+               nspp *= scale;
+               if (nspp == samples_per_pixel) {
+                       nspp *= 2.0;
+               }
        } else {
-               nspp /= 2;
+               nspp /= scale;
+               if (nspp == samples_per_pixel) {
+                       nspp /= 2.0;
+               }
        }
 
        temporal_zoom (nspp);
@@ -1749,6 +1773,7 @@ Editor::temporal_zoom (framecnt_t fpp)
        framepos_t leftmost_after_zoom = 0;
        framepos_t where;
        bool in_track_canvas;
+       bool use_mouse_frame = true;
        framecnt_t nfpp;
        double l;
 
@@ -1809,18 +1834,13 @@ Editor::temporal_zoom (framecnt_t fpp)
        case ZoomFocusMouse:
                /* try to keep the mouse over the same point in the display */
 
-               if (!mouse_frame (where, in_track_canvas)) {
-                       /* use playhead instead */
-                       where = playhead_cursor->current_frame ();
-
-                       if (where < half_page_size) {
-                               leftmost_after_zoom = 0;
-                       } else {
-                               leftmost_after_zoom = where - half_page_size;
-                       }
-
-               } else {
+               if (_drags->active()) {
+                       where = _drags->current_pointer_frame ();
+               } else if (!mouse_frame (where, in_track_canvas)) {
+                       use_mouse_frame = false;
+               }
 
+               if (use_mouse_frame) {
                        l = - ((new_page_size * ((where - current_leftmost)/(double)current_page)) - where);
 
                        if (l < 0) {
@@ -1830,8 +1850,16 @@ Editor::temporal_zoom (framecnt_t fpp)
                        } else {
                                leftmost_after_zoom = (framepos_t) l;
                        }
-               }
+               } else {
+                       /* use playhead instead */
+                       where = playhead_cursor->current_frame ();
 
+                       if (where < half_page_size) {
+                               leftmost_after_zoom = 0;
+                       } else {
+                               leftmost_after_zoom = where - half_page_size;
+                       }
+               }
                break;
 
        case ZoomFocusEdit:
@@ -4822,6 +4850,13 @@ Editor::paste_internal (framepos_t position, float times, const int32_t sub_num)
        commit_reversible_command ();
 }
 
+void
+Editor::duplicate_regions (float times)
+{
+       RegionSelection rs (get_regions_from_selection_and_entered());
+       duplicate_some_regions (rs, times);
+}
+
 void
 Editor::duplicate_some_regions (RegionSelection& regions, float times)
 {
@@ -5049,7 +5084,7 @@ Editor::normalize_region ()
 
        NormalizeDialog dialog (rs.size() > 1);
 
-       if (dialog.run () == RESPONSE_CANCEL) {
+       if (dialog.run () != RESPONSE_ACCEPT) {
                return;
        }
 
@@ -5374,6 +5409,11 @@ Editor::quantize_regions (const RegionSelection& rs)
                quantize_dialog = new QuantizeDialog (*this);
        }
 
+       if (quantize_dialog->is_mapped()) {
+               /* in progress already */
+               return;
+       }
+
        quantize_dialog->present ();
        const int r = quantize_dialog->run ();
        quantize_dialog->hide ();
@@ -7348,6 +7388,26 @@ edit your ardour.rc file to set the\n\
                return;
        }
 
+       if (current_mixer_strip && routes.size () > 1 && std::find (routes.begin(), routes.end(), current_mixer_strip->route()) != routes.end ()) {
+               /* Route deletion calls Editor::timeaxisview_deleted() iteratively (for each deleted
+                * route). If the deleted route is currently displayed in the Editor-Mixer (highly
+                * likely because deletion requires selection) this will call
+                * Editor::set_selected_mixer_strip () which is expensive ( MixerStrip::set_route() ).
+                * It's likewise likely that the route that has just been displayed in the
+                * Editor-Mixer will be next in line for deletion.
+                *
+                * So simply switch to the master-bus (if present)
+                */
+               for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+                       if ((*i)->stripable ()->is_master ()) {
+                               set_selected_mixer_strip (*(*i));
+                               break;
+                       }
+               }
+       }
+
+       Mixer_UI::instance()->selection().block_routes_changed (true);
+       selection->block_tracks_changed (true);
        {
                DisplaySuspender ds;
                boost::shared_ptr<RouteList> rl (new RouteList);
@@ -7360,6 +7420,9 @@ edit your ardour.rc file to set the\n\
         * destructors are called,
         * diskstream drops references, save_state is called (again for every track)
         */
+       selection->block_tracks_changed (false);
+       Mixer_UI::instance()->selection().block_routes_changed (false);
+       selection->TracksChanged (); /* EMIT SIGNAL */
 }
 
 void
@@ -7381,7 +7444,7 @@ Editor::do_insert_time ()
        }
 
        insert_time (
-               get_preferred_edit_position (EDIT_IGNORE_MOUSE),
+               d.position(),
                d.distance(),
                d.intersected_region_action (),
                d.all_playlists(),
@@ -7530,7 +7593,6 @@ Editor::do_remove_time ()
                return;
        }
 
-       framepos_t pos = get_preferred_edit_position (EDIT_IGNORE_MOUSE);
        InsertRemoveTimeDialog d (*this, true);
 
        int response = d.run ();
@@ -7546,7 +7608,7 @@ Editor::do_remove_time ()
        }
 
        remove_time (
-               pos,
+               d.position(),
                distance,
                SplitIntersected,
                d.move_glued(),