remote control IDs follow editor/mixer view order; fix multiple display of disk over...
[ardour.git] / gtk2_ardour / ardour_ui_dialogs.cc
1 /*
2     Copyright (C) 2000 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 /* This file contains any ARDOUR_UI methods that require knowledge of
21    the various dialog boxes, and exists so that no compilation dependency 
22    exists between the main ARDOUR_UI modules and their respective classes.
23    This is to cut down on the compile times.  It also helps with my sanity.
24 */
25
26 #include <ardour/session.h>
27
28 #include "actions.h"
29 #include "ardour_ui.h"
30 #include "connection_editor.h"
31 #include "location_ui.h"
32 #include "mixer_ui.h"
33 #include "option_editor.h"
34 #include "public_editor.h"
35 #include "route_params_ui.h"
36 #include "sfdb_ui.h"
37 #include "color_manager.h"
38
39 #include "i18n.h"
40
41 using namespace ARDOUR;
42 using namespace PBD;
43 using namespace Glib;
44 using namespace Gtk;
45 using namespace Gtkmm2ext;
46
47 void
48 ARDOUR_UI::connect_to_session (Session *s)
49 {
50         session = s;
51
52         session->HaltOnXrun.connect (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
53         session->RecordStateChanged.connect (mem_fun (*this, &ARDOUR_UI::record_state_changed));
54
55         /* sensitize menu bar options that are now valid */
56
57         ActionManager::set_sensitive (ActionManager::session_sensitive_actions, true);
58         
59         if (session->locations()->num_range_markers()) {
60                 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
61         } else {
62                 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
63         }
64
65         if (!session->control_out()) {
66                 Glib::RefPtr<Action> act = ActionManager::get_action (X_("options"), X_("SoloViaBus"));
67                 if (act) {
68                         act->set_sensitive (false);
69                 }
70         }
71
72         /* allow wastebasket flush again */
73
74         Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
75         if (act) {
76                 act->set_sensitive (true);
77         }
78
79         /* there are never any selections on startup */
80
81         ActionManager::set_sensitive (ActionManager::region_selection_sensitive_actions, false);
82         ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false);
83         ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, false);
84         ActionManager::set_sensitive (ActionManager::line_selection_sensitive_actions, false);
85         ActionManager::set_sensitive (ActionManager::point_selection_sensitive_actions, false);
86         ActionManager::set_sensitive (ActionManager::playlist_selection_sensitive_actions, false);
87
88         session->locations()->added.connect (mem_fun (*this, &ARDOUR_UI::handle_locations_change));
89         session->locations()->removed.connect (mem_fun (*this, &ARDOUR_UI::handle_locations_change));
90
91         rec_button.set_sensitive (true);
92         shuttle_box.set_sensitive (true);
93         
94         if (connection_editor) {
95                 connection_editor->set_session (s);
96         }
97
98         if (location_ui) {
99                 location_ui->set_session(s);
100         }
101
102         if (route_params) {
103                 route_params->set_session (s);
104         }
105
106         if (option_editor) {
107                 option_editor->set_session (s);
108         }
109
110         setup_session_options ();
111
112         Blink.connect (mem_fun(*this, &ARDOUR_UI::transport_rec_enable_blink));
113         Blink.connect (mem_fun(*this, &ARDOUR_UI::solo_blink));
114         Blink.connect (mem_fun(*this, &ARDOUR_UI::audition_blink));
115
116         /* these are all need to be handled in an RT-safe and MT way, so don't
117            do any GUI work, just queue it for handling by the GUI thread.
118         */
119
120         session->TransportStateChange.connect (mem_fun(*this, &ARDOUR_UI::queue_transport_change));
121
122         /* alert the user to these things happening */
123
124         session->AuditionActive.connect (mem_fun(*this, &ARDOUR_UI::auditioning_changed));
125         session->SoloActive.connect (mem_fun(*this, &ARDOUR_UI::soloing_changed));
126
127         solo_alert_button.set_active (session->soloing());
128
129         /* can't be auditioning here */
130
131         primary_clock.set_session (s);
132         secondary_clock.set_session (s);
133         big_clock.set_session (s);
134         preroll_clock.set_session (s);
135         postroll_clock.set_session (s);
136
137         /* Clocks are on by default after we are connected to a session, so show that here.
138         */
139         
140         connect_dependents_to_session (s);
141
142         /* listen to clock mode changes. don't do this earlier because otherwise as the clocks
143            restore their modes or are explicitly set, we will cause the "new" mode to be saved
144            back to the session XML ("extra") state.
145          */
146
147         AudioClock::ModeChanged.connect (mem_fun (*this, &ARDOUR_UI::store_clock_modes));
148
149         start_clocking ();
150         start_blinking ();
151
152         transport_stopped ();
153
154         second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_second), 1000);
155         point_one_second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_point_one_seconds), 100);
156         // point_oh_five_second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_point_oh_five_seconds), 50);
157         point_zero_one_second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_point_zero_one_seconds), 40);
158 }
159
160 int
161 ARDOUR_UI::unload_session ()
162 {
163         if (session && session->dirty()) {
164                 switch (ask_about_saving_session (_("close"))) {
165                 case -1:
166                         return 1;
167                         
168                 case 1:
169                         session->save_state ("");
170                         break;
171                 }
172         }
173         editor->hide ();
174         second_connection.disconnect ();
175         point_one_second_connection.disconnect ();
176         point_oh_five_second_connection.disconnect ();
177         point_zero_one_second_connection.disconnect();
178
179         ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
180         
181         rec_button.set_sensitive (false);
182         shuttle_box.set_sensitive (false);
183
184         stop_blinking ();
185         stop_clocking ();
186
187         /* drop everything attached to the blink signal */
188
189         Blink.clear ();
190
191         primary_clock.set_session (0);
192         secondary_clock.set_session (0);
193         big_clock.set_session (0);
194         preroll_clock.set_session (0);
195         postroll_clock.set_session (0);
196
197         if (option_editor) {
198                 option_editor->set_session (0);
199         }
200
201         if (mixer) {
202                 mixer->hide_all ();
203         }
204
205         delete session;
206         session = 0;
207
208         update_buffer_load ();
209
210         return 0;
211 }
212
213 int
214 ARDOUR_UI::create_connection_editor ()
215 {
216 #if 0
217         if (connection_editor == 0) {
218                 connection_editor = new ConnectionEditor ();
219                 connection_editor->signal_unmap().connect (sigc::bind (ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleConnections")));
220         }
221
222         if (session) {
223                 connection_editor->set_session (session);
224         }
225 #endif
226
227         return 0;
228 }
229
230 void
231 ARDOUR_UI::toggle_connection_editor ()
232 {
233         if (create_connection_editor()) {
234                 return;
235         }
236
237 #if 0
238         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleConnections"));
239         if (act) {
240                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
241         
242                 if (tact->get_active()) {
243                         connection_editor->show_all ();
244                         connection_editor->present ();
245                 } else {
246                         connection_editor->hide ();
247                 } 
248         }
249 #endif
250 }
251
252 void
253 ARDOUR_UI::toggle_big_clock_window ()
254 {
255         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBigClock"));
256         if (act) {
257                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
258         
259                 if (tact->get_active()) {
260                         big_clock_window->show_all ();
261                         big_clock_window->present ();
262                 } else {
263                         big_clock_window->hide ();
264                 } 
265         }
266 }
267
268 void
269 ARDOUR_UI::toggle_options_window ()
270 {
271         if (option_editor == 0) {
272                 option_editor = new OptionEditor (*this, *editor, *mixer);
273                 option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleOptionsEditor")));
274                 option_editor->set_session (session);
275         } 
276
277         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleOptionsEditor"));
278         if (act) {
279                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
280         
281                 if (tact->get_active()) {
282                         option_editor->show_all ();
283                         option_editor->present ();
284                 } else {
285                         option_editor->hide ();
286                 } 
287         }
288 }
289
290 int
291 ARDOUR_UI::create_location_ui ()
292 {
293         if (location_ui == 0) {
294                 location_ui = new LocationUI ();
295                 location_ui->set_session (session);
296                 location_ui->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleLocations")));
297         }
298         return 0;
299 }
300
301 void
302 ARDOUR_UI::toggle_location_window ()
303 {
304         if (create_location_ui()) {
305                 return;
306         }
307
308         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleLocations"));
309         if (act) {
310                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
311         
312                 if (tact->get_active()) {
313                         location_ui->show_all ();
314                         location_ui->present ();
315                 } else {
316                         location_ui->hide ();
317                 } 
318         }
319 }
320
321 void
322 ARDOUR_UI::toggle_color_manager ()
323 {
324         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleColorManager"));
325         if (act) {
326                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
327         
328                 if (tact->get_active()) {
329                         color_manager->show_all ();
330                         color_manager->present ();
331                 } else {
332                         color_manager->hide ();
333                 } 
334         }
335 }
336
337 int
338 ARDOUR_UI::create_route_params ()
339 {
340         if (route_params == 0) {
341                 route_params = new RouteParams_UI (*engine);
342                 route_params->set_session (session);
343                 route_params->signal_unmap().connect (sigc::bind(sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleInspector")));
344         }
345         return 0;
346 }
347
348 void
349 ARDOUR_UI::toggle_route_params_window ()
350 {
351         if (create_route_params ()) {
352                 return;
353         }
354
355         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleInspector"));
356         if (act) {
357                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
358         
359                 if (tact->get_active()) {
360                         route_params->show_all ();
361                         route_params->present ();
362                 } else {
363                         route_params->hide ();
364                 } 
365         }
366 }
367
368 void
369 ARDOUR_UI::handle_locations_change (Location* ignored)
370 {
371         if (session) {
372                 if (session->locations()->num_range_markers()) {
373                         ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
374                 } else {
375                         ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
376                 }
377         }
378 }