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