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"
28 #include "ardour/automation_watch.h"
31 #include "add_route_dialog.h"
32 #include "ardour_ui.h"
33 #include "bundle_manager.h"
34 #include "global_port_matrix.h"
35 #include "gui_object.h"
36 #include "gui_thread.h"
37 #include "keyeditor.h"
38 #include "location_ui.h"
39 #include "main_clock.h"
40 #include "midi_tracer.h"
42 #include "public_editor.h"
43 #include "rc_option_editor.h"
44 #include "route_params_ui.h"
45 #include "shuttle_control.h"
46 #include "session_option_editor.h"
47 #include "speaker_dialog.h"
49 #include "theme_manager.h"
50 #include "time_info_box.h"
54 using namespace ARDOUR;
58 using namespace Gtkmm2ext;
61 ARDOUR_UI::set_session (Session *s)
63 SessionHandlePtr::set_session (s);
69 const XMLNode* node = _session->extra_xml (X_("UI"));
72 const XMLNodeList& children = node->children();
73 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
74 if ((*i)->name() == GUIObjectState::xml_node_name) {
75 gui_object_state->load (**i);
81 AutomationWatch::instance().set_session (s);
83 if (location_ui->get()) {
84 location_ui->get()->set_session(s);
87 if (speaker_config_window->get()) {
88 speaker_config_window->get()->set_speakers (s->get_speakers());
92 route_params->set_session (s);
95 if (add_route_dialog) {
96 add_route_dialog->set_session (s);
99 if (session_option_editor) {
100 session_option_editor->set_session (s);
104 shuttle_box->set_session (s);
107 for (ARDOUR::DataType::iterator i = ARDOUR::DataType::begin(); i != ARDOUR::DataType::end(); ++i) {
108 if (_global_port_matrix[*i]->get()) {
109 _global_port_matrix[*i]->get()->set_session (_session);
113 primary_clock->set_session (s);
114 secondary_clock->set_session (s);
115 big_clock->set_session (s);
116 time_info_box->set_session (s);
118 /* sensitize menu bar options that are now valid */
120 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, true);
121 ActionManager::set_sensitive (ActionManager::write_sensitive_actions, _session->writable());
123 if (_session->locations()->num_range_markers()) {
124 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
126 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
129 if (!_session->monitor_out()) {
130 Glib::RefPtr<Action> act = ActionManager::get_action (X_("options"), X_("SoloViaBus"));
132 act->set_sensitive (false);
136 /* allow wastebasket flush again */
138 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
140 act->set_sensitive (true);
143 /* there are never any selections on startup */
145 ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false);
146 ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, false);
147 ActionManager::set_sensitive (ActionManager::line_selection_sensitive_actions, false);
148 ActionManager::set_sensitive (ActionManager::point_selection_sensitive_actions, false);
149 ActionManager::set_sensitive (ActionManager::playlist_selection_sensitive_actions, false);
151 rec_button.set_sensitive (true);
153 solo_alert_button.set_active (_session->soloing());
155 setup_session_options ();
157 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::transport_rec_enable_blink));
158 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::solo_blink));
159 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::sync_blink));
160 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::audition_blink));
161 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::feedback_blink));
163 _session->RecordStateChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::record_state_changed, this), gui_context());
164 _session->StepEditStatusChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::step_edit_status_change, this, _1), gui_context());
165 _session->TransportStateChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::map_transport_state, this), gui_context());
166 _session->DirtyChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::update_autosave, this), gui_context());
168 _session->Xrun.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::xrun_handler, this, _1), gui_context());
169 _session->SoloActive.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::soloing_changed, this, _1), gui_context());
170 _session->AuditionActive.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::auditioning_changed, this, _1), gui_context());
171 _session->locations()->added.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
172 _session->locations()->removed.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
173 _session->config.ParameterChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_parameter_changed, this, _1), gui_context ());
175 #ifdef HAVE_JACK_SESSION
176 engine->JackSessionEvent.connect (*_session, MISSING_INVALIDATOR, boost::bind (&Session::jack_session_event, _session, _1), gui_context());
179 /* Clocks are on by default after we are connected to a session, so show that here.
182 connect_dependents_to_session (s);
184 /* listen to clock mode changes. don't do this earlier because otherwise as the clocks
185 restore their modes or are explicitly set, we will cause the "new" mode to be saved
186 back to the session XML ("Extra") state.
189 AudioClock::ModeChanged.connect (sigc::mem_fun (*this, &ARDOUR_UI::store_clock_modes));
191 Glib::signal_idle().connect (sigc::mem_fun (*this, &ARDOUR_UI::first_idle));
196 map_transport_state ();
198 second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_second), 1000);
199 point_one_second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_one_seconds), 100);
200 point_zero_one_second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_zero_one_seconds), 40);
206 ARDOUR_UI::unload_session (bool hide_stuff)
208 if (_session && _session->dirty()) {
209 std::vector<std::string> actions;
210 actions.push_back (_("Don't close"));
211 actions.push_back (_("Just close"));
212 actions.push_back (_("Save and close"));
213 switch (ask_about_saving_session (actions)) {
219 _session->save_state ("");
227 theme_manager->hide ();
230 second_connection.disconnect ();
231 point_one_second_connection.disconnect ();
232 point_oh_five_second_connection.disconnect ();
233 point_zero_one_second_connection.disconnect();
235 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
237 rec_button.set_sensitive (false);
242 /* drop everything attached to the blink signal */
249 session_loaded = false;
251 update_buffer_load ();
257 ARDOUR_UI::toggle_big_clock_window ()
259 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBigClock"));
261 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
263 if (tact->get_active()) {
264 big_clock_window->get()->show_all ();
265 big_clock_window->get()->present ();
267 big_clock_window->get()->hide ();
273 ARDOUR_UI::toggle_speaker_config_window ()
275 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("toggle-speaker-config"));
277 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
279 if (tact->get_active()) {
280 speaker_config_window->get()->show_all ();
281 speaker_config_window->get()->present ();
283 speaker_config_window->get()->hide ();
289 ARDOUR_UI::new_midi_tracer_window ()
291 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("NewMIDITracer"));
296 std::list<MidiTracer*>::iterator i = _midi_tracer_windows.begin ();
297 while (i != _midi_tracer_windows.end() && (*i)->get_visible() == true) {
301 if (i == _midi_tracer_windows.end()) {
302 /* all our MIDITracer windows are visible; make a new one */
303 MidiTracer* t = new MidiTracer ();
306 _midi_tracer_windows.push_back (t);
308 /* re-use the hidden one */
314 ARDOUR_UI::toggle_rc_options_window ()
316 if (rc_option_editor == 0) {
317 rc_option_editor = new RCOptionEditor;
318 rc_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleRCOptionsEditor")));
319 rc_option_editor->set_session (_session);
322 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleRCOptionsEditor"));
324 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
326 if (tact->get_active()) {
327 rc_option_editor->show_all ();
328 rc_option_editor->present ();
330 rc_option_editor->hide ();
336 ARDOUR_UI::toggle_session_options_window ()
338 if (session_option_editor == 0) {
339 session_option_editor = new SessionOptionEditor (_session);
340 session_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleSessionOptionsEditor")));
343 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleSessionOptionsEditor"));
345 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
347 if (tact->get_active()) {
348 session_option_editor->show_all ();
349 session_option_editor->present ();
351 session_option_editor->hide ();
357 ARDOUR_UI::create_location_ui ()
359 if (location_ui->get() == 0) {
360 location_ui->set (new LocationUIWindow ());
361 location_ui->get()->set_session (_session);
362 location_ui->get()->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleLocations")));
368 ARDOUR_UI::toggle_location_window ()
370 if (create_location_ui()) {
374 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleLocations"));
376 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
378 if (tact->get_active()) {
379 location_ui->get()->show_all ();
380 location_ui->get()->present ();
382 location_ui->get()->hide ();
388 ARDOUR_UI::toggle_key_editor ()
390 if (key_editor == 0) {
391 key_editor = new KeyEditor;
392 key_editor->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleKeyEditor")));
395 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleKeyEditor"));
397 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
399 if (tact->get_active()) {
400 key_editor->show_all ();
401 key_editor->present ();
409 ARDOUR_UI::toggle_theme_manager ()
411 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleThemeManager"));
413 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
415 if (tact->get_active()) {
416 theme_manager->show_all ();
417 theme_manager->present ();
419 theme_manager->hide ();
425 ARDOUR_UI::create_bundle_manager ()
427 if (bundle_manager == 0) {
428 bundle_manager = new BundleManager (_session);
429 bundle_manager->signal_unmap().connect (sigc::bind (sigc::ptr_fun (&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleBundleManager")));
434 ARDOUR_UI::toggle_bundle_manager ()
436 create_bundle_manager ();
438 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBundleManager"));
440 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
442 if (tact->get_active()) {
443 bundle_manager->show_all ();
444 bundle_manager->present ();
446 bundle_manager->hide ();
452 ARDOUR_UI::create_route_params ()
454 if (route_params == 0) {
455 route_params = new RouteParams_UI ();
456 route_params->set_session (_session);
457 route_params->signal_unmap().connect (sigc::bind(sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleInspector")));
463 ARDOUR_UI::toggle_route_params_window ()
465 if (create_route_params ()) {
469 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleInspector"));
471 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
473 if (tact->get_active()) {
474 route_params->show_all ();
475 route_params->present ();
477 route_params->hide ();
483 ARDOUR_UI::handle_locations_change (Location *)
486 if (_session->locations()->num_range_markers()) {
487 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
489 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
495 ARDOUR_UI::main_window_state_event_handler (GdkEventWindowState* ev, bool window_was_editor)
497 if (window_was_editor) {
499 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
500 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
501 float_big_clock (editor);
506 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
507 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
508 float_big_clock (mixer);