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