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