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);
125 /* sensitize menu bar options that are now valid */
127 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, true);
128 ActionManager::set_sensitive (ActionManager::write_sensitive_actions, _session->writable());
130 if (_session->locations()->num_range_markers()) {
131 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
133 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
136 if (!_session->monitor_out()) {
137 Glib::RefPtr<Action> act = ActionManager::get_action (X_("options"), X_("SoloViaBus"));
139 act->set_sensitive (false);
143 /* allow wastebasket flush again */
145 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
147 act->set_sensitive (true);
150 /* there are never any selections on startup */
152 ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false);
153 ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, false);
154 ActionManager::set_sensitive (ActionManager::line_selection_sensitive_actions, false);
155 ActionManager::set_sensitive (ActionManager::point_selection_sensitive_actions, false);
156 ActionManager::set_sensitive (ActionManager::playlist_selection_sensitive_actions, false);
158 rec_button.set_sensitive (true);
160 solo_alert_button.set_active (_session->soloing());
162 setup_session_options ();
164 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::transport_rec_enable_blink));
165 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::solo_blink));
166 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::sync_blink));
167 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::audition_blink));
168 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::feedback_blink));
170 _session->RecordStateChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::record_state_changed, this), gui_context());
171 _session->StepEditStatusChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::step_edit_status_change, this, _1), gui_context());
172 _session->TransportStateChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::map_transport_state, this), gui_context());
173 _session->DirtyChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::update_autosave, this), gui_context());
175 _session->Xrun.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::xrun_handler, this, _1), gui_context());
176 _session->SoloActive.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::soloing_changed, this, _1), gui_context());
177 _session->AuditionActive.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::auditioning_changed, this, _1), gui_context());
178 _session->locations()->added.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
179 _session->locations()->removed.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
180 _session->config.ParameterChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_parameter_changed, this, _1), gui_context ());
182 #ifdef HAVE_JACK_SESSION
183 engine->JackSessionEvent.connect (*_session, MISSING_INVALIDATOR, boost::bind (&Session::jack_session_event, _session, _1), gui_context());
186 /* Clocks are on by default after we are connected to a session, so show that here.
189 connect_dependents_to_session (s);
191 /* listen to clock mode changes. don't do this earlier because otherwise as the clocks
192 restore their modes or are explicitly set, we will cause the "new" mode to be saved
193 back to the session XML ("Extra") state.
196 AudioClock::ModeChanged.connect (sigc::mem_fun (*this, &ARDOUR_UI::store_clock_modes));
198 Glib::signal_idle().connect (sigc::mem_fun (*this, &ARDOUR_UI::first_idle));
203 map_transport_state ();
205 second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_second), 1000);
206 point_one_second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_one_seconds), 100);
207 point_zero_one_second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_zero_one_seconds), 40);
213 ARDOUR_UI::unload_session (bool hide_stuff)
215 if (_session && _session->dirty()) {
216 std::vector<std::string> actions;
217 actions.push_back (_("Don't close"));
218 actions.push_back (_("Just close"));
219 actions.push_back (_("Save and close"));
220 switch (ask_about_saving_session (actions)) {
226 _session->save_state ("");
234 theme_manager->hide ();
237 second_connection.disconnect ();
238 point_one_second_connection.disconnect ();
239 point_oh_five_second_connection.disconnect ();
240 point_zero_one_second_connection.disconnect();
242 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
244 rec_button.set_sensitive (false);
249 /* drop everything attached to the blink signal */
256 session_loaded = false;
258 update_buffer_load ();
264 ARDOUR_UI::toggle_big_clock_window ()
266 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBigClock"));
268 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
270 if (tact->get_active()) {
271 big_clock_window->get()->show_all ();
272 big_clock_window->get()->present ();
274 big_clock_window->get()->hide ();
280 ARDOUR_UI::toggle_speaker_config_window ()
282 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("toggle-speaker-config"));
284 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
286 if (tact->get_active()) {
287 speaker_config_window->get()->show_all ();
288 speaker_config_window->get()->present ();
290 speaker_config_window->get()->hide ();
296 ARDOUR_UI::new_midi_tracer_window ()
298 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("NewMIDITracer"));
303 std::list<MidiTracer*>::iterator i = _midi_tracer_windows.begin ();
304 while (i != _midi_tracer_windows.end() && (*i)->get_visible() == true) {
308 if (i == _midi_tracer_windows.end()) {
309 /* all our MIDITracer windows are visible; make a new one */
310 MidiTracer* t = new MidiTracer ();
313 _midi_tracer_windows.push_back (t);
315 /* re-use the hidden one */
321 ARDOUR_UI::toggle_rc_options_window ()
323 if (rc_option_editor == 0) {
324 rc_option_editor = new RCOptionEditor;
325 rc_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleRCOptionsEditor")));
326 rc_option_editor->set_session (_session);
329 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleRCOptionsEditor"));
331 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
333 if (tact->get_active()) {
334 rc_option_editor->show_all ();
335 rc_option_editor->present ();
337 rc_option_editor->hide ();
343 ARDOUR_UI::toggle_session_options_window ()
345 if (session_option_editor == 0) {
346 session_option_editor = new SessionOptionEditor (_session);
347 session_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleSessionOptionsEditor")));
350 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleSessionOptionsEditor"));
352 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
354 if (tact->get_active()) {
355 session_option_editor->show_all ();
356 session_option_editor->present ();
358 session_option_editor->hide ();
364 ARDOUR_UI::create_location_ui ()
366 if (location_ui->get() == 0) {
367 location_ui->set (new LocationUIWindow ());
368 location_ui->get()->set_session (_session);
369 location_ui->get()->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleLocations")));
375 ARDOUR_UI::toggle_location_window ()
377 if (create_location_ui()) {
381 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleLocations"));
383 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
385 if (tact->get_active()) {
386 location_ui->get()->show_all ();
387 location_ui->get()->present ();
389 location_ui->get()->hide ();
395 ARDOUR_UI::toggle_key_editor ()
397 if (key_editor == 0) {
398 key_editor = new KeyEditor;
399 key_editor->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleKeyEditor")));
402 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleKeyEditor"));
404 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
406 if (tact->get_active()) {
407 key_editor->show_all ();
408 key_editor->present ();
416 ARDOUR_UI::toggle_theme_manager ()
418 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleThemeManager"));
420 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
422 if (tact->get_active()) {
423 theme_manager->show_all ();
424 theme_manager->present ();
426 theme_manager->hide ();
432 ARDOUR_UI::create_bundle_manager ()
434 if (bundle_manager == 0) {
435 bundle_manager = new BundleManager (_session);
436 bundle_manager->signal_unmap().connect (sigc::bind (sigc::ptr_fun (&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleBundleManager")));
441 ARDOUR_UI::toggle_bundle_manager ()
443 create_bundle_manager ();
445 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBundleManager"));
447 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
449 if (tact->get_active()) {
450 bundle_manager->show_all ();
451 bundle_manager->present ();
453 bundle_manager->hide ();
459 ARDOUR_UI::create_route_params ()
461 if (route_params == 0) {
462 route_params = new RouteParams_UI ();
463 route_params->set_session (_session);
464 route_params->signal_unmap().connect (sigc::bind(sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleInspector")));
470 ARDOUR_UI::toggle_route_params_window ()
472 if (create_route_params ()) {
476 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleInspector"));
478 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
480 if (tact->get_active()) {
481 route_params->show_all ();
482 route_params->present ();
484 route_params->hide ();
490 ARDOUR_UI::handle_locations_change (Location *)
493 if (_session->locations()->num_range_markers()) {
494 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
496 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
502 ARDOUR_UI::main_window_state_event_handler (GdkEventWindowState* ev, bool window_was_editor)
504 if (window_was_editor) {
506 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
507 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
508 float_big_clock (editor);
513 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
514 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
515 float_big_clock (mixer);