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);
65 for (ARDOUR::DataType::iterator i = ARDOUR::DataType::begin(); i != ARDOUR::DataType::end(); ++i) {
66 GlobalPortMatrixWindow* w;
67 if ((w = _global_port_matrix[*i]->get()) != 0) {
76 const XMLNode* node = _session->extra_xml (X_("UI"));
79 const XMLNodeList& children = node->children();
80 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
81 if ((*i)->name() == GUIObjectState::xml_node_name) {
82 gui_object_state->load (**i);
88 AutomationWatch::instance().set_session (s);
90 if (location_ui->get()) {
91 location_ui->get()->set_session(s);
94 if (speaker_config_window->get()) {
95 speaker_config_window->get()->set_speakers (s->get_speakers());
99 route_params->set_session (s);
102 if (add_route_dialog) {
103 add_route_dialog->set_session (s);
106 if (session_option_editor) {
107 session_option_editor->set_session (s);
111 shuttle_box->set_session (s);
114 for (ARDOUR::DataType::iterator i = ARDOUR::DataType::begin(); i != ARDOUR::DataType::end(); ++i) {
115 if (_global_port_matrix[*i]->get()) {
116 _global_port_matrix[*i]->get()->set_session (_session);
120 primary_clock->set_session (s);
121 secondary_clock->set_session (s);
122 big_clock->set_session (s);
123 time_info_box->set_session (s);
124 video_timeline->set_session (s);
126 /* sensitize menu bar options that are now valid */
128 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, true);
129 ActionManager::set_sensitive (ActionManager::write_sensitive_actions, _session->writable());
131 if (_session->locations()->num_range_markers()) {
132 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
134 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
137 if (!_session->monitor_out()) {
138 Glib::RefPtr<Action> act = ActionManager::get_action (X_("options"), X_("SoloViaBus"));
140 act->set_sensitive (false);
144 /* allow wastebasket flush again */
146 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
148 act->set_sensitive (true);
151 /* there are never any selections on startup */
153 ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false);
154 ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, false);
155 ActionManager::set_sensitive (ActionManager::line_selection_sensitive_actions, false);
156 ActionManager::set_sensitive (ActionManager::point_selection_sensitive_actions, false);
157 ActionManager::set_sensitive (ActionManager::playlist_selection_sensitive_actions, false);
159 rec_button.set_sensitive (true);
161 solo_alert_button.set_active (_session->soloing());
163 setup_session_options ();
165 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::transport_rec_enable_blink));
166 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::solo_blink));
167 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::sync_blink));
168 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::audition_blink));
169 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::feedback_blink));
171 _session->RecordStateChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::record_state_changed, this), gui_context());
172 _session->StepEditStatusChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::step_edit_status_change, this, _1), gui_context());
173 _session->TransportStateChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::map_transport_state, this), gui_context());
174 _session->DirtyChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::update_autosave, this), gui_context());
176 _session->Xrun.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::xrun_handler, this, _1), gui_context());
177 _session->SoloActive.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::soloing_changed, this, _1), gui_context());
178 _session->AuditionActive.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::auditioning_changed, this, _1), gui_context());
179 _session->locations()->added.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
180 _session->locations()->removed.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
181 _session->config.ParameterChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_parameter_changed, this, _1), gui_context ());
183 #ifdef HAVE_JACK_SESSION
184 engine->JackSessionEvent.connect (*_session, MISSING_INVALIDATOR, boost::bind (&Session::jack_session_event, _session, _1), gui_context());
187 /* Clocks are on by default after we are connected to a session, so show that here.
190 connect_dependents_to_session (s);
192 /* listen to clock mode changes. don't do this earlier because otherwise as the clocks
193 restore their modes or are explicitly set, we will cause the "new" mode to be saved
194 back to the session XML ("Extra") state.
197 AudioClock::ModeChanged.connect (sigc::mem_fun (*this, &ARDOUR_UI::store_clock_modes));
199 Glib::signal_idle().connect (sigc::mem_fun (*this, &ARDOUR_UI::first_idle));
204 map_transport_state ();
206 second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_second), 1000);
207 point_one_second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_one_seconds), 100);
208 point_zero_one_second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_zero_one_seconds), 40);
214 ARDOUR_UI::unload_session (bool hide_stuff)
217 ARDOUR_UI::instance()->video_timeline->sync_session_state();
220 if (_session && _session->dirty()) {
221 std::vector<std::string> actions;
222 actions.push_back (_("Don't close"));
223 actions.push_back (_("Just close"));
224 actions.push_back (_("Save and close"));
225 switch (ask_about_saving_session (actions)) {
231 _session->save_state ("");
239 theme_manager->hide ();
242 second_connection.disconnect ();
243 point_one_second_connection.disconnect ();
244 point_oh_five_second_connection.disconnect ();
245 point_zero_one_second_connection.disconnect();
247 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
249 rec_button.set_sensitive (false);
251 ARDOUR_UI::instance()->video_timeline->close_session();
256 /* drop everything attached to the blink signal */
263 session_loaded = false;
265 update_buffer_load ();
271 ARDOUR_UI::toggle_big_clock_window ()
273 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBigClock"));
275 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
277 if (tact->get_active()) {
278 big_clock_window->get()->show_all ();
279 big_clock_window->get()->present ();
281 big_clock_window->get()->hide ();
287 ARDOUR_UI::toggle_speaker_config_window ()
289 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("toggle-speaker-config"));
291 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
293 if (tact->get_active()) {
294 speaker_config_window->get()->show_all ();
295 speaker_config_window->get()->present ();
297 speaker_config_window->get()->hide ();
303 ARDOUR_UI::new_midi_tracer_window ()
305 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("NewMIDITracer"));
310 std::list<MidiTracer*>::iterator i = _midi_tracer_windows.begin ();
311 while (i != _midi_tracer_windows.end() && (*i)->get_visible() == true) {
315 if (i == _midi_tracer_windows.end()) {
316 /* all our MIDITracer windows are visible; make a new one */
317 MidiTracer* t = new MidiTracer ();
320 _midi_tracer_windows.push_back (t);
322 /* re-use the hidden one */
328 ARDOUR_UI::toggle_rc_options_window ()
330 if (rc_option_editor == 0) {
331 rc_option_editor = new RCOptionEditor;
332 rc_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleRCOptionsEditor")));
333 rc_option_editor->set_session (_session);
336 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleRCOptionsEditor"));
338 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
340 if (tact->get_active()) {
341 rc_option_editor->show_all ();
342 rc_option_editor->present ();
344 rc_option_editor->hide ();
350 ARDOUR_UI::toggle_session_options_window ()
352 if (session_option_editor == 0) {
353 session_option_editor = new SessionOptionEditor (_session);
354 session_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleSessionOptionsEditor")));
357 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleSessionOptionsEditor"));
359 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
361 if (tact->get_active()) {
362 session_option_editor->show_all ();
363 session_option_editor->present ();
365 session_option_editor->hide ();
371 ARDOUR_UI::create_location_ui ()
373 if (location_ui->get() == 0) {
374 location_ui->set (new LocationUIWindow ());
375 location_ui->get()->set_session (_session);
376 location_ui->get()->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleLocations")));
382 ARDOUR_UI::toggle_location_window ()
384 if (create_location_ui()) {
388 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleLocations"));
390 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
392 if (tact->get_active()) {
393 location_ui->get()->show_all ();
394 location_ui->get()->present ();
396 location_ui->get()->hide ();
402 ARDOUR_UI::toggle_key_editor ()
404 if (key_editor == 0) {
405 key_editor = new KeyEditor;
406 key_editor->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleKeyEditor")));
409 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleKeyEditor"));
411 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
413 if (tact->get_active()) {
414 key_editor->show_all ();
415 key_editor->present ();
423 ARDOUR_UI::toggle_theme_manager ()
425 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleThemeManager"));
427 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
429 if (tact->get_active()) {
430 theme_manager->show_all ();
431 theme_manager->present ();
433 theme_manager->hide ();
439 ARDOUR_UI::create_bundle_manager ()
441 if (bundle_manager == 0) {
442 bundle_manager = new BundleManager (_session);
443 bundle_manager->signal_unmap().connect (sigc::bind (sigc::ptr_fun (&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleBundleManager")));
448 ARDOUR_UI::toggle_bundle_manager ()
450 create_bundle_manager ();
452 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBundleManager"));
454 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
456 if (tact->get_active()) {
457 bundle_manager->show_all ();
458 bundle_manager->present ();
460 bundle_manager->hide ();
466 ARDOUR_UI::create_route_params ()
468 if (route_params == 0) {
469 route_params = new RouteParams_UI ();
470 route_params->set_session (_session);
471 route_params->signal_unmap().connect (sigc::bind(sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleInspector")));
477 ARDOUR_UI::toggle_route_params_window ()
479 if (create_route_params ()) {
483 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleInspector"));
485 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
487 if (tact->get_active()) {
488 route_params->show_all ();
489 route_params->present ();
491 route_params->hide ();
497 ARDOUR_UI::handle_locations_change (Location *)
500 if (_session->locations()->num_range_markers()) {
501 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
503 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
509 ARDOUR_UI::main_window_state_event_handler (GdkEventWindowState* ev, bool window_was_editor)
511 if (window_was_editor) {
513 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
514 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
515 float_big_clock (editor);
520 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
521 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
522 float_big_clock (mixer);