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 /* close video-monitor
221 * this needed to enfore querying its settings (window size,..)
222 * which are reported asynchroneously.
224 ARDOUR_UI::instance()->video_timeline->close_session();
227 if (_session && _session->dirty()) {
228 std::vector<std::string> actions;
229 actions.push_back (_("Don't close"));
230 actions.push_back (_("Just close"));
231 actions.push_back (_("Save and close"));
232 switch (ask_about_saving_session (actions)) {
234 ARDOUR_UI::instance()->video_timeline->set_session(_session);
239 _session->save_state ("");
247 theme_manager->hide ();
250 second_connection.disconnect ();
251 point_one_second_connection.disconnect ();
252 point_oh_five_second_connection.disconnect ();
253 point_zero_one_second_connection.disconnect();
255 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
257 rec_button.set_sensitive (false);
262 /* drop everything attached to the blink signal */
269 session_loaded = false;
271 update_buffer_load ();
277 ARDOUR_UI::toggle_big_clock_window ()
279 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBigClock"));
281 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
283 if (tact->get_active()) {
284 big_clock_window->get()->show_all ();
285 big_clock_window->get()->present ();
287 big_clock_window->get()->hide ();
293 ARDOUR_UI::toggle_speaker_config_window ()
295 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("toggle-speaker-config"));
297 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
299 if (tact->get_active()) {
300 speaker_config_window->get()->show_all ();
301 speaker_config_window->get()->present ();
303 speaker_config_window->get()->hide ();
309 ARDOUR_UI::new_midi_tracer_window ()
311 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("NewMIDITracer"));
316 std::list<MidiTracer*>::iterator i = _midi_tracer_windows.begin ();
317 while (i != _midi_tracer_windows.end() && (*i)->get_visible() == true) {
321 if (i == _midi_tracer_windows.end()) {
322 /* all our MIDITracer windows are visible; make a new one */
323 MidiTracer* t = new MidiTracer ();
326 _midi_tracer_windows.push_back (t);
328 /* re-use the hidden one */
334 ARDOUR_UI::toggle_rc_options_window ()
336 if (rc_option_editor == 0) {
337 rc_option_editor = new RCOptionEditor;
338 rc_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleRCOptionsEditor")));
339 rc_option_editor->set_session (_session);
342 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleRCOptionsEditor"));
344 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
346 if (tact->get_active()) {
347 rc_option_editor->show_all ();
348 rc_option_editor->present ();
350 rc_option_editor->hide ();
356 ARDOUR_UI::toggle_session_options_window ()
358 if (session_option_editor == 0) {
359 session_option_editor = new SessionOptionEditor (_session);
360 session_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleSessionOptionsEditor")));
363 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleSessionOptionsEditor"));
365 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
367 if (tact->get_active()) {
368 session_option_editor->show_all ();
369 session_option_editor->present ();
371 session_option_editor->hide ();
377 ARDOUR_UI::create_location_ui ()
379 if (location_ui->get() == 0) {
380 location_ui->set (new LocationUIWindow ());
381 location_ui->get()->set_session (_session);
382 location_ui->get()->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleLocations")));
388 ARDOUR_UI::toggle_location_window ()
390 if (create_location_ui()) {
394 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleLocations"));
396 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
398 if (tact->get_active()) {
399 location_ui->get()->show_all ();
400 location_ui->get()->present ();
402 location_ui->get()->hide ();
408 ARDOUR_UI::toggle_key_editor ()
410 if (key_editor == 0) {
411 key_editor = new KeyEditor;
412 key_editor->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleKeyEditor")));
415 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleKeyEditor"));
417 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
419 if (tact->get_active()) {
420 key_editor->show_all ();
421 key_editor->present ();
429 ARDOUR_UI::toggle_theme_manager ()
431 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleThemeManager"));
433 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
435 if (tact->get_active()) {
436 theme_manager->show_all ();
437 theme_manager->present ();
439 theme_manager->hide ();
445 ARDOUR_UI::create_bundle_manager ()
447 if (bundle_manager == 0) {
448 bundle_manager = new BundleManager (_session);
449 bundle_manager->signal_unmap().connect (sigc::bind (sigc::ptr_fun (&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleBundleManager")));
454 ARDOUR_UI::toggle_bundle_manager ()
456 create_bundle_manager ();
458 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBundleManager"));
460 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
462 if (tact->get_active()) {
463 bundle_manager->show_all ();
464 bundle_manager->present ();
466 bundle_manager->hide ();
472 ARDOUR_UI::create_route_params ()
474 if (route_params == 0) {
475 route_params = new RouteParams_UI ();
476 route_params->set_session (_session);
477 route_params->signal_unmap().connect (sigc::bind(sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleInspector")));
483 ARDOUR_UI::toggle_route_params_window ()
485 if (create_route_params ()) {
489 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleInspector"));
491 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
493 if (tact->get_active()) {
494 route_params->show_all ();
495 route_params->present ();
497 route_params->hide ();
503 ARDOUR_UI::handle_locations_change (Location *)
506 if (_session->locations()->num_range_markers()) {
507 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
509 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
515 ARDOUR_UI::main_window_state_event_handler (GdkEventWindowState* ev, bool window_was_editor)
517 if (window_was_editor) {
519 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
520 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
521 float_big_clock (editor);
526 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
527 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
528 float_big_clock (mixer);