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