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