fix crash with a new session
[ardour2.git] / gtk2_ardour / ardour_ui_dialogs.cc
blobe3cb0c7e1a989171eb408495d28d0d70dde76e93
1 /*
2 Copyright (C) 2000 Paul Davis
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.
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.
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.
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.
26 #include "ardour/session.h"
27 #include "ardour/audioengine.h"
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"
50 #include "i18n.h"
52 using namespace ARDOUR;
53 using namespace PBD;
54 using namespace Glib;
55 using namespace Gtk;
56 using namespace Gtkmm2ext;
58 void
59 ARDOUR_UI::set_session (Session *s)
61 SessionHandlePtr::set_session (s);
63 if (!_session) {
64 return;
67 const XMLNode* node = _session->extra_xml (X_("UI"));
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;
79 if (location_ui->get()) {
80 location_ui->get()->set_session(s);
83 if (speaker_config_window->get()) {
84 speaker_config_window->get()->set_speakers (s->get_speakers());
87 if (route_params) {
88 route_params->set_session (s);
91 if (add_route_dialog) {
92 add_route_dialog->set_session (s);
95 if (session_option_editor) {
96 session_option_editor->set_session (s);
99 if (shuttle_box) {
100 shuttle_box->set_session (s);
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);
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);
116 /* sensitize menu bar options that are now valid */
118 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, true);
119 ActionManager::set_sensitive (ActionManager::write_sensitive_actions, _session->writable());
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);
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);
134 /* allow wastebasket flush again */
136 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
137 if (act) {
138 act->set_sensitive (true);
141 /* there are never any selections on startup */
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);
149 rec_button.set_sensitive (true);
151 solo_alert_button.set_active (_session->soloing());
153 setup_session_options ();
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));
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());
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 ());
172 #ifdef HAVE_JACK_SESSION
173 engine->JackSessionEvent.connect (*_session, MISSING_INVALIDATOR, ui_bind (&Session::jack_session_event, _session, _1), gui_context());
174 #endif
176 /* Clocks are on by default after we are connected to a session, so show that here.
179 connect_dependents_to_session (s);
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.
186 AudioClock::ModeChanged.connect (sigc::mem_fun (*this, &ARDOUR_UI::store_clock_modes));
188 Glib::signal_idle().connect (sigc::mem_fun (*this, &ARDOUR_UI::first_idle));
190 start_clocking ();
191 start_blinking ();
193 map_transport_state ();
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);
199 update_format ();
203 ARDOUR_UI::unload_session (bool hide_stuff)
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;
215 case 1:
216 _session->save_state ("");
217 break;
221 if (hide_stuff) {
222 editor->hide ();
223 mixer->hide ();
224 theme_manager->hide ();
227 second_connection.disconnect ();
228 point_one_second_connection.disconnect ();
229 point_oh_five_second_connection.disconnect ();
230 point_zero_one_second_connection.disconnect();
232 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
234 rec_button.set_sensitive (false);
236 stop_blinking ();
237 stop_clocking ();
239 /* drop everything attached to the blink signal */
241 Blink.clear ();
243 delete _session;
245 update_buffer_load ();
247 return 0;
250 void
251 ARDOUR_UI::toggle_big_clock_window ()
253 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBigClock"));
254 if (act) {
255 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
257 if (tact->get_active()) {
258 big_clock_window->get()->show_all ();
259 big_clock_window->get()->present ();
260 } else {
261 big_clock_window->get()->hide ();
266 void
267 ARDOUR_UI::toggle_speaker_config_window ()
269 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("toggle-speaker-config"));
270 if (act) {
271 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
273 if (tact->get_active()) {
274 speaker_config_window->get()->show_all ();
275 speaker_config_window->get()->present ();
276 } else {
277 speaker_config_window->get()->hide ();
282 void
283 ARDOUR_UI::new_midi_tracer_window ()
285 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("NewMIDITracer"));
286 if (!act) {
287 return;
290 std::list<MidiTracer*>::iterator i = _midi_tracer_windows.begin ();
291 while (i != _midi_tracer_windows.end() && (*i)->get_visible() == true) {
292 ++i;
295 if (i == _midi_tracer_windows.end()) {
296 /* all our MIDITracer windows are visible; make a new one */
297 MidiTracer* t = new MidiTracer ();
298 manage_window (*t);
299 t->show_all ();
300 _midi_tracer_windows.push_back (t);
301 } else {
302 /* re-use the hidden one */
303 (*i)->show_all ();
307 void
308 ARDOUR_UI::toggle_rc_options_window ()
310 if (rc_option_editor == 0) {
311 rc_option_editor = new RCOptionEditor;
312 rc_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleRCOptionsEditor")));
313 rc_option_editor->set_session (_session);
316 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleRCOptionsEditor"));
317 if (act) {
318 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
320 if (tact->get_active()) {
321 rc_option_editor->show_all ();
322 rc_option_editor->present ();
323 } else {
324 rc_option_editor->hide ();
329 void
330 ARDOUR_UI::toggle_session_options_window ()
332 if (session_option_editor == 0) {
333 session_option_editor = new SessionOptionEditor (_session);
334 session_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleSessionOptionsEditor")));
337 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleSessionOptionsEditor"));
338 if (act) {
339 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
341 if (tact->get_active()) {
342 session_option_editor->show_all ();
343 session_option_editor->present ();
344 } else {
345 session_option_editor->hide ();
351 ARDOUR_UI::create_location_ui ()
353 if (location_ui->get() == 0) {
354 location_ui->set (new LocationUIWindow ());
355 location_ui->get()->set_session (_session);
356 location_ui->get()->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleLocations")));
358 return 0;
361 void
362 ARDOUR_UI::toggle_location_window ()
364 if (create_location_ui()) {
365 return;
368 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleLocations"));
369 if (act) {
370 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
372 if (tact->get_active()) {
373 location_ui->get()->show_all ();
374 location_ui->get()->present ();
375 } else {
376 location_ui->get()->hide ();
381 void
382 ARDOUR_UI::toggle_key_editor ()
384 if (key_editor == 0) {
385 key_editor = new KeyEditor;
386 key_editor->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleKeyEditor")));
389 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleKeyEditor"));
390 if (act) {
391 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
393 if (tact->get_active()) {
394 key_editor->show_all ();
395 key_editor->present ();
396 } else {
397 key_editor->hide ();
402 void
403 ARDOUR_UI::toggle_theme_manager ()
405 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleThemeManager"));
406 if (act) {
407 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
409 if (tact->get_active()) {
410 theme_manager->show_all ();
411 theme_manager->present ();
412 } else {
413 theme_manager->hide ();
418 void
419 ARDOUR_UI::create_bundle_manager ()
421 if (bundle_manager == 0) {
422 bundle_manager = new BundleManager (_session);
423 bundle_manager->signal_unmap().connect (sigc::bind (sigc::ptr_fun (&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleBundleManager")));
427 void
428 ARDOUR_UI::toggle_bundle_manager ()
430 create_bundle_manager ();
432 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBundleManager"));
433 if (act) {
434 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
436 if (tact->get_active()) {
437 bundle_manager->show_all ();
438 bundle_manager->present ();
439 } else {
440 bundle_manager->hide ();
446 ARDOUR_UI::create_route_params ()
448 if (route_params == 0) {
449 route_params = new RouteParams_UI ();
450 route_params->set_session (_session);
451 route_params->signal_unmap().connect (sigc::bind(sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleInspector")));
453 return 0;
456 void
457 ARDOUR_UI::toggle_route_params_window ()
459 if (create_route_params ()) {
460 return;
463 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleInspector"));
464 if (act) {
465 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
467 if (tact->get_active()) {
468 route_params->show_all ();
469 route_params->present ();
470 } else {
471 route_params->hide ();
476 void
477 ARDOUR_UI::handle_locations_change (Location *)
479 if (_session) {
480 if (_session->locations()->num_range_markers()) {
481 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
482 } else {
483 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
488 bool
489 ARDOUR_UI::main_window_state_event_handler (GdkEventWindowState* ev, bool window_was_editor)
491 if (window_was_editor) {
493 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
494 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
495 float_big_clock (editor);
498 } else {
500 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
501 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
502 float_big_clock (mixer);
506 return false;