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