Back out big shared_ptr change. Moving to a branch. Apologies all.
[ardour.git] / gtk2_ardour / editor_selection.cc
index 9bfba273f75ee99e00d4eda433317d4976edbc29..3b53a2d8217dfb873b0207716d8a85f9c3523d77 100644 (file)
@@ -34,6 +34,7 @@
 #include "audio_streamview.h"
 #include "automation_line.h"
 #include "control_point.h"
+#include "editor_regions.h"
 
 #include "i18n.h"
 
@@ -261,76 +262,66 @@ Editor::get_onscreen_tracks (TrackViewList& tvl)
        }
 }
 
+/** Given a track, find any other tracks that are in the same active route group with a given property.
+ *  @param basis Base track.
+ *  @param equivs Filled with the base track and the found tracks.
+ *  @param prop Property to look for in route groups.
+ */
+
 void
-Editor::get_relevant_tracks (set<RouteTimeAxisView*>& relevant_tracks)
+Editor::get_equivalent_tracks (RouteTimeAxisView* basis, set<RouteTimeAxisView*> & equivs, RouteGroup::Property prop) const
 {
-       /* step one: get all selected tracks and all tracks in the relevant edit groups */
-
-       for (TrackSelection::iterator ti = selection->tracks.begin(); ti != selection->tracks.end(); ++ti) {
+       equivs.insert (basis);
 
-               RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(*ti);
+       RouteGroup* group = basis->route()->route_group();
+       if (group && group->active_property (prop)) {
 
-               if (!rtv) {
-                       continue;
+               /* the basis is a member of an active route group, with the appropriate
+                  properties; find other members */
+               
+               for (TrackViewList::const_iterator i = track_views.begin(); i != track_views.end(); ++i) {
+                       RouteTimeAxisView* v = dynamic_cast<RouteTimeAxisView*> (*i);
+                       if (v && v->route()->route_group() == group) {
+                               equivs.insert (v);
+                       }
                }
+       }
+}
 
-               RouteGroup* group = rtv->route()->edit_group();
-
-               if (group && group->is_active()) {
-                       
-                       /* active group for this track, loop over all tracks and get every member of the group */
+/** Find tracks that are selected, and also those that are in the same `selection'-enabled route
+ *  group as one that is selected.
+ *  @param relevant_tracks set to add tracks to.
+ */
 
-                       for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
-                               
-                               RouteTimeAxisView* trtv;
-                               
-                               if ((trtv = dynamic_cast<RouteTimeAxisView*> (*i)) != 0) {
-                                       
-                                       if (trtv->route()->edit_group() == group) {
-                                               relevant_tracks.insert (trtv);
-                                       }
-                               }
-                       }
-               } else {
-                       relevant_tracks.insert (rtv);
+void
+Editor::get_relevant_tracks (set<RouteTimeAxisView*>& relevant_tracks) const
+{
+       for (TrackSelection::iterator ti = selection->tracks.begin(); ti != selection->tracks.end(); ++ti) {
+               RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*ti);
+               if (rtv) {
+                       get_equivalent_tracks (rtv, relevant_tracks, RouteGroup::Select);
                }
        }
 }
 
-/**
- *  Call a slot for a given `basis' track and also for any track that is in the same
- *  active edit group.
+/** Call a slot for a given `basis' track and also for any track that is in the same
+ *  active route group with a particular set of properties.
+ *
  *  @param sl Slot to call.
  *  @param basis Basis track.
+ *  @param prop Properties that active edit groups must share to be included in the map.
  */
 
 void
-Editor::mapover_tracks (slot<void, RouteTimeAxisView&, uint32_t> sl, TimeAxisView* basis) const
+Editor::mapover_tracks (slot<void, RouteTimeAxisView&, uint32_t> sl, TimeAxisView* basis, RouteGroup::Property prop) const
 {
        RouteTimeAxisView* route_basis = dynamic_cast<RouteTimeAxisView*> (basis);
        if (route_basis == 0) {
                return;
        }
-
-       /* work out the tracks that we will call the slot for; use
-          a set here as it will disallow possible duplicates of the
-          basis track */
+       
        set<RouteTimeAxisView*> tracks;
-
-       /* always call for the basis */
-       tracks.insert (route_basis);
-
-       RouteGroup* group = route_basis->route()->edit_group();
-       if (group && group->is_active()) {
-
-               /* the basis is a member of an active edit group; find other members */
-               for (TrackViewList::const_iterator i = track_views.begin(); i != track_views.end(); ++i) {
-                       RouteTimeAxisView* v = dynamic_cast<RouteTimeAxisView*> (*i);
-                       if (v && v->route()->edit_group() == group) {
-                               tracks.insert (v);
-                       }
-               }
-       }
+       get_equivalent_tracks (route_basis, tracks, prop);
 
        /* call the slots */
        uint32_t const sz = tracks.size ();
@@ -340,7 +331,7 @@ Editor::mapover_tracks (slot<void, RouteTimeAxisView&, uint32_t> sl, TimeAxisVie
 }
 
 void
-Editor::mapped_get_equivalent_regions (RouteTimeAxisView& tv, uint32_t ignored, RegionView* basis, vector<RegionView*>* all_equivs) const
+Editor::mapped_get_equivalent_regions (RouteTimeAxisView& tv, uint32_t ignored, RegionView * basis, vector<RegionView*>* all_equivs) const
 {
        boost::shared_ptr<Playlist> pl;
        vector<boost::shared_ptr<Region> > results;
@@ -369,15 +360,40 @@ Editor::mapped_get_equivalent_regions (RouteTimeAxisView& tv, uint32_t ignored,
 }
 
 void
-Editor::get_equivalent_regions (RegionView* basis, vector<RegionView*>& equivalent_regions) const
+Editor::get_equivalent_regions (RegionView* basis, vector<RegionView*>& equivalent_regions, RouteGroup::Property prop) const
 {
-       mapover_tracks (bind (mem_fun (*this, &Editor::mapped_get_equivalent_regions), basis, &equivalent_regions), &basis->get_trackview());
+       mapover_tracks (bind (mem_fun (*this, &Editor::mapped_get_equivalent_regions), basis, &equivalent_regions), &basis->get_trackview(), prop);
        
        /* add clicked regionview since we skipped all other regions in the same track as the one it was in */
        
        equivalent_regions.push_back (basis);
 }
 
+RegionSelection
+Editor::get_equivalent_regions (RegionSelection & basis, RouteGroup::Property prop) const
+{
+       RegionSelection equivalent;
+       
+       for (RegionSelection::const_iterator i = basis.begin(); i != basis.end(); ++i) {
+
+               vector<RegionView*> eq;
+               
+               mapover_tracks (
+                       bind (mem_fun (*this, &Editor::mapped_get_equivalent_regions), *i, &eq),
+                       &(*i)->get_trackview(), prop
+                       );
+
+               for (vector<RegionView*>::iterator j = eq.begin(); j != eq.end(); ++j) {
+                       equivalent.add (*j);
+               }
+
+               equivalent.add (*i);
+       }
+
+       return equivalent;
+}
+       
+
 int
 Editor::get_regionview_count_from_region_list (boost::shared_ptr<Region> region)
 {
@@ -467,7 +483,7 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op,
                                if (press) {
 
                                        if (selection->selected (clicked_routeview)) {
-                                               get_equivalent_regions (clicked_regionview, all_equivalent_regions);
+                                               get_equivalent_regions (clicked_regionview, all_equivalent_regions, RouteGroup::Select);
                                        } else {
                                                all_equivalent_regions.push_back (clicked_regionview);
                                        }
@@ -487,7 +503,8 @@ Editor::set_selected_regionview_from_click (bool press, Selection::Operation op,
                        
                case Selection::Set:
                        if (!selection->selected (clicked_regionview)) {
-                               selection->set (clicked_regionview);
+                               get_equivalent_regions (clicked_regionview, all_equivalent_regions, RouteGroup::Select);
+                               selection->set (all_equivalent_regions);
                                commit = true;
                        } else {
                                /* no commit necessary: clicked on an already selected region */
@@ -862,15 +879,15 @@ Editor::sensitize_the_right_region_actions (bool have_selected_regions)
 void
 Editor::region_selection_changed ()
 {
-       region_list_change_connection.block(true);
+       _regions->block_change_connection (true);
        editor_regions_selection_changed_connection.block(true);
-       
-       region_list_display.get_selection()->unselect_all();
+
+       _regions->unselect_all ();
        
        for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
                
                (*i)->set_selected_regionviews (selection->regions);
-               set_selected_in_region_list(selection->regions);
+               _regions->set_selected (selection->regions);
        
        }
        
@@ -878,7 +895,7 @@ Editor::region_selection_changed ()
 
        zoomed_to_region = false;
 
-       region_list_change_connection.block(false);
+       _regions->block_change_connection (false);
        editor_regions_selection_changed_connection.block(false);
 }