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