remove extraneous 'r' from rec-enable buttons
[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 #include "ardour/audioengine.h"
28
29 #include "actions.h"
30 #include "add_route_dialog.h"
31 #include "ardour_ui.h"
32 #include "bundle_manager.h"
33 #include "global_port_matrix.h"
34 #include "gui_object.h"
35 #include "gui_thread.h"
36 #include "keyeditor.h"
37 #include "location_ui.h"
38 #include "midi_tracer.h"
39 #include "mixer_ui.h"
40 #include "public_editor.h"
41 #include "rc_option_editor.h"
42 #include "route_params_ui.h"
43 #include "shuttle_control.h"
44 #include "session_option_editor.h"
45 #include "speaker_dialog.h"
46 #include "sfdb_ui.h"
47 #include "theme_manager.h"
48 #include "time_info_box.h"
49
50 #include "i18n.h"
51
52 using namespace ARDOUR;
53 using namespace PBD;
54 using namespace Glib;
55 using namespace Gtk;
56 using namespace Gtkmm2ext;
57
58 void
59 ARDOUR_UI::set_session (Session *s)
60 {
61         SessionHandlePtr::set_session (s);
62
63         if (!_session) {
64                 return;
65         }
66
67         const XMLNode* node = _session->extra_xml (X_("UI"));
68
69         if (node) {
70                 const XMLNodeList& children = node->children();
71                 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
72                         if ((*i)->name() == GUIObjectState::xml_node_name) {
73                                 gui_object_state->load (**i);
74                                 break;
75                         }
76                 }
77         }
78
79         if (location_ui->get()) {
80                 location_ui->get()->set_session(s);
81         }
82
83         if (speaker_config_window->get()) {
84                 speaker_config_window->get()->set_speakers (s->get_speakers());
85         }
86
87         if (route_params) {
88                 route_params->set_session (s);
89         }
90
91         if (add_route_dialog) {
92                 add_route_dialog->set_session (s);
93         }
94
95         if (session_option_editor) {
96                 session_option_editor->set_session (s);
97         }
98
99         if (shuttle_box) {
100                 shuttle_box->set_session (s);
101         }
102
103         for (ARDOUR::DataType::iterator i = ARDOUR::DataType::begin(); i != ARDOUR::DataType::end(); ++i) {
104                 if (_global_port_matrix[*i]->get()) {
105                         _global_port_matrix[*i]->get()->set_session (_session);
106                 }
107         }
108
109         primary_clock->set_session (s);
110         secondary_clock->set_session (s);
111         big_clock->set_session (s);
112         preroll_clock->set_session (s);
113         postroll_clock->set_session (s);
114         time_info_box->set_session (s);
115
116         /* sensitize menu bar options that are now valid */
117
118         ActionManager::set_sensitive (ActionManager::session_sensitive_actions, true);
119         ActionManager::set_sensitive (ActionManager::write_sensitive_actions, _session->writable());
120
121         if (_session->locations()->num_range_markers()) {
122                 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
123         } else {
124                 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
125         }
126
127         if (!_session->monitor_out()) {
128                 Glib::RefPtr<Action> act = ActionManager::get_action (X_("options"), X_("SoloViaBus"));
129                 if (act) {
130                         act->set_sensitive (false);
131                 }
132         }
133
134         /* allow wastebasket flush again */
135
136         Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
137         if (act) {
138                 act->set_sensitive (true);
139         }
140
141         /* there are never any selections on startup */
142
143         ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false);
144         ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, false);
145         ActionManager::set_sensitive (ActionManager::line_selection_sensitive_actions, false);
146         ActionManager::set_sensitive (ActionManager::point_selection_sensitive_actions, false);
147         ActionManager::set_sensitive (ActionManager::playlist_selection_sensitive_actions, false);
148
149         rec_button.set_sensitive (true);
150
151         solo_alert_button.set_active (_session->soloing());
152
153         setup_session_options ();
154
155         Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::transport_rec_enable_blink));
156         Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::solo_blink));
157         Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::sync_blink));
158         Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::audition_blink));
159
160         _session->RecordStateChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::record_state_changed, this), gui_context());
161         _session->StepEditStatusChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::step_edit_status_change, this, _1), gui_context());
162         _session->TransportStateChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::map_transport_state, this), gui_context());
163         _session->DirtyChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::update_autosave, this), gui_context());
164
165         _session->Xrun.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::xrun_handler, this, _1), gui_context());
166         _session->SoloActive.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::soloing_changed, this, _1), gui_context());
167         _session->AuditionActive.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::auditioning_changed, this, _1), gui_context());
168         _session->locations()->added.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
169         _session->locations()->removed.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
170         _session->config.ParameterChanged.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::session_parameter_changed, this, _1), gui_context ());
171
172 #ifdef HAVE_JACK_SESSION
173         engine->JackSessionEvent.connect (*_session, MISSING_INVALIDATOR, ui_bind (&Session::jack_session_event, _session, _1), gui_context());
174 #endif
175
176         /* Clocks are on by default after we are connected to a session, so show that here.
177         */
178
179         connect_dependents_to_session (s);
180
181         /* listen to clock mode changes. don't do this earlier because otherwise as the clocks
182            restore their modes or are explicitly set, we will cause the "new" mode to be saved
183            back to the session XML ("Extra") state.
184          */
185
186         AudioClock::ModeChanged.connect (sigc::mem_fun (*this, &ARDOUR_UI::store_clock_modes));
187
188         Glib::signal_idle().connect (sigc::mem_fun (*this, &ARDOUR_UI::first_idle));
189
190         start_clocking ();
191         start_blinking ();
192
193         map_transport_state ();
194
195         second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_second), 1000);
196         point_one_second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_one_seconds), 100);
197         point_zero_one_second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_zero_one_seconds), 40);
198
199         update_format ();
200 }
201
202 int
203 ARDOUR_UI::unload_session (bool hide_stuff)
204 {
205         if (_session && _session->dirty()) {
206                 std::vector<std::string> actions;
207                 actions.push_back (_("Don't close"));
208                 actions.push_back (_("Just close"));
209                 actions.push_back (_("Save and close"));
210                 switch (ask_about_saving_session (actions)) {
211                 case -1:
212                         // cancel
213                         return 1;
214
215                 case 1:
216                         _session->save_state ("");
217                         break;
218                 }
219         }
220
221         if (hide_stuff) {
222                 editor->hide ();
223                 mixer->hide ();
224                 theme_manager->hide ();
225         }
226
227         second_connection.disconnect ();
228         point_one_second_connection.disconnect ();
229         point_oh_five_second_connection.disconnect ();
230         point_zero_one_second_connection.disconnect();
231
232         ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
233
234         rec_button.set_sensitive (false);
235
236         stop_blinking ();
237         stop_clocking ();
238
239         /* drop everything attached to the blink signal */
240
241         Blink.clear ();
242
243         delete _session;
244         _session = 0;
245
246         update_buffer_load ();
247
248         return 0;
249 }
250
251 void
252 ARDOUR_UI::toggle_big_clock_window ()
253 {
254         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBigClock"));
255         if (act) {
256                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
257
258                 if (tact->get_active()) {
259                         big_clock_window->get()->show_all ();
260                         big_clock_window->get()->present ();
261                 } else {
262                         big_clock_window->get()->hide ();
263                 }
264         }
265 }
266
267 void
268 ARDOUR_UI::toggle_speaker_config_window ()
269 {
270         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("toggle-speaker-config"));
271         if (act) {
272                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
273
274                 if (tact->get_active()) {
275                         speaker_config_window->get()->show_all ();
276                         speaker_config_window->get()->present ();
277                 } else {
278                         speaker_config_window->get()->hide ();
279                 }
280         }
281 }
282
283 void
284 ARDOUR_UI::new_midi_tracer_window ()
285 {
286         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("NewMIDITracer"));
287         if (!act) {
288                 return;
289         }
290
291         std::list<MidiTracer*>::iterator i = _midi_tracer_windows.begin ();
292         while (i != _midi_tracer_windows.end() && (*i)->get_visible() == true) {
293                 ++i;
294         }
295
296         if (i == _midi_tracer_windows.end()) {
297                 /* all our MIDITracer windows are visible; make a new one */
298                 MidiTracer* t = new MidiTracer ();
299                 manage_window (*t);
300                 t->show_all ();
301                 _midi_tracer_windows.push_back (t);
302         } else {
303                 /* re-use the hidden one */
304                 (*i)->show_all ();
305         }
306 }
307
308 void
309 ARDOUR_UI::toggle_rc_options_window ()
310 {
311         if (rc_option_editor == 0) {
312                 rc_option_editor = new RCOptionEditor;
313                 rc_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleRCOptionsEditor")));
314                 rc_option_editor->set_session (_session);
315         }
316
317         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleRCOptionsEditor"));
318         if (act) {
319                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
320
321                 if (tact->get_active()) {
322                         rc_option_editor->show_all ();
323                         rc_option_editor->present ();
324                 } else {
325                         rc_option_editor->hide ();
326                 }
327         }
328 }
329
330 void
331 ARDOUR_UI::toggle_session_options_window ()
332 {
333         if (session_option_editor == 0) {
334                 session_option_editor = new SessionOptionEditor (_session);
335                 session_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleSessionOptionsEditor")));
336         }
337
338         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleSessionOptionsEditor"));
339         if (act) {
340                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
341
342                 if (tact->get_active()) {
343                         session_option_editor->show_all ();
344                         session_option_editor->present ();
345                 } else {
346                         session_option_editor->hide ();
347                 }
348         }
349 }
350
351 int
352 ARDOUR_UI::create_location_ui ()
353 {
354         if (location_ui->get() == 0) {
355                 location_ui->set (new LocationUIWindow ());
356                 location_ui->get()->set_session (_session);
357                 location_ui->get()->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleLocations")));
358         }
359         return 0;
360 }
361
362 void
363 ARDOUR_UI::toggle_location_window ()
364 {
365         if (create_location_ui()) {
366                 return;
367         }
368
369         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleLocations"));
370         if (act) {
371                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
372
373                 if (tact->get_active()) {
374                         location_ui->get()->show_all ();
375                         location_ui->get()->present ();
376                 } else {
377                         location_ui->get()->hide ();
378                 }
379         }
380 }
381
382 void
383 ARDOUR_UI::toggle_key_editor ()
384 {
385         if (key_editor == 0) {
386                 key_editor = new KeyEditor;
387                 key_editor->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleKeyEditor")));
388         }
389
390         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleKeyEditor"));
391         if (act) {
392                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
393
394                 if (tact->get_active()) {
395                         key_editor->show_all ();
396                         key_editor->present ();
397                 } else {
398                         key_editor->hide ();
399                 }
400         }
401 }
402
403 void
404 ARDOUR_UI::toggle_theme_manager ()
405 {
406         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleThemeManager"));
407         if (act) {
408                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
409
410                 if (tact->get_active()) {
411                         theme_manager->show_all ();
412                         theme_manager->present ();
413                 } else {
414                         theme_manager->hide ();
415                 }
416         }
417 }
418
419 void
420 ARDOUR_UI::create_bundle_manager ()
421 {
422         if (bundle_manager == 0) {
423                 bundle_manager = new BundleManager (_session);
424                 bundle_manager->signal_unmap().connect (sigc::bind (sigc::ptr_fun (&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleBundleManager")));
425         }
426 }
427
428 void
429 ARDOUR_UI::toggle_bundle_manager ()
430 {
431         create_bundle_manager ();
432
433         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBundleManager"));
434         if (act) {
435                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
436
437                 if (tact->get_active()) {
438                         bundle_manager->show_all ();
439                         bundle_manager->present ();
440                 } else {
441                         bundle_manager->hide ();
442                 }
443         }
444 }
445
446 int
447 ARDOUR_UI::create_route_params ()
448 {
449         if (route_params == 0) {
450                 route_params = new RouteParams_UI ();
451                 route_params->set_session (_session);
452                 route_params->signal_unmap().connect (sigc::bind(sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleInspector")));
453         }
454         return 0;
455 }
456
457 void
458 ARDOUR_UI::toggle_route_params_window ()
459 {
460         if (create_route_params ()) {
461                 return;
462         }
463
464         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleInspector"));
465         if (act) {
466                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
467
468                 if (tact->get_active()) {
469                         route_params->show_all ();
470                         route_params->present ();
471                 } else {
472                         route_params->hide ();
473                 }
474         }
475 }
476
477 void
478 ARDOUR_UI::handle_locations_change (Location *)
479 {
480         if (_session) {
481                 if (_session->locations()->num_range_markers()) {
482                         ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
483                 } else {
484                         ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
485                 }
486         }
487 }
488
489 bool
490 ARDOUR_UI::main_window_state_event_handler (GdkEventWindowState* ev, bool window_was_editor)
491 {
492         if (window_was_editor) {
493
494                 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
495                     (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
496                         float_big_clock (editor);
497                 }
498
499         } else {
500
501                 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
502                     (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
503                         float_big_clock (mixer);
504                 }
505         }
506
507         return false;
508 }