Dave Camerons fix for bug 2108, slightly modified
[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 "theme_manager.h"
38 #include "keyeditor.h"
39
40 #include "i18n.h"
41
42 using namespace ARDOUR;
43 using namespace PBD;
44 using namespace Glib;
45 using namespace Gtk;
46 using namespace Gtkmm2ext;
47
48 void
49 ARDOUR_UI::connect_to_session (Session *s)
50 {
51         session = s;
52
53         session->Xrun.connect (mem_fun(*this, &ARDOUR_UI::xrun_handler));
54         session->RecordStateChanged.connect (mem_fun (*this, &ARDOUR_UI::record_state_changed));
55
56         /* sensitize menu bar options that are now valid */
57
58         ActionManager::set_sensitive (ActionManager::session_sensitive_actions, true);
59         
60         if (session->locations()->num_range_markers()) {
61                 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
62         } else {
63                 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
64         }
65
66         if (!session->control_out()) {
67                 Glib::RefPtr<Action> act = ActionManager::get_action (X_("options"), X_("SoloViaBus"));
68                 if (act) {
69                         act->set_sensitive (false);
70                 }
71         }
72
73         /* allow wastebasket flush again */
74
75         Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
76         if (act) {
77                 act->set_sensitive (true);
78         }
79
80         /* there are never any selections on startup */
81
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         /* update autochange callback on dirty state changing */
130
131         session->DirtyChanged.connect (mem_fun(*this, &ARDOUR_UI::update_autosave));
132
133         /* can't be auditioning here */
134
135         primary_clock.set_session (s);
136         secondary_clock.set_session (s);
137         big_clock.set_session (s);
138         preroll_clock.set_session (s);
139         postroll_clock.set_session (s);
140
141         /* Clocks are on by default after we are connected to a session, so show that here.
142         */
143         
144         connect_dependents_to_session (s);
145
146         /* listen to clock mode changes. don't do this earlier because otherwise as the clocks
147            restore their modes or are explicitly set, we will cause the "new" mode to be saved
148            back to the session XML ("extra") state.
149          */
150
151         AudioClock::ModeChanged.connect (mem_fun (*this, &ARDOUR_UI::store_clock_modes));
152
153         Glib::signal_idle().connect (mem_fun (*this, &ARDOUR_UI::first_idle));
154
155         start_clocking ();
156         start_blinking ();
157
158         transport_stopped ();
159
160         second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_second), 1000);
161         point_one_second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_point_one_seconds), 100);
162         point_zero_one_second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_point_zero_one_seconds), 40);
163 }
164
165 int
166 ARDOUR_UI::unload_session (bool hide_stuff)
167 {
168         if (session && session->dirty()) {
169                 switch (ask_about_saving_session (_("close"))) {
170                 case -1:
171                         return 1;
172                         
173                 case 1:
174                         session->save_state ("");
175                         break;
176                 }
177         }
178
179         if (hide_stuff) {
180                 editor->hide ();
181                 mixer->hide ();
182                 theme_manager->hide ();
183         }
184
185         second_connection.disconnect ();
186         point_one_second_connection.disconnect ();
187         point_oh_five_second_connection.disconnect ();
188         point_zero_one_second_connection.disconnect();
189
190         ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
191         
192         rec_button.set_sensitive (false);
193         shuttle_box.set_sensitive (false);
194
195         stop_blinking ();
196         stop_clocking ();
197
198         /* drop everything attached to the blink signal */
199
200         Blink.clear ();
201
202         primary_clock.set_session (0);
203         secondary_clock.set_session (0);
204         big_clock.set_session (0);
205         preroll_clock.set_session (0);
206         postroll_clock.set_session (0);
207
208         if (option_editor) {
209                 option_editor->set_session (0);
210         }
211
212         if (mixer) {
213                 mixer->hide_all ();
214         }
215
216         delete session;
217         session = 0;
218
219         update_buffer_load ();
220
221         return 0;
222 }
223
224 int
225 ARDOUR_UI::create_connection_editor ()
226 {
227 #if 0
228         if (connection_editor == 0) {
229                 connection_editor = new ConnectionEditor ();
230                 connection_editor->signal_unmap().connect (sigc::bind (ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleConnections")));
231         }
232
233         if (session) {
234                 connection_editor->set_session (session);
235         }
236 #endif
237
238         return 0;
239 }
240
241 void
242 ARDOUR_UI::toggle_connection_editor ()
243 {
244         if (create_connection_editor()) {
245                 return;
246         }
247
248 #if 0
249         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleConnections"));
250         if (act) {
251                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
252         
253                 if (tact->get_active()) {
254                         connection_editor->show_all ();
255                         connection_editor->present ();
256                 } else {
257                         connection_editor->hide ();
258                 } 
259         }
260 #endif
261 }
262
263 void
264 ARDOUR_UI::toggle_big_clock_window ()
265 {
266         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBigClock"));
267         if (act) {
268                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
269         
270                 if (tact->get_active()) {
271                         big_clock_window->show_all ();
272                         big_clock_window->present ();
273                 } else {
274                         big_clock_window->hide ();
275                 } 
276         }
277 }
278
279 void
280 ARDOUR_UI::toggle_options_window ()
281 {
282         if (option_editor == 0) {
283                 option_editor = new OptionEditor (*this, *editor, *mixer);
284                 option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleOptionsEditor")));
285                 option_editor->set_session (session);
286         } 
287
288         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleOptionsEditor"));
289         if (act) {
290                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
291         
292                 if (tact->get_active()) {
293                         option_editor->show_all ();
294                         option_editor->present ();
295                 } else {
296                         option_editor->hide ();
297                 } 
298         }
299 }
300
301 int
302 ARDOUR_UI::create_location_ui ()
303 {
304         if (location_ui == 0) {
305                 location_ui = new LocationUI ();
306                 location_ui->set_session (session);
307                 location_ui->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleLocations")));
308         }
309         return 0;
310 }
311
312 void
313 ARDOUR_UI::toggle_location_window ()
314 {
315         if (create_location_ui()) {
316                 return;
317         }
318
319         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleLocations"));
320         if (act) {
321                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
322         
323                 if (tact->get_active()) {
324                         location_ui->show_all ();
325                         location_ui->present ();
326                 } else {
327                         location_ui->hide ();
328                 } 
329         }
330 }
331
332 void
333 ARDOUR_UI::toggle_key_editor ()
334 {
335         if (key_editor == 0) {
336                 key_editor = new KeyEditor;
337                 key_editor->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleKeyEditor")));  
338         }
339
340         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleKeyEditor"));
341         if (act) {
342                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
343         
344                 if (tact->get_active()) {
345                         key_editor->show_all ();
346                         key_editor->present ();
347                 } else {
348                         key_editor->hide ();
349                 } 
350         }
351 }
352
353 void
354 ARDOUR_UI::toggle_theme_manager ()
355 {
356         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleThemeManager"));
357         if (act) {
358                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
359         
360                 if (tact->get_active()) {
361                         theme_manager->show_all ();
362                         theme_manager->present ();
363                 } else {
364                         theme_manager->hide ();
365                 } 
366         }
367 }
368
369 int
370 ARDOUR_UI::create_route_params ()
371 {
372         if (route_params == 0) {
373                 route_params = new RouteParams_UI ();
374                 route_params->set_session (session);
375                 route_params->signal_unmap().connect (sigc::bind(sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleInspector")));
376         }
377         return 0;
378 }
379
380 void
381 ARDOUR_UI::toggle_route_params_window ()
382 {
383         if (create_route_params ()) {
384                 return;
385         }
386
387         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleInspector"));
388         if (act) {
389                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
390         
391                 if (tact->get_active()) {
392                         route_params->show_all ();
393                         route_params->present ();
394                 } else {
395                         route_params->hide ();
396                 } 
397         }
398 }
399
400 void
401 ARDOUR_UI::handle_locations_change (Location* ignored)
402 {
403         if (session) {
404                 if (session->locations()->num_range_markers()) {
405                         ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
406                 } else {
407                         ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
408                 }
409         }
410 }