a) moved metering and meter falloff code into libardour
[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/basename.h>
37 #include <pbd/pathscanner.h>
38 #include <pbd/failed_constructor.h>
39 #include <gtkmm2ext/gtk_ui.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 "color_manager.h"
76
77 #include "i18n.h"
78
79 using namespace ARDOUR;
80 using namespace Gtkmm2ext;
81 using namespace Gtk;
82 using namespace sigc;
83
84 ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
85
86 sigc::signal<void,bool> ARDOUR_UI::Blink;
87 sigc::signal<void>      ARDOUR_UI::RapidScreenUpdate;
88 sigc::signal<void>      ARDOUR_UI::SuperRapidScreenUpdate;
89 sigc::signal<void,jack_nframes_t> ARDOUR_UI::Clock;
90
91 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
92
93         : Gtkmm2ext::UI ("ardour", argcp, argvp, rcfile),
94           
95           primary_clock (X_("TransportClockDisplay"), true, false, true),
96           secondary_clock (X_("SecondaryClockDisplay"), true, false, true),
97           preroll_clock (X_("PreRollClock"), true, true),
98           postroll_clock (X_("PostRollClock"), true, true),
99
100           /* adjuster table */
101
102           adjuster_table (3, 3),
103
104           /* preroll stuff */
105
106           preroll_button (_("pre\nroll")),
107           postroll_button (_("post\nroll")),
108
109           /* big clock */
110
111           big_clock ("BigClockDisplay", true),
112
113           /* transport */
114
115           time_master_button (_("time\nmaster")),
116
117           shuttle_units_button (_("% ")),
118
119           punch_in_button (_("punch\nin")),
120           punch_out_button (_("punch\nout")),
121           auto_return_button (_("auto\nreturn")),
122           auto_play_button (_("auto\nplay")),
123           auto_input_button (_("auto\ninput")),
124           click_button (_("click")),
125           auditioning_alert_button (_("AUDITIONING")),
126           solo_alert_button (_("SOLO")),
127           shown_flag (false)
128
129 {
130         using namespace Gtk::Menu_Helpers;
131
132         Gtkmm2ext::init();
133         
134         about = 0;
135
136         if (theArdourUI == 0) {
137                 theArdourUI = this;
138         }
139
140         ActionManager::init ();
141
142         /* load colors */
143
144         color_manager = new ColorManager();
145
146         std::string color_file = ARDOUR::find_config_file("ardour.colors");
147         
148         color_manager->load (color_file);
149
150         m_new_session_dialog = 0;
151         m_new_session_dialog_ref = NewSessionDialogFactory::create();
152         m_new_session_dialog_ref->get_widget_derived (NewSessionDialogFactory::top_level_widget_name(), m_new_session_dialog);
153         editor = 0;
154         mixer = 0;
155         session = 0;
156         _session_is_new = false;
157         big_clock_window = 0;
158         session_selector_window = 0;
159         last_key_press_time = 0;
160         connection_editor = 0;
161         add_route_dialog = 0;
162         route_params = 0;
163         option_editor = 0;
164         location_ui = 0;
165         sfdb = 0;
166         open_session_selector = 0;
167         have_configure_timeout = false;
168         have_disk_overrun_displayed = false;
169         have_disk_underrun_displayed = false;
170         _will_create_new_session_automatically = false;
171         session_loaded = false;
172         last_speed_displayed = -1.0f;
173
174         last_configure_time.tv_sec = 0;
175         last_configure_time.tv_usec = 0;
176
177         shuttle_grabbed = false;
178         shuttle_fract = 0.0;
179         shuttle_max_speed = 8.0f;
180
181         set_shuttle_units (Percentage);
182         set_shuttle_behaviour (Sprung);
183
184         shuttle_style_menu = 0;
185         shuttle_unit_menu = 0;
186
187         gettimeofday (&last_peak_grab, 0);
188         gettimeofday (&last_shuttle_request, 0);
189
190         ARDOUR::DiskStream::CannotRecordNoInput.connect (mem_fun(*this, &ARDOUR_UI::cannot_record_no_input));
191         ARDOUR::DiskStream::DeleteSources.connect (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread));
192         ARDOUR::DiskStream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
193         ARDOUR::DiskStream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
194
195         /* handle pending state with a dialog */
196
197         ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
198
199         /* have to wait for AudioEngine and Configuration before proceeding */
200 }
201
202 void
203 ARDOUR_UI::cannot_record_no_input (DiskStream* ds)
204 {
205         ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::cannot_record_no_input), ds));
206         
207         string msg = string_compose (_("\
208 You cannot record-enable\n\
209 track %1\n\
210 because it has no input connections.\n\
211 You would be wasting space recording silence."),
212                               ds->name());
213
214         MessageDialog message (*editor, msg);
215         message.run ();
216 }
217
218 void
219 ARDOUR_UI::set_engine (AudioEngine& e)
220 {
221         engine = &e;
222
223         engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
224         engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
225         engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
226         engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
227
228         _tooltips.enable();
229
230         keyboard = new Keyboard;
231
232         string meter_path;
233
234         meter_path = ARDOUR::find_data_file("v_meter_strip.xpm", "pixmaps");
235         if (meter_path.empty()) {
236                 error << _("no vertical meter strip image found") << endmsg;
237                 exit (1);
238         }
239         FastMeter::set_vertical_xpm (meter_path);
240
241         meter_path = ARDOUR::find_data_file("h_meter_strip.xpm", "pixmaps");
242         if (meter_path.empty()) {
243                 error << _("no horizontal meter strip image found") << endmsg;
244                 exit (1);
245         }
246         FastMeter::set_horizontal_xpm (meter_path);
247
248         if (setup_windows ()) {
249                 throw failed_constructor ();
250         }
251
252         if (GTK_ARDOUR::show_key_actions) {
253                 vector<string> names;
254                 vector<string> paths;
255                 vector<string> keys;
256                 vector<AccelKey> bindings;
257
258                 ActionManager::get_all_actions (names, paths, keys, bindings);
259
260                 vector<string>::iterator n;
261                 vector<string>::iterator k;
262                 for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) {
263                         cerr << "Action: " << (*n) << " bound to " << (*k) << endl;
264                 }
265
266                 exit (0);
267         }
268
269         /* start with timecode, metering enabled
270         */
271         
272         blink_timeout_tag = -1;
273
274         /* the global configuration object is now valid */
275
276         use_config ();
277
278         /* this being a GUI and all, we want peakfiles */
279
280         FileSource::set_build_peakfiles (true);
281         FileSource::set_build_missing_peakfiles (true);
282
283         if (Source::start_peak_thread ()) {
284                 throw failed_constructor();
285         }
286
287         /* start the time-of-day-clock */
288         
289         update_wall_clock ();
290         Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
291
292         update_disk_space ();
293         update_cpu_load ();
294         update_sample_rate (engine->frame_rate());
295
296         starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
297         stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
298 }
299
300 ARDOUR_UI::~ARDOUR_UI ()
301 {
302         save_ardour_state ();
303
304         if (keyboard) {
305                 delete keyboard;
306         }
307
308         if (editor) {
309                 delete editor;
310         }
311
312         if (mixer) {
313                 delete mixer;
314         }
315
316         if (add_route_dialog) {
317                 delete add_route_dialog;
318         }
319
320         Source::stop_peak_thread ();
321 }
322
323 gint
324 ARDOUR_UI::configure_timeout ()
325 {
326         struct timeval now;
327         struct timeval diff;
328
329         if (last_configure_time.tv_sec == 0 && last_configure_time.tv_usec == 0) {
330                 /* no configure events yet */
331                 return TRUE;
332         }
333
334         gettimeofday (&now, 0);
335         timersub (&now, &last_configure_time, &diff);
336
337         /* force a gap of 0.5 seconds since the last configure event
338          */
339
340         if (diff.tv_sec == 0 && diff.tv_usec < 500000) {
341                 return TRUE;
342         } else {
343                 have_configure_timeout = false;
344                 save_ardour_state ();
345                 return FALSE;
346         }
347 }
348
349 gboolean
350 ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
351 {
352         if (have_configure_timeout) {
353                 gettimeofday (&last_configure_time, 0);
354         } else {
355                 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
356                 have_configure_timeout = true;
357         }
358                 
359         return FALSE;
360 }
361
362 void
363 ARDOUR_UI::save_ardour_state ()
364 {
365         if (!keyboard || !mixer || !editor) {
366                 return;
367         }
368         
369         /* XXX this is all a bit dubious. add_extra_xml() uses
370            a different lifetime model from add_instant_xml().
371         */
372
373         XMLNode* node = new XMLNode (keyboard->get_state());
374         Config->add_extra_xml (*node);
375         Config->save_state();
376
377         XMLNode& enode (static_cast<Stateful*>(editor)->get_state());
378         XMLNode& mnode (mixer->get_state());
379
380         if (session) {
381                 session->add_instant_xml(enode, session->path());
382                 session->add_instant_xml(mnode, session->path());
383         } else {
384                 Config->add_instant_xml(enode, get_user_ardour_path());
385                 Config->add_instant_xml(mnode, get_user_ardour_path());
386         }
387
388         /* keybindings */
389
390         AccelMap::save ("ardour.saved_bindings");
391 }
392
393 void
394 ARDOUR_UI::startup ()
395 {
396         /* Once the UI is up and running, start the audio engine. Doing
397            this before the UI is up and running can cause problems
398            when not running with SCHED_FIFO, because the amount of
399            CPU and disk work needed to get the UI started can interfere
400            with the scheduling of the audio thread.
401         */
402
403         Glib::signal_idle().connect (mem_fun(*this, &ARDOUR_UI::start_engine));
404 }
405
406 void
407 ARDOUR_UI::finish()
408 {
409         if (session && session->dirty()) {
410                 switch (ask_about_saving_session(_("quit"))) {
411                 case -1:
412                         return;
413                         break;
414                 case 1:
415                         /* use the default name */
416                         if (save_state_canfail ("")) {
417                                 /* failed - don't quit */
418                                 MessageDialog msg (*editor, 
419                                                _("\
420 Ardour was unable to save your session.\n\n\
421 If you still wish to quit, please use the\n\n\
422 \"Just quit\" option."));
423                                 msg.run ();
424                                 return;
425                         }
426                         break;
427                 case 0:
428                         break;
429                 }
430         }
431
432         quit ();
433 }
434
435 int
436 ARDOUR_UI::ask_about_saving_session (const string & what)
437 {
438         ArdourDialog window (_("ardour: save session?"));
439         Gtk::Label  prompt_label;
440         string msg;
441
442         msg = string_compose(_("Save and %1"), what);
443         window.add_button (msg, RESPONSE_ACCEPT);
444         msg = string_compose(_("Just %1"), what);
445         window.add_button (msg, RESPONSE_APPLY);
446         msg = string_compose(_("Don't %1"), what);
447         window.add_button (msg, RESPONSE_REJECT);
448
449         Gtk::Button noquit_button (msg);
450         noquit_button.set_name ("EditorGTKButton");
451
452         string prompt;
453         string type;
454
455         if (session->snap_name() == session->name()) {
456                 type = _("session");
457         } else {
458                 type = _("snapshot");
459         }
460         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?"), 
461                          type, session->snap_name());
462         
463         prompt_label.set_text (prompt);
464         prompt_label.set_alignment (0.5, 0.5);
465         prompt_label.set_name (X_("PrompterLabel"));
466         
467         window.get_vbox()->pack_start (prompt_label);
468
469         window.set_name (_("Prompter"));
470         window.set_position (Gtk::WIN_POS_MOUSE);
471         window.set_modal (true);
472         window.show_all ();
473
474         save_the_session = 0;
475
476         editor->ensure_float (window);
477
478         ResponseType r = (ResponseType) window.run();
479
480         window.hide ();
481
482         switch (r) {
483         case RESPONSE_ACCEPT: // save and get out of here
484                 return 1;
485         case RESPONSE_APPLY:  // get out of here
486                 return 0;
487         default:
488                 break;
489         }
490
491         return -1;
492 }
493         
494 gint
495 ARDOUR_UI::every_second ()
496 {
497         update_cpu_load ();
498         update_buffer_load ();
499         update_disk_space ();
500         return TRUE;
501 }
502
503 gint
504 ARDOUR_UI::every_point_one_seconds ()
505 {
506         update_speed_display ();
507         RapidScreenUpdate(); /* EMIT_SIGNAL */
508         return TRUE;
509 }
510
511 gint
512 ARDOUR_UI::every_point_zero_one_seconds ()
513 {
514         SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
515         return TRUE;
516 }
517
518 void
519 ARDOUR_UI::update_sample_rate (jack_nframes_t ignored)
520 {
521         char buf[32];
522
523         ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
524
525         if (!engine->connected()) {
526
527                 snprintf (buf, sizeof (buf), _("disconnected"));
528
529         } else {
530
531                 jack_nframes_t rate = engine->frame_rate();
532                 
533                 if (fmod (rate, 1000.0) != 0.0) {
534                         snprintf (buf, sizeof (buf), _("SR: %.1f kHz / %4.1f msecs"), 
535                                   (float) rate/1000.0f,
536                                   (engine->frames_per_cycle() / (float) rate) * 1000.0f);
537                 } else {
538                         snprintf (buf, sizeof (buf), _("SR: %u kHz / %4.1f msecs"), 
539                                   rate/1000,
540                                   (engine->frames_per_cycle() / (float) rate) * 1000.0f);
541                 }
542         }
543
544         sample_rate_label.set_text (buf);
545 }
546
547 void
548 ARDOUR_UI::update_cpu_load ()
549 {
550         char buf[32];
551         snprintf (buf, sizeof (buf), _("DSP Load: %.1f%%"), engine->get_cpu_load());
552         cpu_load_label.set_text (buf);
553 }
554
555 void
556 ARDOUR_UI::update_buffer_load ()
557 {
558         char buf[64];
559
560         if (session) {
561                 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"), 
562                           session->playback_load(), session->capture_load());
563                 buffer_load_label.set_text (buf);
564         } else {
565                 buffer_load_label.set_text ("");
566         }
567 }
568
569 void
570 ARDOUR_UI::count_recenabled_diskstreams (DiskStream& ds)
571 {
572         if (ds.record_enabled()) {
573                 rec_enabled_diskstreams++;
574         }
575 }
576
577 void
578 ARDOUR_UI::update_disk_space()
579 {
580         if (session == 0) {
581                 return;
582         }
583
584         jack_nframes_t frames = session->available_capture_duration();
585         char buf[64];
586
587         if (frames == max_frames) {
588                 strcpy (buf, _("space: 24hrs+"));
589         } else {
590                 int hrs;
591                 int mins;
592                 int secs;
593                 jack_nframes_t fr = session->frame_rate();
594                 
595                 if (session->actively_recording()){
596                         
597                         rec_enabled_diskstreams = 0;
598                         session->foreach_diskstream (this, &ARDOUR_UI::count_recenabled_diskstreams);
599                         
600                         if (rec_enabled_diskstreams) {
601                                 frames /= rec_enabled_diskstreams;
602                         }
603                         
604                 } else {
605                         
606                         /* hmmm. shall we divide by the route count? or the diskstream count?
607                            or what? for now, do nothing ...
608                         */
609                         
610                 }
611                 
612                 hrs  = frames / (fr * 3600);
613                 frames -= hrs * fr * 3600;
614                 mins = frames / (fr * 60);
615                 frames -= mins * fr * 60;
616                 secs = frames / fr;
617                 
618                 snprintf (buf, sizeof(buf), _("space: %02dh:%02dm:%02ds"), hrs, mins, secs);
619         }
620
621         disk_space_label.set_text (buf);
622 }                 
623
624 gint
625 ARDOUR_UI::update_wall_clock ()
626 {
627         time_t now;
628         struct tm *tm_now;
629         char buf[16];
630
631         time (&now);
632         tm_now = localtime (&now);
633
634         sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
635         wall_clock_label.set_text (buf);
636
637         return TRUE;
638 }
639 void
640 ARDOUR_UI::control_methods_adjusted ()
641
642 {
643         int which_method;
644
645         which_method = (int) online_control_button->adjustment.get_value();
646         switch (which_method) {
647         case 0:
648                 allow_mmc_and_local ();
649                 break;
650         case 1:
651                 allow_mmc_only ();
652                 break;
653         case 2:
654                 allow_local_only ();
655                 break;
656         default:
657                 fatal << _("programming error: impossible control method") << endmsg;
658         }
659 }
660         
661
662 void
663 ARDOUR_UI::mmc_device_id_adjusted ()
664
665 {
666 #if 0
667         if (mmc) {
668                 int dev_id = (int) mmc_id_button->adjustment.get_value();
669                 mmc->set_device_id (dev_id);
670         }
671 #endif
672 }
673
674 gint
675 ARDOUR_UI::session_menu (GdkEventButton *ev)
676 {
677         session_popup_menu->popup (0, 0);
678         return TRUE;
679 }
680
681 void
682 ARDOUR_UI::redisplay_recent_sessions ()
683 {
684         vector<string *> *sessions;
685         vector<string *>::iterator i;
686         RecentSessionsSorter cmp;
687         
688         recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
689         recent_session_model->clear ();
690
691         RecentSessions rs;
692         ARDOUR::read_recent_sessions (rs);
693
694         if (rs.empty()) {
695                 recent_session_display.set_model (recent_session_model);
696                 return;
697         }
698
699         /* sort them alphabetically */
700         sort (rs.begin(), rs.end(), cmp);
701         sessions = new vector<string*>;
702
703         for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
704                 sessions->push_back (new string ((*i).second));
705         }
706
707         for (i = sessions->begin(); i != sessions->end(); ++i) {
708
709                 vector<string*>* states;
710                 vector<const gchar*> item;
711                 string fullpath = *(*i);
712                 
713                 /* remove any trailing / */
714
715                 if (fullpath[fullpath.length()-1] == '/') {
716                         fullpath = fullpath.substr (0, fullpath.length()-1);
717                 }
718
719                 /* now get available states for this session */
720
721                 if ((states = Session::possible_states (fullpath)) == 0) {
722                         /* no state file? */
723                         continue;
724                 }
725
726                 TreeModel::Row row = *(recent_session_model->append());
727
728                 row[recent_session_columns.visible_name] = PBD::basename (fullpath);
729                 row[recent_session_columns.fullpath] = fullpath;
730
731                 if (states->size() > 1) {
732
733                         /* add the children */
734                         
735                         for (vector<string*>::iterator i2 = states->begin(); i2 != states->end(); ++i2) {
736                                 
737                                 TreeModel::Row child_row = *(recent_session_model->append (row.children()));
738
739                                 child_row[recent_session_columns.visible_name] = **i2;
740                                 child_row[recent_session_columns.fullpath] = fullpath;
741
742                                 delete *i2;
743                         }
744                 }
745
746                 delete states;
747         }
748
749         recent_session_display.set_model (recent_session_model);
750         delete sessions;
751 }
752
753 void
754 ARDOUR_UI::build_session_selector ()
755 {
756         session_selector_window = new ArdourDialog ("session selector");
757         
758         Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
759         
760         session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
761         session_selector_window->add_button (Stock::OK, RESPONSE_ACCEPT);
762
763         recent_session_model = TreeStore::create (recent_session_columns);
764         recent_session_display.set_model (recent_session_model);
765         recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
766         recent_session_display.set_headers_visible (false);
767         recent_session_display.get_selection()->set_mode (SELECTION_SINGLE);
768
769         recent_session_display.signal_row_activated().connect (mem_fun (*this, &ARDOUR_UI::recent_session_row_activated));
770
771         scroller->add (recent_session_display);
772         scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
773
774         session_selector_window->set_name ("SessionSelectorWindow");
775         session_selector_window->set_size_request (200, 400);
776         session_selector_window->get_vbox()->pack_start (*scroller);
777         session_selector_window->show_all_children();
778 }
779
780 void
781 ARDOUR_UI::recent_session_row_activated (const TreePath& path, TreeViewColumn* col)
782 {
783         session_selector_window->response (RESPONSE_ACCEPT);
784 }
785
786 void
787 ARDOUR_UI::open_recent_session ()
788 {
789         /* popup selector window */
790
791         if (session_selector_window == 0) {
792                 build_session_selector ();
793         }
794
795         redisplay_recent_sessions ();
796
797         ResponseType r = (ResponseType) session_selector_window->run ();
798
799         session_selector_window->hide();
800
801         switch (r) {
802         case RESPONSE_ACCEPT:
803                 break;
804         default:
805                 return;
806         }
807
808         Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
809
810         if (i == recent_session_model->children().end()) {
811                 return;
812         }
813         
814         Glib::ustring path = (*i)[recent_session_columns.fullpath];
815         Glib::ustring state = (*i)[recent_session_columns.visible_name];
816
817         _session_is_new = false;
818
819         load_session (path, state);
820 }
821
822 bool
823 ARDOUR_UI::filter_ardour_session_dirs (const FileFilter::Info& info) 
824 {
825         struct stat statbuf;
826
827         if (stat (info.filename.c_str(), &statbuf) != 0) {
828                 return false;
829         }
830
831         if (!S_ISDIR(statbuf.st_mode)) {
832                 return false;
833         }
834
835         string session_file = info.filename;
836         session_file += '/';
837         session_file += PBD::basename (info.filename);
838         session_file += ".ardour";
839         
840         if (stat (session_file.c_str(), &statbuf) != 0) {
841                 return false;
842         }
843
844         return S_ISREG (statbuf.st_mode);
845 }
846
847 void
848 ARDOUR_UI::open_session ()
849 {
850         /* popup selector window */
851
852         if (open_session_selector == 0) {
853
854                 /* ardour sessions are folders */
855
856                 open_session_selector = new Gtk::FileChooserDialog (_("open session"), FILE_CHOOSER_ACTION_OPEN);
857                 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
858                 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
859
860                 FileFilter session_filter;
861                 session_filter.add_pattern ("*.ardour");
862                 session_filter.set_name (_("Ardour sessions"));
863                 open_session_selector->add_filter (session_filter);
864                 open_session_selector->set_filter (session_filter);
865         }
866
867         int response = open_session_selector->run();
868         open_session_selector->hide ();
869
870         switch (response) {
871         case RESPONSE_ACCEPT:
872                 break;
873         default:
874                 open_session_selector->hide();
875                 return;
876         }
877
878         open_session_selector->hide();
879         string session_path = open_session_selector->get_filename();
880         string path, name;
881         bool isnew;
882
883         if (session_path.length() > 0) {
884                 if (Session::find_session (session_path, path, name, isnew) == 0) {
885                         _session_is_new = isnew;
886                         load_session (path, name);
887                 }
888         }
889 }
890
891
892 void
893 ARDOUR_UI::session_add_midi_track ()
894 {
895         cerr << _("Patience is a virtue.\n");
896 }
897
898 void
899 ARDOUR_UI::session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode)
900 {
901         Route* route;
902
903         if (session == 0) {
904                 warning << _("You cannot add a track without a session already loaded.") << endmsg;
905                 return;
906         }
907
908         try { 
909                 if (disk) {
910                         if ((route = session->new_audio_track (input_channels, output_channels, mode)) == 0) {
911                                 error << _("could not create new audio track") << endmsg;
912                         }
913                 } else {
914                         if ((route = session->new_audio_route (input_channels, output_channels)) == 0) {
915                                 error << _("could not create new audio bus") << endmsg;
916                         }
917                 }
918                 
919 #if CONTROLOUTS
920                 if (need_control_room_outs) {
921                         pan_t pans[2];
922                         
923                         pans[0] = 0.5;
924                         pans[1] = 0.5;
925                         
926                         route->set_stereo_control_outs (control_lr_channels);
927                         route->control_outs()->set_stereo_pan (pans, this);
928                 }
929 #endif /* CONTROLOUTS */
930         }
931
932         catch (...) {
933                 MessageDialog msg (*editor, 
934                                    _("There are insufficient JACK ports available\n\
935 to create a new track or bus.\n\
936 You should save Ardour, exit and\n\
937 restart JACK with more ports."));
938                 msg.run ();
939         }
940 }
941
942 void
943 ARDOUR_UI::diskstream_added (DiskStream* ds)
944 {
945 }
946
947 void
948 ARDOUR_UI::do_transport_locate (jack_nframes_t new_position)
949 {
950         jack_nframes_t _preroll;
951
952         if (session) {
953                 _preroll = session->convert_to_frames_at (new_position, session->preroll);
954
955                 if (new_position > _preroll) {
956                         new_position -= _preroll;
957                 } else {
958                         new_position = 0;
959                 }
960
961                 session->request_locate (new_position);
962         }
963 }
964
965 void
966 ARDOUR_UI::transport_goto_start ()
967 {
968         if (session) {
969                 session->goto_start();
970
971                 
972                 /* force displayed area in editor to start no matter
973                    what "follow playhead" setting is.
974                 */
975                 
976                 if (editor) {
977                         editor->reposition_x_origin (session->current_start_frame());
978                 }
979         }
980 }
981
982 void
983 ARDOUR_UI::transport_goto_zero ()
984 {
985         if (session) {
986                 session->request_locate (0);
987
988                 
989                 /* force displayed area in editor to start no matter
990                    what "follow playhead" setting is.
991                 */
992                 
993                 if (editor) {
994                         editor->reposition_x_origin (0);
995                 }
996         }
997 }
998
999 void
1000 ARDOUR_UI::transport_goto_end ()
1001 {
1002         if (session) {
1003                 jack_nframes_t frame = session->current_end_frame();
1004                 session->request_locate (frame);
1005
1006                 /* force displayed area in editor to start no matter
1007                    what "follow playhead" setting is.
1008                 */
1009                 
1010                 if (editor) {
1011                         editor->reposition_x_origin (frame);
1012                 }
1013         }
1014 }
1015
1016 void
1017 ARDOUR_UI::transport_stop ()
1018 {
1019         if (!session) {
1020                 return;
1021         }
1022
1023         if (session->is_auditioning()) {
1024                 session->cancel_audition ();
1025                 return;
1026         }
1027         
1028         if (session->get_auto_loop()) {
1029                 session->request_auto_loop (false);
1030         }
1031         
1032         session->request_stop ();
1033 }
1034
1035 void
1036 ARDOUR_UI::transport_stop_and_forget_capture ()
1037 {
1038         if (session) {
1039                 session->request_stop (true);
1040         }
1041 }
1042
1043 void
1044 ARDOUR_UI::remove_last_capture()
1045 {
1046         if (editor) {
1047                 editor->remove_last_capture();
1048         }
1049 }
1050
1051 void
1052 ARDOUR_UI::transport_record ()
1053 {
1054         if (session) {
1055                 switch (session->record_status()) {
1056                 case Session::Disabled:
1057                         if (session->ntracks() == 0) {
1058                                 string txt = _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu.");
1059                                 MessageDialog msg (*editor, txt);
1060                                 msg.run ();
1061                                 return;
1062                         }
1063                         session->maybe_enable_record ();
1064                         break;
1065                 case Session::Recording:
1066                 case Session::Enabled:
1067                         session->disable_record (true);
1068                 }
1069         }
1070 }
1071
1072 void
1073 ARDOUR_UI::transport_roll ()
1074 {
1075         bool rolling;
1076
1077         if (!session) {
1078                 return;
1079         }
1080
1081         rolling = session->transport_rolling ();
1082
1083         if (session->get_auto_loop()) {
1084                 session->request_auto_loop (false);
1085                 auto_loop_button.set_active (false);
1086                 roll_button.set_active (true);
1087         } else if (session->get_play_range ()) {
1088                 session->request_play_range (false);
1089                 play_selection_button.set_active (false);
1090         } else if (rolling) {
1091                 session->request_locate (session->last_transport_start(), true);
1092         }
1093
1094         session->request_transport_speed (1.0f);
1095 }
1096
1097 void
1098 ARDOUR_UI::transport_loop()
1099 {
1100         if (session) {
1101                 if (session->get_auto_loop()) {
1102                         if (session->transport_rolling()) {
1103                                 Location * looploc = session->locations()->auto_loop_location();
1104                                 if (looploc) {
1105                                         session->request_locate (looploc->start(), true);
1106                                 }
1107                         }
1108                 }
1109                 else {
1110                         session->request_auto_loop (true);
1111                 }
1112         }
1113 }
1114
1115 void
1116 ARDOUR_UI::transport_play_selection ()
1117 {
1118         if (!session) {
1119                 return;
1120         }
1121
1122         if (!session->get_play_range()) {
1123                 session->request_stop ();
1124         }
1125
1126         editor->play_selection ();
1127 }
1128
1129 void
1130 ARDOUR_UI::transport_rewind (int option)
1131 {
1132         float current_transport_speed;
1133  
1134         if (session) {
1135                 current_transport_speed = session->transport_speed();
1136                 
1137                 if (current_transport_speed >= 0.0f) {
1138                         switch (option) {
1139                         case 0:
1140                                 session->request_transport_speed (-1.0f);
1141                                 break;
1142                         case 1:
1143                                 session->request_transport_speed (-4.0f);
1144                                 break;
1145                         case -1:
1146                                 session->request_transport_speed (-0.5f);
1147                                 break;
1148                         }
1149                 } else {
1150                         /* speed up */
1151                         session->request_transport_speed (current_transport_speed * 1.5f);
1152                 }
1153         }
1154 }
1155
1156 void
1157 ARDOUR_UI::transport_forward (int option)
1158 {
1159         float current_transport_speed;
1160         
1161         if (session) {
1162                 current_transport_speed = session->transport_speed();
1163                 
1164                 if (current_transport_speed <= 0.0f) {
1165                         switch (option) {
1166                         case 0:
1167                                 session->request_transport_speed (1.0f);
1168                                 break;
1169                         case 1:
1170                                 session->request_transport_speed (4.0f);
1171                                 break;
1172                         case -1:
1173                                 session->request_transport_speed (0.5f);
1174                                 break;
1175                         }
1176                 } else {
1177                         /* speed up */
1178                         session->request_transport_speed (current_transport_speed * 1.5f);
1179                 }
1180         }
1181 }
1182
1183 void
1184 ARDOUR_UI::toggle_monitor_enable (guint32 dstream)
1185 {
1186         if (session == 0) {
1187                 return;
1188         }
1189
1190         DiskStream *ds;
1191
1192         if ((ds = session->diskstream_by_id (dstream)) != 0) {
1193                 Port *port = ds->io()->input (0);
1194                 port->request_monitor_input (!port->monitoring_input());
1195         }
1196 }
1197
1198 void
1199 ARDOUR_UI::toggle_record_enable (guint32 dstream)
1200 {
1201         if (session == 0) {
1202                 return;
1203         }
1204
1205         DiskStream *ds;
1206
1207         if ((ds = session->diskstream_by_id (dstream)) != 0) {
1208                 ds->set_record_enabled (!ds->record_enabled(), this);
1209         }
1210 }
1211
1212 void
1213 ARDOUR_UI::queue_transport_change ()
1214 {
1215         Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
1216 }
1217
1218 void
1219 ARDOUR_UI::map_transport_state ()
1220 {
1221         float sp = session->transport_speed();
1222
1223         if (sp == 1.0f) {
1224                 transport_rolling ();
1225         } else if (sp < 0.0f) {
1226                 transport_rewinding ();
1227         } else if (sp > 0.0f) {
1228                 transport_forwarding ();
1229         } else {
1230                 transport_stopped ();
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"), 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"), 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                 return 1;
2249         default:
2250                 return 0;
2251         }
2252 }
2253         
2254 void
2255 ARDOUR_UI::disconnect_from_jack ()
2256 {
2257         if (engine) {
2258                 if( engine->disconnect_from_jack ()) {
2259                         MessageDialog msg (*editor, _("Could not disconnect from JACK"));
2260                         msg.run ();
2261                 }
2262
2263                 update_sample_rate (0);
2264         }
2265 }
2266
2267 void
2268 ARDOUR_UI::reconnect_to_jack ()
2269 {
2270         if (engine) {
2271                 if (engine->reconnect_to_jack ()) {
2272                         MessageDialog msg (*editor,  _("Could not reconnect to JACK"));
2273                         msg.run ();
2274                 }
2275
2276                 update_sample_rate (0);
2277         }
2278 }
2279
2280 void
2281 ARDOUR_UI::set_jack_buffer_size (jack_nframes_t nframes)
2282 {
2283         engine->request_buffer_size (nframes);
2284         update_sample_rate (0);
2285 }
2286
2287 int
2288 ARDOUR_UI::cmdline_new_session (string path)
2289 {
2290         if (path[0] != '/') {
2291                 char buf[PATH_MAX+1];
2292                 string str;
2293
2294                 getcwd (buf, sizeof (buf));
2295                 str = buf;
2296                 str += '/';
2297                 str += path;
2298                 path = str;
2299         }
2300
2301         new_session (false, path);
2302
2303         _will_create_new_session_automatically = false; /* done it */
2304         return FALSE; /* don't call it again */
2305 }
2306
2307 void
2308 ARDOUR_UI::set_native_file_header_format (HeaderFormat hf)
2309 {
2310         Glib::RefPtr<Action> act;
2311         
2312         switch (hf) {
2313         case BWF:
2314                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
2315                 break;
2316         case WAVE:
2317                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
2318                 break;
2319         case WAVE64:
2320                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
2321                 break;
2322         case iXML:
2323                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
2324                 break;
2325         case RF64:
2326                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
2327                 break;
2328         }
2329
2330         if (act) {
2331                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2332                 if (ract && ract->get_active() && Config->get_native_file_header_format() != hf) {
2333                         Config->set_native_file_header_format (hf);
2334                         if (session) {
2335                                 session->reset_native_file_format ();
2336                         }
2337                 }
2338         }
2339 }
2340
2341 void
2342 ARDOUR_UI::set_native_file_data_format (SampleFormat sf)
2343 {
2344         Glib::RefPtr<Action> act;
2345         
2346         switch (sf) {
2347         case FormatFloat:
2348                 act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
2349                 break;
2350         case FormatInt24:
2351                 act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
2352                 break;
2353         }
2354
2355         if (act) {
2356                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2357
2358                 if (ract && ract->get_active() && Config->get_native_file_data_format() != sf) {
2359                         Config->set_native_file_data_format (sf);
2360                         if (session) {
2361                                 session->reset_native_file_format ();
2362                         }
2363                 }
2364         }
2365 }
2366
2367 void
2368 ARDOUR_UI::use_config ()
2369 {
2370         Glib::RefPtr<Action> act;
2371
2372         switch (Config->get_native_file_data_format ()) {
2373         case FormatFloat:
2374                 act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
2375                 break;
2376         case FormatInt24:
2377                 act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
2378                 break;
2379         }
2380
2381         if (act) {
2382                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2383                 ract->set_active ();
2384         }       
2385
2386         switch (Config->get_native_file_header_format ()) {
2387         case BWF:
2388                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
2389                 break;
2390         case WAVE:
2391                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
2392                 break;
2393         case WAVE64:
2394                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
2395                 break;
2396         case iXML:
2397                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
2398                 break;
2399         case RF64:
2400                 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
2401                 break;
2402         }
2403
2404         if (act) {
2405                 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2406                 ract->set_active ();
2407         }       
2408 }