f0848e6f89faebcb954ff27f78ed2028ee7354a6
[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         /* load colors */
141
142         color_manager = new ColorManager();
143
144         std::string color_file = ARDOUR::find_config_file("ardour.colors");
145         
146         color_manager->load (color_file);
147
148         editor = 0;
149         mixer = 0;
150         session = 0;
151         _session_is_new = false;
152         big_clock_window = 0;
153         session_selector_window = 0;
154         last_key_press_time = 0;
155         connection_editor = 0;
156         add_route_dialog = 0;
157         route_params = 0;
158         option_editor = 0;
159         location_ui = 0;
160         sfdb = 0;
161         open_session_selector = 0;
162         have_configure_timeout = false;
163         have_disk_overrun_displayed = false;
164         have_disk_underrun_displayed = false;
165         _will_create_new_session_automatically = false;
166         session_loaded = false;
167         last_speed_displayed = -1.0f;
168
169         last_configure_time.tv_sec = 0;
170         last_configure_time.tv_usec = 0;
171
172         shuttle_grabbed = false;
173         shuttle_fract = 0.0;
174         shuttle_max_speed = 8.0f;
175
176         set_shuttle_units (Percentage);
177         set_shuttle_behaviour (Sprung);
178
179         shuttle_style_menu = 0;
180         shuttle_unit_menu = 0;
181
182         gettimeofday (&last_peak_grab, 0);
183         gettimeofday (&last_shuttle_request, 0);
184
185         ARDOUR::AudioDiskstream::DeleteSources.connect (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread));
186         ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
187         ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
188
189         /* handle pending state with a dialog */
190
191         ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
192
193         /* have to wait for AudioEngine and Configuration before proceeding */
194 }
195
196 void
197 ARDOUR_UI::set_engine (AudioEngine& e)
198 {
199         engine = &e;
200
201         engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
202         engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
203         engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
204         engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
205
206         ActionManager::init ();
207         new_session_dialog = new NewSessionDialog();
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, uint32_t how_many)
873 {
874         list<boost::shared_ptr<MidiTrack> > tracks;
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
884                         tracks = session->new_midi_track (ARDOUR::Normal, how_many);
885
886                         if (tracks.size() != how_many) {
887                                 if (how_many == 1) {
888                                         error << _("could not create a new midi track") << endmsg;
889                                 } else {
890                                         error << string_compose (_("could not create %1 new midi tracks"), how_many) << endmsg;
891                                 }
892                         }
893                 } /*else {
894                         if ((route = session->new_midi_route ()) == 0) {
895                                 error << _("could not create new midi bus") << endmsg;
896                         }
897                 }*/
898         }
899
900         catch (...) {
901                 MessageDialog msg (*editor, 
902                                    _("There are insufficient JACK ports available\n\
903 to create a new track or bus.\n\
904 You should save Ardour, exit and\n\
905 restart JACK with more ports."));
906                 msg.run ();
907         }
908 }
909
910
911 void
912 ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, uint32_t how_many)
913 {
914         list<boost::shared_ptr<AudioTrack> > tracks;
915         Session::RouteList routes;
916
917         if (session == 0) {
918                 warning << _("You cannot add a track or bus without a session already loaded.") << endmsg;
919                 return;
920         }
921
922         try { 
923                 if (track) {
924                         tracks = session->new_audio_track (input_channels, output_channels, mode, how_many);
925
926                         if (tracks.size() != how_many) {
927                                 if (how_many == 1) {
928                                         error << _("could not create a new audio track") << endmsg;
929                                 } else {
930                                         error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
931                                 }
932                         }
933
934                 } else {
935
936                         routes = session->new_audio_route (input_channels, output_channels, how_many);
937
938                         if (routes.size() != how_many) {
939                                 if (how_many == 1) {
940                                         error << _("could not create a new audio track") << endmsg;
941                                 } else {
942                                         error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
943                                 }
944                         }
945                 }
946                 
947 #if CONTROLOUTS
948                 if (need_control_room_outs) {
949                         pan_t pans[2];
950                         
951                         pans[0] = 0.5;
952                         pans[1] = 0.5;
953                         
954                         route->set_stereo_control_outs (control_lr_channels);
955                         route->control_outs()->set_stereo_pan (pans, this);
956                 }
957 #endif /* CONTROLOUTS */
958         }
959
960         catch (...) {
961                 MessageDialog msg (*editor, 
962                                    _("There are insufficient JACK ports available\n\
963 to create a new track or bus.\n\
964 You should save Ardour, exit and\n\
965 restart JACK with more ports."));
966                 msg.run ();
967         }
968 }
969
970 void
971 ARDOUR_UI::do_transport_locate (jack_nframes_t new_position)
972 {
973         jack_nframes_t _preroll;
974
975         if (session) {
976                 _preroll = session->convert_to_frames_at (new_position, session->preroll);
977
978                 if (new_position > _preroll) {
979                         new_position -= _preroll;
980                 } else {
981                         new_position = 0;
982                 }
983
984                 session->request_locate (new_position);
985         }
986 }
987
988 void
989 ARDOUR_UI::transport_goto_start ()
990 {
991         if (session) {
992                 session->goto_start();
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 (session->current_start_frame());
1001                 }
1002         }
1003 }
1004
1005 void
1006 ARDOUR_UI::transport_goto_zero ()
1007 {
1008         if (session) {
1009                 session->request_locate (0);
1010
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 (0);
1018                 }
1019         }
1020 }
1021
1022 void
1023 ARDOUR_UI::transport_goto_end ()
1024 {
1025         if (session) {
1026                 jack_nframes_t frame = session->current_end_frame();
1027                 session->request_locate (frame);
1028
1029                 /* force displayed area in editor to start no matter
1030                    what "follow playhead" setting is.
1031                 */
1032                 
1033                 if (editor) {
1034                         editor->reposition_x_origin (frame);
1035                 }
1036         }
1037 }
1038
1039 void
1040 ARDOUR_UI::transport_stop ()
1041 {
1042         if (!session) {
1043                 return;
1044         }
1045
1046         if (session->is_auditioning()) {
1047                 session->cancel_audition ();
1048                 return;
1049         }
1050         
1051         if (session->get_auto_loop()) {
1052                 session->request_auto_loop (false);
1053         }
1054         
1055         session->request_stop ();
1056 }
1057
1058 void
1059 ARDOUR_UI::transport_stop_and_forget_capture ()
1060 {
1061         if (session) {
1062                 session->request_stop (true);
1063         }
1064 }
1065
1066 void
1067 ARDOUR_UI::remove_last_capture()
1068 {
1069         if (editor) {
1070                 editor->remove_last_capture();
1071         }
1072 }
1073
1074 void
1075 ARDOUR_UI::transport_record ()
1076 {
1077         if (session) {
1078                 switch (session->record_status()) {
1079                 case Session::Disabled:
1080                         if (session->ntracks() == 0) {
1081                                 string txt = _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu.");
1082                                 MessageDialog msg (*editor, txt);
1083                                 msg.run ();
1084                                 return;
1085                         }
1086                         session->maybe_enable_record ();
1087                         break;
1088                 case Session::Recording:
1089                 case Session::Enabled:
1090                         session->disable_record (true);
1091                 }
1092         }
1093 }
1094
1095 void
1096 ARDOUR_UI::transport_roll ()
1097 {
1098         bool rolling;
1099
1100         if (!session) {
1101                 return;
1102         }
1103
1104         rolling = session->transport_rolling ();
1105
1106         if (session->get_auto_loop()) {
1107                 session->request_auto_loop (false);
1108                 auto_loop_button.set_active (false);
1109                 roll_button.set_active (true);
1110         } else if (session->get_play_range ()) {
1111                 session->request_play_range (false);
1112                 play_selection_button.set_active (false);
1113         } else if (rolling) {
1114                 session->request_locate (session->last_transport_start(), true);
1115         }
1116
1117         session->request_transport_speed (1.0f);
1118 }
1119
1120 void
1121 ARDOUR_UI::transport_loop()
1122 {
1123         if (session) {
1124                 if (session->get_auto_loop()) {
1125                         if (session->transport_rolling()) {
1126                                 Location * looploc = session->locations()->auto_loop_location();
1127                                 if (looploc) {
1128                                         session->request_locate (looploc->start(), true);
1129                                 }
1130                         }
1131                 }
1132                 else {
1133                         session->request_auto_loop (true);
1134                 }
1135         }
1136 }
1137
1138 void
1139 ARDOUR_UI::transport_play_selection ()
1140 {
1141         if (!session) {
1142                 return;
1143         }
1144
1145         if (!session->get_play_range()) {
1146                 session->request_stop ();
1147         }
1148
1149         editor->play_selection ();
1150 }
1151
1152 void
1153 ARDOUR_UI::transport_rewind (int option)
1154 {
1155         float current_transport_speed;
1156  
1157         if (session) {
1158                 current_transport_speed = session->transport_speed();
1159                 
1160                 if (current_transport_speed >= 0.0f) {
1161                         switch (option) {
1162                         case 0:
1163                                 session->request_transport_speed (-1.0f);
1164                                 break;
1165                         case 1:
1166                                 session->request_transport_speed (-4.0f);
1167                                 break;
1168                         case -1:
1169                                 session->request_transport_speed (-0.5f);
1170                                 break;
1171                         }
1172                 } else {
1173                         /* speed up */
1174                         session->request_transport_speed (current_transport_speed * 1.5f);
1175                 }
1176         }
1177 }
1178
1179 void
1180 ARDOUR_UI::transport_forward (int option)
1181 {
1182         float current_transport_speed;
1183         
1184         if (session) {
1185                 current_transport_speed = session->transport_speed();
1186                 
1187                 if (current_transport_speed <= 0.0f) {
1188                         switch (option) {
1189                         case 0:
1190                                 session->request_transport_speed (1.0f);
1191                                 break;
1192                         case 1:
1193                                 session->request_transport_speed (4.0f);
1194                                 break;
1195                         case -1:
1196                                 session->request_transport_speed (0.5f);
1197                                 break;
1198                         }
1199                 } else {
1200                         /* speed up */
1201                         session->request_transport_speed (current_transport_speed * 1.5f);
1202                 }
1203         }
1204 }
1205
1206 void
1207 ARDOUR_UI::toggle_record_enable (uint32_t dstream)
1208 {
1209         if (session == 0) {
1210                 return;
1211         }
1212
1213         boost::shared_ptr<Route> r;
1214         
1215         if ((r = session->route_by_remote_id (dstream)) != 0) {
1216
1217                 Track* t;
1218
1219                 if ((t = dynamic_cast<Track*>(r.get())) != 0) {
1220                         t->diskstream()->set_record_enabled (!t->diskstream()->record_enabled());
1221                 }
1222         }
1223         if (session == 0) {
1224                 return;
1225         }
1226 }
1227
1228 void
1229 ARDOUR_UI::queue_transport_change ()
1230 {
1231         Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
1232 }
1233
1234 void
1235 ARDOUR_UI::map_transport_state ()
1236 {
1237         float sp = session->transport_speed();
1238
1239         if (sp == 1.0f) {
1240                 transport_rolling ();
1241         } else if (sp < 0.0f) {
1242                 transport_rewinding ();
1243         } else if (sp > 0.0f) {
1244                 transport_forwarding ();
1245         } else {
1246                 transport_stopped ();
1247         }
1248 }
1249
1250 void
1251 ARDOUR_UI::allow_local_only ()
1252 {
1253
1254 }
1255
1256 void
1257 ARDOUR_UI::allow_mmc_only ()
1258 {
1259
1260 }
1261
1262 void
1263 ARDOUR_UI::allow_mmc_and_local ()
1264 {
1265
1266 }
1267
1268 void
1269 ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg)
1270 {
1271         snprintf (buf, sizeof(buf), "%s", ((GlobalClickBox *) arg)->strings[
1272                 (int) adj.get_value()].c_str());
1273 }
1274
1275 void
1276 ARDOUR_UI::engine_stopped ()
1277 {
1278         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
1279         ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1280         ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1281 }
1282
1283
1284 void
1285 ARDOUR_UI::engine_running ()
1286 {
1287         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
1288         ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true);
1289         ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
1290 }
1291
1292 void
1293 ARDOUR_UI::engine_halted ()
1294 {
1295         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
1296
1297         ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1298         ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1299
1300         update_sample_rate (0);
1301
1302         MessageDialog msg (*editor, 
1303                            _("\
1304 JACK has either been shutdown or it\n\
1305 disconnected Ardour because Ardour\n\
1306 was not fast enough. You can save the\n\
1307 session and/or try to reconnect to JACK ."));
1308         msg.run ();
1309 }
1310
1311 int32_t
1312 ARDOUR_UI::do_engine_start ()
1313 {
1314         try { 
1315                 engine->start();
1316         }
1317
1318         catch (AudioEngine::PortRegistrationFailure& err) {
1319                 engine->stop ();
1320                 error << _("Unable to create all required ports")
1321                       << endmsg;
1322                 unload_session ();
1323                 return -1;
1324         }
1325
1326         catch (...) {
1327                 engine->stop ();
1328                 error << _("Unable to start the session running")
1329                       << endmsg;
1330                 unload_session ();
1331                 return -2;
1332         }
1333         
1334         return 0;
1335 }
1336
1337 gint
1338 ARDOUR_UI::start_engine ()
1339 {
1340         if (do_engine_start () == 0) {
1341                 if (session && _session_is_new) {
1342                         /* we need to retain initial visual 
1343                            settings for a new session 
1344                         */
1345                         session->save_state ("");
1346                 }
1347
1348                 /* there is too much going on, in too many threads, for us to 
1349                    end up with a clean session. So wait 1 second after loading,
1350                    and fix it up. its ugly, but until i come across a better
1351                    solution, its what we have.
1352                 */
1353
1354                 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::make_session_clean), 1000);
1355         }
1356
1357         return FALSE;
1358 }
1359
1360 void
1361 ARDOUR_UI::update_clocks ()
1362 {
1363          Clock (session->audible_frame()); /* EMIT_SIGNAL */
1364 }
1365
1366 void
1367 ARDOUR_UI::start_clocking ()
1368 {
1369         clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
1370 }
1371
1372 void
1373 ARDOUR_UI::stop_clocking ()
1374 {
1375         clock_signal_connection.disconnect ();
1376 }
1377         
1378 void
1379 ARDOUR_UI::toggle_clocking ()
1380 {
1381 #if 0
1382         if (clock_button.get_active()) {
1383                 start_clocking ();
1384         } else {
1385                 stop_clocking ();
1386         }
1387 #endif
1388 }
1389
1390 gint
1391 ARDOUR_UI::_blink (void *arg)
1392
1393 {
1394         ((ARDOUR_UI *) arg)->blink ();
1395         return TRUE;
1396 }
1397
1398 void
1399 ARDOUR_UI::blink ()
1400 {
1401          Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
1402 }
1403
1404 void
1405 ARDOUR_UI::start_blinking ()
1406 {
1407         /* Start the blink signal. Everybody with a blinking widget
1408            uses Blink to drive the widget's state.
1409         */
1410
1411         if (blink_timeout_tag < 0) {
1412                 blink_on = false;       
1413                 blink_timeout_tag = g_timeout_add (240, _blink, this);
1414         }
1415 }
1416
1417 void
1418 ARDOUR_UI::stop_blinking ()
1419 {
1420         if (blink_timeout_tag >= 0) {
1421                 g_source_remove (blink_timeout_tag);
1422                 blink_timeout_tag = -1;
1423         }
1424 }
1425
1426 void
1427 ARDOUR_UI::name_io_setup (AudioEngine& engine, 
1428                           string& buf,
1429                           IO& io,
1430                           bool in)
1431 {
1432         if (in) {
1433                 if (io.n_inputs().get_total() == 0) {
1434                         buf = _("none");
1435                         return;
1436                 }
1437                 
1438                 /* XXX we're not handling multiple ports yet. */
1439
1440                 const char **connections = io.input(0)->get_connections();
1441                 
1442                 if (connections == 0 || connections[0] == '\0') {
1443                         buf = _("off");
1444                 } else {
1445                         buf = connections[0];
1446                 }
1447
1448                 free (connections);
1449
1450         } else {
1451
1452                 if (io.n_outputs().get_total() == 0) {
1453                         buf = _("none");
1454                         return;
1455                 }
1456                 
1457                 /* XXX we're not handling multiple ports yet. */
1458
1459                 const char **connections = io.output(0)->get_connections();
1460                 
1461                 if (connections == 0 || connections[0] == '\0') {
1462                         buf = _("off");
1463                 } else {
1464                         buf = connections[0];
1465                 }
1466
1467                 free (connections);
1468         }
1469 }
1470
1471 void
1472 ARDOUR_UI::snapshot_session ()
1473 {
1474         ArdourPrompter prompter (true);
1475         string snapname;
1476         string now;
1477         time_t n;
1478
1479         time (&n);
1480         now = ctime (&n);
1481         now = now.substr (20, 4) + now.substr (3, 16) + " (" + now.substr (0, 3) + ")";
1482
1483         prompter.set_name ("Prompter");
1484         prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1485         prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
1486         prompter.set_prompt (_("Name of New Snapshot"));
1487         prompter.set_initial_text (now);
1488         
1489         switch (prompter.run()) {
1490         case RESPONSE_ACCEPT:
1491                 prompter.get_result (snapname);
1492                 if (snapname.length()){
1493                         save_state (snapname);
1494                 }
1495                 break;
1496
1497         default:
1498                 break;
1499         }
1500 }
1501
1502 void
1503 ARDOUR_UI::save_state (const string & name)
1504 {
1505         (void) save_state_canfail (name);
1506 }
1507                 
1508 int
1509 ARDOUR_UI::save_state_canfail (string name)
1510 {
1511         if (session) {
1512                 int ret;
1513
1514                 if (name.length() == 0) {
1515                         name = session->snap_name();
1516                 }
1517
1518                 if ((ret = session->save_state (name)) != 0) {
1519                         return ret;
1520                 }
1521         }
1522         save_ardour_state (); /* XXX cannot fail? yeah, right ... */
1523         return 0;
1524 }
1525
1526 void
1527 ARDOUR_UI::restore_state (string name)
1528 {
1529         if (session) {
1530                 if (name.length() == 0) {
1531                         name = session->name();
1532                 }
1533                 session->restore_state (name);
1534         }
1535 }
1536
1537 void
1538 ARDOUR_UI::primary_clock_value_changed ()
1539 {
1540         if (session) {
1541                 session->request_locate (primary_clock.current_time ());
1542         }
1543 }
1544
1545 void
1546 ARDOUR_UI::secondary_clock_value_changed ()
1547 {
1548         if (session) {
1549                 session->request_locate (secondary_clock.current_time ());
1550         }
1551 }
1552
1553 void
1554 ARDOUR_UI::rec_enable_button_blink (bool onoff, AudioDiskstream *dstream, Widget *w)
1555 {
1556         if (session && dstream && dstream->record_enabled()) {
1557
1558                 Session::RecordState rs;
1559                 
1560                 rs = session->record_status ();
1561
1562                 switch (rs) {
1563                 case Session::Disabled:
1564                 case Session::Enabled:
1565                         if (w->get_state() != STATE_SELECTED) {
1566                                 w->set_state (STATE_SELECTED);
1567                         }
1568                         break;
1569
1570                 case Session::Recording:
1571                         if (w->get_state() != STATE_ACTIVE) {
1572                                 w->set_state (STATE_ACTIVE);
1573                         }
1574                         break;
1575                 }
1576
1577         } else {
1578                 if (w->get_state() != STATE_NORMAL) {
1579                         w->set_state (STATE_NORMAL);
1580                 }
1581         }
1582 }
1583
1584 void
1585 ARDOUR_UI::transport_rec_enable_blink (bool onoff) 
1586 {
1587         if (session == 0) {
1588                 return;
1589         }
1590         
1591         switch (session->record_status()) {
1592         case Session::Enabled:
1593                 if (onoff) {
1594                         rec_button.set_state (1);
1595                 } else {
1596                         rec_button.set_state (0);
1597                 }
1598                 break;
1599
1600         case Session::Recording:
1601                 rec_button.set_state (2);
1602                 break;
1603
1604         default:
1605                 rec_button.set_state (0);
1606                 break;
1607         }
1608 }
1609
1610 gint
1611 ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
1612 {
1613         window->hide();
1614         Gtk::Main::quit ();
1615         return TRUE;
1616 }
1617
1618 void
1619 ARDOUR_UI::start_keyboard_prefix ()
1620 {
1621         keyboard->start_prefix();
1622 }
1623
1624 void
1625 ARDOUR_UI::save_template ()
1626
1627 {
1628         ArdourPrompter prompter (true);
1629         string name;
1630
1631         prompter.set_name (X_("Prompter"));
1632         prompter.set_prompt (_("Name for mix template:"));
1633         prompter.set_initial_text(session->name() + _("-template"));
1634         prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1635         prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
1636
1637         switch (prompter.run()) {
1638         case RESPONSE_ACCEPT:
1639                 prompter.get_result (name);
1640                 
1641                 if (name.length()) {
1642                         session->save_template (name);
1643                 }
1644                 break;
1645
1646         default:
1647                 break;
1648         }
1649 }
1650
1651 void
1652 ARDOUR_UI::new_session (bool startup, std::string predetermined_path)
1653 {
1654         string session_name;
1655         string session_path;
1656
1657         int response = Gtk::RESPONSE_NONE;
1658
1659         new_session_dialog->set_modal(true);
1660         new_session_dialog->set_name(predetermined_path);
1661         new_session_dialog->reset_recent();
1662         new_session_dialog->show();
1663
1664         //Glib::RefPtr<Gdk::Window> nsd_window = new_session_dialog->get_window();
1665
1666         do {
1667                 response = new_session_dialog->run ();
1668                 //nsd_window ->set_cursor(Gdk::Cursor(Gdk::WATCH));
1669                 if(response == Gtk::RESPONSE_CANCEL || response == Gtk::RESPONSE_DELETE_EVENT) {
1670                         quit();
1671                         return;
1672
1673                 } else if (response == Gtk::RESPONSE_NONE) {
1674                         /* Clear was pressed */
1675                         new_session_dialog->reset();
1676
1677                 } else if (response == Gtk::RESPONSE_YES) {
1678
1679                         /* YES  == OPEN, but there's no enum for that */
1680
1681                         session_name = new_session_dialog->session_name();
1682                         
1683                         if (session_name.empty()) {
1684                                 response = Gtk::RESPONSE_NONE;
1685                                 cerr << "session name is empty\n";
1686                                 continue;
1687                         } 
1688
1689                         if (session_name[0] == '/' || 
1690                             (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1691                             (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1692                                 load_session (Glib::path_get_dirname (session_name), session_name);
1693                         } else {
1694                                 session_path = new_session_dialog->session_folder();
1695                                 load_session (session_path, session_name);
1696                         }
1697                         
1698                 } else if (response == Gtk::RESPONSE_OK) {
1699
1700                         if (new_session_dialog->get_current_page() == 1) {
1701                   
1702                                 /* XXX this is a bit of a hack.. 
1703                                    i really want the new sesion dialog to return RESPONSE_YES
1704                                    if we're on page 1 (the load page)
1705                                    Unfortunately i can't see how atm.. 
1706                                 */
1707                                 
1708                                 if (session_name.empty()) {
1709                                         response = Gtk::RESPONSE_NONE;
1710                                         cerr << "session name is empty 2\n";
1711                                         continue;
1712                                 } 
1713                                 
1714                                 if (session_name[0] == '/' || 
1715                                     (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1716                                     (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1717                                         load_session (Glib::path_get_dirname (session_name), session_name);
1718                                 } else {
1719                                         session_path = new_session_dialog->session_folder();
1720                                         load_session (session_path, session_name);
1721                                 }
1722                         
1723                         } else {
1724
1725                                 _session_is_new = true;
1726                               
1727                                 session_name = new_session_dialog->session_name();
1728                         
1729                                 if (session_name.empty()) {
1730                                         response = Gtk::RESPONSE_NONE;
1731                                         cerr << "session name is empty 3\n";
1732                                         continue;
1733                                 } 
1734
1735                                 if (session_name[0] == '/' || 
1736                                     (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1737                                     (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1738
1739                                         session_path = Glib::path_get_dirname (session_name);
1740                                         session_name = Glib::path_get_basename (session_name);
1741
1742                                 } else {
1743
1744                                         std::string session_path = new_session_dialog->session_folder();
1745                                         
1746                                 }
1747                         
1748                                 //XXX This is needed because session constructor wants a 
1749                                 //non-existant path. hopefully this will be fixed at some point.
1750                                 
1751                                 session_path = Glib::build_filename (session_path, session_name);
1752                                                 
1753                                 std::string template_name = new_session_dialog->session_template_name();
1754                                                 
1755                                 if (new_session_dialog->use_session_template()) {
1756                                                         
1757                                         load_session (session_path, session_name, &template_name);
1758                           
1759                                 } else {
1760                                                         
1761                                         uint32_t cchns;
1762                                         uint32_t mchns;
1763                                         Session::AutoConnectOption iconnect;
1764                                         Session::AutoConnectOption oconnect;
1765                                                         
1766                                         if (new_session_dialog->create_control_bus()) {
1767                                                 cchns = (uint32_t) new_session_dialog->control_channel_count();
1768                                         } else {
1769                                                 cchns = 0;
1770                                         }
1771                                                         
1772                                         if (new_session_dialog->create_master_bus()) {
1773                                                 mchns = (uint32_t) new_session_dialog->master_channel_count();
1774                                         } else {
1775                                                 mchns = 0;
1776                                         }
1777                                                         
1778                                         if (new_session_dialog->connect_inputs()) {
1779                                                 iconnect = Session::AutoConnectPhysical;
1780                                         } else {
1781                                                 iconnect = Session::AutoConnectOption (0);
1782                                         }
1783                                                         
1784                                         /// @todo some minor tweaks.
1785                                                         
1786                                         if (new_session_dialog->connect_outs_to_master()) {
1787                                                 oconnect = Session::AutoConnectMaster;
1788                                         } else if (new_session_dialog->connect_outs_to_physical()) {
1789                                                 oconnect = Session::AutoConnectPhysical;
1790                                         } else {
1791                                                 oconnect = Session::AutoConnectOption (0);
1792                                         } 
1793                                                         
1794                                         uint32_t nphysin = (uint32_t) new_session_dialog->input_limit_count();
1795                                         uint32_t nphysout = (uint32_t) new_session_dialog->output_limit_count();
1796                                                         
1797                                         build_session (session_path,
1798                                                        session_name,
1799                                                        cchns,
1800                                                        mchns,
1801                                                        iconnect,
1802                                                        oconnect,
1803                                                        nphysin,
1804                                                        nphysout, 
1805                                                        engine->frame_rate() * 60 * 5);
1806                                 }
1807                         }
1808                 }
1809                 
1810         } while (response == Gtk::RESPONSE_NONE);
1811
1812         show();
1813         new_session_dialog->get_window()->set_cursor();
1814         new_session_dialog->hide();
1815 }
1816
1817 void
1818 ARDOUR_UI::close_session()
1819 {
1820         unload_session();
1821         new_session ();
1822 }
1823
1824 int
1825 ARDOUR_UI::load_session (const string & path, const string & snap_name, string* mix_template)
1826 {
1827         Session *new_session;
1828         int x;
1829         session_loaded = false;
1830         x = unload_session ();
1831
1832         if (x < 0) {
1833                 return -1;
1834         } else if (x > 0) {
1835                 return 0;
1836         }
1837
1838         /* if it already exists, we must have write access */
1839
1840         if (::access (path.c_str(), F_OK) == 0 && ::access (path.c_str(), W_OK)) {
1841                 MessageDialog msg (*editor, _("\
1842 You do not have write access to this session.\n\
1843 This prevents the session from being loaded."));
1844                 msg.run ();
1845                 return -1;
1846         }
1847
1848         try {
1849                 new_session = new Session (*engine, path, snap_name, mix_template);
1850         }
1851
1852         catch (...) {
1853
1854                 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
1855                 return -1;
1856         }
1857
1858         connect_to_session (new_session);
1859
1860         session_loaded = true;
1861         return 0;
1862 }
1863
1864 int
1865 ARDOUR_UI::make_session_clean ()
1866 {
1867         if (session) {
1868                 session->set_clean ();
1869         }
1870
1871         show ();
1872
1873         return FALSE;
1874 }
1875
1876 int
1877 ARDOUR_UI::build_session (const string & path, const string & snap_name, 
1878                           uint32_t control_channels,
1879                           uint32_t master_channels, 
1880                           Session::AutoConnectOption input_connect,
1881                           Session::AutoConnectOption output_connect,
1882                           uint32_t nphysin,
1883                           uint32_t nphysout,
1884                           jack_nframes_t initial_length)
1885 {
1886         Session *new_session;
1887         int x;
1888
1889         session_loaded = false;
1890         x = unload_session ();
1891         if (x < 0) {
1892                 return -1;
1893         } else if (x > 0) {
1894                 return 0;
1895         }
1896         
1897         _session_is_new = true;
1898
1899         try {
1900                 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
1901                                            control_channels, master_channels, nphysin, nphysout, initial_length);
1902         }
1903
1904         catch (...) {
1905
1906                 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
1907                 return -1;
1908         }
1909
1910         connect_to_session (new_session);
1911
1912         session_loaded = true;
1913         return 0;
1914 }
1915
1916 void
1917 ARDOUR_UI::show ()
1918 {
1919         if (editor) {
1920                 editor->show_window ();
1921                 
1922                 if (!shown_flag) {
1923                         editor->present ();
1924                 }
1925
1926                 shown_flag = true;
1927         }
1928         
1929         if (about) {
1930                 about->present ();
1931         }
1932 }
1933
1934 void
1935 ARDOUR_UI::show_splash ()
1936 {
1937         if (about == 0) {
1938                 about = new About();
1939         }
1940         about->present();
1941 }
1942
1943 void
1944 ARDOUR_UI::hide_splash ()
1945 {
1946         if (about) {
1947                 about->get_window()->set_cursor ();
1948                 about->hide();
1949         }
1950 }
1951
1952 void
1953 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title, const string & msg)
1954 {
1955         size_t removed;
1956
1957         removed = rep.paths.size();
1958
1959         if (removed == 0) {
1960                 MessageDialog msgd (*editor,
1961                                     _("No audio files were ready for cleanup"), 
1962                                     true,
1963                                     Gtk::MESSAGE_INFO,
1964                                     (Gtk::ButtonsType)(Gtk::BUTTONS_CLOSE)  );
1965                 msgd.set_secondary_text (_("If this seems suprising, \n\
1966 check for any existing snapshots.\n\
1967 These may still include regions that\n\
1968 require some unused files to continue to exist."));
1969         
1970                 msgd.run ();
1971                 return;
1972         } 
1973
1974         ArdourDialog results (_("ardour: cleanup"), true, false);
1975         
1976         struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
1977             CleanupResultsModelColumns() { 
1978                     add (visible_name);
1979                     add (fullpath);
1980             }
1981             Gtk::TreeModelColumn<Glib::ustring> visible_name;
1982             Gtk::TreeModelColumn<Glib::ustring> fullpath;
1983         };
1984
1985         
1986         CleanupResultsModelColumns results_columns;
1987         Glib::RefPtr<Gtk::ListStore> results_model;
1988         Gtk::TreeView results_display;
1989         
1990         results_model = ListStore::create (results_columns);
1991         results_display.set_model (results_model);
1992         results_display.append_column (list_title, results_columns.visible_name);
1993
1994         results_display.set_name ("CleanupResultsList");
1995         results_display.set_headers_visible (true);
1996         results_display.set_headers_clickable (false);
1997         results_display.set_reorderable (false);
1998
1999         Gtk::ScrolledWindow list_scroller;
2000         Gtk::Label txt;
2001         Gtk::VBox dvbox;
2002         Gtk::HBox dhbox;  // the hbox for the image and text
2003         Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
2004         Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO,  Gtk::ICON_SIZE_DIALOG));
2005
2006         dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
2007
2008         if (rep.space < 1048576.0f) {
2009                 if (removed > 1) {
2010                   txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2011                 } else {
2012                         txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2013                 }
2014         } else {
2015                 if (removed > 1) {
2016                         txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2017                 } else {
2018                         txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2019                 }
2020         }
2021
2022         dhbox.pack_start (*dimage, true, false, 5);
2023         dhbox.pack_start (txt, true, false, 5);
2024
2025         for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2026                 TreeModel::Row row = *(results_model->append());
2027                 row[results_columns.visible_name] = *i;
2028                 row[results_columns.fullpath] = *i;
2029         }
2030         
2031         list_scroller.add (results_display);
2032         list_scroller.set_size_request (-1, 150);
2033         list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2034
2035         dvbox.pack_start (dhbox, true, false, 5);
2036         dvbox.pack_start (list_scroller, true, false, 5);
2037         ddhbox.pack_start (dvbox, true, false, 5);
2038
2039         results.get_vbox()->pack_start (ddhbox, true, false, 5);
2040         results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
2041         results.set_default_response (RESPONSE_CLOSE);
2042         results.set_position (Gtk::WIN_POS_MOUSE);
2043         results.show_all_children ();
2044         results.set_resizable (false);
2045
2046         results.run ();
2047
2048 }
2049
2050 void
2051 ARDOUR_UI::cleanup ()
2052 {
2053         if (session == 0) {
2054                 /* shouldn't happen: menu item is insensitive */
2055                 return;
2056         }
2057
2058
2059         MessageDialog  checker (_("Are you sure you want to cleanup?"),
2060                                 true,
2061                                 Gtk::MESSAGE_QUESTION,
2062                                 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
2063
2064         checker.set_secondary_text(_("Cleanup is a destructive operation.\n\
2065 ALL undo/redo information will be lost if you cleanup.\n\
2066 After cleanup, unused audio files will be moved to a \
2067 \"dead sounds\" location."));
2068         
2069         checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2070         checker.add_button (_("Clean Up"), RESPONSE_ACCEPT);
2071         checker.set_default_response (RESPONSE_CANCEL);
2072
2073         checker.set_name (_("CleanupDialog"));
2074         checker.set_wmclass (_("ardour_cleanup"), "Ardour");
2075         checker.set_position (Gtk::WIN_POS_MOUSE);
2076
2077         switch (checker.run()) {
2078         case RESPONSE_ACCEPT:
2079                 break;
2080         default:
2081                 return;
2082         }
2083
2084         Session::cleanup_report rep;
2085
2086         editor->prepare_for_cleanup ();
2087
2088         if (session->cleanup_sources (rep)) {
2089                 return;
2090         }
2091         checker.hide();
2092         display_cleanup_results (rep, 
2093                                  _("cleaned files"),
2094                                  _("\
2095 The following %1 %2 not in use and \n\
2096 have been moved to:\n\
2097 %3. \n\n\
2098 Flushing the wastebasket will \n\
2099 release an additional\n\
2100 %4 %5bytes of disk space.\n"
2101                                          ));
2102 }
2103
2104 void
2105 ARDOUR_UI::flush_trash ()
2106 {
2107         if (session == 0) {
2108                 /* shouldn't happen: menu item is insensitive */
2109                 return;
2110         }
2111
2112         Session::cleanup_report rep;
2113
2114         if (session->cleanup_trash_sources (rep)) {
2115                 return;
2116         }
2117
2118         display_cleanup_results (rep, 
2119                                  _("deleted file"),
2120                                  _("The following %1 %2 deleted from\n\
2121 %3,\n\
2122 releasing %4 %5bytes of disk space"));
2123 }
2124
2125 void
2126 ARDOUR_UI::add_route ()
2127 {
2128         int count;
2129
2130         if (!session) {
2131                 return;
2132         }
2133
2134         if (add_route_dialog == 0) {
2135                 add_route_dialog = new AddRouteDialog;
2136                 editor->ensure_float (*add_route_dialog);
2137         }
2138
2139         if (add_route_dialog->is_visible()) {
2140                 /* we're already doing this */
2141                 return;
2142         }
2143
2144         ResponseType r = (ResponseType) add_route_dialog->run ();
2145
2146         add_route_dialog->hide();
2147
2148         switch (r) {
2149                 case RESPONSE_ACCEPT:
2150                         break;
2151                 default:
2152                         return;
2153                         break;
2154         }
2155
2156         if ((count = add_route_dialog->count()) <= 0) {
2157                 return;
2158         }
2159
2160         uint32_t input_chan = add_route_dialog->channels ();
2161         uint32_t output_chan;
2162         string name_template = add_route_dialog->name_template ();
2163         bool track = add_route_dialog->track ();
2164
2165         Session::AutoConnectOption oac = session->get_output_auto_connect();
2166
2167         if (oac & Session::AutoConnectMaster) {
2168                 output_chan = (session->master_out() ? session->master_out()->n_inputs().get(DataType::AUDIO) : input_chan);
2169         } else {
2170                 output_chan = input_chan;
2171         }
2172
2173         /* XXX do something with name template */
2174
2175         if (add_route_dialog->type() == ARDOUR::DataType::MIDI) {
2176                 if (track) {
2177                         session_add_midi_track(count);
2178                 } else  {
2179                         MessageDialog msg (*editor,
2180                                         _("Sorry, MIDI Busses are not supported at this time."));
2181                         msg.run ();
2182                         //session_add_midi_bus();
2183                 }
2184         } else { 
2185                 if (track) {
2186                         session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), count);
2187                 } else {
2188                         session_add_audio_bus (input_chan, output_chan, count);
2189                 }
2190         }
2191 }
2192
2193 XMLNode*
2194 ARDOUR_UI::mixer_settings () const
2195 {
2196         XMLNode* node = 0;
2197
2198         if (session) {
2199                 node = session->instant_xml(X_("Mixer"), session->path());
2200         } else {
2201                 node = Config->instant_xml(X_("Mixer"), get_user_ardour_path());
2202         }
2203
2204         if (!node) {
2205                 node = new XMLNode (X_("Mixer"));
2206         }
2207
2208         return node;
2209 }
2210
2211 XMLNode*
2212 ARDOUR_UI::editor_settings () const
2213 {
2214         XMLNode* node = 0;
2215
2216         if (session) {
2217                 node = session->instant_xml(X_("Editor"), session->path());
2218         } else {
2219                 node = Config->instant_xml(X_("Editor"), get_user_ardour_path());
2220         }
2221
2222         if (!node) {
2223                 node = new XMLNode (X_("Editor"));
2224         }
2225         return node;
2226 }
2227
2228 XMLNode*
2229 ARDOUR_UI::keyboard_settings () const
2230 {
2231         XMLNode* node = 0;
2232
2233         node = Config->extra_xml(X_("Keyboard"));
2234         
2235         if (!node) {
2236                 node = new XMLNode (X_("Keyboard"));
2237         }
2238         return node;
2239 }
2240
2241 void
2242 ARDOUR_UI::halt_on_xrun_message ()
2243 {
2244         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
2245
2246         MessageDialog msg (*editor,
2247                            _("Recording was stopped because your system could not keep up."));
2248         msg.run ();
2249 }
2250
2251 void 
2252 ARDOUR_UI::delete_sources_in_the_right_thread (list<boost::shared_ptr<ARDOUR::Source> >* deletion_list)
2253 {
2254         ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread), deletion_list));
2255
2256         for (list<boost::shared_ptr<Source> >::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) {
2257                 (*i)->drop_references ();
2258         }
2259
2260         delete deletion_list;
2261 }
2262
2263 void
2264 ARDOUR_UI::disk_overrun_handler ()
2265 {
2266         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2267
2268         if (!have_disk_overrun_displayed) {
2269                 have_disk_overrun_displayed = true;
2270                 MessageDialog msg (*editor, X_("diskrate dialog"), _("\
2271 The disk system on your computer\n\
2272 was not able to keep up with Ardour.\n\
2273 \n\
2274 Specifically, it failed to write data to disk\n\
2275 quickly enough to keep up with recording.\n"));
2276                 msg.run ();
2277                 have_disk_overrun_displayed = false;
2278         }
2279 }
2280
2281 void
2282 ARDOUR_UI::disk_underrun_handler ()
2283 {
2284         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2285
2286         if (!have_disk_underrun_displayed) {
2287                 have_disk_underrun_displayed = true;
2288                 MessageDialog msg (*editor,
2289                         (_("The disk system on your computer\n\
2290 was not able to keep up with Ardour.\n\
2291 \n\
2292 Specifically, it failed to read data from disk\n\
2293 quickly enough to keep up with playback.\n")));
2294                 msg.run ();
2295                 have_disk_underrun_displayed = false;
2296         } 
2297 }
2298
2299 void
2300 ARDOUR_UI::disk_underrun_message_gone ()
2301 {
2302         have_disk_underrun_displayed = false;
2303 }
2304
2305 void
2306 ARDOUR_UI::disk_overrun_message_gone ()
2307 {
2308         have_disk_underrun_displayed = false;
2309 }
2310
2311 int
2312 ARDOUR_UI::pending_state_dialog ()
2313 {
2314         ArdourDialog dialog ("pending state dialog");
2315         Label  message (_("\
2316 This session appears to have been in\n\
2317 middle of recording when ardour or\n\
2318 the computer was shutdown.\n\
2319 \n\
2320 Ardour can recover any captured audio for\n\
2321 you, or it can ignore it. Please decide\n\
2322 what you would like to do.\n"));
2323
2324         dialog.get_vbox()->pack_start (message);
2325         dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
2326         dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
2327
2328         dialog.set_position (WIN_POS_CENTER);
2329         dialog.show_all ();
2330         
2331         switch (dialog.run ()) {
2332         case RESPONSE_ACCEPT:
2333                 return 1;
2334         default:
2335                 return 0;
2336         }
2337 }
2338         
2339 void
2340 ARDOUR_UI::disconnect_from_jack ()
2341 {
2342         if (engine) {
2343                 if( engine->disconnect_from_jack ()) {
2344                         MessageDialog msg (*editor, _("Could not disconnect from JACK"));
2345                         msg.run ();
2346                 }
2347
2348                 update_sample_rate (0);
2349         }
2350 }
2351
2352 void
2353 ARDOUR_UI::reconnect_to_jack ()
2354 {
2355         if (engine) {
2356                 if (engine->reconnect_to_jack ()) {
2357                         MessageDialog msg (*editor,  _("Could not reconnect to JACK"));
2358                         msg.run ();
2359                 }
2360
2361                 update_sample_rate (0);
2362         }
2363 }
2364
2365 void
2366 ARDOUR_UI::set_jack_buffer_size (jack_nframes_t nframes)
2367 {
2368         engine->request_buffer_size (nframes);
2369         update_sample_rate (0);
2370 }
2371
2372 int
2373 ARDOUR_UI::cmdline_new_session (string path)
2374 {
2375         if (path[0] != '/') {
2376                 char buf[PATH_MAX+1];
2377                 string str;
2378
2379                 getcwd (buf, sizeof (buf));
2380                 str = buf;
2381                 str += '/';
2382                 str += path;
2383                 path = str;
2384         }
2385
2386         new_session (false, path);
2387
2388         _will_create_new_session_automatically = false; /* done it */
2389         return FALSE; /* don't call it again */
2390 }
2391
2392 void
2393 ARDOUR_UI::set_native_file_header_format (HeaderFormat hf)
2394 {
2395         Glib::RefPtr<Action> act;
2396         
2397         switch (hf) {
2398         case BWF:
2399                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
2400                 break;
2401         case WAVE:
2402                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
2403                 break;
2404         case WAVE64:
2405                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
2406                 break;
2407         case iXML:
2408                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
2409                 break;
2410         case RF64:
2411                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
2412                 break;
2413         case CAF:
2414                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatCAF"));
2415                 break;
2416         case AIFF:
2417                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatAIFF"));
2418                 break;
2419         }
2420
2421         if (act) {
2422                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2423                 if (ract && ract->get_active() && Config->get_native_file_header_format() != hf) {
2424                         Config->set_native_file_header_format (hf);
2425                         if (session) {
2426                                 session->reset_native_file_format ();
2427                         }
2428                 }
2429         }
2430 }
2431
2432 void
2433 ARDOUR_UI::set_native_file_data_format (SampleFormat sf)
2434 {
2435         Glib::RefPtr<Action> act;
2436         
2437         switch (sf) {
2438         case FormatFloat:
2439                 act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
2440                 break;
2441         case FormatInt24:
2442                 act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
2443                 break;
2444         }
2445
2446         if (act) {
2447                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2448
2449                 if (ract && ract->get_active() && Config->get_native_file_data_format() != sf) {
2450                         Config->set_native_file_data_format (sf);
2451                         if (session) {
2452                                 session->reset_native_file_format ();
2453                         }
2454                 }
2455         }
2456 }
2457
2458 void
2459 ARDOUR_UI::use_config ()
2460 {
2461         Glib::RefPtr<Action> act;
2462
2463         switch (Config->get_native_file_data_format ()) {
2464         case FormatFloat:
2465                 act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
2466                 break;
2467         case FormatInt24:
2468                 act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
2469                 break;
2470         }
2471
2472         if (act) {
2473                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2474                 ract->set_active ();
2475         }       
2476
2477         switch (Config->get_native_file_header_format ()) {
2478         case BWF:
2479                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
2480                 break;
2481         case WAVE:
2482                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
2483                 break;
2484         case WAVE64:
2485                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
2486                 break;
2487         case iXML:
2488                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
2489                 break;
2490         case RF64:
2491                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
2492                 break;
2493         case CAF:
2494                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatCAF"));
2495                 break;
2496         case AIFF:
2497                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatAIFF"));
2498                 break;
2499         }
2500
2501         if (act) {
2502                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2503                 ract->set_active ();
2504         }       
2505 }