improvements (?) for window visibility during session loading - time to test on linux
[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
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         /* 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         }
183
184         second_connection.disconnect ();
185         point_one_second_connection.disconnect ();
186         point_oh_five_second_connection.disconnect ();
187         point_zero_one_second_connection.disconnect();
188
189         ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
190         
191         rec_button.set_sensitive (false);
192         shuttle_box.set_sensitive (false);
193
194         stop_blinking ();
195         stop_clocking ();
196
197         /* drop everything attached to the blink signal */
198
199         Blink.clear ();
200
201         primary_clock.set_session (0);
202         secondary_clock.set_session (0);
203         big_clock.set_session (0);
204         preroll_clock.set_session (0);
205         postroll_clock.set_session (0);
206
207         if (option_editor) {
208                 option_editor->set_session (0);
209         }
210
211         if (mixer) {
212                 mixer->hide_all ();
213         }
214
215         delete session;
216         session = 0;
217
218         update_buffer_load ();
219
220         return 0;
221 }
222
223 int
224 ARDOUR_UI::create_connection_editor ()
225 {
226 #if 0
227         if (connection_editor == 0) {
228                 connection_editor = new ConnectionEditor ();
229                 connection_editor->signal_unmap().connect (sigc::bind (ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleConnections")));
230         }
231
232         if (session) {
233                 connection_editor->set_session (session);
234         }
235 #endif
236
237         return 0;
238 }
239
240 void
241 ARDOUR_UI::toggle_connection_editor ()
242 {
243         if (create_connection_editor()) {
244                 return;
245         }
246
247 #if 0
248         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleConnections"));
249         if (act) {
250                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
251         
252                 if (tact->get_active()) {
253                         connection_editor->show_all ();
254                         connection_editor->present ();
255                 } else {
256                         connection_editor->hide ();
257                 } 
258         }
259 #endif
260 }
261
262 void
263 ARDOUR_UI::toggle_big_clock_window ()
264 {
265         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBigClock"));
266         if (act) {
267                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
268         
269                 if (tact->get_active()) {
270                         big_clock_window->show_all ();
271                         big_clock_window->present ();
272                 } else {
273                         big_clock_window->hide ();
274                 } 
275         }
276 }
277
278 void
279 ARDOUR_UI::toggle_options_window ()
280 {
281         if (option_editor == 0) {
282                 option_editor = new OptionEditor (*this, *editor, *mixer);
283                 option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleOptionsEditor")));
284                 option_editor->set_session (session);
285         } 
286
287         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleOptionsEditor"));
288         if (act) {
289                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
290         
291                 if (tact->get_active()) {
292                         option_editor->show_all ();
293                         option_editor->present ();
294                 } else {
295                         option_editor->hide ();
296                 } 
297         }
298 }
299
300 int
301 ARDOUR_UI::create_location_ui ()
302 {
303         if (location_ui == 0) {
304                 location_ui = new LocationUI ();
305                 location_ui->set_session (session);
306                 location_ui->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleLocations")));
307         }
308         return 0;
309 }
310
311 void
312 ARDOUR_UI::toggle_location_window ()
313 {
314         if (create_location_ui()) {
315                 return;
316         }
317
318         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleLocations"));
319         if (act) {
320                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
321         
322                 if (tact->get_active()) {
323                         location_ui->show_all ();
324                         location_ui->present ();
325                 } else {
326                         location_ui->hide ();
327                 } 
328         }
329 }
330
331 void
332 ARDOUR_UI::toggle_theme_manager ()
333 {
334         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleThemeManager"));
335         if (act) {
336                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
337         
338                 if (tact->get_active()) {
339                         theme_manager->show_all ();
340                         theme_manager->present ();
341                 } else {
342                         theme_manager->hide ();
343                 } 
344         }
345 }
346
347 int
348 ARDOUR_UI::create_route_params ()
349 {
350         if (route_params == 0) {
351                 route_params = new RouteParams_UI ();
352                 route_params->set_session (session);
353                 route_params->signal_unmap().connect (sigc::bind(sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleInspector")));
354         }
355         return 0;
356 }
357
358 void
359 ARDOUR_UI::toggle_route_params_window ()
360 {
361         if (create_route_params ()) {
362                 return;
363         }
364
365         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleInspector"));
366         if (act) {
367                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
368         
369                 if (tact->get_active()) {
370                         route_params->show_all ();
371                         route_params->present ();
372                 } else {
373                         route_params->hide ();
374                 } 
375         }
376 }
377
378 void
379 ARDOUR_UI::handle_locations_change (Location* ignored)
380 {
381         if (session) {
382                 if (session->locations()->num_range_markers()) {
383                         ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
384                 } else {
385                         ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
386                 }
387         }
388 }