Small tempo/meter dialog useability changes
[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
472         dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP)
473 ;
474         dhbox.set_homogeneous (false);
475         dhbox.pack_start (*dimage, false, false, 5);
476         dhbox.pack_start (prompt_label, true, false, 5);
477         window.get_vbox()->pack_start (dhbox);
478
479         window.set_name (_("Prompter"));
480         window.set_position (Gtk::WIN_POS_MOUSE);
481         window.set_modal (true);
482         window.set_resizable (false);
483         window.show_all ();
484
485         save_the_session = 0;
486
487         editor->ensure_float (window);
488
489         ResponseType r = (ResponseType) window.run();
490
491         window.hide ();
492
493         switch (r) {
494         case RESPONSE_ACCEPT: // save and get out of here
495                 return 1;
496         case RESPONSE_APPLY:  // get out of here
497                 return 0;
498         default:
499                 break;
500         }
501
502         return -1;
503 }
504         
505 gint
506 ARDOUR_UI::every_second ()
507 {
508         update_cpu_load ();
509         update_buffer_load ();
510         update_disk_space ();
511         return TRUE;
512 }
513
514 gint
515 ARDOUR_UI::every_point_one_seconds ()
516 {
517         update_speed_display ();
518         RapidScreenUpdate(); /* EMIT_SIGNAL */
519         return TRUE;
520 }
521
522 gint
523 ARDOUR_UI::every_point_zero_one_seconds ()
524 {
525         SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
526         return TRUE;
527 }
528
529 void
530 ARDOUR_UI::update_sample_rate (jack_nframes_t ignored)
531 {
532         char buf[32];
533
534         ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
535
536         if (!engine->connected()) {
537
538                 snprintf (buf, sizeof (buf), _("disconnected"));
539
540         } else {
541
542                 jack_nframes_t rate = engine->frame_rate();
543                 
544                 if (fmod (rate, 1000.0) != 0.0) {
545                         snprintf (buf, sizeof (buf), _("SR: %.1f kHz / %4.1f msecs"), 
546                                   (float) rate/1000.0f,
547                                   (engine->frames_per_cycle() / (float) rate) * 1000.0f);
548                 } else {
549                         snprintf (buf, sizeof (buf), _("SR: %u kHz / %4.1f msecs"), 
550                                   rate/1000,
551                                   (engine->frames_per_cycle() / (float) rate) * 1000.0f);
552                 }
553         }
554
555         sample_rate_label.set_text (buf);
556 }
557
558 void
559 ARDOUR_UI::update_cpu_load ()
560 {
561         char buf[32];
562         snprintf (buf, sizeof (buf), _("DSP Load: %.1f%%"), engine->get_cpu_load());
563         cpu_load_label.set_text (buf);
564 }
565
566 void
567 ARDOUR_UI::update_buffer_load ()
568 {
569         char buf[64];
570
571         if (session) {
572                 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"), 
573                           session->playback_load(), session->capture_load());
574                 buffer_load_label.set_text (buf);
575         } else {
576                 buffer_load_label.set_text ("");
577         }
578 }
579
580 void
581 ARDOUR_UI::count_recenabled_diskstreams (DiskStream& ds)
582 {
583         if (ds.record_enabled()) {
584                 rec_enabled_diskstreams++;
585         }
586 }
587
588 void
589 ARDOUR_UI::update_disk_space()
590 {
591         if (session == 0) {
592                 return;
593         }
594
595         jack_nframes_t frames = session->available_capture_duration();
596         char buf[64];
597
598         if (frames == max_frames) {
599                 strcpy (buf, _("space: 24hrs+"));
600         } else {
601                 int hrs;
602                 int mins;
603                 int secs;
604                 jack_nframes_t fr = session->frame_rate();
605                 
606                 if (session->actively_recording()){
607                         
608                         rec_enabled_diskstreams = 0;
609                         session->foreach_diskstream (this, &ARDOUR_UI::count_recenabled_diskstreams);
610                         
611                         if (rec_enabled_diskstreams) {
612                                 frames /= rec_enabled_diskstreams;
613                         }
614                         
615                 } else {
616                         
617                         /* hmmm. shall we divide by the route count? or the diskstream count?
618                            or what? for now, do nothing ...
619                         */
620                         
621                 }
622                 
623                 hrs  = frames / (fr * 3600);
624                 frames -= hrs * fr * 3600;
625                 mins = frames / (fr * 60);
626                 frames -= mins * fr * 60;
627                 secs = frames / fr;
628                 
629                 snprintf (buf, sizeof(buf), _("space: %02dh:%02dm:%02ds"), hrs, mins, secs);
630         }
631
632         disk_space_label.set_text (buf);
633 }                 
634
635 gint
636 ARDOUR_UI::update_wall_clock ()
637 {
638         time_t now;
639         struct tm *tm_now;
640         char buf[16];
641
642         time (&now);
643         tm_now = localtime (&now);
644
645         sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
646         wall_clock_label.set_text (buf);
647
648         return TRUE;
649 }
650 void
651 ARDOUR_UI::control_methods_adjusted ()
652
653 {
654         int which_method;
655
656         which_method = (int) online_control_button->adjustment.get_value();
657         switch (which_method) {
658         case 0:
659                 allow_mmc_and_local ();
660                 break;
661         case 1:
662                 allow_mmc_only ();
663                 break;
664         case 2:
665                 allow_local_only ();
666                 break;
667         default:
668                 fatal << _("programming error: impossible control method") << endmsg;
669         }
670 }
671         
672
673 void
674 ARDOUR_UI::mmc_device_id_adjusted ()
675
676 {
677 #if 0
678         if (mmc) {
679                 int dev_id = (int) mmc_id_button->adjustment.get_value();
680                 mmc->set_device_id (dev_id);
681         }
682 #endif
683 }
684
685 gint
686 ARDOUR_UI::session_menu (GdkEventButton *ev)
687 {
688         session_popup_menu->popup (0, 0);
689         return TRUE;
690 }
691
692 void
693 ARDOUR_UI::redisplay_recent_sessions ()
694 {
695         vector<string *> *sessions;
696         vector<string *>::iterator i;
697         RecentSessionsSorter cmp;
698         
699         recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
700         recent_session_model->clear ();
701
702         RecentSessions rs;
703         ARDOUR::read_recent_sessions (rs);
704
705         if (rs.empty()) {
706                 recent_session_display.set_model (recent_session_model);
707                 return;
708         }
709
710         /* sort them alphabetically */
711         sort (rs.begin(), rs.end(), cmp);
712         sessions = new vector<string*>;
713
714         for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
715                 sessions->push_back (new string ((*i).second));
716         }
717
718         for (i = sessions->begin(); i != sessions->end(); ++i) {
719
720                 vector<string*>* states;
721                 vector<const gchar*> item;
722                 string fullpath = *(*i);
723                 
724                 /* remove any trailing / */
725
726                 if (fullpath[fullpath.length()-1] == '/') {
727                         fullpath = fullpath.substr (0, fullpath.length()-1);
728                 }
729
730                 /* now get available states for this session */
731
732                 if ((states = Session::possible_states (fullpath)) == 0) {
733                         /* no state file? */
734                         continue;
735                 }
736
737                 TreeModel::Row row = *(recent_session_model->append());
738
739                 row[recent_session_columns.visible_name] = PBD::basename (fullpath);
740                 row[recent_session_columns.fullpath] = fullpath;
741
742                 if (states->size() > 1) {
743
744                         /* add the children */
745                         
746                         for (vector<string*>::iterator i2 = states->begin(); i2 != states->end(); ++i2) {
747                                 
748                                 TreeModel::Row child_row = *(recent_session_model->append (row.children()));
749
750                                 child_row[recent_session_columns.visible_name] = **i2;
751                                 child_row[recent_session_columns.fullpath] = fullpath;
752
753                                 delete *i2;
754                         }
755                 }
756
757                 delete states;
758         }
759
760         recent_session_display.set_model (recent_session_model);
761         delete sessions;
762 }
763
764 void
765 ARDOUR_UI::build_session_selector ()
766 {
767         session_selector_window = new ArdourDialog ("session selector");
768         
769         Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
770         
771         session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
772         session_selector_window->add_button (Stock::OPEN, RESPONSE_ACCEPT);
773         session_selector_window->set_default_response (RESPONSE_ACCEPT);
774         recent_session_model = TreeStore::create (recent_session_columns);
775         recent_session_display.set_model (recent_session_model);
776         recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
777         recent_session_display.set_headers_visible (false);
778         recent_session_display.get_selection()->set_mode (SELECTION_SINGLE);
779
780         recent_session_display.signal_row_activated().connect (mem_fun (*this, &ARDOUR_UI::recent_session_row_activated));
781
782         scroller->add (recent_session_display);
783         scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
784
785         session_selector_window->set_name ("SessionSelectorWindow");
786         session_selector_window->set_size_request (200, 400);
787         session_selector_window->get_vbox()->pack_start (*scroller);
788         session_selector_window->show_all_children();
789 }
790
791 void
792 ARDOUR_UI::recent_session_row_activated (const TreePath& path, TreeViewColumn* col)
793 {
794         session_selector_window->response (RESPONSE_ACCEPT);
795 }
796
797 void
798 ARDOUR_UI::open_recent_session ()
799 {
800         /* popup selector window */
801
802         if (session_selector_window == 0) {
803                 build_session_selector ();
804         }
805
806         redisplay_recent_sessions ();
807
808         ResponseType r = (ResponseType) session_selector_window->run ();
809
810         session_selector_window->hide();
811
812         switch (r) {
813         case RESPONSE_ACCEPT:
814                 break;
815         default:
816                 return;
817         }
818
819         Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
820
821         if (i == recent_session_model->children().end()) {
822                 return;
823         }
824         
825         Glib::ustring path = (*i)[recent_session_columns.fullpath];
826         Glib::ustring state = (*i)[recent_session_columns.visible_name];
827
828         _session_is_new = false;
829
830         load_session (path, state);
831 }
832
833 bool
834 ARDOUR_UI::filter_ardour_session_dirs (const FileFilter::Info& info) 
835 {
836         struct stat statbuf;
837
838         if (stat (info.filename.c_str(), &statbuf) != 0) {
839                 return false;
840         }
841
842         if (!S_ISDIR(statbuf.st_mode)) {
843                 return false;
844         }
845
846         string session_file = info.filename;
847         session_file += '/';
848         session_file += PBD::basename (info.filename);
849         session_file += ".ardour";
850         
851         if (stat (session_file.c_str(), &statbuf) != 0) {
852                 return false;
853         }
854
855         return S_ISREG (statbuf.st_mode);
856 }
857
858 void
859 ARDOUR_UI::open_session ()
860 {
861         /* popup selector window */
862
863         if (open_session_selector == 0) {
864
865                 /* ardour sessions are folders */
866
867                 open_session_selector = new Gtk::FileChooserDialog (_("open session"), FILE_CHOOSER_ACTION_OPEN);
868                 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
869                 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
870
871                 FileFilter session_filter;
872                 session_filter.add_pattern ("*.ardour");
873                 session_filter.set_name (_("Ardour sessions"));
874                 open_session_selector->add_filter (session_filter);
875                 open_session_selector->set_filter (session_filter);
876         }
877
878         int response = open_session_selector->run();
879         open_session_selector->hide ();
880
881         switch (response) {
882         case RESPONSE_ACCEPT:
883                 break;
884         default:
885                 open_session_selector->hide();
886                 return;
887         }
888
889         open_session_selector->hide();
890         string session_path = open_session_selector->get_filename();
891         string path, name;
892         bool isnew;
893
894         if (session_path.length() > 0) {
895                 if (Session::find_session (session_path, path, name, isnew) == 0) {
896                         _session_is_new = isnew;
897                         load_session (path, name);
898                 }
899         }
900 }
901
902
903 void
904 ARDOUR_UI::session_add_midi_track ()
905 {
906         cerr << _("Patience is a virtue.\n");
907 }
908
909 void
910 ARDOUR_UI::session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode)
911 {
912         Route* route;
913
914         if (session == 0) {
915                 warning << _("You cannot add a track without a session already loaded.") << endmsg;
916                 return;
917         }
918
919         try { 
920                 if (disk) {
921                         if ((route = session->new_audio_track (input_channels, output_channels, mode)) == 0) {
922                                 error << _("could not create new audio track") << endmsg;
923                         }
924                 } else {
925                         if ((route = session->new_audio_route (input_channels, output_channels)) == 0) {
926                                 error << _("could not create new audio bus") << endmsg;
927                         }
928                 }
929                 
930 #if CONTROLOUTS
931                 if (need_control_room_outs) {
932                         pan_t pans[2];
933                         
934                         pans[0] = 0.5;
935                         pans[1] = 0.5;
936                         
937                         route->set_stereo_control_outs (control_lr_channels);
938                         route->control_outs()->set_stereo_pan (pans, this);
939                 }
940 #endif /* CONTROLOUTS */
941         }
942
943         catch (...) {
944                 MessageDialog msg (*editor, 
945                                    _("There are insufficient JACK ports available\n\
946 to create a new track or bus.\n\
947 You should save Ardour, exit and\n\
948 restart JACK with more ports."));
949                 msg.run ();
950         }
951 }
952
953 void
954 ARDOUR_UI::diskstream_added (DiskStream* ds)
955 {
956 }
957
958 void
959 ARDOUR_UI::do_transport_locate (jack_nframes_t new_position)
960 {
961         jack_nframes_t _preroll;
962
963         if (session) {
964                 _preroll = session->convert_to_frames_at (new_position, session->preroll);
965
966                 if (new_position > _preroll) {
967                         new_position -= _preroll;
968                 } else {
969                         new_position = 0;
970                 }
971
972                 session->request_locate (new_position);
973         }
974 }
975
976 void
977 ARDOUR_UI::transport_goto_start ()
978 {
979         if (session) {
980                 session->goto_start();
981
982                 
983                 /* force displayed area in editor to start no matter
984                    what "follow playhead" setting is.
985                 */
986                 
987                 if (editor) {
988                         editor->reposition_x_origin (session->current_start_frame());
989                 }
990         }
991 }
992
993 void
994 ARDOUR_UI::transport_goto_zero ()
995 {
996         if (session) {
997                 session->request_locate (0);
998
999                 
1000                 /* force displayed area in editor to start no matter
1001                    what "follow playhead" setting is.
1002                 */
1003                 
1004                 if (editor) {
1005                         editor->reposition_x_origin (0);
1006                 }
1007         }
1008 }
1009
1010 void
1011 ARDOUR_UI::transport_goto_end ()
1012 {
1013         if (session) {
1014                 jack_nframes_t frame = session->current_end_frame();
1015                 session->request_locate (frame);
1016
1017                 /* force displayed area in editor to start no matter
1018                    what "follow playhead" setting is.
1019                 */
1020                 
1021                 if (editor) {
1022                         editor->reposition_x_origin (frame);
1023                 }
1024         }
1025 }
1026
1027 void
1028 ARDOUR_UI::transport_stop ()
1029 {
1030         if (!session) {
1031                 return;
1032         }
1033
1034         if (session->is_auditioning()) {
1035                 session->cancel_audition ();
1036                 return;
1037         }
1038         
1039         if (session->get_auto_loop()) {
1040                 session->request_auto_loop (false);
1041         }
1042         
1043         session->request_stop ();
1044 }
1045
1046 void
1047 ARDOUR_UI::transport_stop_and_forget_capture ()
1048 {
1049         if (session) {
1050                 session->request_stop (true);
1051         }
1052 }
1053
1054 void
1055 ARDOUR_UI::remove_last_capture()
1056 {
1057         if (editor) {
1058                 editor->remove_last_capture();
1059         }
1060 }
1061
1062 void
1063 ARDOUR_UI::transport_record ()
1064 {
1065         if (session) {
1066                 switch (session->record_status()) {
1067                 case Session::Disabled:
1068                         if (session->ntracks() == 0) {
1069                                 string txt = _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu.");
1070                                 MessageDialog msg (*editor, txt);
1071                                 msg.run ();
1072                                 return;
1073                         }
1074                         session->maybe_enable_record ();
1075                         break;
1076                 case Session::Recording:
1077                 case Session::Enabled:
1078                         session->disable_record (true);
1079                 }
1080         }
1081 }
1082
1083 void
1084 ARDOUR_UI::transport_roll ()
1085 {
1086         bool rolling;
1087
1088         if (!session) {
1089                 return;
1090         }
1091
1092         rolling = session->transport_rolling ();
1093
1094         if (session->get_auto_loop()) {
1095                 session->request_auto_loop (false);
1096                 auto_loop_button.set_active (false);
1097                 roll_button.set_active (true);
1098         } else if (session->get_play_range ()) {
1099                 session->request_play_range (false);
1100                 play_selection_button.set_active (false);
1101         } else if (rolling) {
1102                 session->request_locate (session->last_transport_start(), true);
1103         }
1104
1105         session->request_transport_speed (1.0f);
1106 }
1107
1108 void
1109 ARDOUR_UI::transport_loop()
1110 {
1111         if (session) {
1112                 if (session->get_auto_loop()) {
1113                         if (session->transport_rolling()) {
1114                                 Location * looploc = session->locations()->auto_loop_location();
1115                                 if (looploc) {
1116                                         session->request_locate (looploc->start(), true);
1117                                 }
1118                         }
1119                 }
1120                 else {
1121                         session->request_auto_loop (true);
1122                 }
1123         }
1124 }
1125
1126 void
1127 ARDOUR_UI::transport_play_selection ()
1128 {
1129         if (!session) {
1130                 return;
1131         }
1132
1133         if (!session->get_play_range()) {
1134                 session->request_stop ();
1135         }
1136
1137         editor->play_selection ();
1138 }
1139
1140 void
1141 ARDOUR_UI::transport_rewind (int option)
1142 {
1143         float current_transport_speed;
1144  
1145         if (session) {
1146                 current_transport_speed = session->transport_speed();
1147                 
1148                 if (current_transport_speed >= 0.0f) {
1149                         switch (option) {
1150                         case 0:
1151                                 session->request_transport_speed (-1.0f);
1152                                 break;
1153                         case 1:
1154                                 session->request_transport_speed (-4.0f);
1155                                 break;
1156                         case -1:
1157                                 session->request_transport_speed (-0.5f);
1158                                 break;
1159                         }
1160                 } else {
1161                         /* speed up */
1162                         session->request_transport_speed (current_transport_speed * 1.5f);
1163                 }
1164         }
1165 }
1166
1167 void
1168 ARDOUR_UI::transport_forward (int option)
1169 {
1170         float current_transport_speed;
1171         
1172         if (session) {
1173                 current_transport_speed = session->transport_speed();
1174                 
1175                 if (current_transport_speed <= 0.0f) {
1176                         switch (option) {
1177                         case 0:
1178                                 session->request_transport_speed (1.0f);
1179                                 break;
1180                         case 1:
1181                                 session->request_transport_speed (4.0f);
1182                                 break;
1183                         case -1:
1184                                 session->request_transport_speed (0.5f);
1185                                 break;
1186                         }
1187                 } else {
1188                         /* speed up */
1189                         session->request_transport_speed (current_transport_speed * 1.5f);
1190                 }
1191         }
1192 }
1193
1194 void
1195 ARDOUR_UI::toggle_monitor_enable (guint32 dstream)
1196 {
1197         if (session == 0) {
1198                 return;
1199         }
1200
1201         DiskStream *ds;
1202
1203         if ((ds = session->diskstream_by_id (dstream)) != 0) {
1204                 Port *port = ds->io()->input (0);
1205                 port->request_monitor_input (!port->monitoring_input());
1206         }
1207 }
1208
1209 void
1210 ARDOUR_UI::toggle_record_enable (guint32 dstream)
1211 {
1212         if (session == 0) {
1213                 return;
1214         }
1215
1216         DiskStream *ds;
1217
1218         if ((ds = session->diskstream_by_id (dstream)) != 0) {
1219                 ds->set_record_enabled (!ds->record_enabled(), this);
1220         }
1221 }
1222
1223 void
1224 ARDOUR_UI::queue_transport_change ()
1225 {
1226         Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
1227 }
1228
1229 void
1230 ARDOUR_UI::map_transport_state ()
1231 {
1232         float sp = session->transport_speed();
1233
1234         if (sp == 1.0f) {
1235                 transport_rolling ();
1236         } else if (sp < 0.0f) {
1237                 transport_rewinding ();
1238         } else if (sp > 0.0f) {
1239                 transport_forwarding ();
1240         } else {
1241                 transport_stopped ();
1242         }
1243 }
1244
1245 void
1246 ARDOUR_UI::allow_local_only ()
1247 {
1248
1249 }
1250
1251 void
1252 ARDOUR_UI::allow_mmc_only ()
1253 {
1254
1255 }
1256
1257 void
1258 ARDOUR_UI::allow_mmc_and_local ()
1259 {
1260
1261 }
1262
1263 void
1264 ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg)
1265 {
1266         snprintf (buf, sizeof(buf), "%s", ((GlobalClickBox *) arg)->strings[
1267                 (int) adj.get_value()].c_str());
1268 }
1269
1270 void
1271 ARDOUR_UI::engine_stopped ()
1272 {
1273         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
1274         ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1275         ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1276 }
1277
1278
1279 void
1280 ARDOUR_UI::engine_running ()
1281 {
1282         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
1283         ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true);
1284         ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
1285 }
1286
1287 void
1288 ARDOUR_UI::engine_halted ()
1289 {
1290         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
1291
1292         ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1293         ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1294
1295         update_sample_rate (0);
1296
1297         MessageDialog msg (*editor, 
1298                            _("\
1299 JACK has either been shutdown or it\n\
1300 disconnected Ardour because Ardour\n\
1301 was not fast enough. You can save the\n\
1302 session and/or try to reconnect to JACK ."));
1303         msg.run ();
1304 }
1305
1306 int32_t
1307 ARDOUR_UI::do_engine_start ()
1308 {
1309         try { 
1310                 engine->start();
1311         }
1312
1313         catch (AudioEngine::PortRegistrationFailure& err) {
1314                 engine->stop ();
1315                 error << _("Unable to create all required ports")
1316                       << endmsg;
1317                 unload_session ();
1318                 return -1;
1319         }
1320
1321         catch (...) {
1322                 engine->stop ();
1323                 error << _("Unable to start the session running")
1324                       << endmsg;
1325                 unload_session ();
1326                 return -2;
1327         }
1328         
1329         return 0;
1330 }
1331
1332 gint
1333 ARDOUR_UI::start_engine ()
1334 {
1335         if (do_engine_start () == 0) {
1336                 if (session && _session_is_new) {
1337                         /* we need to retain initial visual 
1338                            settings for a new session 
1339                         */
1340                         session->save_state ("");
1341                 }
1342
1343                 /* there is too much going on, in too many threads, for us to 
1344                    end up with a clean session. So wait 1 second after loading,
1345                    and fix it up. its ugly, but until i come across a better
1346                    solution, its what we have.
1347                 */
1348
1349                 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::make_session_clean), 1000);
1350         }
1351
1352         return FALSE;
1353 }
1354
1355 void
1356 ARDOUR_UI::update_clocks ()
1357 {
1358          Clock (session->audible_frame()); /* EMIT_SIGNAL */
1359 }
1360
1361 void
1362 ARDOUR_UI::start_clocking ()
1363 {
1364         clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
1365 }
1366
1367 void
1368 ARDOUR_UI::stop_clocking ()
1369 {
1370         clock_signal_connection.disconnect ();
1371 }
1372         
1373 void
1374 ARDOUR_UI::toggle_clocking ()
1375 {
1376 #if 0
1377         if (clock_button.get_active()) {
1378                 start_clocking ();
1379         } else {
1380                 stop_clocking ();
1381         }
1382 #endif
1383 }
1384
1385 gint
1386 ARDOUR_UI::_blink (void *arg)
1387
1388 {
1389         ((ARDOUR_UI *) arg)->blink ();
1390         return TRUE;
1391 }
1392
1393 void
1394 ARDOUR_UI::blink ()
1395 {
1396          Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
1397 }
1398
1399 void
1400 ARDOUR_UI::start_blinking ()
1401 {
1402         /* Start the blink signal. Everybody with a blinking widget
1403            uses Blink to drive the widget's state.
1404         */
1405
1406         if (blink_timeout_tag < 0) {
1407                 blink_on = false;       
1408                 blink_timeout_tag = gtk_timeout_add (240, _blink, this);
1409         }
1410 }
1411
1412 void
1413 ARDOUR_UI::stop_blinking ()
1414 {
1415         if (blink_timeout_tag >= 0) {
1416                 gtk_timeout_remove (blink_timeout_tag);
1417                 blink_timeout_tag = -1;
1418         }
1419 }
1420
1421
1422 void
1423 ARDOUR_UI::add_diskstream_to_menu (DiskStream& dstream)
1424 {
1425         using namespace Gtk;
1426         using namespace Menu_Helpers;
1427
1428         if (dstream.hidden()) {
1429                 return;
1430         }
1431
1432         MenuList& items = diskstream_menu->items();
1433         items.push_back (MenuElem (dstream.name(), bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), (gint32) dstream.id())));
1434 }
1435         
1436 void
1437 ARDOUR_UI::diskstream_selected (gint32 id)
1438 {
1439         selected_dstream = id;
1440         Main::quit ();
1441 }
1442
1443 gint32
1444 ARDOUR_UI::select_diskstream (GdkEventButton *ev)
1445 {
1446         using namespace Gtk;
1447         using namespace Menu_Helpers;
1448
1449         if (session == 0) {
1450                 return -1;
1451         }
1452
1453         diskstream_menu = new Menu();
1454         diskstream_menu->set_name ("ArdourContextMenu");
1455         using namespace Gtk;
1456         using namespace Menu_Helpers;
1457
1458         MenuList& items = diskstream_menu->items();
1459         items.push_back (MenuElem (_("No Stream"), (bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), -1))));
1460
1461         session->foreach_diskstream (this, &ARDOUR_UI::add_diskstream_to_menu);
1462
1463         if (ev) {
1464                 diskstream_menu->popup (ev->button, ev->time);
1465         } else {
1466                 diskstream_menu->popup (0, 0);
1467         }
1468
1469         selected_dstream = -1;
1470
1471         Main::run ();
1472
1473         delete diskstream_menu;
1474
1475         return selected_dstream;
1476 }
1477
1478 void
1479 ARDOUR_UI::name_io_setup (AudioEngine& engine, 
1480                           string& buf,
1481                           IO& io,
1482                           bool in)
1483 {
1484         if (in) {
1485                 if (io.n_inputs() == 0) {
1486                         buf = _("none");
1487                         return;
1488                 }
1489                 
1490                 /* XXX we're not handling multiple ports yet. */
1491
1492                 const char **connections = io.input(0)->get_connections();
1493                 
1494                 if (connections == 0 || connections[0] == '\0') {
1495                         buf = _("off");
1496                 } else {
1497                         buf = connections[0];
1498                 }
1499
1500                 free (connections);
1501
1502         } else {
1503
1504                 if (io.n_outputs() == 0) {
1505                         buf = _("none");
1506                         return;
1507                 }
1508                 
1509                 /* XXX we're not handling multiple ports yet. */
1510
1511                 const char **connections = io.output(0)->get_connections();
1512                 
1513                 if (connections == 0 || connections[0] == '\0') {
1514                         buf = _("off");
1515                 } else {
1516                         buf = connections[0];
1517                 }
1518
1519                 free (connections);
1520         }
1521 }
1522
1523 void
1524 ARDOUR_UI::snapshot_session ()
1525 {
1526         ArdourPrompter prompter (true);
1527         string snapname;
1528         string now;
1529         time_t n;
1530
1531         time (&n);
1532         now = ctime (&n);
1533         now = now.substr (20, 4) + now.substr (3, 16) + " (" + now.substr (0, 3) + ")";
1534
1535         prompter.set_name ("Prompter");
1536         prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1537         prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
1538         prompter.set_prompt (_("Name of New Snapshot"));
1539         prompter.set_initial_text (now);
1540         
1541         switch (prompter.run()) {
1542         case RESPONSE_ACCEPT:
1543                 prompter.get_result (snapname);
1544                 if (snapname.length()){
1545                         save_state (snapname);
1546                 }
1547                 break;
1548
1549         default:
1550                 break;
1551         }
1552 }
1553
1554 void
1555 ARDOUR_UI::save_state (const string & name)
1556 {
1557         (void) save_state_canfail (name);
1558 }
1559                 
1560 int
1561 ARDOUR_UI::save_state_canfail (string name)
1562 {
1563         if (session) {
1564                 int ret;
1565
1566                 if (name.length() == 0) {
1567                         name = session->snap_name();
1568                 }
1569
1570                 if ((ret = session->save_state (name)) != 0) {
1571                         return ret;
1572                 }
1573         }
1574         save_ardour_state (); /* XXX cannot fail? yeah, right ... */
1575         return 0;
1576 }
1577
1578 void
1579 ARDOUR_UI::restore_state (string name)
1580 {
1581         if (session) {
1582                 if (name.length() == 0) {
1583                         name = session->name();
1584                 }
1585                 session->restore_state (name);
1586         }
1587 }
1588
1589 void
1590 ARDOUR_UI::primary_clock_value_changed ()
1591 {
1592         if (session) {
1593                 session->request_locate (primary_clock.current_time ());
1594         }
1595 }
1596
1597 void
1598 ARDOUR_UI::secondary_clock_value_changed ()
1599 {
1600         if (session) {
1601                 session->request_locate (secondary_clock.current_time ());
1602         }
1603 }
1604
1605 void
1606 ARDOUR_UI::rec_enable_button_blink (bool onoff, DiskStream *dstream, Widget *w)
1607 {
1608         if (session && dstream && dstream->record_enabled()) {
1609
1610                 Session::RecordState rs;
1611                 
1612                 rs = session->record_status ();
1613
1614                 switch (rs) {
1615                 case Session::Disabled:
1616                 case Session::Enabled:
1617                         if (w->get_state() != STATE_SELECTED) {
1618                                 w->set_state (STATE_SELECTED);
1619                         }
1620                         break;
1621
1622                 case Session::Recording:
1623                         if (w->get_state() != STATE_ACTIVE) {
1624                                 w->set_state (STATE_ACTIVE);
1625                         }
1626                         break;
1627                 }
1628
1629         } else {
1630                 if (w->get_state() != STATE_NORMAL) {
1631                         w->set_state (STATE_NORMAL);
1632                 }
1633         }
1634 }
1635
1636 void
1637 ARDOUR_UI::transport_rec_enable_blink (bool onoff) 
1638 {
1639         if (session == 0) {
1640                 return;
1641         }
1642         
1643         switch (session->record_status()) {
1644         case Session::Enabled:
1645                 if (onoff) {
1646                         rec_button.set_state (1);
1647                 } else {
1648                         rec_button.set_state (0);
1649                 }
1650                 break;
1651
1652         case Session::Recording:
1653                 rec_button.set_state (2);
1654                 break;
1655
1656         default:
1657                 rec_button.set_state (0);
1658                 break;
1659         }
1660 }
1661
1662 gint
1663 ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
1664 {
1665         window->hide();
1666         Gtk::Main::quit ();
1667         return TRUE;
1668 }
1669
1670 void
1671 ARDOUR_UI::start_keyboard_prefix ()
1672 {
1673         keyboard->start_prefix();
1674 }
1675
1676 void
1677 ARDOUR_UI::save_template ()
1678
1679 {
1680         ArdourPrompter prompter (true);
1681         string name;
1682
1683         prompter.set_name (X_("Prompter"));
1684         prompter.set_prompt (_("Name for mix template:"));
1685         prompter.set_initial_text(session->name() + _("-template"));
1686         prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1687         prompter.set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
1688
1689         switch (prompter.run()) {
1690         case RESPONSE_ACCEPT:
1691                 prompter.get_result (name);
1692                 
1693                 if (name.length()) {
1694                         session->save_template (name);
1695                 }
1696                 break;
1697
1698         default:
1699                 break;
1700         }
1701 }
1702
1703 void
1704 ARDOUR_UI::new_session (bool startup, std::string predetermined_path)
1705 {
1706         m_new_session_dialog->show_all();
1707         m_new_session_dialog->set_transient_for(*editor);
1708         m_new_session_dialog->set_name(predetermined_path);
1709
1710         int response = Gtk::RESPONSE_CANCEL;
1711
1712         do {
1713                 response = m_new_session_dialog->run ();
1714                 if(response == Gtk::RESPONSE_CANCEL) {
1715                   quit();
1716                   return;
1717                 } else if (response == Gtk::RESPONSE_YES) {
1718                   /* YES  == OPEN, but there's no enum for that */
1719                   std::string session_name = m_new_session_dialog->session_name();
1720                   std::string session_path = m_new_session_dialog->session_folder();
1721                   load_session (session_path, session_name);
1722
1723
1724                 } else if (response == Gtk::RESPONSE_OK) {
1725                   if (m_new_session_dialog->get_current_page() == 1) {
1726
1727                     /* XXX this is a bit of a hack.. 
1728                        i really want the new sesion dialog to return RESPONSE_YES
1729                        if we're on page 1 (the load page)
1730                        Unfortunately i can't see how atm.. 
1731                     */
1732                         std::string session_name = m_new_session_dialog->session_name();
1733                         std::string session_path = m_new_session_dialog->session_folder();
1734                         load_session (session_path, session_name);
1735
1736                   } else {
1737
1738                         _session_is_new = true;
1739                         
1740                         std::string session_name = m_new_session_dialog->session_name();
1741                         std::string session_path = m_new_session_dialog->session_folder();
1742                         
1743                         /*
1744                           XXX This is needed because session constructor wants a 
1745                           non-existant path. hopefully this will be fixed at some point.
1746                         */
1747                         session_path = Glib::build_filename(session_path, session_name);
1748                         
1749                         std::string template_name = m_new_session_dialog->session_template_name();
1750                         
1751                         if (m_new_session_dialog->use_session_template()) {
1752                                 
1753                                 load_session (session_path, session_name, &template_name);
1754                                 
1755                         } else {
1756                                 
1757                                 uint32_t cchns;
1758                                 uint32_t mchns;
1759                                 Session::AutoConnectOption iconnect;
1760                                 Session::AutoConnectOption oconnect;
1761                                 
1762                                 if (m_new_session_dialog->create_control_bus()) {
1763                                         cchns = (uint32_t) m_new_session_dialog->control_channel_count();
1764                                 } else {
1765                                         cchns = 0;
1766                                 }
1767                                 
1768                                 if (m_new_session_dialog->create_master_bus()) {
1769                                         mchns = (uint32_t) m_new_session_dialog->master_channel_count();
1770                                 } else {
1771                                         mchns = 0;
1772                                 }
1773                                 
1774                                 if (m_new_session_dialog->connect_inputs()) {
1775                                         iconnect = Session::AutoConnectPhysical;
1776                                 } else {
1777                                         iconnect = Session::AutoConnectOption (0);
1778                                 }
1779                                 
1780                                 /// @todo some minor tweaks.
1781
1782                                 if (m_new_session_dialog->connect_outs_to_master()) {
1783                                         oconnect = Session::AutoConnectMaster;
1784                                 } else if (m_new_session_dialog->connect_outs_to_physical()) {
1785                                         oconnect = Session::AutoConnectPhysical;
1786                                 } else {
1787                                         oconnect = Session::AutoConnectOption (0);
1788                                 } 
1789                                 
1790                                 uint32_t nphysin = (uint32_t) m_new_session_dialog->input_limit_count();
1791                                 uint32_t nphysout = (uint32_t) m_new_session_dialog->output_limit_count();
1792                                 
1793                                 build_session (session_path,
1794                                                session_name,
1795                                                cchns,
1796                                                mchns,
1797                                                iconnect,
1798                                                oconnect,
1799                                                nphysin,
1800                                                nphysout, 
1801                                                engine->frame_rate() * 60 * 5);
1802                         }
1803                   }     
1804                 }
1805                 
1806         } while(response == Gtk::RESPONSE_HELP);
1807         m_new_session_dialog->hide_all();
1808         show();
1809
1810 }
1811
1812 void
1813 ARDOUR_UI::close_session()
1814 {
1815   unload_session();
1816   new_session ();
1817 }
1818
1819 int
1820 ARDOUR_UI::load_session (const string & path, const string & snap_name, string* mix_template)
1821 {
1822         Session *new_session;
1823         int x;
1824         session_loaded = false;
1825         x = unload_session ();
1826
1827         if (x < 0) {
1828                 return -1;
1829         } else if (x > 0) {
1830                 return 0;
1831         }
1832
1833         /* if it already exists, we must have write access */
1834
1835         if (::access (path.c_str(), F_OK) == 0 && ::access (path.c_str(), W_OK)) {
1836                 MessageDialog msg (*editor, _("\
1837 You do not have write access to this session.\n\
1838 This prevents the session from being loaded."));
1839                 msg.run ();
1840                 return -1;
1841         }
1842
1843         try {
1844                 new_session = new Session (*engine, path, snap_name, mix_template);
1845         }
1846
1847         catch (...) {
1848
1849                 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
1850                 return -1;
1851         }
1852
1853         connect_to_session (new_session);
1854
1855         //if (engine->running()) {
1856         //mixer->show_window();
1857         //}
1858         session_loaded = true;
1859         return 0;
1860 }
1861
1862 int
1863 ARDOUR_UI::make_session_clean ()
1864 {
1865         if (session) {
1866                 session->set_clean ();
1867         }
1868
1869         show ();
1870
1871         return FALSE;
1872 }
1873
1874 int
1875 ARDOUR_UI::build_session (const string & path, const string & snap_name, 
1876                           uint32_t control_channels,
1877                           uint32_t master_channels, 
1878                           Session::AutoConnectOption input_connect,
1879                           Session::AutoConnectOption output_connect,
1880                           uint32_t nphysin,
1881                           uint32_t nphysout,
1882                           jack_nframes_t initial_length)
1883 {
1884         Session *new_session;
1885         int x;
1886
1887         session_loaded = false;
1888         x = unload_session ();
1889         if (x < 0) {
1890                 return -1;
1891         } else if (x > 0) {
1892                 return 0;
1893         }
1894         
1895         _session_is_new = true;
1896
1897         try {
1898                 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
1899                                            control_channels, master_channels, nphysin, nphysout, initial_length);
1900         }
1901
1902         catch (...) {
1903
1904                 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
1905                 return -1;
1906         }
1907
1908         connect_to_session (new_session);
1909
1910         //if (engine->running()) {
1911         //mixer->show_window();
1912         //}
1913         session_loaded = true;
1914         return 0;
1915 }
1916
1917 void
1918 ARDOUR_UI::show ()
1919 {
1920         if (editor) {
1921                 editor->show_window ();
1922                 shown_flag = true;
1923         }
1924
1925         if (session && mixer) {
1926                 // mixer->show_window ();
1927         }
1928         
1929         if (about) {
1930                 about->present ();
1931         }
1932 }
1933
1934 void
1935 ARDOUR_UI::show_splash ()
1936 {
1937         if (about == 0) {
1938                 about = new About();
1939         }
1940         about->present();
1941 }
1942
1943 void
1944 ARDOUR_UI::hide_splash ()
1945 {
1946         if (about) {
1947                 // about->hide();
1948         }
1949 }
1950
1951 void
1952 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title, const string & msg)
1953 {
1954         size_t removed;
1955
1956         removed = rep.paths.size();
1957
1958         if (removed == 0) {
1959                 MessageDialog msgd (*editor,
1960                                     _("No audio files were ready for cleanup"), 
1961                                     true,
1962                                     Gtk::MESSAGE_INFO,
1963                                     (Gtk::ButtonsType)(Gtk::BUTTONS_CLOSE)  );
1964                 msgd.set_secondary_text (_("If this seems suprising, \n\
1965 check for any existing snapshots.\n\
1966 These may still include regions that\n\
1967 require some unused files to continue to exist."));
1968         
1969                 msgd.run ();
1970                 return;
1971         } 
1972
1973         ArdourDialog results (_("ardour: cleanup"), true, false);
1974         
1975         struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
1976             CleanupResultsModelColumns() { 
1977                     add (visible_name);
1978                     add (fullpath);
1979             }
1980             Gtk::TreeModelColumn<Glib::ustring> visible_name;
1981             Gtk::TreeModelColumn<Glib::ustring> fullpath;
1982         };
1983
1984         
1985         CleanupResultsModelColumns results_columns;
1986         Glib::RefPtr<Gtk::ListStore> results_model;
1987         Gtk::TreeView results_display;
1988         
1989         results_model = ListStore::create (results_columns);
1990         results_display.set_model (results_model);
1991         results_display.append_column (list_title, results_columns.visible_name);
1992
1993         results_display.set_name ("CleanupResultsList");
1994         results_display.set_headers_visible (true);
1995         results_display.set_headers_clickable (false);
1996         results_display.set_reorderable (false);
1997
1998         Gtk::ScrolledWindow list_scroller;
1999         Gtk::Label txt;
2000         Gtk::VBox dvbox;
2001         Gtk::HBox dhbox;  // the hbox for the image and text
2002         Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
2003         Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO,  Gtk::ICON_SIZE_DIALOG));
2004
2005         dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
2006
2007         if (rep.space < 1048576.0f) {
2008                 if (removed > 1) {
2009                   txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2010                 } else {
2011                         txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2012                 }
2013         } else {
2014                 if (removed > 1) {
2015                         txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2016                 } else {
2017                         txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2018                 }
2019         }
2020
2021         dhbox.pack_start (*dimage, true, false, 5);
2022         dhbox.pack_start (txt, true, false, 5);
2023
2024         for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2025                 TreeModel::Row row = *(results_model->append());
2026                 row[results_columns.visible_name] = *i;
2027                 row[results_columns.fullpath] = *i;
2028         }
2029         
2030         list_scroller.add (results_display);
2031         list_scroller.set_size_request (-1, 150);
2032         list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2033
2034         dvbox.pack_start (dhbox, true, false, 5);
2035         dvbox.pack_start (list_scroller, true, false, 5);
2036         ddhbox.pack_start (dvbox, true, false, 5);
2037
2038         results.get_vbox()->pack_start (ddhbox, true, false, 5);
2039         results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
2040         results.set_default_response (RESPONSE_CLOSE);
2041         results.set_position (Gtk::WIN_POS_MOUSE);
2042         results.show_all_children ();
2043         results.set_resizable (false);
2044
2045         results.run ();
2046
2047 }
2048
2049 void
2050 ARDOUR_UI::cleanup ()
2051 {
2052         if (session == 0) {
2053                 /* shouldn't happen: menu item is insensitive */
2054                 return;
2055         }
2056
2057
2058         MessageDialog  checker (_("Are you sure you want to cleanup?"),
2059                                 true,
2060                                 Gtk::MESSAGE_QUESTION,
2061                                 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
2062
2063         checker.set_secondary_text(_("Cleanup is a destructive operation.\n\
2064 ALL undo/redo information will be lost if you cleanup.\n\
2065 After cleanup, unused audio files will be moved to a \
2066 \"dead sounds\" location."));
2067         
2068         checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2069         checker.add_button (_("Clean Up"), RESPONSE_ACCEPT);
2070         checker.set_default_response (RESPONSE_CANCEL);
2071
2072         checker.set_name (_("CleanupDialog"));
2073         checker.set_wmclass (_("ardour_cleanup"), "Ardour");
2074         checker.set_position (Gtk::WIN_POS_MOUSE);
2075
2076         switch (checker.run()) {
2077         case RESPONSE_ACCEPT:
2078                 break;
2079         default:
2080                 return;
2081         }
2082
2083         Session::cleanup_report rep;
2084
2085         editor->prepare_for_cleanup ();
2086
2087         if (session->cleanup_sources (rep)) {
2088                 return;
2089         }
2090         checker.hide();
2091         display_cleanup_results (rep, 
2092                                  _("cleaned files"),
2093                                  _("\
2094 The following %1 %2 not in use and \n\
2095 have been moved to:\n\
2096 %3. \n\n\
2097 Flushing the wastebasket will \n\
2098 release an additional\n\
2099 %4 %5bytes of disk space.\n"
2100                                          ));
2101 }
2102
2103 void
2104 ARDOUR_UI::flush_trash ()
2105 {
2106         if (session == 0) {
2107                 /* shouldn't happen: menu item is insensitive */
2108                 return;
2109         }
2110
2111         Session::cleanup_report rep;
2112
2113         if (session->cleanup_trash_sources (rep)) {
2114                 return;
2115         }
2116
2117         display_cleanup_results (rep, 
2118                                  _("deleted file"),
2119                                  _("The following %1 %2 deleted from\n\
2120 %3,\n\
2121 releasing %4 %5bytes of disk space"));
2122 }
2123
2124 void
2125 ARDOUR_UI::add_route ()
2126 {
2127         int count;
2128
2129         if (!session) {
2130                 return;
2131         }
2132
2133         if (add_route_dialog == 0) {
2134                 add_route_dialog = new AddRouteDialog;
2135                 editor->ensure_float (*add_route_dialog);
2136         }
2137
2138         if (add_route_dialog->is_visible()) {
2139                 /* we're already doing this */
2140                 return;
2141         }
2142
2143         ResponseType r = (ResponseType) add_route_dialog->run ();
2144         
2145         add_route_dialog->hide();
2146
2147         switch (r) {
2148         case RESPONSE_ACCEPT:
2149                 break;
2150         default:
2151                 return;
2152                 break;
2153         }
2154
2155         if ((count = add_route_dialog->count()) <= 0) {
2156                 return;
2157         }
2158
2159         uint32_t input_chan = add_route_dialog->channels ();
2160         uint32_t output_chan;
2161         string name_template = add_route_dialog->name_template ();
2162         bool track = add_route_dialog->track ();
2163
2164         Session::AutoConnectOption oac = session->get_output_auto_connect();
2165
2166         if (oac & Session::AutoConnectMaster) {
2167                 output_chan = (session->master_out() ? session->master_out()->n_inputs() : input_chan);
2168         } else {
2169                 output_chan = input_chan;
2170         }
2171
2172         /* XXX do something with name template */
2173
2174         while (count) {
2175                 if (track) {
2176                         session_add_audio_track (input_chan, output_chan, add_route_dialog->mode());
2177                 } else {
2178                         session_add_audio_bus (input_chan, output_chan);
2179                 }
2180                 --count;
2181                 
2182                 while (Main::events_pending()) {
2183                         Main::iteration ();
2184                 }
2185         }
2186 }
2187
2188 XMLNode*
2189 ARDOUR_UI::mixer_settings () const
2190 {
2191         XMLNode* node = 0;
2192
2193         if (session) {
2194                 node = session->instant_xml(X_("Mixer"), session->path());
2195         } else {
2196                 node = Config->instant_xml(X_("Mixer"), get_user_ardour_path());
2197         }
2198
2199         if (!node) {
2200                 node = new XMLNode (X_("Mixer"));
2201         }
2202
2203         return node;
2204 }
2205
2206 XMLNode*
2207 ARDOUR_UI::editor_settings () const
2208 {
2209         XMLNode* node = 0;
2210
2211         if (session) {
2212                 node = session->instant_xml(X_("Editor"), session->path());
2213         } else {
2214                 node = Config->instant_xml(X_("Editor"), get_user_ardour_path());
2215         }
2216
2217         if (!node) {
2218                 node = new XMLNode (X_("Editor"));
2219         }
2220         return node;
2221 }
2222
2223 XMLNode*
2224 ARDOUR_UI::keyboard_settings () const
2225 {
2226         XMLNode* node = 0;
2227
2228         node = Config->extra_xml(X_("Keyboard"));
2229         
2230         if (!node) {
2231                 node = new XMLNode (X_("Keyboard"));
2232         }
2233         return node;
2234 }
2235
2236 void
2237 ARDOUR_UI::halt_on_xrun_message ()
2238 {
2239         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
2240
2241         MessageDialog msg (*editor,
2242                            _("Recording was stopped because your system could not keep up."));
2243         msg.run ();
2244 }
2245
2246 void 
2247 ARDOUR_UI::delete_sources_in_the_right_thread (list<ARDOUR::Source*>* deletion_list)
2248 {
2249         ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread), deletion_list));
2250
2251         for (list<Source*>::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) {
2252                 delete *i;
2253         }
2254
2255         delete deletion_list;
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 (jack_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 (false, 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::set_native_file_header_format (HeaderFormat hf)
2389 {
2390         Glib::RefPtr<Action> act;
2391         
2392         switch (hf) {
2393         case BWF:
2394                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
2395                 break;
2396         case WAVE:
2397                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
2398                 break;
2399         case WAVE64:
2400                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
2401                 break;
2402         case iXML:
2403                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
2404                 break;
2405         case RF64:
2406                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
2407                 break;
2408         }
2409
2410         if (act) {
2411                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2412                 if (ract && ract->get_active() && Config->get_native_file_header_format() != hf) {
2413                         Config->set_native_file_header_format (hf);
2414                         if (session) {
2415                                 session->reset_native_file_format ();
2416                         }
2417                 }
2418         }
2419 }
2420
2421 void
2422 ARDOUR_UI::set_native_file_data_format (SampleFormat sf)
2423 {
2424         Glib::RefPtr<Action> act;
2425         
2426         switch (sf) {
2427         case FormatFloat:
2428                 act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
2429                 break;
2430         case FormatInt24:
2431                 act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
2432                 break;
2433         }
2434
2435         if (act) {
2436                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2437
2438                 if (ract && ract->get_active() && Config->get_native_file_data_format() != sf) {
2439                         Config->set_native_file_data_format (sf);
2440                         if (session) {
2441                                 session->reset_native_file_format ();
2442                         }
2443                 }
2444         }
2445 }
2446
2447 void
2448 ARDOUR_UI::use_config ()
2449 {
2450         Glib::RefPtr<Action> act;
2451
2452         switch (Config->get_native_file_data_format ()) {
2453         case FormatFloat:
2454                 act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
2455                 break;
2456         case FormatInt24:
2457                 act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
2458                 break;
2459         }
2460
2461         if (act) {
2462                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2463                 ract->set_active ();
2464         }       
2465
2466         switch (Config->get_native_file_header_format ()) {
2467         case BWF:
2468                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
2469                 break;
2470         case WAVE:
2471                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
2472                 break;
2473         case WAVE64:
2474                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
2475                 break;
2476         case iXML:
2477                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
2478                 break;
2479         case RF64:
2480                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
2481                 break;
2482         }
2483
2484         if (act) {
2485                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2486                 ract->set_active ();
2487         }       
2488 }