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