140ee649ea59f07b678609672b01e9e67b13858a
[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         /* there are never any selections on startup */
66
67         ActionManager::set_sensitive (ActionManager::region_selection_sensitive_actions, false);
68         ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false);
69         ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, false);
70         ActionManager::set_sensitive (ActionManager::line_selection_sensitive_actions, false);
71         ActionManager::set_sensitive (ActionManager::point_selection_sensitive_actions, false);
72         ActionManager::set_sensitive (ActionManager::playlist_selection_sensitive_actions, false);
73
74         session->locations()->added.connect (mem_fun (*this, &ARDOUR_UI::handle_locations_change));
75         session->locations()->removed.connect (mem_fun (*this, &ARDOUR_UI::handle_locations_change));
76
77         rec_button.set_sensitive (true);
78         shuttle_box.set_sensitive (true);
79         
80         if (connection_editor) {
81                 connection_editor->set_session (s);
82         }
83
84         if (location_ui) {
85                 location_ui->set_session(s);
86         }
87
88         if (route_params) {
89                 route_params->set_session (s);
90         }
91
92         if (option_editor) {
93                 option_editor->set_session (s);
94         }
95
96         setup_session_options ();
97
98         Blink.connect (mem_fun(*this, &ARDOUR_UI::transport_rec_enable_blink));
99         Blink.connect (mem_fun(*this, &ARDOUR_UI::solo_blink));
100         Blink.connect (mem_fun(*this, &ARDOUR_UI::audition_blink));
101
102         /* these are all need to be handled in an RT-safe and MT way, so don't
103            do any GUI work, just queue it for handling by the GUI thread.
104         */
105
106         session->TransportStateChange.connect (mem_fun(*this, &ARDOUR_UI::queue_transport_change));
107
108         /* alert the user to these things happening */
109
110         session->AuditionActive.connect (mem_fun(*this, &ARDOUR_UI::auditioning_changed));
111         session->SoloActive.connect (mem_fun(*this, &ARDOUR_UI::soloing_changed));
112
113         solo_alert_button.set_active (session->soloing());
114
115         /* can't be auditioning here */
116
117         primary_clock.set_session (s);
118         secondary_clock.set_session (s);
119         big_clock.set_session (s);
120         preroll_clock.set_session (s);
121         postroll_clock.set_session (s);
122
123         /* Clocks are on by default after we are connected to a session, so show that here.
124         */
125         
126         connect_dependents_to_session (s);
127
128         /* listen to clock mode changes. don't do this earlier because otherwise as the clocks
129            restore their modes or are explicitly set, we will cause the "new" mode to be saved
130            back to the session XML ("extra") state.
131          */
132
133         AudioClock::ModeChanged.connect (mem_fun (*this, &ARDOUR_UI::store_clock_modes));
134
135         start_clocking ();
136         start_blinking ();
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 void
353 ARDOUR_UI::handle_locations_change (Location* ignored)
354 {
355         if (session) {
356                 if (session->locations()->num_range_markers()) {
357                         ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
358                 } else {
359                         ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
360                 }
361         }
362 }