fix math bug with numthreads computation
[ardour2.git] / gtk2_ardour / ardour_ui_dialogs.cc
blob0c1240e4356b49a01b560c0ee76da20cc315710f
1 /*
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"
29 #include "actions.h"
30 #include "ardour_ui.h"
31 #include "location_ui.h"
32 #include "mixer_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"
37 #include "sfdb_ui.h"
38 #include "theme_manager.h"
39 #include "bundle_manager.h"
40 #include "keyeditor.h"
41 #include "gui_thread.h"
43 #include "i18n.h"
45 using namespace ARDOUR;
46 using namespace PBD;
47 using namespace Glib;
48 using namespace Gtk;
49 using namespace Gtkmm2ext;
51 void
52 ARDOUR_UI::set_session (Session *s)
54 SessionHandlePtr::set_session (s);
56 if (!_session) {
57 return;
60 if (location_ui) {
61 location_ui->set_session(s);
64 if (route_params) {
65 route_params->set_session (s);
68 primary_clock.set_session (s);
69 secondary_clock.set_session (s);
70 big_clock.set_session (s);
71 preroll_clock.set_session (s);
72 postroll_clock.set_session (s);
74 /* sensitize menu bar options that are now valid */
76 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, true);
77 ActionManager::set_sensitive (ActionManager::write_sensitive_actions, _session->writable());
79 if (_session->locations()->num_range_markers()) {
80 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
81 } else {
82 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
85 if (!_session->monitor_out()) {
86 Glib::RefPtr<Action> act = ActionManager::get_action (X_("options"), X_("SoloViaBus"));
87 if (act) {
88 act->set_sensitive (false);
92 /* allow wastebasket flush again */
94 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
95 if (act) {
96 act->set_sensitive (true);
99 /* there are never any selections on startup */
101 ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false);
102 ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, false);
103 ActionManager::set_sensitive (ActionManager::line_selection_sensitive_actions, false);
104 ActionManager::set_sensitive (ActionManager::point_selection_sensitive_actions, false);
105 ActionManager::set_sensitive (ActionManager::playlist_selection_sensitive_actions, false);
107 rec_button.set_sensitive (true);
108 shuttle_box.set_sensitive (true);
109 solo_alert_button.set_active (_session->soloing());
111 setup_session_options ();
113 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::transport_rec_enable_blink));
114 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::solo_blink));
115 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::sync_blink));
116 Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::audition_blink));
118 _session->RecordStateChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::record_state_changed, this), gui_context());
119 _session->TransportStateChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::map_transport_state, this), gui_context());
120 _session->DirtyChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::update_autosave, this), gui_context());
122 _session->Xrun.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::xrun_handler, this, _1), gui_context());
123 _session->SoloActive.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::soloing_changed, this, _1), gui_context());
124 _session->AuditionActive.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::auditioning_changed, this, _1), gui_context());
125 _session->locations()->added.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
126 _session->locations()->removed.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
128 #ifdef HAVE_JACK_SESSION
129 engine->JackSessionEvent.connect (*_session, MISSING_INVALIDATOR, ui_bind (&Session::jack_session_event, _session, _1), gui_context());
130 #endif
132 /* Clocks are on by default after we are connected to a session, so show that here.
135 connect_dependents_to_session (s);
137 /* listen to clock mode changes. don't do this earlier because otherwise as the clocks
138 restore their modes or are explicitly set, we will cause the "new" mode to be saved
139 back to the session XML ("Extra") state.
142 AudioClock::ModeChanged.connect (sigc::mem_fun (*this, &ARDOUR_UI::store_clock_modes));
144 Glib::signal_idle().connect (sigc::mem_fun (*this, &ARDOUR_UI::first_idle));
146 start_clocking ();
147 start_blinking ();
149 map_transport_state ();
151 second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_second), 1000);
152 point_one_second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_one_seconds), 100);
153 point_zero_one_second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_zero_one_seconds), 40);
157 ARDOUR_UI::unload_session (bool hide_stuff)
159 if (_session && _session->dirty()) {
160 switch (ask_about_saving_session (_("close"))) {
161 case -1:
162 // cancel
163 return 1;
165 case 1:
166 _session->save_state ("");
167 break;
171 if (hide_stuff) {
172 editor->hide ();
173 mixer->hide ();
174 theme_manager->hide ();
177 second_connection.disconnect ();
178 point_one_second_connection.disconnect ();
179 point_oh_five_second_connection.disconnect ();
180 point_zero_one_second_connection.disconnect();
182 ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
184 rec_button.set_sensitive (false);
185 shuttle_box.set_sensitive (false);
187 stop_blinking ();
188 stop_clocking ();
190 /* drop everything attached to the blink signal */
192 Blink.clear ();
194 delete _session;
196 update_buffer_load ();
198 return 0;
201 void
202 ARDOUR_UI::toggle_big_clock_window ()
204 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBigClock"));
205 if (act) {
206 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
208 if (tact->get_active()) {
209 big_clock_window->show_all ();
210 big_clock_window->present ();
211 } else {
212 big_clock_window->hide ();
217 void
218 ARDOUR_UI::toggle_rc_options_window ()
220 if (rc_option_editor == 0) {
221 rc_option_editor = new RCOptionEditor;
222 rc_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleRCOptionsEditor")));
223 rc_option_editor->set_session (_session);
226 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleRCOptionsEditor"));
227 if (act) {
228 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
230 if (tact->get_active()) {
231 rc_option_editor->show_all ();
232 rc_option_editor->present ();
233 } else {
234 rc_option_editor->hide ();
239 void
240 ARDOUR_UI::toggle_session_options_window ()
242 if (session_option_editor == 0) {
243 session_option_editor = new SessionOptionEditor (_session);
244 session_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleSessionOptionsEditor")));
247 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleSessionOptionsEditor"));
248 if (act) {
249 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
251 if (tact->get_active()) {
252 session_option_editor->show_all ();
253 session_option_editor->present ();
254 } else {
255 session_option_editor->hide ();
261 ARDOUR_UI::create_location_ui ()
263 if (location_ui == 0) {
264 location_ui = new LocationUIWindow ();
265 location_ui->set_session (_session);
266 location_ui->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleLocations")));
268 return 0;
271 void
272 ARDOUR_UI::toggle_location_window ()
274 if (create_location_ui()) {
275 return;
278 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleLocations"));
279 if (act) {
280 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
282 if (tact->get_active()) {
283 location_ui->show_all ();
284 location_ui->present ();
285 } else {
286 location_ui->hide ();
291 void
292 ARDOUR_UI::toggle_key_editor ()
294 if (key_editor == 0) {
295 key_editor = new KeyEditor;
296 key_editor->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleKeyEditor")));
299 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleKeyEditor"));
300 if (act) {
301 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
303 if (tact->get_active()) {
304 key_editor->show_all ();
305 key_editor->present ();
306 } else {
307 key_editor->hide ();
312 void
313 ARDOUR_UI::toggle_theme_manager ()
315 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleThemeManager"));
316 if (act) {
317 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
319 if (tact->get_active()) {
320 theme_manager->show_all ();
321 theme_manager->present ();
322 } else {
323 theme_manager->hide ();
328 void
329 ARDOUR_UI::create_bundle_manager ()
331 if (bundle_manager == 0) {
332 bundle_manager = new BundleManager (_session);
333 bundle_manager->signal_unmap().connect (sigc::bind (sigc::ptr_fun (&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleBundleManager")));
337 void
338 ARDOUR_UI::toggle_bundle_manager ()
340 create_bundle_manager ();
342 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBundleManager"));
343 if (act) {
344 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
346 if (tact->get_active()) {
347 bundle_manager->show_all ();
348 bundle_manager->present ();
349 } else {
350 bundle_manager->hide ();
356 ARDOUR_UI::create_route_params ()
358 if (route_params == 0) {
359 route_params = new RouteParams_UI ();
360 route_params->set_session (_session);
361 route_params->signal_unmap().connect (sigc::bind(sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleInspector")));
363 return 0;
366 void
367 ARDOUR_UI::toggle_route_params_window ()
369 if (create_route_params ()) {
370 return;
373 RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleInspector"));
374 if (act) {
375 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
377 if (tact->get_active()) {
378 route_params->show_all ();
379 route_params->present ();
380 } else {
381 route_params->hide ();
386 void
387 ARDOUR_UI::handle_locations_change (Location *)
389 if (_session) {
390 if (_session->locations()->num_range_markers()) {
391 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
392 } else {
393 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
398 bool
399 ARDOUR_UI::main_window_state_event_handler (GdkEventWindowState* ev, bool window_was_editor)
401 if (window_was_editor) {
403 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
404 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
405 float_big_clock (editor);
408 } else {
410 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
411 (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
412 float_big_clock (mixer);
416 return false;