track templates; indent fixes needed and will be forthcoming; minor fix for the curve...
[ardour.git] / gtk2_ardour / ardour_ui.cc
1 /*
2     Copyright (C) 1999-2007 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 */
19
20 #include <algorithm>
21 #include <cmath>
22 #include <fcntl.h>
23 #include <signal.h>
24 #include <unistd.h>
25 #include <time.h>
26 #include <cerrno>
27 #include <fstream>
28
29 #include <iostream>
30
31 #include <sys/resource.h>
32
33 #include <gtkmm/messagedialog.h>
34 #include <gtkmm/accelmap.h>
35
36 #include <pbd/error.h>
37 #include <pbd/basename.h>
38 #include <pbd/compose.h>
39 #include <pbd/pathscanner.h>
40 #include <pbd/failed_constructor.h>
41 #include <pbd/enumwriter.h>
42 #include <pbd/stacktrace.h>
43 #include <gtkmm2ext/gtk_ui.h>
44 #include <gtkmm2ext/utils.h>
45 #include <gtkmm2ext/click_box.h>
46 #include <gtkmm2ext/fastmeter.h>
47 #include <gtkmm2ext/stop_signal.h>
48 #include <gtkmm2ext/popup.h>
49 #include <gtkmm2ext/window_title.h>
50
51 #include <midi++/port.h>
52 #include <midi++/mmc.h>
53
54 #include <ardour/ardour.h>
55 #include <ardour/profile.h>
56 #include <ardour/session_route.h>
57 #include <ardour/port.h>
58 #include <ardour/audioengine.h>
59 #include <ardour/playlist.h>
60 #include <ardour/utils.h>
61 #include <ardour/plugin.h>
62 #include <ardour/audio_diskstream.h>
63 #include <ardour/audiofilesource.h>
64 #include <ardour/recent_sessions.h>
65 #include <ardour/port.h>
66 #include <ardour/audio_track.h>
67
68 typedef uint64_t microseconds_t;
69
70 #include "actions.h"
71 #include "ardour_ui.h"
72 #include "public_editor.h"
73 #include "audio_clock.h"
74 #include "keyboard.h"
75 #include "mixer_ui.h"
76 #include "prompter.h"
77 #include "opts.h"
78 #include "add_route_dialog.h"
79 #include "new_session_dialog.h"
80 #include "about.h"
81 #include "splash.h"
82 #include "utils.h"
83 #include "gui_thread.h"
84 #include "theme_manager.h"
85 #include "engine_dialog.h"
86 #include "gain_meter.h"
87 #include "route_time_axis.h"
88
89 #include "i18n.h"
90
91 using namespace ARDOUR;
92 using namespace PBD;
93 using namespace Gtkmm2ext;
94 using namespace Gtk;
95 using namespace sigc;
96
97 ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
98 UIConfiguration *ARDOUR_UI::ui_config = 0;
99
100 sigc::signal<void,bool> ARDOUR_UI::Blink;
101 sigc::signal<void>      ARDOUR_UI::RapidScreenUpdate;
102 sigc::signal<void>      ARDOUR_UI::SuperRapidScreenUpdate;
103 sigc::signal<void,nframes_t, bool, nframes_t> ARDOUR_UI::Clock;
104
105 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
106
107         : Gtkmm2ext::UI (X_("Ardour"), argcp, argvp),
108
109           primary_clock (X_("primary"), false, X_("TransportClockDisplay"), true, false, true),
110           secondary_clock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, false, true),
111           preroll_clock (X_("preroll"), false, X_("PreRollClock"), true, true),
112           postroll_clock (X_("postroll"), false, X_("PostRollClock"), true, true),
113
114           /* preroll stuff */
115
116           preroll_button (_("pre\nroll")),
117           postroll_button (_("post\nroll")),
118
119           /* big clock */
120
121           big_clock (X_("bigclock"), false, "BigClockNonRecording", true, false, true),
122
123           /* transport */
124
125           roll_controllable ("transport roll", *this, TransportControllable::Roll),
126           stop_controllable ("transport stop", *this, TransportControllable::Stop),
127           goto_start_controllable ("transport goto start", *this, TransportControllable::GotoStart),
128           goto_end_controllable ("transport goto end", *this, TransportControllable::GotoEnd),
129           auto_loop_controllable ("transport auto loop", *this, TransportControllable::AutoLoop),
130           play_selection_controllable ("transport play selection", *this, TransportControllable::PlaySelection),
131           rec_controllable ("transport rec-enable", *this, TransportControllable::RecordEnable),
132           shuttle_controllable ("shuttle", *this, TransportControllable::ShuttleControl),
133           shuttle_controller_binding_proxy (shuttle_controllable),
134
135           roll_button (&roll_controllable),
136           stop_button (&stop_controllable),
137           goto_start_button (&goto_start_controllable),
138           goto_end_button (&goto_end_controllable),
139           auto_loop_button (&auto_loop_controllable),
140           play_selection_button (&play_selection_controllable),
141           rec_button (&rec_controllable),
142           
143           shuttle_units_button (_("% ")),
144
145           punch_in_button (_("Punch In")),
146           punch_out_button (_("Punch Out")),
147           auto_return_button (_("Auto Return")),
148           auto_play_button (_("Auto Play")),
149           auto_input_button (_("Auto Input")),
150           click_button (_("Click")),
151           time_master_button (_("time\nmaster")),
152
153           auditioning_alert_button (_("AUDITION")),
154           solo_alert_button (_("SOLO")),
155           shown_flag (false),
156           error_log_button (_("Errors"))
157 {
158         using namespace Gtk::Menu_Helpers;
159
160         Gtkmm2ext::init();
161
162 #ifdef TOP_MENUBAR
163         _auto_display_errors = false;
164 #endif
165
166         about = 0;
167         splash = 0;
168
169         if (ARDOUR_COMMAND_LINE::session_name.length()) {       
170                 /* only show this if we're not going to post the new session dialog */
171                 show_splash ();
172         }
173
174         if (theArdourUI == 0) {
175                 theArdourUI = this;
176         }
177
178         ui_config = new UIConfiguration();
179         theme_manager = new ThemeManager();
180
181         engine = 0;
182         editor = 0;
183         mixer = 0;
184         session = 0;
185         _session_is_new = false;
186         big_clock_window = 0;
187         session_selector_window = 0;
188         new_session_dialog = 0;
189         last_key_press_time = 0;
190         connection_editor = 0;
191         add_route_dialog = 0;
192         route_params = 0;
193         option_editor = 0;
194         location_ui = 0;
195         key_editor = 0;
196         open_session_selector = 0;
197         have_configure_timeout = false;
198         have_disk_speed_dialog_displayed = false;
199         _will_create_new_session_automatically = false;
200         session_loaded = false;
201         last_speed_displayed = -1.0f;
202         ignore_dual_punch = false;
203         _mixer_on_top = false;
204
205         roll_button.unset_flags (Gtk::CAN_FOCUS);
206         stop_button.unset_flags (Gtk::CAN_FOCUS);
207         goto_start_button.unset_flags (Gtk::CAN_FOCUS);
208         goto_end_button.unset_flags (Gtk::CAN_FOCUS);
209         auto_loop_button.unset_flags (Gtk::CAN_FOCUS);
210         play_selection_button.unset_flags (Gtk::CAN_FOCUS);
211         rec_button.unset_flags (Gtk::CAN_FOCUS);
212
213         last_configure_time= 0;
214
215         shuttle_grabbed = false;
216         shuttle_fract = 0.0;
217         shuttle_max_speed = 8.0f;
218
219         shuttle_style_menu = 0;
220         shuttle_unit_menu = 0;
221
222         // We do not have jack linked in yet so;
223         
224         last_shuttle_request = last_peak_grab = 0; //  get_microseconds();
225
226         ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
227         ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
228
229         ARDOUR::Plugin::PresetFileExists.connect (mem_fun(*this, &ARDOUR_UI::preset_file_exists_handler));
230
231         /* handle dialog requests */
232
233         ARDOUR::Session::Dialog.connect (mem_fun(*this, &ARDOUR_UI::session_dialog));
234
235         /* handle pending state with a dialog */
236
237         ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
238
239         /* handle sr mismatch with a dialog */
240
241         ARDOUR::Session::AskAboutSampleRateMismatch.connect (mem_fun(*this, &ARDOUR_UI::sr_mismatch_dialog));
242
243         /* lets get this party started */
244
245         try {
246                 if (ARDOUR::init (ARDOUR_COMMAND_LINE::use_vst, ARDOUR_COMMAND_LINE::try_hw_optimization)) {
247                         throw failed_constructor ();
248                 }
249
250                 setup_gtk_ardour_enums ();
251                 Config->set_current_owner (ConfigVariableBase::Interface);
252                 setup_profile ();
253
254                 GainMeter::setup_slider_pix ();
255                 RouteTimeAxisView::setup_slider_pix ();
256
257         } catch (failed_constructor& err) {
258                 error << _("could not initialize Ardour.") << endmsg;
259                 // pass it on up
260                 throw;
261         } 
262
263         /* we like keyboards */
264
265         keyboard = new Keyboard;
266
267         reset_dpi();
268
269         starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
270         stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
271
272         platform_setup ();
273 }
274
275 int
276 ARDOUR_UI::create_engine ()
277 {
278         // this gets called every time by new_session()
279
280         if (engine) {
281                 return 0;
282         }
283
284         loading_message (_("Starting audio engine"));
285
286         try { 
287                 engine = new ARDOUR::AudioEngine (ARDOUR_COMMAND_LINE::jack_client_name);
288
289         } catch (...) {
290
291                 return -1;
292         }
293
294         engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
295         engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
296         engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
297         engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
298
299         post_engine ();
300
301         return 0;
302 }
303
304 void
305 ARDOUR_UI::post_engine ()
306 {
307         /* Things to be done once we create the AudioEngine
308          */
309
310         check_memory_locking();
311
312         ActionManager::init ();
313         _tooltips.enable();
314
315         if (setup_windows ()) {
316                 throw failed_constructor ();
317         }
318
319         /* this is the first point at which all the keybindings are available */
320
321         if (ARDOUR_COMMAND_LINE::show_key_actions) {
322                 vector<string> names;
323                 vector<string> paths;
324                 vector<string> keys;
325                 vector<AccelKey> bindings;
326
327                 ActionManager::get_all_actions (names, paths, keys, bindings);
328
329                 vector<string>::iterator n;
330                 vector<string>::iterator k;
331                 for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) {
332                         cerr << "Action: " << (*n) << " bound to " << (*k) << endl;
333                 }
334
335                 exit (0);
336         }
337
338         blink_timeout_tag = -1;
339
340         /* the global configuration object is now valid */
341
342         use_config ();
343
344         /* this being a GUI and all, we want peakfiles */
345
346         AudioFileSource::set_build_peakfiles (true);
347         AudioFileSource::set_build_missing_peakfiles (true);
348
349         /* set default clock modes */
350
351         if (Profile->get_sae()) {
352                 primary_clock.set_mode (AudioClock::BBT);
353                 secondary_clock.set_mode (AudioClock::MinSec);
354         }  else {
355                 primary_clock.set_mode (AudioClock::SMPTE);
356                 secondary_clock.set_mode (AudioClock::BBT);
357         }
358
359         /* start the time-of-day-clock */
360         
361 #ifndef GTKOSX
362         /* OS X provides an always visible wallclock, so don't be stupid */
363         update_wall_clock ();
364         Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
365 #endif
366
367         update_disk_space ();
368         update_cpu_load ();
369         update_sample_rate (engine->frame_rate());
370
371         platform_specific ();
372
373         /* now start and maybe save state */
374
375         if (do_engine_start () == 0) {
376                 if (session && _session_is_new) {
377                         /* we need to retain initial visual 
378                            settings for a new session 
379                         */
380                         session->save_state ("");
381                 }
382         }
383 }
384
385 ARDOUR_UI::~ARDOUR_UI ()
386 {
387         save_ardour_state ();
388
389         if (keyboard) {
390                 delete keyboard;
391         }
392
393         if (editor) {
394                 delete editor;
395         }
396
397         if (mixer) {
398                 delete mixer;
399         }
400
401         if (add_route_dialog) {
402                 delete add_route_dialog;
403         }
404
405         if (new_session_dialog) {
406                 delete new_session_dialog;
407         }
408 }
409
410 void
411 ARDOUR_UI::pop_back_splash ()
412 {
413         if (Splash::instance()) {
414                 // Splash::instance()->pop_back();
415                 Splash::instance()->hide ();
416         }
417 }
418
419 gint
420 ARDOUR_UI::configure_timeout ()
421 {
422         if (last_configure_time == 0) {
423                 /* no configure events yet */
424                 return TRUE;
425         }
426
427         /* force a gap of 0.5 seconds since the last configure event
428          */
429
430         if (get_microseconds() - last_configure_time < 500000) {
431                 return TRUE;
432         } else {
433                 have_configure_timeout = false;
434                 save_ardour_state ();
435                 return FALSE;
436         }
437 }
438
439 gboolean
440 ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
441 {
442         if (have_configure_timeout) {
443                 last_configure_time = get_microseconds();
444         } else {
445                 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
446                 have_configure_timeout = true;
447         }
448         
449         return FALSE;
450 }
451
452 void
453 ARDOUR_UI::set_transport_controllable_state (const XMLNode& node)
454 {
455         const XMLProperty* prop;
456
457         if ((prop = node.property ("roll")) != 0) {
458                 roll_controllable.set_id (prop->value());
459         }
460         if ((prop = node.property ("stop")) != 0) {
461                 stop_controllable.set_id (prop->value());
462         }
463         if ((prop = node.property ("goto_start")) != 0) {
464                 goto_start_controllable.set_id (prop->value());
465         }
466         if ((prop = node.property ("goto_end")) != 0) {
467                 goto_end_controllable.set_id (prop->value());
468         }
469         if ((prop = node.property ("auto_loop")) != 0) {
470                 auto_loop_controllable.set_id (prop->value());
471         }
472         if ((prop = node.property ("play_selection")) != 0) {
473                 play_selection_controllable.set_id (prop->value());
474         }
475         if ((prop = node.property ("rec")) != 0) {
476                 rec_controllable.set_id (prop->value());
477         }
478         if ((prop = node.property ("shuttle")) != 0) {
479                 shuttle_controllable.set_id (prop->value());
480         }
481 }
482
483 XMLNode&
484 ARDOUR_UI::get_transport_controllable_state ()
485 {
486         XMLNode* node = new XMLNode(X_("TransportControllables"));
487         char buf[64];
488
489         roll_controllable.id().print (buf, sizeof (buf));
490         node->add_property (X_("roll"), buf);
491         stop_controllable.id().print (buf, sizeof (buf));
492         node->add_property (X_("stop"), buf);
493         goto_start_controllable.id().print (buf, sizeof (buf));
494         node->add_property (X_("goto_start"), buf);
495         goto_end_controllable.id().print (buf, sizeof (buf));
496         node->add_property (X_("goto_end"), buf);
497         auto_loop_controllable.id().print (buf, sizeof (buf));
498         node->add_property (X_("auto_loop"), buf);
499         play_selection_controllable.id().print (buf, sizeof (buf));
500         node->add_property (X_("play_selection"), buf);
501         rec_controllable.id().print (buf, sizeof (buf));
502         node->add_property (X_("rec"), buf);
503         shuttle_controllable.id().print (buf, sizeof (buf));
504         node->add_property (X_("shuttle"), buf);
505
506         return *node;
507 }
508
509 void
510 ARDOUR_UI::save_ardour_state ()
511 {
512         if (!keyboard || !mixer || !editor) {
513                 return;
514         }
515         
516         /* XXX this is all a bit dubious. add_extra_xml() uses
517            a different lifetime model from add_instant_xml().
518         */
519
520         XMLNode* node = new XMLNode (keyboard->get_state());
521         Config->add_extra_xml (*node);
522         Config->add_extra_xml (get_transport_controllable_state());
523         if (new_session_dialog) {
524                 if (new_session_dialog->engine_control.was_used()) {
525                         Config->add_extra_xml (new_session_dialog->engine_control.get_state());
526                 }
527         }
528         Config->save_state();
529         ui_config->save_state ();
530
531         XMLNode enode(static_cast<Stateful*>(editor)->get_state());
532         XMLNode mnode(mixer->get_state());
533
534         if (session) {
535                 session->add_instant_xml (enode, session->path());
536                 session->add_instant_xml (mnode, session->path());
537         } else {
538                 Config->add_instant_xml (enode, get_user_ardour_path());
539                 Config->add_instant_xml (mnode, get_user_ardour_path());
540         }
541
542         Keyboard::save_keybindings ();
543 }
544
545 gint
546 ARDOUR_UI::autosave_session ()
547 {
548         if (g_main_depth() > 1) {
549                 /* inside a recursive main loop,
550                    give up because we may not be able to 
551                    take a lock.
552                 */
553                 return 1;
554         }
555
556         if (!Config->get_periodic_safety_backups())
557                 return 1;
558         
559         if (session) {
560                 session->maybe_write_autosave();
561         }
562
563         return 1;
564 }
565
566 void
567 ARDOUR_UI::update_autosave ()
568 {
569         ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::update_autosave));
570         
571         if (session->dirty()) {
572                 if (_autosave_connection.connected()) {
573                         _autosave_connection.disconnect();
574                 }
575
576                 _autosave_connection = Glib::signal_timeout().connect (mem_fun (*this, &ARDOUR_UI::autosave_session),
577                                                                     Config->get_periodic_safety_backup_interval() * 1000);
578
579         } else {
580                 if (_autosave_connection.connected()) {
581                         _autosave_connection.disconnect();
582                 }               
583         }
584 }
585
586 void
587 ARDOUR_UI::backend_audio_error (bool we_set_params, Gtk::Window* toplevel)
588 {
589         string title;
590         if (we_set_params) {
591                 title = _("Ardour could not start JACK");
592         } else {
593                 title = _("Ardour could not connect to JACK.");
594         }
595
596         MessageDialog win (title,
597                            false,
598                            Gtk::MESSAGE_INFO,
599                            Gtk::BUTTONS_NONE);
600         
601         if (we_set_params) {
602                 win.set_secondary_text(_("There are several possible reasons:\n\
603 \n\
604 1) You requested audio parameters that are not supported..\n\
605 2) JACK is running as another user.\n\
606 \n\
607 Please consider the possibilities, and perhaps try different parameters."));
608         } else {
609                 win.set_secondary_text(_("There are several possible reasons:\n\
610 \n\
611 1) JACK is not running.\n\
612 2) JACK is running as another user, perhaps root.\n\
613 3) There is already another client called \"ardour\".\n\
614 \n\
615 Please consider the possibilities, and perhaps (re)start JACK."));
616         }
617
618         if (toplevel) {
619                 win.set_transient_for (*toplevel);
620         }
621
622         if (we_set_params) {
623                 win.add_button (Stock::OK, RESPONSE_CLOSE);
624         } else {
625                 win.add_button (Stock::QUIT, RESPONSE_CLOSE);
626         }
627
628         win.set_default_response (RESPONSE_CLOSE);
629         
630         win.show_all ();
631         win.set_position (Gtk::WIN_POS_CENTER);
632         pop_back_splash ();
633
634         /* we just don't care about the result, but we want to block */
635
636         win.run ();
637 }
638
639 void
640 ARDOUR_UI::startup ()
641 {
642         string name, path;
643         
644         new_session_dialog = new NewSessionDialog();
645
646         bool backend_audio_is_running = EngineControl::engine_running();
647         XMLNode* audio_setup = Config->extra_xml ("AudioSetup");
648         
649         if (audio_setup) {
650                 new_session_dialog->engine_control.set_state (*audio_setup);
651         }
652         
653         if (!get_session_parameters (backend_audio_is_running, ARDOUR_COMMAND_LINE::new_session)) {
654                 return;
655         }
656         
657         BootMessage (_("Ardour is ready for use"));
658         show ();
659 }
660
661 void
662 ARDOUR_UI::no_memory_warning ()
663 {
664         XMLNode node (X_("no-memory-warning"));
665         Config->add_instant_xml (node, get_user_ardour_path());
666 }
667
668 void
669 ARDOUR_UI::check_memory_locking ()
670 {
671 #ifdef __APPLE__
672         /* OS X doesn't support mlockall(2), and so testing for memory locking capability there is pointless */
673         return;
674 #else // !__APPLE__
675
676         XMLNode* memory_warning_node = Config->instant_xml (X_("no-memory-warning"), get_user_ardour_path());
677
678         if (engine->is_realtime() && memory_warning_node == 0) {
679
680                 struct rlimit limits;
681                 int64_t ram;
682                 long pages, page_size;
683
684                 if ((page_size = sysconf (_SC_PAGESIZE)) < 0 ||(pages = sysconf (_SC_PHYS_PAGES)) < 0) {
685                         ram = 0;
686                 } else {
687                         ram = (int64_t) pages * (int64_t) page_size;
688                 }
689
690                 if (getrlimit (RLIMIT_MEMLOCK, &limits)) {
691                         return;
692                 }
693                 
694                 if (limits.rlim_cur != RLIM_INFINITY) {
695
696                         if (ram == 0 || ((double) limits.rlim_cur / ram) < 0.75) {
697                         
698
699                                 MessageDialog msg (_("WARNING: Your system has a limit for maximum amount of locked memory. "
700                                                      "This might cause Ardour to run out of memory before your system "
701                                                      "runs out of memory. \n\n"
702                                                      "You can view the memory limit with 'ulimit -l', "
703                                                      "and it is normally controlled by /etc/security/limits.conf"));
704                                 
705                                 VBox* vbox = msg.get_vbox();
706                                 HBox hbox;
707                                 CheckButton cb (_("Do not show this window again"));
708                                 
709                                 cb.signal_toggled().connect (mem_fun (*this, &ARDOUR_UI::no_memory_warning));
710                                 
711                                 hbox.pack_start (cb, true, false);
712                                 vbox->pack_start (hbox);
713                                 hbox.show_all ();
714
715                                 pop_back_splash ();
716                                 
717                                 msg.run ();
718                         }
719                 }
720         }
721 #endif // !__APPLE__
722 }
723
724
725 void
726 ARDOUR_UI::finish()
727 {
728         if (session) {
729
730                 if (session->transport_rolling()) {
731                         session->request_stop ();
732                         usleep (2500000);
733                 }
734
735                 if (session->dirty()) {
736                         switch (ask_about_saving_session(_("quit"))) {
737                         case -1:
738                                 return;
739                                 break;
740                         case 1:
741                                 /* use the default name */
742                                 if (save_state_canfail ("")) {
743                                         /* failed - don't quit */
744                                         MessageDialog msg (*editor, 
745                                                            _("\
746 Ardour was unable to save your session.\n\n\
747 If you still wish to quit, please use the\n\n\
748 \"Just quit\" option."));
749                                         pop_back_splash();
750                                         msg.run ();
751                                         return;
752                                 }
753                                 break;
754                         case 0:
755                                 break;
756                         }
757                 }
758                 
759                 session->set_deletion_in_progress ();
760         }
761
762         ArdourDialog::close_all_dialogs ();
763         engine->stop (true);
764         save_ardour_state ();
765         quit ();
766 }
767
768 int
769 ARDOUR_UI::ask_about_saving_session (const string & what)
770 {
771         ArdourDialog window (_("ardour: save session?"));
772         Gtk::HBox dhbox;  // the hbox for the image and text
773         Gtk::Label  prompt_label;
774         Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_WARNING,  Gtk::ICON_SIZE_DIALOG));
775
776         string msg;
777
778         msg = string_compose(_("Don't %1"), what);
779         window.add_button (msg, RESPONSE_REJECT);
780         msg = string_compose(_("Just %1"), what);
781         window.add_button (msg, RESPONSE_APPLY);
782         msg = string_compose(_("Save and %1"), what);
783         window.add_button (msg, RESPONSE_ACCEPT);
784
785         window.set_default_response (RESPONSE_ACCEPT);
786
787         Gtk::Button noquit_button (msg);
788         noquit_button.set_name ("EditorGTKButton");
789
790         string prompt;
791         string type;
792
793         if (session->snap_name() == session->name()) {
794                 type = _("session");
795         } else {
796                 type = _("snapshot");
797         }
798         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?"), 
799                          type, session->snap_name());
800         
801         prompt_label.set_text (prompt);
802         prompt_label.set_name (X_("PrompterLabel"));
803         prompt_label.set_alignment(ALIGN_LEFT, ALIGN_TOP);
804
805         dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP)
806 ;
807         dhbox.set_homogeneous (false);
808         dhbox.pack_start (*dimage, false, false, 5);
809         dhbox.pack_start (prompt_label, true, false, 5);
810         window.get_vbox()->pack_start (dhbox);
811
812         window.set_name (_("Prompter"));
813         window.set_position (Gtk::WIN_POS_MOUSE);
814         window.set_modal (true);
815         window.set_resizable (false);
816         window.show_all ();
817
818         window.set_keep_above (true);
819         window.present ();
820
821         ResponseType r = (ResponseType) window.run();
822
823         window.hide ();
824
825         switch (r) {
826         case RESPONSE_ACCEPT: // save and get out of here
827                 return 1;
828         case RESPONSE_APPLY:  // get out of here
829                 return 0;
830         default:
831                 break;
832         }
833
834         return -1;
835 }
836         
837 int
838 ARDOUR_UI::every_second ()
839 {
840         update_cpu_load ();
841         update_buffer_load ();
842         update_disk_space ();
843         return TRUE;
844 }
845
846 gint
847 ARDOUR_UI::every_point_one_seconds ()
848 {
849         update_speed_display ();
850         RapidScreenUpdate(); /* EMIT_SIGNAL */
851         return TRUE;
852 }
853
854 gint
855 ARDOUR_UI::every_point_zero_one_seconds ()
856 {
857         // august 2007: actual update frequency: 40Hz, not 100Hz
858
859         SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
860         return TRUE;
861 }
862
863 void
864 ARDOUR_UI::update_sample_rate (nframes_t ignored)
865 {
866         char buf[32];
867
868         ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
869
870         if (!engine->connected()) {
871
872                 snprintf (buf, sizeof (buf), _("disconnected"));
873
874         } else {
875
876                 nframes_t rate = engine->frame_rate();
877                 
878                 if (fmod (rate, 1000.0) != 0.0) {
879                         snprintf (buf, sizeof (buf), _("%.1f kHz / %4.1f ms"), 
880                                   (float) rate/1000.0f,
881                                   (engine->frames_per_cycle() / (float) rate) * 1000.0f);
882                 } else {
883                         snprintf (buf, sizeof (buf), _("%u kHz / %4.1f ms"), 
884                                   rate/1000,
885                                   (engine->frames_per_cycle() / (float) rate) * 1000.0f);
886                 }
887         }
888
889         sample_rate_label.set_text (buf);
890 }
891
892 void
893 ARDOUR_UI::update_cpu_load ()
894 {
895         char buf[32];
896         snprintf (buf, sizeof (buf), _("DSP: %5.1f%%"), engine->get_cpu_load());
897         cpu_load_label.set_text (buf);
898 }
899
900 void
901 ARDOUR_UI::update_buffer_load ()
902 {
903         char buf[64];
904
905         if (session) {
906                 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"), 
907                           session->playback_load(), session->capture_load());
908                 buffer_load_label.set_text (buf);
909         } else {
910                 buffer_load_label.set_text ("");
911         }
912 }
913
914 void
915 ARDOUR_UI::count_recenabled_streams (Route& route)
916 {
917         Track* track = dynamic_cast<Track*>(&route);
918         if (track && track->diskstream()->record_enabled()) {
919                 rec_enabled_streams += track->n_inputs();
920         }
921 }
922
923 void
924 ARDOUR_UI::update_disk_space()
925 {
926         if (session == 0) {
927                 return;
928         }
929
930         nframes_t frames = session->available_capture_duration();
931         char buf[64];
932
933         if (frames == max_frames) {
934                 strcpy (buf, _("Disk: 24hrs+"));
935         } else {
936                 int hrs;
937                 int mins;
938                 int secs;
939                 nframes_t fr = session->frame_rate();
940                 
941                 rec_enabled_streams = 0;
942                 session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
943                 
944                 if (rec_enabled_streams) {
945                         frames /= rec_enabled_streams;
946                 }
947                 
948                 hrs  = frames / (fr * 3600);
949                 frames -= hrs * fr * 3600;
950                 mins = frames / (fr * 60);
951                 frames -= mins * fr * 60;
952                 secs = frames / fr;
953                 
954                 snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs);
955         }
956
957         disk_space_label.set_text (buf);
958 }                 
959
960 gint
961 ARDOUR_UI::update_wall_clock ()
962 {
963         time_t now;
964         struct tm *tm_now;
965         char buf[16];
966
967         time (&now);
968         tm_now = localtime (&now);
969
970         sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
971         wall_clock_label.set_text (buf);
972
973         return TRUE;
974 }
975
976 gint
977 ARDOUR_UI::session_menu (GdkEventButton *ev)
978 {
979         session_popup_menu->popup (0, 0);
980         return TRUE;
981 }
982
983 void
984 ARDOUR_UI::redisplay_recent_sessions ()
985 {
986         vector<string *> *sessions;
987         vector<string *>::iterator i;
988         RecentSessionsSorter cmp;
989         
990         recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
991         recent_session_model->clear ();
992
993         RecentSessions rs;
994         ARDOUR::read_recent_sessions (rs);
995
996         if (rs.empty()) {
997                 recent_session_display.set_model (recent_session_model);
998                 return;
999         }
1000
1001         /* sort them alphabetically */
1002         sort (rs.begin(), rs.end(), cmp);
1003         sessions = new vector<string*>;
1004
1005         for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
1006                 sessions->push_back (new string ((*i).second));
1007         }
1008
1009         for (i = sessions->begin(); i != sessions->end(); ++i) {
1010
1011                 vector<string*>* states;
1012                 vector<const gchar*> item;
1013                 string fullpath = *(*i);
1014                 
1015                 /* remove any trailing / */
1016
1017                 if (fullpath[fullpath.length()-1] == '/') {
1018                         fullpath = fullpath.substr (0, fullpath.length()-1);
1019                 }
1020
1021                 /* check whether session still exists */
1022                 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
1023                         /* session doesn't exist */
1024                         cerr << "skipping non-existent session " << fullpath << endl;
1025                         continue;
1026                 }               
1027                 
1028                 /* now get available states for this session */
1029
1030                 if ((states = Session::possible_states (fullpath)) == 0) {
1031                         /* no state file? */
1032                         continue;
1033                 }
1034
1035                 TreeModel::Row row = *(recent_session_model->append());
1036
1037                 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
1038                 row[recent_session_columns.fullpath] = fullpath;
1039
1040                 if (states->size() > 1) {
1041
1042                         /* add the children */
1043                         
1044                         for (vector<string*>::iterator i2 = states->begin(); i2 != states->end(); ++i2) {
1045                                 
1046                                 TreeModel::Row child_row = *(recent_session_model->append (row.children()));
1047
1048                                 child_row[recent_session_columns.visible_name] = **i2;
1049                                 child_row[recent_session_columns.fullpath] = fullpath;
1050
1051                                 delete *i2;
1052                         }
1053                 }
1054
1055                 delete states;
1056         }
1057
1058         recent_session_display.set_model (recent_session_model);
1059         delete sessions;
1060 }
1061
1062 void
1063 ARDOUR_UI::build_session_selector ()
1064 {
1065         session_selector_window = new ArdourDialog ("session selector");
1066         
1067         Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
1068         
1069         session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
1070         session_selector_window->add_button (Stock::OPEN, RESPONSE_ACCEPT);
1071         session_selector_window->set_default_response (RESPONSE_ACCEPT);
1072         recent_session_model = TreeStore::create (recent_session_columns);
1073         recent_session_display.set_model (recent_session_model);
1074         recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1075         recent_session_display.set_headers_visible (false);
1076         recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
1077         recent_session_display.signal_row_activated().connect (mem_fun (*this, &ARDOUR_UI::recent_session_row_activated));
1078
1079         scroller->add (recent_session_display);
1080         scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1081
1082         session_selector_window->set_name ("SessionSelectorWindow");
1083         session_selector_window->set_size_request (200, 400);
1084         session_selector_window->get_vbox()->pack_start (*scroller);
1085         session_selector_window->show_all_children();
1086 }
1087
1088 void
1089 ARDOUR_UI::recent_session_row_activated (const TreePath& path, TreeViewColumn* col)
1090 {
1091         session_selector_window->response (RESPONSE_ACCEPT);
1092 }
1093
1094 void
1095 ARDOUR_UI::open_recent_session ()
1096 {
1097         bool can_return = (session != 0);
1098
1099         if (session_selector_window == 0) {
1100                 build_session_selector ();
1101         }
1102         
1103         redisplay_recent_sessions ();
1104
1105         while (true) {
1106                 
1107                 session_selector_window->set_position (WIN_POS_MOUSE);
1108
1109                 ResponseType r = (ResponseType) session_selector_window->run ();
1110                 
1111                 switch (r) {
1112                 case RESPONSE_ACCEPT:
1113                         break;
1114                 default:
1115                         if (can_return) {
1116                                 session_selector_window->hide();
1117                                 return;
1118                         } else {
1119                                 exit (1);
1120                         }
1121                 }
1122
1123                 if (recent_session_display.get_selection()->count_selected_rows() == 0) {
1124                         continue;
1125                 }
1126                 
1127                 session_selector_window->hide();
1128
1129                 Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
1130                 
1131                 if (i == recent_session_model->children().end()) {
1132                         return;
1133                 }
1134                 
1135                 Glib::ustring path = (*i)[recent_session_columns.fullpath];
1136                 Glib::ustring state = (*i)[recent_session_columns.visible_name];
1137                 
1138                 _session_is_new = false;
1139                 
1140                 if (load_session (path, state) == 0) {
1141                         break;
1142                 }
1143
1144                 can_return = false;
1145         }
1146 }
1147
1148 bool
1149 ARDOUR_UI::check_audioengine ()
1150 {
1151         if (engine) {
1152                 if (!engine->connected()) {
1153                         MessageDialog msg (_("Ardour is not connected to JACK\n"
1154                                              "You cannot open or close sessions in this condition"));
1155                         pop_back_splash ();
1156                         msg.run ();
1157                         return false;
1158                 }
1159                 return true;
1160         } else {
1161                 return false;
1162         }
1163 }
1164
1165 void
1166 ARDOUR_UI::open_session ()
1167 {
1168         if (!check_audioengine()) {
1169                 return;
1170         }
1171
1172         /* popup selector window */
1173
1174         if (open_session_selector == 0) {
1175
1176                 /* ardour sessions are folders */
1177
1178                 open_session_selector = new Gtk::FileChooserDialog (_("open session"), FILE_CHOOSER_ACTION_OPEN);
1179                 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1180                 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
1181                 open_session_selector->set_default_response(Gtk::RESPONSE_ACCEPT);
1182
1183                 FileFilter session_filter;
1184                 session_filter.add_pattern ("*.ardour");
1185                 session_filter.set_name (_("Ardour sessions"));
1186                 open_session_selector->add_filter (session_filter);
1187                 open_session_selector->set_filter (session_filter);
1188         }
1189
1190         int response = open_session_selector->run();
1191         open_session_selector->hide ();
1192
1193         switch (response) {
1194         case RESPONSE_ACCEPT:
1195                 break;
1196         default:
1197                 open_session_selector->hide();
1198                 return;
1199         }
1200
1201         open_session_selector->hide();
1202         string session_path = open_session_selector->get_filename();
1203         string path, name;
1204         bool isnew;
1205
1206         if (session_path.length() > 0) {
1207                 if (Session::find_session (session_path, path, name, isnew) == 0) {
1208                         _session_is_new = isnew;
1209                         load_session (path, name);
1210                 }
1211         }
1212 }
1213
1214
1215 void
1216 ARDOUR_UI::session_add_midi_track ()
1217 {
1218         cerr << _("Patience is a virtue.\n");
1219 }
1220
1221 void
1222 ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, uint32_t how_many)
1223 {
1224         list<boost::shared_ptr<AudioTrack> > tracks;
1225         Session::RouteList routes;
1226
1227         if (session == 0) {
1228                 warning << _("You cannot add a track or bus without a session already loaded.") << endmsg;
1229                 return;
1230         }
1231
1232         try { 
1233                 if (track) {
1234                         tracks = session->new_audio_track (input_channels, output_channels, mode, how_many);
1235
1236                         if (tracks.size() != how_many) {
1237                                 if (how_many == 1) {
1238                                         error << _("could not create a new audio track") << endmsg;
1239                                 } else {
1240                                         error << string_compose (_("could only create %1 of %2 new audio %3"), 
1241                                                                  tracks.size(), how_many, (track ? _("tracks") : _("busses"))) << endmsg;
1242                                 }
1243                         }
1244
1245                 } else {
1246
1247                         routes = session->new_audio_route (input_channels, output_channels, how_many);
1248
1249                         if (routes.size() != how_many) {
1250                                 if (how_many == 1) {
1251                                         error << _("could not create a new audio track") << endmsg;
1252                                 } else {
1253                                         error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
1254                                 }
1255                         }
1256                 }
1257                 
1258 #if CONTROLOUTS
1259                 if (need_control_room_outs) {
1260                         pan_t pans[2];
1261                         
1262                         pans[0] = 0.5;
1263                         pans[1] = 0.5;
1264                         
1265                         route->set_stereo_control_outs (control_lr_channels);
1266                         route->control_outs()->set_stereo_pan (pans, this);
1267                 }
1268 #endif /* CONTROLOUTS */
1269         }
1270
1271         catch (...) {
1272                 MessageDialog msg (*editor, 
1273                                    _("There are insufficient JACK ports available\n\
1274 to create a new track or bus.\n\
1275 You should save Ardour, exit and\n\
1276 restart JACK with more ports."));
1277                 pop_back_splash ();
1278                 msg.run ();
1279         }
1280 }
1281
1282 void
1283 ARDOUR_UI::do_transport_locate (nframes_t new_position)
1284 {
1285         nframes_t _preroll = 0;
1286
1287         if (session) {
1288                 // XXX CONFIG_CHANGE FIX - requires AnyTime handling
1289                 // _preroll = session->convert_to_frames_at (new_position, Config->get_preroll());
1290
1291                 if (new_position > _preroll) {
1292                         new_position -= _preroll;
1293                 } else {
1294                         new_position = 0;
1295                 }
1296
1297                 session->request_locate (new_position);
1298         }
1299 }
1300
1301 void
1302 ARDOUR_UI::transport_goto_start ()  
1303 {
1304         if (session) {
1305                 session->goto_start();
1306
1307                 
1308                 /* force displayed area in editor to start no matter
1309                    what "follow playhead" setting is.
1310                 */
1311                 
1312                 if (editor) {
1313                         editor->reset_x_origin (session->current_start_frame());
1314                 }
1315         }
1316 }
1317
1318 void
1319 ARDOUR_UI::transport_goto_zero ()
1320 {
1321         if (session) {
1322                 session->request_locate (0);
1323
1324                 
1325                 /* force displayed area in editor to start no matter
1326                    what "follow playhead" setting is.
1327                 */
1328                 
1329                 if (editor) {
1330                         editor->reset_x_origin (0);
1331                 }
1332         }
1333 }
1334
1335 void
1336 ARDOUR_UI::transport_goto_wallclock ()
1337 {
1338         if (session && editor) {
1339
1340                 time_t now;
1341                 struct tm tmnow;
1342                 nframes64_t frames;
1343                 
1344                 time (&now);
1345                 localtime_r (&now, &tmnow);
1346         
1347                 frames = tmnow.tm_hour * (60 * 60 * session->frame_rate());
1348                 frames += tmnow.tm_min * (60 * session->frame_rate());
1349                 frames += tmnow.tm_sec * session->frame_rate();
1350
1351                 session->request_locate (frames);
1352
1353                 /* force displayed area in editor to start no matter
1354                    what "follow playhead" setting is.
1355                 */
1356                 
1357                 if (editor) {
1358                         editor->reset_x_origin (frames - (editor->current_page_frames()/2));
1359                 }
1360         }
1361 }
1362
1363 void
1364 ARDOUR_UI::transport_goto_end ()
1365 {
1366         if (session) {
1367                 nframes_t frame = session->current_end_frame();
1368                 session->request_locate (frame);
1369
1370                 /* force displayed area in editor to start no matter
1371                    what "follow playhead" setting is.
1372                 */
1373                 
1374                 if (editor) {
1375                         editor->reset_x_origin (frame);
1376                 }
1377         }
1378 }
1379
1380 void
1381 ARDOUR_UI::transport_stop ()
1382 {
1383         if (!session) {
1384                 return;
1385         }
1386
1387         if (session->is_auditioning()) {
1388                 session->cancel_audition ();
1389                 return;
1390         }
1391         
1392         if (session->get_play_loop ()) {
1393                 session->request_play_loop (false);
1394         }
1395         
1396         session->request_stop ();
1397 }
1398
1399 void
1400 ARDOUR_UI::transport_stop_and_forget_capture ()
1401 {
1402         if (session) {
1403                 session->request_stop (true);
1404         }
1405 }
1406
1407 void
1408 ARDOUR_UI::remove_last_capture()
1409 {
1410         if (editor) {
1411                 editor->remove_last_capture();
1412         }
1413 }
1414
1415 void
1416 ARDOUR_UI::transport_record (bool roll)
1417 {
1418         
1419         if (session) {
1420                 switch (session->record_status()) {
1421                 case Session::Disabled:
1422                         if (session->ntracks() == 0) {
1423                                 MessageDialog msg (*editor, _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu."));
1424                                 msg.run ();
1425                                 return;
1426                         }
1427                         session->maybe_enable_record ();
1428                         if (roll) {
1429                                 transport_roll ();
1430                         }
1431                         break;
1432                 case Session::Recording:
1433                         if (roll) {
1434                                 session->request_stop();
1435                         } else {
1436                                 session->disable_record (false, true);
1437                         }
1438                         break;
1439
1440                 case Session::Enabled:
1441                         session->disable_record (false, true);
1442                 }
1443         }
1444         //cerr << "ARDOUR_UI::transport_record () called roll = " << roll << " session->record_status() = " << session->record_status() << endl;
1445 }
1446
1447 void
1448 ARDOUR_UI::transport_roll ()
1449 {
1450         bool rolling;
1451
1452         if (!session) {
1453                 return;
1454         }
1455
1456         rolling = session->transport_rolling ();
1457
1458         //cerr << "ARDOUR_UI::transport_roll () called session->record_status() = " << session->record_status() << endl;
1459
1460         if (session->get_play_loop()) {
1461                 session->request_play_loop (false);
1462                 auto_loop_button.set_visual_state (1);
1463                 roll_button.set_visual_state (1);
1464         } else if (session->get_play_range ()) {
1465                 session->request_play_range (false);
1466                 play_selection_button.set_visual_state (0);
1467         } else if (rolling) {
1468                 session->request_locate (session->last_transport_start(), true);
1469         }
1470
1471         session->request_transport_speed (1.0f);
1472 }
1473
1474 void
1475 ARDOUR_UI::transport_loop()
1476 {
1477         if (session) {
1478                 if (session->get_play_loop()) {
1479                         if (session->transport_rolling()) {
1480                                 Location * looploc = session->locations()->auto_loop_location();
1481                                 if (looploc) {
1482                                         session->request_locate (looploc->start(), true);
1483                                 }
1484                         }
1485                 }
1486                 else {
1487                         session->request_play_loop (true);
1488                 }
1489         }
1490 }
1491
1492 void
1493 ARDOUR_UI::transport_play_selection ()
1494 {
1495         if (!session) {
1496                 return;
1497         }
1498
1499         if (!session->get_play_range()) {
1500                 session->request_stop ();
1501         }
1502
1503         editor->play_selection ();
1504 }
1505
1506 void
1507 ARDOUR_UI::transport_rewind (int option)
1508 {
1509         float current_transport_speed;
1510  
1511         if (session) {
1512                 current_transport_speed = session->transport_speed();
1513                 
1514                 if (current_transport_speed >= 0.0f) {
1515                         switch (option) {
1516                         case 0:
1517                                 session->request_transport_speed (-1.0f);
1518                                 break;
1519                         case 1:
1520                                 session->request_transport_speed (-4.0f);
1521                                 break;
1522                         case -1:
1523                                 session->request_transport_speed (-0.5f);
1524                                 break;
1525                         }
1526                 } else {
1527                         /* speed up */
1528                         session->request_transport_speed (current_transport_speed * 1.5f);
1529                 }
1530         }
1531 }
1532
1533 void
1534 ARDOUR_UI::transport_forward (int option)
1535 {
1536         float current_transport_speed;
1537         
1538         if (session) {
1539                 current_transport_speed = session->transport_speed();
1540                 
1541                 if (current_transport_speed <= 0.0f) {
1542                         switch (option) {
1543                         case 0:
1544                                 session->request_transport_speed (1.0f);
1545                                 break;
1546                         case 1:
1547                                 session->request_transport_speed (4.0f);
1548                                 break;
1549                         case -1:
1550                                 session->request_transport_speed (0.5f);
1551                                 break;
1552                         }
1553                 } else {
1554                         /* speed up */
1555                         session->request_transport_speed (current_transport_speed * 1.5f);
1556                 }
1557         }
1558 }
1559
1560 void
1561 ARDOUR_UI::toggle_record_enable (uint32_t dstream)
1562 {
1563         if (session == 0) {
1564                 return;
1565         }
1566
1567         boost::shared_ptr<Route> r;
1568         
1569         if ((r = session->route_by_remote_id (dstream)) != 0) {
1570
1571                 Track* t;
1572
1573                 if ((t = dynamic_cast<Track*>(r.get())) != 0) {
1574                         t->diskstream()->set_record_enabled (!t->diskstream()->record_enabled());
1575                 }
1576         }
1577         if (session == 0) {
1578                 return;
1579         }
1580 }
1581
1582 void
1583 ARDOUR_UI::queue_transport_change ()
1584 {
1585         Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
1586 }
1587
1588 void
1589 ARDOUR_UI::map_transport_state ()
1590 {
1591         float sp = session->transport_speed();
1592
1593         if (sp == 1.0f) {
1594                 transport_rolling ();
1595         } else if (sp < 0.0f) {
1596                 transport_rewinding ();
1597         } else if (sp > 0.0f) {
1598                 transport_forwarding ();
1599         } else {
1600                 transport_stopped ();
1601         }
1602 }
1603
1604 void
1605 ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg)
1606 {
1607         snprintf (buf, sizeof(buf), "%s", ((GlobalClickBox *) arg)->strings[
1608                 (int) adj.get_value()].c_str());
1609 }
1610
1611 void
1612 ARDOUR_UI::engine_stopped ()
1613 {
1614         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
1615         ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1616         ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1617 }
1618
1619 void
1620 ARDOUR_UI::engine_running ()
1621 {
1622         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
1623         ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true);
1624         ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
1625
1626         Glib::RefPtr<Action> action;
1627         const char* action_name = 0;
1628
1629         switch (engine->frames_per_cycle()) {
1630         case 32:
1631                 action_name = X_("JACKLatency32");
1632                 break;
1633         case 64:
1634                 action_name = X_("JACKLatency64");
1635                 break;
1636         case 128:
1637                 action_name = X_("JACKLatency128");
1638                 break;
1639         case 512:
1640                 action_name = X_("JACKLatency512");
1641                 break;
1642         case 1024:
1643                 action_name = X_("JACKLatency1024");
1644                 break;
1645         case 2048:
1646                 action_name = X_("JACKLatency2048");
1647                 break;
1648         case 4096:
1649                 action_name = X_("JACKLatency4096");
1650                 break;
1651         case 8192:
1652                 action_name = X_("JACKLatency8192");
1653                 break;
1654         default:
1655                 /* XXX can we do anything useful ? */
1656                 break;
1657         }
1658
1659         if (action_name) {
1660
1661                 action = ActionManager::get_action (X_("JACK"), action_name);
1662                 
1663                 if (action) {
1664                         Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic (action);
1665                         ract->set_active ();
1666                 }
1667         }
1668 }
1669
1670 void
1671 ARDOUR_UI::engine_halted ()
1672 {
1673         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
1674
1675         ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1676         ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1677
1678         update_sample_rate (0);
1679
1680         MessageDialog msg (*editor, 
1681                            _("\
1682 JACK has either been shutdown or it\n\
1683 disconnected Ardour because Ardour\n\
1684 was not fast enough. Try to restart\n\
1685 JACK, reconnect and save the session."));
1686         pop_back_splash ();
1687         msg.run ();
1688 }
1689
1690 int32_t
1691 ARDOUR_UI::do_engine_start ()
1692 {
1693         try { 
1694                 engine->start();
1695         }
1696
1697         catch (...) {
1698                 engine->stop ();
1699                 error << _("Unable to start the session running")
1700                       << endmsg;
1701                 unload_session ();
1702                 return -2;
1703         }
1704         
1705         return 0;
1706 }
1707
1708 void
1709 ARDOUR_UI::setup_theme ()
1710 {
1711         theme_manager->setup_theme();
1712 }
1713
1714 void
1715 ARDOUR_UI::update_clocks ()
1716 {
1717         if (!editor || !editor->dragging_playhead()) {
1718                 Clock (session->audible_frame(), false, editor->get_preferred_edit_position()); /* EMIT_SIGNAL */
1719         }
1720 }
1721
1722 void
1723 ARDOUR_UI::start_clocking ()
1724 {
1725         clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
1726 }
1727
1728 void
1729 ARDOUR_UI::stop_clocking ()
1730 {
1731         clock_signal_connection.disconnect ();
1732 }
1733         
1734 void
1735 ARDOUR_UI::toggle_clocking ()
1736 {
1737 #if 0
1738         if (clock_button.get_active()) {
1739                 start_clocking ();
1740         } else {
1741                 stop_clocking ();
1742         }
1743 #endif
1744 }
1745
1746 gint
1747 ARDOUR_UI::_blink (void *arg)
1748
1749 {
1750         ((ARDOUR_UI *) arg)->blink ();
1751         return TRUE;
1752 }
1753
1754 void
1755 ARDOUR_UI::blink ()
1756 {
1757         Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
1758 }
1759
1760 void
1761 ARDOUR_UI::start_blinking ()
1762 {
1763         /* Start the blink signal. Everybody with a blinking widget
1764            uses Blink to drive the widget's state.
1765         */
1766
1767         if (blink_timeout_tag < 0) {
1768                 blink_on = false;       
1769                 blink_timeout_tag = g_timeout_add (240, _blink, this);
1770         }
1771 }
1772
1773 void
1774 ARDOUR_UI::stop_blinking ()
1775 {
1776         if (blink_timeout_tag >= 0) {
1777                 g_source_remove (blink_timeout_tag);
1778                 blink_timeout_tag = -1;
1779         }
1780 }
1781
1782 void
1783 ARDOUR_UI::name_io_setup (AudioEngine& engine, 
1784                           string& buf,
1785                           IO& io,
1786                           bool in)
1787 {
1788         if (in) {
1789                 if (io.n_inputs() == 0) {
1790                         buf = _("none");
1791                         return;
1792                 }
1793                 
1794                 /* XXX we're not handling multiple ports yet. */
1795
1796                 const char **connections = io.input(0)->get_connections();
1797                 
1798                 if (connections == 0 || connections[0] == '\0') {
1799                         buf = _("off");
1800                 } else {
1801                         buf = connections[0];
1802                 }
1803
1804                 free (connections);
1805
1806         } else {
1807
1808                 if (io.n_outputs() == 0) {
1809                         buf = _("none");
1810                         return;
1811                 }
1812                 
1813                 /* XXX we're not handling multiple ports yet. */
1814
1815                 const char **connections = io.output(0)->get_connections();
1816                 
1817                 if (connections == 0 || connections[0] == '\0') {
1818                         buf = _("off");
1819                 } else {
1820                         buf = connections[0];
1821                 }
1822
1823                 free (connections);
1824         }
1825 }
1826
1827 /** Ask the user for the name of a new shapshot and then take it.
1828  */
1829 void
1830 ARDOUR_UI::snapshot_session ()
1831 {
1832         ArdourPrompter prompter (true);
1833         string snapname;
1834         char timebuf[128];
1835         time_t n;
1836         struct tm local_time;
1837
1838         time (&n);
1839         localtime_r (&n, &local_time);
1840         strftime (timebuf, sizeof(timebuf), "%FT%T", &local_time);
1841
1842         prompter.set_name ("Prompter");
1843         prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1844         prompter.set_prompt (_("Name of New Snapshot"));
1845         prompter.set_initial_text (timebuf);
1846         
1847         switch (prompter.run()) {
1848         case RESPONSE_ACCEPT:
1849                 prompter.get_result (snapname);
1850                 if (snapname.length()){
1851                         save_state (snapname);
1852                 }
1853                 break;
1854
1855         default:
1856                 break;
1857         }
1858 }
1859
1860 void
1861 ARDOUR_UI::save_state (const string & name)
1862 {
1863         (void) save_state_canfail (name);
1864 }
1865                 
1866 int
1867 ARDOUR_UI::save_state_canfail (string name)
1868 {
1869         if (session) {
1870                 int ret;
1871
1872                 if (name.length() == 0) {
1873                         name = session->snap_name();
1874                 }
1875
1876                 if ((ret = session->save_state (name)) != 0) {
1877                         return ret;
1878                 }
1879         }
1880         save_ardour_state (); /* XXX cannot fail? yeah, right ... */
1881         return 0;
1882 }
1883
1884 void
1885 ARDOUR_UI::primary_clock_value_changed ()
1886 {
1887         if (session) {
1888                 session->request_locate (primary_clock.current_time ());
1889         }
1890 }
1891
1892 void
1893 ARDOUR_UI::big_clock_value_changed ()
1894 {
1895         if (session) {
1896                 session->request_locate (big_clock.current_time ());
1897         }
1898 }
1899
1900 void
1901 ARDOUR_UI::secondary_clock_value_changed ()
1902 {
1903         if (session) {
1904                 session->request_locate (secondary_clock.current_time ());
1905         }
1906 }
1907
1908 void
1909 ARDOUR_UI::transport_rec_enable_blink (bool onoff) 
1910 {
1911         if (session == 0) {
1912                 return;
1913         }
1914         
1915         switch (session->record_status()) {
1916         case Session::Enabled:
1917                 if (onoff) {
1918                         rec_button.set_visual_state (2);
1919                 } else {
1920                         rec_button.set_visual_state (0);
1921                 }
1922                 break;
1923
1924         case Session::Recording:
1925                 rec_button.set_visual_state (1);
1926                 break;
1927
1928         default:
1929                 rec_button.set_visual_state (0);
1930                 break;
1931         }
1932 }
1933
1934 void
1935 ARDOUR_UI::save_template ()
1936
1937 {
1938         ArdourPrompter prompter (true);
1939         string name;
1940
1941         if (!check_audioengine()) {
1942                 return;
1943         }
1944
1945         prompter.set_name (X_("Prompter"));
1946         prompter.set_prompt (_("Name for mix template:"));
1947         prompter.set_initial_text(session->name() + _("-template"));
1948         prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1949
1950         switch (prompter.run()) {
1951         case RESPONSE_ACCEPT:
1952                 prompter.get_result (name);
1953                 
1954                 if (name.length()) {
1955                         session->save_template (name);
1956                 }
1957                 break;
1958
1959         default:
1960                 break;
1961         }
1962 }
1963
1964 void
1965 ARDOUR_UI::fontconfig_dialog ()
1966 {
1967 #ifdef GTKOSX
1968         /* X11 users will always have fontconfig info around, but new GTK-OSX users 
1969            may not and it can take a while to build it. Warn them.
1970         */
1971         
1972         Glib::ustring fontconfig = Glib::build_filename (Glib::get_home_dir(), ".fontconfig");
1973         
1974         if (!Glib::file_test (fontconfig, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
1975                 MessageDialog msg (*new_session_dialog,
1976                                    _("Welcome to Ardour.\n\n"
1977                                      "The program will take a bit longer to start up\n"
1978                                      "while the system fonts are checked.\n\n"
1979                                      "This will only be done once, and you will\n"
1980                                      "not see this message again\n"),
1981                                    true,
1982                                    Gtk::MESSAGE_INFO,
1983                                    Gtk::BUTTONS_OK);
1984                 pop_back_splash ();
1985                 msg.show_all ();
1986                 msg.present ();
1987                 msg.run ();
1988         }
1989 #endif
1990 }
1991
1992 void
1993 ARDOUR_UI::parse_cmdline_path (const Glib::ustring& cmdline_path, Glib::ustring& session_name, Glib::ustring& session_path, bool& existing_session)
1994 {
1995         existing_session = false;
1996
1997         if (Glib::file_test (cmdline_path, Glib::FILE_TEST_IS_DIR)) {
1998                 session_path = cmdline_path;
1999                 existing_session = true;
2000         } else if (Glib::file_test (cmdline_path, Glib::FILE_TEST_IS_REGULAR)) {
2001                 session_path = Glib::path_get_dirname (string (cmdline_path));
2002                 existing_session = true;
2003         } else {
2004                 /* it doesn't exist, assume the best */
2005                 session_path = Glib::path_get_dirname (string (cmdline_path));
2006         }
2007         
2008         session_name = basename_nosuffix (string (cmdline_path));
2009 }
2010
2011 int
2012 ARDOUR_UI::load_cmdline_session (const Glib::ustring& session_name, const Glib::ustring& session_path, bool& existing_session)
2013 {
2014         /* when this is called, the backend audio system must be running */
2015
2016         /* the main idea here is to deal with the fact that a cmdline argument for the session
2017            can be interpreted in different ways - it could be a directory or a file, and before
2018            we load, we need to know both the session directory and the snapshot (statefile) within it
2019            that we are supposed to use.
2020         */
2021
2022         if (session_name.length() == 0 || session_path.length() == 0) {
2023                 return false;
2024         }
2025         
2026         if (Glib::file_test (session_path, Glib::FILE_TEST_IS_DIR)) {
2027
2028                 Glib::ustring predicted_session_file;
2029                 
2030                 predicted_session_file = session_path;
2031                 predicted_session_file += '/';
2032                 predicted_session_file += session_name;
2033                 predicted_session_file += Session::statefile_suffix();
2034                 
2035                 if (Glib::file_test (predicted_session_file, Glib::FILE_TEST_EXISTS)) {
2036                         existing_session = true;
2037                 }
2038                 
2039         } else if (Glib::file_test (session_path, Glib::FILE_TEST_EXISTS)) {
2040                 
2041                 if (session_path.find (Session::statefile_suffix()) == session_path.length() - 7) {
2042                         /* existing .ardour file */
2043                         existing_session = true;
2044                 }
2045
2046         } else {
2047                 existing_session = false;
2048         }
2049         
2050         /* lets just try to load it */
2051         
2052         if (create_engine ()) {
2053                 backend_audio_error (false, new_session_dialog);
2054                 return -1;
2055         }
2056         
2057         return load_session (session_path, session_name);
2058 }
2059
2060 bool
2061 ARDOUR_UI::ask_about_loading_existing_session (const Glib::ustring& session_path)
2062 {
2063         Glib::ustring str = string_compose (_("This session\n%1\nalready exists. Do you want to open it?"), session_path);
2064         
2065         MessageDialog msg (str,
2066                            false,
2067                            Gtk::MESSAGE_WARNING,
2068                            Gtk::BUTTONS_YES_NO,
2069                            true);
2070         
2071         
2072         msg.set_name (X_("CleanupDialog"));
2073         msg.set_wmclass (X_("existing_session"), "Ardour");
2074         msg.set_position (Gtk::WIN_POS_MOUSE);
2075         pop_back_splash ();
2076
2077         switch (msg.run()) {
2078         case RESPONSE_YES:
2079                 return true;
2080                 break;
2081         }
2082         return false;
2083 }
2084
2085 int
2086 ARDOUR_UI::build_session_from_nsd (const Glib::ustring& session_path, const Glib::ustring& session_name)
2087 {
2088         
2089         uint32_t cchns;
2090         uint32_t mchns;
2091         AutoConnectOption iconnect;
2092         AutoConnectOption oconnect;
2093         uint32_t nphysin;
2094         uint32_t nphysout;
2095         
2096         if (Profile->get_sae()) {
2097                 
2098                 cchns = 0;
2099                 mchns = 2;
2100                 iconnect = AutoConnectPhysical;
2101                 oconnect = AutoConnectMaster;
2102                 nphysin = 0; // use all available
2103                 nphysout = 0; // use all available
2104                 
2105         } else {
2106                 
2107                 /* get settings from advanced section of NSD */
2108                 
2109                 if (new_session_dialog->create_control_bus()) {
2110                         cchns = (uint32_t) new_session_dialog->control_channel_count();
2111                 } else {
2112                         cchns = 0;
2113                 }
2114                 
2115                 if (new_session_dialog->create_master_bus()) {
2116                         mchns = (uint32_t) new_session_dialog->master_channel_count();
2117                 } else {
2118                         mchns = 0;
2119                 }
2120                 
2121                 if (new_session_dialog->connect_inputs()) {
2122                         iconnect = AutoConnectPhysical;
2123                 } else {
2124                         iconnect = AutoConnectOption (0);
2125                 }
2126                 
2127                 /// @todo some minor tweaks.
2128                 
2129                 if (new_session_dialog->connect_outs_to_master()) {
2130                         oconnect = AutoConnectMaster;
2131                 } else if (new_session_dialog->connect_outs_to_physical()) {
2132                         oconnect = AutoConnectPhysical;
2133                 } else {
2134                         oconnect = AutoConnectOption (0);
2135                 } 
2136                 
2137                 nphysin = (uint32_t) new_session_dialog->input_limit_count();
2138                 nphysout = (uint32_t) new_session_dialog->output_limit_count();
2139         }
2140         
2141         if (build_session (session_path,
2142                            session_name,
2143                            cchns,
2144                            mchns,
2145                            iconnect,
2146                            oconnect,
2147                            nphysin,
2148                            nphysout, 
2149                            engine->frame_rate() * 60 * 5)) {
2150                 
2151                 return -1;
2152         }
2153
2154         return 0;
2155 }
2156
2157 void
2158 ARDOUR_UI::end_loading_messages ()
2159 {
2160         // hide_splash ();
2161 }
2162
2163 void
2164 ARDOUR_UI::loading_message (const std::string& msg)
2165 {
2166         show_splash ();
2167         splash->message (msg);
2168         flush_pending ();
2169 }
2170
2171 void
2172 ARDOUR_UI::idle_load (const Glib::ustring& path)
2173 {
2174         if (session) {
2175                 if (Glib::file_test (path, Glib::FILE_TEST_IS_DIR)) {
2176                         /* /path/to/foo => /path/to/foo, foo */
2177                         load_session (path, basename_nosuffix (path));
2178                 } else {
2179                         /* /path/to/foo/foo.ardour => /path/to/foo, foo */
2180                         load_session (Glib::path_get_dirname (path), basename_nosuffix (path));
2181                 }
2182         } else {
2183
2184                 ARDOUR_COMMAND_LINE::session_name = path;
2185
2186                 if (new_session_dialog) {
2187
2188
2189                         /* make it break out of Dialog::run() and
2190                            start again.
2191                          */
2192
2193                         new_session_dialog->response (1);
2194                 }
2195         }
2196 }
2197
2198 bool
2199 ARDOUR_UI::get_session_parameters (bool backend_audio_is_running, bool should_be_new)
2200 {
2201         bool existing_session = false;
2202         Glib::ustring session_name;
2203         Glib::ustring session_path;
2204         Glib::ustring template_name;
2205         int response;
2206
2207   begin:
2208         response = Gtk::RESPONSE_NONE;
2209
2210         if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
2211
2212                 parse_cmdline_path (ARDOUR_COMMAND_LINE::session_name, session_name, session_path, existing_session);
2213
2214                 /* don't ever reuse this */
2215
2216                 ARDOUR_COMMAND_LINE::session_name = string();
2217
2218                 if (existing_session && backend_audio_is_running) {
2219
2220                         /* just load the thing already */
2221
2222                         if (load_cmdline_session (session_name, session_path, existing_session) == 0) {
2223                                 return true;
2224                         }
2225                 }
2226
2227                 /* make the NSD use whatever information we have */
2228
2229                 new_session_dialog->set_session_name (session_name);
2230                 new_session_dialog->set_session_folder (session_path);
2231         }
2232
2233         /* loading failed, or we need the NSD for something */
2234
2235         new_session_dialog->set_modal (false);
2236         new_session_dialog->set_position (WIN_POS_CENTER);
2237         new_session_dialog->set_current_page (0);
2238         new_session_dialog->set_existing_session (existing_session);
2239         new_session_dialog->reset_recent();
2240
2241         do {
2242                 new_session_dialog->set_have_engine (backend_audio_is_running);
2243                 new_session_dialog->present ();
2244                 response = new_session_dialog->run ();
2245                 
2246                 _session_is_new = false;
2247                 
2248                 /* handle possible negative responses */
2249
2250                 switch (response) {
2251                 case 1:
2252                         /* sent by idle_load, meaning restart the whole process again */
2253                         new_session_dialog->hide();
2254                         new_session_dialog->reset();
2255                         goto begin;
2256                         break;
2257
2258                 case Gtk::RESPONSE_CANCEL:
2259                 case Gtk::RESPONSE_DELETE_EVENT:
2260                         if (!session) {
2261                                 if (engine && engine->running()) {
2262                                         engine->stop (true);
2263                                 }
2264                                 quit();
2265                         }
2266                         new_session_dialog->hide ();
2267                         return false;
2268                         
2269                 case Gtk::RESPONSE_NONE:
2270                         /* "Clear" was pressed */
2271                         goto try_again;
2272                 }
2273
2274                 fontconfig_dialog();
2275
2276                 if (!backend_audio_is_running) {
2277                         int ret = new_session_dialog->engine_control.setup_engine ();
2278                         if (ret < 0) {
2279                                 return false;
2280                         } else if (ret > 0) {
2281                                 response = Gtk::RESPONSE_REJECT;
2282                                 goto try_again;
2283                         }
2284                 }
2285                 
2286                 if (create_engine ()) {
2287
2288                         backend_audio_error (!backend_audio_is_running, new_session_dialog);
2289                         flush_pending ();
2290
2291                         new_session_dialog->set_existing_session (false);
2292                         new_session_dialog->set_current_page (2);
2293
2294                         response = Gtk::RESPONSE_NONE;
2295                         goto try_again;
2296                 }
2297
2298                 backend_audio_is_running = true;                
2299                         
2300                 if (response == Gtk::RESPONSE_OK) {
2301
2302                         session_name = new_session_dialog->session_name();
2303
2304                         if (session_name.empty()) {
2305                                 response = Gtk::RESPONSE_NONE;
2306                                 goto try_again;
2307                         } 
2308
2309                         /* if the user mistakenly typed path information into the session filename entry,
2310                            convert what they typed into a path & a name
2311                         */
2312                         
2313                         if (session_name[0] == '/' || 
2314                             (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
2315                             (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
2316
2317                                 session_path = Glib::path_get_dirname (session_name);
2318                                 session_name = Glib::path_get_basename (session_name);
2319                                 
2320                         } else {
2321
2322                                 session_path = new_session_dialog->session_folder();
2323                         }
2324
2325                         template_name = Glib::ustring();                        
2326                         switch (new_session_dialog->which_page()) {
2327
2328                         case NewSessionDialog::OpenPage: 
2329                         case NewSessionDialog::EnginePage:
2330                                 goto loadit;
2331                                 break;
2332
2333                         case NewSessionDialog::NewPage: /* nominally the "new" session creator, but could be in use for an old session */
2334                                 
2335                                 should_be_new = true;
2336                                 
2337                                 //XXX This is needed because session constructor wants a 
2338                                 //non-existant path. hopefully this will be fixed at some point.
2339                                 
2340                                 session_path = Glib::build_filename (session_path, session_name);
2341
2342                                 if (Glib::file_test (session_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
2343
2344                                         if (ask_about_loading_existing_session (session_path)) {
2345                                                 goto loadit;
2346                                         } else {
2347                                                 response = RESPONSE_NONE;
2348                                                 goto try_again;
2349                                         } 
2350                                 }
2351
2352                                 _session_is_new = true;
2353                                                 
2354                                 if (new_session_dialog->use_session_template()) {
2355
2356                                         template_name = new_session_dialog->session_template_name();
2357                                         goto loadit;
2358                           
2359                                 } else {
2360                                         if (build_session_from_nsd (session_path, session_name)) {
2361                                                 response = RESPONSE_NONE;
2362                                                 goto try_again;
2363                                         }
2364                                         goto done;
2365                                 }
2366                                 break;
2367                                 
2368                         default:
2369                                 break;
2370                         }
2371                         
2372                   loadit:
2373                         new_session_dialog->hide ();
2374
2375                         if (load_session (session_path, session_name, template_name)) {
2376                                 /* force a retry */
2377                                 response = Gtk::RESPONSE_NONE;
2378                         }
2379
2380                   try_again:
2381                         if (response == Gtk::RESPONSE_NONE) {
2382                                 new_session_dialog->set_existing_session (false);
2383                                 new_session_dialog->reset ();
2384                         }
2385                 }
2386
2387         } while (response == Gtk::RESPONSE_NONE || response == Gtk::RESPONSE_REJECT);
2388
2389   done:
2390         show();
2391         new_session_dialog->hide();
2392         new_session_dialog->reset();
2393         goto_editor_window ();
2394         return true;
2395 }       
2396
2397 void
2398 ARDOUR_UI::close_session ()
2399 {
2400         if (!check_audioengine()) {
2401                 return;
2402         }
2403
2404         unload_session (true);
2405         
2406         get_session_parameters (true, false);
2407 }
2408
2409 int
2410 ARDOUR_UI::load_session (const Glib::ustring& path, const Glib::ustring& snap_name, Glib::ustring mix_template)
2411 {
2412         Session *new_session;
2413         int unload_status;
2414         int retval = -1;
2415
2416         session_loaded = false;
2417
2418         if (!check_audioengine()) {
2419                 return -1;
2420         }
2421
2422         unload_status = unload_session ();
2423
2424         if (unload_status < 0) {
2425                 goto out;
2426         } else if (unload_status > 0) {
2427                 retval = 0;
2428                 goto out;
2429         }
2430
2431         /* if it already exists, we must have write access */
2432
2433         if (Glib::file_test (path.c_str(), Glib::FILE_TEST_EXISTS) && ::access (path.c_str(), W_OK)) {
2434                 MessageDialog msg (*editor, _("You do not have write access to this session.\n"
2435                                               "This prevents the session from being loaded."));
2436                 pop_back_splash ();
2437                 msg.run ();
2438                 goto out;
2439         }
2440
2441         loading_message (_("Please wait while Ardour loads your session"));
2442
2443         try {
2444                 new_session = new Session (*engine, path, snap_name, mix_template);
2445         }
2446
2447         /* this one is special */
2448
2449         catch (AudioEngine::PortRegistrationFailure& err) {
2450
2451                 MessageDialog msg (err.what(),
2452                                    true,
2453                                    Gtk::MESSAGE_INFO,
2454                                    Gtk::BUTTONS_CLOSE);
2455                 
2456                 msg.set_title (_("Port Registration Error"));
2457                 msg.set_secondary_text (_("Click the Close button to try again."));
2458                 msg.set_position (Gtk::WIN_POS_CENTER);
2459                 pop_back_splash ();
2460                 msg.present ();
2461
2462                 int response = msg.run ();
2463
2464                 msg.hide ();
2465
2466                 switch (response) {
2467                 case RESPONSE_CANCEL:
2468                         exit (1);
2469                 default:
2470                         break;
2471                 }
2472                 goto out;
2473         }
2474
2475         catch (...) {
2476
2477                 MessageDialog msg (string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name),
2478                                    true,
2479                                    Gtk::MESSAGE_INFO,
2480                                    Gtk::BUTTONS_CLOSE);
2481                 
2482                 msg.set_title (_("Loading Error"));
2483                 msg.set_secondary_text (_("Click the Close button to try again."));
2484                 msg.set_position (Gtk::WIN_POS_CENTER);
2485                 pop_back_splash ();
2486                 msg.present ();
2487
2488                 int response = msg.run ();
2489
2490                 msg.hide ();
2491
2492                 switch (response) {
2493                 case RESPONSE_CANCEL:
2494                         exit (1);
2495                 default:
2496                         break;
2497                 }
2498                 goto out;
2499         }
2500
2501         connect_to_session (new_session);
2502
2503         Config->set_current_owner (ConfigVariableBase::Interface);
2504
2505         session_loaded = true;
2506         
2507         goto_editor_window ();
2508
2509         if (session) {
2510                 session->set_clean ();
2511         }
2512
2513         flush_pending ();
2514         retval = 0;
2515
2516   out:
2517         return retval;
2518 }
2519
2520 int
2521 ARDOUR_UI::build_session (const Glib::ustring& path, const Glib::ustring& snap_name, 
2522                           uint32_t control_channels,
2523                           uint32_t master_channels, 
2524                           AutoConnectOption input_connect,
2525                           AutoConnectOption output_connect,
2526                           uint32_t nphysin,
2527                           uint32_t nphysout,
2528                           nframes_t initial_length)
2529 {
2530         Session *new_session;
2531         int x;
2532
2533         if (!check_audioengine()) {
2534                 return -1;
2535         }
2536
2537         session_loaded = false;
2538
2539         x = unload_session ();
2540
2541         if (x < 0) {
2542                 return -1;
2543         } else if (x > 0) {
2544                 return 0;
2545         }
2546         
2547         _session_is_new = true;
2548
2549         try {
2550                 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
2551                                            control_channels, master_channels, nphysin, nphysout, initial_length);
2552         }
2553
2554         catch (...) {
2555
2556                 MessageDialog msg (string_compose(_("Could not create session in \"%1\""), path));
2557                 pop_back_splash ();
2558                 msg.run ();
2559                 return -1;
2560         }
2561
2562         connect_to_session (new_session);
2563
2564         session_loaded = true;
2565
2566         new_session->save_state(new_session->name());
2567
2568         return 0;
2569 }
2570
2571 void
2572 ARDOUR_UI::show ()
2573 {
2574         if (editor) {
2575                 editor->show_window ();
2576                 
2577                 if (!shown_flag) {
2578                         editor->present ();
2579                 }
2580
2581                 shown_flag = true;
2582         }
2583 }
2584
2585 void
2586 ARDOUR_UI::show_about ()
2587 {
2588         if (about == 0) {
2589                 about = new About;
2590                 about->signal_response().connect(mem_fun (*this, &ARDOUR_UI::about_signal_response) );
2591         }
2592
2593         about->show_all ();
2594 }
2595
2596 void
2597 ARDOUR_UI::hide_about ()
2598 {
2599         if (about) {
2600                 about->get_window()->set_cursor ();
2601                 about->hide ();
2602         }
2603 }
2604
2605 void
2606 ARDOUR_UI::about_signal_response(int response)
2607 {
2608         hide_about();
2609 }
2610
2611 void
2612 ARDOUR_UI::show_splash ()
2613 {
2614         if (splash == 0) {
2615                 try {
2616                         splash = new Splash;
2617                 } catch (...) {
2618                         return;
2619                 }
2620         }
2621
2622         splash->show ();
2623         splash->present ();
2624         splash->queue_draw ();
2625         splash->get_window()->process_updates (true);
2626         flush_pending ();
2627 }
2628
2629 void
2630 ARDOUR_UI::hide_splash ()
2631 {
2632         if (splash) {
2633                 splash->hide();
2634         }
2635 }
2636
2637 void
2638 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title, const string & msg)
2639 {
2640         size_t removed;
2641
2642         removed = rep.paths.size();
2643
2644         if (removed == 0) {
2645                 MessageDialog msgd (*editor,
2646                                     _("No audio files were ready for cleanup"), 
2647                                     true,
2648                                     Gtk::MESSAGE_INFO,
2649                                     (Gtk::ButtonsType)(Gtk::BUTTONS_OK)  );
2650                 msgd.set_secondary_text (_("If this seems suprising, \n\
2651 check for any existing snapshots.\n\
2652 These may still include regions that\n\
2653 require some unused files to continue to exist."));
2654         
2655                 msgd.run ();
2656                 return;
2657         } 
2658
2659         ArdourDialog results (_("ardour: cleanup"), true, false);
2660         
2661         struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
2662             CleanupResultsModelColumns() { 
2663                     add (visible_name);
2664                     add (fullpath);
2665             }
2666             Gtk::TreeModelColumn<Glib::ustring> visible_name;
2667             Gtk::TreeModelColumn<Glib::ustring> fullpath;
2668         };
2669
2670         
2671         CleanupResultsModelColumns results_columns;
2672         Glib::RefPtr<Gtk::ListStore> results_model;
2673         Gtk::TreeView results_display;
2674         
2675         results_model = ListStore::create (results_columns);
2676         results_display.set_model (results_model);
2677         results_display.append_column (list_title, results_columns.visible_name);
2678
2679         results_display.set_name ("CleanupResultsList");
2680         results_display.set_headers_visible (true);
2681         results_display.set_headers_clickable (false);
2682         results_display.set_reorderable (false);
2683
2684         Gtk::ScrolledWindow list_scroller;
2685         Gtk::Label txt;
2686         Gtk::VBox dvbox;
2687         Gtk::HBox dhbox;  // the hbox for the image and text
2688         Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
2689         Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO,  Gtk::ICON_SIZE_DIALOG));
2690
2691         dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
2692
2693         if (rep.space < 1048576.0f) {
2694                 if (removed > 1) {
2695                   txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2696                 } else {
2697                         txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2698                 }
2699         } else {
2700                 if (removed > 1) {
2701                         txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2702                 } else {
2703                         txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2704                 }
2705         }
2706
2707         dhbox.pack_start (*dimage, true, false, 5);
2708         dhbox.pack_start (txt, true, false, 5);
2709
2710         for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2711                 TreeModel::Row row = *(results_model->append());
2712                 row[results_columns.visible_name] = *i;
2713                 row[results_columns.fullpath] = *i;
2714         }
2715         
2716         list_scroller.add (results_display);
2717         list_scroller.set_size_request (-1, 150);
2718         list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2719
2720         dvbox.pack_start (dhbox, true, false, 5);
2721         dvbox.pack_start (list_scroller, true, false, 5);
2722         ddhbox.pack_start (dvbox, true, false, 5);
2723
2724         results.get_vbox()->pack_start (ddhbox, true, false, 5);
2725         results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
2726         results.set_default_response (RESPONSE_CLOSE);
2727         results.set_position (Gtk::WIN_POS_MOUSE);
2728         results.show_all_children ();
2729         results.set_resizable (false);
2730
2731         results.run ();
2732
2733 }
2734
2735 void
2736 ARDOUR_UI::cleanup ()
2737 {
2738         if (session == 0) {
2739                 /* shouldn't happen: menu item is insensitive */
2740                 return;
2741         }
2742
2743
2744         MessageDialog  checker (_("Are you sure you want to cleanup?"),
2745                                 true,
2746                                 Gtk::MESSAGE_QUESTION,
2747                                 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
2748
2749         checker.set_secondary_text(_("Cleanup is a destructive operation.\n\
2750 ALL undo/redo information will be lost if you cleanup.\n\
2751 After cleanup, unused audio files will be moved to a \
2752 \"dead sounds\" location."));
2753         
2754         checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2755         checker.add_button (_("Clean Up"), RESPONSE_ACCEPT);
2756         checker.set_default_response (RESPONSE_CANCEL);
2757
2758         checker.set_name (_("CleanupDialog"));
2759         checker.set_wmclass (X_("ardour_cleanup"), "Ardour");
2760         checker.set_position (Gtk::WIN_POS_MOUSE);
2761
2762         switch (checker.run()) {
2763         case RESPONSE_ACCEPT:
2764                 break;
2765         default:
2766                 return;
2767         }
2768
2769         Session::cleanup_report rep;
2770
2771         editor->prepare_for_cleanup ();
2772
2773         /* do not allow flush until a session is reloaded */
2774
2775         Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
2776         if (act) {
2777                 act->set_sensitive (false);
2778         }
2779
2780         if (session->cleanup_sources (rep)) {
2781                 editor->finish_cleanup ();
2782                 return;
2783         }
2784         
2785         editor->finish_cleanup ();
2786
2787         checker.hide();
2788         display_cleanup_results (rep, 
2789                                  _("cleaned files"),
2790                                  _("\
2791 The following %1 %2 not in use and \n\
2792 have been moved to:\n\
2793 %3. \n\n\
2794 Flushing the wastebasket will \n\
2795 release an additional\n\
2796 %4 %5bytes of disk space.\n"
2797                                          ));
2798
2799 }
2800
2801 void
2802 ARDOUR_UI::flush_trash ()
2803 {
2804         if (session == 0) {
2805                 /* shouldn't happen: menu item is insensitive */
2806                 return;
2807         }
2808
2809         Session::cleanup_report rep;
2810
2811         if (session->cleanup_trash_sources (rep)) {
2812                 return;
2813         }
2814
2815         display_cleanup_results (rep, 
2816                                  _("deleted file"),
2817                                  _("The following %1 %2 deleted from\n\
2818 %3,\n\
2819 releasing %4 %5bytes of disk space"));
2820 }
2821
2822 void
2823 ARDOUR_UI::add_route (Gtk::Window* float_window)
2824 {
2825         int count;
2826
2827         if (!session) {
2828                 return;
2829         }
2830
2831         if (add_route_dialog == 0) {
2832                 add_route_dialog = new AddRouteDialog;
2833                 if (float_window) {
2834                         add_route_dialog->set_transient_for (*float_window);
2835                 }
2836         }
2837
2838         if (add_route_dialog->is_visible()) {
2839                 /* we're already doing this */
2840                 return;
2841         }
2842
2843         ResponseType r = (ResponseType) add_route_dialog->run ();
2844         
2845         add_route_dialog->hide();
2846
2847         switch (r) {
2848         case RESPONSE_ACCEPT:
2849                 break;
2850         default:
2851                 return;
2852                 break;
2853         }
2854
2855         if ((count = add_route_dialog->count()) <= 0) {
2856                 return;
2857         }
2858
2859         string template_path = add_route_dialog->track_template();
2860
2861         if (!template_path.empty()) {
2862           session->new_route_from_template (count, template_path);
2863           return;
2864         }
2865         
2866         uint32_t input_chan = add_route_dialog->channels ();
2867         uint32_t output_chan;
2868         string name_template = add_route_dialog->name_template ();
2869         bool track = add_route_dialog->track ();
2870
2871         AutoConnectOption oac = Config->get_output_auto_connect();
2872
2873         if (oac & AutoConnectMaster) {
2874                 output_chan = (session->master_out() ? session->master_out()->n_inputs() : input_chan);
2875         } else {
2876                 output_chan = input_chan;
2877         }
2878
2879         /* XXX do something with name template */
2880
2881         if (track) {
2882                 session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), count);
2883         } else {
2884                 session_add_audio_bus (input_chan, output_chan, count);
2885         }
2886 }
2887
2888 XMLNode*
2889 ARDOUR_UI::mixer_settings () const
2890 {
2891         XMLNode* node = 0;
2892
2893         if (session) {
2894                 node = session->instant_xml(X_("Mixer"), session->path());
2895         } else {
2896                 node = Config->instant_xml(X_("Mixer"), get_user_ardour_path());
2897         }
2898
2899         if (!node) {
2900                 node = new XMLNode (X_("Mixer"));
2901         }
2902
2903         return node;
2904 }
2905
2906 XMLNode*
2907 ARDOUR_UI::editor_settings () const
2908 {
2909         XMLNode* node = 0;
2910
2911         if (session) {
2912                 node = session->instant_xml(X_("Editor"), session->path());
2913         } else {
2914                 node = Config->instant_xml(X_("Editor"), get_user_ardour_path());
2915         }
2916         
2917         if (!node) {
2918                 if (getenv("ARDOUR_INSTANT_XML_PATH")) {
2919                         node = Config->instant_xml(X_("Editor"), getenv("ARDOUR_INSTANT_XML_PATH"));
2920                 }
2921         }
2922
2923         if (!node) {
2924                 node = new XMLNode (X_("Editor"));
2925         }
2926         return node;
2927 }
2928
2929 XMLNode*
2930 ARDOUR_UI::keyboard_settings () const
2931 {
2932         XMLNode* node = 0;
2933
2934         node = Config->extra_xml(X_("Keyboard"));
2935         
2936         if (!node) {
2937                 node = new XMLNode (X_("Keyboard"));
2938         }
2939         return node;
2940 }
2941
2942 void
2943 ARDOUR_UI::create_xrun_marker(nframes_t where)
2944 {
2945         editor->mouse_add_new_marker (where, false, true);
2946 }
2947
2948 void
2949 ARDOUR_UI::halt_on_xrun_message ()
2950 {
2951         MessageDialog msg (*editor,
2952                            _("Recording was stopped because your system could not keep up."));
2953         msg.run ();
2954 }
2955
2956 void
2957 ARDOUR_UI::xrun_handler(nframes_t where)
2958 {
2959         if (!session) {
2960                 return;
2961         }
2962
2963         ENSURE_GUI_THREAD (bind(mem_fun(*this, &ARDOUR_UI::xrun_handler), where));
2964
2965         if (session && Config->get_create_xrun_marker() && session->actively_recording()) {
2966                 create_xrun_marker(where);
2967         }
2968
2969         if (session && Config->get_stop_recording_on_xrun() && session->actively_recording()) {
2970                 halt_on_xrun_message ();
2971         }
2972 }
2973
2974 bool
2975 ARDOUR_UI::preset_file_exists_handler ()
2976 {
2977         /* if driven from another thread, say "do not overwrite" and show the user nothing.
2978          */
2979
2980         if (!Gtkmm2ext::UI::instance()->caller_is_ui_thread()) {        \
2981                 return false;
2982         }
2983         
2984         HBox* hbox = new HBox();
2985         Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG);
2986         Gtk::Dialog dialog (_("Preset Exists"), true, false);
2987         Label  message (_("\
2988 A preset with this name already exists for this plugin.\n\
2989 \n\
2990 What you would like to do?\n"));
2991         image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
2992         hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
2993         hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
2994         dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
2995         dialog.add_button (_("Overwrite the existing preset"), RESPONSE_ACCEPT);
2996         dialog.add_button (_("Leave the existing preset alone"), RESPONSE_REJECT);
2997         dialog.set_default_response (RESPONSE_ACCEPT);
2998         dialog.set_position (WIN_POS_MOUSE);
2999         dialog.set_type_hint (Gdk::WINDOW_TYPE_HINT_UTILITY); // need to make it float above the preset name dialog
3000
3001         message.show();
3002         image->show();
3003         hbox->show();
3004
3005         switch (dialog.run ()) {
3006         case RESPONSE_ACCEPT:
3007                 return true;
3008         default:
3009                 return false;
3010         }
3011 }
3012
3013 void
3014 ARDOUR_UI::disk_overrun_handler ()
3015 {
3016         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
3017
3018         if (!have_disk_speed_dialog_displayed) {
3019                 have_disk_speed_dialog_displayed = true;
3020                 MessageDialog* msg = new MessageDialog (*editor, _("\
3021 The disk system on your computer\n\
3022 was not able to keep up with Ardour.\n\
3023 \n\
3024 Specifically, it failed to write data to disk\n\
3025 quickly enough to keep up with recording.\n"));
3026                 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
3027                 msg->show_all ();
3028         }
3029 }
3030
3031 void
3032 ARDOUR_UI::disk_underrun_handler ()
3033 {
3034         ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
3035
3036         if (!have_disk_speed_dialog_displayed) {
3037                 have_disk_speed_dialog_displayed = true;
3038                 MessageDialog* msg = new MessageDialog (*editor,
3039                                    _("The disk system on your computer\n\
3040 was not able to keep up with Ardour.\n\
3041 \n\
3042 Specifically, it failed to read data from disk\n\
3043 quickly enough to keep up with playback.\n"));
3044                 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
3045                 msg->show_all ();
3046         } 
3047 }
3048
3049 void
3050 ARDOUR_UI::disk_speed_dialog_gone (int ignored_response, MessageDialog* msg)
3051 {
3052         have_disk_speed_dialog_displayed = false;
3053         delete msg;
3054 }
3055
3056 void
3057 ARDOUR_UI::session_dialog (std::string msg)
3058 {
3059         ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::session_dialog), msg));
3060         
3061         MessageDialog* d;
3062
3063         if (editor) {
3064                 d = new MessageDialog (*editor, msg, false, MESSAGE_INFO, BUTTONS_OK, true);
3065         } else {
3066                 d = new MessageDialog (msg, false, MESSAGE_INFO, BUTTONS_OK, true);
3067         }
3068
3069         d->show_all ();
3070         d->run ();
3071         delete d;
3072 }       
3073
3074 int
3075 ARDOUR_UI::pending_state_dialog ()
3076 {
3077         HBox* hbox = new HBox();
3078         Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG);
3079         ArdourDialog dialog (_("Crash Recovery"), true);
3080         Label  message (_("\
3081 This session appears to have been in\n\
3082 middle of recording when ardour or\n\
3083 the computer was shutdown.\n\
3084 \n\
3085 Ardour can recover any captured audio for\n\
3086 you, or it can ignore it. Please decide\n\
3087 what you would like to do.\n"));
3088         image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
3089         hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
3090         hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
3091         dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
3092         dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
3093         dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
3094         dialog.set_default_response (RESPONSE_ACCEPT);
3095         dialog.set_position (WIN_POS_CENTER);
3096         message.show();
3097         image->show();
3098         hbox->show();
3099
3100         switch (dialog.run ()) {
3101         case RESPONSE_ACCEPT:
3102                 return 1;
3103         default:
3104                 return 0;
3105         }
3106 }
3107
3108 int
3109 ARDOUR_UI::sr_mismatch_dialog (nframes_t desired, nframes_t actual)
3110 {
3111         HBox* hbox = new HBox();
3112         Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG);
3113         ArdourDialog dialog (_("Sample Rate Mismatch"), true);
3114         Label  message (string_compose (_("\
3115 This session was created with a sample rate of %1 Hz\n\
3116 \n\
3117 The audioengine is currently running at %2 Hz\n"), desired, actual));
3118
3119         image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
3120         hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
3121         hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
3122         dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
3123         dialog.add_button (_("Do not load session"), RESPONSE_REJECT);
3124         dialog.add_button (_("Load session anyway"), RESPONSE_ACCEPT);
3125         dialog.set_default_response (RESPONSE_ACCEPT);
3126         dialog.set_position (WIN_POS_CENTER);
3127         message.show();
3128         image->show();
3129         hbox->show();
3130
3131         switch (dialog.run ()) {
3132         case RESPONSE_ACCEPT:
3133                 return 0;
3134         default:
3135                 return 1;
3136         }
3137 }
3138
3139         
3140 void
3141 ARDOUR_UI::disconnect_from_jack ()
3142 {
3143         if (engine) {
3144                 if( engine->disconnect_from_jack ()) {
3145                         MessageDialog msg (*editor, _("Could not disconnect from JACK"));
3146                         msg.run ();
3147                 }
3148
3149                 update_sample_rate (0);
3150         }
3151 }
3152
3153 void
3154 ARDOUR_UI::reconnect_to_jack ()
3155 {
3156         if (engine) {
3157                 if (engine->reconnect_to_jack ()) {
3158                         MessageDialog msg (*editor,  _("Could not reconnect to JACK"));
3159                         msg.run ();
3160                 }
3161
3162                 update_sample_rate (0);
3163         }
3164 }
3165
3166 void
3167 ARDOUR_UI::use_config ()
3168 {
3169         Glib::RefPtr<Action> act;
3170
3171         switch (Config->get_native_file_data_format ()) {
3172         case FormatFloat:
3173                 act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
3174                 break;
3175         case FormatInt24:
3176                 act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
3177                 break;
3178         case FormatInt16:
3179                 act = ActionManager::get_action (X_("options"), X_("FileDataFormat16bit"));
3180                 break;
3181         }
3182
3183         if (act) {
3184                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
3185                 ract->set_active ();
3186         }       
3187
3188         switch (Config->get_native_file_header_format ()) {
3189         case BWF:
3190                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
3191                 break;
3192         case WAVE:
3193                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
3194                 break;
3195         case WAVE64:
3196                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
3197                 break;
3198         case iXML:
3199                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
3200                 break;
3201         case RF64:
3202                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
3203                 break;
3204         case CAF:
3205                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatCAF"));
3206                 break;
3207         case AIFF:
3208                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatAIFF"));
3209                 break;
3210         }
3211
3212         if (act) {
3213                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
3214                 ract->set_active ();
3215         }       
3216
3217         XMLNode* node = Config->extra_xml (X_("TransportControllables"));
3218         if (node) {
3219                 set_transport_controllable_state (*node);
3220         }
3221 }
3222
3223 void
3224 ARDOUR_UI::update_transport_clocks (nframes_t pos)
3225 {
3226         if (Config->get_primary_clock_delta_edit_cursor()) {
3227                 primary_clock.set (pos, false, editor->get_preferred_edit_position(), 1);
3228         } else {
3229                 primary_clock.set (pos, 0, true);
3230         }
3231
3232         if (Config->get_secondary_clock_delta_edit_cursor()) {
3233                 secondary_clock.set (pos, false, editor->get_preferred_edit_position(), 2);
3234         } else {
3235                 secondary_clock.set (pos);
3236         }
3237
3238         if (big_clock_window) {
3239                 big_clock.set (pos);
3240         }
3241 }
3242
3243 void
3244 ARDOUR_UI::record_state_changed ()
3245 {
3246         ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::record_state_changed));
3247
3248         if (!session || !big_clock_window) {
3249                 /* why bother - the clock isn't visible */
3250                 return;
3251         }
3252
3253         switch (session->record_status()) {
3254         case Session::Recording:
3255                 big_clock.set_widget_name ("BigClockRecording");
3256                 break;
3257         default:
3258                 big_clock.set_widget_name ("BigClockNonRecording");
3259                 break;
3260         }
3261 }
3262
3263 bool
3264 ARDOUR_UI::first_idle ()
3265 {
3266         if (session) {
3267                 session->allow_auto_play (true);
3268         }
3269
3270         if (editor) {
3271                 editor->first_idle();
3272         }
3273
3274         Keyboard::set_can_save_keybindings (true);
3275         return false;
3276 }
3277
3278 void
3279 ARDOUR_UI::store_clock_modes ()
3280 {
3281         XMLNode* node = new XMLNode(X_("ClockModes"));
3282
3283         for (vector<AudioClock*>::iterator x = AudioClock::clocks.begin(); x != AudioClock::clocks.end(); ++x) {
3284                 node->add_property ((*x)->name().c_str(), enum_2_string ((*x)->mode()));
3285         }
3286
3287         session->add_extra_xml (*node);
3288         session->set_dirty ();
3289 }
3290
3291
3292                 
3293 ARDOUR_UI::TransportControllable::TransportControllable (std::string name, ARDOUR_UI& u, ToggleType tp)
3294         : Controllable (name), ui (u), type(tp)
3295 {
3296         
3297 }
3298
3299 void
3300 ARDOUR_UI::TransportControllable::set_value (float val)
3301 {
3302         if (type == ShuttleControl) {
3303                 double fract;
3304
3305                 if (val == 0.5f) {
3306                         fract = 0.0;
3307                 } else {
3308                         if (val < 0.5f) {
3309                                 fract = -((0.5f - val)/0.5f);
3310                         } else {
3311                                 fract = ((val - 0.5f)/0.5f);
3312                         }
3313                 }
3314                 
3315                 ui.set_shuttle_fract (fract);
3316                 return;
3317         }
3318
3319         if (val < 0.5f) {
3320                 /* do nothing: these are radio-style actions */
3321                 return;
3322         }
3323
3324         const char *action = 0;
3325
3326         switch (type) {
3327         case Roll:
3328                 action = X_("Roll");
3329                 break;
3330         case Stop:
3331                 action = X_("Stop");
3332                 break;
3333         case GotoStart:
3334                 action = X_("Goto Start");
3335                 break;
3336         case GotoEnd:
3337                 action = X_("Goto End");
3338                 break;
3339         case AutoLoop:
3340                 action = X_("Loop");
3341                 break;
3342         case PlaySelection:
3343                 action = X_("Play Selection");
3344                 break;
3345         case RecordEnable:
3346                 action = X_("Record");
3347                 break;
3348         default:
3349                 break;
3350         }
3351
3352         if (action == 0) {
3353                 return;
3354         }
3355
3356         Glib::RefPtr<Action> act = ActionManager::get_action ("Transport", action);
3357
3358         if (act) {
3359                 act->activate ();
3360         }
3361 }
3362
3363 float
3364 ARDOUR_UI::TransportControllable::get_value (void) const
3365 {
3366         float val = 0.0f;
3367         
3368         switch (type) {
3369         case Roll:
3370                 break;
3371         case Stop:
3372                 break;
3373         case GotoStart:
3374                 break;
3375         case GotoEnd:
3376                 break;
3377         case AutoLoop:
3378                 break;
3379         case PlaySelection:
3380                 break;
3381         case RecordEnable:
3382                 break;
3383         case ShuttleControl:
3384                 break;
3385         default:
3386                 break;
3387         }
3388
3389         return val;
3390 }
3391
3392 void
3393 ARDOUR_UI::TransportControllable::set_id (const string& str)
3394 {
3395         _id = str;
3396 }
3397
3398 void
3399 ARDOUR_UI::setup_profile ()
3400 {
3401         if (gdk_screen_width() < 1200) {
3402                 Profile->set_small_screen ();
3403         }
3404
3405         if (getenv ("ARDOUR_SAE")) {
3406                 Profile->set_sae ();
3407                 Profile->set_single_package ();
3408         }
3409 }
3410