region list patch #2 from chris g, slightly reworked by me; sv_se po changes, possibl...
[ardour.git] / gtk2_ardour / editor_selection.cc
index 5fcdb8ef327a83129c083653fafd16a571353dda..e1c6f4e7ea9b15e959a73a7793af23f79df97df6 100644 (file)
 */
 
 #include <algorithm>
-#include <stdlib.h>
+#include <cstdlib>
 
 #include <pbd/stacktrace.h>
 
 #include <ardour/diskstream.h>
 #include <ardour/playlist.h>
 #include <ardour/route_group.h>
+#include <ardour/profile.h>
 
 #include "editor.h"
 #include "actions.h"
@@ -183,7 +184,6 @@ Editor::set_selected_track_as_side_effect (bool force)
 void
 Editor::set_selected_track (TimeAxisView& view, Selection::Operation op, bool no_remove)
 {
-
        switch (op) {
        case Selection::Toggle:
                if (selection->selected (&view)) {
@@ -202,21 +202,7 @@ Editor::set_selected_track (TimeAxisView& view, Selection::Operation op, bool no
                break;
 
        case Selection::Set:
-               if (selection->selected (&view) && selection->tracks.size() > 1) {
-
-                       /* reset track selection if there is only 1 other track
-                          selected OR if no_remove is not set (its there to 
-                          prevent deselecting a multi-track selection
-                          when clicking on an already selected track
-                          for some reason.
-                       */
-
-                       if (selection->tracks.empty()) {
-                               selection->set (&view);
-                       } else if (selection->tracks.size() == 1 || !no_remove) {
-                               selection->set (&view);
-                       }
-               }
+               selection->set (&view);
                break;
                
        case Selection::Extend:
@@ -249,7 +235,7 @@ Editor::set_selected_control_point_from_click (Selection::Operation op, bool no_
        /* select this point and any others that it represents */
 
        double y1, y2;
-       nframes_t x1, x2;
+       nframes64_t x1, x2;
 
        x1 = pixel_to_frame (clicked_control_point->get_x() - 10);
        x2 = pixel_to_frame (clicked_control_point->get_x() + 10);
@@ -376,6 +362,44 @@ Editor::get_equivalent_regions (RegionView* basis, vector<RegionView*>& equivale
        equivalent_regions.push_back (basis);
 }
 
+int
+Editor::get_regionview_count_from_region_list (boost::shared_ptr<Region> region)
+{
+       int region_count = 0;
+       
+       for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+               
+               RouteTimeAxisView* tatv;
+               
+               if ((tatv = dynamic_cast<RouteTimeAxisView*> (*i)) != 0) {
+                       
+                       boost::shared_ptr<Playlist> pl;
+                       vector<boost::shared_ptr<Region> > results;
+                       RegionView* marv;
+                       boost::shared_ptr<Diskstream> ds;
+                       
+                       if ((ds = tatv->get_diskstream()) == 0) {
+                               /* bus */
+                               continue;
+                       }
+                       
+                       if ((pl = (ds->playlist())) != 0) {
+                               pl->get_region_list_equivalent_regions (region, results);
+                       }
+                       
+                       for (vector<boost::shared_ptr<Region> >::iterator ir = results.begin(); ir != results.end(); ++ir) {
+                               if ((marv = tatv->view()->find_view (*ir)) != 0) {
+                                       region_count++;
+                               }
+                       }
+                       
+               }
+       }
+       
+       return region_count;
+}
+
+
 bool
 Editor::set_selected_regionview_from_click (bool press, Selection::Operation op, bool no_track_remove)
 {
@@ -463,8 +487,8 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op,
        } else if (op == Selection::Extend) {
 
                list<Selectable*> results;
-               nframes_t last_frame;
-               nframes_t first_frame;
+               nframes64_t last_frame;
+               nframes64_t first_frame;
                bool same_track = false;
 
                /* 1. find the last selected regionview in the track that was clicked in */
@@ -713,6 +737,37 @@ Editor::set_selected_regionview_from_region_list (boost::shared_ptr<Region> regi
        commit_reversible_command () ;
 }
 
+bool
+Editor::set_selected_regionview_from_map_event (GdkEventAny* ev, StreamView* sv, boost::weak_ptr<Region> weak_r)
+{
+       RegionView* rv;
+       boost::shared_ptr<Region> r (weak_r.lock());
+
+       if (!r) {
+               return true;
+       }
+
+       if ((rv = sv->find_view (r)) == 0) {
+               return true;
+       }
+
+       /* don't reset the selection if its something other than 
+          a single other region.
+       */
+
+       if (selection->regions.size() > 1) {
+               return true;
+       }
+       
+       begin_reversible_command (_("set selected regions"));
+       
+       selection->set (rv);
+
+       commit_reversible_command () ;
+
+       return true;
+}
+
 void
 Editor::track_selection_changed ()
 {
@@ -731,11 +786,17 @@ Editor::track_selection_changed ()
                        (*i)->set_selected (false);
                }
        }
+
+       ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, !selection->tracks.empty());
 }
 
 void
 Editor::time_selection_changed ()
 {
+       if (Profile->get_sae()) {
+               return;
+       }
+
        for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
                (*i)->hide_selection ();
        }
@@ -758,6 +819,30 @@ Editor::time_selection_changed ()
 
 }
 
+void
+Editor::sensitize_the_right_region_actions (bool have_selected_regions)
+{
+       for (vector<Glib::RefPtr<Action> >::iterator x = ActionManager::region_selection_sensitive_actions.begin();
+            x != ActionManager::region_selection_sensitive_actions.end(); ++x) {
+
+               string accel_path = (*x)->get_accel_path ();
+               AccelKey key;
+
+               /* if there is an accelerator, it should always be sensitive
+                  to allow for keyboard ops on entered regions.
+               */
+
+               bool known = ActionManager::lookup_entry (accel_path, key);
+
+               if (known && ((key.get_key() != GDK_VoidSymbol) && (key.get_key() != 0))) {
+                       (*x)->set_sensitive (true);
+               } else {
+                       (*x)->set_sensitive (have_selected_regions);
+               }
+       }
+}
+
+
 void
 Editor::region_selection_changed ()
 {
@@ -765,6 +850,8 @@ Editor::region_selection_changed ()
                (*i)->set_selected_regionviews (selection->regions);
        }
        
+       sensitize_the_right_region_actions (!selection->regions.empty());
+
        zoomed_to_region = false;
 }
 
@@ -776,17 +863,16 @@ Editor::point_selection_changed ()
        }
 }
 
-/** Select everything in the selected tracks
- * @param Selection operation to apply.
- */
 void
-Editor::select_all_in_selected_tracks (Selection::Operation op)
+Editor::select_all_in_track (Selection::Operation op)
 {
        list<Selectable *> touched;
 
-       for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
-               (*i)->get_selectables (0, max_frames, 0, DBL_MAX, touched);
+       if (!clicked_routeview) {
+               return;
        }
+       
+       clicked_routeview->get_selectables (0, max_frames, 0, DBL_MAX, touched);
 
        switch (op) {
        case Selection::Toggle:
@@ -808,7 +894,7 @@ void
 Editor::select_all (Selection::Operation op)
 {
        list<Selectable *> touched;
-       
+
        for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
                if ((*iter)->hidden()) {
                        continue;
@@ -832,17 +918,16 @@ Editor::select_all (Selection::Operation op)
        }
        commit_reversible_command ();
 }
-
-/** Invert the selection in the selected tracks */
 void
-Editor::invert_selection_in_selected_tracks ()
+Editor::invert_selection_in_track ()
 {
        list<Selectable *> touched;
 
-       for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
-               (*i)->get_inverted_selectables (*selection, touched);
+       if (!clicked_routeview) {
+               return;
        }
        
+       clicked_routeview->get_inverted_selectables (*selection, touched);
        selection->set (touched);
 }
 
@@ -862,7 +947,7 @@ Editor::invert_selection ()
 }
 
 bool
-Editor::select_all_within (nframes_t start, nframes_t end, double top, double bot, const TrackViewList& tracklist, Selection::Operation op)
+Editor::select_all_within (nframes64_t start, nframes64_t end, double top, double bot, const TrackViewList& tracklist, Selection::Operation op)
 {
        list<Selectable*> touched;
        list<Selectable*>::size_type n = 0;
@@ -926,20 +1011,16 @@ Editor::select_all_within (nframes_t start, nframes_t end, double top, double bo
 }
 
 void
-Editor::set_selection_from_audio_region ()
+Editor::set_selection_from_region ()
 {
        if (selection->regions.empty()) {
                return;
        }
 
-       RegionView* rv = *(selection->regions.begin());
-       boost::shared_ptr<Region> region = rv->region();
-       
-       begin_reversible_command (_("set selection from region"));
-       selection->set (0, region->position(), region->last_frame());
-       commit_reversible_command ();
-
-       set_mouse_mode (Editing::MouseRange, false);
+       selection->set (0, selection->regions.start(), selection->regions.end_frame());
+       if (!Profile->get_sae()) {
+               set_mouse_mode (Editing::MouseRange, false);
+       }
 }
 
 void
@@ -972,7 +1053,9 @@ Editor::set_selection_from_range (Location& loc)
        selection->set (0, loc.start(), loc.end());
        commit_reversible_command ();
 
-       set_mouse_mode (Editing::MouseRange, false);
+       if (!Profile->get_sae()) {
+               set_mouse_mode (Editing::MouseRange, false);
+       }
 }
 
 void
@@ -984,14 +1067,22 @@ Editor::select_all_selectables_using_time_selection ()
                return;
        }
 
-       nframes_t start = selection->time[clicked_selection].start;
-       nframes_t end = selection->time[clicked_selection].end;
+       nframes64_t start = selection->time[clicked_selection].start;
+       nframes64_t end = selection->time[clicked_selection].end;
 
        if (end - start < 1)  {
                return;
        }
 
-       for (TrackViewList::iterator iter = selection->tracks.begin(); iter != selection->tracks.end(); ++iter) {
+       TrackSelection* ts;
+
+       if (selection->tracks.empty()) {
+               ts = &track_views;
+       } else {
+               ts = &selection->tracks;
+       }
+
+       for (TrackViewList::iterator iter = ts->begin(); iter != ts->end(); ++iter) {
                if ((*iter)->hidden()) {
                        continue;
                }
@@ -1014,7 +1105,16 @@ Editor::select_all_selectables_using_punch()
                return;
        }
 
-       for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
+
+       TrackSelection* ts;
+
+       if (selection->tracks.empty()) {
+               ts = &track_views;
+       } else {
+               ts = &selection->tracks;
+       }
+
+       for (TrackViewList::iterator iter = ts->begin(); iter != ts->end(); ++iter) {
                if ((*iter)->hidden()) {
                        continue;
                }
@@ -1036,7 +1136,16 @@ Editor::select_all_selectables_using_loop()
                return;
        }
 
-       for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
+
+       TrackSelection* ts;
+
+       if (selection->tracks.empty()) {
+               ts = &track_views;
+       } else {
+               ts = &selection->tracks;
+       }
+
+       for (TrackViewList::iterator iter = ts->begin(); iter != ts->end(); ++iter) {
                if ((*iter)->hidden()) {
                        continue;
                }
@@ -1051,8 +1160,8 @@ Editor::select_all_selectables_using_loop()
 void
 Editor::select_all_selectables_using_cursor (Cursor *cursor, bool after)
 {
-        nframes_t start;
-       nframes_t end;
+        nframes64_t start;
+       nframes64_t end;
        list<Selectable *> touched;
 
        if (after) {
@@ -1069,7 +1178,16 @@ Editor::select_all_selectables_using_cursor (Cursor *cursor, bool after)
                }
        }
 
-       for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
+
+       TrackSelection* ts;
+
+       if (selection->tracks.empty()) {
+               ts = &track_views;
+       } else {
+               ts = &selection->tracks;
+       }
+
+       for (TrackViewList::iterator iter = ts->begin(); iter != ts->end(); ++iter) {
                if ((*iter)->hidden()) {
                        continue;
                }
@@ -1082,8 +1200,8 @@ Editor::select_all_selectables_using_cursor (Cursor *cursor, bool after)
 void
 Editor::select_all_selectables_using_edit (bool after)
 {
-        nframes_t start;
-       nframes_t end;
+        nframes64_t start;
+       nframes64_t end;
        list<Selectable *> touched;
 
        if (after) {
@@ -1100,7 +1218,16 @@ Editor::select_all_selectables_using_edit (bool after)
                }
        }
 
-       for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
+
+       TrackSelection* ts;
+
+       if (selection->tracks.empty()) {
+               ts = &track_views;
+       } else {
+               ts = &selection->tracks;
+       }
+
+       for (TrackViewList::iterator iter = ts->begin(); iter != ts->end(); ++iter) {
                if ((*iter)->hidden()) {
                        continue;
                }
@@ -1120,8 +1247,16 @@ Editor::select_all_selectables_between (bool within)
        if (!get_edit_op_range (start, end)) {
                return;
        }
-       
-       for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
+
+       TrackSelection* ts;
+
+       if (selection->tracks.empty()) {
+               ts = &track_views;
+       } else {
+               ts = &selection->tracks;
+       }
+
+       for (TrackViewList::iterator iter = ts->begin(); iter != ts->end(); ++iter) {
                if ((*iter)->hidden()) {
                        continue;
                }
@@ -1233,6 +1368,12 @@ Editor::get_edit_op_range (nframes64_t& start, nframes64_t& end) const
                swap (start, end);
        }
 
+       /* turn range into one delimited by start...end,
+          not start...end-1
+       */
+
+       end++;
+
        return true;
 }
 
@@ -1241,3 +1382,5 @@ Editor::deselect_all ()
 {
        selection->clear ();
 }
+
+