Some fixes to the new session dialog.
[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_modal(true);
1708         m_new_session_dialog->set_name(predetermined_path);
1709         m_new_session_dialog->reset_recent();
1710
1711         int response = Gtk::RESPONSE_CANCEL;
1712
1713         do {
1714                 response = m_new_session_dialog->run ();
1715                 if(response == Gtk::RESPONSE_CANCEL || response == Gtk::RESPONSE_DELETE_EVENT) {
1716                   quit();
1717                   return;
1718
1719                 } else if (response == 0) {
1720                   /* Clear was pressed */
1721                   m_new_session_dialog->reset();
1722
1723                 } else if (response == Gtk::RESPONSE_YES) {
1724                   /* YES  == OPEN, but there's no enum for that */
1725                   std::string session_name = m_new_session_dialog->session_name();
1726                   std::string session_path = m_new_session_dialog->session_folder();
1727                   load_session (session_path, session_name);
1728
1729
1730                 } else if (response == Gtk::RESPONSE_OK) {
1731                   if (m_new_session_dialog->get_current_page() == 1) {
1732
1733                     /* XXX this is a bit of a hack.. 
1734                        i really want the new sesion dialog to return RESPONSE_YES
1735                        if we're on page 1 (the load page)
1736                        Unfortunately i can't see how atm.. 
1737                     */
1738                         std::string session_name = m_new_session_dialog->session_name();
1739                         std::string session_path = m_new_session_dialog->session_folder();
1740                         load_session (session_path, session_name);
1741
1742                   } else {
1743
1744                         _session_is_new = true;
1745                         
1746                         std::string session_name = m_new_session_dialog->session_name();
1747                         std::string session_path = m_new_session_dialog->session_folder();
1748                         
1749                         /*
1750                           XXX This is needed because session constructor wants a 
1751                           non-existant path. hopefully this will be fixed at some point.
1752                         */
1753                         session_path = Glib::build_filename(session_path, session_name);
1754                         
1755                         std::string template_name = m_new_session_dialog->session_template_name();
1756                         
1757                         if (m_new_session_dialog->use_session_template()) {
1758                                 
1759                                 load_session (session_path, session_name, &template_name);
1760                                 
1761                         } else {
1762                                 
1763                                 uint32_t cchns;
1764                                 uint32_t mchns;
1765                                 Session::AutoConnectOption iconnect;
1766                                 Session::AutoConnectOption oconnect;
1767                                 
1768                                 if (m_new_session_dialog->create_control_bus()) {
1769                                         cchns = (uint32_t) m_new_session_dialog->control_channel_count();
1770                                 } else {
1771                                         cchns = 0;
1772                                 }
1773                                 
1774                                 if (m_new_session_dialog->create_master_bus()) {
1775                                         mchns = (uint32_t) m_new_session_dialog->master_channel_count();
1776                                 } else {
1777                                         mchns = 0;
1778                                 }
1779                                 
1780                                 if (m_new_session_dialog->connect_inputs()) {
1781                                         iconnect = Session::AutoConnectPhysical;
1782                                 } else {
1783                                         iconnect = Session::AutoConnectOption (0);
1784                                 }
1785                                 
1786                                 /// @todo some minor tweaks.
1787
1788                                 if (m_new_session_dialog->connect_outs_to_master()) {
1789                                         oconnect = Session::AutoConnectMaster;
1790                                 } else if (m_new_session_dialog->connect_outs_to_physical()) {
1791                                         oconnect = Session::AutoConnectPhysical;
1792                                 } else {
1793                                         oconnect = Session::AutoConnectOption (0);
1794                                 } 
1795                                 
1796                                 uint32_t nphysin = (uint32_t) m_new_session_dialog->input_limit_count();
1797                                 uint32_t nphysout = (uint32_t) m_new_session_dialog->output_limit_count();
1798                                 
1799                                 build_session (session_path,
1800                                                session_name,
1801                                                cchns,
1802                                                mchns,
1803                                                iconnect,
1804                                                oconnect,
1805                                                nphysin,
1806                                                nphysout, 
1807                                                engine->frame_rate() * 60 * 5);
1808                         }
1809                   }     
1810                 }
1811                 
1812         } while (response == 0);
1813         m_new_session_dialog->hide_all();
1814         show();
1815
1816 }
1817
1818 void
1819 ARDOUR_UI::close_session()
1820 {
1821   unload_session();
1822   new_session ();
1823 }
1824
1825 int
1826 ARDOUR_UI::load_session (const string & path, const string & snap_name, string* mix_template)
1827 {
1828         Session *new_session;
1829         int x;
1830         session_loaded = false;
1831         x = unload_session ();
1832
1833         if (x < 0) {
1834                 return -1;
1835         } else if (x > 0) {
1836                 return 0;
1837         }
1838
1839         /* if it already exists, we must have write access */
1840
1841         if (::access (path.c_str(), F_OK) == 0 && ::access (path.c_str(), W_OK)) {
1842                 MessageDialog msg (*editor, _("\
1843 You do not have write access to this session.\n\
1844 This prevents the session from being loaded."));
1845                 msg.run ();
1846                 return -1;
1847         }
1848
1849         try {
1850                 new_session = new Session (*engine, path, snap_name, mix_template);
1851         }
1852
1853         catch (...) {
1854
1855                 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
1856                 return -1;
1857         }
1858
1859         connect_to_session (new_session);
1860
1861         //if (engine->running()) {
1862         //mixer->show_window();
1863         //}
1864         session_loaded = true;
1865         return 0;
1866 }
1867
1868 int
1869 ARDOUR_UI::make_session_clean ()
1870 {
1871         if (session) {
1872                 session->set_clean ();
1873         }
1874
1875         show ();
1876
1877         return FALSE;
1878 }
1879
1880 int
1881 ARDOUR_UI::build_session (const string & path, const string & snap_name, 
1882                           uint32_t control_channels,
1883                           uint32_t master_channels, 
1884                           Session::AutoConnectOption input_connect,
1885                           Session::AutoConnectOption output_connect,
1886                           uint32_t nphysin,
1887                           uint32_t nphysout,
1888                           jack_nframes_t initial_length)
1889 {
1890         Session *new_session;
1891         int x;
1892
1893         session_loaded = false;
1894         x = unload_session ();
1895         if (x < 0) {
1896                 return -1;
1897         } else if (x > 0) {
1898                 return 0;
1899         }
1900         
1901         _session_is_new = true;
1902
1903         try {
1904                 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
1905                                            control_channels, master_channels, nphysin, nphysout, initial_length);
1906         }
1907
1908         catch (...) {
1909
1910                 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
1911                 return -1;
1912         }
1913
1914         connect_to_session (new_session);
1915
1916         //if (engine->running()) {
1917         //mixer->show_window();
1918         //}
1919         session_loaded = true;
1920         return 0;
1921 }
1922
1923 void
1924 ARDOUR_UI::show ()
1925 {
1926         if (editor) {
1927                 editor->show_window ();
1928                 shown_flag = true;
1929         }
1930
1931         if (session && mixer) {
1932                 // mixer->show_window ();
1933         }
1934         
1935         if (about) {
1936                 about->present ();
1937         }
1938 }
1939
1940 void
1941 ARDOUR_UI::show_splash ()
1942 {
1943         if (about == 0) {
1944                 about = new About();
1945         }
1946         about->present();
1947 }
1948
1949 void
1950 ARDOUR_UI::hide_splash ()
1951 {
1952         if (about) {
1953                 // about->hide();
1954         }
1955 }
1956
1957 void
1958 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title, const string & msg)
1959 {
1960         size_t removed;
1961
1962         removed = rep.paths.size();
1963
1964         if (removed == 0) {
1965                 MessageDialog msgd (*editor,
1966                                     _("No audio files were ready for cleanup"), 
1967                                     true,
1968                                     Gtk::MESSAGE_INFO,
1969                                     (Gtk::ButtonsType)(Gtk::BUTTONS_CLOSE)  );
1970                 msgd.set_secondary_text (_("If this seems suprising, \n\
1971 check for any existing snapshots.\n\
1972 These may still include regions that\n\
1973 require some unused files to continue to exist."));
1974         
1975                 msgd.run ();
1976                 return;
1977         } 
1978
1979         ArdourDialog results (_("ardour: cleanup"), true, false);
1980         
1981         struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
1982             CleanupResultsModelColumns() { 
1983                     add (visible_name);
1984                     add (fullpath);
1985             }
1986             Gtk::TreeModelColumn<Glib::ustring> visible_name;
1987             Gtk::TreeModelColumn<Glib::ustring> fullpath;
1988         };
1989
1990         
1991         CleanupResultsModelColumns results_columns;
1992         Glib::RefPtr<Gtk::ListStore> results_model;
1993         Gtk::TreeView results_display;
1994         
1995         results_model = ListStore::create (results_columns);
1996         results_display.set_model (results_model);
1997         results_display.append_column (list_title, results_columns.visible_name);
1998
1999         results_display.set_name ("CleanupResultsList");
2000         results_display.set_headers_visible (true);
2001         results_display.set_headers_clickable (false);
2002         results_display.set_reorderable (false);
2003
2004         Gtk::ScrolledWindow list_scroller;
2005         Gtk::Label txt;
2006         Gtk::VBox dvbox;
2007         Gtk::HBox dhbox;  // the hbox for the image and text
2008         Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
2009         Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO,  Gtk::ICON_SIZE_DIALOG));
2010
2011         dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
2012
2013         if (rep.space < 1048576.0f) {
2014                 if (removed > 1) {
2015                   txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2016                 } else {
2017                         txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2018                 }
2019         } else {
2020                 if (removed > 1) {
2021                         txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2022                 } else {
2023                         txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2024                 }
2025         }
2026
2027         dhbox.pack_start (*dimage, true, false, 5);
2028         dhbox.pack_start (txt, true, false, 5);
2029
2030         for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2031                 TreeModel::Row row = *(results_model->append());
2032                 row[results_columns.visible_name] = *i;
2033                 row[results_columns.fullpath] = *i;
2034         }
2035         
2036         list_scroller.add (results_display);
2037         list_scroller.set_size_request (-1, 150);
2038         list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2039
2040         dvbox.pack_start (dhbox, true, false, 5);
2041         dvbox.pack_start (list_scroller, true, false, 5);
2042         ddhbox.pack_start (dvbox, true, false, 5);
2043
2044         results.get_vbox()->pack_start (ddhbox, true, false, 5);
2045         results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
2046         results.set_default_response (RESPONSE_CLOSE);
2047         results.set_position (Gtk::WIN_POS_MOUSE);
2048         results.show_all_children ();
2049         results.set_resizable (false);
2050
2051         results.run ();
2052
2053 }
2054
2055 void
2056 ARDOUR_UI::cleanup ()
2057 {
2058         if (session == 0) {
2059                 /* shouldn't happen: menu item is insensitive */
2060                 return;
2061         }
2062
2063
2064         MessageDialog  checker (_("Are you sure you want to cleanup?"),
2065                                 true,
2066                                 Gtk::MESSAGE_QUESTION,
2067                                 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
2068
2069         checker.set_secondary_text(_("Cleanup is a destructive operation.\n\
2070 ALL undo/redo information will be lost if you cleanup.\n\
2071 After cleanup, unused audio files will be moved to a \
2072 \"dead sounds\" location."));
2073         
2074         checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2075         checker.add_button (_("Clean Up"), RESPONSE_ACCEPT);
2076         checker.set_default_response (RESPONSE_CANCEL);
2077
2078         checker.set_name (_("CleanupDialog"));
2079         checker.set_wmclass (_("ardour_cleanup"), "Ardour");
2080         checker.set_position (Gtk::WIN_POS_MOUSE);
2081
2082         switch (checker.run()) {
2083         case RESPONSE_ACCEPT:
2084                 break;
2085         default:
2086                 return;
2087         }
2088
2089         Session::cleanup_report rep;
2090
2091         editor->prepare_for_cleanup ();
2092
2093         if (session->cleanup_sources (rep)) {
2094                 return;
2095         }
2096         checker.hide();
2097         display_cleanup_results (rep, 
2098                                  _("cleaned files"),
2099                                  _("\
2100 The following %1 %2 not in use and \n\
2101 have been moved to:\n\
2102 %3. \n\n\
2103 Flushing the wastebasket will \n\
2104 release an additional\n\
2105 %4 %5bytes of disk space.\n"
2106                                          ));
2107 }
2108
2109 void
2110 ARDOUR_UI::flush_trash ()
2111 {
2112         if (session == 0) {
2113                 /* shouldn't happen: menu item is insensitive */
2114                 return;
2115         }
2116
2117         Session::cleanup_report rep;
2118
2119         if (session->cleanup_trash_sources (rep)) {
2120                 return;
2121         }
2122
2123         display_cleanup_results (rep, 
2124                                  _("deleted file"),
2125                                  _("The following %1 %2 deleted from\n\
2126 %3,\n\
2127 releasing %4 %5bytes of disk space"));
2128 }
2129
2130 void
2131 ARDOUR_UI::add_route ()
2132 {
2133         int count;
2134
2135         if (!session) {
2136                 return;
2137         }
2138
2139         if (add_route_dialog == 0) {
2140                 add_route_dialog = new AddRouteDialog;
2141                 editor->ensure_float (*add_route_dialog);
2142         }
2143
2144         if (add_route_dialog->is_visible()) {
2145                 /* we're already doing this */
2146                 return;
2147         }
2148
2149         ResponseType r = (ResponseType) add_route_dialog->run ();
2150         
2151         add_route_dialog->hide();
2152
2153         switch (r) {
2154         case RESPONSE_ACCEPT:
2155                 break;
2156         default:
2157                 return;
2158                 break;
2159         }
2160
2161         if ((count = add_route_dialog->count()) <= 0) {
2162                 return;
2163         }
2164
2165         uint32_t input_chan = add_route_dialog->channels ();
2166         uint32_t output_chan;
2167         string name_template = add_route_dialog->name_template ();
2168         bool track = add_route_dialog->track ();
2169
2170         Session::AutoConnectOption oac = session->get_output_auto_connect();
2171
2172         if (oac & Session::AutoConnectMaster) {
2173                 output_chan = (session->master_out() ? session->master_out()->n_inputs() : input_chan);
2174         } else {
2175                 output_chan = input_chan;
2176         }
2177
2178         /* XXX do something with name template */
2179
2180         while (count) {
2181                 if (track) {
2182                         session_add_audio_track (input_chan, output_chan, add_route_dialog->mode());
2183                 } else {
2184                         session_add_audio_bus (input_chan, output_chan);
2185                 }
2186                 --count;
2187                 
2188                 while (Main::events_pending()) {
2189                         Main::iteration ();
2190                 }
2191         }
2192 }
2193
2194 XMLNode*
2195 ARDOUR_UI::mixer_settings () const
2196 {
2197         XMLNode* node = 0;
2198
2199         if (session) {
2200                 node = session->instant_xml(X_("Mixer"), session->path());
2201         } else {
2202                 node = Config->instant_xml(X_("Mixer"), get_user_ardour_path());
2203         }
2204
2205         if (!node) {
2206                 node = new XMLNode (X_("Mixer"));
2207         }
2208
2209         return node;
2210 }
2211
2212 XMLNode*
2213 ARDOUR_UI::editor_settings () const
2214 {
2215         XMLNode* node = 0;
2216
2217         if (session) {
2218                 node = session->instant_xml(X_("Editor"), session->path());
2219         } else {
2220                 node = Config->instant_xml(X_("Editor"), get_user_ardour_path());
2221         }
2222
2223         if (!node) {
2224                 node = new XMLNode (X_("Editor"));
2225         }
2226         return node;
2227 }
2228
2229 XMLNode*
2230 ARDOUR_UI::keyboard_settings () const
2231 {
2232         XMLNode* node = 0;
2233
2234         node = Config->extra_xml(X_("Keyboard"));
2235         
2236         if (!node) {
2237                 node = new XMLNode (X_("Keyboard"));
2238         }
2239         return node;
2240 }
2241
2242 void
2243 ARDOUR_UI::halt_on_xrun_message ()
2244 {
2245         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
2246
2247         MessageDialog msg (*editor,
2248                            _("Recording was stopped because your system could not keep up."));
2249         msg.run ();
2250 }
2251
2252 void 
2253 ARDOUR_UI::delete_sources_in_the_right_thread (list<ARDOUR::Source*>* deletion_list)
2254 {
2255         ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread), deletion_list));
2256
2257         for (list<Source*>::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) {
2258                 delete *i;
2259         }
2260
2261         delete deletion_list;
2262 }
2263
2264 void
2265 ARDOUR_UI::disk_overrun_handler ()
2266 {
2267         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2268
2269         if (!have_disk_overrun_displayed) {
2270                 have_disk_overrun_displayed = true;
2271                 MessageDialog msg (*editor, X_("diskrate dialog"), _("\
2272 The disk system on your computer\n\
2273 was not able to keep up with Ardour.\n\
2274 \n\
2275 Specifically, it failed to write data to disk\n\
2276 quickly enough to keep up with recording.\n"));
2277                 msg.run ();
2278                 have_disk_overrun_displayed = false;
2279         }
2280 }
2281
2282 void
2283 ARDOUR_UI::disk_underrun_handler ()
2284 {
2285         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2286
2287         if (!have_disk_underrun_displayed) {
2288                 have_disk_underrun_displayed = true;
2289                 MessageDialog msg (*editor,
2290                         (_("The disk system on your computer\n\
2291 was not able to keep up with Ardour.\n\
2292 \n\
2293 Specifically, it failed to read data from disk\n\
2294 quickly enough to keep up with playback.\n")));
2295                 msg.run ();
2296                 have_disk_underrun_displayed = false;
2297         } 
2298 }
2299
2300 void
2301 ARDOUR_UI::disk_underrun_message_gone ()
2302 {
2303         have_disk_underrun_displayed = false;
2304 }
2305
2306 void
2307 ARDOUR_UI::disk_overrun_message_gone ()
2308 {
2309         have_disk_underrun_displayed = false;
2310 }
2311
2312 int
2313 ARDOUR_UI::pending_state_dialog ()
2314 {
2315         ArdourDialog dialog ("pending state dialog");
2316         Label  message (_("\
2317 This session appears to have been in\n\
2318 middle of recording when ardour or\n\
2319 the computer was shutdown.\n\
2320 \n\
2321 Ardour can recover any captured audio for\n\
2322 you, or it can ignore it. Please decide\n\
2323 what you would like to do.\n"));
2324
2325         dialog.get_vbox()->pack_start (message);
2326         dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
2327         dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
2328
2329         dialog.set_position (WIN_POS_CENTER);
2330         dialog.show_all ();
2331         
2332         switch (dialog.run ()) {
2333         case RESPONSE_ACCEPT:
2334                 return 1;
2335         default:
2336                 return 0;
2337         }
2338 }
2339         
2340 void
2341 ARDOUR_UI::disconnect_from_jack ()
2342 {
2343         if (engine) {
2344                 if( engine->disconnect_from_jack ()) {
2345                         MessageDialog msg (*editor, _("Could not disconnect from JACK"));
2346                         msg.run ();
2347                 }
2348
2349                 update_sample_rate (0);
2350         }
2351 }
2352
2353 void
2354 ARDOUR_UI::reconnect_to_jack ()
2355 {
2356         if (engine) {
2357                 if (engine->reconnect_to_jack ()) {
2358                         MessageDialog msg (*editor,  _("Could not reconnect to JACK"));
2359                         msg.run ();
2360                 }
2361
2362                 update_sample_rate (0);
2363         }
2364 }
2365
2366 void
2367 ARDOUR_UI::set_jack_buffer_size (jack_nframes_t nframes)
2368 {
2369         engine->request_buffer_size (nframes);
2370         update_sample_rate (0);
2371 }
2372
2373 int
2374 ARDOUR_UI::cmdline_new_session (string path)
2375 {
2376         if (path[0] != '/') {
2377                 char buf[PATH_MAX+1];
2378                 string str;
2379
2380                 getcwd (buf, sizeof (buf));
2381                 str = buf;
2382                 str += '/';
2383                 str += path;
2384                 path = str;
2385         }
2386
2387         new_session (false, path);
2388
2389         _will_create_new_session_automatically = false; /* done it */
2390         return FALSE; /* don't call it again */
2391 }
2392
2393 void
2394 ARDOUR_UI::set_native_file_header_format (HeaderFormat hf)
2395 {
2396         Glib::RefPtr<Action> act;
2397         
2398         switch (hf) {
2399         case BWF:
2400                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
2401                 break;
2402         case WAVE:
2403                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
2404                 break;
2405         case WAVE64:
2406                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
2407                 break;
2408         case iXML:
2409                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
2410                 break;
2411         case RF64:
2412                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
2413                 break;
2414         }
2415
2416         if (act) {
2417                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2418                 if (ract && ract->get_active() && Config->get_native_file_header_format() != hf) {
2419                         Config->set_native_file_header_format (hf);
2420                         if (session) {
2421                                 session->reset_native_file_format ();
2422                         }
2423                 }
2424         }
2425 }
2426
2427 void
2428 ARDOUR_UI::set_native_file_data_format (SampleFormat sf)
2429 {
2430         Glib::RefPtr<Action> act;
2431         
2432         switch (sf) {
2433         case FormatFloat:
2434                 act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
2435                 break;
2436         case FormatInt24:
2437                 act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
2438                 break;
2439         }
2440
2441         if (act) {
2442                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2443
2444                 if (ract && ract->get_active() && Config->get_native_file_data_format() != sf) {
2445                         Config->set_native_file_data_format (sf);
2446                         if (session) {
2447                                 session->reset_native_file_format ();
2448                         }
2449                 }
2450         }
2451 }
2452
2453 void
2454 ARDOUR_UI::use_config ()
2455 {
2456         Glib::RefPtr<Action> act;
2457
2458         switch (Config->get_native_file_data_format ()) {
2459         case FormatFloat:
2460                 act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
2461                 break;
2462         case FormatInt24:
2463                 act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
2464                 break;
2465         }
2466
2467         if (act) {
2468                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2469                 ract->set_active ();
2470         }       
2471
2472         switch (Config->get_native_file_header_format ()) {
2473         case BWF:
2474                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
2475                 break;
2476         case WAVE:
2477                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
2478                 break;
2479         case WAVE64:
2480                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
2481                 break;
2482         case iXML:
2483                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
2484                 break;
2485         case RF64:
2486                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
2487                 break;
2488         }
2489
2490         if (act) {
2491                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2492                 ract->set_active ();
2493         }       
2494 }