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