Connect Script Manager "Edit" -> Lua Scripting Window
[ardour.git] / gtk2_ardour / editor_selection.cc
index 563b90427919b6a6c1757bb00562cb5429b6c0c3..d214d48a320b42127c3a8c761276e270b451fe33 100644 (file)
@@ -21,6 +21,7 @@
 #include <cstdlib>
 
 #include "pbd/stacktrace.h"
+#include "pbd/unwind.h"
 
 #include "ardour/midi_region.h"
 #include "ardour/playlist.h"
@@ -174,6 +175,7 @@ Editor::select_all_tracks ()
                        visible_views.push_back (*i);
                }
        }
+       PBD::Unwinder<bool> uw (_track_selection_change_without_scroll, true);
        selection->set (visible_views);
 }
 
@@ -966,7 +968,9 @@ Editor::track_selection_changed ()
                 * selected, because we always append to that list.
                 */
                set_selected_mixer_strip (*(selection->tracks.back()));
-               ensure_time_axis_view_is_visible (*(selection->tracks.back()), false);
+               if (!_track_selection_change_without_scroll) {
+                       ensure_time_axis_view_is_visible (*(selection->tracks.back()), false);
+               }
                break;
        }
 
@@ -1002,6 +1006,8 @@ Editor::track_selection_changed ()
 
        ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, !selection->tracks.empty());
 
+       sensitize_the_right_region_actions (false);
+
        /* notify control protocols */
 
        ControlProtocol::StripableSelectionChanged (stripables);
@@ -1086,23 +1092,23 @@ Editor::sensitize_all_region_actions (bool s)
        _all_region_actions_sensitized = s;
 }
 
-/** Sensitize region-based actions based on the selection ONLY, ignoring the entered_regionview.
- *  This method is called from three places:
+/** Sensitize region-based actions.
  *
- *    1. just before the top level Region menu is shown
- *    2. whenever the region selection changes
- *    3. just before popping up a track context menu
- *
- *  This method also sets up toggle action state as appropriate.
+ *  This method is called from whenever we leave the canvas, either by moving
+ *  the pointer out of it, or by popping up a context menu. See
+ *  Editor::{entered,left}_track_canvas() for details there.
  */
 void
-Editor::sensitize_the_right_region_actions (bool from_context_menu, bool from_outside_canvas)
+Editor::sensitize_the_right_region_actions (bool because_canvas_crossing)
 {
        bool have_selection = false;
        bool have_entered = false;
        bool have_edit_point = false;
        RegionSelection rs;
 
+       // std::cerr << "STRRA: crossing ? " << because_canvas_crossing << " within ? " << within_track_canvas
+       // << std::endl;
+
        if (!selection->regions.empty()) {
                have_selection = true;
                rs = selection->regions;
@@ -1113,18 +1119,41 @@ Editor::sensitize_the_right_region_actions (bool from_context_menu, bool from_ou
                rs.add (entered_regionview);
        }
 
-       if (!selection->tracks.empty()) {
-               RegionSelection at_edit_point;
-               framepos_t const where = get_preferred_edit_position (Editing::EDIT_IGNORE_NONE, from_context_menu, from_outside_canvas);
-               get_regions_at (at_edit_point, where, selection->tracks);
-               if (!at_edit_point.empty()) {
-                       have_edit_point = true;
-               }
-               if (rs.empty()) {
-                       rs.insert (rs.end(), at_edit_point.begin(), at_edit_point.end());
+       if (rs.empty() && !selection->tracks.empty()) {
+
+               /* no selected regions, but some selected tracks.
+                */
+
+               if (_edit_point == EditAtMouse) {
+                       if (!within_track_canvas) {
+                               /* pointer is not in canvas, so edit point is meaningless */
+                               have_edit_point = false;
+                       } else {
+                               /* inside canvas. we don't know where the edit
+                                  point will be when an action is invoked, but
+                                  assume it could intersect with a region.
+                               */
+                               have_edit_point = true;
+                       }
+               } else {
+                       RegionSelection at_edit_point;
+                       framepos_t const where = get_preferred_edit_position (Editing::EDIT_IGNORE_NONE, false, !within_track_canvas);
+                       get_regions_at (at_edit_point, where, selection->tracks);
+                       if (!at_edit_point.empty()) {
+                               have_edit_point = true;
+                       }
+                       if (rs.empty()) {
+                               rs.insert (rs.end(), at_edit_point.begin(), at_edit_point.end());
+                       }
                }
        }
 
+       //std::cerr << "\tfinal have selection: " << have_selection
+       // << " have entered " << have_entered
+       // << " have edit point " << have_edit_point
+       // << " EP = " << enum_2_string (_edit_point)
+       // << std::endl;
+
        typedef std::map<std::string,RegionAction> RegionActionMap;
 
        _ignore_region_action = true;
@@ -1420,7 +1449,7 @@ Editor::region_selection_changed ()
        _regions->block_change_connection (false);
        editor_regions_selection_changed_connection.block(false);
 
-       sensitize_the_right_region_actions (false, false);
+       sensitize_the_right_region_actions (false);
 
        /* propagate into backend */