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