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