comments for BBT math methods; remove chunks from GUI; split location UI into a...
[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
28 #include "actions.h"
29 #include "ardour_ui.h"
30 #include "location_ui.h"
31 #include "mixer_ui.h"
32 #include "rc_option_editor.h"
33 #include "session_option_editor.h"
34 #include "public_editor.h"
35 #include "route_params_ui.h"
36 #include "sfdb_ui.h"
37 #include "theme_manager.h"
38 #include "bundle_manager.h"
39 #include "keyeditor.h"
40
41 #include "i18n.h"
42
43 using namespace ARDOUR;
44 using namespace PBD;
45 using namespace Glib;
46 using namespace Gtk;
47 using namespace Gtkmm2ext;
48
49 void
50 ARDOUR_UI::connect_to_session (Session *s)
51 {
52         session = s;
53
54         session->Xrun.connect (mem_fun(*this, &ARDOUR_UI::xrun_handler));
55         session->RecordStateChanged.connect (mem_fun (*this, &ARDOUR_UI::record_state_changed));
56
57         /* sensitize menu bar options that are now valid */
58
59         ActionManager::set_sensitive (ActionManager::session_sensitive_actions, true);
60         ActionManager::set_sensitive (ActionManager::write_sensitive_actions, session->writable());
61
62         if (session->locations()->num_range_markers()) {
63                 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
64         } else {
65                 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
66         }
67
68         if (!session->control_out()) {
69                 Glib::RefPtr<Action> act = ActionManager::get_action (X_("options"), X_("SoloViaBus"));
70                 if (act) {
71                         act->set_sensitive (false);
72                 }
73         }
74
75         /* allow wastebasket flush again */
76
77         Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
78         if (act) {
79                 act->set_sensitive (true);
80         }
81
82         /* there are never any selections on startup */
83
84         ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false);
85         ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, false);
86         ActionManager::set_sensitive (ActionManager::line_selection_sensitive_actions, false);
87         ActionManager::set_sensitive (ActionManager::point_selection_sensitive_actions, false);
88         ActionManager::set_sensitive (ActionManager::playlist_selection_sensitive_actions, false);
89
90         session->locations()->added.connect (mem_fun (*this, &ARDOUR_UI::handle_locations_change));
91         session->locations()->removed.connect (mem_fun (*this, &ARDOUR_UI::handle_locations_change));
92
93         rec_button.set_sensitive (true);
94         shuttle_box.set_sensitive (true);
95
96         if (location_ui) {
97                 location_ui->set_session(s);
98         }
99
100         if (route_params) {
101                 route_params->set_session (s);
102         }
103
104         setup_session_options ();
105
106         Blink.connect (mem_fun(*this, &ARDOUR_UI::transport_rec_enable_blink));
107         Blink.connect (mem_fun(*this, &ARDOUR_UI::solo_blink));
108         Blink.connect (mem_fun(*this, &ARDOUR_UI::sync_blink));
109         Blink.connect (mem_fun(*this, &ARDOUR_UI::audition_blink));
110
111         /* these are all need to be handled in an RT-safe and MT way, so don't
112            do any GUI work, just queue it for handling by the GUI thread.
113         */
114
115         session->TransportStateChange.connect (mem_fun(*this, &ARDOUR_UI::map_transport_state));
116
117         /* alert the user to these things happening */
118
119         session->AuditionActive.connect (mem_fun(*this, &ARDOUR_UI::auditioning_changed));
120         session->SoloActive.connect (mem_fun(*this, &ARDOUR_UI::soloing_changed));
121
122         solo_alert_button.set_active (session->soloing());
123
124         /* update autochange callback on dirty state changing */
125
126         session->DirtyChanged.connect (mem_fun(*this, &ARDOUR_UI::update_autosave));
127
128         /* can't be auditioning here */
129
130         primary_clock.set_session (s);
131         secondary_clock.set_session (s);
132         big_clock.set_session (s);
133         preroll_clock.set_session (s);
134         postroll_clock.set_session (s);
135
136         /* Clocks are on by default after we are connected to a session, so show that here.
137         */
138
139         connect_dependents_to_session (s);
140
141         /* listen to clock mode changes. don't do this earlier because otherwise as the clocks
142            restore their modes or are explicitly set, we will cause the "new" mode to be saved
143            back to the session XML ("Extra") state.
144          */
145
146         AudioClock::ModeChanged.connect (mem_fun (*this, &ARDOUR_UI::store_clock_modes));
147
148         Glib::signal_idle().connect (mem_fun (*this, &ARDOUR_UI::first_idle));
149
150         start_clocking ();
151         start_blinking ();
152
153         map_transport_state ();
154
155         second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_second), 1000);
156         point_one_second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_point_one_seconds), 100);
157         point_zero_one_second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_point_zero_one_seconds), 40);
158 }
159
160 int
161 ARDOUR_UI::unload_session (bool hide_stuff)
162 {
163         if (session && session->dirty()) {
164                 switch (ask_about_saving_session (_("close"))) {
165                 case -1:
166                         // cancel
167                         return 1;
168
169                 case 1:
170                         session->save_state ("");
171                         break;
172                 }
173         }
174
175         if (hide_stuff) {
176                 editor->hide ();
177                 mixer->hide ();
178                 theme_manager->hide ();
179         }
180
181         second_connection.disconnect ();
182         point_one_second_connection.disconnect ();
183         point_oh_five_second_connection.disconnect ();
184         point_zero_one_second_connection.disconnect();
185
186         ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
187
188         rec_button.set_sensitive (false);
189         shuttle_box.set_sensitive (false);
190
191         stop_blinking ();
192         stop_clocking ();
193
194         /* drop everything attached to the blink signal */
195
196         Blink.clear ();
197
198         primary_clock.set_session (0);
199         secondary_clock.set_session (0);
200         big_clock.set_session (0);
201         preroll_clock.set_session (0);
202         postroll_clock.set_session (0);
203
204         delete session;
205         session = 0;
206
207         update_buffer_load ();
208
209         return 0;
210 }
211
212 void
213 ARDOUR_UI::toggle_big_clock_window ()
214 {
215         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBigClock"));
216         if (act) {
217                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
218
219                 if (tact->get_active()) {
220                         big_clock_window->show_all ();
221                         big_clock_window->present ();
222                 } else {
223                         big_clock_window->hide ();
224                 }
225         }
226 }
227
228 void
229 ARDOUR_UI::toggle_rc_options_window ()
230 {
231         if (rc_option_editor == 0) {
232                 rc_option_editor = new RCOptionEditor;
233                 rc_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleRCOptionsEditor")));
234                 rc_option_editor->set_session (session);
235         }
236
237         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleRCOptionsEditor"));
238         if (act) {
239                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
240
241                 if (tact->get_active()) {
242                         rc_option_editor->show_all ();
243                         rc_option_editor->present ();
244                 } else {
245                         rc_option_editor->hide ();
246                 }
247         }
248 }
249
250 void
251 ARDOUR_UI::toggle_session_options_window ()
252 {
253         if (session_option_editor == 0) {
254                 session_option_editor = new SessionOptionEditor (session);
255                 session_option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleSessionOptionsEditor")));
256         }
257
258         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleSessionOptionsEditor"));
259         if (act) {
260                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
261
262                 if (tact->get_active()) {
263                         session_option_editor->show_all ();
264                         session_option_editor->present ();
265                 } else {
266                         session_option_editor->hide ();
267                 }
268         }
269 }
270
271 int
272 ARDOUR_UI::create_location_ui ()
273 {
274         if (location_ui == 0) {
275                 location_ui = new LocationUIWindow ();
276                 location_ui->set_session (session);
277                 location_ui->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleLocations")));
278         }
279         return 0;
280 }
281
282 void
283 ARDOUR_UI::toggle_location_window ()
284 {
285         if (create_location_ui()) {
286                 return;
287         }
288
289         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleLocations"));
290         if (act) {
291                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
292
293                 if (tact->get_active()) {
294                         location_ui->show_all ();
295                         location_ui->present ();
296                 } else {
297                         location_ui->hide ();
298                 }
299         }
300 }
301
302 void
303 ARDOUR_UI::toggle_key_editor ()
304 {
305         if (key_editor == 0) {
306                 key_editor = new KeyEditor;
307                 key_editor->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleKeyEditor")));
308         }
309
310         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleKeyEditor"));
311         if (act) {
312                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
313
314                 if (tact->get_active()) {
315                         key_editor->show_all ();
316                         key_editor->present ();
317                 } else {
318                         key_editor->hide ();
319                 }
320         }
321 }
322
323 void
324 ARDOUR_UI::toggle_theme_manager ()
325 {
326         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleThemeManager"));
327         if (act) {
328                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
329
330                 if (tact->get_active()) {
331                         theme_manager->show_all ();
332                         theme_manager->present ();
333                 } else {
334                         theme_manager->hide ();
335                 }
336         }
337 }
338
339 void
340 ARDOUR_UI::create_bundle_manager ()
341 {
342         if (bundle_manager == 0) {
343                 bundle_manager = new BundleManager (*session);
344                 bundle_manager->signal_unmap().connect (sigc::bind (sigc::ptr_fun (&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleBundleManager")));
345         }
346 }
347
348 void
349 ARDOUR_UI::toggle_bundle_manager ()
350 {
351         create_bundle_manager ();
352
353         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBundleManager"));
354         if (act) {
355                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
356
357                 if (tact->get_active()) {
358                         bundle_manager->show_all ();
359                         bundle_manager->present ();
360                 } else {
361                         bundle_manager->hide ();
362                 }
363         }
364 }
365
366 int
367 ARDOUR_UI::create_route_params ()
368 {
369         if (route_params == 0) {
370                 route_params = new RouteParams_UI ();
371                 route_params->set_session (session);
372                 route_params->signal_unmap().connect (sigc::bind(sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleInspector")));
373         }
374         return 0;
375 }
376
377 void
378 ARDOUR_UI::toggle_route_params_window ()
379 {
380         if (create_route_params ()) {
381                 return;
382         }
383
384         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleInspector"));
385         if (act) {
386                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
387
388                 if (tact->get_active()) {
389                         route_params->show_all ();
390                         route_params->present ();
391                 } else {
392                         route_params->hide ();
393                 }
394         }
395 }
396
397 void
398 ARDOUR_UI::handle_locations_change (Location *)
399 {
400         if (session) {
401                 if (session->locations()->num_range_markers()) {
402                         ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
403                 } else {
404                         ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
405                 }
406         }
407 }
408
409 bool
410 ARDOUR_UI::main_window_state_event_handler (GdkEventWindowState* ev, bool window_was_editor)
411 {
412         if (window_was_editor) {
413
414                 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
415                     (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
416                         float_big_clock (editor);
417                 }
418
419         } else {
420
421                 if ((ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) &&
422                     (ev->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)) {
423                         float_big_clock (mixer);
424                 }
425         }
426
427         return false;
428 }