Various work on bundles. We now have a Bundle Manager dialogue, and hopefully things...
[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 #include "bundle_manager.h"
39 #include "keyeditor.h"
40
41 #include "i18n.h"
42
43 using namespace ARDOUR;
44 using namespace PBD;
45 using namespace Glib;
46 using namespace Gtk;
47 using namespace Gtkmm2ext;
48
49 void
50 ARDOUR_UI::connect_to_session (Session *s)
51 {
52         session = s;
53
54         session->HaltOnXrun.connect (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
55         session->RecordStateChanged.connect (mem_fun (*this, &ARDOUR_UI::record_state_changed));
56
57         /* sensitize menu bar options that are now valid */
58
59         ActionManager::set_sensitive (ActionManager::session_sensitive_actions, true);
60         
61         if (session->locations()->num_range_markers()) {
62                 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
63         } else {
64                 ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
65         }
66
67         if (!session->control_out()) {
68                 Glib::RefPtr<Action> act = ActionManager::get_action (X_("options"), X_("SoloViaBus"));
69                 if (act) {
70                         act->set_sensitive (false);
71                 }
72         }
73
74         /* allow wastebasket flush again */
75
76         Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
77         if (act) {
78                 act->set_sensitive (true);
79         }
80
81         /* there are never any selections on startup */
82
83         ActionManager::set_sensitive (ActionManager::region_selection_sensitive_actions, false);
84         ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false);
85         ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, false);
86         ActionManager::set_sensitive (ActionManager::line_selection_sensitive_actions, false);
87         ActionManager::set_sensitive (ActionManager::point_selection_sensitive_actions, false);
88         ActionManager::set_sensitive (ActionManager::playlist_selection_sensitive_actions, false);
89
90         session->locations()->added.connect (mem_fun (*this, &ARDOUR_UI::handle_locations_change));
91         session->locations()->removed.connect (mem_fun (*this, &ARDOUR_UI::handle_locations_change));
92
93         rec_button.set_sensitive (true);
94         shuttle_box.set_sensitive (true);
95         
96         if (connection_editor) {
97                 connection_editor->set_session (s);
98         }
99
100         if (location_ui) {
101                 location_ui->set_session(s);
102         }
103
104         if (route_params) {
105                 route_params->set_session (s);
106         }
107
108         if (option_editor) {
109                 option_editor->set_session (s);
110         }
111
112         setup_session_options ();
113
114         Blink.connect (mem_fun(*this, &ARDOUR_UI::transport_rec_enable_blink));
115         Blink.connect (mem_fun(*this, &ARDOUR_UI::solo_blink));
116         Blink.connect (mem_fun(*this, &ARDOUR_UI::audition_blink));
117
118         /* these are all need to be handled in an RT-safe and MT way, so don't
119            do any GUI work, just queue it for handling by the GUI thread.
120         */
121
122         session->TransportStateChange.connect (mem_fun(*this, &ARDOUR_UI::queue_transport_change));
123
124         /* alert the user to these things happening */
125
126         session->AuditionActive.connect (mem_fun(*this, &ARDOUR_UI::auditioning_changed));
127         session->SoloActive.connect (mem_fun(*this, &ARDOUR_UI::soloing_changed));
128
129         solo_alert_button.set_active (session->soloing());
130
131         /* update autochange callback on dirty state changing */
132
133         session->DirtyChanged.connect (mem_fun(*this, &ARDOUR_UI::update_autosave));
134
135         /* can't be auditioning here */
136
137         primary_clock.set_session (s);
138         secondary_clock.set_session (s);
139         big_clock.set_session (s);
140         preroll_clock.set_session (s);
141         postroll_clock.set_session (s);
142
143         /* Clocks are on by default after we are connected to a session, so show that here.
144         */
145         
146         connect_dependents_to_session (s);
147
148         /* listen to clock mode changes. don't do this earlier because otherwise as the clocks
149            restore their modes or are explicitly set, we will cause the "new" mode to be saved
150            back to the session XML ("extra") state.
151          */
152
153         AudioClock::ModeChanged.connect (mem_fun (*this, &ARDOUR_UI::store_clock_modes));
154
155         Glib::signal_idle().connect (mem_fun (*this, &ARDOUR_UI::first_idle));
156
157         start_clocking ();
158         start_blinking ();
159
160         transport_stopped ();
161
162         second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_second), 1000);
163         point_one_second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_point_one_seconds), 100);
164         point_zero_one_second_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::every_point_zero_one_seconds), 40);
165 }
166
167 int
168 ARDOUR_UI::unload_session (bool hide_stuff)
169 {
170         if (session && session->dirty()) {
171                 switch (ask_about_saving_session (_("close"))) {
172                 case -1:
173                         // cancel
174                         return 1;
175                         
176                 case 1:
177                         session->save_state ("");
178                         break;
179                 }
180         }
181
182         if (hide_stuff) {
183                 editor->hide ();
184                 mixer->hide ();
185         }
186
187         second_connection.disconnect ();
188         point_one_second_connection.disconnect ();
189         point_oh_five_second_connection.disconnect ();
190         point_zero_one_second_connection.disconnect();
191
192         ActionManager::set_sensitive (ActionManager::session_sensitive_actions, false);
193         
194         rec_button.set_sensitive (false);
195         shuttle_box.set_sensitive (false);
196
197         stop_blinking ();
198         stop_clocking ();
199
200         /* drop everything attached to the blink signal */
201
202         Blink.clear ();
203
204         primary_clock.set_session (0);
205         secondary_clock.set_session (0);
206         big_clock.set_session (0);
207         preroll_clock.set_session (0);
208         postroll_clock.set_session (0);
209
210         if (option_editor) {
211                 option_editor->set_session (0);
212         }
213
214         delete session;
215         session = 0;
216
217         update_buffer_load ();
218
219         return 0;
220 }
221
222 int
223 ARDOUR_UI::create_connection_editor ()
224 {
225 #if 0
226         if (connection_editor == 0) {
227                 connection_editor = new ConnectionEditor ();
228                 connection_editor->signal_unmap().connect (sigc::bind (ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleConnections")));
229         }
230
231         if (session) {
232                 connection_editor->set_session (session);
233         }
234 #endif
235
236         return 0;
237 }
238
239 void
240 ARDOUR_UI::toggle_connection_editor ()
241 {
242         if (create_connection_editor()) {
243                 return;
244         }
245
246 #if 0
247         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleConnections"));
248         if (act) {
249                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
250         
251                 if (tact->get_active()) {
252                         connection_editor->show_all ();
253                         connection_editor->present ();
254                 } else {
255                         connection_editor->hide ();
256                 } 
257         }
258 #endif
259 }
260
261 void
262 ARDOUR_UI::toggle_big_clock_window ()
263 {
264         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBigClock"));
265         if (act) {
266                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
267         
268                 if (tact->get_active()) {
269                         big_clock_window->show_all ();
270                         big_clock_window->present ();
271                 } else {
272                         big_clock_window->hide ();
273                 } 
274         }
275 }
276
277 void
278 ARDOUR_UI::toggle_options_window ()
279 {
280         if (option_editor == 0) {
281                 option_editor = new OptionEditor (*this, *editor, *mixer);
282                 option_editor->signal_unmap().connect(sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleOptionsEditor")));
283                 option_editor->set_session (session);
284         } 
285
286         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleOptionsEditor"));
287         if (act) {
288                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
289         
290                 if (tact->get_active()) {
291                         option_editor->show_all ();
292                         option_editor->present ();
293                 } else {
294                         option_editor->hide ();
295                 } 
296         }
297 }
298
299 int
300 ARDOUR_UI::create_location_ui ()
301 {
302         if (location_ui == 0) {
303                 location_ui = new LocationUI ();
304                 location_ui->set_session (session);
305                 location_ui->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleLocations")));
306         }
307         return 0;
308 }
309
310 void
311 ARDOUR_UI::toggle_location_window ()
312 {
313         if (create_location_ui()) {
314                 return;
315         }
316
317         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleLocations"));
318         if (act) {
319                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
320         
321                 if (tact->get_active()) {
322                         location_ui->show_all ();
323                         location_ui->present ();
324                 } else {
325                         location_ui->hide ();
326                 } 
327         }
328 }
329
330 void
331 ARDOUR_UI::toggle_key_editor ()
332 {
333         if (key_editor == 0) {
334                 key_editor = new KeyEditor;
335                 key_editor->signal_unmap().connect (sigc::bind (sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleKeyEditor")));  
336         }
337
338         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleKeyEditor"));
339         if (act) {
340                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
341         
342                 if (tact->get_active()) {
343                         key_editor->show_all ();
344                         key_editor->present ();
345                 } else {
346                         key_editor->hide ();
347                 } 
348         }
349 }
350
351 void
352 ARDOUR_UI::toggle_theme_manager ()
353 {
354         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleThemeManager"));
355         if (act) {
356                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
357         
358                 if (tact->get_active()) {
359                         theme_manager->show_all ();
360                         theme_manager->present ();
361                 } else {
362                         theme_manager->hide ();
363                 } 
364         }
365 }
366
367 void
368 ARDOUR_UI::create_bundle_manager ()
369 {
370         if (bundle_manager == 0) {
371                 bundle_manager = new BundleManager (*session);
372                 bundle_manager->signal_unmap().connect (sigc::bind (sigc::ptr_fun (&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleBundleManager")));
373         }
374 }
375
376 void
377 ARDOUR_UI::toggle_bundle_manager ()
378 {
379         create_bundle_manager ();
380         
381         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleBundleManager"));
382         if (act) {
383                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic (act);
384         
385                 if (tact->get_active()) {
386                         bundle_manager->show_all ();
387                         bundle_manager->present ();
388                 } else {
389                         bundle_manager->hide ();
390                 } 
391         }
392 }
393
394 int
395 ARDOUR_UI::create_route_params ()
396 {
397         if (route_params == 0) {
398                 route_params = new RouteParams_UI ();
399                 route_params->set_session (session);
400                 route_params->signal_unmap().connect (sigc::bind(sigc::ptr_fun(&ActionManager::uncheck_toggleaction), X_("<Actions>/Common/ToggleInspector")));
401         }
402         return 0;
403 }
404
405 void
406 ARDOUR_UI::toggle_route_params_window ()
407 {
408         if (create_route_params ()) {
409                 return;
410         }
411
412         RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleInspector"));
413         if (act) {
414                 RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
415         
416                 if (tact->get_active()) {
417                         route_params->show_all ();
418                         route_params->present ();
419                 } else {
420                         route_params->hide ();
421                 } 
422         }
423 }
424
425 void
426 ARDOUR_UI::handle_locations_change (Location* ignored)
427 {
428         if (session) {
429                 if (session->locations()->num_range_markers()) {
430                         ActionManager::set_sensitive (ActionManager::range_sensitive_actions, true);
431                 } else {
432                         ActionManager::set_sensitive (ActionManager::range_sensitive_actions, false);
433                 }
434         }
435 }