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