Merged with trunk (painfully)
[ardour.git] / gtk2_ardour / ardour_ui.cc
1 /*
2     Copyright (C) 1999-2002 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     $Id$
19 */
20
21 #include <algorithm>
22 #include <cmath>
23 #include <fcntl.h>
24 #include <signal.h>
25 #include <unistd.h>
26 #include <cerrno>
27 #include <fstream>
28
29 #include <iostream>
30
31 #include <gtkmm/messagedialog.h>
32 #include <gtkmm/accelmap.h>
33
34 #include <pbd/error.h>
35 #include <pbd/compose.h>
36 #include <pbd/pathscanner.h>
37 #include <pbd/failed_constructor.h>
38 #include <gtkmm2ext/gtk_ui.h>
39 #include <gtkmm2ext/utils.h>
40 #include <gtkmm2ext/click_box.h>
41 #include <gtkmm2ext/fastmeter.h>
42 #include <gtkmm2ext/stop_signal.h>
43 #include <gtkmm2ext/popup.h>
44
45 #include <midi++/port.h>
46 #include <midi++/mmc.h>
47
48 #include <ardour/ardour.h>
49 #include <ardour/port.h>
50 #include <ardour/audioengine.h>
51 #include <ardour/playlist.h>
52 #include <ardour/utils.h>
53 #include <ardour/diskstream.h>
54 #include <ardour/filesource.h>
55 #include <ardour/recent_sessions.h>
56 #include <ardour/session_diskstream.h>
57 #include <ardour/port.h>
58 #include <ardour/audio_track.h>
59
60 #include "actions.h"
61 #include "ardour_ui.h"
62 #include "public_editor.h"
63 #include "audio_clock.h"
64 #include "keyboard.h"
65 #include "mixer_ui.h"
66 #include "prompter.h"
67 #include "opts.h"
68 #include "keyboard_target.h"
69 #include "add_route_dialog.h"
70 #include "new_session_dialog.h"
71 #include "about.h"
72 #include "utils.h"
73 #include "gui_thread.h"
74 #include "color_manager.h"
75
76 #include "i18n.h"
77
78 using namespace ARDOUR;
79 using namespace Gtkmm2ext;
80 using namespace Gtk;
81 using namespace sigc;
82
83 ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
84
85 sigc::signal<void,bool> ARDOUR_UI::Blink;
86 sigc::signal<void>      ARDOUR_UI::RapidScreenUpdate;
87 sigc::signal<void>      ARDOUR_UI::SuperRapidScreenUpdate;
88 sigc::signal<void,jack_nframes_t> ARDOUR_UI::Clock;
89
90 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
91
92         : Gtkmm2ext::UI ("ardour", argcp, argvp, rcfile),
93           
94           primary_clock (X_("TransportClockDisplay"), true, false, true),
95           secondary_clock (X_("SecondaryClockDisplay"), true, false, true),
96           preroll_clock (X_("PreRollClock"), true, true),
97           postroll_clock (X_("PostRollClock"), true, true),
98
99           /* adjuster table */
100
101           adjuster_table (3, 3),
102
103           /* preroll stuff */
104
105           preroll_button (_("pre\nroll")),
106           postroll_button (_("post\nroll")),
107
108           /* big clock */
109
110           big_clock ("BigClockDisplay", true),
111
112           /* transport */
113
114           time_master_button (_("time\nmaster")),
115
116           shuttle_units_button (_("% ")),
117
118           punch_in_button (_("punch\nin")),
119           punch_out_button (_("punch\nout")),
120           auto_return_button (_("auto\nreturn")),
121           auto_play_button (_("auto\nplay")),
122           auto_input_button (_("auto\ninput")),
123           click_button (_("click")),
124           auditioning_alert_button (_("AUDITIONING")),
125           solo_alert_button (_("SOLO")),
126           shown_flag (false)
127
128 {
129         using namespace Gtk::Menu_Helpers;
130
131         Gtkmm2ext::init();
132         
133         about = 0;
134
135         if (theArdourUI == 0) {
136                 theArdourUI = this;
137         }
138
139         ActionManager::init ();
140
141         /* load colors */
142
143         color_manager = new ColorManager();
144
145         std::string color_file = ARDOUR::find_config_file("ardour.colors");
146         
147         color_manager->load (color_file);
148
149         m_new_session_dialog = new NewSessionDialog();
150         editor = 0;
151         mixer = 0;
152         session = 0;
153         _session_is_new = false;
154         big_clock_window = 0;
155         session_selector_window = 0;
156         last_key_press_time = 0;
157         connection_editor = 0;
158         add_route_dialog = 0;
159         route_params = 0;
160         option_editor = 0;
161         location_ui = 0;
162         sfdb = 0;
163         open_session_selector = 0;
164         have_configure_timeout = false;
165         have_disk_overrun_displayed = false;
166         have_disk_underrun_displayed = false;
167         _will_create_new_session_automatically = false;
168         session_loaded = false;
169         last_speed_displayed = -1.0f;
170
171         last_configure_time.tv_sec = 0;
172         last_configure_time.tv_usec = 0;
173
174         shuttle_grabbed = false;
175         shuttle_fract = 0.0;
176         shuttle_max_speed = 8.0f;
177
178         set_shuttle_units (Percentage);
179         set_shuttle_behaviour (Sprung);
180
181         shuttle_style_menu = 0;
182         shuttle_unit_menu = 0;
183
184         gettimeofday (&last_peak_grab, 0);
185         gettimeofday (&last_shuttle_request, 0);
186
187         ARDOUR::DiskStream::DeleteSources.connect (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread));
188         ARDOUR::DiskStream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
189         ARDOUR::DiskStream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
190
191         /* handle pending state with a dialog */
192
193         ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
194
195         /* have to wait for AudioEngine and Configuration before proceeding */
196 }
197
198 void
199 ARDOUR_UI::set_engine (AudioEngine& e)
200 {
201         engine = &e;
202
203         engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
204         engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
205         engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
206         engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
207
208         _tooltips.enable();
209
210         keyboard = new Keyboard;
211
212         if (setup_windows ()) {
213                 throw failed_constructor ();
214         }
215
216         if (GTK_ARDOUR::show_key_actions) {
217                 vector<string> names;
218                 vector<string> paths;
219                 vector<string> keys;
220                 vector<AccelKey> bindings;
221
222                 ActionManager::get_all_actions (names, paths, keys, bindings);
223
224                 vector<string>::iterator n;
225                 vector<string>::iterator k;
226                 for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) {
227                         cerr << "Action: " << (*n) << " bound to " << (*k) << endl;
228                 }
229
230                 exit (0);
231         }
232
233         /* start with timecode, metering enabled
234         */
235         
236         blink_timeout_tag = -1;
237
238         /* the global configuration object is now valid */
239
240         use_config ();
241
242         /* this being a GUI and all, we want peakfiles */
243
244         FileSource::set_build_peakfiles (true);
245         FileSource::set_build_missing_peakfiles (true);
246
247         if (Source::start_peak_thread ()) {
248                 throw failed_constructor();
249         }
250
251         /* start the time-of-day-clock */
252         
253         update_wall_clock ();
254         Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
255
256         update_disk_space ();
257         update_cpu_load ();
258         update_sample_rate (engine->frame_rate());
259
260         starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
261         stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
262 }
263
264 ARDOUR_UI::~ARDOUR_UI ()
265 {
266         save_ardour_state ();
267
268         if (keyboard) {
269                 delete keyboard;
270         }
271
272         if (editor) {
273                 delete editor;
274         }
275
276         if (mixer) {
277                 delete mixer;
278         }
279
280         if (add_route_dialog) {
281                 delete add_route_dialog;
282         }
283
284         Source::stop_peak_thread ();
285 }
286
287 gint
288 ARDOUR_UI::configure_timeout ()
289 {
290         struct timeval now;
291         struct timeval diff;
292
293         if (last_configure_time.tv_sec == 0 && last_configure_time.tv_usec == 0) {
294                 /* no configure events yet */
295                 return TRUE;
296         }
297
298         gettimeofday (&now, 0);
299         timersub (&now, &last_configure_time, &diff);
300
301         /* force a gap of 0.5 seconds since the last configure event
302          */
303
304         if (diff.tv_sec == 0 && diff.tv_usec < 500000) {
305                 return TRUE;
306         } else {
307                 have_configure_timeout = false;
308                 save_ardour_state ();
309                 return FALSE;
310         }
311 }
312
313 gboolean
314 ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
315 {
316         if (have_configure_timeout) {
317                 gettimeofday (&last_configure_time, 0);
318         } else {
319                 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
320                 have_configure_timeout = true;
321         }
322                 
323         return FALSE;
324 }
325
326 void
327 ARDOUR_UI::save_ardour_state ()
328 {
329         if (!keyboard || !mixer || !editor) {
330                 return;
331         }
332         
333         /* XXX this is all a bit dubious. add_extra_xml() uses
334            a different lifetime model from add_instant_xml().
335         */
336
337         XMLNode* node = new XMLNode (keyboard->get_state());
338         Config->add_extra_xml (*node);
339         Config->save_state();
340
341         XMLNode& enode (static_cast<Stateful*>(editor)->get_state());
342         XMLNode& mnode (mixer->get_state());
343
344         if (session) {
345                 session->add_instant_xml(enode, session->path());
346                 session->add_instant_xml(mnode, session->path());
347         } else {
348                 Config->add_instant_xml(enode, get_user_ardour_path());
349                 Config->add_instant_xml(mnode, get_user_ardour_path());
350         }
351
352         /* keybindings */
353
354         AccelMap::save ("ardour.saved_bindings");
355 }
356
357 void
358 ARDOUR_UI::startup ()
359 {
360         /* Once the UI is up and running, start the audio engine. Doing
361            this before the UI is up and running can cause problems
362            when not running with SCHED_FIFO, because the amount of
363            CPU and disk work needed to get the UI started can interfere
364            with the scheduling of the audio thread.
365         */
366
367         Glib::signal_idle().connect (mem_fun(*this, &ARDOUR_UI::start_engine));
368 }
369
370 void
371 ARDOUR_UI::finish()
372 {
373         if (session && session->dirty()) {
374                 switch (ask_about_saving_session(_("quit"))) {
375                 case -1:
376                         return;
377                         break;
378                 case 1:
379                         /* use the default name */
380                         if (save_state_canfail ("")) {
381                                 /* failed - don't quit */
382                                 MessageDialog msg (*editor, 
383                                                _("\
384 Ardour was unable to save your session.\n\n\
385 If you still wish to quit, please use the\n\n\
386 \"Just quit\" option."));
387                                 msg.run ();
388                                 return;
389                         }
390                         break;
391                 case 0:
392                         break;
393                 }
394         }
395         Config->save_state();
396         quit ();
397 }
398
399 int
400 ARDOUR_UI::ask_about_saving_session (const string & what)
401 {
402         ArdourDialog window (_("ardour: save session?"));
403         Gtk::HBox dhbox;  // the hbox for the image and text
404         Gtk::Label  prompt_label;
405         Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_WARNING,  Gtk::ICON_SIZE_DIALOG));
406
407         string msg;
408
409         msg = string_compose(_("Don't %1"), what);
410         window.add_button (msg, RESPONSE_REJECT);
411         msg = string_compose(_("Just %1"), what);
412         window.add_button (msg, RESPONSE_APPLY);
413         msg = string_compose(_("Save and %1"), what);
414         window.add_button (msg, RESPONSE_ACCEPT);
415
416         window.set_default_response (RESPONSE_ACCEPT);
417
418         Gtk::Button noquit_button (msg);
419         noquit_button.set_name ("EditorGTKButton");
420
421         string prompt;
422         string type;
423
424         if (session->snap_name() == session->name()) {
425                 type = _("session");
426         } else {
427                 type = _("snapshot");
428         }
429         prompt = string_compose(_("The %1\"%2\"\nhas not been saved.\n\nAny changes made this time\nwill be lost unless you save it.\n\nWhat do you want to do?"), 
430                          type, session->snap_name());
431         
432         prompt_label.set_text (prompt);
433         prompt_label.set_name (X_("PrompterLabel"));
434         prompt_label.set_alignment(ALIGN_LEFT, ALIGN_TOP);
435
436         dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP)
437 ;
438         dhbox.set_homogeneous (false);
439         dhbox.pack_start (*dimage, false, false, 5);
440         dhbox.pack_start (prompt_label, true, false, 5);
441         window.get_vbox()->pack_start (dhbox);
442
443         window.set_name (_("Prompter"));
444         window.set_position (Gtk::WIN_POS_MOUSE);
445         window.set_modal (true);
446         window.set_resizable (false);
447         window.show_all ();
448
449         save_the_session = 0;
450
451         editor->ensure_float (window);
452
453         ResponseType r = (ResponseType) window.run();
454
455         window.hide ();
456
457         switch (r) {
458         case RESPONSE_ACCEPT: // save and get out of here
459                 return 1;
460         case RESPONSE_APPLY:  // get out of here
461                 return 0;
462         default:
463                 break;
464         }
465
466         return -1;
467 }
468         
469 gint
470 ARDOUR_UI::every_second ()
471 {
472         update_cpu_load ();
473         update_buffer_load ();
474         update_disk_space ();
475         return TRUE;
476 }
477
478 gint
479 ARDOUR_UI::every_point_one_seconds ()
480 {
481         update_speed_display ();
482         RapidScreenUpdate(); /* EMIT_SIGNAL */
483         return TRUE;
484 }
485
486 gint
487 ARDOUR_UI::every_point_zero_one_seconds ()
488 {
489         SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
490         return TRUE;
491 }
492
493 void
494 ARDOUR_UI::update_sample_rate (jack_nframes_t ignored)
495 {
496         char buf[32];
497
498         ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
499
500         if (!engine->connected()) {
501
502                 snprintf (buf, sizeof (buf), _("disconnected"));
503
504         } else {
505
506                 jack_nframes_t rate = engine->frame_rate();
507                 
508                 if (fmod (rate, 1000.0) != 0.0) {
509                         snprintf (buf, sizeof (buf), _("SR: %.1f kHz / %4.1f msecs"), 
510                                   (float) rate/1000.0f,
511                                   (engine->frames_per_cycle() / (float) rate) * 1000.0f);
512                 } else {
513                         snprintf (buf, sizeof (buf), _("SR: %u kHz / %4.1f msecs"), 
514                                   rate/1000,
515                                   (engine->frames_per_cycle() / (float) rate) * 1000.0f);
516                 }
517         }
518
519         sample_rate_label.set_text (buf);
520 }
521
522 void
523 ARDOUR_UI::update_cpu_load ()
524 {
525         char buf[32];
526         snprintf (buf, sizeof (buf), _("DSP Load: %.1f%%"), engine->get_cpu_load());
527         cpu_load_label.set_text (buf);
528 }
529
530 void
531 ARDOUR_UI::update_buffer_load ()
532 {
533         char buf[64];
534
535         if (session) {
536                 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"), 
537                           session->playback_load(), session->capture_load());
538                 buffer_load_label.set_text (buf);
539         } else {
540                 buffer_load_label.set_text ("");
541         }
542 }
543
544 void
545 ARDOUR_UI::count_recenabled_diskstreams (DiskStream& ds)
546 {
547         if (ds.record_enabled()) {
548                 rec_enabled_diskstreams++;
549         }
550 }
551
552 void
553 ARDOUR_UI::update_disk_space()
554 {
555         if (session == 0) {
556                 return;
557         }
558
559         jack_nframes_t frames = session->available_capture_duration();
560         char buf[64];
561
562         if (frames == max_frames) {
563                 strcpy (buf, _("space: 24hrs+"));
564         } else {
565                 int hrs;
566                 int mins;
567                 int secs;
568                 jack_nframes_t fr = session->frame_rate();
569                 
570                 if (session->actively_recording()){
571                         
572                         rec_enabled_diskstreams = 0;
573                         session->foreach_diskstream (this, &ARDOUR_UI::count_recenabled_diskstreams);
574                         
575                         if (rec_enabled_diskstreams) {
576                                 frames /= rec_enabled_diskstreams;
577                         }
578                         
579                 } else {
580                         
581                         /* hmmm. shall we divide by the route count? or the diskstream count?
582                            or what? for now, do nothing ...
583                         */
584                         
585                 }
586                 
587                 hrs  = frames / (fr * 3600);
588                 frames -= hrs * fr * 3600;
589                 mins = frames / (fr * 60);
590                 frames -= mins * fr * 60;
591                 secs = frames / fr;
592                 
593                 snprintf (buf, sizeof(buf), _("space: %02dh:%02dm:%02ds"), hrs, mins, secs);
594         }
595
596         disk_space_label.set_text (buf);
597 }                 
598
599 gint
600 ARDOUR_UI::update_wall_clock ()
601 {
602         time_t now;
603         struct tm *tm_now;
604         char buf[16];
605
606         time (&now);
607         tm_now = localtime (&now);
608
609         sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
610         wall_clock_label.set_text (buf);
611
612         return TRUE;
613 }
614 void
615 ARDOUR_UI::control_methods_adjusted ()
616
617 {
618         int which_method;
619
620         which_method = (int) online_control_button->adjustment.get_value();
621         switch (which_method) {
622         case 0:
623                 allow_mmc_and_local ();
624                 break;
625         case 1:
626                 allow_mmc_only ();
627                 break;
628         case 2:
629                 allow_local_only ();
630                 break;
631         default:
632                 fatal << _("programming error: impossible control method") << endmsg;
633         }
634 }
635         
636
637 void
638 ARDOUR_UI::mmc_device_id_adjusted ()
639
640 {
641 #if 0
642         if (mmc) {
643                 int dev_id = (int) mmc_id_button->adjustment.get_value();
644                 mmc->set_device_id (dev_id);
645         }
646 #endif
647 }
648
649 gint
650 ARDOUR_UI::session_menu (GdkEventButton *ev)
651 {
652         session_popup_menu->popup (0, 0);
653         return TRUE;
654 }
655
656 void
657 ARDOUR_UI::redisplay_recent_sessions ()
658 {
659         vector<string *> *sessions;
660         vector<string *>::iterator i;
661         RecentSessionsSorter cmp;
662         
663         recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
664         recent_session_model->clear ();
665
666         RecentSessions rs;
667         ARDOUR::read_recent_sessions (rs);
668
669         if (rs.empty()) {
670                 recent_session_display.set_model (recent_session_model);
671                 return;
672         }
673
674         /* sort them alphabetically */
675         sort (rs.begin(), rs.end(), cmp);
676         sessions = new vector<string*>;
677
678         for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
679                 sessions->push_back (new string ((*i).second));
680         }
681
682         for (i = sessions->begin(); i != sessions->end(); ++i) {
683
684                 vector<string*>* states;
685                 vector<const gchar*> item;
686                 string fullpath = *(*i);
687                 
688                 /* remove any trailing / */
689
690                 if (fullpath[fullpath.length()-1] == '/') {
691                         fullpath = fullpath.substr (0, fullpath.length()-1);
692                 }
693
694                 /* now get available states for this session */
695
696                 if ((states = Session::possible_states (fullpath)) == 0) {
697                         /* no state file? */
698                         continue;
699                 }
700
701                 TreeModel::Row row = *(recent_session_model->append());
702
703                 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
704                 row[recent_session_columns.fullpath] = fullpath;
705
706                 if (states->size() > 1) {
707
708                         /* add the children */
709                         
710                         for (vector<string*>::iterator i2 = states->begin(); i2 != states->end(); ++i2) {
711                                 
712                                 TreeModel::Row child_row = *(recent_session_model->append (row.children()));
713
714                                 child_row[recent_session_columns.visible_name] = **i2;
715                                 child_row[recent_session_columns.fullpath] = fullpath;
716
717                                 delete *i2;
718                         }
719                 }
720
721                 delete states;
722         }
723
724         recent_session_display.set_model (recent_session_model);
725         delete sessions;
726 }
727
728 void
729 ARDOUR_UI::build_session_selector ()
730 {
731         session_selector_window = new ArdourDialog ("session selector");
732         
733         Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
734         
735         session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
736         session_selector_window->add_button (Stock::OPEN, RESPONSE_ACCEPT);
737         session_selector_window->set_default_response (RESPONSE_ACCEPT);
738         recent_session_model = TreeStore::create (recent_session_columns);
739         recent_session_display.set_model (recent_session_model);
740         recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
741         recent_session_display.set_headers_visible (false);
742         recent_session_display.get_selection()->set_mode (SELECTION_SINGLE);
743
744         recent_session_display.signal_row_activated().connect (mem_fun (*this, &ARDOUR_UI::recent_session_row_activated));
745
746         scroller->add (recent_session_display);
747         scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
748
749         session_selector_window->set_name ("SessionSelectorWindow");
750         session_selector_window->set_size_request (200, 400);
751         session_selector_window->get_vbox()->pack_start (*scroller);
752         session_selector_window->show_all_children();
753 }
754
755 void
756 ARDOUR_UI::recent_session_row_activated (const TreePath& path, TreeViewColumn* col)
757 {
758         session_selector_window->response (RESPONSE_ACCEPT);
759 }
760
761 void
762 ARDOUR_UI::open_recent_session ()
763 {
764         /* popup selector window */
765
766         if (session_selector_window == 0) {
767                 build_session_selector ();
768         }
769
770         redisplay_recent_sessions ();
771
772         ResponseType r = (ResponseType) session_selector_window->run ();
773
774         session_selector_window->hide();
775
776         switch (r) {
777         case RESPONSE_ACCEPT:
778                 break;
779         default:
780                 return;
781         }
782
783         Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
784
785         if (i == recent_session_model->children().end()) {
786                 return;
787         }
788         
789         Glib::ustring path = (*i)[recent_session_columns.fullpath];
790         Glib::ustring state = (*i)[recent_session_columns.visible_name];
791
792         _session_is_new = false;
793
794         load_session (path, state);
795 }
796
797 bool
798 ARDOUR_UI::filter_ardour_session_dirs (const FileFilter::Info& info) 
799 {
800         struct stat statbuf;
801
802         if (stat (info.filename.c_str(), &statbuf) != 0) {
803                 return false;
804         }
805
806         if (!S_ISDIR(statbuf.st_mode)) {
807                 return false;
808         }
809
810         // XXX Portability
811         
812         string session_file = info.filename;
813         session_file += '/';
814         session_file += Glib::path_get_basename (info.filename);
815         session_file += ".ardour";
816         
817         if (stat (session_file.c_str(), &statbuf) != 0) {
818                 return false;
819         }
820
821         return S_ISREG (statbuf.st_mode);
822 }
823
824 void
825 ARDOUR_UI::open_session ()
826 {
827         /* popup selector window */
828
829         if (open_session_selector == 0) {
830
831                 /* ardour sessions are folders */
832
833                 open_session_selector = new Gtk::FileChooserDialog (_("open session"), FILE_CHOOSER_ACTION_OPEN);
834                 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
835                 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
836
837                 FileFilter session_filter;
838                 session_filter.add_pattern ("*.ardour");
839                 session_filter.set_name (_("Ardour sessions"));
840                 open_session_selector->add_filter (session_filter);
841                 open_session_selector->set_filter (session_filter);
842         }
843
844         int response = open_session_selector->run();
845         open_session_selector->hide ();
846
847         switch (response) {
848         case RESPONSE_ACCEPT:
849                 break;
850         default:
851                 open_session_selector->hide();
852                 return;
853         }
854
855         open_session_selector->hide();
856         string session_path = open_session_selector->get_filename();
857         string path, name;
858         bool isnew;
859
860         if (session_path.length() > 0) {
861                 if (Session::find_session (session_path, path, name, isnew) == 0) {
862                         _session_is_new = isnew;
863                         load_session (path, name);
864                 }
865         }
866 }
867
868
869 void
870 ARDOUR_UI::session_add_midi_track ()
871 {
872         cerr << _("Patience is a virtue.\n");
873 }
874
875 void
876 ARDOUR_UI::session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode)
877 {
878         Route* route;
879
880         if (session == 0) {
881                 warning << _("You cannot add a track without a session already loaded.") << endmsg;
882                 return;
883         }
884
885         try { 
886                 if (disk) {
887                         if ((route = session->new_audio_track (input_channels, output_channels, mode)) == 0) {
888                                 error << _("could not create new audio track") << endmsg;
889                         }
890                 } else {
891                         if ((route = session->new_audio_route (input_channels, output_channels)) == 0) {
892                                 error << _("could not create new audio bus") << endmsg;
893                         }
894                 }
895                 
896 #if CONTROLOUTS
897                 if (need_control_room_outs) {
898                         pan_t pans[2];
899                         
900                         pans[0] = 0.5;
901                         pans[1] = 0.5;
902                         
903                         route->set_stereo_control_outs (control_lr_channels);
904                         route->control_outs()->set_stereo_pan (pans, this);
905                 }
906 #endif /* CONTROLOUTS */
907         }
908
909         catch (...) {
910                 MessageDialog msg (*editor, 
911                                    _("There are insufficient JACK ports available\n\
912 to create a new track or bus.\n\
913 You should save Ardour, exit and\n\
914 restart JACK with more ports."));
915                 msg.run ();
916         }
917 }
918
919 void
920 ARDOUR_UI::diskstream_added (DiskStream* ds)
921 {
922 }
923
924 void
925 ARDOUR_UI::do_transport_locate (jack_nframes_t new_position)
926 {
927         jack_nframes_t _preroll;
928
929         if (session) {
930                 _preroll = session->convert_to_frames_at (new_position, session->preroll);
931
932                 if (new_position > _preroll) {
933                         new_position -= _preroll;
934                 } else {
935                         new_position = 0;
936                 }
937
938                 session->request_locate (new_position);
939         }
940 }
941
942 void
943 ARDOUR_UI::transport_goto_start ()
944 {
945         if (session) {
946                 session->goto_start();
947
948                 
949                 /* force displayed area in editor to start no matter
950                    what "follow playhead" setting is.
951                 */
952                 
953                 if (editor) {
954                         editor->reposition_x_origin (session->current_start_frame());
955                 }
956         }
957 }
958
959 void
960 ARDOUR_UI::transport_goto_zero ()
961 {
962         if (session) {
963                 session->request_locate (0);
964
965                 
966                 /* force displayed area in editor to start no matter
967                    what "follow playhead" setting is.
968                 */
969                 
970                 if (editor) {
971                         editor->reposition_x_origin (0);
972                 }
973         }
974 }
975
976 void
977 ARDOUR_UI::transport_goto_end ()
978 {
979         if (session) {
980                 jack_nframes_t frame = session->current_end_frame();
981                 session->request_locate (frame);
982
983                 /* force displayed area in editor to start no matter
984                    what "follow playhead" setting is.
985                 */
986                 
987                 if (editor) {
988                         editor->reposition_x_origin (frame);
989                 }
990         }
991 }
992
993 void
994 ARDOUR_UI::transport_stop ()
995 {
996         if (!session) {
997                 return;
998         }
999
1000         if (session->is_auditioning()) {
1001                 session->cancel_audition ();
1002                 return;
1003         }
1004         
1005         if (session->get_auto_loop()) {
1006                 session->request_auto_loop (false);
1007         }
1008         
1009         session->request_stop ();
1010 }
1011
1012 void
1013 ARDOUR_UI::transport_stop_and_forget_capture ()
1014 {
1015         if (session) {
1016                 session->request_stop (true);
1017         }
1018 }
1019
1020 void
1021 ARDOUR_UI::remove_last_capture()
1022 {
1023         if (editor) {
1024                 editor->remove_last_capture();
1025         }
1026 }
1027
1028 void
1029 ARDOUR_UI::transport_record ()
1030 {
1031         if (session) {
1032                 switch (session->record_status()) {
1033                 case Session::Disabled:
1034                         if (session->ntracks() == 0) {
1035                                 string txt = _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu.");
1036                                 MessageDialog msg (*editor, txt);
1037                                 msg.run ();
1038                                 return;
1039                         }
1040                         session->maybe_enable_record ();
1041                         break;
1042                 case Session::Recording:
1043                 case Session::Enabled:
1044                         session->disable_record (true);
1045                 }
1046         }
1047 }
1048
1049 void
1050 ARDOUR_UI::transport_roll ()
1051 {
1052         bool rolling;
1053
1054         if (!session) {
1055                 return;
1056         }
1057
1058         rolling = session->transport_rolling ();
1059
1060         if (session->get_auto_loop()) {
1061                 session->request_auto_loop (false);
1062                 auto_loop_button.set_active (false);
1063                 roll_button.set_active (true);
1064         } else if (session->get_play_range ()) {
1065                 session->request_play_range (false);
1066                 play_selection_button.set_active (false);
1067         } else if (rolling) {
1068                 session->request_locate (session->last_transport_start(), true);
1069         }
1070
1071         session->request_transport_speed (1.0f);
1072 }
1073
1074 void
1075 ARDOUR_UI::transport_loop()
1076 {
1077         if (session) {
1078                 if (session->get_auto_loop()) {
1079                         if (session->transport_rolling()) {
1080                                 Location * looploc = session->locations()->auto_loop_location();
1081                                 if (looploc) {
1082                                         session->request_locate (looploc->start(), true);
1083                                 }
1084                         }
1085                 }
1086                 else {
1087                         session->request_auto_loop (true);
1088                 }
1089         }
1090 }
1091
1092 void
1093 ARDOUR_UI::transport_play_selection ()
1094 {
1095         if (!session) {
1096                 return;
1097         }
1098
1099         if (!session->get_play_range()) {
1100                 session->request_stop ();
1101         }
1102
1103         editor->play_selection ();
1104 }
1105
1106 void
1107 ARDOUR_UI::transport_rewind (int option)
1108 {
1109         float current_transport_speed;
1110  
1111         if (session) {
1112                 current_transport_speed = session->transport_speed();
1113                 
1114                 if (current_transport_speed >= 0.0f) {
1115                         switch (option) {
1116                         case 0:
1117                                 session->request_transport_speed (-1.0f);
1118                                 break;
1119                         case 1:
1120                                 session->request_transport_speed (-4.0f);
1121                                 break;
1122                         case -1:
1123                                 session->request_transport_speed (-0.5f);
1124                                 break;
1125                         }
1126                 } else {
1127                         /* speed up */
1128                         session->request_transport_speed (current_transport_speed * 1.5f);
1129                 }
1130         }
1131 }
1132
1133 void
1134 ARDOUR_UI::transport_forward (int option)
1135 {
1136         float current_transport_speed;
1137         
1138         if (session) {
1139                 current_transport_speed = session->transport_speed();
1140                 
1141                 if (current_transport_speed <= 0.0f) {
1142                         switch (option) {
1143                         case 0:
1144                                 session->request_transport_speed (1.0f);
1145                                 break;
1146                         case 1:
1147                                 session->request_transport_speed (4.0f);
1148                                 break;
1149                         case -1:
1150                                 session->request_transport_speed (0.5f);
1151                                 break;
1152                         }
1153                 } else {
1154                         /* speed up */
1155                         session->request_transport_speed (current_transport_speed * 1.5f);
1156                 }
1157         }
1158 }
1159
1160 void
1161 ARDOUR_UI::toggle_monitor_enable (guint32 dstream)
1162 {
1163         if (session == 0) {
1164                 return;
1165         }
1166
1167         DiskStream *ds;
1168
1169         if ((ds = session->diskstream_by_id (dstream)) != 0) {
1170                 Port *port = ds->io()->input (0);
1171                 port->request_monitor_input (!port->monitoring_input());
1172         }
1173 }
1174
1175 void
1176 ARDOUR_UI::toggle_record_enable (guint32 dstream)
1177 {
1178         if (session == 0) {
1179                 return;
1180         }
1181
1182         DiskStream *ds;
1183
1184         if ((ds = session->diskstream_by_id (dstream)) != 0) {
1185                 ds->set_record_enabled (!ds->record_enabled(), this);
1186         }
1187 }
1188
1189 void
1190 ARDOUR_UI::queue_transport_change ()
1191 {
1192         Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
1193 }
1194
1195 void
1196 ARDOUR_UI::map_transport_state ()
1197 {
1198         float sp = session->transport_speed();
1199
1200         if (sp == 1.0f) {
1201                 transport_rolling ();
1202         } else if (sp < 0.0f) {
1203                 transport_rewinding ();
1204         } else if (sp > 0.0f) {
1205                 transport_forwarding ();
1206         } else {
1207                 transport_stopped ();
1208         }
1209 }
1210
1211 void
1212 ARDOUR_UI::allow_local_only ()
1213 {
1214
1215 }
1216
1217 void
1218 ARDOUR_UI::allow_mmc_only ()
1219 {
1220
1221 }
1222
1223 void
1224 ARDOUR_UI::allow_mmc_and_local ()
1225 {
1226
1227 }
1228
1229 void
1230 ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg)
1231 {
1232         snprintf (buf, sizeof(buf), "%s", ((GlobalClickBox *) arg)->strings[
1233                 (int) adj.get_value()].c_str());
1234 }
1235
1236 void
1237 ARDOUR_UI::engine_stopped ()
1238 {
1239         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
1240         ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1241         ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1242 }
1243
1244
1245 void
1246 ARDOUR_UI::engine_running ()
1247 {
1248         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
1249         ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true);
1250         ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
1251 }
1252
1253 void
1254 ARDOUR_UI::engine_halted ()
1255 {
1256         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
1257
1258         ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1259         ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1260
1261         update_sample_rate (0);
1262
1263         MessageDialog msg (*editor, 
1264                            _("\
1265 JACK has either been shutdown or it\n\
1266 disconnected Ardour because Ardour\n\
1267 was not fast enough. You can save the\n\
1268 session and/or try to reconnect to JACK ."));
1269         msg.run ();
1270 }
1271
1272 int32_t
1273 ARDOUR_UI::do_engine_start ()
1274 {
1275         try { 
1276                 engine->start();
1277         }
1278
1279         catch (AudioEngine::PortRegistrationFailure& err) {
1280                 engine->stop ();
1281                 error << _("Unable to create all required ports")
1282                       << endmsg;
1283                 unload_session ();
1284                 return -1;
1285         }
1286
1287         catch (...) {
1288                 engine->stop ();
1289                 error << _("Unable to start the session running")
1290                       << endmsg;
1291                 unload_session ();
1292                 return -2;
1293         }
1294         
1295         return 0;
1296 }
1297
1298 gint
1299 ARDOUR_UI::start_engine ()
1300 {
1301         if (do_engine_start () == 0) {
1302                 if (session && _session_is_new) {
1303                         /* we need to retain initial visual 
1304                            settings for a new session 
1305                         */
1306                         session->save_state ("");
1307                 }
1308
1309                 /* there is too much going on, in too many threads, for us to 
1310                    end up with a clean session. So wait 1 second after loading,
1311                    and fix it up. its ugly, but until i come across a better
1312                    solution, its what we have.
1313                 */
1314
1315                 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::make_session_clean), 1000);
1316         }
1317
1318         return FALSE;
1319 }
1320
1321 void
1322 ARDOUR_UI::update_clocks ()
1323 {
1324          Clock (session->audible_frame()); /* EMIT_SIGNAL */
1325 }
1326
1327 void
1328 ARDOUR_UI::start_clocking ()
1329 {
1330         clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
1331 }
1332
1333 void
1334 ARDOUR_UI::stop_clocking ()
1335 {
1336         clock_signal_connection.disconnect ();
1337 }
1338         
1339 void
1340 ARDOUR_UI::toggle_clocking ()
1341 {
1342 #if 0
1343         if (clock_button.get_active()) {
1344                 start_clocking ();
1345         } else {
1346                 stop_clocking ();
1347         }
1348 #endif
1349 }
1350
1351 gint
1352 ARDOUR_UI::_blink (void *arg)
1353
1354 {
1355         ((ARDOUR_UI *) arg)->blink ();
1356         return TRUE;
1357 }
1358
1359 void
1360 ARDOUR_UI::blink ()
1361 {
1362          Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
1363 }
1364
1365 void
1366 ARDOUR_UI::start_blinking ()
1367 {
1368         /* Start the blink signal. Everybody with a blinking widget
1369            uses Blink to drive the widget's state.
1370         */
1371
1372         if (blink_timeout_tag < 0) {
1373                 blink_on = false;       
1374                 blink_timeout_tag = gtk_timeout_add (240, _blink, this);
1375         }
1376 }
1377
1378 void
1379 ARDOUR_UI::stop_blinking ()
1380 {
1381         if (blink_timeout_tag >= 0) {
1382                 gtk_timeout_remove (blink_timeout_tag);
1383                 blink_timeout_tag = -1;
1384         }
1385 }
1386
1387
1388 void
1389 ARDOUR_UI::add_diskstream_to_menu (DiskStream& dstream)
1390 {
1391         using namespace Gtk;
1392         using namespace Menu_Helpers;
1393
1394         if (dstream.hidden()) {
1395                 return;
1396         }
1397
1398         MenuList& items = diskstream_menu->items();
1399         items.push_back (MenuElem (dstream.name(), bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), (gint32) dstream.id())));
1400 }
1401         
1402 void
1403 ARDOUR_UI::diskstream_selected (gint32 id)
1404 {
1405         selected_dstream = id;
1406         Main::quit ();
1407 }
1408
1409 gint32
1410 ARDOUR_UI::select_diskstream (GdkEventButton *ev)
1411 {
1412         using namespace Gtk;
1413         using namespace Menu_Helpers;
1414
1415         if (session == 0) {
1416                 return -1;
1417         }
1418
1419         diskstream_menu = new Menu();
1420         diskstream_menu->set_name ("ArdourContextMenu");
1421         using namespace Gtk;
1422         using namespace Menu_Helpers;
1423
1424         MenuList& items = diskstream_menu->items();
1425         items.push_back (MenuElem (_("No Stream"), (bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), -1))));
1426
1427         session->foreach_diskstream (this, &ARDOUR_UI::add_diskstream_to_menu);
1428
1429         if (ev) {
1430                 diskstream_menu->popup (ev->button, ev->time);
1431         } else {
1432                 diskstream_menu->popup (0, 0);
1433         }
1434
1435         selected_dstream = -1;
1436
1437         Main::run ();
1438
1439         delete diskstream_menu;
1440
1441         return selected_dstream;
1442 }
1443
1444 void
1445 ARDOUR_UI::name_io_setup (AudioEngine& engine, 
1446                           string& buf,
1447                           IO& io,
1448                           bool in)
1449 {
1450         if (in) {
1451                 if (io.n_inputs() == 0) {
1452                         buf = _("none");
1453                         return;
1454                 }
1455                 
1456                 /* XXX we're not handling multiple ports yet. */
1457
1458                 const char **connections = io.input(0)->get_connections();
1459                 
1460                 if (connections == 0 || connections[0] == '\0') {
1461                         buf = _("off");
1462                 } else {
1463                         buf = connections[0];
1464                 }
1465
1466                 free (connections);
1467
1468         } else {
1469
1470                 if (io.n_outputs() == 0) {
1471                         buf = _("none");
1472                         return;
1473                 }
1474                 
1475                 /* XXX we're not handling multiple ports yet. */
1476
1477                 const char **connections = io.output(0)->get_connections();
1478                 
1479                 if (connections == 0 || connections[0] == '\0') {
1480                         buf = _("off");
1481                 } else {
1482                         buf = connections[0];
1483                 }
1484
1485                 free (connections);
1486         }
1487 }
1488
1489 void
1490 ARDOUR_UI::snapshot_session ()
1491 {
1492         ArdourPrompter prompter (true);
1493         string snapname;
1494         string now;
1495         time_t n;
1496
1497         time (&n);
1498         now = ctime (&n);
1499         now = now.substr (20, 4) + now.substr (3, 16) + " (" + now.substr (0, 3) + ")";
1500
1501         prompter.set_name ("Prompter");
1502         prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1503         prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
1504         prompter.set_prompt (_("Name of New Snapshot"));
1505         prompter.set_initial_text (now);
1506         
1507         switch (prompter.run()) {
1508         case RESPONSE_ACCEPT:
1509                 prompter.get_result (snapname);
1510                 if (snapname.length()){
1511                         save_state (snapname);
1512                 }
1513                 break;
1514
1515         default:
1516                 break;
1517         }
1518 }
1519
1520 void
1521 ARDOUR_UI::save_state (const string & name)
1522 {
1523         (void) save_state_canfail (name);
1524 }
1525                 
1526 int
1527 ARDOUR_UI::save_state_canfail (string name)
1528 {
1529         if (session) {
1530                 int ret;
1531
1532                 if (name.length() == 0) {
1533                         name = session->snap_name();
1534                 }
1535
1536                 if ((ret = session->save_state (name)) != 0) {
1537                         return ret;
1538                 }
1539         }
1540         save_ardour_state (); /* XXX cannot fail? yeah, right ... */
1541         return 0;
1542 }
1543
1544 void
1545 ARDOUR_UI::restore_state (string name)
1546 {
1547         if (session) {
1548                 if (name.length() == 0) {
1549                         name = session->name();
1550                 }
1551                 session->restore_state (name);
1552         }
1553 }
1554
1555 void
1556 ARDOUR_UI::primary_clock_value_changed ()
1557 {
1558         if (session) {
1559                 session->request_locate (primary_clock.current_time ());
1560         }
1561 }
1562
1563 void
1564 ARDOUR_UI::secondary_clock_value_changed ()
1565 {
1566         if (session) {
1567                 session->request_locate (secondary_clock.current_time ());
1568         }
1569 }
1570
1571 void
1572 ARDOUR_UI::rec_enable_button_blink (bool onoff, DiskStream *dstream, Widget *w)
1573 {
1574         if (session && dstream && dstream->record_enabled()) {
1575
1576                 Session::RecordState rs;
1577                 
1578                 rs = session->record_status ();
1579
1580                 switch (rs) {
1581                 case Session::Disabled:
1582                 case Session::Enabled:
1583                         if (w->get_state() != STATE_SELECTED) {
1584                                 w->set_state (STATE_SELECTED);
1585                         }
1586                         break;
1587
1588                 case Session::Recording:
1589                         if (w->get_state() != STATE_ACTIVE) {
1590                                 w->set_state (STATE_ACTIVE);
1591                         }
1592                         break;
1593                 }
1594
1595         } else {
1596                 if (w->get_state() != STATE_NORMAL) {
1597                         w->set_state (STATE_NORMAL);
1598                 }
1599         }
1600 }
1601
1602 void
1603 ARDOUR_UI::transport_rec_enable_blink (bool onoff) 
1604 {
1605         if (session == 0) {
1606                 return;
1607         }
1608         
1609         switch (session->record_status()) {
1610         case Session::Enabled:
1611                 if (onoff) {
1612                         rec_button.set_state (1);
1613                 } else {
1614                         rec_button.set_state (0);
1615                 }
1616                 break;
1617
1618         case Session::Recording:
1619                 rec_button.set_state (2);
1620                 break;
1621
1622         default:
1623                 rec_button.set_state (0);
1624                 break;
1625         }
1626 }
1627
1628 gint
1629 ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
1630 {
1631         window->hide();
1632         Gtk::Main::quit ();
1633         return TRUE;
1634 }
1635
1636 void
1637 ARDOUR_UI::start_keyboard_prefix ()
1638 {
1639         keyboard->start_prefix();
1640 }
1641
1642 void
1643 ARDOUR_UI::save_template ()
1644
1645 {
1646         ArdourPrompter prompter (true);
1647         string name;
1648
1649         prompter.set_name (X_("Prompter"));
1650         prompter.set_prompt (_("Name for mix template:"));
1651         prompter.set_initial_text(session->name() + _("-template"));
1652         prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1653         prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
1654
1655         switch (prompter.run()) {
1656         case RESPONSE_ACCEPT:
1657                 prompter.get_result (name);
1658                 
1659                 if (name.length()) {
1660                         session->save_template (name);
1661                 }
1662                 break;
1663
1664         default:
1665                 break;
1666         }
1667 }
1668
1669 void
1670 ARDOUR_UI::new_session (bool startup, std::string predetermined_path)
1671 {
1672         m_new_session_dialog->show();
1673         m_new_session_dialog->set_modal(true);
1674         m_new_session_dialog->set_name(predetermined_path);
1675         m_new_session_dialog->reset_recent();
1676
1677         int response = Gtk::RESPONSE_CANCEL;
1678
1679         do {
1680                 response = m_new_session_dialog->run ();
1681                 if(response == Gtk::RESPONSE_CANCEL || response == Gtk::RESPONSE_DELETE_EVENT) {
1682                   quit();
1683                   return;
1684
1685                 } else if (response == Gtk::RESPONSE_NONE) {
1686                   /* Clear was pressed */
1687                   m_new_session_dialog->reset();
1688
1689                 } else if (response == Gtk::RESPONSE_YES) {
1690                   /* YES  == OPEN, but there's no enum for that */
1691                   std::string session_name = m_new_session_dialog->session_name();
1692                   std::string session_path = m_new_session_dialog->session_folder();
1693                   load_session (session_path, session_name);
1694
1695
1696                 } else if (response == Gtk::RESPONSE_OK) {
1697                   if (m_new_session_dialog->get_current_page() == 1) {
1698
1699                     /* XXX this is a bit of a hack.. 
1700                        i really want the new sesion dialog to return RESPONSE_YES
1701                        if we're on page 1 (the load page)
1702                        Unfortunately i can't see how atm.. 
1703                     */
1704                         std::string session_name = m_new_session_dialog->session_name();
1705                         std::string session_path = m_new_session_dialog->session_folder();
1706                         load_session (session_path, session_name);
1707
1708                   } else {
1709
1710                         _session_is_new = true;
1711                         
1712                         std::string session_name = m_new_session_dialog->session_name();
1713                         std::string session_path = m_new_session_dialog->session_folder();
1714                         
1715
1716                           //XXX This is needed because session constructor wants a 
1717                           //non-existant path. hopefully this will be fixed at some point.
1718                         
1719                         session_path = Glib::build_filename(session_path, session_name);
1720                         
1721                         std::string template_name = m_new_session_dialog->session_template_name();
1722                         
1723                         if (m_new_session_dialog->use_session_template()) {
1724                                 
1725                                 load_session (session_path, session_name, &template_name);
1726                                 
1727                         } else {
1728                                 
1729                                 uint32_t cchns;
1730                                 uint32_t mchns;
1731                                 Session::AutoConnectOption iconnect;
1732                                 Session::AutoConnectOption oconnect;
1733                                 
1734                                 if (m_new_session_dialog->create_control_bus()) {
1735                                         cchns = (uint32_t) m_new_session_dialog->control_channel_count();
1736                                 } else {
1737                                         cchns = 0;
1738                                 }
1739                                 
1740                                 if (m_new_session_dialog->create_master_bus()) {
1741                                         mchns = (uint32_t) m_new_session_dialog->master_channel_count();
1742                                 } else {
1743                                         mchns = 0;
1744                                 }
1745                                 
1746                                 if (m_new_session_dialog->connect_inputs()) {
1747                                         iconnect = Session::AutoConnectPhysical;
1748                                 } else {
1749                                         iconnect = Session::AutoConnectOption (0);
1750                                 }
1751                                 
1752                                 /// @todo some minor tweaks.
1753
1754                                 if (m_new_session_dialog->connect_outs_to_master()) {
1755                                         oconnect = Session::AutoConnectMaster;
1756                                 } else if (m_new_session_dialog->connect_outs_to_physical()) {
1757                                         oconnect = Session::AutoConnectPhysical;
1758                                 } else {
1759                                         oconnect = Session::AutoConnectOption (0);
1760                                 } 
1761                                 
1762                                 uint32_t nphysin = (uint32_t) m_new_session_dialog->input_limit_count();
1763                                 uint32_t nphysout = (uint32_t) m_new_session_dialog->output_limit_count();
1764                                 
1765                                 build_session (session_path,
1766                                                session_name,
1767                                                cchns,
1768                                                mchns,
1769                                                iconnect,
1770                                                oconnect,
1771                                                nphysin,
1772                                                nphysout, 
1773                                                engine->frame_rate() * 60 * 5);
1774                         }
1775                   }     
1776                 }
1777                 
1778         } while (response == Gtk::RESPONSE_NONE);
1779         m_new_session_dialog->hide();
1780         show();
1781
1782 }
1783
1784 void
1785 ARDOUR_UI::close_session()
1786 {
1787   unload_session();
1788   new_session ();
1789 }
1790
1791 int
1792 ARDOUR_UI::load_session (const string & path, const string & snap_name, string* mix_template)
1793 {
1794         Session *new_session;
1795         int x;
1796         session_loaded = false;
1797         x = unload_session ();
1798
1799         if (x < 0) {
1800                 return -1;
1801         } else if (x > 0) {
1802                 return 0;
1803         }
1804
1805         /* if it already exists, we must have write access */
1806
1807         if (::access (path.c_str(), F_OK) == 0 && ::access (path.c_str(), W_OK)) {
1808                 MessageDialog msg (*editor, _("\
1809 You do not have write access to this session.\n\
1810 This prevents the session from being loaded."));
1811                 msg.run ();
1812                 return -1;
1813         }
1814
1815         try {
1816                 new_session = new Session (*engine, path, snap_name, mix_template);
1817         }
1818
1819         catch (...) {
1820
1821                 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
1822                 return -1;
1823         }
1824
1825         connect_to_session (new_session);
1826
1827         //if (engine->running()) {
1828         //mixer->show_window();
1829         //}
1830         session_loaded = true;
1831         return 0;
1832 }
1833
1834 int
1835 ARDOUR_UI::make_session_clean ()
1836 {
1837         if (session) {
1838                 session->set_clean ();
1839         }
1840
1841         show ();
1842
1843         return FALSE;
1844 }
1845
1846 int
1847 ARDOUR_UI::build_session (const string & path, const string & snap_name, 
1848                           uint32_t control_channels,
1849                           uint32_t master_channels, 
1850                           Session::AutoConnectOption input_connect,
1851                           Session::AutoConnectOption output_connect,
1852                           uint32_t nphysin,
1853                           uint32_t nphysout,
1854                           jack_nframes_t initial_length)
1855 {
1856         Session *new_session;
1857         int x;
1858
1859         session_loaded = false;
1860         x = unload_session ();
1861         if (x < 0) {
1862                 return -1;
1863         } else if (x > 0) {
1864                 return 0;
1865         }
1866         
1867         _session_is_new = true;
1868
1869         try {
1870                 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
1871                                            control_channels, master_channels, nphysin, nphysout, initial_length);
1872         }
1873
1874         catch (...) {
1875
1876                 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
1877                 return -1;
1878         }
1879
1880         connect_to_session (new_session);
1881
1882         //if (engine->running()) {
1883         //mixer->show_window();
1884         //}
1885         session_loaded = true;
1886         return 0;
1887 }
1888
1889 void
1890 ARDOUR_UI::show ()
1891 {
1892         if (editor) {
1893                 editor->show_window ();
1894                 shown_flag = true;
1895         }
1896
1897         if (session && mixer) {
1898                 // mixer->show_window ();
1899         }
1900         
1901         if (about) {
1902                 about->present ();
1903         }
1904 }
1905
1906 void
1907 ARDOUR_UI::show_splash ()
1908 {
1909         if (about == 0) {
1910                 about = new About();
1911         }
1912         about->present();
1913 }
1914
1915 void
1916 ARDOUR_UI::hide_splash ()
1917 {
1918         if (about) {
1919                 // about->hide();
1920         }
1921 }
1922
1923 void
1924 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title, const string & msg)
1925 {
1926         size_t removed;
1927
1928         removed = rep.paths.size();
1929
1930         if (removed == 0) {
1931                 MessageDialog msgd (*editor,
1932                                     _("No audio files were ready for cleanup"), 
1933                                     true,
1934                                     Gtk::MESSAGE_INFO,
1935                                     (Gtk::ButtonsType)(Gtk::BUTTONS_CLOSE)  );
1936                 msgd.set_secondary_text (_("If this seems suprising, \n\
1937 check for any existing snapshots.\n\
1938 These may still include regions that\n\
1939 require some unused files to continue to exist."));
1940         
1941                 msgd.run ();
1942                 return;
1943         } 
1944
1945         ArdourDialog results (_("ardour: cleanup"), true, false);
1946         
1947         struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
1948             CleanupResultsModelColumns() { 
1949                     add (visible_name);
1950                     add (fullpath);
1951             }
1952             Gtk::TreeModelColumn<Glib::ustring> visible_name;
1953             Gtk::TreeModelColumn<Glib::ustring> fullpath;
1954         };
1955
1956         
1957         CleanupResultsModelColumns results_columns;
1958         Glib::RefPtr<Gtk::ListStore> results_model;
1959         Gtk::TreeView results_display;
1960         
1961         results_model = ListStore::create (results_columns);
1962         results_display.set_model (results_model);
1963         results_display.append_column (list_title, results_columns.visible_name);
1964
1965         results_display.set_name ("CleanupResultsList");
1966         results_display.set_headers_visible (true);
1967         results_display.set_headers_clickable (false);
1968         results_display.set_reorderable (false);
1969
1970         Gtk::ScrolledWindow list_scroller;
1971         Gtk::Label txt;
1972         Gtk::VBox dvbox;
1973         Gtk::HBox dhbox;  // the hbox for the image and text
1974         Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
1975         Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO,  Gtk::ICON_SIZE_DIALOG));
1976
1977         dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
1978
1979         if (rep.space < 1048576.0f) {
1980                 if (removed > 1) {
1981                   txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
1982                 } else {
1983                         txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
1984                 }
1985         } else {
1986                 if (removed > 1) {
1987                         txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
1988                 } else {
1989                         txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
1990                 }
1991         }
1992
1993         dhbox.pack_start (*dimage, true, false, 5);
1994         dhbox.pack_start (txt, true, false, 5);
1995
1996         for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
1997                 TreeModel::Row row = *(results_model->append());
1998                 row[results_columns.visible_name] = *i;
1999                 row[results_columns.fullpath] = *i;
2000         }
2001         
2002         list_scroller.add (results_display);
2003         list_scroller.set_size_request (-1, 150);
2004         list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2005
2006         dvbox.pack_start (dhbox, true, false, 5);
2007         dvbox.pack_start (list_scroller, true, false, 5);
2008         ddhbox.pack_start (dvbox, true, false, 5);
2009
2010         results.get_vbox()->pack_start (ddhbox, true, false, 5);
2011         results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
2012         results.set_default_response (RESPONSE_CLOSE);
2013         results.set_position (Gtk::WIN_POS_MOUSE);
2014         results.show_all_children ();
2015         results.set_resizable (false);
2016
2017         results.run ();
2018
2019 }
2020
2021 void
2022 ARDOUR_UI::cleanup ()
2023 {
2024         if (session == 0) {
2025                 /* shouldn't happen: menu item is insensitive */
2026                 return;
2027         }
2028
2029
2030         MessageDialog  checker (_("Are you sure you want to cleanup?"),
2031                                 true,
2032                                 Gtk::MESSAGE_QUESTION,
2033                                 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
2034
2035         checker.set_secondary_text(_("Cleanup is a destructive operation.\n\
2036 ALL undo/redo information will be lost if you cleanup.\n\
2037 After cleanup, unused audio files will be moved to a \
2038 \"dead sounds\" location."));
2039         
2040         checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2041         checker.add_button (_("Clean Up"), RESPONSE_ACCEPT);
2042         checker.set_default_response (RESPONSE_CANCEL);
2043
2044         checker.set_name (_("CleanupDialog"));
2045         checker.set_wmclass (_("ardour_cleanup"), "Ardour");
2046         checker.set_position (Gtk::WIN_POS_MOUSE);
2047
2048         switch (checker.run()) {
2049         case RESPONSE_ACCEPT:
2050                 break;
2051         default:
2052                 return;
2053         }
2054
2055         Session::cleanup_report rep;
2056
2057         editor->prepare_for_cleanup ();
2058
2059         if (session->cleanup_sources (rep)) {
2060                 return;
2061         }
2062         checker.hide();
2063         display_cleanup_results (rep, 
2064                                  _("cleaned files"),
2065                                  _("\
2066 The following %1 %2 not in use and \n\
2067 have been moved to:\n\
2068 %3. \n\n\
2069 Flushing the wastebasket will \n\
2070 release an additional\n\
2071 %4 %5bytes of disk space.\n"
2072                                          ));
2073 }
2074
2075 void
2076 ARDOUR_UI::flush_trash ()
2077 {
2078         if (session == 0) {
2079                 /* shouldn't happen: menu item is insensitive */
2080                 return;
2081         }
2082
2083         Session::cleanup_report rep;
2084
2085         if (session->cleanup_trash_sources (rep)) {
2086                 return;
2087         }
2088
2089         display_cleanup_results (rep, 
2090                                  _("deleted file"),
2091                                  _("The following %1 %2 deleted from\n\
2092 %3,\n\
2093 releasing %4 %5bytes of disk space"));
2094 }
2095
2096 void
2097 ARDOUR_UI::add_route ()
2098 {
2099         int count;
2100
2101         if (!session) {
2102                 return;
2103         }
2104
2105         if (add_route_dialog == 0) {
2106                 add_route_dialog = new AddRouteDialog;
2107                 editor->ensure_float (*add_route_dialog);
2108         }
2109
2110         if (add_route_dialog->is_visible()) {
2111                 /* we're already doing this */
2112                 return;
2113         }
2114
2115         ResponseType r = (ResponseType) add_route_dialog->run ();
2116         
2117         add_route_dialog->hide();
2118
2119         switch (r) {
2120         case RESPONSE_ACCEPT:
2121                 break;
2122         default:
2123                 return;
2124                 break;
2125         }
2126
2127         if ((count = add_route_dialog->count()) <= 0) {
2128                 return;
2129         }
2130
2131         uint32_t input_chan = add_route_dialog->channels ();
2132         uint32_t output_chan;
2133         string name_template = add_route_dialog->name_template ();
2134         bool track = add_route_dialog->track ();
2135
2136         Session::AutoConnectOption oac = session->get_output_auto_connect();
2137
2138         if (oac & Session::AutoConnectMaster) {
2139                 output_chan = (session->master_out() ? session->master_out()->n_inputs() : input_chan);
2140         } else {
2141                 output_chan = input_chan;
2142         }
2143
2144         /* XXX do something with name template */
2145
2146         while (count) {
2147                 if (track) {
2148                         session_add_audio_track (input_chan, output_chan, add_route_dialog->mode());
2149                 } else {
2150                         session_add_audio_bus (input_chan, output_chan);
2151                 }
2152                 --count;
2153                 
2154                 while (Main::events_pending()) {
2155                         Main::iteration ();
2156                 }
2157         }
2158 }
2159
2160 XMLNode*
2161 ARDOUR_UI::mixer_settings () const
2162 {
2163         XMLNode* node = 0;
2164
2165         if (session) {
2166                 node = session->instant_xml(X_("Mixer"), session->path());
2167         } else {
2168                 node = Config->instant_xml(X_("Mixer"), get_user_ardour_path());
2169         }
2170
2171         if (!node) {
2172                 node = new XMLNode (X_("Mixer"));
2173         }
2174
2175         return node;
2176 }
2177
2178 XMLNode*
2179 ARDOUR_UI::editor_settings () const
2180 {
2181         XMLNode* node = 0;
2182
2183         if (session) {
2184                 node = session->instant_xml(X_("Editor"), session->path());
2185         } else {
2186                 node = Config->instant_xml(X_("Editor"), get_user_ardour_path());
2187         }
2188
2189         if (!node) {
2190                 node = new XMLNode (X_("Editor"));
2191         }
2192         return node;
2193 }
2194
2195 XMLNode*
2196 ARDOUR_UI::keyboard_settings () const
2197 {
2198         XMLNode* node = 0;
2199
2200         node = Config->extra_xml(X_("Keyboard"));
2201         
2202         if (!node) {
2203                 node = new XMLNode (X_("Keyboard"));
2204         }
2205         return node;
2206 }
2207
2208 void
2209 ARDOUR_UI::halt_on_xrun_message ()
2210 {
2211         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
2212
2213         MessageDialog msg (*editor,
2214                            _("Recording was stopped because your system could not keep up."));
2215         msg.run ();
2216 }
2217
2218 void 
2219 ARDOUR_UI::delete_sources_in_the_right_thread (list<ARDOUR::Source*>* deletion_list)
2220 {
2221         ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread), deletion_list));
2222
2223         for (list<Source*>::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) {
2224                 delete *i;
2225         }
2226
2227         delete deletion_list;
2228 }
2229
2230 void
2231 ARDOUR_UI::disk_overrun_handler ()
2232 {
2233         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2234
2235         if (!have_disk_overrun_displayed) {
2236                 have_disk_overrun_displayed = true;
2237                 MessageDialog msg (*editor, X_("diskrate dialog"), _("\
2238 The disk system on your computer\n\
2239 was not able to keep up with Ardour.\n\
2240 \n\
2241 Specifically, it failed to write data to disk\n\
2242 quickly enough to keep up with recording.\n"));
2243                 msg.run ();
2244                 have_disk_overrun_displayed = false;
2245         }
2246 }
2247
2248 void
2249 ARDOUR_UI::disk_underrun_handler ()
2250 {
2251         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2252
2253         if (!have_disk_underrun_displayed) {
2254                 have_disk_underrun_displayed = true;
2255                 MessageDialog msg (*editor,
2256                         (_("The disk system on your computer\n\
2257 was not able to keep up with Ardour.\n\
2258 \n\
2259 Specifically, it failed to read data from disk\n\
2260 quickly enough to keep up with playback.\n")));
2261                 msg.run ();
2262                 have_disk_underrun_displayed = false;
2263         } 
2264 }
2265
2266 void
2267 ARDOUR_UI::disk_underrun_message_gone ()
2268 {
2269         have_disk_underrun_displayed = false;
2270 }
2271
2272 void
2273 ARDOUR_UI::disk_overrun_message_gone ()
2274 {
2275         have_disk_underrun_displayed = false;
2276 }
2277
2278 int
2279 ARDOUR_UI::pending_state_dialog ()
2280 {
2281         ArdourDialog dialog ("pending state dialog");
2282         Label  message (_("\
2283 This session appears to have been in\n\
2284 middle of recording when ardour or\n\
2285 the computer was shutdown.\n\
2286 \n\
2287 Ardour can recover any captured audio for\n\
2288 you, or it can ignore it. Please decide\n\
2289 what you would like to do.\n"));
2290
2291         dialog.get_vbox()->pack_start (message);
2292         dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
2293         dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
2294
2295         dialog.set_position (WIN_POS_CENTER);
2296         dialog.show_all ();
2297         
2298         switch (dialog.run ()) {
2299         case RESPONSE_ACCEPT:
2300                 return 1;
2301         default:
2302                 return 0;
2303         }
2304 }
2305         
2306 void
2307 ARDOUR_UI::disconnect_from_jack ()
2308 {
2309         if (engine) {
2310                 if( engine->disconnect_from_jack ()) {
2311                         MessageDialog msg (*editor, _("Could not disconnect from JACK"));
2312                         msg.run ();
2313                 }
2314
2315                 update_sample_rate (0);
2316         }
2317 }
2318
2319 void
2320 ARDOUR_UI::reconnect_to_jack ()
2321 {
2322         if (engine) {
2323                 if (engine->reconnect_to_jack ()) {
2324                         MessageDialog msg (*editor,  _("Could not reconnect to JACK"));
2325                         msg.run ();
2326                 }
2327
2328                 update_sample_rate (0);
2329         }
2330 }
2331
2332 void
2333 ARDOUR_UI::set_jack_buffer_size (jack_nframes_t nframes)
2334 {
2335         engine->request_buffer_size (nframes);
2336         update_sample_rate (0);
2337 }
2338
2339 int
2340 ARDOUR_UI::cmdline_new_session (string path)
2341 {
2342         if (path[0] != '/') {
2343                 char buf[PATH_MAX+1];
2344                 string str;
2345
2346                 getcwd (buf, sizeof (buf));
2347                 str = buf;
2348                 str += '/';
2349                 str += path;
2350                 path = str;
2351         }
2352
2353         new_session (false, path);
2354
2355         _will_create_new_session_automatically = false; /* done it */
2356         return FALSE; /* don't call it again */
2357 }
2358
2359 void
2360 ARDOUR_UI::set_native_file_header_format (HeaderFormat hf)
2361 {
2362         Glib::RefPtr<Action> act;
2363         
2364         switch (hf) {
2365         case BWF:
2366                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
2367                 break;
2368         case WAVE:
2369                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
2370                 break;
2371         case WAVE64:
2372                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
2373                 break;
2374         case iXML:
2375                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
2376                 break;
2377         case RF64:
2378                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
2379                 break;
2380         }
2381
2382         if (act) {
2383                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2384                 if (ract && ract->get_active() && Config->get_native_file_header_format() != hf) {
2385                         Config->set_native_file_header_format (hf);
2386                         if (session) {
2387                                 session->reset_native_file_format ();
2388                         }
2389                 }
2390         }
2391 }
2392
2393 void
2394 ARDOUR_UI::set_native_file_data_format (SampleFormat sf)
2395 {
2396         Glib::RefPtr<Action> act;
2397         
2398         switch (sf) {
2399         case FormatFloat:
2400                 act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
2401                 break;
2402         case FormatInt24:
2403                 act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
2404                 break;
2405         }
2406
2407         if (act) {
2408                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2409
2410                 if (ract && ract->get_active() && Config->get_native_file_data_format() != sf) {
2411                         Config->set_native_file_data_format (sf);
2412                         if (session) {
2413                                 session->reset_native_file_format ();
2414                         }
2415                 }
2416         }
2417 }
2418
2419 void
2420 ARDOUR_UI::use_config ()
2421 {
2422         Glib::RefPtr<Action> act;
2423
2424         switch (Config->get_native_file_data_format ()) {
2425         case FormatFloat:
2426                 act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
2427                 break;
2428         case FormatInt24:
2429                 act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
2430                 break;
2431         }
2432
2433         if (act) {
2434                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2435                 ract->set_active ();
2436         }       
2437
2438         switch (Config->get_native_file_header_format ()) {
2439         case BWF:
2440                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
2441                 break;
2442         case WAVE:
2443                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
2444                 break;
2445         case WAVE64:
2446                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
2447                 break;
2448         case iXML:
2449                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
2450                 break;
2451         case RF64:
2452                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
2453                 break;
2454         }
2455
2456         if (act) {
2457                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2458                 ract->set_active ();
2459         }       
2460 }