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