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