Merged with trunk R1736.
[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         /* update autochange callback on dirty state changing */
130
131         session->DirtyChanged.connect (mem_fun(*this, &ARDOUR_UI::update_autosave));
132
133         /* can't be auditioning here */
134
135         primary_clock.set_session (s);
136         secondary_clock.set_session (s);
137         big_clock.set_session (s);
138         preroll_clock.set_session (s);
139         postroll_clock.set_session (s);
140
141         /* Clocks are on by default after we are connected to a session, so show that here.
142         */
143         
144         connect_dependents_to_session (s);
145
146         /* listen to clock mode changes. don't do this earlier because otherwise as the clocks
147            restore their modes or are explicitly set, we will cause the "new" mode to be saved
148            back to the session XML ("extra") state.
149          */
150
151         AudioClock::ModeChanged.connect (mem_fun (*this, &ARDOUR_UI::store_clock_modes));
152
153         Glib::signal_idle().connect (mem_fun (*this, &ARDOUR_UI::first_idle));
154
155         start_clocking ();
156         start_blinking ();
157
158         transport_stopped ();
159
160         second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_second), 1000);
161         point_one_second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_point_one_seconds), 100);
162         point_zero_one_second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_point_zero_one_seconds), 40);
163 }
164
165 int
166 ARDOUR_UI::unload_session ()
167 {
168         if (session && session->dirty()) {
169                 switch (ask_about_saving_session (_("close"))) {
170                 case -1:
171                         return 1;
172                         
173                 case 1:
174                         session->save_state ("");
175                         break;
176                 }
177         }
178         editor->hide ();
179         second_connection.disconnect ();
180         point_one_second_connection.disconnect ();
181         point_oh_five_second_connection.disconnect ();
182         point_zero_one_second_connection.disconnect();
183
184         ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
185         
186         rec_button.set_sensitive (false);
187         shuttle_box.set_sensitive (false);
188
189         stop_blinking ();
190         stop_clocking ();
191
192         /* drop everything attached to the blink signal */
193
194         Blink.clear ();
195
196         primary_clock.set_session (0);
197         secondary_clock.set_session (0);
198         big_clock.set_session (0);
199         preroll_clock.set_session (0);
200         postroll_clock.set_session (0);
201
202         if (option_editor) {
203                 option_editor->set_session (0);
204         }
205
206         if (mixer) {
207                 mixer->hide_all ();
208         }
209
210         delete session;
211         session = 0;
212
213         update_buffer_load ();
214
215         return 0;
216 }
217
218 int
219 ARDOUR_UI::create_connection_editor ()
220 {
221 #if 0
222         if (connection_editor == 0) {
223                 connection_editor = new ConnectionEditor ();
224                 connection_editor->signal_unmap().connect (sigc::bind (ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleConnections")));
225         }
226
227         if (session) {
228                 connection_editor->set_session (session);
229         }
230 #endif
231
232         return 0;
233 }
234
235 void
236 ARDOUR_UI::toggle_connection_editor ()
237 {
238         if (create_connection_editor()) {
239                 return;
240         }
241
242 #if 0
243         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleConnections"));
244         if (act) {
245                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
246         
247                 if (tact->get_active()) {
248                         connection_editor->show_all ();
249                         connection_editor->present ();
250                 } else {
251                         connection_editor->hide ();
252                 } 
253         }
254 #endif
255 }
256
257 void
258 ARDOUR_UI::toggle_big_clock_window ()
259 {
260         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBigClock"));
261         if (act) {
262                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
263         
264                 if (tact->get_active()) {
265                         big_clock_window->show_all ();
266                         big_clock_window->present ();
267                 } else {
268                         big_clock_window->hide ();
269                 } 
270         }
271 }
272
273 void
274 ARDOUR_UI::toggle_options_window ()
275 {
276         if (option_editor == 0) {
277                 option_editor = new OptionEditor (*this, *editor, *mixer);
278                 option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleOptionsEditor")));
279                 option_editor->set_session (session);
280         } 
281
282         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleOptionsEditor"));
283         if (act) {
284                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
285         
286                 if (tact->get_active()) {
287                         option_editor->show_all ();
288                         option_editor->present ();
289                 } else {
290                         option_editor->hide ();
291                 } 
292         }
293 }
294
295 int
296 ARDOUR_UI::create_location_ui ()
297 {
298         if (location_ui == 0) {
299                 location_ui = new LocationUI ();
300                 location_ui->set_session (session);
301                 location_ui->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleLocations")));
302         }
303         return 0;
304 }
305
306 void
307 ARDOUR_UI::toggle_location_window ()
308 {
309         if (create_location_ui()) {
310                 return;
311         }
312
313         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleLocations"));
314         if (act) {
315                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
316         
317                 if (tact->get_active()) {
318                         location_ui->show_all ();
319                         location_ui->present ();
320                 } else {
321                         location_ui->hide ();
322                 } 
323         }
324 }
325
326 void
327 ARDOUR_UI::toggle_color_manager ()
328 {
329         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleColorManager"));
330         if (act) {
331                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
332         
333                 if (tact->get_active()) {
334                         color_manager->show_all ();
335                         color_manager->present ();
336                 } else {
337                         color_manager->hide ();
338                 } 
339         }
340 }
341
342 int
343 ARDOUR_UI::create_route_params ()
344 {
345         if (route_params == 0) {
346                 route_params = new RouteParams_UI ();
347                 route_params->set_session (session);
348                 route_params->signal_unmap().connect (sigc::bind(sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleInspector")));
349         }
350         return 0;
351 }
352
353 void
354 ARDOUR_UI::toggle_route_params_window ()
355 {
356         if (create_route_params ()) {
357                 return;
358         }
359
360         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleInspector"));
361         if (act) {
362                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
363         
364                 if (tact->get_active()) {
365                         route_params->show_all ();
366                         route_params->present ();
367                 } else {
368                         route_params->hide ();
369                 } 
370         }
371 }
372
373 void
374 ARDOUR_UI::handle_locations_change (Location* ignored)
375 {
376         if (session) {
377                 if (session->locations()->num_range_markers()) {
378                         ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
379                 } else {
380                         ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
381                 }
382         }
383 }