91ff10d4730aa6c76c2ab0a69f56d3ffc88a5e5c
[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 "location_ui.h"
31 #include "mixer_ui.h"
32 #include "rc_option_editor.h"
33 #include "session_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 "bundle_manager.h"
39 #include "keyeditor.h"
40
41 #include "i18n.h"
42
43 using namespace ARDOUR;
44 using namespace PBD;
45 using namespace Glib;
46 using namespace Gtk;
47 using namespace Gtkmm2ext;
48
49 void
50 ARDOUR_UI::connect_to_session (Session *s)
51 {
52         session = s;
53
54         session->Xrun.connect (mem_fun(*this, &ARDOUR_UI::xrun_handler));
55         session->RecordStateChanged.connect (mem_fun (*this, &ARDOUR_UI::record_state_changed));
56
57         /* sensitize menu bar options that are now valid */
58
59         ActionManager::set_sensitive (ActionManager::session_sensitive_actions, true);
60         
61         if (session->locations()->num_range_markers()) {
62                 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
63         } else {
64                 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
65         }
66
67         if (!session->control_out()) {
68                 Glib::RefPtr<Action> act = ActionManager::get_action (X_("options"), X_("SoloViaBus"));
69                 if (act) {
70                         act->set_sensitive (false);
71                 }
72         }
73
74         /* allow wastebasket flush again */
75
76         Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
77         if (act) {
78                 act->set_sensitive (true);
79         }
80
81         /* there are never any selections on startup */
82
83         ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false);
84         ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, false);
85         ActionManager::set_sensitive (ActionManager::line_selection_sensitive_actions, false);
86         ActionManager::set_sensitive (ActionManager::point_selection_sensitive_actions, false);
87         ActionManager::set_sensitive (ActionManager::playlist_selection_sensitive_actions, false);
88
89         session->locations()->added.connect (mem_fun (*this, &ARDOUR_UI::handle_locations_change));
90         session->locations()->removed.connect (mem_fun (*this, &ARDOUR_UI::handle_locations_change));
91
92         rec_button.set_sensitive (true);
93         shuttle_box.set_sensitive (true);
94         
95         if (location_ui) {
96                 location_ui->set_session(s);
97         }
98
99         if (route_params) {
100                 route_params->set_session (s);
101         }
102
103         setup_session_options ();
104
105         Blink.connect (mem_fun(*this, &ARDOUR_UI::transport_rec_enable_blink));
106         Blink.connect (mem_fun(*this, &ARDOUR_UI::solo_blink));
107         Blink.connect (mem_fun(*this, &ARDOUR_UI::audition_blink));
108
109         /* these are all need to be handled in an RT-safe and MT way, so don't
110            do any GUI work, just queue it for handling by the GUI thread.
111         */
112
113         session->TransportStateChange.connect (mem_fun(*this, &ARDOUR_UI::queue_transport_change));
114
115         /* alert the user to these things happening */
116
117         session->AuditionActive.connect (mem_fun(*this, &ARDOUR_UI::auditioning_changed));
118         session->SoloActive.connect (mem_fun(*this, &ARDOUR_UI::soloing_changed));
119
120         solo_alert_button.set_active (session->soloing());
121
122         /* update autochange callback on dirty state changing */
123
124         session->DirtyChanged.connect (mem_fun(*this, &ARDOUR_UI::update_autosave));
125
126         /* can't be auditioning here */
127
128         primary_clock.set_session (s);
129         secondary_clock.set_session (s);
130         big_clock.set_session (s);
131         preroll_clock.set_session (s);
132         postroll_clock.set_session (s);
133
134         /* Clocks are on by default after we are connected to a session, so show that here.
135         */
136         
137         connect_dependents_to_session (s);
138
139         /* listen to clock mode changes. don't do this earlier because otherwise as the clocks
140            restore their modes or are explicitly set, we will cause the "new" mode to be saved
141            back to the session XML ("Extra") state.
142          */
143
144         AudioClock::ModeChanged.connect (mem_fun (*this, &ARDOUR_UI::store_clock_modes));
145
146         Glib::signal_idle().connect (mem_fun (*this, &ARDOUR_UI::first_idle));
147
148         start_clocking ();
149         start_blinking ();
150
151         transport_stopped ();
152
153         second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_second), 1000);
154         point_one_second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_point_one_seconds), 100);
155         point_zero_one_second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_point_zero_one_seconds), 40);
156 }
157
158 int
159 ARDOUR_UI::unload_session (bool hide_stuff)
160 {
161         if (session && session->dirty()) {
162                 switch (ask_about_saving_session (_("close"))) {
163                 case -1:
164                         // cancel
165                         return 1;
166                         
167                 case 1:
168                         session->save_state ("");
169                         break;
170                 }
171         }
172
173         if (hide_stuff) {
174                 editor->hide ();
175                 mixer->hide ();
176                 theme_manager->hide ();
177         }
178
179         second_connection.disconnect ();
180         point_one_second_connection.disconnect ();
181         point_oh_five_second_connection.disconnect ();
182         point_zero_one_second_connection.disconnect();
183
184         ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
185         
186         rec_button.set_sensitive (false);
187         shuttle_box.set_sensitive (false);
188
189         stop_blinking ();
190         stop_clocking ();
191
192         /* drop everything attached to the blink signal */
193
194         Blink.clear ();
195
196         primary_clock.set_session (0);
197         secondary_clock.set_session (0);
198         big_clock.set_session (0);
199         preroll_clock.set_session (0);
200         postroll_clock.set_session (0);
201
202         delete session;
203         session = 0;
204
205         update_buffer_load ();
206
207         return 0;
208 }
209
210 void
211 ARDOUR_UI::toggle_big_clock_window ()
212 {
213         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBigClock"));
214         if (act) {
215                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
216         
217                 if (tact->get_active()) {
218                         big_clock_window->show_all ();
219                         big_clock_window->present ();
220                 } else {
221                         big_clock_window->hide ();
222                 } 
223         }
224 }
225
226 void
227 ARDOUR_UI::toggle_rc_options_window ()
228 {
229         if (rc_option_editor == 0) {
230                 rc_option_editor = new RCOptionEditor;
231                 rc_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleRCOptionsEditor")));
232                 rc_option_editor->set_session (session);
233         } 
234
235         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleRCOptionsEditor"));
236         if (act) {
237                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
238         
239                 if (tact->get_active()) {
240                         rc_option_editor->show_all ();
241                         rc_option_editor->present ();
242                 } else {
243                         rc_option_editor->hide ();
244                 } 
245         }
246 }
247
248 void
249 ARDOUR_UI::toggle_session_options_window ()
250 {
251         if (session_option_editor == 0) {
252                 session_option_editor = new SessionOptionEditor (session);
253                 session_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleSessionOptionsEditor")));
254         } 
255
256         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleSessionOptionsEditor"));
257         if (act) {
258                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
259         
260                 if (tact->get_active()) {
261                         session_option_editor->show_all ();
262                         session_option_editor->present ();
263                 } else {
264                         session_option_editor->hide ();
265                 } 
266         }
267 }
268
269 int
270 ARDOUR_UI::create_location_ui ()
271 {
272         if (location_ui == 0) {
273                 location_ui = new LocationUI ();
274                 location_ui->set_session (session);
275                 location_ui->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleLocations")));
276         }
277         return 0;
278 }
279
280 void
281 ARDOUR_UI::toggle_location_window ()
282 {
283         if (create_location_ui()) {
284                 return;
285         }
286
287         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleLocations"));
288         if (act) {
289                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
290         
291                 if (tact->get_active()) {
292                         location_ui->show_all ();
293                         location_ui->present ();
294                 } else {
295                         location_ui->hide ();
296                 } 
297         }
298 }
299
300 void
301 ARDOUR_UI::toggle_key_editor ()
302 {
303         if (key_editor == 0) {
304                 key_editor = new KeyEditor;
305                 key_editor->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleKeyEditor")));  
306         }
307
308         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleKeyEditor"));
309         if (act) {
310                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
311         
312                 if (tact->get_active()) {
313                         key_editor->show_all ();
314                         key_editor->present ();
315                 } else {
316                         key_editor->hide ();
317                 } 
318         }
319 }
320
321 void
322 ARDOUR_UI::toggle_theme_manager ()
323 {
324         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleThemeManager"));
325         if (act) {
326                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
327         
328                 if (tact->get_active()) {
329                         theme_manager->show_all ();
330                         theme_manager->present ();
331                 } else {
332                         theme_manager->hide ();
333                 } 
334         }
335 }
336
337 void
338 ARDOUR_UI::create_bundle_manager ()
339 {
340         if (bundle_manager == 0) {
341                 bundle_manager = new BundleManager (*session);
342                 bundle_manager->signal_unmap().connect (sigc::bind (sigc::ptr_fun (&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleBundleManager")));
343         }
344 }
345
346 void
347 ARDOUR_UI::toggle_bundle_manager ()
348 {
349         create_bundle_manager ();
350         
351         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBundleManager"));
352         if (act) {
353                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
354         
355                 if (tact->get_active()) {
356                         bundle_manager->show_all ();
357                         bundle_manager->present ();
358                 } else {
359                         bundle_manager->hide ();
360                 } 
361         }
362 }
363
364 int
365 ARDOUR_UI::create_route_params ()
366 {
367         if (route_params == 0) {
368                 route_params = new RouteParams_UI ();
369                 route_params->set_session (session);
370                 route_params->signal_unmap().connect (sigc::bind(sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleInspector")));
371         }
372         return 0;
373 }
374
375 void
376 ARDOUR_UI::toggle_route_params_window ()
377 {
378         if (create_route_params ()) {
379                 return;
380         }
381
382         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleInspector"));
383         if (act) {
384                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
385         
386                 if (tact->get_active()) {
387                         route_params->show_all ();
388                         route_params->present ();
389                 } else {
390                         route_params->hide ();
391                 } 
392         }
393 }
394
395 void
396 ARDOUR_UI::handle_locations_change (Location *)
397 {
398         if (session) {
399                 if (session->locations()->num_range_markers()) {
400                         ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
401                 } else {
402                         ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
403                 }
404         }
405 }
406
407 bool
408 ARDOUR_UI::main_window_state_event_handler (GdkEventWindowState* ev, bool window_was_editor)
409 {
410         if (window_was_editor) {
411
412                 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) && 
413                     (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
414                         float_big_clock (editor);
415                 }
416
417         } else {
418
419                 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) && 
420                     (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
421                         float_big_clock (mixer);
422                 }
423         }
424
425         return false;
426 }