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