convert transport buttons to ArdourButton
[ardour.git] / gtk2_ardour / ardour_ui_dialogs.cc
1 /*
2     Copyright (C) 2000 Paul Davis
3
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.
8
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.
13
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.
17
18 */
19
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.
24 */
25
26 #include "ardour/session.h"
27 #include "ardour/audioengine.h"
28
29 #include "actions.h"
30 #include "add_route_dialog.h"
31 #include "ardour_ui.h"
32 #include "bundle_manager.h"
33 #include "global_port_matrix.h"
34 #include "gui_object.h"
35 #include "gui_thread.h"
36 #include "keyeditor.h"
37 #include "location_ui.h"
38 #include "midi_tracer.h"
39 #include "mixer_ui.h"
40 #include "public_editor.h"
41 #include "rc_option_editor.h"
42 #include "route_params_ui.h"
43 #include "shuttle_control.h"
44 #include "session_option_editor.h"
45 #include "speaker_dialog.h"
46 #include "sfdb_ui.h"
47 #include "theme_manager.h"
48 #include "time_info_box.h"
49
50 #include "i18n.h"
51
52 using namespace ARDOUR;
53 using namespace PBD;
54 using namespace Glib;
55 using namespace Gtk;
56 using namespace Gtkmm2ext;
57
58 void
59 ARDOUR_UI::set_session (Session *s)
60 {
61         SessionHandlePtr::set_session (s);
62
63         if (!_session) {
64                 return;
65         }
66
67         const XMLNode* node = _session->extra_xml (X_("UI"));
68
69         if (node) {
70                 const XMLNodeList& children = node->children();
71                 for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
72                         if ((*i)->name() == GUIObjectState::xml_node_name) {
73                                 gui_object_state->load (**i);
74                                 break;
75                         }
76                 }
77         }
78
79         if (location_ui->get()) {
80                 location_ui->get()->set_session(s);
81         }
82
83         if (speaker_config_window->get()) {
84                 speaker_config_window->get()->set_speakers (s->get_speakers());
85         }
86
87         if (route_params) {
88                 route_params->set_session (s);
89         }
90
91         if (add_route_dialog) {
92                 add_route_dialog->set_session (s);
93         }
94
95         if (session_option_editor) {
96                 session_option_editor->set_session (s);
97         }
98
99         if (shuttle_box) {
100                 shuttle_box->set_session (s);
101         }
102
103         for (ARDOUR::DataType::iterator i = ARDOUR::DataType::begin(); i != ARDOUR::DataType::end(); ++i) {
104                 if (_global_port_matrix[*i]->get()) {
105                         _global_port_matrix[*i]->get()->set_session (_session);
106                 }
107         }
108
109         primary_clock->set_session (s);
110         secondary_clock->set_session (s);
111         big_clock->set_session (s);
112         time_info_box->set_session (s);
113
114         /* sensitize menu bar options that are now valid */
115
116         ActionManager::set_sensitive (ActionManager::session_sensitive_actions, true);
117         ActionManager::set_sensitive (ActionManager::write_sensitive_actions, _session->writable());
118
119         if (_session->locations()->num_range_markers()) {
120                 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
121         } else {
122                 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
123         }
124
125         if (!_session->monitor_out()) {
126                 Glib::RefPtr<Action> act = ActionManager::get_action (X_("options"), X_("SoloViaBus"));
127                 if (act) {
128                         act->set_sensitive (false);
129                 }
130         }
131
132         /* allow wastebasket flush again */
133
134         Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
135         if (act) {
136                 act->set_sensitive (true);
137         }
138
139         /* there are never any selections on startup */
140
141         ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false);
142         ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, false);
143         ActionManager::set_sensitive (ActionManager::line_selection_sensitive_actions, false);
144         ActionManager::set_sensitive (ActionManager::point_selection_sensitive_actions, false);
145         ActionManager::set_sensitive (ActionManager::playlist_selection_sensitive_actions, false);
146
147         rec_button.set_sensitive (true);
148
149         solo_alert_button.set_active (_session->soloing());
150
151         setup_session_options ();
152
153         Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::transport_rec_enable_blink));
154         Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::solo_blink));
155         Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::sync_blink));
156         Blink.connect (sigc::mem_fun(*this, &ARDOUR_UI::audition_blink));
157
158         _session->RecordStateChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::record_state_changed, this), gui_context());
159         _session->StepEditStatusChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::step_edit_status_change, this, _1), gui_context());
160         _session->TransportStateChange.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::map_transport_state, this), gui_context());
161         _session->DirtyChanged.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::update_autosave, this), gui_context());
162
163         _session->Xrun.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::xrun_handler, this, _1), gui_context());
164         _session->SoloActive.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::soloing_changed, this, _1), gui_context());
165         _session->AuditionActive.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::auditioning_changed, this, _1), gui_context());
166         _session->locations()->added.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
167         _session->locations()->removed.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::handle_locations_change, this, _1), gui_context());
168         _session->config.ParameterChanged.connect (_session_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::session_parameter_changed, this, _1), gui_context ());
169
170 #ifdef HAVE_JACK_SESSION
171         engine->JackSessionEvent.connect (*_session, MISSING_INVALIDATOR, ui_bind (&Session::jack_session_event, _session, _1), gui_context());
172 #endif
173
174         /* Clocks are on by default after we are connected to a session, so show that here.
175         */
176
177         connect_dependents_to_session (s);
178
179         /* listen to clock mode changes. don't do this earlier because otherwise as the clocks
180            restore their modes or are explicitly set, we will cause the "new" mode to be saved
181            back to the session XML ("Extra") state.
182          */
183
184         AudioClock::ModeChanged.connect (sigc::mem_fun (*this, &ARDOUR_UI::store_clock_modes));
185
186         Glib::signal_idle().connect (sigc::mem_fun (*this, &ARDOUR_UI::first_idle));
187
188         start_clocking ();
189         start_blinking ();
190
191         map_transport_state ();
192
193         second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_second), 1000);
194         point_one_second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_one_seconds), 100);
195         point_zero_one_second_connection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::every_point_zero_one_seconds), 40);
196
197         update_format ();
198 }
199
200 int
201 ARDOUR_UI::unload_session (bool hide_stuff)
202 {
203         if (_session && _session->dirty()) {
204                 std::vector<std::string> actions;
205                 actions.push_back (_("Don't close"));
206                 actions.push_back (_("Just close"));
207                 actions.push_back (_("Save and close"));
208                 switch (ask_about_saving_session (actions)) {
209                 case -1:
210                         // cancel
211                         return 1;
212
213                 case 1:
214                         _session->save_state ("");
215                         break;
216                 }
217         }
218
219         if (hide_stuff) {
220                 editor->hide ();
221                 mixer->hide ();
222                 theme_manager->hide ();
223         }
224
225         second_connection.disconnect ();
226         point_one_second_connection.disconnect ();
227         point_oh_five_second_connection.disconnect ();
228         point_zero_one_second_connection.disconnect();
229
230         ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
231
232         rec_button.set_sensitive (false);
233
234         stop_blinking ();
235         stop_clocking ();
236
237         /* drop everything attached to the blink signal */
238
239         Blink.clear ();
240
241         delete _session;
242         _session = 0;
243
244         update_buffer_load ();
245
246         return 0;
247 }
248
249 void
250 ARDOUR_UI::toggle_big_clock_window ()
251 {
252         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBigClock"));
253         if (act) {
254                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
255
256                 if (tact->get_active()) {
257                         big_clock_window->get()->show_all ();
258                         big_clock_window->get()->present ();
259                 } else {
260                         big_clock_window->get()->hide ();
261                 }
262         }
263 }
264
265 void
266 ARDOUR_UI::toggle_speaker_config_window ()
267 {
268         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("toggle-speaker-config"));
269         if (act) {
270                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
271
272                 if (tact->get_active()) {
273                         speaker_config_window->get()->show_all ();
274                         speaker_config_window->get()->present ();
275                 } else {
276                         speaker_config_window->get()->hide ();
277                 }
278         }
279 }
280
281 void
282 ARDOUR_UI::new_midi_tracer_window ()
283 {
284         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("NewMIDITracer"));
285         if (!act) {
286                 return;
287         }
288
289         std::list<MidiTracer*>::iterator i = _midi_tracer_windows.begin ();
290         while (i != _midi_tracer_windows.end() && (*i)->get_visible() == true) {
291                 ++i;
292         }
293
294         if (i == _midi_tracer_windows.end()) {
295                 /* all our MIDITracer windows are visible; make a new one */
296                 MidiTracer* t = new MidiTracer ();
297                 manage_window (*t);
298                 t->show_all ();
299                 _midi_tracer_windows.push_back (t);
300         } else {
301                 /* re-use the hidden one */
302                 (*i)->show_all ();
303         }
304 }
305
306 void
307 ARDOUR_UI::toggle_rc_options_window ()
308 {
309         if (rc_option_editor == 0) {
310                 rc_option_editor = new RCOptionEditor;
311                 rc_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleRCOptionsEditor")));
312                 rc_option_editor->set_session (_session);
313         }
314
315         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleRCOptionsEditor"));
316         if (act) {
317                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
318
319                 if (tact->get_active()) {
320                         rc_option_editor->show_all ();
321                         rc_option_editor->present ();
322                 } else {
323                         rc_option_editor->hide ();
324                 }
325         }
326 }
327
328 void
329 ARDOUR_UI::toggle_session_options_window ()
330 {
331         if (session_option_editor == 0) {
332                 session_option_editor = new SessionOptionEditor (_session);
333                 session_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleSessionOptionsEditor")));
334         }
335
336         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleSessionOptionsEditor"));
337         if (act) {
338                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
339
340                 if (tact->get_active()) {
341                         session_option_editor->show_all ();
342                         session_option_editor->present ();
343                 } else {
344                         session_option_editor->hide ();
345                 }
346         }
347 }
348
349 int
350 ARDOUR_UI::create_location_ui ()
351 {
352         if (location_ui->get() == 0) {
353                 location_ui->set (new LocationUIWindow ());
354                 location_ui->get()->set_session (_session);
355                 location_ui->get()->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleLocations")));
356         }
357         return 0;
358 }
359
360 void
361 ARDOUR_UI::toggle_location_window ()
362 {
363         if (create_location_ui()) {
364                 return;
365         }
366
367         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleLocations"));
368         if (act) {
369                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
370
371                 if (tact->get_active()) {
372                         location_ui->get()->show_all ();
373                         location_ui->get()->present ();
374                 } else {
375                         location_ui->get()->hide ();
376                 }
377         }
378 }
379
380 void
381 ARDOUR_UI::toggle_key_editor ()
382 {
383         if (key_editor == 0) {
384                 key_editor = new KeyEditor;
385                 key_editor->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleKeyEditor")));
386         }
387
388         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleKeyEditor"));
389         if (act) {
390                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
391
392                 if (tact->get_active()) {
393                         key_editor->show_all ();
394                         key_editor->present ();
395                 } else {
396                         key_editor->hide ();
397                 }
398         }
399 }
400
401 void
402 ARDOUR_UI::toggle_theme_manager ()
403 {
404         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleThemeManager"));
405         if (act) {
406                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
407
408                 if (tact->get_active()) {
409                         theme_manager->show_all ();
410                         theme_manager->present ();
411                 } else {
412                         theme_manager->hide ();
413                 }
414         }
415 }
416
417 void
418 ARDOUR_UI::create_bundle_manager ()
419 {
420         if (bundle_manager == 0) {
421                 bundle_manager = new BundleManager (_session);
422                 bundle_manager->signal_unmap().connect (sigc::bind (sigc::ptr_fun (&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleBundleManager")));
423         }
424 }
425
426 void
427 ARDOUR_UI::toggle_bundle_manager ()
428 {
429         create_bundle_manager ();
430
431         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBundleManager"));
432         if (act) {
433                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
434
435                 if (tact->get_active()) {
436                         bundle_manager->show_all ();
437                         bundle_manager->present ();
438                 } else {
439                         bundle_manager->hide ();
440                 }
441         }
442 }
443
444 int
445 ARDOUR_UI::create_route_params ()
446 {
447         if (route_params == 0) {
448                 route_params = new RouteParams_UI ();
449                 route_params->set_session (_session);
450                 route_params->signal_unmap().connect (sigc::bind(sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleInspector")));
451         }
452         return 0;
453 }
454
455 void
456 ARDOUR_UI::toggle_route_params_window ()
457 {
458         if (create_route_params ()) {
459                 return;
460         }
461
462         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleInspector"));
463         if (act) {
464                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
465
466                 if (tact->get_active()) {
467                         route_params->show_all ();
468                         route_params->present ();
469                 } else {
470                         route_params->hide ();
471                 }
472         }
473 }
474
475 void
476 ARDOUR_UI::handle_locations_change (Location *)
477 {
478         if (_session) {
479                 if (_session->locations()->num_range_markers()) {
480                         ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
481                 } else {
482                         ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
483                 }
484         }
485 }
486
487 bool
488 ARDOUR_UI::main_window_state_event_handler (GdkEventWindowState* ev, bool window_was_editor)
489 {
490         if (window_was_editor) {
491
492                 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
493                     (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
494                         float_big_clock (editor);
495                 }
496
497         } else {
498
499                 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
500                     (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
501                         float_big_clock (mixer);
502                 }
503         }
504
505         return false;
506 }