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