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 #ifdef WITH_VIDEOTIMELINE
125 video_timeline->set_session (s);
128 /* sensitize menu bar options that are now valid */
130 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, true);
131 ActionManager::set_sensitive (ActionManager::write_sensitive_actions, _session->writable());
133 if (_session->locations()->num_range_markers()) {
134 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
136 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
139 if (!_session->monitor_out()) {
140 Glib::RefPtr<Action> act = ActionManager::get_action (X_("options"), X_("SoloViaBus"));
142 act->set_sensitive (false);
146 /* allow wastebasket flush again */
148 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
150 act->set_sensitive (true);
153 /* there are never any selections on startup */
155 ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false);
156 ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, false);
157 ActionManager::set_sensitive (ActionManager::line_selection_sensitive_actions, false);
158 ActionManager::set_sensitive (ActionManager::point_selection_sensitive_actions, false);
159 ActionManager::set_sensitive (ActionManager::playlist_selection_sensitive_actions, false);
161 rec_button.set_sensitive (true);
163 solo_alert_button.set_active (_session->soloing());
165 setup_session_options ();
167 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::transport_rec_enable_blink));
168 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::solo_blink));
169 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::sync_blink));
170 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::audition_blink));
171 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::feedback_blink));
173 _session->RecordStateChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::record_state_changed, this), gui_context());
174 _session->StepEditStatusChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::step_edit_status_change, this, _1), gui_context());
175 _session->TransportStateChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::map_transport_state, this), gui_context());
176 _session->DirtyChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::update_autosave, this), gui_context());
178 _session->Xrun.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::xrun_handler, this, _1), gui_context());
179 _session->SoloActive.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::soloing_changed, this, _1), gui_context());
180 _session->AuditionActive.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::auditioning_changed, this, _1), gui_context());
181 _session->locations()->added.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
182 _session->locations()->removed.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
183 _session->config.ParameterChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_parameter_changed, this, _1), gui_context ());
185 #ifdef HAVE_JACK_SESSION
186 engine->JackSessionEvent.connect (*_session, MISSING_INVALIDATOR, boost::bind (&Session::jack_session_event, _session, _1), gui_context());
189 /* Clocks are on by default after we are connected to a session, so show that here.
192 connect_dependents_to_session (s);
194 /* listen to clock mode changes. don't do this earlier because otherwise as the clocks
195 restore their modes or are explicitly set, we will cause the "new" mode to be saved
196 back to the session XML ("Extra") state.
199 AudioClock::ModeChanged.connect (sigc::mem_fun (*this, &ARDOUR_UI::store_clock_modes));
201 Glib::signal_idle().connect (sigc::mem_fun (*this, &ARDOUR_UI::first_idle));
206 map_transport_state ();
208 second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_second), 1000);
209 point_one_second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_one_seconds), 100);
210 point_zero_one_second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_zero_one_seconds), 40);
216 ARDOUR_UI::unload_session (bool hide_stuff)
218 #ifdef WITH_VIDEOTIMELINE
220 ARDOUR_UI::instance()->video_timeline->sync_session_state();
223 if (_session && _session->dirty()) {
224 std::vector<std::string> actions;
225 actions.push_back (_("Don't close"));
226 actions.push_back (_("Just close"));
227 actions.push_back (_("Save and close"));
228 switch (ask_about_saving_session (actions)) {
234 _session->save_state ("");
242 theme_manager->hide ();
245 second_connection.disconnect ();
246 point_one_second_connection.disconnect ();
247 point_oh_five_second_connection.disconnect ();
248 point_zero_one_second_connection.disconnect();
250 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
252 rec_button.set_sensitive (false);
253 #ifdef WITH_VIDEOTIMELINE
254 ARDOUR_UI::instance()->video_timeline->close_session();
260 /* drop everything attached to the blink signal */
267 session_loaded = false;
269 update_buffer_load ();
275 ARDOUR_UI::toggle_big_clock_window ()
277 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBigClock"));
279 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
281 if (tact->get_active()) {
282 big_clock_window->get()->show_all ();
283 big_clock_window->get()->present ();
285 big_clock_window->get()->hide ();
291 ARDOUR_UI::toggle_speaker_config_window ()
293 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("toggle-speaker-config"));
295 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
297 if (tact->get_active()) {
298 speaker_config_window->get()->show_all ();
299 speaker_config_window->get()->present ();
301 speaker_config_window->get()->hide ();
307 ARDOUR_UI::new_midi_tracer_window ()
309 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("NewMIDITracer"));
314 std::list<MidiTracer*>::iterator i = _midi_tracer_windows.begin ();
315 while (i != _midi_tracer_windows.end() && (*i)->get_visible() == true) {
319 if (i == _midi_tracer_windows.end()) {
320 /* all our MIDITracer windows are visible; make a new one */
321 MidiTracer* t = new MidiTracer ();
324 _midi_tracer_windows.push_back (t);
326 /* re-use the hidden one */
332 ARDOUR_UI::toggle_rc_options_window ()
334 if (rc_option_editor == 0) {
335 rc_option_editor = new RCOptionEditor;
336 rc_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleRCOptionsEditor")));
337 rc_option_editor->set_session (_session);
340 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleRCOptionsEditor"));
342 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
344 if (tact->get_active()) {
345 rc_option_editor->show_all ();
346 rc_option_editor->present ();
348 rc_option_editor->hide ();
354 ARDOUR_UI::toggle_session_options_window ()
356 if (session_option_editor == 0) {
357 session_option_editor = new SessionOptionEditor (_session);
358 session_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleSessionOptionsEditor")));
361 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleSessionOptionsEditor"));
363 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
365 if (tact->get_active()) {
366 session_option_editor->show_all ();
367 session_option_editor->present ();
369 session_option_editor->hide ();
375 ARDOUR_UI::create_location_ui ()
377 if (location_ui->get() == 0) {
378 location_ui->set (new LocationUIWindow ());
379 location_ui->get()->set_session (_session);
380 location_ui->get()->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleLocations")));
386 ARDOUR_UI::toggle_location_window ()
388 if (create_location_ui()) {
392 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleLocations"));
394 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
396 if (tact->get_active()) {
397 location_ui->get()->show_all ();
398 location_ui->get()->present ();
400 location_ui->get()->hide ();
406 ARDOUR_UI::toggle_key_editor ()
408 if (key_editor == 0) {
409 key_editor = new KeyEditor;
410 key_editor->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleKeyEditor")));
413 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleKeyEditor"));
415 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
417 if (tact->get_active()) {
418 key_editor->show_all ();
419 key_editor->present ();
427 ARDOUR_UI::toggle_theme_manager ()
429 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleThemeManager"));
431 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
433 if (tact->get_active()) {
434 theme_manager->show_all ();
435 theme_manager->present ();
437 theme_manager->hide ();
443 ARDOUR_UI::create_bundle_manager ()
445 if (bundle_manager == 0) {
446 bundle_manager = new BundleManager (_session);
447 bundle_manager->signal_unmap().connect (sigc::bind (sigc::ptr_fun (&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleBundleManager")));
452 ARDOUR_UI::toggle_bundle_manager ()
454 create_bundle_manager ();
456 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBundleManager"));
458 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
460 if (tact->get_active()) {
461 bundle_manager->show_all ();
462 bundle_manager->present ();
464 bundle_manager->hide ();
470 ARDOUR_UI::create_route_params ()
472 if (route_params == 0) {
473 route_params = new RouteParams_UI ();
474 route_params->set_session (_session);
475 route_params->signal_unmap().connect (sigc::bind(sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleInspector")));
481 ARDOUR_UI::toggle_route_params_window ()
483 if (create_route_params ()) {
487 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleInspector"));
489 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
491 if (tact->get_active()) {
492 route_params->show_all ();
493 route_params->present ();
495 route_params->hide ();
501 ARDOUR_UI::handle_locations_change (Location *)
504 if (_session->locations()->num_range_markers()) {
505 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
507 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
513 ARDOUR_UI::main_window_state_event_handler (GdkEventWindowState* ev, bool window_was_editor)
515 if (window_was_editor) {
517 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
518 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
519 float_big_clock (editor);
524 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
525 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
526 float_big_clock (mixer);