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->close_session();
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);
257 /* drop everything attached to the blink signal */
264 session_loaded = false;
266 update_buffer_load ();
272 ARDOUR_UI::toggle_big_clock_window ()
274 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBigClock"));
276 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
278 if (tact->get_active()) {
279 big_clock_window->get()->show_all ();
280 big_clock_window->get()->present ();
282 big_clock_window->get()->hide ();
288 ARDOUR_UI::toggle_speaker_config_window ()
290 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("toggle-speaker-config"));
292 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
294 if (tact->get_active()) {
295 speaker_config_window->get()->show_all ();
296 speaker_config_window->get()->present ();
298 speaker_config_window->get()->hide ();
304 ARDOUR_UI::new_midi_tracer_window ()
306 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("NewMIDITracer"));
311 std::list<MidiTracer*>::iterator i = _midi_tracer_windows.begin ();
312 while (i != _midi_tracer_windows.end() && (*i)->get_visible() == true) {
316 if (i == _midi_tracer_windows.end()) {
317 /* all our MIDITracer windows are visible; make a new one */
318 MidiTracer* t = new MidiTracer ();
321 _midi_tracer_windows.push_back (t);
323 /* re-use the hidden one */
329 ARDOUR_UI::toggle_rc_options_window ()
331 if (rc_option_editor == 0) {
332 rc_option_editor = new RCOptionEditor;
333 rc_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleRCOptionsEditor")));
334 rc_option_editor->set_session (_session);
337 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleRCOptionsEditor"));
339 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
341 if (tact->get_active()) {
342 rc_option_editor->show_all ();
343 rc_option_editor->present ();
345 rc_option_editor->hide ();
351 ARDOUR_UI::toggle_session_options_window ()
353 if (session_option_editor == 0) {
354 session_option_editor = new SessionOptionEditor (_session);
355 session_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleSessionOptionsEditor")));
358 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleSessionOptionsEditor"));
360 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
362 if (tact->get_active()) {
363 session_option_editor->show_all ();
364 session_option_editor->present ();
366 session_option_editor->hide ();
372 ARDOUR_UI::create_location_ui ()
374 if (location_ui->get() == 0) {
375 location_ui->set (new LocationUIWindow ());
376 location_ui->get()->set_session (_session);
377 location_ui->get()->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleLocations")));
383 ARDOUR_UI::toggle_location_window ()
385 if (create_location_ui()) {
389 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleLocations"));
391 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
393 if (tact->get_active()) {
394 location_ui->get()->show_all ();
395 location_ui->get()->present ();
397 location_ui->get()->hide ();
403 ARDOUR_UI::toggle_key_editor ()
405 if (key_editor == 0) {
406 key_editor = new KeyEditor;
407 key_editor->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleKeyEditor")));
410 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleKeyEditor"));
412 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
414 if (tact->get_active()) {
415 key_editor->show_all ();
416 key_editor->present ();
424 ARDOUR_UI::toggle_theme_manager ()
426 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleThemeManager"));
428 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
430 if (tact->get_active()) {
431 theme_manager->show_all ();
432 theme_manager->present ();
434 theme_manager->hide ();
440 ARDOUR_UI::create_bundle_manager ()
442 if (bundle_manager == 0) {
443 bundle_manager = new BundleManager (_session);
444 bundle_manager->signal_unmap().connect (sigc::bind (sigc::ptr_fun (&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleBundleManager")));
449 ARDOUR_UI::toggle_bundle_manager ()
451 create_bundle_manager ();
453 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBundleManager"));
455 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
457 if (tact->get_active()) {
458 bundle_manager->show_all ();
459 bundle_manager->present ();
461 bundle_manager->hide ();
467 ARDOUR_UI::create_route_params ()
469 if (route_params == 0) {
470 route_params = new RouteParams_UI ();
471 route_params->set_session (_session);
472 route_params->signal_unmap().connect (sigc::bind(sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleInspector")));
478 ARDOUR_UI::toggle_route_params_window ()
480 if (create_route_params ()) {
484 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleInspector"));
486 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
488 if (tact->get_active()) {
489 route_params->show_all ();
490 route_params->present ();
492 route_params->hide ();
498 ARDOUR_UI::handle_locations_change (Location *)
501 if (_session->locations()->num_range_markers()) {
502 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
504 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
510 ARDOUR_UI::main_window_state_event_handler (GdkEventWindowState* ev, bool window_was_editor)
512 if (window_was_editor) {
514 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
515 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
516 float_big_clock (editor);
521 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
522 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
523 float_big_clock (mixer);