Make static analysis happy..
[ardour.git] / gtk2_ardour / route_processor_selection.cc
1 /*
2     Copyright (C) 2002 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <algorithm>
21 #include <sigc++/bind.h>
22
23 #include "pbd/error.h"
24 #include "pbd/i18n.h"
25
26 #include "ardour/selection.h"
27 #include "ardour/session.h"
28 #include "ardour/session_handle.h"
29
30 #include "axis_provider.h"
31 #include "gui_thread.h"
32 #include "mixer_strip.h"
33 #include "mixer_ui.h"
34 #include "route_processor_selection.h"
35 #include "route_ui.h"
36
37 using namespace std;
38 using namespace ARDOUR;
39 using namespace PBD;
40
41 RouteProcessorSelection::RouteProcessorSelection (SessionHandlePtr& s, AxisViewProvider& ap)
42         : shp (s), avp (ap)
43 {
44 }
45
46 bool
47 operator== (const RouteProcessorSelection& a, const RouteProcessorSelection& b)
48 {
49         // XXX MUST TEST PROCESSORS SOMEHOW
50         return a.axes == b.axes;
51 }
52
53 void
54 RouteProcessorSelection::clear ()
55 {
56         clear_processors ();
57         clear_routes ();
58 }
59
60 void
61 RouteProcessorSelection::clear_routes ()
62 {
63         if (shp.session()) {
64                 PresentationInfo::ChangeSuspender cs;
65                 shp.session()->selection().clear_stripables ();
66         }
67 }
68
69 std::list<AxisView*>
70 RouteProcessorSelection::add_grouped_tracks (AxisView* r) const
71 {
72         std::list<AxisView*> rv;
73
74         boost::shared_ptr<Route> route = boost::dynamic_pointer_cast<Route>(r->stripable());
75         if (route) {
76                 ARDOUR::RouteGroup* rg = route->route_group ();
77                 if (rg && rg->is_active() && rg->is_select ()) {
78
79                         boost::shared_ptr<RouteList> rl = rg->route_list ();
80                         for (RouteList::const_iterator i = rl->begin(); i != rl->end(); ++i) {
81                                 AxisView* av = avp.axis_view_by_stripable (*i);
82                                 rv.push_back (av);
83                         }
84                 }
85         }
86         return rv;
87 }
88
89 void
90 RouteProcessorSelection::presentation_info_changed (PropertyChange const & what_changed)
91 {
92         Session* s = shp.session();
93
94         if (!s) {
95                 /* too early ... session handle provider doesn't know about the
96                    session yet.
97                 */
98                 return;
99         }
100
101         PropertyChange pc;
102         pc.add (Properties::selected);
103
104         CoreSelection::StripableAutomationControls sc;
105         s->selection().get_stripables (sc);
106
107         for (AxisViewSelection::iterator a = axes.begin(); a != axes.end(); ++a) {
108                 (*a)->set_selected (false);
109         }
110
111         axes.clear ();
112
113         for (CoreSelection::StripableAutomationControls::const_iterator i = sc.begin(); i != sc.end(); ++i) {
114                 AxisView* av = avp.axis_view_by_stripable ((*i).stripable);
115                 if (av) {
116                         axes.insert (av);
117                         av->set_selected (true);
118                 }
119         }
120 }
121
122 void
123 RouteProcessorSelection::add (AxisView* r, bool with_groups)
124 {
125         if (!shp.session()) {
126                 return;
127         }
128
129         std::list<AxisView*> avl;
130         if (with_groups) {
131                 avl= add_grouped_tracks (r);
132         }
133         avl.push_back (r);
134
135         PresentationInfo::ChangeSuspender cs;
136         for (std::list<AxisView*>::const_iterator i = avl.begin (); i != avl.end (); ++i) {
137                 if (axes.insert (*i).second) {
138                         shp.session()->selection().add ((*i)->stripable(), boost::shared_ptr<AutomationControl>());
139                         MixerStrip* ms = dynamic_cast<MixerStrip*> (*i);
140                         if (ms) {
141                                 ms->CatchDeletion.connect (*this, invalidator (*this), boost::bind (&RouteProcessorSelection::remove, this, _1, false), gui_context());
142                         }
143                 }
144         }
145 }
146
147 void
148 RouteProcessorSelection::remove (AxisView* r, bool with_groups)
149 {
150         if (!shp.session()) {
151                 return;
152         }
153         ENSURE_GUI_THREAD (*this, &RouteProcessorSelection::remove, r);
154
155         std::list<AxisView*> avl;
156         if (with_groups) {
157                 avl= add_grouped_tracks (r);
158         }
159         avl.push_back (r);
160
161         PresentationInfo::ChangeSuspender cs;
162         for (std::list<AxisView*>::const_iterator i = avl.begin (); i != avl.end (); ++i) {
163                 shp.session()->selection().remove ((*i)->stripable(), boost::shared_ptr<AutomationControl>());
164         }
165 }
166
167 void
168 RouteProcessorSelection::set (AxisView* r)
169 {
170         if (!shp.session()) {
171                 return;
172         }
173         shp.session()->selection().clear_stripables ();
174         add (r, true);
175 }
176
177 bool
178 RouteProcessorSelection::selected (AxisView* r)
179 {
180         return find (axes.begin(), axes.end(), r) != axes.end();
181 }
182
183 bool
184 RouteProcessorSelection::empty ()
185 {
186         return processors.empty () && axes.empty ();
187 }