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