89ab470d9b9aba9e33657d38364af504f0f53d4f
[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 "connection_editor.h"
31 #include "location_ui.h"
32 #include "mixer_ui.h"
33 #include "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 "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->HaltOnXrun.connect (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
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::region_selection_sensitive_actions, false);
83         ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false);
84         ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, false);
85         ActionManager::set_sensitive (ActionManager::line_selection_sensitive_actions, false);
86         ActionManager::set_sensitive (ActionManager::point_selection_sensitive_actions, false);
87         ActionManager::set_sensitive (ActionManager::playlist_selection_sensitive_actions, false);
88
89         session->locations()->added.connect (mem_fun (*this, &ARDOUR_UI::handle_locations_change));
90         session->locations()->removed.connect (mem_fun (*this, &ARDOUR_UI::handle_locations_change));
91
92         rec_button.set_sensitive (true);
93         shuttle_box.set_sensitive (true);
94         
95         if (connection_editor) {
96                 connection_editor->set_session (s);
97         }
98
99         if (location_ui) {
100                 location_ui->set_session(s);
101         }
102
103         if (route_params) {
104                 route_params->set_session (s);
105         }
106
107         if (option_editor) {
108                 option_editor->set_session (s);
109         }
110
111         setup_session_options ();
112
113         Blink.connect (mem_fun(*this, &ARDOUR_UI::transport_rec_enable_blink));
114         Blink.connect (mem_fun(*this, &ARDOUR_UI::solo_blink));
115         Blink.connect (mem_fun(*this, &ARDOUR_UI::audition_blink));
116
117         /* these are all need to be handled in an RT-safe and MT way, so don't
118            do any GUI work, just queue it for handling by the GUI thread.
119         */
120
121         session->TransportStateChange.connect (mem_fun(*this, &ARDOUR_UI::queue_transport_change));
122
123         /* alert the user to these things happening */
124
125         session->AuditionActive.connect (mem_fun(*this, &ARDOUR_UI::auditioning_changed));
126         session->SoloActive.connect (mem_fun(*this, &ARDOUR_UI::soloing_changed));
127
128         solo_alert_button.set_active (session->soloing());
129
130         /* update autochange callback on dirty state changing */
131
132         session->DirtyChanged.connect (mem_fun(*this, &ARDOUR_UI::update_autosave));
133
134         /* can't be auditioning here */
135
136         primary_clock.set_session (s);
137         secondary_clock.set_session (s);
138         big_clock.set_session (s);
139         preroll_clock.set_session (s);
140         postroll_clock.set_session (s);
141
142         /* Clocks are on by default after we are connected to a session, so show that here.
143         */
144         
145         connect_dependents_to_session (s);
146
147         /* listen to clock mode changes. don't do this earlier because otherwise as the clocks
148            restore their modes or are explicitly set, we will cause the "new" mode to be saved
149            back to the session XML ("extra") state.
150          */
151
152         AudioClock::ModeChanged.connect (mem_fun (*this, &ARDOUR_UI::store_clock_modes));
153
154         Glib::signal_idle().connect (mem_fun (*this, &ARDOUR_UI::first_idle));
155
156         start_clocking ();
157         start_blinking ();
158
159         transport_stopped ();
160
161         second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_second), 1000);
162         point_one_second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_point_one_seconds), 100);
163         point_zero_one_second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_point_zero_one_seconds), 40);
164 }
165
166 int
167 ARDOUR_UI::unload_session (bool hide_stuff)
168 {
169         if (session && session->dirty()) {
170                 switch (ask_about_saving_session (_("close"))) {
171                 case -1:
172                         // cancel
173                         return 1;
174                         
175                 case 1:
176                         session->save_state ("");
177                         break;
178                 }
179         }
180
181         if (hide_stuff) {
182                 editor->hide ();
183                 mixer->hide ();
184         }
185
186         second_connection.disconnect ();
187         point_one_second_connection.disconnect ();
188         point_oh_five_second_connection.disconnect ();
189         point_zero_one_second_connection.disconnect();
190
191         ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
192         
193         rec_button.set_sensitive (false);
194         shuttle_box.set_sensitive (false);
195
196         stop_blinking ();
197         stop_clocking ();
198
199         /* drop everything attached to the blink signal */
200
201         Blink.clear ();
202
203         primary_clock.set_session (0);
204         secondary_clock.set_session (0);
205         big_clock.set_session (0);
206         preroll_clock.set_session (0);
207         postroll_clock.set_session (0);
208
209         if (option_editor) {
210                 option_editor->set_session (0);
211         }
212
213         delete session;
214         session = 0;
215
216         update_buffer_load ();
217
218         return 0;
219 }
220
221 int
222 ARDOUR_UI::create_connection_editor ()
223 {
224 #if 0
225         if (connection_editor == 0) {
226                 connection_editor = new ConnectionEditor ();
227                 connection_editor->signal_unmap().connect (sigc::bind (ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleConnections")));
228         }
229
230         if (session) {
231                 connection_editor->set_session (session);
232         }
233 #endif
234
235         return 0;
236 }
237
238 void
239 ARDOUR_UI::toggle_connection_editor ()
240 {
241         if (create_connection_editor()) {
242                 return;
243         }
244
245 #if 0
246         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleConnections"));
247         if (act) {
248                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
249         
250                 if (tact->get_active()) {
251                         connection_editor->show_all ();
252                         connection_editor->present ();
253                 } else {
254                         connection_editor->hide ();
255                 } 
256         }
257 #endif
258 }
259
260 void
261 ARDOUR_UI::toggle_big_clock_window ()
262 {
263         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBigClock"));
264         if (act) {
265                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
266         
267                 if (tact->get_active()) {
268                         big_clock_window->show_all ();
269                         big_clock_window->present ();
270                 } else {
271                         big_clock_window->hide ();
272                 } 
273         }
274 }
275
276 void
277 ARDOUR_UI::toggle_options_window ()
278 {
279         if (option_editor == 0) {
280                 option_editor = new OptionEditor (*this, *editor, *mixer);
281                 option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleOptionsEditor")));
282                 option_editor->set_session (session);
283         } 
284
285         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleOptionsEditor"));
286         if (act) {
287                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
288         
289                 if (tact->get_active()) {
290                         option_editor->show_all ();
291                         option_editor->present ();
292                 } else {
293                         option_editor->hide ();
294                 } 
295         }
296 }
297
298 int
299 ARDOUR_UI::create_location_ui ()
300 {
301         if (location_ui == 0) {
302                 location_ui = new LocationUI ();
303                 location_ui->set_session (session);
304                 location_ui->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleLocations")));
305         }
306         return 0;
307 }
308
309 void
310 ARDOUR_UI::toggle_location_window ()
311 {
312         if (create_location_ui()) {
313                 return;
314         }
315
316         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleLocations"));
317         if (act) {
318                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
319         
320                 if (tact->get_active()) {
321                         location_ui->show_all ();
322                         location_ui->present ();
323                 } else {
324                         location_ui->hide ();
325                 } 
326         }
327 }
328
329 void
330 ARDOUR_UI::toggle_key_editor ()
331 {
332         if (key_editor == 0) {
333                 key_editor = new KeyEditor;
334                 key_editor->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleKeyEditor")));  
335         }
336
337         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleKeyEditor"));
338         if (act) {
339                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
340         
341                 if (tact->get_active()) {
342                         key_editor->show_all ();
343                         key_editor->present ();
344                 } else {
345                         key_editor->hide ();
346                 } 
347         }
348 }
349
350 void
351 ARDOUR_UI::toggle_theme_manager ()
352 {
353         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleThemeManager"));
354         if (act) {
355                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
356         
357                 if (tact->get_active()) {
358                         theme_manager->show_all ();
359                         theme_manager->present ();
360                 } else {
361                         theme_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* ignored)
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 }