Move RDF-based preset stuff into LadspaPlugin, to make way for a set of evil hacks...
[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 "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"
42 #include "midi_tracer.h"
43 #include "add_route_dialog.h"
44 #include "global_port_matrix.h"
45
46 #include "i18n.h"
47
48 using namespace ARDOUR;
49 using namespace PBD;
50 using namespace Glib;
51 using namespace Gtk;
52 using namespace Gtkmm2ext;
53
54 void
55 ARDOUR_UI::set_session (Session *s)
56 {
57         SessionHandlePtr::set_session (s);
58
59         if (!_session) {
60                 return;
61         }
62
63         if (location_ui->get()) {
64                 location_ui->get()->set_session(s);
65         }
66
67         if (route_params) {
68                 route_params->set_session (s);
69         }
70
71         if (add_route_dialog) {
72                 add_route_dialog->set_session (s);
73         }
74
75         if (session_option_editor) {
76                 session_option_editor->set_session (s);
77         }
78
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);
82                 }
83         }
84
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);
91         
92         /* sensitize menu bar options that are now valid */
93
94         ActionManager::set_sensitive (ActionManager::session_sensitive_actions, true);
95         ActionManager::set_sensitive (ActionManager::write_sensitive_actions, _session->writable());
96
97         if (_session->locations()->num_range_markers()) {
98                 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
99         } else {
100                 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
101         }
102
103         if (!_session->monitor_out()) {
104                 Glib::RefPtr<Action> act = ActionManager::get_action (X_("options"), X_("SoloViaBus"));
105                 if (act) {
106                         act->set_sensitive (false);
107                 }
108         }
109
110         /* allow wastebasket flush again */
111
112         Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
113         if (act) {
114                 act->set_sensitive (true);
115         }
116
117         /* there are never any selections on startup */
118
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);
124
125         rec_button.set_sensitive (true);
126         shuttle_box.set_sensitive (true);
127         solo_alert_button.set_active (_session->soloing());
128
129         setup_session_options ();
130
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));
135
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());
140
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());
146
147 #ifdef HAVE_JACK_SESSION
148         engine->JackSessionEvent.connect (*_session, MISSING_INVALIDATOR, ui_bind (&Session::jack_session_event, _session, _1), gui_context());
149 #endif
150
151         /* Clocks are on by default after we are connected to a session, so show that here.
152         */
153
154         connect_dependents_to_session (s);
155
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.
159          */
160
161         AudioClock::ModeChanged.connect (sigc::mem_fun (*this, &ARDOUR_UI::store_clock_modes));
162
163         Glib::signal_idle().connect (sigc::mem_fun (*this, &ARDOUR_UI::first_idle));
164
165         start_clocking ();
166         start_blinking ();
167
168         map_transport_state ();
169
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);
173 }
174
175 int
176 ARDOUR_UI::unload_session (bool hide_stuff)
177 {
178         if (_session && _session->dirty()) {
179                 switch (ask_about_saving_session (_("close"))) {
180                 case -1:
181                         // cancel
182                         return 1;
183
184                 case 1:
185                         _session->save_state ("");
186                         break;
187                 }
188         }
189
190         if (hide_stuff) {
191                 editor->hide ();
192                 mixer->hide ();
193                 theme_manager->hide ();
194         }
195
196         second_connection.disconnect ();
197         point_one_second_connection.disconnect ();
198         point_oh_five_second_connection.disconnect ();
199         point_zero_one_second_connection.disconnect();
200
201         ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
202
203         rec_button.set_sensitive (false);
204         shuttle_box.set_sensitive (false);
205
206         stop_blinking ();
207         stop_clocking ();
208
209         /* drop everything attached to the blink signal */
210
211         Blink.clear ();
212
213         delete _session;
214
215         update_buffer_load ();
216
217         return 0;
218 }
219
220 void
221 ARDOUR_UI::toggle_big_clock_window ()
222 {
223         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBigClock"));
224         if (act) {
225                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
226
227                 if (tact->get_active()) {
228                         big_clock_window->get()->show_all ();
229                         big_clock_window->get()->present ();
230                 } else {
231                         big_clock_window->get()->hide ();
232                 }
233         }
234 }
235
236 void
237 ARDOUR_UI::new_midi_tracer_window ()
238 {
239         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("NewMIDITracer"));
240         if (!act) {
241                 return;
242         }
243
244         std::list<MidiTracer*>::iterator i = _midi_tracer_windows.begin ();
245         while (i != _midi_tracer_windows.end() && (*i)->get_visible() == true) {
246                 ++i;
247         }
248
249         if (i == _midi_tracer_windows.end()) {
250                 /* all our MIDITracer windows are visible; make a new one */
251                 MidiTracer* t = new MidiTracer ();
252                 manage_window (*t);
253                 t->show_all ();
254                 _midi_tracer_windows.push_back (t);
255         } else {
256                 /* re-use the hidden one */
257                 (*i)->show_all ();
258         }
259 }
260
261 void
262 ARDOUR_UI::toggle_rc_options_window ()
263 {
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);
268         }
269
270         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleRCOptionsEditor"));
271         if (act) {
272                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
273
274                 if (tact->get_active()) {
275                         rc_option_editor->show_all ();
276                         rc_option_editor->present ();
277                 } else {
278                         rc_option_editor->hide ();
279                 }
280         }
281 }
282
283 void
284 ARDOUR_UI::toggle_session_options_window ()
285 {
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")));
289         }
290
291         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleSessionOptionsEditor"));
292         if (act) {
293                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
294
295                 if (tact->get_active()) {
296                         session_option_editor->show_all ();
297                         session_option_editor->present ();
298                 } else {
299                         session_option_editor->hide ();
300                 }
301         }
302 }
303
304 int
305 ARDOUR_UI::create_location_ui ()
306 {
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")));
311         }
312         return 0;
313 }
314
315 void
316 ARDOUR_UI::toggle_location_window ()
317 {
318         if (create_location_ui()) {
319                 return;
320         }
321
322         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleLocations"));
323         if (act) {
324                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
325
326                 if (tact->get_active()) {
327                         location_ui->get()->show_all ();
328                         location_ui->get()->present ();
329                 } else {
330                         location_ui->get()->hide ();
331                 }
332         }
333 }
334
335 void
336 ARDOUR_UI::toggle_key_editor ()
337 {
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")));
341         }
342
343         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleKeyEditor"));
344         if (act) {
345                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
346
347                 if (tact->get_active()) {
348                         key_editor->show_all ();
349                         key_editor->present ();
350                 } else {
351                         key_editor->hide ();
352                 }
353         }
354 }
355
356 void
357 ARDOUR_UI::toggle_theme_manager ()
358 {
359         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleThemeManager"));
360         if (act) {
361                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
362
363                 if (tact->get_active()) {
364                         theme_manager->show_all ();
365                         theme_manager->present ();
366                 } else {
367                         theme_manager->hide ();
368                 }
369         }
370 }
371
372 void
373 ARDOUR_UI::create_bundle_manager ()
374 {
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")));
378         }
379 }
380
381 void
382 ARDOUR_UI::toggle_bundle_manager ()
383 {
384         create_bundle_manager ();
385
386         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBundleManager"));
387         if (act) {
388                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
389
390                 if (tact->get_active()) {
391                         bundle_manager->show_all ();
392                         bundle_manager->present ();
393                 } else {
394                         bundle_manager->hide ();
395                 }
396         }
397 }
398
399 int
400 ARDOUR_UI::create_route_params ()
401 {
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")));
406         }
407         return 0;
408 }
409
410 void
411 ARDOUR_UI::toggle_route_params_window ()
412 {
413         if (create_route_params ()) {
414                 return;
415         }
416
417         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleInspector"));
418         if (act) {
419                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
420
421                 if (tact->get_active()) {
422                         route_params->show_all ();
423                         route_params->present ();
424                 } else {
425                         route_params->hide ();
426                 }
427         }
428 }
429
430 void
431 ARDOUR_UI::handle_locations_change (Location *)
432 {
433         if (_session) {
434                 if (_session->locations()->num_range_markers()) {
435                         ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
436                 } else {
437                         ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
438                 }
439         }
440 }
441
442 bool
443 ARDOUR_UI::main_window_state_event_handler (GdkEventWindowState* ev, bool window_was_editor)
444 {
445         if (window_was_editor) {
446
447                 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
448                     (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
449                         float_big_clock (editor);
450                 }
451
452         } else {
453
454                 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
455                     (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
456                         float_big_clock (mixer);
457                 }
458         }
459
460         return false;
461 }