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