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