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