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"
30 #include "ardour_ui.h"
31 #include "location_ui.h"
33 #include "rc_option_editor.h"
34 #include "session_option_editor.h"
35 #include "public_editor.h"
36 #include "route_params_ui.h"
38 #include "theme_manager.h"
39 #include "bundle_manager.h"
40 #include "keyeditor.h"
41 #include "gui_thread.h"
42 #include "midi_tracer.h"
43 #include "add_route_dialog.h"
44 #include "global_port_matrix.h"
48 using namespace ARDOUR;
52 using namespace Gtkmm2ext;
55 ARDOUR_UI::set_session (Session *s)
57 SessionHandlePtr::set_session (s);
63 if (location_ui->get()) {
64 location_ui->get()->set_session(s);
68 route_params->set_session (s);
71 if (add_route_dialog) {
72 add_route_dialog->set_session (s);
75 if (session_option_editor) {
76 session_option_editor->set_session (s);
79 for (ARDOUR::DataType::iterator i = ARDOUR::DataType::begin(); i != ARDOUR::DataType::end(); ++i) {
80 if (_global_port_matrix[*i]->get()) {
81 _global_port_matrix[*i]->get()->set_session (_session);
85 primary_clock.set_session (s);
86 secondary_clock.set_session (s);
87 big_clock.set_session (s);
88 preroll_clock.set_session (s);
89 postroll_clock.set_session (s);
90 _menu_bar_clock.set_session (s);
92 /* sensitize menu bar options that are now valid */
94 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, true);
95 ActionManager::set_sensitive (ActionManager::write_sensitive_actions, _session->writable());
97 if (_session->locations()->num_range_markers()) {
98 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
100 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
103 if (!_session->monitor_out()) {
104 Glib::RefPtr<Action> act = ActionManager::get_action (X_("options"), X_("SoloViaBus"));
106 act->set_sensitive (false);
110 /* allow wastebasket flush again */
112 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
114 act->set_sensitive (true);
117 /* there are never any selections on startup */
119 ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false);
120 ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, false);
121 ActionManager::set_sensitive (ActionManager::line_selection_sensitive_actions, false);
122 ActionManager::set_sensitive (ActionManager::point_selection_sensitive_actions, false);
123 ActionManager::set_sensitive (ActionManager::playlist_selection_sensitive_actions, false);
125 rec_button.set_sensitive (true);
126 shuttle_box.set_sensitive (true);
127 solo_alert_button.set_active (_session->soloing());
129 setup_session_options ();
131 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::transport_rec_enable_blink));
132 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::solo_blink));
133 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::sync_blink));
134 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::audition_blink));
136 _session->RecordStateChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::record_state_changed, this), gui_context());
137 _session->StepEditStatusChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::step_edit_status_change, this, _1), gui_context());
138 _session->TransportStateChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::map_transport_state, this), gui_context());
139 _session->DirtyChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::update_autosave, this), gui_context());
141 _session->Xrun.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::xrun_handler, this, _1), gui_context());
142 _session->SoloActive.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::soloing_changed, this, _1), gui_context());
143 _session->AuditionActive.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::auditioning_changed, this, _1), gui_context());
144 _session->locations()->added.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
145 _session->locations()->removed.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
147 #ifdef HAVE_JACK_SESSION
148 engine->JackSessionEvent.connect (*_session, MISSING_INVALIDATOR, ui_bind (&Session::jack_session_event, _session, _1), gui_context());
151 /* Clocks are on by default after we are connected to a session, so show that here.
154 connect_dependents_to_session (s);
156 /* listen to clock mode changes. don't do this earlier because otherwise as the clocks
157 restore their modes or are explicitly set, we will cause the "new" mode to be saved
158 back to the session XML ("Extra") state.
161 AudioClock::ModeChanged.connect (sigc::mem_fun (*this, &ARDOUR_UI::store_clock_modes));
163 Glib::signal_idle().connect (sigc::mem_fun (*this, &ARDOUR_UI::first_idle));
168 map_transport_state ();
170 second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_second), 1000);
171 point_one_second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_one_seconds), 100);
172 point_zero_one_second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_zero_one_seconds), 40);
176 ARDOUR_UI::unload_session (bool hide_stuff)
178 if (_session && _session->dirty()) {
179 switch (ask_about_saving_session (_("close"))) {
185 _session->save_state ("");
193 theme_manager->hide ();
196 second_connection.disconnect ();
197 point_one_second_connection.disconnect ();
198 point_oh_five_second_connection.disconnect ();
199 point_zero_one_second_connection.disconnect();
201 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
203 rec_button.set_sensitive (false);
204 shuttle_box.set_sensitive (false);
209 /* drop everything attached to the blink signal */
215 update_buffer_load ();
221 ARDOUR_UI::toggle_big_clock_window ()
223 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBigClock"));
225 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
227 if (tact->get_active()) {
228 big_clock_window->get()->show_all ();
229 big_clock_window->get()->present ();
231 big_clock_window->get()->hide ();
237 ARDOUR_UI::new_midi_tracer_window ()
239 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("NewMIDITracer"));
244 std::list<MidiTracer*>::iterator i = _midi_tracer_windows.begin ();
245 while (i != _midi_tracer_windows.end() && (*i)->get_visible() == true) {
249 if (i == _midi_tracer_windows.end()) {
250 /* all our MIDITracer windows are visible; make a new one */
251 MidiTracer* t = new MidiTracer ();
254 _midi_tracer_windows.push_back (t);
256 /* re-use the hidden one */
262 ARDOUR_UI::toggle_rc_options_window ()
264 if (rc_option_editor == 0) {
265 rc_option_editor = new RCOptionEditor;
266 rc_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleRCOptionsEditor")));
267 rc_option_editor->set_session (_session);
270 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleRCOptionsEditor"));
272 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
274 if (tact->get_active()) {
275 rc_option_editor->show_all ();
276 rc_option_editor->present ();
278 rc_option_editor->hide ();
284 ARDOUR_UI::toggle_session_options_window ()
286 if (session_option_editor == 0) {
287 session_option_editor = new SessionOptionEditor (_session);
288 session_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleSessionOptionsEditor")));
291 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleSessionOptionsEditor"));
293 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
295 if (tact->get_active()) {
296 session_option_editor->show_all ();
297 session_option_editor->present ();
299 session_option_editor->hide ();
305 ARDOUR_UI::create_location_ui ()
307 if (location_ui->get() == 0) {
308 location_ui->set (new LocationUIWindow ());
309 location_ui->get()->set_session (_session);
310 location_ui->get()->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleLocations")));
316 ARDOUR_UI::toggle_location_window ()
318 if (create_location_ui()) {
322 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleLocations"));
324 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
326 if (tact->get_active()) {
327 location_ui->get()->show_all ();
328 location_ui->get()->present ();
330 location_ui->get()->hide ();
336 ARDOUR_UI::toggle_key_editor ()
338 if (key_editor == 0) {
339 key_editor = new KeyEditor;
340 key_editor->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleKeyEditor")));
343 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleKeyEditor"));
345 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
347 if (tact->get_active()) {
348 key_editor->show_all ();
349 key_editor->present ();
357 ARDOUR_UI::toggle_theme_manager ()
359 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleThemeManager"));
361 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
363 if (tact->get_active()) {
364 theme_manager->show_all ();
365 theme_manager->present ();
367 theme_manager->hide ();
373 ARDOUR_UI::create_bundle_manager ()
375 if (bundle_manager == 0) {
376 bundle_manager = new BundleManager (_session);
377 bundle_manager->signal_unmap().connect (sigc::bind (sigc::ptr_fun (&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleBundleManager")));
382 ARDOUR_UI::toggle_bundle_manager ()
384 create_bundle_manager ();
386 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBundleManager"));
388 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
390 if (tact->get_active()) {
391 bundle_manager->show_all ();
392 bundle_manager->present ();
394 bundle_manager->hide ();
400 ARDOUR_UI::create_route_params ()
402 if (route_params == 0) {
403 route_params = new RouteParams_UI ();
404 route_params->set_session (_session);
405 route_params->signal_unmap().connect (sigc::bind(sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleInspector")));
411 ARDOUR_UI::toggle_route_params_window ()
413 if (create_route_params ()) {
417 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleInspector"));
419 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
421 if (tact->get_active()) {
422 route_params->show_all ();
423 route_params->present ();
425 route_params->hide ();
431 ARDOUR_UI::handle_locations_change (Location *)
434 if (_session->locations()->num_range_markers()) {
435 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
437 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
443 ARDOUR_UI::main_window_state_event_handler (GdkEventWindowState* ev, bool window_was_editor)
445 if (window_was_editor) {
447 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
448 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
449 float_big_clock (editor);
454 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
455 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
456 float_big_clock (mixer);