+
+ for (set<RouteTimeAxisView*>::iterator i = tracks.begin(); i != tracks.end(); ++i) {
+ sl (**i, sz);
+ }
+}
+
+/** 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_with_unique_playlists (sigc::slot<void, RouteTimeAxisView&, uint32_t> sl, TimeAxisView* basis, PBD::PropertyID prop) const
+{
+ RouteTimeAxisView* route_basis = dynamic_cast<RouteTimeAxisView*> (basis);
+ set<boost::shared_ptr<Playlist> > playlists;
+
+ if (route_basis == 0) {
+ return;
+ }
+
+ set<RouteTimeAxisView*> tracks;
+ tracks.insert (route_basis);
+
+ RouteGroup* group = route_basis->route()->route_group(); // could be null, not a problem
+
+ if (group && group->enabled_property(prop) && group->enabled_property (Properties::active.property_id) ) {
+
+ /* 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) {
+
+ boost::shared_ptr<Track> t = v->track();
+ if (t) {
+ if (playlists.insert (t->playlist()).second) {
+ /* haven't seen this playlist yet */
+ tracks.insert (v);
+ }
+ } else {
+ /* not actually a "Track", but a timeaxis view that
+ we should mapover anyway.
+ */
+ tracks.insert (v);
+ }
+ }
+ }
+ }
+
+ /* call the slots */
+ uint32_t const sz = tracks.size ();
+