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