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