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