replaced canonicalize_file_name with realpath, which is available.
[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         if (!session->control_out()) {
66                 Glib::RefPtr<Action> act = ActionManager::get_action (X_("options"), X_("SoloViaBus"));
67                 if (act) {
68                         act->set_sensitive (false);
69                 }
70         }
71
72         /* allow wastebasket flush again */
73
74         Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
75         if (act) {
76                 act->set_sensitive (true);
77         }
78
79         /* there are never any selections on startup */
80
81         ActionManager::set_sensitive (ActionManager::region_selection_sensitive_actions, false);
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 (connection_editor) {
95                 connection_editor->set_session (s);
96         }
97
98         if (location_ui) {
99                 location_ui->set_session(s);
100         }
101
102         if (route_params) {
103                 route_params->set_session (s);
104         }
105
106         if (option_editor) {
107                 option_editor->set_session (s);
108         }
109
110         setup_session_options ();
111
112         Blink.connect (mem_fun(*this, &ARDOUR_UI::transport_rec_enable_blink));
113         Blink.connect (mem_fun(*this, &ARDOUR_UI::solo_blink));
114         Blink.connect (mem_fun(*this, &ARDOUR_UI::audition_blink));
115
116         /* these are all need to be handled in an RT-safe and MT way, so don't
117            do any GUI work, just queue it for handling by the GUI thread.
118         */
119
120         session->TransportStateChange.connect (mem_fun(*this, &ARDOUR_UI::queue_transport_change));
121
122         /* alert the user to these things happening */
123
124         session->AuditionActive.connect (mem_fun(*this, &ARDOUR_UI::auditioning_changed));
125         session->SoloActive.connect (mem_fun(*this, &ARDOUR_UI::soloing_changed));
126
127         solo_alert_button.set_active (session->soloing());
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         start_clocking ();
150         start_blinking ();
151
152         transport_stopped ();
153
154         second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_second), 1000);
155         point_one_second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_point_one_seconds), 100);
156         point_zero_one_second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_point_zero_one_seconds), 40);
157 }
158
159 int
160 ARDOUR_UI::unload_session ()
161 {
162         if (session && session->dirty()) {
163                 switch (ask_about_saving_session (_("close"))) {
164                 case -1:
165                         return 1;
166                         
167                 case 1:
168                         session->save_state ("");
169                         break;
170                 }
171         }
172         editor->hide ();
173         second_connection.disconnect ();
174         point_one_second_connection.disconnect ();
175         point_oh_five_second_connection.disconnect ();
176         point_zero_one_second_connection.disconnect();
177
178         ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
179         
180         rec_button.set_sensitive (false);
181         shuttle_box.set_sensitive (false);
182
183         stop_blinking ();
184         stop_clocking ();
185
186         /* drop everything attached to the blink signal */
187
188         Blink.clear ();
189
190         primary_clock.set_session (0);
191         secondary_clock.set_session (0);
192         big_clock.set_session (0);
193         preroll_clock.set_session (0);
194         postroll_clock.set_session (0);
195
196         if (option_editor) {
197                 option_editor->set_session (0);
198         }
199
200         if (mixer) {
201                 mixer->hide_all ();
202         }
203
204         delete session;
205         session = 0;
206
207         update_buffer_load ();
208
209         return 0;
210 }
211
212 int
213 ARDOUR_UI::create_connection_editor ()
214 {
215 #if 0
216         if (connection_editor == 0) {
217                 connection_editor = new ConnectionEditor ();
218                 connection_editor->signal_unmap().connect (sigc::bind (ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleConnections")));
219         }
220
221         if (session) {
222                 connection_editor->set_session (session);
223         }
224 #endif
225
226         return 0;
227 }
228
229 void
230 ARDOUR_UI::toggle_connection_editor ()
231 {
232         if (create_connection_editor()) {
233                 return;
234         }
235
236 #if 0
237         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleConnections"));
238         if (act) {
239                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
240         
241                 if (tact->get_active()) {
242                         connection_editor->show_all ();
243                         connection_editor->present ();
244                 } else {
245                         connection_editor->hide ();
246                 } 
247         }
248 #endif
249 }
250
251 void
252 ARDOUR_UI::toggle_big_clock_window ()
253 {
254         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBigClock"));
255         if (act) {
256                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
257         
258                 if (tact->get_active()) {
259                         big_clock_window->show_all ();
260                         big_clock_window->present ();
261                 } else {
262                         big_clock_window->hide ();
263                 } 
264         }
265 }
266
267 void
268 ARDOUR_UI::toggle_options_window ()
269 {
270         if (option_editor == 0) {
271                 option_editor = new OptionEditor (*this, *editor, *mixer);
272                 option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleOptionsEditor")));
273                 option_editor->set_session (session);
274         } 
275
276         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleOptionsEditor"));
277         if (act) {
278                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
279         
280                 if (tact->get_active()) {
281                         option_editor->show_all ();
282                         option_editor->present ();
283                 } else {
284                         option_editor->hide ();
285                 } 
286         }
287 }
288
289 int
290 ARDOUR_UI::create_location_ui ()
291 {
292         if (location_ui == 0) {
293                 location_ui = new LocationUI ();
294                 location_ui->set_session (session);
295                 location_ui->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleLocations")));
296         }
297         return 0;
298 }
299
300 void
301 ARDOUR_UI::toggle_location_window ()
302 {
303         if (create_location_ui()) {
304                 return;
305         }
306
307         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleLocations"));
308         if (act) {
309                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
310         
311                 if (tact->get_active()) {
312                         location_ui->show_all ();
313                         location_ui->present ();
314                 } else {
315                         location_ui->hide ();
316                 } 
317         }
318 }
319
320 void
321 ARDOUR_UI::toggle_color_manager ()
322 {
323         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleColorManager"));
324         if (act) {
325                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
326         
327                 if (tact->get_active()) {
328                         color_manager->show_all ();
329                         color_manager->present ();
330                 } else {
331                         color_manager->hide ();
332                 } 
333         }
334 }
335
336 int
337 ARDOUR_UI::create_route_params ()
338 {
339         if (route_params == 0) {
340                 route_params = new RouteParams_UI ();
341                 route_params->set_session (session);
342                 route_params->signal_unmap().connect (sigc::bind(sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleInspector")));
343         }
344         return 0;
345 }
346
347 void
348 ARDOUR_UI::toggle_route_params_window ()
349 {
350         if (create_route_params ()) {
351                 return;
352         }
353
354         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleInspector"));
355         if (act) {
356                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
357         
358                 if (tact->get_active()) {
359                         route_params->show_all ();
360                         route_params->present ();
361                 } else {
362                         route_params->hide ();
363                 } 
364         }
365 }
366
367 void
368 ARDOUR_UI::handle_locations_change (Location* ignored)
369 {
370         if (session) {
371                 if (session->locations()->num_range_markers()) {
372                         ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
373                 } else {
374                         ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
375                 }
376         }
377 }