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