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