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