Allow to inhibit screensaver/system sleep
[ardour.git] / gtk2_ardour / ardour_ui.cc
1 /*
2  * Copyright (C) 2005-2007 Doug McLain <doug@nostar.net>
3  * Copyright (C) 2005-2017 Tim Mayberry <mojofunk@gmail.com>
4  * Copyright (C) 2005-2019 Paul Davis <paul@linuxaudiosystems.com>
5  * Copyright (C) 2005 Karsten Wiese <fzuuzf@googlemail.com>
6  * Copyright (C) 2005 Taybin Rutkin <taybin@taybin.com>
7  * Copyright (C) 2006-2015 David Robillard <d@drobilla.net>
8  * Copyright (C) 2007-2012 Carl Hetherington <carl@carlh.net>
9  * Copyright (C) 2008-2010 Sakari Bergen <sakari.bergen@beatwaves.net>
10  * Copyright (C) 2012-2019 Robin Gareus <robin@gareus.org>
11  * Copyright (C) 2013-2015 Colin Fletcher <colin.m.fletcher@googlemail.com>
12  * Copyright (C) 2013-2016 John Emmas <john@creativepost.co.uk>
13  * Copyright (C) 2013-2016 Nick Mainsbridge <mainsbridge@gmail.com>
14  * Copyright (C) 2014-2018 Ben Loftis <ben@harrisonconsoles.com>
15  * Copyright (C) 2015 AndrĂ© Nusser <andre.nusser@googlemail.com>
16  * Copyright (C) 2016-2018 Len Ovens <len@ovenwerks.net>
17  * Copyright (C) 2017 Johannes Mueller <github@johannes-mueller.org>
18  *
19  * This program is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 2 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License along
30  * with this program; if not, write to the Free Software Foundation, Inc.,
31  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32  */
33
34 #ifdef WAF_BUILD
35 #include "gtk2ardour-config.h"
36 #include "gtk2ardour-version.h"
37 #endif
38
39 #include <algorithm>
40 #include <cmath>
41 #include <iostream>
42 #include <cerrno>
43
44 #include <stdarg.h>
45
46 #ifndef PLATFORM_WINDOWS
47 #include <sys/resource.h>
48 #endif
49
50 #ifdef __FreeBSD__
51 #include <sys/types.h>
52 #include <sys/sysctl.h>
53 #endif
54
55 #include <stdint.h>
56 #include <fcntl.h>
57 #include <signal.h>
58 #include <unistd.h>
59 #include <time.h>
60
61 #include <glib.h>
62 #include "pbd/gstdio_compat.h"
63
64 #include <gtkmm/accelmap.h>
65 #include <gtkmm/messagedialog.h>
66 #include <gtkmm/stock.h>
67 #include <gtkmm/uimanager.h>
68
69 #include "pbd/error.h"
70 #include "pbd/basename.h"
71 #include "pbd/compose.h"
72 #include "pbd/convert.h"
73 #include "pbd/failed_constructor.h"
74 #include "pbd/file_archive.h"
75 #include "pbd/enumwriter.h"
76 #include "pbd/memento_command.h"
77 #include "pbd/openuri.h"
78 #include "pbd/stl_delete.h"
79 #include "pbd/types_convert.h"
80 #include "pbd/unwind.h"
81 #include "pbd/file_utils.h"
82 #include "pbd/localtime_r.h"
83 #include "pbd/pthread_utils.h"
84 #include "pbd/replace_all.h"
85 #include "pbd/scoped_file_descriptor.h"
86 #include "pbd/xml++.h"
87
88 #include "gtkmm2ext/application.h"
89 #include "gtkmm2ext/bindings.h"
90 #include "gtkmm2ext/gtk_ui.h"
91 #include "gtkmm2ext/utils.h"
92 #include "gtkmm2ext/window_title.h"
93
94 #include "widgets/fastmeter.h"
95 #include "widgets/prompter.h"
96 #include "widgets/tooltips.h"
97
98 #include "ardour/ardour.h"
99 #include "ardour/audio_backend.h"
100 #include "ardour/audio_track.h"
101 #include "ardour/audioengine.h"
102 #include "ardour/audiofilesource.h"
103 #include "ardour/automation_watch.h"
104 #include "ardour/disk_reader.h"
105 #include "ardour/disk_writer.h"
106 #include "ardour/filename_extensions.h"
107 #include "ardour/filesystem_paths.h"
108 #include "ardour/ltc_file_reader.h"
109 #include "ardour/monitor_control.h"
110 #include "ardour/midi_track.h"
111 #include "ardour/port.h"
112 #include "ardour/plugin_manager.h"
113 #include "ardour/process_thread.h"
114 #include "ardour/profile.h"
115 #include "ardour/recent_sessions.h"
116 #include "ardour/record_enable_control.h"
117 #include "ardour/revision.h"
118 #include "ardour/session_directory.h"
119 #include "ardour/session_route.h"
120 #include "ardour/session_state_utils.h"
121 #include "ardour/session_utils.h"
122 #include "ardour/source_factory.h"
123 #include "ardour/transport_master.h"
124 #include "ardour/transport_master_manager.h"
125 #include "ardour/system_exec.h"
126 #include "ardour/track.h"
127 #include "ardour/vca_manager.h"
128 #include "ardour/utils.h"
129
130 #include "LuaBridge/LuaBridge.h"
131
132 #ifdef WINDOWS_VST_SUPPORT
133 #include <fst.h>
134 #endif
135 #ifdef AUDIOUNIT_SUPPORT
136 #include "ardour/audio_unit.h"
137 #endif
138
139 // fix for OSX (nsm.h has a check function, AU/Apple defines check)
140 #ifdef check
141 #undef check
142 #endif
143
144 #include "temporal/time.h"
145
146 typedef uint64_t microseconds_t;
147
148 #include "about.h"
149 #include "editing.h"
150 #include "enums_convert.h"
151 #include "actions.h"
152 #include "add_route_dialog.h"
153 #include "ambiguous_file_dialog.h"
154 #include "ardour_ui.h"
155 #include "audio_clock.h"
156 #include "audio_region_view.h"
157 #include "big_clock_window.h"
158 #include "big_transport_window.h"
159 #include "bundle_manager.h"
160 #include "duplicate_routes_dialog.h"
161 #include "debug.h"
162 #include "engine_dialog.h"
163 #include "export_video_dialog.h"
164 #include "export_video_infobox.h"
165 #include "gain_meter.h"
166 #include "global_port_matrix.h"
167 #include "gui_object.h"
168 #include "gui_thread.h"
169 #include "idleometer.h"
170 #include "keyboard.h"
171 #include "keyeditor.h"
172 #include "location_ui.h"
173 #include "lua_script_manager.h"
174 #include "luawindow.h"
175 #include "main_clock.h"
176 #include "missing_file_dialog.h"
177 #include "missing_plugin_dialog.h"
178 #include "mixer_ui.h"
179 #include "meterbridge.h"
180 #include "meter_patterns.h"
181 #include "mouse_cursors.h"
182 #include "nsm.h"
183 #include "opts.h"
184 #include "pingback.h"
185 #include "plugin_dspload_window.h"
186 #include "processor_box.h"
187 #include "public_editor.h"
188 #include "rc_option_editor.h"
189 #include "route_time_axis.h"
190 #include "route_params_ui.h"
191 #include "save_as_dialog.h"
192 #include "save_template_dialog.h"
193 #include "script_selector.h"
194 #include "session_archive_dialog.h"
195 #include "session_dialog.h"
196 #include "session_metadata_dialog.h"
197 #include "session_option_editor.h"
198 #include "speaker_dialog.h"
199 #include "splash.h"
200 #include "startup.h"
201 #include "template_dialog.h"
202 #include "time_axis_view_item.h"
203 #include "time_info_box.h"
204 #include "timers.h"
205 #include "transport_masters_dialog.h"
206 #include "utils.h"
207 #include "utils_videotl.h"
208 #include "video_server_dialog.h"
209 #include "add_video_dialog.h"
210 #include "transcode_video_dialog.h"
211
212 #include "pbd/i18n.h"
213
214 using namespace ARDOUR;
215 using namespace ARDOUR_UI_UTILS;
216 using namespace PBD;
217 using namespace Gtkmm2ext;
218 using namespace ArdourWidgets;
219 using namespace Gtk;
220 using namespace std;
221 using namespace Editing;
222
223 ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
224
225 sigc::signal<void, samplepos_t> ARDOUR_UI::Clock;
226 sigc::signal<void> ARDOUR_UI::CloseAllDialogs;
227
228 static bool
229 ask_about_configuration_copy (string const & old_dir, string const & new_dir, int version)
230 {
231         MessageDialog msg (string_compose (_("%1 %2.x has discovered configuration files from %1 %3.x.\n\n"
232                                              "Would you like these files to be copied and used for %1 %2.x?\n\n"
233                                              "(This will require you to restart %1.)"),
234                                            PROGRAM_NAME, PROGRAM_VERSION, version),
235                            false, /* no markup */
236                            Gtk::MESSAGE_INFO,
237                            Gtk::BUTTONS_YES_NO,
238                            true /* modal, though it hardly matters since it is the only window */
239         );
240
241         msg.set_default_response (Gtk::RESPONSE_YES);
242         msg.show_all ();
243
244         return (msg.run() == Gtk::RESPONSE_YES);
245 }
246
247 static void
248 libxml_generic_error_func (void* /* parsing_context*/,
249                            const char* msg,
250                            ...)
251 {
252         va_list ap;
253         char buf[2048];
254
255         va_start (ap, msg);
256         vsnprintf (buf, sizeof (buf), msg, ap);
257         error << buf << endmsg;
258         va_end (ap);
259 }
260
261 static void
262 libxml_structured_error_func (void* /* parsing_context*/,
263                               xmlErrorPtr err)
264 {
265         string msg;
266
267         if (err->message)
268                 msg = err->message;
269
270         replace_all (msg, "\n", "");
271
272         if (!msg.empty()) {
273                 if (err->file && err->line) {
274                         error << X_("XML error: ") << msg << " in " << err->file << " at line " << err->line;
275
276                         if (err->int2) {
277                                 error << ':' << err->int2;
278                         }
279
280                         error << endmsg;
281                 } else {
282                         error << X_("XML error: ") << msg << endmsg;
283                 }
284         }
285 }
286
287
288 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
289         : Gtkmm2ext::UI (PROGRAM_NAME, X_("gui"), argcp, argvp)
290         , session_load_in_progress (false)
291         , gui_object_state (new GUIObjectState)
292         , primary_clock   (new MainClock (X_("primary"),   X_("transport"), true ))
293         , secondary_clock (new MainClock (X_("secondary"), X_("secondary"), false))
294         , big_clock (new AudioClock (X_("bigclock"), false, "big", true, true, false, false))
295         , video_timeline(0)
296         , ignore_dual_punch (false)
297         , main_window_visibility (0)
298         , editor (0)
299         , mixer (0)
300         , nsm (0)
301         , _was_dirty (false)
302         , _mixer_on_top (false)
303         , _initial_verbose_plugin_scan (false)
304         , _shared_popup_menu (0)
305         , secondary_clock_spacer (0)
306         , auto_input_button (ArdourButton::led_default_elements)
307         , time_info_box (0)
308         , auto_return_button (ArdourButton::led_default_elements)
309         , follow_edits_button (ArdourButton::led_default_elements)
310         , auditioning_alert_button (_("Audition"))
311         , solo_alert_button (_("Solo"))
312         , feedback_alert_button (_("Feedback"))
313         , error_alert_button ( ArdourButton::just_led_default_elements )
314         , editor_meter_peak_display()
315         , editor_meter(0)
316         , _numpad_locate_happening (false)
317         , _session_is_new (false)
318         , last_key_press_time (0)
319         , save_as_dialog (0)
320         , meterbridge (0)
321         , luawindow (0)
322         , rc_option_editor (0)
323         , speaker_config_window (X_("speaker-config"), _("Speaker Configuration"))
324         , add_route_dialog (X_("add-routes"), _("Add Tracks/Busses"))
325         , about (X_("about"), _("About"))
326         , location_ui (X_("locations"), S_("Ranges|Locations"))
327         , route_params (X_("inspector"), _("Tracks and Busses"))
328         , audio_midi_setup (X_("audio-midi-setup"), _("Audio/MIDI Setup"))
329         , export_video_dialog (X_("video-export"), _("Video Export Dialog"))
330         , lua_script_window (X_("script-manager"), _("Script Manager"))
331         , idleometer (X_("idle-o-meter"), _("Idle'o'Meter"))
332         , plugin_dsp_load_window (X_("plugin-dsp-load"), _("Plugin DSP Load"))
333         , transport_masters_window (X_("transport-masters"), _("Transport Masters"))
334         , session_option_editor (X_("session-options-editor"), _("Properties"), boost::bind (&ARDOUR_UI::create_session_option_editor, this))
335         , add_video_dialog (X_("add-video"), _("Add Video"), boost::bind (&ARDOUR_UI::create_add_video_dialog, this))
336         , bundle_manager (X_("bundle-manager"), _("Bundle Manager"), boost::bind (&ARDOUR_UI::create_bundle_manager, this))
337         , big_clock_window (X_("big-clock"), _("Big Clock"), boost::bind (&ARDOUR_UI::create_big_clock_window, this))
338         , big_transport_window (X_("big-transport"), _("Transport Controls"), boost::bind (&ARDOUR_UI::create_big_transport_window, this))
339         , audio_port_matrix (X_("audio-connection-manager"), _("Audio Connections"), boost::bind (&ARDOUR_UI::create_global_port_matrix, this, ARDOUR::DataType::AUDIO))
340         , midi_port_matrix (X_("midi-connection-manager"), _("MIDI Connections"), boost::bind (&ARDOUR_UI::create_global_port_matrix, this, ARDOUR::DataType::MIDI))
341         , key_editor (X_("key-editor"), _("Keyboard Shortcuts"), boost::bind (&ARDOUR_UI::create_key_editor, this))
342         , video_server_process (0)
343         , splash (0)
344         , have_configure_timeout (false)
345         , last_configure_time (0)
346         , last_peak_grab (0)
347         , have_disk_speed_dialog_displayed (false)
348         , _status_bar_visibility (X_("status-bar"))
349         , _feedback_exists (false)
350         , _log_not_acknowledged (LogLevelNone)
351         , duplicate_routes_dialog (0)
352         , editor_visibility_button (S_("Window|Editor"))
353         , mixer_visibility_button (S_("Window|Mixer"))
354         , prefs_visibility_button (S_("Window|Preferences"))
355 {
356         Gtkmm2ext::init (localedir);
357
358         UIConfiguration::instance().post_gui_init ();
359
360         if (ARDOUR::handle_old_configuration_files (boost::bind (ask_about_configuration_copy, _1, _2, _3))) {
361                 {
362                         /* "touch" the been-here-before path now that config has been migrated */
363                         PBD::ScopedFileDescriptor fout (g_open (been_here_before_path ().c_str(), O_CREAT|O_TRUNC|O_RDWR, 0666));
364                 }
365                 MessageDialog msg (string_compose (_("Your configuration files were copied. You can now restart %1."), PROGRAM_NAME), true);
366                 msg.run ();
367                 /* configuration was modified, exit immediately */
368                 _exit (EXIT_SUCCESS);
369         }
370
371
372         if (string (VERSIONSTRING).find (".pre") != string::npos) {
373                 /* check this is not being run from ./ardev etc. */
374                 if (!running_from_source_tree ()) {
375                         pre_release_dialog ();
376                 }
377         }
378
379         if (theArdourUI == 0) {
380                 theArdourUI = this;
381         }
382
383         /* track main window visibility */
384
385         main_window_visibility = new VisibilityTracker (_main_window);
386
387         /* stop libxml from spewing to stdout/stderr */
388
389         xmlSetGenericErrorFunc (this, libxml_generic_error_func);
390         xmlSetStructuredErrorFunc (this, libxml_structured_error_func);
391
392         /* Set this up early */
393
394         ActionManager::init ();
395
396         /* we like keyboards */
397
398         keyboard = new ArdourKeyboard(*this);
399
400         XMLNode* node = ARDOUR_UI::instance()->keyboard_settings();
401         if (node) {
402                 keyboard->set_state (*node, Stateful::loading_state_version);
403         }
404
405         /* actions do not need to be defined when we load keybindings. They
406          * will be lazily discovered. But bindings do need to exist when we
407          * create windows/tabs with their own binding sets.
408          */
409
410         keyboard->setup_keybindings ();
411
412         if ((global_bindings = Bindings::get_bindings (X_("Global"))) == 0) {
413                 error << _("Global keybindings are missing") << endmsg;
414         }
415
416         install_actions ();
417
418         UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &ARDOUR_UI::parameter_changed));
419         boost::function<void (string)> pc (boost::bind (&ARDOUR_UI::parameter_changed, this, _1));
420         UIConfiguration::instance().map_parameters (pc);
421
422         transport_ctrl.setup (this);
423
424         ARDOUR::DiskWriter::Overrun.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::disk_overrun_handler, this), gui_context());
425         ARDOUR::DiskReader::Underrun.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::disk_underrun_handler, this), gui_context());
426
427         ARDOUR::Session::VersionMismatch.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_format_mismatch, this, _1, _2), gui_context());
428
429         /* handle dialog requests */
430
431         ARDOUR::Session::Dialog.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_dialog, this, _1), gui_context());
432
433         /* handle pending state with a dialog (PROBLEM: needs to return a value and thus cannot be x-thread) */
434
435         ARDOUR::Session::AskAboutPendingState.connect_same_thread (forever_connections, boost::bind (&ARDOUR_UI::pending_state_dialog, this));
436
437         /* handle Audio/MIDI setup when session requires it */
438
439         ARDOUR::Session::AudioEngineSetupRequired.connect_same_thread (forever_connections, boost::bind (&ARDOUR_UI::do_audio_midi_setup, this, _1));
440
441         /* handle sr mismatch with a dialog (PROBLEM: needs to return a value and thus cannot be x-thread) */
442
443         ARDOUR::Session::AskAboutSampleRateMismatch.connect_same_thread (forever_connections, boost::bind (&ARDOUR_UI::sr_mismatch_dialog, this, _1, _2));
444
445         /* handle sr mismatch with a dialog - cross-thread from engine */
446         ARDOUR::Session::NotifyAboutSampleRateMismatch.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::sr_mismatch_message, this, _1, _2), gui_context ());
447
448         /* handle requests to quit (coming from JACK session) */
449
450         ARDOUR::Session::Quit.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::finish, this), gui_context ());
451
452         /* tell the user about feedback */
453
454         ARDOUR::Session::FeedbackDetected.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::feedback_detected, this), gui_context ());
455         ARDOUR::Session::SuccessfulGraphSort.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::successful_graph_sort, this), gui_context ());
456
457         /* handle requests to deal with missing files */
458
459         ARDOUR::Session::MissingFile.connect_same_thread (forever_connections, boost::bind (&ARDOUR_UI::missing_file, this, _1, _2, _3));
460
461         /* and ambiguous files */
462
463         ARDOUR::FileSource::AmbiguousFileName.connect_same_thread (forever_connections, boost::bind (&ARDOUR_UI::ambiguous_file, this, _1, _2));
464
465         /* also plugin scan messages */
466         ARDOUR::PluginScanMessage.connect (forever_connections, MISSING_INVALIDATOR, boost::bind(&ARDOUR_UI::plugin_scan_dialog, this, _1, _2, _3), gui_context());
467         ARDOUR::PluginScanTimeout.connect (forever_connections, MISSING_INVALIDATOR, boost::bind(&ARDOUR_UI::plugin_scan_timeout, this, _1), gui_context());
468
469         ARDOUR::GUIIdle.connect (forever_connections, MISSING_INVALIDATOR, boost::bind(&ARDOUR_UI::gui_idle_handler, this), gui_context());
470
471         Config->ParameterChanged.connect ( forever_connections, MISSING_INVALIDATOR, boost::bind(&ARDOUR_UI::set_flat_buttons, this), gui_context() );
472         set_flat_buttons();
473
474         /* lets get this party started */
475
476         setup_gtk_ardour_enums ();
477         setup_profile ();
478
479         SessionEvent::create_per_thread_pool ("GUI", 4096);
480
481         UIConfiguration::instance().reset_dpi ();
482
483         TimeAxisViewItem::set_constant_heights ();
484
485         /* The following must happen after ARDOUR::init() so that Config is set up */
486
487         const XMLNode* ui_xml = Config->extra_xml (X_("UI"));
488
489         if (ui_xml) {
490                 key_editor.set_state (*ui_xml, 0);
491                 session_option_editor.set_state (*ui_xml, 0);
492                 speaker_config_window.set_state (*ui_xml, 0);
493                 about.set_state (*ui_xml, 0);
494                 add_route_dialog.set_state (*ui_xml, 0);
495                 add_video_dialog.set_state (*ui_xml, 0);
496                 route_params.set_state (*ui_xml, 0);
497                 bundle_manager.set_state (*ui_xml, 0);
498                 location_ui.set_state (*ui_xml, 0);
499                 big_clock_window.set_state (*ui_xml, 0);
500                 big_transport_window.set_state (*ui_xml, 0);
501                 audio_port_matrix.set_state (*ui_xml, 0);
502                 midi_port_matrix.set_state (*ui_xml, 0);
503                 export_video_dialog.set_state (*ui_xml, 0);
504                 lua_script_window.set_state (*ui_xml, 0);
505                 idleometer.set_state (*ui_xml, 0);
506                 plugin_dsp_load_window.set_state (*ui_xml, 0);
507                 transport_masters_window.set_state (*ui_xml, 0);
508         }
509
510         /* Separate windows */
511
512         WM::Manager::instance().register_window (&key_editor);
513         WM::Manager::instance().register_window (&session_option_editor);
514         WM::Manager::instance().register_window (&speaker_config_window);
515         WM::Manager::instance().register_window (&about);
516         WM::Manager::instance().register_window (&add_route_dialog);
517         WM::Manager::instance().register_window (&add_video_dialog);
518         WM::Manager::instance().register_window (&route_params);
519         WM::Manager::instance().register_window (&audio_midi_setup);
520         WM::Manager::instance().register_window (&export_video_dialog);
521         WM::Manager::instance().register_window (&lua_script_window);
522         WM::Manager::instance().register_window (&bundle_manager);
523         WM::Manager::instance().register_window (&location_ui);
524         WM::Manager::instance().register_window (&big_clock_window);
525         WM::Manager::instance().register_window (&big_transport_window);
526         WM::Manager::instance().register_window (&audio_port_matrix);
527         WM::Manager::instance().register_window (&midi_port_matrix);
528         WM::Manager::instance().register_window (&idleometer);
529         WM::Manager::instance().register_window (&plugin_dsp_load_window);
530         WM::Manager::instance().register_window (&transport_masters_window);
531
532         /* do not retain position for add route dialog */
533         add_route_dialog.set_state_mask (WindowProxy::Size);
534
535         /* Trigger setting up the color scheme and loading the GTK RC file */
536
537         UIConfiguration::instance().load_rc_file (false);
538
539         _process_thread = new ProcessThread ();
540         _process_thread->init ();
541
542         UIConfiguration::instance().DPIReset.connect (sigc::mem_fun (*this, &ARDOUR_UI::resize_text_widgets));
543
544         attach_to_engine ();
545 }
546
547 void
548 ARDOUR_UI::pre_release_dialog ()
549 {
550         ArdourDialog d (_("Pre-Release Warning"), true, false);
551         d.add_button (Gtk::Stock::OK, Gtk::RESPONSE_OK);
552
553         Label* label = manage (new Label);
554         label->set_markup (string_compose (_("<b>Welcome to this pre-release build of %1 %2</b>\n\n\
555 There are still several issues and bugs to be worked on,\n\
556 as well as general workflow improvements, before this can be considered\n\
557 release software. So, a few guidelines:\n\
558 \n\
559 1) Please do <b>NOT</b> use this software with the expectation that it is stable or reliable\n\
560    though it may be so, depending on your workflow.\n\
561 2) Please wait for a helpful writeup of new features.\n\
562 3) <b>Please do NOT use the forums at ardour.org to report issues</b>.\n\
563 4) <b>Please do NOT file bugs for this alpha-development versions at this point in time</b>.\n\
564    There is no bug triaging before the initial development concludes and\n\
565    reporting issue for incomplete, ongoing work-in-progress is mostly useless.\n\
566 5) Please <b>DO</b> join us on IRC for real time discussions about %1 %2. You\n\
567    can get there directly from within the program via the Help->Chat menu option.\n\
568 6) Please <b>DO</b> submit patches for issues after discussing them on IRC.\n\
569 \n\
570 Full information on all the above can be found on the support page at\n\
571 \n\
572                 http://ardour.org/support\n\
573 "), PROGRAM_NAME, VERSIONSTRING));
574
575         d.get_vbox()->set_border_width (12);
576         d.get_vbox()->pack_start (*label, false, false, 12);
577         d.get_vbox()->show_all ();
578
579         d.run ();
580 }
581
582 GlobalPortMatrixWindow*
583 ARDOUR_UI::create_global_port_matrix (ARDOUR::DataType type)
584 {
585         if (!_session) {
586                 return 0;
587         }
588         return new GlobalPortMatrixWindow (_session, type);
589 }
590
591 void
592 ARDOUR_UI::attach_to_engine ()
593 {
594         AudioEngine::instance()->Running.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::engine_running, this, _1), gui_context());
595         ARDOUR::Port::set_connecting_blocked (ARDOUR_COMMAND_LINE::no_connect_ports);
596 }
597
598 void
599 ARDOUR_UI::engine_stopped ()
600 {
601         ENSURE_GUI_THREAD (*this, &ARDOUR_UI::engine_stopped)
602         ActionManager::set_sensitive (ActionManager::engine_sensitive_actions, false);
603         ActionManager::set_sensitive (ActionManager::engine_opposite_sensitive_actions, true);
604         update_sample_rate (0);
605         update_cpu_load ();
606 }
607
608 void
609 ARDOUR_UI::engine_running (uint32_t cnt)
610 {
611         if (cnt == 0) {
612                 post_engine();
613         }
614
615         if (_session) {
616                 _session->reset_xrun_count ();
617         }
618         update_disk_space ();
619         update_cpu_load ();
620         update_sample_rate (AudioEngine::instance()->sample_rate());
621         update_timecode_format ();
622         update_peak_thread_work ();
623         ActionManager::set_sensitive (ActionManager::engine_sensitive_actions, true);
624         ActionManager::set_sensitive (ActionManager::engine_opposite_sensitive_actions, false);
625 }
626
627 void
628 ARDOUR_UI::engine_halted (const char* reason, bool free_reason)
629 {
630         if (!Gtkmm2ext::UI::instance()->caller_is_ui_thread()) {
631                 /* we can't rely on the original string continuing to exist when we are called
632                    again in the GUI thread, so make a copy and note that we need to
633                    free it later.
634                 */
635                 char *copy = strdup (reason);
636                 Gtkmm2ext::UI::instance()->call_slot (MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::engine_halted, this, copy, true));
637                 return;
638         }
639
640         ActionManager::set_sensitive (ActionManager::engine_sensitive_actions, false);
641         ActionManager::set_sensitive (ActionManager::engine_opposite_sensitive_actions, true);
642
643         update_sample_rate (0);
644
645         string msgstr;
646
647         /* if the reason is a non-empty string, it means that the backend was shutdown
648            rather than just Ardour.
649         */
650
651         if (strlen (reason)) {
652                 msgstr = string_compose (_("The audio backend was shutdown because:\n\n%1"), reason);
653         } else {
654                 msgstr = string_compose (_("\
655 The audio backend has either been shutdown or it\n\
656 disconnected %1 because %1\n\
657 was not fast enough. Try to restart\n\
658 the audio backend and save the session."), PROGRAM_NAME);
659         }
660
661         MessageDialog msg (_main_window, msgstr);
662         pop_back_splash (msg);
663         msg.run ();
664
665         if (free_reason) {
666                 free (const_cast<char*> (reason));
667         }
668 }
669
670 void
671 ARDOUR_UI::post_engine ()
672 {
673         /* Things to be done once (and once ONLY) after we have a backend running in the AudioEngine
674          */
675 #ifdef AUDIOUNIT_SUPPORT
676         std::string au_msg;
677         if (AUPluginInfo::au_get_crashlog(au_msg)) {
678                 popup_error(_("Audio Unit Plugin Scan Failed. Automatic AU scanning has been disabled. Please see the log window for further details."));
679                 error << _("Audio Unit Plugin Scan Failed:") << endmsg;
680                 info << au_msg << endmsg;
681         }
682 #endif
683
684         /* connect to important signals */
685
686         AudioEngine::instance()->Stopped.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::engine_stopped, this), gui_context());
687         AudioEngine::instance()->SampleRateChanged.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::update_sample_rate, this, _1), gui_context());
688         AudioEngine::instance()->BufferSizeChanged.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::update_sample_rate, this, _1), gui_context());
689         AudioEngine::instance()->Halted.connect_same_thread (halt_connection, boost::bind (&ARDOUR_UI::engine_halted, this, _1, false));
690         AudioEngine::instance()->BecameSilent.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::audioengine_became_silent, this), gui_context());
691
692         if (setup_windows ()) {
693                 throw failed_constructor ();
694         }
695
696         transport_ctrl.map_actions ();
697
698         /* Do this after setup_windows (), as that's when the _status_bar_visibility is created */
699         XMLNode* n = Config->extra_xml (X_("UI"));
700         if (n) {
701                 _status_bar_visibility.set_state (*n);
702         }
703
704         check_memory_locking();
705
706         /* this is the first point at which all the possible actions are
707          * available, because some of the available actions are dependent on
708          * aspects of the engine/backend.
709          */
710
711         if (ARDOUR_COMMAND_LINE::show_key_actions) {
712                 stringstream sstr;
713                 Bindings::save_all_bindings_as_html (sstr);
714
715                 if (sstr.str().empty()) {
716                         return;
717                 }
718                 gchar* file_name;
719                 GError *err = NULL;
720                 gint fd;
721
722                 if ((fd = g_file_open_tmp ("akprintXXXXXX.html", &file_name, &err)) < 0) {
723                         if (err) {
724                                 error << string_compose (_("Could not open temporary file to print bindings (%1)"), err->message) << endmsg;
725                                 g_error_free (err);
726                         }
727                         return;
728                 }
729
730 #ifdef PLATFORM_WINDOWS
731                 ::close (fd);
732 #endif
733
734                 err = NULL;
735
736                 if (!g_file_set_contents (file_name, sstr.str().c_str(), sstr.str().size(), &err)) {
737 #ifndef PLATFORM_WINDOWS
738                         ::close (fd);
739 #endif
740                         g_unlink (file_name);
741                         if (err) {
742                                 error << string_compose (_("Could not save bindings to file (%1)"), err->message) << endmsg;
743                                 g_error_free (err);
744                         }
745                         return;
746                 }
747
748 #ifndef PLATFORM_WINDOWS
749                 ::close (fd);
750 #endif
751
752                 PBD::open_uri (string_compose ("file:///%1", file_name));
753
754                 halt_connection.disconnect ();
755                 AudioEngine::instance()->stop ();
756                 exit (EXIT_SUCCESS);
757
758         }
759
760         if (ARDOUR_COMMAND_LINE::show_actions) {
761
762
763                 vector<string> paths;
764                 vector<string> labels;
765                 vector<string> tooltips;
766                 vector<string> keys;
767                 vector<Glib::RefPtr<Gtk::Action> > actions;
768                 string ver_in = revision;
769                 string ver = ver_in.substr(0, ver_in.find("-"));
770
771                 stringstream output;
772                 output << "\n<h2>Menu actions</h2>" << endl;
773                 output << "<p>\n  Every single menu item in " << PROGRAM_NAME << "'s GUI is accessible by control" << endl;
774                 output << "  surfaces or scripts.\n</p>\n" << endl;
775                 output << "<p>\n  The list below shows all available values of <em>action-name</em> as of" << endl;
776                 output << "  " << PROGRAM_NAME << " " << ver << ". You can get the current list at any" << endl;
777                 output << "  time by running " << PROGRAM_NAME << " with the -A flag.\n</p>\n" << endl;
778                 output << "<table class=\"dl\">\n  <thead>" << endl;
779                 output << "      <tr><th>Action Name</th><th>Menu Name</th></tr>" << endl;
780                 output << "  </thead>\n  <tbody>" << endl;
781
782                 ActionManager::get_all_actions (paths, labels, tooltips, keys, actions);
783
784                 vector<string>::iterator p;
785                 vector<string>::iterator l;
786
787                 for (p = paths.begin(), l = labels.begin(); p != paths.end(); ++p, ++l) {
788                         output << " <tr><th><kbd class=\"osc\">" << *p << "</kbd></th><td>" << *l << "</td></tr>" << endl;
789                 }
790                 output << "  </tbody>\n  </table>" << endl;
791
792                 // output this mess to a browser for easiest X-platform use
793                 // it is not pretty HTML, but it works and it's main purpose
794                 // is to create raw html to fit in Ardour's manual with no editing
795                 gchar* file_name;
796                 GError *err = NULL;
797                 gint fd;
798
799                 if ((fd = g_file_open_tmp ("list-of-menu-actionsXXXXXX.html", &file_name, &err)) < 0) {
800                         if (err) {
801                                 error << string_compose (_("Could not open temporary file to print bindings (%1)"), err->message) << endmsg;
802                                 g_error_free (err);
803                         }
804                         return;
805                 }
806
807 #ifdef PLATFORM_WINDOWS
808                 ::close (fd);
809 #endif
810
811                 err = NULL;
812
813                 if (!g_file_set_contents (file_name, output.str().c_str(), output.str().size(), &err)) {
814 #ifndef PLATFORM_WINDOWS
815                         ::close (fd);
816 #endif
817                         g_unlink (file_name);
818                         if (err) {
819                                 error << string_compose (_("Could not save bindings to file (%1)"), err->message) << endmsg;
820                                 g_error_free (err);
821                         }
822                         return;
823                 }
824
825 #ifndef PLATFORM_WINDOWS
826                 ::close (fd);
827 #endif
828
829                 PBD::open_uri (string_compose ("file:///%1", file_name));
830
831                 halt_connection.disconnect ();
832                 AudioEngine::instance()->stop ();
833                 exit (EXIT_SUCCESS);
834         }
835
836         /* this being a GUI and all, we want peakfiles */
837
838         AudioFileSource::set_build_peakfiles (true);
839         AudioFileSource::set_build_missing_peakfiles (true);
840
841         /* set default clock modes */
842
843         primary_clock->set_mode (AudioClock::Timecode);
844         secondary_clock->set_mode (AudioClock::BBT);
845
846         /* start the time-of-day-clock */
847
848 #ifndef __APPLE__
849         /* OS X provides a nearly-always visible wallclock, so don't be stupid */
850         update_wall_clock ();
851         Glib::signal_timeout().connect_seconds (sigc::mem_fun(*this, &ARDOUR_UI::update_wall_clock), 1);
852 #endif
853
854         {
855                 DisplaySuspender ds;
856                 Config->ParameterChanged.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::parameter_changed, this, _1), gui_context());
857                 boost::function<void (string)> pc (boost::bind (&ARDOUR_UI::parameter_changed, this, _1));
858                 Config->map_parameters (pc);
859
860                 UIConfiguration::instance().map_parameters (pc);
861         }
862 }
863
864 ARDOUR_UI::~ARDOUR_UI ()
865 {
866         UIConfiguration::instance().save_state();
867
868         ARDOUR_UI_UTILS::inhibit_screensaver (false);
869
870         stop_video_server();
871
872         if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
873                 // don't bother at 'real' exit. the OS cleans up for us.
874                 delete big_clock; big_clock = 0;
875                 delete primary_clock; primary_clock = 0;
876                 delete secondary_clock; secondary_clock = 0;
877                 delete _process_thread; _process_thread = 0;
878                 delete time_info_box; time_info_box = 0;
879                 delete meterbridge; meterbridge = 0;
880                 delete luawindow; luawindow = 0;
881                 delete editor; editor = 0;
882                 delete mixer; mixer = 0;
883                 delete rc_option_editor; rc_option_editor = 0; // failed to wrap object warning
884                 delete nsm; nsm = 0;
885                 delete gui_object_state; gui_object_state = 0;
886                 delete _shared_popup_menu ; _shared_popup_menu = 0;
887                 delete main_window_visibility;
888                 FastMeter::flush_pattern_cache ();
889                 ArdourFader::flush_pattern_cache ();
890         }
891
892 #ifndef NDEBUG
893         /* Small trick to flush main-thread event pool.
894          * Other thread-pools are destroyed at pthread_exit(),
895          * but tmain thread termination is too late to trigger Pool::~Pool()
896          */
897         SessionEvent* ev = new SessionEvent (SessionEvent::SetTransportSpeed, SessionEvent::Clear, SessionEvent::Immediate, 0, 0); // get the pool reference, values don't matter since the event is never queued.
898         delete ev->event_pool();
899 #endif
900 }
901
902 void
903 ARDOUR_UI::pop_back_splash (Gtk::Window& win)
904 {
905         if (Splash::instance()) {
906                 Splash::instance()->pop_back_for (win);
907         }
908 }
909
910 gint
911 ARDOUR_UI::configure_timeout ()
912 {
913         if (last_configure_time == 0) {
914                 /* no configure events yet */
915                 return true;
916         }
917
918         /* force a gap of 0.5 seconds since the last configure event
919          */
920
921         if (get_microseconds() - last_configure_time < 500000) {
922                 return true;
923         } else {
924                 have_configure_timeout = false;
925                 save_ardour_state ();
926                 return false;
927         }
928 }
929
930 gboolean
931 ARDOUR_UI::configure_handler (GdkEventConfigure* /*conf*/)
932 {
933         if (have_configure_timeout) {
934                 last_configure_time = get_microseconds();
935         } else {
936                 Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
937                 have_configure_timeout = true;
938         }
939
940         return FALSE;
941 }
942
943 void
944 ARDOUR_UI::set_transport_controllable_state (const XMLNode& node)
945 {
946         std::string str;
947
948         if (node.get_property ("roll", str)){
949                 roll_controllable->set_id (str);
950         }
951         if (node.get_property ("stop", str)) {
952                 stop_controllable->set_id (str);
953         }
954         if (node.get_property ("goto-start", str)) {
955                 goto_start_controllable->set_id (str);
956         }
957         if (node.get_property ("goto-end", str)) {
958                 goto_end_controllable->set_id (str);
959         }
960         if (node.get_property ("auto-loop", str)) {
961                 auto_loop_controllable->set_id (str);
962         }
963         if (node.get_property ("play-selection", str)) {
964                 play_selection_controllable->set_id (str);
965         }
966         if (node.get_property ("rec", str)) {
967                 rec_controllable->set_id (str);
968         }
969         if (node.get_property ("shuttle", str)) {
970                 shuttle_box.controllable()->set_id (str);
971         }
972 }
973
974 XMLNode&
975 ARDOUR_UI::get_transport_controllable_state ()
976 {
977         XMLNode* node = new XMLNode(X_("TransportControllables"));
978
979         node->set_property (X_("roll"), roll_controllable->id());
980         node->set_property (X_("stop"), stop_controllable->id());
981         node->set_property (X_("goto-start"), goto_start_controllable->id());
982         node->set_property (X_("goto-end"), goto_end_controllable->id());
983         node->set_property (X_("auto-loop"), auto_loop_controllable->id());
984         node->set_property (X_("play-selection"), play_selection_controllable->id());
985         node->set_property (X_("rec"), rec_controllable->id());
986         node->set_property (X_("shuttle"), shuttle_box.controllable()->id());
987
988         return *node;
989 }
990
991 void
992 ARDOUR_UI::save_session_at_its_request (std::string snapshot_name)
993 {
994         if (_session) {
995                 _session->save_state (snapshot_name);
996         }
997 }
998
999 gint
1000 ARDOUR_UI::autosave_session ()
1001 {
1002         if (g_main_depth() > 1) {
1003                 /* inside a recursive main loop,
1004                    give up because we may not be able to
1005                    take a lock.
1006                 */
1007                 return 1;
1008         }
1009
1010         if (!Config->get_periodic_safety_backups()) {
1011                 return 1;
1012         }
1013
1014         if (_session) {
1015                 _session->maybe_write_autosave();
1016         }
1017
1018         return 1;
1019 }
1020
1021 void
1022 ARDOUR_UI::session_dirty_changed ()
1023 {
1024         update_autosave ();
1025         update_title ();
1026 }
1027
1028 void
1029 ARDOUR_UI::update_autosave ()
1030 {
1031         if (_session && _session->dirty()) {
1032                 if (_autosave_connection.connected()) {
1033                         _autosave_connection.disconnect();
1034                 }
1035
1036                 _autosave_connection = Glib::signal_timeout().connect (sigc::mem_fun (*this, &ARDOUR_UI::autosave_session),
1037                                 Config->get_periodic_safety_backup_interval() * 1000);
1038
1039         } else {
1040                 if (_autosave_connection.connected()) {
1041                         _autosave_connection.disconnect();
1042                 }
1043         }
1044 }
1045
1046 void
1047 ARDOUR_UI::check_announcements ()
1048 {
1049 #ifdef PHONE_HOME
1050         string _annc_filename;
1051
1052 #ifdef __APPLE__
1053         _annc_filename = PROGRAM_NAME "_announcements_osx_";
1054 #elif defined PLATFORM_WINDOWS
1055         _annc_filename = PROGRAM_NAME "_announcements_windows_";
1056 #else
1057         _annc_filename = PROGRAM_NAME "_announcements_linux_";
1058 #endif
1059         _annc_filename.append (VERSIONSTRING);
1060
1061         _announce_string = "";
1062
1063         std::string path = Glib::build_filename (user_config_directory(), _annc_filename);
1064         FILE* fin = g_fopen (path.c_str(), "rb");
1065         if (fin) {
1066                 while (!feof (fin)) {
1067                         char tmp[1024];
1068                         size_t len;
1069                         if ((len = fread (tmp, sizeof(char), 1024, fin)) == 0 || ferror (fin)) {
1070                                 break;
1071                         }
1072                         _announce_string.append (tmp, len);
1073                 }
1074                 fclose (fin);
1075         }
1076
1077         pingback (VERSIONSTRING, path);
1078 #endif
1079 }
1080
1081 static bool
1082 _hide_splash (gpointer arg)
1083 {
1084         ((ARDOUR_UI*)arg)->hide_splash();
1085         return false;
1086 }
1087
1088 int
1089 ARDOUR_UI::starting ()
1090 {
1091         Application* app = Application::instance ();
1092         const char *nsm_url;
1093         bool brand_new_user = ArdourStartup::required ();
1094
1095         app->ShouldQuit.connect (sigc::mem_fun (*this, &ARDOUR_UI::queue_finish));
1096         app->ShouldLoad.connect (sigc::mem_fun (*this, &ARDOUR_UI::load_from_application_api));
1097
1098         if (ARDOUR_COMMAND_LINE::check_announcements) {
1099                 check_announcements ();
1100         }
1101
1102         app->ready ();
1103
1104         /* we need to create this early because it may need to set the
1105          *  audio backend end up.
1106          */
1107
1108         try {
1109                 audio_midi_setup.get (true);
1110         } catch (...) {
1111                 std::cerr << "audio-midi engine setup failed."<< std::endl;
1112                 return -1;
1113         }
1114
1115         if ((nsm_url = g_getenv ("NSM_URL")) != 0) {
1116                 nsm = new NSM_Client;
1117                 if (!nsm->init (nsm_url)) {
1118                         /* the ardour executable may have different names:
1119                          *
1120                          * waf's obj.target for distro versions: eg ardour4, ardourvst4
1121                          * Ardour4, Mixbus3 for bundled versions + full path on OSX & windows
1122                          * argv[0] does not apply since we need the wrapper-script (not the binary itself)
1123                          *
1124                          * The wrapper startup script should set the environment variable 'ARDOUR_SELF'
1125                          */
1126                         const char *process_name = g_getenv ("ARDOUR_SELF");
1127                         nsm->announce (PROGRAM_NAME, ":dirty:", process_name ? process_name : "ardour6");
1128
1129                         unsigned int i = 0;
1130                         // wait for announce reply from nsm server
1131                         for ( i = 0; i < 5000; ++i) {
1132                                 nsm->check ();
1133
1134                                 Glib::usleep (i);
1135                                 if (nsm->is_active()) {
1136                                         break;
1137                                 }
1138                         }
1139                         if (i == 5000) {
1140                                 error << _("NSM server did not announce itself") << endmsg;
1141                                 return -1;
1142                         }
1143                         // wait for open command from nsm server
1144                         for ( i = 0; i < 5000; ++i) {
1145                                 nsm->check ();
1146                                 Glib::usleep (1000);
1147                                 if (nsm->client_id ()) {
1148                                         break;
1149                                 }
1150                         }
1151
1152                         if (i == 5000) {
1153                                 error << _("NSM: no client ID provided") << endmsg;
1154                                 return -1;
1155                         }
1156
1157                         if (_session && nsm) {
1158                                 _session->set_nsm_state( nsm->is_active() );
1159                         } else {
1160                                 error << _("NSM: no session created") << endmsg;
1161                                 return -1;
1162                         }
1163
1164                         // nsm requires these actions disabled
1165                         vector<string> action_names;
1166                         action_names.push_back("SaveAs");
1167                         action_names.push_back("Rename");
1168                         action_names.push_back("New");
1169                         action_names.push_back("Open");
1170                         action_names.push_back("Recent");
1171                         action_names.push_back("Close");
1172
1173                         for (vector<string>::const_iterator n = action_names.begin(); n != action_names.end(); ++n) {
1174                                 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), (*n).c_str());
1175                                 if (act) {
1176                                         act->set_sensitive (false);
1177                                 }
1178                         }
1179
1180                 } else {
1181                         delete nsm;
1182                         nsm = 0;
1183                         error << _("NSM: initialization failed") << endmsg;
1184                         return -1;
1185                 }
1186
1187         } else  {
1188
1189                 if (brand_new_user) {
1190                         _initial_verbose_plugin_scan = true;
1191                         ArdourStartup s;
1192                         s.present ();
1193                         main().run();
1194                         s.hide ();
1195                         _initial_verbose_plugin_scan = false;
1196                         switch (s.response ()) {
1197                         case Gtk::RESPONSE_OK:
1198                                 break;
1199                         default:
1200                                 return -1;
1201                         }
1202                 }
1203
1204                 // TODO: maybe IFF brand_new_user
1205                 if (ARDOUR::Profile->get_mixbus () && Config->get_copy_demo_sessions ()) {
1206                         std::string dspd (Config->get_default_session_parent_dir());
1207                         Searchpath ds (ARDOUR::ardour_data_search_path());
1208                         ds.add_subdirectory_to_paths ("sessions");
1209                         vector<string> demos;
1210                         find_files_matching_pattern (demos, ds, ARDOUR::session_archive_suffix);
1211
1212                         ARDOUR::RecentSessions rs;
1213                         ARDOUR::read_recent_sessions (rs);
1214
1215                         for (vector<string>::iterator i = demos.begin(); i != demos.end (); ++i) {
1216                                 /* "demo-session" must be inside "demo-session.<session_archive_suffix>" */
1217                                 std::string name = basename_nosuffix (basename_nosuffix (*i));
1218                                 std::string path = Glib::build_filename (dspd, name);
1219                                 /* skip if session-dir already exists */
1220                                 if (Glib::file_test(path.c_str(), Glib::FILE_TEST_IS_DIR)) {
1221                                         continue;
1222                                 }
1223                                 /* skip sessions that are already in 'recent'.
1224                                  * eg. a new user changed <session-default-dir> shorly after installation
1225                                  */
1226                                 for (ARDOUR::RecentSessions::iterator r = rs.begin(); r != rs.end(); ++r) {
1227                                         if ((*r).first == name) {
1228                                                 continue;
1229                                         }
1230                                 }
1231                                 try {
1232                                         PBD::FileArchive ar (*i);
1233                                         if (0 == ar.inflate (dspd)) {
1234                                                 store_recent_sessions (name, path);
1235                                                 info << string_compose (_("Copied Demo Session %1."), name) << endmsg;
1236                                         }
1237                                 } catch (...) {}
1238                         }
1239                 }
1240
1241 #ifdef NO_PLUGIN_STATE
1242
1243                 ARDOUR::RecentSessions rs;
1244                 ARDOUR::read_recent_sessions (rs);
1245
1246                 string path = Glib::build_filename (user_config_directory(), ".iknowaboutfreeversion");
1247
1248                 if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS) && !rs.empty()) {
1249
1250                         /* already used Ardour, have sessions ... warn about plugin state */
1251
1252                         ArdourDialog d (_("Free/Demo Version Warning"), true);
1253                         Label l;
1254                         Button b (string_compose (_("Subscribe and support development of %1"), PROGRAM_NAME));
1255                         CheckButton c (_("Don't warn me about this again"));
1256
1257                         l.set_markup (string_compose (_("<span weight=\"bold\" size=\"large\">%1</span>\n\n<b>%2</b>\n\n<i>%3</i>\n\n%4"),
1258                                                       string_compose (_("This is a free/demo version of %1"), PROGRAM_NAME),
1259                                                       _("It will not restore OR save any plugin settings"),
1260                                                       _("If you load an existing session with plugin settings\n"
1261                                                         "they will not be used and will be lost."),
1262                                                       _("To get full access to updates without this limitation\n"
1263                                                         "consider becoming a subscriber for a low cost every month.")));
1264                         l.set_justify (JUSTIFY_CENTER);
1265
1266                         b.signal_clicked().connect (mem_fun(*this, &ARDOUR_UI::launch_subscribe));
1267
1268                         d.get_vbox()->pack_start (l, true, true);
1269                         d.get_vbox()->pack_start (b, false, false, 12);
1270                         d.get_vbox()->pack_start (c, false, false, 12);
1271
1272                         d.add_button (_("Quit now"), RESPONSE_CANCEL);
1273                         d.add_button (string_compose (_("Continue using %1"), PROGRAM_NAME), RESPONSE_OK);
1274
1275                         d.show_all ();
1276
1277                         c.signal_toggled().connect (sigc::hide_return (sigc::bind (sigc::ptr_fun (toggle_file_existence), path)));
1278
1279                         if (d.run () != RESPONSE_OK) {
1280                                 _exit (EXIT_SUCCESS);
1281                         }
1282                 }
1283 #endif
1284
1285                 /* go get a session */
1286
1287                 const bool new_session_required = (ARDOUR_COMMAND_LINE::new_session || brand_new_user);
1288
1289                 if (get_session_parameters (false, new_session_required, ARDOUR_COMMAND_LINE::load_template)) {
1290                         std::cerr << "Cannot get session parameters."<< std::endl;
1291                         return -1;
1292                 }
1293         }
1294
1295         use_config ();
1296
1297         WM::Manager::instance().show_visible ();
1298
1299         /* We have to do this here since goto_editor_window() ends up calling show_all() on the
1300          * editor window, and we may want stuff to be hidden.
1301          */
1302         _status_bar_visibility.update ();
1303
1304         BootMessage (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
1305
1306         /* all other dialogs are created conditionally */
1307
1308         return 0;
1309 }
1310
1311 void
1312 ARDOUR_UI::check_memory_locking ()
1313 {
1314 #if defined(__APPLE__) || defined(PLATFORM_WINDOWS)
1315         /* OS X doesn't support mlockall(2), and so testing for memory locking capability there is pointless */
1316         return;
1317 #else // !__APPLE__
1318
1319         XMLNode* memory_warning_node = Config->instant_xml (X_("no-memory-warning"));
1320
1321         if (AudioEngine::instance()->is_realtime() && memory_warning_node == 0) {
1322
1323                 struct rlimit limits;
1324                 int64_t ram;
1325                 long pages, page_size;
1326 #ifdef __FreeBSD__
1327                 size_t pages_len=sizeof(pages);
1328                 if ((page_size = getpagesize()) < 0 ||
1329                                 sysctlbyname("hw.availpages", &pages, &pages_len, NULL, 0))
1330 #else
1331                 if ((page_size = sysconf (_SC_PAGESIZE)) < 0 ||(pages = sysconf (_SC_PHYS_PAGES)) < 0)
1332 #endif
1333                 {
1334                         ram = 0;
1335                 } else {
1336                         ram = (int64_t) pages * (int64_t) page_size;
1337                 }
1338
1339                 if (getrlimit (RLIMIT_MEMLOCK, &limits)) {
1340                         return;
1341                 }
1342
1343                 if (limits.rlim_cur != RLIM_INFINITY) {
1344
1345                         if (ram == 0 || ((double) limits.rlim_cur / ram) < 0.75) {
1346
1347                                 MessageDialog msg (
1348                                         string_compose (
1349                                                 _("WARNING: Your system has a limit for maximum amount of locked memory. "
1350                                                   "This might cause %1 to run out of memory before your system "
1351                                                   "runs out of memory. \n\n"
1352                                                   "You can view the memory limit with 'ulimit -l', "
1353                                                   "and it is normally controlled by %2"),
1354                                                 PROGRAM_NAME,
1355 #ifdef __FreeBSD__
1356                                                 X_("/etc/login.conf")
1357 #else
1358                                                 X_(" /etc/security/limits.conf")
1359 #endif
1360                                         ).c_str());
1361
1362                                 msg.set_default_response (RESPONSE_OK);
1363
1364                                 VBox* vbox = msg.get_vbox();
1365                                 HBox hbox;
1366                                 CheckButton cb (_("Do not show this window again"));
1367                                 hbox.pack_start (cb, true, false);
1368                                 vbox->pack_start (hbox);
1369                                 cb.show();
1370                                 vbox->show();
1371                                 hbox.show ();
1372
1373                                 pop_back_splash (msg);
1374
1375                                 msg.run ();
1376
1377                                 if (cb.get_active()) {
1378                                         XMLNode node (X_("no-memory-warning"));
1379                                         Config->add_instant_xml (node);
1380                                 }
1381                         }
1382                 }
1383         }
1384 #endif // !__APPLE__
1385 }
1386
1387
1388 void
1389 ARDOUR_UI::queue_finish ()
1390 {
1391         Glib::signal_idle().connect (mem_fun (*this, &ARDOUR_UI::idle_finish));
1392 }
1393
1394 bool
1395 ARDOUR_UI::idle_finish ()
1396 {
1397         finish ();
1398         return false; /* do not call again */
1399 }
1400
1401 void
1402 ARDOUR_UI::finish()
1403 {
1404         if (_session) {
1405                 ARDOUR_UI::instance()->video_timeline->sync_session_state();
1406
1407                 if (_session->dirty()) {
1408                         vector<string> actions;
1409                         actions.push_back (_("Don't quit"));
1410                         actions.push_back (_("Just quit"));
1411                         actions.push_back (_("Save and quit"));
1412                         switch (ask_about_saving_session(actions)) {
1413                         case -1:
1414                                 return;
1415                                 break;
1416                         case 1:
1417                                 /* use the default name */
1418                                 if (save_state_canfail ("")) {
1419                                         /* failed - don't quit */
1420                                         MessageDialog msg (_main_window,
1421                                                            string_compose (_("\
1422 %1 was unable to save your session.\n\n\
1423 If you still wish to quit, please use the\n\n\
1424 \"Just quit\" option."), PROGRAM_NAME));
1425                                         pop_back_splash(msg);
1426                                         msg.run ();
1427                                         return;
1428                                 }
1429                                 break;
1430                         case 0:
1431                                 break;
1432                         }
1433                 }
1434
1435                 second_connection.disconnect ();
1436                 point_one_second_connection.disconnect ();
1437                 point_zero_something_second_connection.disconnect();
1438                 fps_connection.disconnect();
1439         }
1440
1441         delete ARDOUR_UI::instance()->video_timeline;
1442         ARDOUR_UI::instance()->video_timeline = NULL;
1443         stop_video_server();
1444
1445         /* Save state before deleting the session, as that causes some
1446            windows to be destroyed before their visible state can be
1447            saved.
1448         */
1449         save_ardour_state ();
1450
1451         if (key_editor.get (false)) {
1452                 key_editor->disconnect ();
1453         }
1454
1455         close_all_dialogs ();
1456
1457         if (_session) {
1458                 _session->set_clean ();
1459                 _session->remove_pending_capture_state ();
1460                 delete _session;
1461                 _session = 0;
1462         }
1463
1464         halt_connection.disconnect ();
1465         AudioEngine::instance()->stop ();
1466 #ifdef WINDOWS_VST_SUPPORT
1467         fst_stop_threading();
1468 #endif
1469         quit ();
1470 }
1471
1472 int
1473 ARDOUR_UI::ask_about_saving_session (const vector<string>& actions)
1474 {
1475         ArdourDialog window (_("Unsaved Session"));
1476         Gtk::HBox dhbox;  // the hbox for the image and text
1477         Gtk::Label  prompt_label;
1478         Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_WARNING,  Gtk::ICON_SIZE_DIALOG));
1479
1480         string msg;
1481
1482         assert (actions.size() >= 3);
1483
1484         window.add_button (actions[0], RESPONSE_REJECT);
1485         window.add_button (actions[1], RESPONSE_APPLY);
1486         window.add_button (actions[2], RESPONSE_ACCEPT);
1487
1488         window.set_default_response (RESPONSE_ACCEPT);
1489
1490         Gtk::Button noquit_button (msg);
1491         noquit_button.set_name ("EditorGTKButton");
1492
1493         string prompt;
1494
1495         if (_session->snap_name() == _session->name()) {
1496                 prompt = string_compose(_("The session \"%1\"\nhas not been saved.\n\nAny changes made this time\nwill be lost unless you save it.\n\nWhat do you want to do?"),
1497                                         _session->snap_name());
1498         } else {
1499                 prompt = string_compose(_("The snapshot \"%1\"\nhas not been saved.\n\nAny changes made this time\nwill be lost unless you save it.\n\nWhat do you want to do?"),
1500                                         _session->snap_name());
1501         }
1502
1503         prompt_label.set_text (prompt);
1504         prompt_label.set_name (X_("PrompterLabel"));
1505         prompt_label.set_alignment(ALIGN_LEFT, ALIGN_TOP);
1506
1507         dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP);
1508         dhbox.set_homogeneous (false);
1509         dhbox.pack_start (*dimage, false, false, 5);
1510         dhbox.pack_start (prompt_label, true, false, 5);
1511         window.get_vbox()->pack_start (dhbox);
1512
1513         window.set_name (_("Prompter"));
1514         window.set_modal (true);
1515         window.set_resizable (false);
1516
1517         dhbox.show();
1518         prompt_label.show();
1519         dimage->show();
1520         window.show();
1521         window.present ();
1522
1523         ResponseType r = (ResponseType) window.run();
1524
1525         window.hide ();
1526
1527         switch (r) {
1528         case RESPONSE_ACCEPT: // save and get out of here
1529                 return 1;
1530         case RESPONSE_APPLY:  // get out of here
1531                 return 0;
1532         default:
1533                 break;
1534         }
1535
1536         return -1;
1537 }
1538
1539
1540 void
1541 ARDOUR_UI::every_second ()
1542 {
1543         update_cpu_load ();
1544         update_disk_space ();
1545         update_timecode_format ();
1546         update_peak_thread_work ();
1547
1548         if (nsm && nsm->is_active ()) {
1549                 nsm->check ();
1550
1551                 if (!_was_dirty && _session->dirty ()) {
1552                         nsm->is_dirty ();
1553                         _was_dirty = true;
1554                 }
1555                 else if (_was_dirty && !_session->dirty ()){
1556                         nsm->is_clean ();
1557                         _was_dirty = false;
1558                 }
1559         }
1560 }
1561
1562 void
1563 ARDOUR_UI::every_point_one_seconds ()
1564 {
1565         if (editor) editor->build_region_boundary_cache();
1566 }
1567
1568 void
1569 ARDOUR_UI::every_point_zero_something_seconds ()
1570 {
1571         // august 2007: actual update frequency: 25Hz (40ms), not 100Hz
1572
1573         if (editor_meter && UIConfiguration::instance().get_show_editor_meter() && editor_meter_peak_display.is_mapped ()) {
1574                 float mpeak = editor_meter->update_meters();
1575                 if (mpeak > editor_meter_max_peak) {
1576                         if (mpeak >= UIConfiguration::instance().get_meter_peak()) {
1577                                 editor_meter_peak_display.set_active_state ( Gtkmm2ext::ExplicitActive );
1578                         }
1579                 }
1580         }
1581 }
1582
1583 void
1584 ARDOUR_UI::set_fps_timeout_connection ()
1585 {
1586         unsigned int interval = 40;
1587         if (!_session) return;
1588         if (_session->timecode_frames_per_second() != 0) {
1589                 /* ideally we'll use a select() to sleep and not accumulate
1590                  * idle time to provide a regular periodic signal.
1591                  * See linux_vst_gui_support.cc 'elapsed_time_ms'.
1592                  * However, that'll require a dedicated thread and cross-thread
1593                  * signals to the GUI Thread..
1594                  */
1595                 interval = floor(500. /* update twice per FPS, since Glib::signal_timeout is very irregular */
1596                                 * _session->sample_rate() / _session->nominal_sample_rate()
1597                                 / _session->timecode_frames_per_second()
1598                                 );
1599 #ifdef PLATFORM_WINDOWS
1600                 // the smallest windows scheduler time-slice is ~15ms.
1601                 // periodic GUI timeouts shorter than that will cause
1602                 // WaitForSingleObject to spinlock (100% of one CPU Core)
1603                 // and gtk never enters idle mode.
1604                 // also changing timeBeginPeriod(1) does not affect that in
1605                 // any beneficial way, so we just limit the max rate for now.
1606                 interval = std::max(30u, interval); // at most ~33Hz.
1607 #else
1608                 interval = std::max(8u, interval); // at most 120Hz.
1609 #endif
1610         }
1611         fps_connection.disconnect();
1612         Timers::set_fps_interval (interval);
1613 }
1614
1615 void
1616 ARDOUR_UI::update_sample_rate (samplecnt_t)
1617 {
1618         char buf[64];
1619
1620         ENSURE_GUI_THREAD (*this, &ARDOUR_UI::update_sample_rate, ignored)
1621
1622         if (!AudioEngine::instance()->running()) {
1623
1624                 snprintf (buf, sizeof (buf), "%s", _("Audio: <span foreground=\"red\">none</span>"));
1625
1626         } else {
1627
1628                 samplecnt_t rate = AudioEngine::instance()->sample_rate();
1629
1630                 if (rate == 0) {
1631                         /* no sample rate available */
1632                         snprintf (buf, sizeof (buf), "%s", _("Audio: <span foreground=\"red\">none</span>"));
1633                 } else {
1634
1635                         if (fmod (rate, 1000.0) != 0.0) {
1636                                 snprintf (buf, sizeof (buf), _("Audio: <span foreground=\"green\">%.1f kHz / %4.1f ms</span>"),
1637                                           (float) rate / 1000.0f,
1638                                           (AudioEngine::instance()->usecs_per_cycle() / 1000.0f));
1639                         } else {
1640                                 snprintf (buf, sizeof (buf), _("Audio: <span foreground=\"green\">%" PRId64 " kHz / %4.1f ms</span>"),
1641                                           rate/1000,
1642                                           (AudioEngine::instance()->usecs_per_cycle() / 1000.0f));
1643                         }
1644                 }
1645         }
1646         sample_rate_label.set_markup (buf);
1647 }
1648
1649 void
1650 ARDOUR_UI::update_format ()
1651 {
1652         if (!_session) {
1653                 format_label.set_text ("");
1654                 return;
1655         }
1656
1657         stringstream s;
1658         s << _("File:") << X_(" <span foreground=\"green\">");
1659
1660         switch (_session->config.get_native_file_header_format ()) {
1661         case BWF:
1662                 s << _("BWF");
1663                 break;
1664         case WAVE:
1665                 s << _("WAV");
1666                 break;
1667         case WAVE64:
1668                 s << _("WAV64");
1669                 break;
1670         case CAF:
1671                 s << _("CAF");
1672                 break;
1673         case AIFF:
1674                 s << _("AIFF");
1675                 break;
1676         case iXML:
1677                 s << _("iXML");
1678                 break;
1679         case RF64:
1680                 s << _("RF64");
1681                 break;
1682         case RF64_WAV:
1683                 s << _("RF64/WAV");
1684                 break;
1685         case MBWF:
1686                 s << _("MBWF");
1687                 break;
1688         case FLAC:
1689                 s << _("FLAC");
1690                 break;
1691         }
1692
1693         s << " ";
1694
1695         switch (_session->config.get_native_file_data_format ()) {
1696         case FormatFloat:
1697                 s << _("32-float");
1698                 break;
1699         case FormatInt24:
1700                 s << _("24-int");
1701                 break;
1702         case FormatInt16:
1703                 s << _("16-int");
1704                 break;
1705         }
1706
1707         s << X_("</span>");
1708
1709         format_label.set_markup (s.str ());
1710 }
1711
1712 void
1713 ARDOUR_UI::update_cpu_load ()
1714 {
1715         const unsigned int x = _session ? _session->get_xrun_count () : 0;
1716         double const c = AudioEngine::instance()->get_dsp_load ();
1717
1718         const char* const bg = c > 90 ? " background=\"red\"" : "";
1719
1720         char buf[64];
1721         if (x > 9999) {
1722                 snprintf (buf, sizeof (buf), "DSP: <span%s>%.0f%%</span> (>10k)", bg, c);
1723         } else if (x > 0) {
1724                 snprintf (buf, sizeof (buf), "DSP: <span%s>%.0f%%</span> (%d)", bg, c, x);
1725         } else {
1726                 snprintf (buf, sizeof (buf), "DSP: <span%s>%.0f%%</span>", bg, c);
1727         }
1728
1729         dsp_load_label.set_markup (buf);
1730
1731         if (x > 9999) {
1732                 snprintf (buf, sizeof (buf), _("DSP: %.1f%% X: >10k\n%s"), c, _("Shift+Click to clear xruns."));
1733         } else if (x > 0) {
1734                 snprintf (buf, sizeof (buf), _("DSP: %.1f%% X: %u\n%s"), c, x, _("Shift+Click to clear xruns."));
1735         } else {
1736                 snprintf (buf, sizeof (buf), _("DSP: %.1f%%"), c);
1737         }
1738
1739         ArdourWidgets::set_tooltip (dsp_load_label, buf);
1740 }
1741
1742 void
1743 ARDOUR_UI::update_peak_thread_work ()
1744 {
1745         char buf[64];
1746         const int c = SourceFactory::peak_work_queue_length ();
1747         if (c > 0) {
1748                 snprintf (buf, sizeof (buf), _("PkBld: <span foreground=\"%s\">%d</span>"), c >= 2 ? X_("red") : X_("green"), c);
1749                 peak_thread_work_label.set_markup (buf);
1750         } else {
1751                 peak_thread_work_label.set_markup (X_(""));
1752         }
1753 }
1754
1755 void
1756 ARDOUR_UI::count_recenabled_streams (Route& route)
1757 {
1758         Track* track = dynamic_cast<Track*>(&route);
1759         if (track && track->rec_enable_control()->get_value()) {
1760                 rec_enabled_streams += track->n_inputs().n_total();
1761         }
1762 }
1763
1764 void
1765 ARDOUR_UI::format_disk_space_label (float remain_sec)
1766 {
1767         if (remain_sec < 0) {
1768                 disk_space_label.set_text (_("N/A"));
1769                 ArdourWidgets::set_tooltip (disk_space_label, _("Unknown"));
1770                 return;
1771         }
1772
1773         char buf[64];
1774
1775         int sec = floor (remain_sec);
1776         int hrs  = sec / 3600;
1777         int mins = (sec / 60) % 60;
1778         int secs = sec % 60;
1779         snprintf (buf, sizeof(buf), _("%02dh:%02dm:%02ds"), hrs, mins, secs);
1780         ArdourWidgets::set_tooltip (disk_space_label, buf);
1781
1782         if (remain_sec > 86400) {
1783                 disk_space_label.set_text (_("Rec: >24h"));
1784                 return;
1785         } else if (remain_sec > 32400 /* 9 hours */) {
1786                 snprintf (buf, sizeof (buf), "Rec: %.0fh", remain_sec / 3600.f);
1787         } else if (remain_sec > 5940 /* 99 mins */) {
1788                 snprintf (buf, sizeof (buf), "Rec: %.1fh", remain_sec / 3600.f);
1789         } else {
1790                 snprintf (buf, sizeof (buf), "Rec: %.0fm", remain_sec / 60.f);
1791         }
1792         disk_space_label.set_text (buf);
1793
1794 }
1795
1796 void
1797 ARDOUR_UI::update_disk_space()
1798 {
1799         if (_session == 0) {
1800                 format_disk_space_label (-1);
1801                 return;
1802         }
1803
1804         boost::optional<samplecnt_t> opt_samples = _session->available_capture_duration();
1805         samplecnt_t fr = _session->sample_rate();
1806
1807         if (fr == 0) {
1808                 /* skip update - no SR available */
1809                 format_disk_space_label (-1);
1810                 return;
1811         }
1812
1813         if (!opt_samples) {
1814                 /* Available space is unknown */
1815                 format_disk_space_label (-1);
1816         } else if (opt_samples.get_value_or (0) == max_samplecnt) {
1817                 format_disk_space_label (max_samplecnt);
1818         } else {
1819                 rec_enabled_streams = 0;
1820                 _session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams, false);
1821
1822                 samplecnt_t samples = opt_samples.get_value_or (0);
1823
1824                 if (rec_enabled_streams) {
1825                         samples /= rec_enabled_streams;
1826                 }
1827
1828                 format_disk_space_label (samples / (float)fr);
1829         }
1830
1831 }
1832
1833 void
1834 ARDOUR_UI::update_timecode_format ()
1835 {
1836         char buf[64];
1837
1838         if (_session) {
1839                 bool matching;
1840                 boost::shared_ptr<TimecodeTransportMaster> tcmaster;
1841                 boost::shared_ptr<TransportMaster> tm = TransportMasterManager::instance().current();
1842
1843                 if ((tm->type() == LTC || tm->type() == MTC) && (tcmaster = boost::dynamic_pointer_cast<TimecodeTransportMaster>(tm)) != 0) {
1844                         matching = (tcmaster->apparent_timecode_format() == _session->config.get_timecode_format());
1845                 } else {
1846                         matching = true;
1847                 }
1848
1849                 snprintf (buf, sizeof (buf), S_("Timecode|TC: <span foreground=\"%s\">%s</span>"),
1850                           matching ? X_("green") : X_("red"),
1851                           Timecode::timecode_format_name (_session->config.get_timecode_format()).c_str());
1852         } else {
1853                 snprintf (buf, sizeof (buf), "TC: n/a");
1854         }
1855
1856         timecode_format_label.set_markup (buf);
1857 }
1858
1859 gint
1860 ARDOUR_UI::update_wall_clock ()
1861 {
1862         time_t now;
1863         struct tm *tm_now;
1864         static int last_min = -1;
1865
1866         time (&now);
1867         tm_now = localtime (&now);
1868         if (last_min != tm_now->tm_min) {
1869                 char buf[16];
1870                 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
1871                 wall_clock_label.set_text (buf);
1872                 last_min = tm_now->tm_min;
1873         }
1874
1875         return TRUE;
1876 }
1877
1878 void
1879 ARDOUR_UI::open_recent_session ()
1880 {
1881         bool can_return = (_session != 0);
1882
1883         SessionDialog recent_session_dialog;
1884
1885         while (true) {
1886
1887                 ResponseType r = (ResponseType) recent_session_dialog.run ();
1888
1889                 switch (r) {
1890                 case RESPONSE_ACCEPT:
1891                         break;
1892                 default:
1893                         if (can_return) {
1894                                 recent_session_dialog.hide();
1895                                 return;
1896                         } else {
1897                                 exit (EXIT_FAILURE);
1898                         }
1899                 }
1900
1901                 recent_session_dialog.hide();
1902
1903                 bool should_be_new;
1904
1905                 std::string path = recent_session_dialog.session_folder();
1906                 std::string state = recent_session_dialog.session_name (should_be_new);
1907
1908                 if (should_be_new == true) {
1909                         continue;
1910                 }
1911
1912                 _session_is_new = false;
1913
1914                 if (load_session (path, state) == 0) {
1915                         break;
1916                 }
1917
1918                 can_return = false;
1919         }
1920 }
1921
1922 bool
1923 ARDOUR_UI::check_audioengine (Gtk::Window& parent)
1924 {
1925         if (!AudioEngine::instance()->running()) {
1926                 MessageDialog msg (parent, string_compose (
1927                                            _("%1 is not connected to any audio backend.\n"
1928                                            "You cannot open or close sessions in this condition"),
1929                                            PROGRAM_NAME));
1930                 pop_back_splash (msg);
1931                 msg.run ();
1932                 return false;
1933         }
1934         return true;
1935 }
1936
1937 void
1938 ARDOUR_UI::open_session ()
1939 {
1940         if (!check_audioengine (_main_window)) {
1941                 return;
1942         }
1943
1944         /* ardour sessions are folders */
1945         Gtk::FileChooserDialog open_session_selector(_("Open Session"), FILE_CHOOSER_ACTION_OPEN);
1946         open_session_selector.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1947         open_session_selector.add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
1948         open_session_selector.set_default_response(Gtk::RESPONSE_ACCEPT);
1949
1950         if (_session) {
1951                 string session_parent_dir = Glib::path_get_dirname(_session->path());
1952                 open_session_selector.set_current_folder(session_parent_dir);
1953         } else {
1954                 open_session_selector.set_current_folder(Config->get_default_session_parent_dir());
1955         }
1956
1957         Gtkmm2ext::add_volume_shortcuts (open_session_selector);
1958         try {
1959                 /* add_shortcut_folder throws an exception if the folder being added already has a shortcut */
1960                 string default_session_folder = Config->get_default_session_parent_dir();
1961                 open_session_selector.add_shortcut_folder (default_session_folder);
1962         }
1963         catch (Glib::Error const& e) {
1964                 std::cerr << "open_session_selector.add_shortcut_folder() threw Glib::Error " << e.what() << std::endl;
1965         }
1966
1967         FileFilter session_filter;
1968         session_filter.add_pattern (string_compose(X_("*%1"), ARDOUR::statefile_suffix));
1969         session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
1970         open_session_selector.add_filter (session_filter);
1971
1972         FileFilter archive_filter;
1973         archive_filter.add_pattern (string_compose(X_("*%1"), ARDOUR::session_archive_suffix));
1974         archive_filter.set_name (_("Session Archives"));
1975
1976         open_session_selector.add_filter (archive_filter);
1977
1978         open_session_selector.set_filter (session_filter);
1979
1980         int response = open_session_selector.run();
1981         open_session_selector.hide ();
1982
1983         if (response == Gtk::RESPONSE_CANCEL) {
1984                 return;
1985         }
1986
1987         string session_path = open_session_selector.get_filename();
1988         string path, name;
1989         bool isnew;
1990
1991         if (session_path.length() > 0) {
1992                 int rv = ARDOUR::inflate_session (session_path,
1993                                 Config->get_default_session_parent_dir(), path, name);
1994                 if (rv == 0) {
1995                         _session_is_new = false;
1996                         load_session (path, name);
1997                 }
1998                 else if (rv < 0) {
1999                         MessageDialog msg (_main_window,
2000                                         string_compose (_("Extracting session-archive failed: %1"), inflate_error (rv)));
2001                         msg.run ();
2002                 }
2003                 else if (ARDOUR::find_session (session_path, path, name, isnew) == 0) {
2004                         _session_is_new = isnew;
2005                         load_session (path, name);
2006                 }
2007         }
2008 }
2009
2010 void
2011 ARDOUR_UI::session_add_mixed_track (
2012                 const ChanCount& input,
2013                 const ChanCount& output,
2014                 RouteGroup* route_group,
2015                 uint32_t how_many,
2016                 const string& name_template,
2017                 bool strict_io,
2018                 PluginInfoPtr instrument,
2019                 Plugin::PresetRecord* pset,
2020                 ARDOUR::PresentationInfo::order_t order)
2021 {
2022         assert (_session);
2023
2024         if (Profile->get_mixbus ()) {
2025                 strict_io = true;
2026         }
2027
2028         try {
2029                 list<boost::shared_ptr<MidiTrack> > tracks;
2030                 tracks = _session->new_midi_track (input, output, strict_io, instrument, pset, route_group, how_many, name_template, order, ARDOUR::Normal);
2031
2032                 if (tracks.size() != how_many) {
2033                         error << string_compose(P_("could not create %1 new mixed track", "could not create %1 new mixed tracks", how_many), how_many) << endmsg;
2034                 }
2035         }
2036
2037         catch (...) {
2038                 display_insufficient_ports_message ();
2039                 return;
2040         }
2041 }
2042
2043 void
2044 ARDOUR_UI::session_add_midi_bus (
2045                 RouteGroup* route_group,
2046                 uint32_t how_many,
2047                 const string& name_template,
2048                 bool strict_io,
2049                 PluginInfoPtr instrument,
2050                 Plugin::PresetRecord* pset,
2051                 ARDOUR::PresentationInfo::order_t order)
2052 {
2053         if (_session == 0) {
2054                 warning << _("You cannot add a track without a session already loaded.") << endmsg;
2055                 return;
2056         }
2057
2058         if (Profile->get_mixbus ()) {
2059                 strict_io = true;
2060         }
2061
2062         try {
2063                 RouteList routes;
2064                 routes = _session->new_midi_route (route_group, how_many, name_template, strict_io, instrument, pset, PresentationInfo::MidiBus, order);
2065                 if (routes.size() != how_many) {
2066                         error << string_compose(P_("could not create %1 new Midi Bus", "could not create %1 new Midi Busses", how_many), how_many) << endmsg;
2067                 }
2068
2069         }
2070         catch (...) {
2071                 display_insufficient_ports_message ();
2072                 return;
2073         }
2074 }
2075
2076 void
2077 ARDOUR_UI::session_add_midi_route (
2078                 bool disk,
2079                 RouteGroup* route_group,
2080                 uint32_t how_many,
2081                 const string& name_template,
2082                 bool strict_io,
2083                 PluginInfoPtr instrument,
2084                 Plugin::PresetRecord* pset,
2085                 ARDOUR::PresentationInfo::order_t order)
2086 {
2087         ChanCount one_midi_channel;
2088         one_midi_channel.set (DataType::MIDI, 1);
2089
2090         if (disk) {
2091                 session_add_mixed_track (one_midi_channel, one_midi_channel, route_group, how_many, name_template, strict_io, instrument, pset, order);
2092         } else {
2093                 session_add_midi_bus (route_group, how_many, name_template, strict_io, instrument, pset, order);
2094         }
2095 }
2096
2097 void
2098 ARDOUR_UI::session_add_audio_route (
2099         bool track,
2100         int32_t input_channels,
2101         int32_t output_channels,
2102         ARDOUR::TrackMode mode,
2103         RouteGroup* route_group,
2104         uint32_t how_many,
2105         string const & name_template,
2106         bool strict_io,
2107         ARDOUR::PresentationInfo::order_t order)
2108 {
2109         list<boost::shared_ptr<AudioTrack> > tracks;
2110         RouteList routes;
2111
2112         assert (_session);
2113
2114         try {
2115                 if (track) {
2116                         tracks = _session->new_audio_track (input_channels, output_channels, route_group, how_many, name_template, order, mode);
2117
2118                         if (tracks.size() != how_many) {
2119                                 error << string_compose (P_("could not create %1 new audio track", "could not create %1 new audio tracks", how_many), how_many)
2120                                       << endmsg;
2121                         }
2122
2123                 } else {
2124
2125                         routes = _session->new_audio_route (input_channels, output_channels, route_group, how_many, name_template, PresentationInfo::AudioBus, order);
2126
2127                         if (routes.size() != how_many) {
2128                                 error << string_compose (P_("could not create %1 new audio bus", "could not create %1 new audio busses", how_many), how_many)
2129                                       << endmsg;
2130                         }
2131                 }
2132         }
2133
2134         catch (...) {
2135                 display_insufficient_ports_message ();
2136                 return;
2137         }
2138
2139         if (strict_io) {
2140                 for (list<boost::shared_ptr<AudioTrack> >::iterator i = tracks.begin(); i != tracks.end(); ++i) {
2141                         (*i)->set_strict_io (true);
2142                 }
2143                 for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
2144                         (*i)->set_strict_io (true);
2145                 }
2146         }
2147 }
2148
2149 void
2150 ARDOUR_UI::session_add_foldback_bus (int32_t channels, uint32_t how_many, string const & name_template)
2151 {
2152         RouteList routes;
2153
2154         assert (_session);
2155
2156         try {
2157                 routes = _session->new_audio_route (channels, channels, 0, how_many, name_template, PresentationInfo::FoldbackBus, -1);
2158
2159                 if (routes.size() != how_many) {
2160                         error << string_compose (P_("could not create %1 new foldback bus", "could not create %1 new foldback busses", how_many), how_many)
2161                               << endmsg;
2162                 }
2163         }
2164
2165         catch (...) {
2166                 display_insufficient_ports_message ();
2167                 return;
2168         }
2169 }
2170
2171 void
2172 ARDOUR_UI::display_insufficient_ports_message ()
2173 {
2174         MessageDialog msg (_main_window,
2175                         string_compose (_("There are insufficient ports available\n\
2176 to create a new track or bus.\n\
2177 You should save %1, exit and\n\
2178 restart with more ports."), PROGRAM_NAME));
2179         pop_back_splash (msg);
2180         msg.run ();
2181 }
2182
2183 void
2184 ARDOUR_UI::transport_goto_start ()
2185 {
2186         if (_session) {
2187                 _session->goto_start();
2188
2189                 /* force displayed area in editor to start no matter
2190                    what "follow playhead" setting is.
2191                 */
2192
2193                 if (editor) {
2194                         editor->center_screen (_session->current_start_sample ());
2195                 }
2196         }
2197 }
2198
2199 void
2200 ARDOUR_UI::transport_goto_zero ()
2201 {
2202         if (_session) {
2203                 _session->request_locate (0);
2204
2205                 /* force displayed area in editor to start no matter
2206                    what "follow playhead" setting is.
2207                 */
2208
2209                 if (editor) {
2210                         editor->reset_x_origin (0);
2211                 }
2212         }
2213 }
2214
2215 void
2216 ARDOUR_UI::transport_goto_wallclock ()
2217 {
2218         if (_session && editor) {
2219
2220                 time_t now;
2221                 struct tm tmnow;
2222                 samplepos_t samples;
2223
2224                 time (&now);
2225                 localtime_r (&now, &tmnow);
2226
2227                 samplecnt_t sample_rate = _session->sample_rate();
2228
2229                 if (sample_rate == 0) {
2230                         /* no frame rate available */
2231                         return;
2232                 }
2233
2234                 samples = tmnow.tm_hour * (60 * 60 * sample_rate);
2235                 samples += tmnow.tm_min * (60 * sample_rate);
2236                 samples += tmnow.tm_sec * sample_rate;
2237
2238                 _session->request_locate (samples, _session->transport_rolling ());
2239
2240                 /* force displayed area in editor to start no matter
2241                    what "follow playhead" setting is.
2242                 */
2243
2244                 if (editor) {
2245                         editor->center_screen (samples);
2246                 }
2247         }
2248 }
2249
2250 void
2251 ARDOUR_UI::transport_goto_end ()
2252 {
2253         if (_session) {
2254                 samplepos_t const sample = _session->current_end_sample();
2255                 _session->request_locate (sample);
2256
2257                 /* force displayed area in editor to start no matter
2258                    what "follow playhead" setting is.
2259                 */
2260
2261                 if (editor) {
2262                         editor->center_screen (sample);
2263                 }
2264         }
2265 }
2266
2267 void
2268 ARDOUR_UI::transport_stop ()
2269 {
2270         if (!_session) {
2271                 return;
2272         }
2273
2274         if (_session->is_auditioning()) {
2275                 _session->cancel_audition ();
2276                 return;
2277         }
2278
2279         _session->request_stop (false, true);
2280 }
2281
2282 /** Check if any tracks are record enabled. If none are, record enable all of them.
2283  * @return true if track record-enabled status was changed, false otherwise.
2284  */
2285 bool
2286 ARDOUR_UI::trx_record_enable_all_tracks ()
2287 {
2288         if (!_session) {
2289                 return false;
2290         }
2291
2292         boost::shared_ptr<RouteList> rl = _session->get_tracks ();
2293         bool none_record_enabled = true;
2294
2295         for (RouteList::iterator r = rl->begin(); r != rl->end(); ++r) {
2296                 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*r);
2297                 assert (t);
2298
2299                 if (t->rec_enable_control()->get_value()) {
2300                         none_record_enabled = false;
2301                         break;
2302                 }
2303         }
2304
2305         if (none_record_enabled) {
2306                 _session->set_controls (route_list_to_control_list (rl, &Stripable::rec_enable_control), 1.0, Controllable::NoGroup);
2307         }
2308
2309         return none_record_enabled;
2310 }
2311
2312 void
2313 ARDOUR_UI::transport_record (bool roll)
2314 {
2315         if (_session) {
2316                 switch (_session->record_status()) {
2317                 case Session::Disabled:
2318                         if (_session->ntracks() == 0) {
2319                                 MessageDialog msg (_main_window, _("Please create one or more tracks before trying to record.\nYou can do this with the \"Add Track or Bus\" option in the Session menu."));
2320                                 msg.run ();
2321                                 return;
2322                         }
2323                         if (Profile->get_trx()) {
2324                                 roll = trx_record_enable_all_tracks ();
2325                         }
2326                         _session->maybe_enable_record ();
2327                         if (roll) {
2328                                 transport_roll ();
2329                         }
2330                         break;
2331                 case Session::Recording:
2332                         if (roll) {
2333                                 _session->request_stop();
2334                         } else {
2335                                 _session->disable_record (false, true);
2336                         }
2337                         break;
2338
2339                 case Session::Enabled:
2340                         _session->disable_record (false, true);
2341                 }
2342         }
2343 }
2344
2345 void
2346 ARDOUR_UI::transport_roll ()
2347 {
2348         if (!_session) {
2349                 return;
2350         }
2351
2352         if (_session->is_auditioning()) {
2353                 return;
2354         }
2355
2356         if (_session->config.get_external_sync()) {
2357                 switch (TransportMasterManager::instance().current()->type()) {
2358                 case Engine:
2359                         break;
2360                 default:
2361                         /* transport controlled by the master */
2362                         return;
2363                 }
2364         }
2365
2366         bool rolling = _session->transport_rolling();
2367
2368         if (_session->get_play_loop()) {
2369
2370                 /* If loop playback is not a mode, then we should cancel
2371                    it when this action is requested. If it is a mode
2372                    we just leave it in place.
2373                 */
2374
2375                 if (!Config->get_loop_is_mode()) {
2376                         /* XXX it is not possible to just leave seamless loop and keep
2377                            playing at present (nov 4th 2009)
2378                         */
2379                         if (!Config->get_seamless_loop()) {
2380                                 /* stop loop playback and stop rolling */
2381                                 _session->request_play_loop (false, true);
2382                         } else if (rolling) {
2383                                 /* stop loop playback but keep rolling */
2384                                 _session->request_play_loop (false, false);
2385                         }
2386                 }
2387
2388         } else if (_session->get_play_range () ) {
2389                 /* stop playing a range if we currently are */
2390                 _session->request_play_range (0, true);
2391         }
2392
2393         if (!rolling) {
2394                 _session->request_transport_speed (1.0f);
2395         }
2396 }
2397
2398 bool
2399 ARDOUR_UI::get_smart_mode() const
2400 {
2401         return ( editor->get_smart_mode() );
2402 }
2403
2404
2405 void
2406 ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode)
2407 {
2408         if (!_session) {
2409                 return;
2410         }
2411
2412         if (_session->is_auditioning()) {
2413                 _session->cancel_audition ();
2414                 return;
2415         }
2416
2417         if (_session->config.get_external_sync()) {
2418                 switch (TransportMasterManager::instance().current()->type()) {
2419                 case Engine:
2420                         break;
2421                 default:
2422                         /* transport controlled by the master */
2423                         return;
2424                 }
2425         }
2426
2427         bool rolling = _session->transport_rolling();
2428         bool affect_transport = true;
2429
2430         if (rolling && roll_out_of_bounded_mode) {
2431                 /* drop out of loop/range playback but leave transport rolling */
2432                 if (_session->get_play_loop()) {
2433                         if (_session->actively_recording()) {
2434
2435                                 /* just stop using the loop, then actually stop
2436                                  * below
2437                                  */
2438                                 _session->request_play_loop (false, affect_transport);
2439
2440                         } else {
2441                                 if (Config->get_seamless_loop()) {
2442                                         /* the disk buffers contain copies of the loop - we can't
2443                                            just keep playing, so stop the transport. the user
2444                                            can restart as they wish.
2445                                         */
2446                                         affect_transport = true;
2447                                 } else {
2448                                         /* disk buffers are normal, so we can keep playing */
2449                                         affect_transport = false;
2450                                 }
2451                                 _session->request_play_loop (false, affect_transport);
2452                         }
2453                 } else if (_session->get_play_range ()) {
2454                         affect_transport = false;
2455                         _session->request_play_range (0, true);
2456                 }
2457         }
2458
2459         if (affect_transport) {
2460                 if (rolling) {
2461                         _session->request_stop (with_abort, true);
2462
2463                 } else if (!with_abort) { /* with_abort == true means the
2464                                            * command was intended to stop
2465                                            * transport, not start.
2466                                            */
2467
2468                         /* the only external sync condition we can be in here
2469                          * would be Engine (JACK) sync, in which case we still
2470                          * want to do this.
2471                          */
2472
2473                         if (UIConfiguration::instance().get_follow_edits() && ( editor->get_selection().time.front().start == _session->transport_sample() ) ) {  //if playhead is exactly at the start of a range, we can assume it was placed there by follow_edits
2474                                 _session->request_play_range (&editor->get_selection().time, true);
2475                                 _session->set_requested_return_sample( editor->get_selection().time.front().start );  //force an auto-return here
2476                         }
2477                         _session->request_transport_speed (1.0f);
2478                 }
2479         }
2480 }
2481
2482 void
2483 ARDOUR_UI::toggle_session_auto_loop ()
2484 {
2485         if (!_session) {
2486                 return;
2487         }
2488
2489         Location * looploc = _session->locations()->auto_loop_location();
2490
2491         if (!looploc) {
2492                 return;
2493         }
2494
2495         if (_session->get_play_loop()) {
2496
2497                 /* looping enabled, our job is to disable it */
2498
2499                 _session->request_play_loop (false);
2500
2501         } else {
2502
2503                 /* looping not enabled, our job is to enable it.
2504
2505                    loop-is-NOT-mode: this action always starts the transport rolling.
2506                    loop-IS-mode:     this action simply sets the loop play mechanism, but
2507                                         does not start transport.
2508                 */
2509                 if (Config->get_loop_is_mode()) {
2510                         _session->request_play_loop (true, false);
2511                 } else {
2512                         _session->request_play_loop (true, true);
2513                 }
2514         }
2515
2516         //show the loop markers
2517         looploc->set_hidden (false, this);
2518 }
2519
2520 void
2521 ARDOUR_UI::transport_play_selection ()
2522 {
2523         if (!_session) {
2524                 return;
2525         }
2526
2527         editor->play_selection ();
2528 }
2529
2530 void
2531 ARDOUR_UI::transport_play_preroll ()
2532 {
2533         if (!_session) {
2534                 return;
2535         }
2536         editor->play_with_preroll ();
2537 }
2538
2539 void
2540 ARDOUR_UI::transport_rec_preroll ()
2541 {
2542         if (!_session) {
2543                 return;
2544         }
2545         editor->rec_with_preroll ();
2546 }
2547
2548 void
2549 ARDOUR_UI::transport_rec_count_in ()
2550 {
2551         if (!_session) {
2552                 return;
2553         }
2554         editor->rec_with_count_in ();
2555 }
2556
2557 void
2558 ARDOUR_UI::transport_rewind (int option)
2559 {
2560         float current_transport_speed;
2561
2562         if (_session) {
2563                 current_transport_speed = _session->transport_speed();
2564
2565                 if (current_transport_speed >= 0.0f) {
2566                         switch (option) {
2567                         case 0:
2568                                 _session->request_transport_speed (-1.0f);
2569                                 break;
2570                         case 1:
2571                                 _session->request_transport_speed (-4.0f);
2572                                 break;
2573                         case -1:
2574                                 _session->request_transport_speed (-0.5f);
2575                                 break;
2576                         }
2577                 } else {
2578                         /* speed up */
2579                         _session->request_transport_speed (current_transport_speed * 1.5f);
2580                 }
2581         }
2582 }
2583
2584 void
2585 ARDOUR_UI::transport_forward (int option)
2586 {
2587         if (!_session) {
2588                 return;
2589         }
2590
2591         float current_transport_speed = _session->transport_speed();
2592
2593         if (current_transport_speed <= 0.0f) {
2594                 switch (option) {
2595                 case 0:
2596                         _session->request_transport_speed (1.0f);
2597                         break;
2598                 case 1:
2599                         _session->request_transport_speed (4.0f);
2600                         break;
2601                 case -1:
2602                         _session->request_transport_speed (0.5f);
2603                         break;
2604                 }
2605         } else {
2606                 /* speed up */
2607                 _session->request_transport_speed (current_transport_speed * 1.5f);
2608         }
2609 }
2610
2611 void
2612 ARDOUR_UI::toggle_record_enable (uint16_t rid)
2613 {
2614         if (!_session) {
2615                 return;
2616         }
2617
2618         boost::shared_ptr<Route> r;
2619
2620         if ((r = _session->get_remote_nth_route (rid)) != 0) {
2621
2622                 boost::shared_ptr<Track> t;
2623
2624                 if ((t = boost::dynamic_pointer_cast<Track>(r)) != 0) {
2625                         t->rec_enable_control()->set_value (!t->rec_enable_control()->get_value(), Controllable::UseGroup);
2626                 }
2627         }
2628 }
2629
2630 void
2631 ARDOUR_UI::map_transport_state ()
2632 {
2633         if (!_session) {
2634                 layered_button.set_sensitive (false);
2635                 return;
2636         }
2637
2638         shuttle_box.map_transport_state ();
2639
2640         float sp = _session->transport_speed();
2641
2642         if (sp != 0.0f) {
2643                 layered_button.set_sensitive (!_session->actively_recording ());
2644         } else {
2645                 layered_button.set_sensitive (true);
2646                 update_disk_space ();
2647         }
2648         if (UIConfiguration::instance().get_screen_saver_mode () == InhibitWhileRecording) {
2649                 inhibit_screensaver (_session->actively_recording ());
2650         }
2651 }
2652
2653 void
2654 ARDOUR_UI::blink_handler (bool blink_on)
2655 {
2656         sync_blink (blink_on);
2657
2658         if (!UIConfiguration::instance().get_blink_alert_indicators()) {
2659                 blink_on = true;
2660         }
2661         error_blink (blink_on);
2662         solo_blink (blink_on);
2663         audition_blink (blink_on);
2664         feedback_blink (blink_on);
2665 }
2666
2667 void
2668 ARDOUR_UI::update_clocks ()
2669 {
2670         if (!_session) return;
2671
2672         if (editor && !editor->dragging_playhead()) {
2673                 Clock (_session->audible_sample()); /* EMIT_SIGNAL */
2674         }
2675 }
2676
2677 void
2678 ARDOUR_UI::start_clocking ()
2679 {
2680         if (UIConfiguration::instance().get_super_rapid_clock_update()) {
2681                 clock_signal_connection = Timers::fps_connect (sigc::mem_fun(*this, &ARDOUR_UI::update_clocks));
2682         } else {
2683                 clock_signal_connection = Timers::rapid_connect (sigc::mem_fun(*this, &ARDOUR_UI::update_clocks));
2684         }
2685 }
2686
2687 void
2688 ARDOUR_UI::stop_clocking ()
2689 {
2690         clock_signal_connection.disconnect ();
2691 }
2692
2693 bool
2694 ARDOUR_UI::save_as_progress_update (float fraction, int64_t cnt, int64_t total, Gtk::Label* label, Gtk::ProgressBar* bar)
2695 {
2696         char buf[256];
2697
2698         snprintf (buf, sizeof (buf), _("Copied %" PRId64 " of %" PRId64), cnt, total);
2699
2700         label->set_text (buf);
2701         bar->set_fraction (fraction);
2702
2703         /* process events, redraws, etc. */
2704
2705         while (gtk_events_pending()) {
2706                 gtk_main_iteration ();
2707         }
2708
2709         return true; /* continue with save-as */
2710 }
2711
2712 void
2713 ARDOUR_UI::save_session_as ()
2714 {
2715         if (!_session) {
2716                 return;
2717         }
2718
2719         if (_session->dirty()) {
2720                 vector<string> actions;
2721                 actions.push_back (_("Abort save-as"));
2722                 actions.push_back (_("Don't save now, just save-as"));
2723                 actions.push_back (_("Save it first"));
2724                 switch (ask_about_saving_session(actions)) {
2725                         case -1:
2726                                 return;
2727                                 break;
2728                         case 1:
2729                                 if (save_state_canfail ("")) {
2730                                         MessageDialog msg (_main_window,
2731                                                         string_compose (_("\
2732 %1 was unable to save your session.\n\n\
2733 If you still wish to proceed, please use the\n\n\
2734 \"Don't save now\" option."), PROGRAM_NAME));
2735                                         pop_back_splash(msg);
2736                                         msg.run ();
2737                                         return;
2738                                 }
2739                                 /* fall through */
2740                         case 0:
2741                                 _session->remove_pending_capture_state ();
2742                                 break;
2743                 }
2744         }
2745
2746         if (!save_as_dialog) {
2747                 save_as_dialog = new SaveAsDialog;
2748         }
2749
2750         save_as_dialog->set_name (_session->name());
2751
2752         int response = save_as_dialog->run ();
2753
2754         save_as_dialog->hide ();
2755
2756         switch (response) {
2757         case Gtk::RESPONSE_OK:
2758                 break;
2759         default:
2760                 return;
2761         }
2762
2763
2764         Session::SaveAs sa;
2765
2766         sa.new_parent_folder = save_as_dialog->new_parent_folder ();
2767         sa.new_name = save_as_dialog->new_name ();
2768         sa.switch_to = save_as_dialog->switch_to();
2769         sa.copy_media = save_as_dialog->copy_media();
2770         sa.copy_external = save_as_dialog->copy_external();
2771         sa.include_media = save_as_dialog->include_media ();
2772
2773         /* Only bother with a progress dialog if we're going to copy
2774            media into the save-as target. Without that choice, this
2775            will be very fast because we're only talking about a few kB's to
2776            perhaps a couple of MB's of data.
2777         */
2778
2779         ArdourDialog progress_dialog (_("Save As"), true);
2780         ScopedConnection c;
2781
2782         if (sa.include_media && sa.copy_media) {
2783
2784                 Gtk::Label* label = manage (new Gtk::Label());
2785                 Gtk::ProgressBar* progress_bar = manage (new Gtk::ProgressBar ());
2786
2787                 progress_dialog.get_vbox()->pack_start (*label);
2788                 progress_dialog.get_vbox()->pack_start (*progress_bar);
2789                 label->show ();
2790                 progress_bar->show ();
2791
2792                 /* this signal will be emitted from within this, the calling thread,
2793                  * after every file is copied. It provides information on percentage
2794                  * complete (in terms of total data to copy), the number of files
2795                  * copied so far, and the total number to copy.
2796                  */
2797
2798                 sa.Progress.connect_same_thread (c, boost::bind (&ARDOUR_UI::save_as_progress_update, this, _1, _2, _3, label, progress_bar));
2799
2800                 progress_dialog.show_all ();
2801                 progress_dialog.present ();
2802         }
2803
2804         if (_session->save_as (sa)) {
2805                 /* ERROR MESSAGE */
2806                 MessageDialog msg (string_compose (_("Save As failed: %1"), sa.failure_message));
2807                 msg.run ();
2808         }
2809
2810         /* the logic here may seem odd: why isn't the condition sa.switch_to ?
2811          * the trick is this: if the new session was copy with media included,
2812          * then Session::save_as() will have already done a neat trick to avoid
2813          * us having to unload and load the new state. But if the media was not
2814          * included, then this is required (it avoids us having to otherwise
2815          * drop all references to media (sources).
2816          */
2817
2818         if (!sa.include_media && sa.switch_to) {
2819                 unload_session (false);
2820                 load_session (sa.final_session_folder_name, sa.new_name);
2821         }
2822 }
2823
2824 void
2825 ARDOUR_UI::archive_session ()
2826 {
2827         if (!_session) {
2828                 return;
2829         }
2830
2831         time_t n;
2832         time (&n);
2833         Glib::DateTime gdt (Glib::DateTime::create_now_local (n));
2834
2835         SessionArchiveDialog sad;
2836         sad.set_name (_session->name() + gdt.format ("_%F_%H%M%S"));
2837         int response = sad.run ();
2838
2839         if (response != Gtk::RESPONSE_OK) {
2840                 sad.hide ();
2841                 return;
2842         }
2843
2844         if (_session->archive_session (sad.target_folder(), sad.name(), sad.encode_option (), sad.compression_level (), sad.only_used_sources (), &sad)) {
2845                 MessageDialog msg (_("Session Archiving failed."));
2846                 msg.run ();
2847         }
2848 }
2849
2850 void
2851 ARDOUR_UI::quick_snapshot_session (bool switch_to_it)
2852 {
2853                 char timebuf[128];
2854                 time_t n;
2855                 struct tm local_time;
2856
2857                 time (&n);
2858                 localtime_r (&n, &local_time);
2859                 strftime (timebuf, sizeof(timebuf), "%FT%H.%M.%S", &local_time);
2860                 if (switch_to_it && _session->dirty ()) {
2861                         save_state_canfail ("");
2862                 }
2863
2864                 save_state (timebuf, switch_to_it);
2865 }
2866
2867
2868 bool
2869 ARDOUR_UI::process_snapshot_session_prompter (Prompter& prompter, bool switch_to_it)
2870 {
2871         string snapname;
2872
2873         prompter.get_result (snapname);
2874
2875         bool do_save = (snapname.length() != 0);
2876
2877         if (do_save) {
2878                 char illegal = Session::session_name_is_legal(snapname);
2879                 if (illegal) {
2880                         MessageDialog msg (string_compose (_("To ensure compatibility with various systems\n"
2881                                                              "snapshot names may not contain a '%1' character"), illegal));
2882                         msg.run ();
2883                         return false;
2884                 }
2885         }
2886
2887         vector<std::string> p;
2888         get_state_files_in_directory (_session->session_directory().root_path(), p);
2889         vector<string> n = get_file_names_no_extension (p);
2890
2891         if (find (n.begin(), n.end(), snapname) != n.end()) {
2892
2893                 do_save = overwrite_file_dialog (prompter,
2894                                                  _("Confirm Snapshot Overwrite"),
2895                                                  _("A snapshot already exists with that name. Do you want to overwrite it?"));
2896         }
2897
2898         if (do_save) {
2899                 save_state (snapname, switch_to_it);
2900         }
2901         else {
2902                 return false;
2903         }
2904
2905         return true;
2906 }
2907
2908
2909 /** Ask the user for the name of a new snapshot and then take it.
2910  */
2911
2912 void
2913 ARDOUR_UI::snapshot_session (bool switch_to_it)
2914 {
2915         if (switch_to_it && _session->dirty()) {
2916                 vector<string> actions;
2917                 actions.push_back (_("Abort saving snapshot"));
2918                 actions.push_back (_("Don't save now, just snapshot"));
2919                 actions.push_back (_("Save it first"));
2920                 switch (ask_about_saving_session(actions)) {
2921                         case -1:
2922                                 return;
2923                                 break;
2924                         case 1:
2925                                 if (save_state_canfail ("")) {
2926                                         MessageDialog msg (_main_window,
2927                                                         string_compose (_("\
2928 %1 was unable to save your session.\n\n\
2929 If you still wish to proceed, please use the\n\n\
2930 \"Don't save now\" option."), PROGRAM_NAME));
2931                                         pop_back_splash(msg);
2932                                         msg.run ();
2933                                         return;
2934                                 }
2935                                 /* fall through */
2936                         case 0:
2937                                 _session->remove_pending_capture_state ();
2938                                 break;
2939                 }
2940         }
2941
2942         Prompter prompter (true);
2943         prompter.set_name ("Prompter");
2944         prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
2945         if (switch_to_it) {
2946                 prompter.set_title (_("Snapshot and switch"));
2947                 prompter.set_prompt (_("New session name"));
2948         } else {
2949                 prompter.set_title (_("Take Snapshot"));
2950                 prompter.set_prompt (_("Name of new snapshot"));
2951         }
2952
2953         if (switch_to_it) {
2954                 prompter.set_initial_text (_session->snap_name());
2955         } else {
2956                 Glib::DateTime tm (g_date_time_new_now_local ());
2957                 prompter.set_initial_text (tm.format ("%FT%H.%M.%S"));
2958         }
2959
2960         bool finished = false;
2961         while (!finished) {
2962                 switch (prompter.run()) {
2963                 case RESPONSE_ACCEPT:
2964                 {
2965                         finished = process_snapshot_session_prompter (prompter, switch_to_it);
2966                         break;
2967                 }
2968
2969                 default:
2970                         finished = true;
2971                         break;
2972                 }
2973         }
2974 }
2975
2976 /** Ask the user for a new session name and then rename the session to it.
2977  */
2978
2979 void
2980 ARDOUR_UI::rename_session ()
2981 {
2982         if (!_session) {
2983                 return;
2984         }
2985
2986         Prompter prompter (true);
2987         string name;
2988
2989         prompter.set_name ("Prompter");
2990         prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
2991         prompter.set_title (_("Rename Session"));
2992         prompter.set_prompt (_("New session name"));
2993
2994   again:
2995         switch (prompter.run()) {
2996         case RESPONSE_ACCEPT:
2997         {
2998                 prompter.get_result (name);
2999
3000                 bool do_rename = (name.length() != 0);
3001
3002                 if (do_rename) {
3003                         char illegal = Session::session_name_is_legal (name);
3004
3005                         if (illegal) {
3006                                 MessageDialog msg (string_compose (_("To ensure compatibility with various systems\n"
3007                                                                      "session names may not contain a '%1' character"), illegal));
3008                                 msg.run ();
3009                                 goto again;
3010                         }
3011
3012                         switch (_session->rename (name)) {
3013                         case -1: {
3014                                 MessageDialog msg (_("That name is already in use by another directory/folder. Please try again."));
3015                                 msg.set_position (WIN_POS_MOUSE);
3016                                 msg.run ();
3017                                 goto again;
3018                                 break;
3019                         }
3020                         case 0:
3021                                 break;
3022                         default: {
3023                                 MessageDialog msg (_("Renaming this session failed.\nThings could be seriously messed up at this point"));
3024                                 msg.set_position (WIN_POS_MOUSE);
3025                                 msg.run ();
3026                                 break;
3027                         }
3028                         }
3029                 }
3030
3031                 break;
3032         }
3033
3034         default:
3035                 break;
3036         }
3037 }
3038
3039 void
3040 ARDOUR_UI::save_state (const string & name, bool switch_to_it)
3041 {
3042         if (!_session || _session->deletion_in_progress()) {
3043                 return;
3044         }
3045
3046         XMLNode* node = new XMLNode (X_("UI"));
3047
3048         WM::Manager::instance().add_state (*node);
3049
3050         node->add_child_nocopy (gui_object_state->get_state());
3051
3052         _session->add_extra_xml (*node);
3053
3054         if (export_video_dialog) {
3055                 _session->add_extra_xml (export_video_dialog->get_state());
3056         }
3057
3058         save_state_canfail (name, switch_to_it);
3059 }
3060
3061 int
3062 ARDOUR_UI::save_state_canfail (string name, bool switch_to_it)
3063 {
3064         if (_session) {
3065                 int ret;
3066
3067                 if ((ret = _session->save_state (name, false, switch_to_it)) != 0) {
3068                         return ret;
3069                 }
3070         }
3071
3072         save_ardour_state (); /* XXX cannot fail? yeah, right ... */
3073         return 0;
3074 }
3075
3076 void
3077 ARDOUR_UI::primary_clock_value_changed ()
3078 {
3079         if (_session) {
3080                 _session->request_locate (primary_clock->current_time ());
3081         }
3082 }
3083
3084 void
3085 ARDOUR_UI::big_clock_value_changed ()
3086 {
3087         if (_session) {
3088                 _session->request_locate (big_clock->current_time ());
3089         }
3090 }
3091
3092 void
3093 ARDOUR_UI::secondary_clock_value_changed ()
3094 {
3095         if (_session) {
3096                 _session->request_locate (secondary_clock->current_time ());
3097         }
3098 }
3099 void
3100 ARDOUR_UI::save_template_dialog_response (int response, SaveTemplateDialog* d)
3101 {
3102         if (response == RESPONSE_ACCEPT) {
3103                 const string name = d->get_template_name ();
3104                 const string desc = d->get_description ();
3105
3106                 int failed = _session->save_template (name, desc);
3107
3108                 if (failed == -2) { /* file already exists. */
3109                         bool overwrite = overwrite_file_dialog (*d,
3110                                                                 _("Confirm Template Overwrite"),
3111                                                                 _("A template already exists with that name. Do you want to overwrite it?"));
3112
3113                         if (overwrite) {
3114                                 _session->save_template (name, desc, true);
3115                         }
3116                         else {
3117                                 d->show ();
3118                                 return;
3119                         }
3120                 }
3121         }
3122         delete d;
3123 }
3124
3125 void
3126 ARDOUR_UI::save_template ()
3127 {
3128         if (!check_audioengine (_main_window)) {
3129                 return;
3130         }
3131
3132         const std::string desc = SessionMetadata::Metadata()->description ();
3133         SaveTemplateDialog* d = new SaveTemplateDialog (_session->name (), desc);
3134         d->signal_response().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::save_template_dialog_response), d));
3135         d->show ();
3136 }
3137
3138 void ARDOUR_UI::manage_templates ()
3139 {
3140         TemplateDialog td;
3141         td.run();
3142 }
3143
3144 void
3145 ARDOUR_UI::edit_metadata ()
3146 {
3147         SessionMetadataEditor dialog;
3148         dialog.set_session (_session);
3149         dialog.grab_focus ();
3150         dialog.run ();
3151 }
3152
3153 void
3154 ARDOUR_UI::import_metadata ()
3155 {
3156         SessionMetadataImporter dialog;
3157         dialog.set_session (_session);
3158         dialog.run ();
3159 }
3160
3161 bool
3162 ARDOUR_UI::ask_about_loading_existing_session (const std::string& session_path)
3163 {
3164         std::string str = string_compose (_("This session\n%1\nalready exists. Do you want to open it?"), session_path);
3165
3166         MessageDialog msg (str,
3167                            false,
3168                            Gtk::MESSAGE_WARNING,
3169                            Gtk::BUTTONS_YES_NO,
3170                            true);
3171
3172
3173         msg.set_name (X_("OpenExistingDialog"));
3174         msg.set_title (_("Open Existing Session"));
3175         msg.set_wmclass (X_("existing_session"), PROGRAM_NAME);
3176         msg.set_position (Gtk::WIN_POS_CENTER);
3177         pop_back_splash (msg);
3178
3179         switch (msg.run()) {
3180         case RESPONSE_YES:
3181                 return true;
3182                 break;
3183         }
3184         return false;
3185 }
3186
3187 int
3188 ARDOUR_UI::build_session_from_dialog (SessionDialog& sd, const std::string& session_path, const std::string& session_name)
3189 {
3190         BusProfile bus_profile;
3191
3192         if (nsm) {
3193                 bus_profile.master_out_channels = 2;
3194         } else {
3195                 /* get settings from advanced section of NSD */
3196                 bus_profile.master_out_channels = (uint32_t) sd.master_channel_count();
3197         }
3198
3199         // NULL profile: no master, no monitor
3200         if (build_session (session_path, session_name, bus_profile.master_out_channels > 0 ? &bus_profile : NULL)) {
3201                 return -1;
3202         }
3203
3204         return 0;
3205 }
3206
3207 void
3208 ARDOUR_UI::load_from_application_api (const std::string& path)
3209 {
3210         /* OS X El Capitan (and probably later) now somehow passes the command
3211            line arguments to an app via the openFile delegate protocol. Ardour
3212            already does its own command line processing, and having both
3213            pathways active causes crashes. So, if the command line was already
3214            set, do nothing here.
3215         */
3216
3217         if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
3218                 return;
3219         }
3220
3221         ARDOUR_COMMAND_LINE::session_name = path;
3222
3223         /* Cancel SessionDialog if it's visible to make OSX delegates work.
3224          *
3225          * ARDOUR_UI::starting connects app->ShouldLoad signal and then shows a SessionDialog
3226          * race-condition:
3227          *  - ShouldLoad does not arrive in time, ARDOUR_COMMAND_LINE::session_name is empty:
3228          *    -> ARDOUR_UI::get_session_parameters starts a SessionDialog.
3229          *  - ShouldLoad signal arrives, this function is called and sets ARDOUR_COMMAND_LINE::session_name
3230          *    -> SessionDialog is not displayed
3231          */
3232
3233         if (_session_dialog) {
3234                 std::string session_name = basename_nosuffix (ARDOUR_COMMAND_LINE::session_name);
3235                 std::string session_path = path;
3236                 if (Glib::file_test (session_path, Glib::FILE_TEST_IS_REGULAR)) {
3237                         session_path = Glib::path_get_dirname (session_path);
3238                 }
3239                 // signal the existing dialog in ARDOUR_UI::get_session_parameters()
3240                 _session_dialog->set_provided_session (session_name, session_path);
3241                 _session_dialog->response (RESPONSE_NONE);
3242                 _session_dialog->hide();
3243                 return;
3244         }
3245
3246         int rv;
3247         if (Glib::file_test (path, Glib::FILE_TEST_IS_DIR)) {
3248                 /* /path/to/foo => /path/to/foo, foo */
3249                 rv = load_session (path, basename_nosuffix (path));
3250         } else {
3251                 /* /path/to/foo/foo.ardour => /path/to/foo, foo */
3252                 rv =load_session (Glib::path_get_dirname (path), basename_nosuffix (path));
3253         }
3254
3255         // if load_session fails -> pop up SessionDialog.
3256         if (rv) {
3257                 ARDOUR_COMMAND_LINE::session_name = "";
3258
3259                 if (get_session_parameters (true, false)) {
3260                         exit (EXIT_FAILURE);
3261                 }
3262         }
3263 }
3264
3265 /** @param quit_on_cancel true if exit() should be called if the user clicks `cancel' in the new session dialog */
3266 int
3267 ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, string load_template)
3268 {
3269         string session_name;
3270         string session_path;
3271         string template_name;
3272         int ret = -1;
3273         bool likely_new = false;
3274         bool cancel_not_quit;
3275
3276         /* deal with any existing DIRTY session now, rather than later. don't
3277          * treat a non-dirty session this way, so that it stays visible
3278          * as we bring up the new session dialog.
3279          */
3280
3281         if (_session && ARDOUR_UI::instance()->video_timeline) {
3282                 ARDOUR_UI::instance()->video_timeline->sync_session_state();
3283         }
3284
3285         /* if there is already a session, relabel the button
3286            on the SessionDialog so that we don't Quit directly
3287         */
3288         cancel_not_quit = (_session != 0) && !quit_on_cancel;
3289
3290         if (_session && _session->dirty()) {
3291                 if (unload_session (false)) {
3292                         /* unload cancelled by user */
3293                         return 0;
3294                 }
3295                 ARDOUR_COMMAND_LINE::session_name = "";
3296         }
3297
3298         if (!load_template.empty()) {
3299                 should_be_new = true;
3300                 template_name = load_template;
3301         }
3302
3303         session_path = ARDOUR_COMMAND_LINE::session_name;
3304
3305         if (!session_path.empty()) {
3306
3307                 if (Glib::file_test (session_path.c_str(), Glib::FILE_TEST_EXISTS)) {
3308
3309                         session_name = basename_nosuffix (ARDOUR_COMMAND_LINE::session_name);
3310
3311                         if (Glib::file_test (session_path.c_str(), Glib::FILE_TEST_IS_REGULAR)) {
3312                                 /* session/snapshot file, change path to be dir */
3313                                 session_path = Glib::path_get_dirname (session_path);
3314                         }
3315                 } else {
3316
3317                         /* session (file or folder) does not exist ... did the
3318                          * user give us a path or just a name?
3319                          */
3320
3321                         if (session_path.find (G_DIR_SEPARATOR) == string::npos) {
3322                                 /* user gave session name with no path info, use
3323                                    default session folder.
3324                                 */
3325                                 session_name = ARDOUR_COMMAND_LINE::session_name;
3326                                 session_path = Glib::build_filename (Config->get_default_session_parent_dir (), session_name);
3327                         } else {
3328                                 session_name = basename_nosuffix (ARDOUR_COMMAND_LINE::session_name);
3329                         }
3330                 }
3331         }
3332
3333         SessionDialog session_dialog (should_be_new, session_name, session_path, load_template, cancel_not_quit);
3334
3335         _session_dialog = &session_dialog;
3336         while (ret != 0) {
3337
3338                 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
3339
3340                         /* if they named a specific statefile, use it, otherwise they are
3341                            just giving a session folder, and we want to use it as is
3342                            to find the session.
3343                         */
3344
3345                         string::size_type suffix = ARDOUR_COMMAND_LINE::session_name.find (statefile_suffix);
3346
3347                         if (suffix != string::npos) {
3348                                 session_path = Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name);
3349                                 session_name = ARDOUR_COMMAND_LINE::session_name.substr (0, suffix);
3350                                 session_name = Glib::path_get_basename (session_name);
3351                         } else {
3352                                 session_path = ARDOUR_COMMAND_LINE::session_name;
3353                                 session_name = Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name);
3354                         }
3355                 } else {
3356                         session_path = "";
3357                         session_name = "";
3358                         session_dialog.clear_given ();
3359                 }
3360
3361                 if (session_name.empty()) {
3362                         /* need the dialog to get the name (at least) from the user */
3363                         switch (session_dialog.run()) {
3364                         case RESPONSE_ACCEPT:
3365                                 break;
3366                         case RESPONSE_NONE:
3367                                 /* this is used for async * app->ShouldLoad(). */
3368                                 continue; // while loop
3369                                 break;
3370                         default:
3371                                 if (quit_on_cancel) {
3372                                         ARDOUR_UI::finish ();
3373                                         Gtkmm2ext::Application::instance()->cleanup();
3374                                         ARDOUR::cleanup ();
3375                                         pthread_cancel_all ();
3376                                         return -1; // caller is responsible to call exit()
3377                                 } else {
3378                                         return ret;
3379                                 }
3380                         }
3381
3382                         session_dialog.hide ();
3383                 }
3384
3385                 /* if we run the startup dialog again, offer more than just "new session" */
3386
3387                 should_be_new = false;
3388
3389                 session_name = session_dialog.session_name (likely_new);
3390                 session_path = session_dialog.session_folder ();
3391
3392                 if (nsm) {
3393                         likely_new = true;
3394                 }
3395
3396                 if (!likely_new) {
3397                         int rv = ARDOUR::inflate_session (session_name,
3398                                         Config->get_default_session_parent_dir(), session_path, session_name);
3399                         if (rv < 0) {
3400                                 MessageDialog msg (session_dialog,
3401                                         string_compose (_("Extracting session-archive failed: %1"), inflate_error (rv)));
3402                                 msg.run ();
3403                                 continue;
3404                         }
3405                         else if (rv == 0) {
3406                                 session_dialog.set_provided_session (session_name, session_path);
3407                         }
3408                 }
3409
3410                 // XXX check archive, inflate
3411                 string::size_type suffix = session_name.find (statefile_suffix);
3412
3413                 if (suffix != string::npos) {
3414                         session_name = session_name.substr (0, suffix);
3415                 }
3416
3417                 /* this shouldn't happen, but we catch it just in case it does */
3418
3419                 if (session_name.empty()) {
3420                         continue;
3421                 }
3422
3423                 if (session_dialog.use_session_template()) {
3424                         template_name = session_dialog.session_template_name();
3425                         _session_is_new = true;
3426                 }
3427
3428                 if (session_name[0] == G_DIR_SEPARATOR ||
3429 #ifdef PLATFORM_WINDOWS
3430                    (session_name.length() > 3 && session_name[1] == ':' && session_name[2] == G_DIR_SEPARATOR)
3431 #else
3432                    (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == G_DIR_SEPARATOR) ||
3433                    (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == G_DIR_SEPARATOR)
3434 #endif
3435                 )
3436                 {
3437
3438                         /* absolute path or cwd-relative path specified for session name: infer session folder
3439                            from what was given.
3440                         */
3441
3442                         session_path = Glib::path_get_dirname (session_name);
3443                         session_name = Glib::path_get_basename (session_name);
3444
3445                 } else {
3446
3447                         session_path = session_dialog.session_folder();
3448
3449                         char illegal = Session::session_name_is_legal (session_name);
3450
3451                         if (illegal) {
3452                                 MessageDialog msg (session_dialog,
3453                                                    string_compose (_("To ensure compatibility with various systems\n"
3454                                                                      "session names may not contain a '%1' character"),
3455                                                                    illegal));
3456                                 msg.run ();
3457                                 ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
3458                                 continue;
3459                         }
3460                 }
3461
3462                 if (Glib::file_test (session_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
3463
3464
3465                         if (likely_new && !nsm) {
3466
3467                                 std::string existing = Glib::build_filename (session_path, session_name);
3468
3469                                 if (!ask_about_loading_existing_session (existing)) {
3470                                         ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
3471                                         continue;
3472                                 }
3473                         }
3474
3475                         _session_is_new = false;
3476
3477                 } else {
3478
3479                         if (!likely_new) {
3480                                 pop_back_splash (session_dialog);
3481                                 MessageDialog msg (string_compose (_("There is no existing session at \"%1\""), session_path));
3482                                 msg.run ();
3483                                 ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
3484                                 continue;
3485                         }
3486
3487                         char illegal = Session::session_name_is_legal(session_name);
3488
3489                         if (illegal) {
3490                                 pop_back_splash (session_dialog);
3491                                 MessageDialog msg (session_dialog, string_compose(_("To ensure compatibility with various systems\n"
3492                                                                                     "session names may not contain a '%1' character"), illegal));
3493                                 msg.run ();
3494                                 ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
3495                                 continue;
3496                         }
3497
3498                         _session_is_new = true;
3499                 }
3500
3501                 if (!template_name.empty() && template_name.substr (0, 11) == "urn:ardour:") {
3502
3503                         ret = build_session_from_dialog (session_dialog, session_path, session_name);
3504                         meta_session_setup (template_name.substr (11));
3505
3506                 } else if (likely_new && template_name.empty()) {
3507
3508                         ret = build_session_from_dialog (session_dialog, session_path, session_name);
3509
3510                 } else {
3511
3512                         ret = load_session (session_path, session_name, template_name);
3513
3514                         if (ret == -2) {
3515                                 /* not connected to the AudioEngine, so quit to avoid an infinite loop */
3516                                 exit (EXIT_FAILURE);
3517                         }
3518
3519                         /* clear this to avoid endless attempts to load the
3520                            same session.
3521                         */
3522
3523                         ARDOUR_COMMAND_LINE::session_name = "";
3524                 }
3525         }
3526
3527         _session_dialog = NULL;
3528
3529         return ret;
3530 }
3531
3532 void
3533 ARDOUR_UI::close_session()
3534 {
3535         if (!check_audioengine (_main_window)) {
3536                 return;
3537         }
3538
3539         if (unload_session (true)) {
3540                 return;
3541         }
3542
3543         ARDOUR_COMMAND_LINE::session_name = "";
3544
3545         if (get_session_parameters (true, false)) {
3546                 exit (EXIT_FAILURE);
3547         }
3548 }
3549
3550 /** @param snap_name Snapshot name (without .ardour suffix).
3551  *  @return -2 if the load failed because we are not connected to the AudioEngine.
3552  */
3553 int
3554 ARDOUR_UI::load_session (const std::string& path, const std::string& snap_name, std::string mix_template)
3555 {
3556         /* load_session calls flush_pending() which allows
3557          * GUI interaction and potentially loading another session
3558          * (that was easy via snapshot sidebar).
3559          * Recursing into load_session() from load_session() and recusive
3560          * event loops causes all kind of crashes.
3561          */
3562         assert (!session_load_in_progress);
3563         if (session_load_in_progress) {
3564                 return -1;
3565         }
3566         PBD::Unwinder<bool> lsu (session_load_in_progress, true);
3567
3568         Session *new_session;
3569         int unload_status;
3570         int retval = -1;
3571
3572         if (_session) {
3573                 unload_status = unload_session ();
3574
3575                 if (unload_status < 0) {
3576                         goto out;
3577                 } else if (unload_status > 0) {
3578                         retval = 0;
3579                         goto out;
3580                 }
3581         }
3582
3583         loading_message (string_compose (_("Please wait while %1 loads your session"), PROGRAM_NAME));
3584
3585         try {
3586                 new_session = new Session (*AudioEngine::instance(), path, snap_name, 0, mix_template);
3587         }
3588
3589         /* this one is special */
3590
3591         catch (AudioEngine::PortRegistrationFailure const& err) {
3592
3593                 MessageDialog msg (err.what(),
3594                                    true,
3595                                    Gtk::MESSAGE_INFO,
3596                                    Gtk::BUTTONS_CLOSE);
3597
3598                 msg.set_title (_("Port Registration Error"));
3599                 msg.set_secondary_text (_("Click the Close button to try again."));
3600                 msg.set_position (Gtk::WIN_POS_CENTER);
3601                 pop_back_splash (msg);
3602                 msg.present ();
3603
3604                 int response = msg.run ();
3605
3606                 msg.hide ();
3607
3608                 switch (response) {
3609                 case RESPONSE_CANCEL:
3610                         exit (EXIT_FAILURE);
3611                 default:
3612                         break;
3613                 }
3614                 goto out;
3615         }
3616         catch (SessionException const& e) {
3617                 MessageDialog msg (string_compose(
3618                                            _("Session \"%1 (snapshot %2)\" did not load successfully:\n%3"),
3619                                            path, snap_name, e.what()),
3620                                    true,
3621                                    Gtk::MESSAGE_INFO,
3622                                    BUTTONS_OK);
3623
3624                 msg.set_title (_("Loading Error"));
3625                 msg.set_position (Gtk::WIN_POS_CENTER);
3626                 pop_back_splash (msg);
3627                 msg.present ();
3628
3629                 dump_errors (cerr);
3630
3631                 (void) msg.run ();
3632                 msg.hide ();
3633
3634                 goto out;
3635         }
3636         catch (...) {
3637
3638                 MessageDialog msg (string_compose(
3639                                            _("Session \"%1 (snapshot %2)\" did not load successfully."),
3640                                            path, snap_name),
3641                                    true,
3642                                    Gtk::MESSAGE_INFO,
3643                                    BUTTONS_OK);
3644
3645                 msg.set_title (_("Loading Error"));
3646                 msg.set_position (Gtk::WIN_POS_CENTER);
3647                 pop_back_splash (msg);
3648                 msg.present ();
3649
3650                 dump_errors (cerr);
3651
3652                 (void) msg.run ();
3653                 msg.hide ();
3654
3655                 goto out;
3656         }
3657
3658         {
3659                 list<string> const u = new_session->unknown_processors ();
3660                 if (!u.empty()) {
3661                         MissingPluginDialog d (_session, u);
3662                         d.run ();
3663                 }
3664         }
3665
3666         if (!new_session->writable()) {
3667                 MessageDialog msg (_("This session has been opened in read-only mode.\n\nYou will not be able to record or save."),
3668                                    true,
3669                                    Gtk::MESSAGE_INFO,
3670                                    BUTTONS_OK);
3671
3672                 msg.set_title (_("Read-only Session"));
3673                 msg.set_position (Gtk::WIN_POS_CENTER);
3674                 pop_back_splash (msg);
3675                 msg.present ();
3676                 (void) msg.run ();
3677                 msg.hide ();
3678         }
3679
3680
3681         /* Now the session been created, add the transport controls */
3682         new_session->add_controllable(roll_controllable);
3683         new_session->add_controllable(stop_controllable);
3684         new_session->add_controllable(goto_start_controllable);
3685         new_session->add_controllable(goto_end_controllable);
3686         new_session->add_controllable(auto_loop_controllable);
3687         new_session->add_controllable(play_selection_controllable);
3688         new_session->add_controllable(rec_controllable);
3689
3690         set_session (new_session);
3691
3692         if (_session) {
3693                 _session->set_clean ();
3694         }
3695
3696 #ifdef WINDOWS_VST_SUPPORT
3697         fst_stop_threading();
3698 #endif
3699
3700         {
3701                 Timers::TimerSuspender t;
3702                 flush_pending (10);
3703         }
3704
3705 #ifdef WINDOWS_VST_SUPPORT
3706         fst_start_threading();
3707 #endif
3708         retval = 0;
3709
3710         if (!mix_template.empty ()) {
3711                 /* if mix_template is given, assume this is a new session */
3712                 string metascript = Glib::build_filename (mix_template, "template.lua");
3713                 meta_session_setup (metascript);
3714         }
3715
3716
3717   out:
3718         /* For successful session load the splash is hidden by ARDOUR_UI::first_idle,
3719          * which is queued by set_session().
3720          * If session-loading fails we hide it explicitly.
3721          * This covers both cases in a central place.
3722          */
3723         if (retval) {
3724                 hide_splash ();
3725         }
3726         return retval;
3727 }
3728
3729 int
3730 ARDOUR_UI::build_session (const std::string& path, const std::string& snap_name, BusProfile* bus_profile)
3731 {
3732         Session *new_session;
3733         int x;
3734
3735         x = unload_session ();
3736
3737         if (x < 0) {
3738                 return -1;
3739         } else if (x > 0) {
3740                 return 0;
3741         }
3742
3743         _session_is_new = true;
3744
3745         try {
3746                 new_session = new Session (*AudioEngine::instance(), path, snap_name, bus_profile);
3747         }
3748
3749         catch (SessionException const& e) {
3750                 cerr << "Here are the errors associated with this failed session:\n";
3751                 dump_errors (cerr);
3752                 cerr << "---------\n";
3753                 MessageDialog msg (string_compose(_("Could not create session in \"%1\": %2"), path, e.what()));
3754                 msg.set_title (_("Loading Error"));
3755                 msg.set_position (Gtk::WIN_POS_CENTER);
3756                 pop_back_splash (msg);
3757                 msg.run ();
3758                 return -1;
3759         }
3760         catch (...) {
3761                 cerr << "Here are the errors associated with this failed session:\n";
3762                 dump_errors (cerr);
3763                 cerr << "---------\n";
3764                 MessageDialog msg (string_compose(_("Could not create session in \"%1\""), path));
3765                 msg.set_title (_("Loading Error"));
3766                 msg.set_position (Gtk::WIN_POS_CENTER);
3767                 pop_back_splash (msg);
3768                 msg.run ();
3769                 return -1;
3770         }
3771
3772         /* Give the new session the default GUI state, if such things exist */
3773
3774         XMLNode* n;
3775         n = Config->instant_xml (X_("Editor"));
3776         if (n) {
3777                 n->remove_nodes_and_delete ("Selection"); // no not apply selection to new sessions.
3778                 new_session->add_instant_xml (*n, false);
3779         }
3780         n = Config->instant_xml (X_("Mixer"));
3781         if (n) {
3782                 new_session->add_instant_xml (*n, false);
3783         }
3784
3785         n = Config->instant_xml (X_("Preferences"));
3786         if (n) {
3787                 new_session->add_instant_xml (*n, false);
3788         }
3789
3790         /* Put the playhead at 0 and scroll fully left */
3791         n = new_session->instant_xml (X_("Editor"));
3792         if (n) {
3793                 n->set_property (X_("playhead"), X_("0"));
3794                 n->set_property (X_("left-frame"), X_("0"));
3795         }
3796
3797         set_session (new_session);
3798
3799         new_session->save_state(new_session->name());
3800
3801         return 0;
3802 }
3803
3804
3805 static void _lua_print (std::string s) {
3806 #ifndef NDEBUG
3807         std::cout << "LuaInstance: " << s << "\n";
3808 #endif
3809         PBD::info << "LuaInstance: " << s << endmsg;
3810 }
3811
3812 std::map<std::string, std::string>
3813 ARDOUR_UI::route_setup_info (const std::string& script_path)
3814 {
3815         std::map<std::string, std::string> rv;
3816
3817         if (!Glib::file_test (script_path, Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_REGULAR)) {
3818                 return rv;
3819         }
3820
3821         LuaState lua;
3822         lua.Print.connect (&_lua_print);
3823         lua.sandbox (true);
3824
3825         lua_State* L = lua.getState();
3826         LuaInstance::register_classes (L);
3827         LuaBindings::set_session (L, _session);
3828         luabridge::push <PublicEditor *> (L, &PublicEditor::instance());
3829         lua_setglobal (L, "Editor");
3830
3831         lua.do_command ("function ardour () end");
3832         lua.do_file (script_path);
3833
3834         try {
3835                 luabridge::LuaRef fn = luabridge::getGlobal (L, "route_setup");
3836                 if (!fn.isFunction ()) {
3837                         return rv;
3838                 }
3839                 luabridge::LuaRef rs = fn ();
3840                 if (!rs.isTable ()) {
3841                         return rv;
3842                 }
3843                 for (luabridge::Iterator i(rs); !i.isNil (); ++i) {
3844                         if (!i.key().isString()) {
3845                                 continue;
3846                         }
3847                         std::string key = i.key().tostring();
3848                         if (i.value().isString() || i.value().isNumber() || i.value().isBoolean()) {
3849                                 rv[key] = i.value().tostring();
3850                         }
3851                 }
3852         } catch (luabridge::LuaException const& e) {
3853                 cerr << "LuaException:" << e.what () << endl;
3854         } catch (...) { }
3855         return rv;
3856 }
3857
3858 void
3859 ARDOUR_UI::meta_route_setup (const std::string& script_path)
3860 {
3861         if (!Glib::file_test (script_path, Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_REGULAR)) {
3862                 return;
3863         }
3864         assert (add_route_dialog);
3865
3866         int count;
3867         if ((count = add_route_dialog->count()) <= 0) {
3868                 return;
3869         }
3870
3871         LuaState lua;
3872         lua.Print.connect (&_lua_print);
3873         lua.sandbox (true);
3874
3875         lua_State* L = lua.getState();
3876         LuaInstance::register_classes (L);
3877         LuaBindings::set_session (L, _session);
3878         luabridge::push <PublicEditor *> (L, &PublicEditor::instance());
3879         lua_setglobal (L, "Editor");
3880
3881         lua.do_command ("function ardour () end");
3882         lua.do_file (script_path);
3883
3884         luabridge::LuaRef args (luabridge::newTable (L));
3885
3886         args["name"]       = add_route_dialog->name_template ();
3887         args["insert_at"]  = translate_order (add_route_dialog->insert_at());
3888         args["group"]      = add_route_dialog->route_group ();
3889         args["strict_io"]  = add_route_dialog->use_strict_io ();
3890         args["instrument"] = add_route_dialog->requested_instrument ();
3891         args["track_mode"] = add_route_dialog->mode ();
3892         args["channels"]   = add_route_dialog->channel_count ();
3893         args["how_many"]   = count;
3894
3895         try {
3896                 luabridge::LuaRef fn = luabridge::getGlobal (L, "factory");
3897                 if (fn.isFunction()) {
3898                         fn (args)();
3899                 }
3900         } catch (luabridge::LuaException const& e) {
3901                 cerr << "LuaException:" << e.what () << endl;
3902         } catch (...) {
3903                 display_insufficient_ports_message ();
3904         }
3905 }
3906
3907 void
3908 ARDOUR_UI::meta_session_setup (const std::string& script_path)
3909 {
3910         if (!Glib::file_test (script_path, Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_REGULAR)) {
3911                 return;
3912         }
3913
3914         LuaState lua;
3915         lua.Print.connect (&_lua_print);
3916         lua.sandbox (true);
3917
3918         lua_State* L = lua.getState();
3919         LuaInstance::register_classes (L);
3920         LuaBindings::set_session (L, _session);
3921         luabridge::push <PublicEditor *> (L, &PublicEditor::instance());
3922         lua_setglobal (L, "Editor");
3923
3924         lua.do_command ("function ardour () end");
3925         lua.do_file (script_path);
3926
3927         try {
3928                 luabridge::LuaRef fn = luabridge::getGlobal (L, "factory");
3929                 if (fn.isFunction()) {
3930                         fn ()();
3931                 }
3932         } catch (luabridge::LuaException const& e) {
3933                 cerr << "LuaException:" << e.what () << endl;
3934         } catch (...) {
3935                 display_insufficient_ports_message ();
3936         }
3937 }
3938
3939 void
3940 ARDOUR_UI::launch_chat ()
3941 {
3942         MessageDialog dialog(_("<b>Just ask and wait for an answer.\nIt may take from minutes to hours.</b>"), true);
3943
3944         dialog.set_title (_("About the Chat"));
3945         dialog.set_secondary_text (_("When you're inside the chat just ask your question and wait for an answer. The chat is occupied by real people with real lives so many of them are passively online and might not read your question before minutes or hours later.\nSo please be patient and wait for an answer.\n\nYou should just leave the chat window open and check back regularly until someone has answered your question."));
3946
3947         switch (dialog.run()) {
3948         case RESPONSE_OK:
3949                 open_uri("http://webchat.freenode.net/?channels=ardour");
3950                 break;
3951         default:
3952                 break;
3953         }
3954 }
3955
3956 void
3957 ARDOUR_UI::launch_manual ()
3958 {
3959         PBD::open_uri (Config->get_tutorial_manual_url());
3960 }
3961
3962 void
3963 ARDOUR_UI::launch_reference ()
3964 {
3965         PBD::open_uri (Config->get_reference_manual_url());
3966 }
3967
3968 void
3969 ARDOUR_UI::launch_tracker ()
3970 {
3971         PBD::open_uri ("http://tracker.ardour.org");
3972 }
3973
3974 void
3975 ARDOUR_UI::launch_subscribe ()
3976 {
3977         PBD::open_uri ("https://community.ardour.org/s/subscribe");
3978 }
3979
3980 void
3981 ARDOUR_UI::launch_cheat_sheet ()
3982 {
3983 #ifdef __APPLE__
3984         PBD::open_uri ("http://manual.ardour.org/files/a3_mnemonic_cheat_sheet_osx.pdf");
3985 #else
3986         PBD::open_uri ("http://manual.ardour.org/files/a3_mnemonic_cheatsheet.pdf");
3987 #endif
3988 }
3989
3990 void
3991 ARDOUR_UI::launch_website ()
3992 {
3993         PBD::open_uri ("http://ardour.org");
3994 }
3995
3996 void
3997 ARDOUR_UI::launch_website_dev ()
3998 {
3999         PBD::open_uri ("http://ardour.org/development.html");
4000 }
4001
4002 void
4003 ARDOUR_UI::launch_forums ()
4004 {
4005         PBD::open_uri ("https://community.ardour.org/forums");
4006 }
4007
4008 void
4009 ARDOUR_UI::launch_howto_report ()
4010 {
4011         PBD::open_uri ("http://ardour.org/reporting_bugs");
4012 }
4013
4014 void
4015 ARDOUR_UI::loading_message (const std::string& msg)
4016 {
4017         if (ARDOUR_COMMAND_LINE::no_splash) {
4018                 return;
4019         }
4020
4021         if (!splash) {
4022                 show_splash ();
4023         }
4024
4025         splash->message (msg);
4026 }
4027
4028 void
4029 ARDOUR_UI::show_splash ()
4030 {
4031         if (splash == 0) {
4032                 try {
4033                         splash = new Splash;
4034                 } catch (...) {
4035                         return;
4036                 }
4037         }
4038
4039         splash->display ();
4040 }
4041
4042 void
4043 ARDOUR_UI::hide_splash ()
4044 {
4045         delete splash;
4046         splash = 0;
4047 }
4048
4049 void
4050 ARDOUR_UI::display_cleanup_results (ARDOUR::CleanupReport& rep, const gchar* list_title, const bool msg_delete)
4051 {
4052         size_t removed;
4053
4054         removed = rep.paths.size();
4055
4056         if (removed == 0) {
4057                 MessageDialog msgd (_main_window,
4058                                     _("No files were ready for clean-up"),
4059                                     true,
4060                                     Gtk::MESSAGE_INFO,
4061                                     Gtk::BUTTONS_OK);
4062                 msgd.set_title (_("Clean-up"));
4063                 msgd.set_secondary_text (_("If this seems surprising, \n\
4064 check for any existing snapshots.\n\
4065 These may still include regions that\n\
4066 require some unused files to continue to exist."));
4067
4068                 msgd.run ();
4069                 return;
4070         }
4071
4072         ArdourDialog results (_("Clean-up"), true, false);
4073
4074         struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
4075                 CleanupResultsModelColumns() {
4076                         add (visible_name);
4077                         add (fullpath);
4078                 }
4079                 Gtk::TreeModelColumn<std::string> visible_name;
4080                 Gtk::TreeModelColumn<std::string> fullpath;
4081         };
4082
4083
4084         CleanupResultsModelColumns results_columns;
4085         Glib::RefPtr<Gtk::ListStore> results_model;
4086         Gtk::TreeView results_display;
4087
4088         results_model = ListStore::create (results_columns);
4089         results_display.set_model (results_model);
4090         results_display.append_column (list_title, results_columns.visible_name);
4091
4092         results_display.set_name ("CleanupResultsList");
4093         results_display.set_headers_visible (true);
4094         results_display.set_headers_clickable (false);
4095         results_display.set_reorderable (false);
4096
4097         Gtk::ScrolledWindow list_scroller;
4098         Gtk::Label txt;
4099         Gtk::VBox dvbox;
4100         Gtk::HBox dhbox;  // the hbox for the image and text
4101         Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
4102         Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO,  Gtk::ICON_SIZE_DIALOG));
4103
4104         dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
4105
4106         const string dead_directory = _session->session_directory().dead_path();
4107
4108         /* subst:
4109            %1 - number of files removed
4110            %2 - location of "dead"
4111            %3 - size of files affected
4112            %4 - prefix for "bytes" to produce sensible results (e.g. mega, kilo, giga)
4113         */
4114
4115         const char* bprefix;
4116         double space_adjusted = 0;
4117
4118         if (rep.space < 1000) {
4119                 bprefix = X_("");
4120                 space_adjusted = rep.space;
4121         } else if (rep.space < 1000000) {
4122                 bprefix = _("kilo");
4123                 space_adjusted = floorf((float)rep.space / 1000.0);
4124         } else if (rep.space < 1000000 * 1000) {
4125                 bprefix = _("mega");
4126                 space_adjusted = floorf((float)rep.space / (1000.0 * 1000.0));
4127         } else {
4128                 bprefix = _("giga");
4129                 space_adjusted = floorf((float)rep.space / (1000.0 * 1000 * 1000.0));
4130         }
4131
4132         if (msg_delete) {
4133                 txt.set_markup (string_compose (P_("\
4134 The following file was deleted from %2,\n\
4135 releasing %3 %4bytes of disk space", "\
4136 The following %1 files were deleted from %2,\n\
4137 releasing %3 %4bytes of disk space", removed),
4138                                         removed, Gtkmm2ext::markup_escape_text (dead_directory), space_adjusted, bprefix, PROGRAM_NAME));
4139         } else {
4140                 txt.set_markup (string_compose (P_("\
4141 The following file was not in use and \n\
4142 has been moved to: %2\n\n\
4143 After a restart of %5\n\n\
4144 <span face=\"mono\">Session -> Clean-up -> Flush Wastebasket</span>\n\n\
4145 will release an additional %3 %4bytes of disk space.\n", "\
4146 The following %1 files were not in use and \n\
4147 have been moved to: %2\n\n\
4148 After a restart of %5\n\n\
4149 <span face=\"mono\">Session -> Clean-up -> Flush Wastebasket</span>\n\n\
4150 will release an additional %3 %4bytes of disk space.\n", removed),
4151                                         removed, Gtkmm2ext::markup_escape_text (dead_directory), space_adjusted, bprefix, PROGRAM_NAME));
4152         }
4153
4154         dhbox.pack_start (*dimage, true, false, 5);
4155         dhbox.pack_start (txt, true, false, 5);
4156
4157         for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
4158                 TreeModel::Row row = *(results_model->append());
4159                 row[results_columns.visible_name] = *i;
4160                 row[results_columns.fullpath] = *i;
4161         }
4162
4163         list_scroller.add (results_display);
4164         list_scroller.set_size_request (-1, 150);
4165         list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
4166
4167         dvbox.pack_start (dhbox, true, false, 5);
4168         dvbox.pack_start (list_scroller, true, false, 5);
4169         ddhbox.pack_start (dvbox, true, false, 5);
4170
4171         results.get_vbox()->pack_start (ddhbox, true, false, 5);
4172         results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
4173         results.set_default_response (RESPONSE_CLOSE);
4174         results.set_position (Gtk::WIN_POS_MOUSE);
4175
4176         results_display.show();
4177         list_scroller.show();
4178         txt.show();
4179         dvbox.show();
4180         dhbox.show();
4181         ddhbox.show();
4182         dimage->show();
4183
4184         //results.get_vbox()->show();
4185         results.set_resizable (false);
4186
4187         results.run ();
4188
4189 }
4190
4191 void
4192 ARDOUR_UI::cleanup ()
4193 {
4194         if (_session == 0) {
4195                 /* shouldn't happen: menu item is insensitive */
4196                 return;
4197         }
4198
4199
4200         MessageDialog checker (_("Are you sure you want to clean-up?"),
4201                                 true,
4202                                 Gtk::MESSAGE_QUESTION,
4203                                 Gtk::BUTTONS_NONE);
4204
4205         checker.set_title (_("Clean-up"));
4206
4207         checker.set_secondary_text(_("Clean-up is a destructive operation.\n\
4208 ALL undo/redo information will be lost if you clean-up.\n\
4209 Clean-up will move all unused files to a \"dead\" location."));
4210
4211         checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
4212         checker.add_button (_("Clean-up"), RESPONSE_ACCEPT);
4213         checker.set_default_response (RESPONSE_CANCEL);
4214
4215         checker.set_name (_("CleanupDialog"));
4216         checker.set_wmclass (X_("ardour_cleanup"), PROGRAM_NAME);
4217         checker.set_position (Gtk::WIN_POS_MOUSE);
4218
4219         switch (checker.run()) {
4220         case RESPONSE_ACCEPT:
4221                 break;
4222         default:
4223                 return;
4224         }
4225         checker.hide();
4226
4227         ARDOUR::CleanupReport rep;
4228
4229         editor->prepare_for_cleanup ();
4230
4231         /* do not allow flush until a session is reloaded */
4232         ActionManager::get_action (X_("Main"), X_("FlushWastebasket"))->set_sensitive (false);
4233
4234         if (_session->cleanup_sources (rep)) {
4235                 editor->finish_cleanup ();
4236                 return;
4237         }
4238
4239         editor->finish_cleanup ();
4240
4241         display_cleanup_results (rep, _("Cleaned Files"), false);
4242 }
4243
4244 void
4245 ARDOUR_UI::flush_trash ()
4246 {
4247         if (_session == 0) {
4248                 /* shouldn't happen: menu item is insensitive */
4249                 return;
4250         }
4251
4252         ARDOUR::CleanupReport rep;
4253
4254         if (_session->cleanup_trash_sources (rep)) {
4255                 return;
4256         }
4257
4258         display_cleanup_results (rep, _("deleted file"), true);
4259 }
4260
4261 void
4262 ARDOUR_UI::cleanup_peakfiles ()
4263 {
4264         if (_session == 0) {
4265                 /* shouldn't happen: menu item is insensitive */
4266                 return;
4267         }
4268
4269         if (! _session->can_cleanup_peakfiles ()) {
4270                 return;
4271         }
4272
4273         // get all region-views in this session
4274         RegionSelection rs;
4275         TrackViewList empty;
4276         empty.clear();
4277         editor->get_regions_after(rs, (samplepos_t) 0, empty);
4278         std::list<RegionView*> views = rs.by_layer();
4279
4280         // remove displayed audio-region-views waveforms
4281         for (list<RegionView*>::iterator i = views.begin(); i != views.end(); ++i) {
4282                 AudioRegionView* arv = dynamic_cast<AudioRegionView*> (*i);
4283                 if (!arv) { continue ; }
4284                 arv->delete_waves();
4285         }
4286
4287         // cleanup peak files:
4288         // - stop pending peakfile threads
4289         // - close peakfiles if any
4290         // - remove peak dir in session
4291         // - setup peakfiles (background thread)
4292         _session->cleanup_peakfiles ();
4293
4294         // re-add waves to ARV
4295         for (list<RegionView*>::iterator i = views.begin(); i != views.end(); ++i) {
4296                 AudioRegionView* arv = dynamic_cast<AudioRegionView*> (*i);
4297                 if (!arv) { continue ; }
4298                 arv->create_waves();
4299         }
4300 }
4301
4302 PresentationInfo::order_t
4303 ARDOUR_UI::translate_order (RouteDialogs::InsertAt place)
4304 {
4305         if (editor->get_selection().tracks.empty()) {
4306                 return place == RouteDialogs::First ? 0 : PresentationInfo::max_order;
4307         }
4308
4309         PresentationInfo::order_t order_hint = PresentationInfo::max_order;
4310
4311         /*
4312           we want the new routes to have their order keys set starting from
4313           the highest order key in the selection + 1 (if available).
4314         */
4315
4316         if (place == RouteDialogs::AfterSelection) {
4317                 RouteTimeAxisView *rtav = dynamic_cast<RouteTimeAxisView*> (editor->get_selection().tracks.back());
4318                 if (rtav) {
4319                         order_hint = rtav->route()->presentation_info().order();
4320                         order_hint++;
4321                 }
4322         } else if (place == RouteDialogs::BeforeSelection) {
4323                 RouteTimeAxisView *rtav = dynamic_cast<RouteTimeAxisView*> (editor->get_selection().tracks.front());
4324                 if (rtav) {
4325                         order_hint = rtav->route()->presentation_info().order();
4326                 }
4327         } else if (place == RouteDialogs::First) {
4328                 order_hint = 0;
4329         } else {
4330                 /* leave order_hint at max_order */
4331         }
4332
4333         return order_hint;
4334 }
4335
4336 void
4337 ARDOUR_UI::start_duplicate_routes ()
4338 {
4339         if (!duplicate_routes_dialog) {
4340                 duplicate_routes_dialog = new DuplicateRouteDialog;
4341         }
4342
4343         if (duplicate_routes_dialog->restart (_session)) {
4344                 return;
4345         }
4346
4347         duplicate_routes_dialog->present ();
4348 }
4349
4350 void
4351 ARDOUR_UI::add_route ()
4352 {
4353         if (!add_route_dialog.get (false)) {
4354                 add_route_dialog->signal_response().connect (sigc::mem_fun (*this, &ARDOUR_UI::add_route_dialog_response));
4355         }
4356
4357         if (!_session) {
4358                 return;
4359         }
4360
4361         if (add_route_dialog->is_visible()) {
4362                 /* we're already doing this */
4363                 return;
4364         }
4365
4366         add_route_dialog->set_position (WIN_POS_MOUSE);
4367         add_route_dialog->present();
4368 }
4369
4370 void
4371 ARDOUR_UI::add_route_dialog_response (int r)
4372 {
4373         if (!_session) {
4374                 warning << _("You cannot add tracks or busses without a session already loaded.") << endmsg;
4375                 return;
4376         }
4377
4378         if (!AudioEngine::instance()->running ()) {
4379                 switch (r) {
4380                         case AddRouteDialog::Add:
4381                         case AddRouteDialog::AddAndClose:
4382                                 break;
4383                         default:
4384                                 return;
4385                 }
4386                 add_route_dialog->ArdourDialog::on_response (r);
4387                 ARDOUR_UI_UTILS::engine_is_running ();
4388                 return;
4389         }
4390
4391         int count;
4392
4393         switch (r) {
4394         case AddRouteDialog::Add:
4395                 add_route_dialog->reset_name_edited ();
4396                 break;
4397         case AddRouteDialog::AddAndClose:
4398                 add_route_dialog->ArdourDialog::on_response (r);
4399                 break;
4400         default:
4401                 add_route_dialog->ArdourDialog::on_response (r);
4402                 return;
4403         }
4404
4405         std::string template_path = add_route_dialog->get_template_path();
4406         if (!template_path.empty() && template_path.substr (0, 11) == "urn:ardour:") {
4407                 meta_route_setup (template_path.substr (11));
4408                 return;
4409         }
4410
4411         if ((count = add_route_dialog->count()) <= 0) {
4412                 return;
4413         }
4414
4415         PresentationInfo::order_t order = translate_order (add_route_dialog->insert_at());
4416         const string name_template = add_route_dialog->name_template ();
4417         DisplaySuspender ds;
4418
4419         if (!template_path.empty ()) {
4420                 if (add_route_dialog->name_template_is_default ()) {
4421                         _session->new_route_from_template (count, order, template_path, string ());
4422                 } else {
4423                         _session->new_route_from_template (count, order, template_path, name_template);
4424                 }
4425                 return;
4426         }
4427
4428         ChanCount input_chan= add_route_dialog->channels ();
4429         ChanCount output_chan;
4430         PluginInfoPtr instrument = add_route_dialog->requested_instrument ();
4431         RouteGroup* route_group = add_route_dialog->route_group ();
4432         AutoConnectOption oac = Config->get_output_auto_connect();
4433         bool strict_io = add_route_dialog->use_strict_io ();
4434
4435         if (oac & AutoConnectMaster) {
4436                 output_chan.set (DataType::AUDIO, (_session->master_out() ? _session->master_out()->n_inputs().n_audio() : input_chan.n_audio()));
4437                 output_chan.set (DataType::MIDI, 0);
4438         } else {
4439                 output_chan = input_chan;
4440         }
4441
4442         /* XXX do something with name template */
4443
4444         Session::ProcessorChangeBlocker pcb (_session);
4445
4446         switch (add_route_dialog->type_wanted()) {
4447         case AddRouteDialog::AudioTrack:
4448                 session_add_audio_route (true, input_chan.n_audio(), output_chan.n_audio(), add_route_dialog->mode(), route_group, count, name_template, strict_io, order);
4449                 break;
4450         case AddRouteDialog::MidiTrack:
4451                 session_add_midi_route (true, route_group, count, name_template, strict_io, instrument, 0, order);
4452                 break;
4453         case AddRouteDialog::MixedTrack:
4454                 session_add_mixed_track (input_chan, output_chan, route_group, count, name_template, strict_io, instrument, 0, order);
4455                 break;
4456         case AddRouteDialog::AudioBus:
4457                 session_add_audio_route (false, input_chan.n_audio(), output_chan.n_audio(), ARDOUR::Normal, route_group, count, name_template, strict_io, order);
4458                 break;
4459         case AddRouteDialog::MidiBus:
4460                 session_add_midi_bus (route_group, count, name_template, strict_io, instrument, 0, order);
4461                 break;
4462         case AddRouteDialog::VCAMaster:
4463                 _session->vca_manager().create_vca (count, name_template);
4464                 break;
4465         case AddRouteDialog::FoldbackBus:
4466                 session_add_foldback_bus (input_chan.n_audio(), count, name_template);
4467                 break;
4468         }
4469 }
4470
4471 void
4472 ARDOUR_UI::stop_video_server (bool ask_confirm)
4473 {
4474         if (!video_server_process && ask_confirm) {
4475                 warning << string_compose (_("Video-Server was not launched by %1. The request to stop it is ignored."), PROGRAM_NAME) << endmsg;
4476         }
4477         if (video_server_process) {
4478                 if(ask_confirm) {
4479                         ArdourDialog confirm (_("Stop Video-Server"), true);
4480                         Label m (_("Do you really want to stop the Video Server?"));
4481                         confirm.get_vbox()->pack_start (m, true, true);
4482                         confirm.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
4483                         confirm.add_button (_("Yes, Stop It"), Gtk::RESPONSE_ACCEPT);
4484                         confirm.show_all ();
4485                         if (confirm.run() == RESPONSE_CANCEL) {
4486                                 return;
4487                         }
4488                 }
4489                 delete video_server_process;
4490                 video_server_process =0;
4491         }
4492 }
4493
4494 void
4495 ARDOUR_UI::start_video_server_menu (Gtk::Window* float_window)
4496 {
4497   ARDOUR_UI::start_video_server( float_window, true);
4498 }
4499
4500 bool
4501 ARDOUR_UI::start_video_server (Gtk::Window* float_window, bool popup_msg)
4502 {
4503         if (!_session) {
4504                 return false;
4505         }
4506         if (popup_msg) {
4507                 if (ARDOUR_UI::instance()->video_timeline->check_server()) {
4508                         if (video_server_process) {
4509                                 popup_error(_("The Video Server is already started."));
4510                         } else {
4511                                 popup_error(_("An external Video Server is configured and can be reached. Not starting a new instance."));
4512                         }
4513                 }
4514         }
4515
4516         int firsttime = 0;
4517         while (!ARDOUR_UI::instance()->video_timeline->check_server()) {
4518                 if (firsttime++) {
4519                         warning << _("Could not connect to the Video Server. Start it or configure its access URL in Preferences.") << endmsg;
4520                 }
4521                 VideoServerDialog *video_server_dialog = new VideoServerDialog (_session);
4522                 if (float_window) {
4523                         video_server_dialog->set_transient_for (*float_window);
4524                 }
4525
4526                 if (!Config->get_show_video_server_dialog() && firsttime < 2) {
4527                         video_server_dialog->hide();
4528                 } else {
4529                         ResponseType r = (ResponseType) video_server_dialog->run ();
4530                         video_server_dialog->hide();
4531                         if (r != RESPONSE_ACCEPT) { return false; }
4532                         if (video_server_dialog->show_again()) {
4533                                 Config->set_show_video_server_dialog(false);
4534                         }
4535                 }
4536
4537                 std::string icsd_exec = video_server_dialog->get_exec_path();
4538                 std::string icsd_docroot = video_server_dialog->get_docroot();
4539 #ifndef PLATFORM_WINDOWS
4540                 if (icsd_docroot.empty()) {
4541                         icsd_docroot = VideoUtils::video_get_docroot (Config);
4542                 }
4543 #endif
4544
4545                 GStatBuf sb;
4546 #ifdef PLATFORM_WINDOWS
4547                 if (VideoUtils::harvid_version >= 0x000802 && icsd_docroot.empty()) {
4548                         /* OK, allow all drive letters */
4549                 } else
4550 #endif
4551                 if (g_lstat (icsd_docroot.c_str(), &sb) != 0 || !S_ISDIR(sb.st_mode)) {
4552                         warning << _("Specified docroot is not an existing directory.") << endmsg;
4553                         continue;
4554                 }
4555 #ifndef PLATFORM_WINDOWS
4556                 if ( (g_lstat (icsd_exec.c_str(), &sb) != 0)
4557                      || (sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == 0 ) {
4558                         warning << _("Given Video Server is not an executable file.") << endmsg;
4559                         continue;
4560                 }
4561 #else
4562                 if ( (g_lstat (icsd_exec.c_str(), &sb) != 0)
4563                      || (sb.st_mode & (S_IXUSR)) == 0 ) {
4564                         warning << _("Given Video Server is not an executable file.") << endmsg;
4565                         continue;
4566                 }
4567 #endif
4568
4569                 char **argp;
4570                 argp=(char**) calloc(9,sizeof(char*));
4571                 argp[0] = strdup(icsd_exec.c_str());
4572                 argp[1] = strdup("-P");
4573                 argp[2] = (char*) calloc(16,sizeof(char)); snprintf(argp[2], 16, "%s", video_server_dialog->get_listenaddr().c_str());
4574                 argp[3] = strdup("-p");
4575                 argp[4] = (char*) calloc(6,sizeof(char)); snprintf(argp[4], 6, "%i", video_server_dialog->get_listenport());
4576                 argp[5] = strdup("-C");
4577                 argp[6] = (char*) calloc(6,sizeof(char)); snprintf(argp[6], 6, "%i", video_server_dialog->get_cachesize());
4578                 argp[7] = strdup(icsd_docroot.c_str());
4579                 argp[8] = 0;
4580                 stop_video_server();
4581
4582 #ifdef PLATFORM_WINDOWS
4583                 if (VideoUtils::harvid_version >= 0x000802 && icsd_docroot.empty()) {
4584                         /* OK, allow all drive letters */
4585                 } else
4586 #endif
4587                 if (icsd_docroot == X_("/") || icsd_docroot == X_("C:\\")) {
4588                         Config->set_video_advanced_setup(false);
4589                 } else {
4590                         std::string url_str = "http://127.0.0.1:" + to_string(video_server_dialog->get_listenport()) + "/";
4591                         Config->set_video_server_url(url_str);
4592                         Config->set_video_server_docroot(icsd_docroot);
4593                         Config->set_video_advanced_setup(true);
4594                 }
4595
4596                 if (video_server_process) {
4597                         delete video_server_process;
4598                 }
4599
4600                 video_server_process = new ARDOUR::SystemExec(icsd_exec, argp);
4601                 if (video_server_process->start()) {
4602                         warning << _("Cannot launch the video-server") << endmsg;
4603                         continue;
4604                 }
4605                 int timeout = 120; // 6 sec
4606                 while (!ARDOUR_UI::instance()->video_timeline->check_server()) {
4607                         Glib::usleep (50000);
4608                         gui_idle_handler();
4609                         if (--timeout <= 0 || !video_server_process->is_running()) break;
4610                 }
4611                 if (timeout <= 0) {
4612                         warning << _("Video-server was started but does not respond to requests...") << endmsg;
4613                 } else {
4614                         if (!ARDOUR_UI::instance()->video_timeline->check_server_docroot()) {
4615                                 delete video_server_process;
4616                                 video_server_process = 0;
4617                         }
4618                 }
4619         }
4620         return true;
4621 }
4622
4623 void
4624 ARDOUR_UI::add_video (Gtk::Window* float_window)
4625 {
4626         if (!_session) {
4627                 return;
4628         }
4629
4630         if (!start_video_server(float_window, false)) {
4631                 warning << _("Could not connect to the Video Server. Start it or configure its access URL in Preferences.") << endmsg;
4632                 return;
4633         }
4634
4635         if (float_window) {
4636                 add_video_dialog->set_transient_for (*float_window);
4637         }
4638
4639         if (add_video_dialog->is_visible()) {
4640                 /* we're already doing this */
4641                 return;
4642         }
4643
4644         ResponseType r = (ResponseType) add_video_dialog->run ();
4645         add_video_dialog->hide();
4646         if (r != RESPONSE_ACCEPT) { return; }
4647
4648         bool local_file, orig_local_file;
4649         std::string path = add_video_dialog->file_name(local_file);
4650
4651         std::string orig_path = path;
4652         orig_local_file = local_file;
4653
4654         bool auto_set_session_fps = add_video_dialog->auto_set_session_fps();
4655
4656         if (local_file && !Glib::file_test(path, Glib::FILE_TEST_EXISTS)) {
4657                 warning << string_compose(_("could not open %1"), path) << endmsg;
4658                 return;
4659         }
4660         if (!local_file && path.length() == 0) {
4661                 warning << _("no video-file selected") << endmsg;
4662                 return;
4663         }
4664
4665         std::string audio_from_video;
4666         bool detect_ltc = false;
4667
4668         switch (add_video_dialog->import_option()) {
4669                 case VTL_IMPORT_TRANSCODE:
4670                         {
4671                                 TranscodeVideoDialog *transcode_video_dialog;
4672                                 transcode_video_dialog = new TranscodeVideoDialog (_session, path);
4673                                 ResponseType r = (ResponseType) transcode_video_dialog->run ();
4674                                 transcode_video_dialog->hide();
4675                                 if (r != RESPONSE_ACCEPT) {
4676                                         delete transcode_video_dialog;
4677                                         return;
4678                                 }
4679
4680                                 audio_from_video = transcode_video_dialog->get_audiofile();
4681
4682                                 if (!audio_from_video.empty() && transcode_video_dialog->detect_ltc()) {
4683                                         detect_ltc = true;
4684                                 }
4685                                 else if (!audio_from_video.empty()) {
4686                                         editor->embed_audio_from_video(
4687                                                         audio_from_video,
4688                                                         video_timeline->get_offset(),
4689                                                         (transcode_video_dialog->import_option() != VTL_IMPORT_NO_VIDEO)
4690                                                         );
4691                                 }
4692                                 switch (transcode_video_dialog->import_option()) {
4693                                         case VTL_IMPORT_TRANSCODED:
4694                                                 path = transcode_video_dialog->get_filename();
4695                                                 local_file = true;
4696                                                 break;
4697                                         case VTL_IMPORT_REFERENCE:
4698                                                 break;
4699                                         default:
4700                                                 delete transcode_video_dialog;
4701                                                 return;
4702                                 }
4703                                 delete transcode_video_dialog;
4704                         }
4705                         break;
4706                 default:
4707                 case VTL_IMPORT_NONE:
4708                         break;
4709         }
4710
4711         /* strip _session->session_directory().video_path() from video file if possible */
4712         if (local_file && !path.compare(0, _session->session_directory().video_path().size(), _session->session_directory().video_path())) {
4713                  path=path.substr(_session->session_directory().video_path().size());
4714                  if (path.at(0) == G_DIR_SEPARATOR) {
4715                          path=path.substr(1);
4716                  }
4717         }
4718
4719         video_timeline->set_update_session_fps(auto_set_session_fps);
4720
4721         if (video_timeline->video_file_info(path, local_file)) {
4722                 XMLNode* node = new XMLNode(X_("Videotimeline"));
4723                 node->set_property (X_("Filename"), path);
4724                 node->set_property (X_("AutoFPS"), auto_set_session_fps);
4725                 node->set_property (X_("LocalFile"), local_file);
4726                 if (orig_local_file) {
4727                         node->set_property (X_("OriginalVideoFile"), orig_path);
4728                 } else {
4729                         node->remove_property (X_("OriginalVideoFile"));
4730                 }
4731                 _session->add_extra_xml (*node);
4732                 _session->set_dirty ();
4733
4734                 if (!audio_from_video.empty() && detect_ltc) {
4735                         std::vector<LTCFileReader::LTCMap> ltc_seq;
4736
4737                         try {
4738                                 /* TODO ask user about TV standard (LTC alignment if any) */
4739                                 LTCFileReader ltcr (audio_from_video, video_timeline->get_video_file_fps());
4740                                 /* TODO ASK user which channel:  0 .. ltcr->channels() - 1 */
4741
4742                                 ltc_seq = ltcr.read_ltc (/*channel*/ 0, /*max LTC samples to decode*/ 15);
4743
4744                                 /* TODO seek near end of file, and read LTC until end.
4745                                  * if it fails to find any LTC samples, scan complete file
4746                                  *
4747                                  * calculate drift of LTC compared to video-duration,
4748                                  * ask user for reference (timecode from start/mid/end)
4749                                  */
4750                         } catch (...) {
4751                                 // LTCFileReader will have written error messages
4752                         }
4753
4754                         ::g_unlink(audio_from_video.c_str());
4755
4756                         if (ltc_seq.size() == 0) {
4757                                 PBD::error << _("No LTC detected, video will not be aligned.") << endmsg;
4758                         } else {
4759                                 /* the very first TC in the file is somteimes not aligned properly */
4760                                 int i = ltc_seq.size() -1;
4761                                 ARDOUR::sampleoffset_t video_start_offset =
4762                                         _session->nominal_sample_rate() * (ltc_seq[i].timecode_sec - ltc_seq[i].framepos_sec);
4763                                 PBD::info << string_compose (_("Align video-start to %1 [samples]"), video_start_offset) << endmsg;
4764                                 video_timeline->set_offset(video_start_offset);
4765                         }
4766                 }
4767
4768                 _session->maybe_update_session_range(
4769                         std::max(video_timeline->get_offset(), (ARDOUR::sampleoffset_t) 0),
4770                         std::max(video_timeline->get_offset() + video_timeline->get_duration(), (ARDOUR::sampleoffset_t) 0));
4771
4772
4773                 if (add_video_dialog->launch_xjadeo() && local_file) {
4774                         editor->set_xjadeo_sensitive(true);
4775                         editor->toggle_xjadeo_proc(1);
4776                 } else {
4777                         editor->toggle_xjadeo_proc(0);
4778                 }
4779                 editor->toggle_ruler_video(true);
4780         }
4781 }
4782
4783 void
4784 ARDOUR_UI::remove_video ()
4785 {
4786         video_timeline->close_session();
4787         editor->toggle_ruler_video(false);
4788
4789         /* reset state */
4790         video_timeline->set_offset_locked(false);
4791         video_timeline->set_offset(0);
4792
4793         /* delete session state */
4794         XMLNode* node = new XMLNode(X_("Videotimeline"));
4795         _session->add_extra_xml(*node);
4796         node = new XMLNode(X_("Videomonitor"));
4797         _session->add_extra_xml(*node);
4798         node = new XMLNode(X_("Videoexport"));
4799         _session->add_extra_xml(*node);
4800         stop_video_server();
4801 }
4802
4803 void
4804 ARDOUR_UI::flush_videotimeline_cache (bool localcacheonly)
4805 {
4806         if (localcacheonly) {
4807                 video_timeline->vmon_update();
4808         } else {
4809                 video_timeline->flush_cache();
4810         }
4811         editor->queue_visual_videotimeline_update();
4812 }
4813
4814 void
4815 ARDOUR_UI::export_video (bool range)
4816 {
4817         if (ARDOUR::Config->get_show_video_export_info()) {
4818                 ExportVideoInfobox infobox (_session);
4819                 Gtk::ResponseType rv = (Gtk::ResponseType) infobox.run();
4820                 if (infobox.show_again()) {
4821                         ARDOUR::Config->set_show_video_export_info(false);
4822                 }
4823                 switch (rv) {
4824                         case GTK_RESPONSE_YES:
4825                                 PBD::open_uri (ARDOUR::Config->get_reference_manual_url() + "/video-timeline/operations/#export");
4826                                 break;
4827                         default:
4828                                 break;
4829                 }
4830         }
4831         export_video_dialog->set_session (_session);
4832         export_video_dialog->apply_state(editor->get_selection().time, range);
4833         export_video_dialog->run ();
4834         export_video_dialog->hide ();
4835 }
4836
4837 XMLNode*
4838 ARDOUR_UI::preferences_settings () const
4839 {
4840         XMLNode* node = 0;
4841
4842         if (_session) {
4843                 node = _session->instant_xml(X_("Preferences"));
4844         } else {
4845                 node = Config->instant_xml(X_("Preferences"));
4846         }
4847
4848         if (!node) {
4849                 node = new XMLNode (X_("Preferences"));
4850         }
4851
4852         return node;
4853 }
4854
4855 XMLNode*
4856 ARDOUR_UI::mixer_settings () const
4857 {
4858         XMLNode* node = 0;
4859
4860         if (_session) {
4861                 node = _session->instant_xml(X_("Mixer"));
4862         } else {
4863                 node = Config->instant_xml(X_("Mixer"));
4864         }
4865
4866         if (!node) {
4867                 node = new XMLNode (X_("Mixer"));
4868         }
4869
4870         return node;
4871 }
4872
4873 XMLNode*
4874 ARDOUR_UI::main_window_settings () const
4875 {
4876         XMLNode* node = 0;
4877
4878         if (_session) {
4879                 node = _session->instant_xml(X_("Main"));
4880         } else {
4881                 node = Config->instant_xml(X_("Main"));
4882         }
4883
4884         if (!node) {
4885                 if (getenv("ARDOUR_INSTANT_XML_PATH")) {
4886                         node = Config->instant_xml(getenv("ARDOUR_INSTANT_XML_PATH"));
4887                 }
4888         }
4889
4890         if (!node) {
4891                 node = new XMLNode (X_("Main"));
4892         }
4893
4894         return node;
4895 }
4896
4897 XMLNode*
4898 ARDOUR_UI::editor_settings () const
4899 {
4900         XMLNode* node = 0;
4901
4902         if (_session) {
4903                 node = _session->instant_xml(X_("Editor"));
4904         } else {
4905                 node = Config->instant_xml(X_("Editor"));
4906         }
4907
4908         if (!node) {
4909                 if (getenv("ARDOUR_INSTANT_XML_PATH")) {
4910                         node = Config->instant_xml(getenv("ARDOUR_INSTANT_XML_PATH"));
4911                 }
4912         }
4913
4914         if (!node) {
4915                 node = new XMLNode (X_("Editor"));
4916         }
4917
4918         return node;
4919 }
4920
4921 XMLNode*
4922 ARDOUR_UI::keyboard_settings () const
4923 {
4924         XMLNode* node = 0;
4925
4926         node = Config->extra_xml(X_("Keyboard"));
4927
4928         if (!node) {
4929                 node = new XMLNode (X_("Keyboard"));
4930         }
4931
4932         return node;
4933 }
4934
4935 void
4936 ARDOUR_UI::create_xrun_marker (samplepos_t where)
4937 {
4938         if (_session) {
4939                 Location *location = new Location (*_session, where, where, _("xrun"), Location::IsMark, 0);
4940                 _session->locations()->add (location);
4941         }
4942 }
4943
4944 void
4945 ARDOUR_UI::halt_on_xrun_message ()
4946 {
4947         cerr << "HALT on xrun\n";
4948         MessageDialog msg (_main_window, _("Recording was stopped because your system could not keep up."));
4949         msg.run ();
4950 }
4951
4952 void
4953 ARDOUR_UI::xrun_handler (samplepos_t where)
4954 {
4955         if (!_session) {
4956                 return;
4957         }
4958
4959         ENSURE_GUI_THREAD (*this, &ARDOUR_UI::xrun_handler, where)
4960
4961         if (_session && Config->get_create_xrun_marker() && _session->actively_recording()) {
4962                 create_xrun_marker(where);
4963         }
4964
4965         if (_session && Config->get_stop_recording_on_xrun() && _session->actively_recording()) {
4966                 halt_on_xrun_message ();
4967         }
4968 }
4969
4970 void
4971 ARDOUR_UI::disk_overrun_handler ()
4972 {
4973         ENSURE_GUI_THREAD (*this, &ARDOUR_UI::disk_overrun_handler)
4974
4975         if (!have_disk_speed_dialog_displayed) {
4976                 have_disk_speed_dialog_displayed = true;
4977                 MessageDialog* msg = new MessageDialog (_main_window, string_compose (_("\
4978 The disk system on your computer\n\
4979 was not able to keep up with %1.\n\
4980 \n\
4981 Specifically, it failed to write data to disk\n\
4982 quickly enough to keep up with recording.\n"), PROGRAM_NAME));
4983                 msg->signal_response().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
4984                 msg->show ();
4985         }
4986 }
4987
4988
4989 /* TODO: this is getting elaborate enough to warrant being split into a dedicated class */
4990 static MessageDialog *scan_dlg = NULL;
4991 static ProgressBar   *scan_pbar = NULL;
4992 static HBox          *scan_tbox = NULL;
4993 static Gtk::Button   *scan_timeout_button;
4994
4995 void
4996 ARDOUR_UI::cancel_plugin_scan ()
4997 {
4998         PluginManager::instance().cancel_plugin_scan();
4999 }
5000
5001 void
5002 ARDOUR_UI::cancel_plugin_timeout ()
5003 {
5004         PluginManager::instance().cancel_plugin_timeout();
5005         scan_timeout_button->set_sensitive (false);
5006 }
5007
5008 void
5009 ARDOUR_UI::plugin_scan_timeout (int timeout)
5010 {
5011         if (!scan_dlg || !scan_dlg->is_mapped() || !scan_pbar) {
5012                 return;
5013         }
5014         if (timeout > 0) {
5015                 scan_pbar->set_sensitive (false);
5016                 scan_timeout_button->set_sensitive (true);
5017                 scan_pbar->set_fraction ((float) timeout / (float) Config->get_vst_scan_timeout());
5018                 scan_tbox->show();
5019         } else {
5020                 scan_pbar->set_sensitive (false);
5021                 scan_timeout_button->set_sensitive (false);
5022         }
5023         gui_idle_handler();
5024 }
5025
5026 void
5027 ARDOUR_UI::plugin_scan_dialog (std::string type, std::string plugin, bool can_cancel)
5028 {
5029         if (type == X_("closeme") && !(scan_dlg && scan_dlg->is_mapped())) {
5030                 return;
5031         }
5032
5033         const bool cancelled = PluginManager::instance().cancelled();
5034         if (type != X_("closeme") && (!UIConfiguration::instance().get_show_plugin_scan_window()) && !_initial_verbose_plugin_scan) {
5035                 if (cancelled && scan_dlg->is_mapped()) {
5036                         scan_dlg->hide();
5037                         gui_idle_handler();
5038                         return;
5039                 }
5040                 if (cancelled || !can_cancel) {
5041                         return;
5042                 }
5043         }
5044
5045         static Gtk::Button *cancel_button;
5046         if (!scan_dlg) {
5047                 scan_dlg = new MessageDialog("", false, MESSAGE_INFO, BUTTONS_NONE); // TODO manage
5048                 VBox* vbox = scan_dlg->get_vbox();
5049                 vbox->set_size_request(400,-1);
5050                 scan_dlg->set_title (_("Scanning for plugins"));
5051
5052                 cancel_button = manage(new Gtk::Button(_("Cancel plugin scan")));
5053                 cancel_button->set_name ("EditorGTKButton");
5054                 cancel_button->signal_clicked().connect ( mem_fun (*this, &ARDOUR_UI::cancel_plugin_scan) );
5055                 cancel_button->show();
5056
5057                 scan_dlg->get_vbox()->pack_start ( *cancel_button, PACK_SHRINK);
5058
5059                 scan_tbox = manage( new HBox() );
5060
5061                 scan_timeout_button = manage(new Gtk::Button(_("Stop Timeout")));
5062                 scan_timeout_button->set_name ("EditorGTKButton");
5063                 scan_timeout_button->signal_clicked().connect ( mem_fun (*this, &ARDOUR_UI::cancel_plugin_timeout) );
5064                 scan_timeout_button->show();
5065
5066                 scan_pbar = manage(new ProgressBar());
5067                 scan_pbar->set_orientation(Gtk::PROGRESS_RIGHT_TO_LEFT);
5068                 scan_pbar->set_text(_("Scan Timeout"));
5069                 scan_pbar->show();
5070
5071                 scan_tbox->pack_start (*scan_pbar, PACK_EXPAND_WIDGET, 4);
5072                 scan_tbox->pack_start (*scan_timeout_button, PACK_SHRINK, 4);
5073
5074                 scan_dlg->get_vbox()->pack_start (*scan_tbox, PACK_SHRINK, 4);
5075         }
5076
5077         assert(scan_dlg && scan_tbox && cancel_button);
5078
5079         if (type == X_("closeme")) {
5080                 scan_tbox->hide();
5081                 scan_dlg->hide();
5082         } else {
5083                 scan_dlg->set_message(type + ": " + Glib::path_get_basename(plugin));
5084                 scan_dlg->show();
5085         }
5086         if (!can_cancel || !cancelled) {
5087                 scan_timeout_button->set_sensitive(false);
5088         }
5089         cancel_button->set_sensitive(can_cancel && !cancelled);
5090
5091         gui_idle_handler();
5092 }
5093
5094 void
5095 ARDOUR_UI::gui_idle_handler ()
5096 {
5097         int timeout = 30;
5098         /* due to idle calls, gtk_events_pending() may always return true */
5099         while (gtk_events_pending() && --timeout) {
5100                 gtk_main_iteration ();
5101         }
5102 }
5103
5104 void
5105 ARDOUR_UI::disk_underrun_handler ()
5106 {
5107         ENSURE_GUI_THREAD (*this, &ARDOUR_UI::disk_underrun_handler)
5108
5109         if (!have_disk_speed_dialog_displayed) {
5110                 have_disk_speed_dialog_displayed = true;
5111                 MessageDialog* msg = new MessageDialog (
5112                         _main_window, string_compose (_("The disk system on your computer\n\
5113 was not able to keep up with %1.\n\
5114 \n\
5115 Specifically, it failed to read data from disk\n\
5116 quickly enough to keep up with playback.\n"), PROGRAM_NAME));
5117                 msg->signal_response().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
5118                 msg->show ();
5119         }
5120 }
5121
5122 void
5123 ARDOUR_UI::disk_speed_dialog_gone (int /*ignored_response*/, MessageDialog* msg)
5124 {
5125         have_disk_speed_dialog_displayed = false;
5126         delete msg;
5127 }
5128
5129 void
5130 ARDOUR_UI::session_dialog (std::string msg)
5131 {
5132         ENSURE_GUI_THREAD (*this, &ARDOUR_UI::session_dialog, msg)
5133
5134         MessageDialog* d;
5135
5136         d = new MessageDialog (msg, false, MESSAGE_INFO, BUTTONS_OK, true);
5137         d->show_all ();
5138         d->run ();
5139         delete d;
5140 }
5141
5142 int
5143 ARDOUR_UI::pending_state_dialog ()
5144 {
5145         HBox* hbox = manage (new HBox());
5146         Image* image = manage (new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG));
5147         ArdourDialog dialog (_("Crash Recovery"), true);
5148         Label  message (string_compose (_("\
5149 This session appears to have been in the\n\
5150 middle of recording when %1 or\n\
5151 the computer was shutdown.\n\
5152 \n\
5153 %1 can recover any captured audio for\n\
5154 you, or it can ignore it. Please decide\n\
5155 what you would like to do.\n"), PROGRAM_NAME));
5156         image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
5157         hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
5158         hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
5159         dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
5160         dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
5161         dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
5162         dialog.set_default_response (RESPONSE_ACCEPT);
5163         dialog.set_position (WIN_POS_CENTER);
5164         message.show();
5165         image->show();
5166         hbox->show();
5167
5168         switch (dialog.run ()) {
5169         case RESPONSE_ACCEPT:
5170                 return 1;
5171         default:
5172                 return 0;
5173         }
5174 }
5175
5176 int
5177 ARDOUR_UI::sr_mismatch_dialog (samplecnt_t desired, samplecnt_t actual)
5178 {
5179         HBox* hbox = new HBox();
5180         Image* image = new Image (Stock::DIALOG_WARNING, ICON_SIZE_DIALOG);
5181         ArdourDialog dialog (_("Sample Rate Mismatch"), true);
5182         Label  message (string_compose (_("\
5183 This session was created with a sample rate of %1 Hz, but\n\
5184 %2 is currently running at %3 Hz.  If you load this session,\n\
5185 audio may be played at the wrong sample rate.\n"), desired, PROGRAM_NAME, actual));
5186
5187         image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
5188         hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
5189         hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
5190         dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
5191         dialog.add_button (_("Do not load session"), RESPONSE_REJECT);
5192         dialog.add_button (_("Load session anyway"), RESPONSE_ACCEPT);
5193         dialog.set_default_response (RESPONSE_ACCEPT);
5194         dialog.set_position (WIN_POS_CENTER);
5195         message.show();
5196         image->show();
5197         hbox->show();
5198
5199         switch (dialog.run()) {
5200         case RESPONSE_ACCEPT:
5201                 return 0;
5202         default:
5203                 break;
5204         }
5205
5206         return 1;
5207 }
5208
5209 void
5210 ARDOUR_UI::sr_mismatch_message (samplecnt_t desired, samplecnt_t actual)
5211 {
5212         MessageDialog msg (string_compose (_("\
5213 This session was created with a sample rate of %1 Hz, but\n\
5214 %2 is currently running at %3 Hz.\n\
5215 Audio will be recorded and played at the wrong sample rate.\n\
5216 Re-Configure the Audio Engine in\n\
5217 Menu > Window > Audio/Midi Setup"),
5218                                 desired, PROGRAM_NAME, actual),
5219                         true,
5220                         Gtk::MESSAGE_WARNING);
5221         msg.run ();
5222 }
5223
5224 void
5225 ARDOUR_UI::use_config ()
5226 {
5227         XMLNode* node = Config->extra_xml (X_("TransportControllables"));
5228         if (node) {
5229                 set_transport_controllable_state (*node);
5230         }
5231 }
5232
5233 void
5234 ARDOUR_UI::update_transport_clocks (samplepos_t pos)
5235 {
5236         switch (UIConfiguration::instance().get_primary_clock_delta_mode()) {
5237                 case NoDelta:
5238                         primary_clock->set (pos);
5239                         break;
5240                 case DeltaEditPoint:
5241                         primary_clock->set (pos, false, editor->get_preferred_edit_position (EDIT_IGNORE_PHEAD));
5242                         break;
5243                 case DeltaOriginMarker:
5244                         {
5245                                 Location* loc = _session->locations()->clock_origin_location ();
5246                                 primary_clock->set (pos, false, loc ? loc->start() : 0);
5247                         }
5248                         break;
5249         }
5250
5251         switch (UIConfiguration::instance().get_secondary_clock_delta_mode()) {
5252                 case NoDelta:
5253                         secondary_clock->set (pos);
5254                         break;
5255                 case DeltaEditPoint:
5256                         secondary_clock->set (pos, false, editor->get_preferred_edit_position (EDIT_IGNORE_PHEAD));
5257                         break;
5258                 case DeltaOriginMarker:
5259                         {
5260                                 Location* loc = _session->locations()->clock_origin_location ();
5261                                 secondary_clock->set (pos, false, loc ? loc->start() : 0);
5262                         }
5263                         break;
5264         }
5265
5266         if (big_clock_window) {
5267                 big_clock->set (pos);
5268         }
5269         ARDOUR_UI::instance()->video_timeline->manual_seek_video_monitor(pos);
5270 }
5271
5272
5273 void
5274 ARDOUR_UI::record_state_changed ()
5275 {
5276         ENSURE_GUI_THREAD (*this, &ARDOUR_UI::record_state_changed);
5277
5278         if (!_session) {
5279                 /* why bother - the clock isn't visible */
5280                 return;
5281         }
5282
5283         ActionManager::set_sensitive (ActionManager::rec_sensitive_actions, !_session->actively_recording());
5284
5285         if (big_clock_window) {
5286                 if (_session->record_status () == Session::Recording && _session->have_rec_enabled_track ()) {
5287                         big_clock->set_active (true);
5288                 } else {
5289                         big_clock->set_active (false);
5290                 }
5291         }
5292
5293 }
5294
5295 bool
5296 ARDOUR_UI::first_idle ()
5297 {
5298         if (_session) {
5299                 _session->allow_auto_play (true);
5300         }
5301
5302         if (editor) {
5303                 editor->first_idle();
5304         }
5305
5306         /* in 1 second, hide the splash screen
5307          *
5308          * Consider hiding it *now*. If a user opens opens a dialog
5309          * during that one second while the splash is still visible,
5310          * the dialog will push-back the splash.
5311          * Closing the dialog later will pop it back.
5312          */
5313         Glib::signal_timeout().connect (sigc::bind (sigc::ptr_fun (_hide_splash), this), 1000);
5314
5315         Keyboard::set_can_save_keybindings (true);
5316         return false;
5317 }
5318
5319 void
5320 ARDOUR_UI::store_clock_modes ()
5321 {
5322         XMLNode* node = new XMLNode(X_("ClockModes"));
5323
5324         for (vector<AudioClock*>::iterator x = AudioClock::clocks.begin(); x != AudioClock::clocks.end(); ++x) {
5325                 XMLNode* child = new XMLNode (X_("Clock"));
5326
5327                 child->set_property (X_("name"), (*x)->name());
5328                 child->set_property (X_("mode"), (*x)->mode());
5329                 child->set_property (X_("on"), (*x)->on());
5330
5331                 node->add_child_nocopy (*child);
5332         }
5333
5334         _session->add_extra_xml (*node);
5335         _session->set_dirty ();
5336 }
5337
5338 void
5339 ARDOUR_UI::setup_profile ()
5340 {
5341         if (gdk_screen_width() < 1200 || getenv ("ARDOUR_NARROW_SCREEN")) {
5342                 Profile->set_small_screen ();
5343         }
5344
5345         if (g_getenv ("TRX")) {
5346                 Profile->set_trx ();
5347         }
5348
5349         if (g_getenv ("MIXBUS")) {
5350                 Profile->set_mixbus ();
5351         }
5352 }
5353
5354 int
5355 ARDOUR_UI::missing_file (Session*s, std::string str, DataType type)
5356 {
5357         MissingFileDialog dialog (s, str, type);
5358
5359         dialog.show ();
5360         dialog.present ();
5361
5362         int result = dialog.run ();
5363         dialog.hide ();
5364
5365         switch (result) {
5366         case RESPONSE_OK:
5367                 break;
5368         default:
5369                 return 1; // quit entire session load
5370         }
5371
5372         result = dialog.get_action ();
5373
5374         return result;
5375 }
5376
5377 int
5378 ARDOUR_UI::ambiguous_file (std::string file, std::vector<std::string> hits)
5379 {
5380         AmbiguousFileDialog dialog (file, hits);
5381
5382         dialog.show ();
5383         dialog.present ();
5384
5385         dialog.run ();
5386
5387         return dialog.get_which ();
5388 }
5389
5390 /** Allocate our thread-local buffers */
5391 void
5392 ARDOUR_UI::get_process_buffers ()
5393 {
5394         _process_thread->get_buffers ();
5395 }
5396
5397 /** Drop our thread-local buffers */
5398 void
5399 ARDOUR_UI::drop_process_buffers ()
5400 {
5401         _process_thread->drop_buffers ();
5402 }
5403
5404 void
5405 ARDOUR_UI::feedback_detected ()
5406 {
5407         _feedback_exists = true;
5408 }
5409
5410 void
5411 ARDOUR_UI::successful_graph_sort ()
5412 {
5413         _feedback_exists = false;
5414 }
5415
5416 void
5417 ARDOUR_UI::midi_panic ()
5418 {
5419         if (_session) {
5420                 _session->midi_panic();
5421         }
5422 }
5423
5424 void
5425 ARDOUR_UI::session_format_mismatch (std::string xml_path, std::string backup_path)
5426 {
5427         const char* start_big = "<span size=\"x-large\" weight=\"bold\">";
5428         const char* end_big = "</span>";
5429         const char* start_mono = "<tt>";
5430         const char* end_mono = "</tt>";
5431
5432         MessageDialog msg (string_compose (_("%4This is a session from an older version of %3%5\n\n"
5433                                              "%3 has copied the old session file\n\n%6%1%7\n\nto\n\n%6%2%7\n\n"
5434                                              "From now on, use the backup copy with older versions of %3"),
5435                                            xml_path, backup_path, PROGRAM_NAME,
5436                                            start_big, end_big,
5437                                            start_mono, end_mono), true);
5438
5439         msg.run ();
5440 }
5441
5442 void
5443 ARDOUR_UI::reset_peak_display ()
5444 {
5445         if (!_session || !_session->master_out() || !editor_meter) return;
5446         editor_meter->clear_meters();
5447         editor_meter_max_peak = -INFINITY;
5448         editor_meter_peak_display.set_active_state ( Gtkmm2ext::Off );
5449 }
5450
5451 void
5452 ARDOUR_UI::reset_group_peak_display (RouteGroup* group)
5453 {
5454         if (!_session || !_session->master_out()) return;
5455         if (group == _session->master_out()->route_group()) {
5456                 reset_peak_display ();
5457         }
5458 }
5459
5460 void
5461 ARDOUR_UI::reset_route_peak_display (Route* route)
5462 {
5463         if (!_session || !_session->master_out()) return;
5464         if (_session->master_out().get() == route) {
5465                 reset_peak_display ();
5466         }
5467 }
5468
5469 int
5470 ARDOUR_UI::do_audio_midi_setup (uint32_t desired_sample_rate)
5471 {
5472         audio_midi_setup->set_desired_sample_rate (desired_sample_rate);
5473         audio_midi_setup->set_position (WIN_POS_CENTER);
5474
5475         if (desired_sample_rate != 0) {
5476                 if (Config->get_try_autostart_engine () || g_getenv ("ARDOUR_TRY_AUTOSTART_ENGINE")) {
5477                         audio_midi_setup->try_autostart ();
5478                         if (ARDOUR::AudioEngine::instance()->running()) {
5479                                 return 0;
5480                         }
5481                 }
5482         }
5483
5484         while (true) {
5485                 int response = audio_midi_setup->run();
5486                 switch (response) {
5487                 case Gtk::RESPONSE_DELETE_EVENT:
5488                         // after latency callibration engine may run,
5489                         // Running() signal was emitted, but dialog will not
5490                         // have emitted a response. The user needs to close
5491                         // the dialog -> Gtk::RESPONSE_DELETE_EVENT
5492                         if (!AudioEngine::instance()->running()) {
5493                                 return -1;
5494                         }
5495                         // fall through
5496                 default:
5497                         if (!AudioEngine::instance()->running()) {
5498                                 continue;
5499                         }
5500                         audio_midi_setup->hide ();
5501                         return 0;
5502                 }
5503         }
5504 }
5505
5506
5507 gint
5508 ARDOUR_UI::transport_numpad_timeout ()
5509 {
5510         _numpad_locate_happening = false;
5511         if (_numpad_timeout_connection.connected() )
5512                 _numpad_timeout_connection.disconnect();
5513         return 1;
5514 }
5515
5516 void
5517 ARDOUR_UI::transport_numpad_decimal ()
5518 {
5519         _numpad_timeout_connection.disconnect();
5520
5521         if (_numpad_locate_happening) {
5522                 if (editor) editor->goto_nth_marker(_pending_locate_num - 1);
5523                 _numpad_locate_happening = false;
5524         } else {
5525                 _pending_locate_num = 0;
5526                 _numpad_locate_happening = true;
5527                 _numpad_timeout_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::transport_numpad_timeout), 2*1000);
5528         }
5529 }
5530
5531 void
5532 ARDOUR_UI::transport_numpad_event (int num)
5533 {
5534         if ( _numpad_locate_happening ) {
5535                 _pending_locate_num = _pending_locate_num*10 + num;
5536         } else {
5537                 switch (num) {
5538                         case 0: toggle_roll(false, false);                           break;
5539                         case 1: transport_rewind(1);                                 break;
5540                         case 2: transport_forward(1);                                break;
5541                         case 3: transport_record(true);                              break;
5542                         case 4: toggle_session_auto_loop();                          break;
5543                         case 5: transport_record(false); toggle_session_auto_loop(); break;
5544                         case 6: toggle_punch();                                      break;
5545                         case 7: toggle_click();                                      break;
5546                         case 8: toggle_auto_return();                                break;
5547                         case 9: toggle_follow_edits();                               break;
5548                 }
5549         }
5550 }
5551
5552 void
5553 ARDOUR_UI::set_flat_buttons ()
5554 {
5555         CairoWidget::set_flat_buttons( UIConfiguration::instance().get_flat_buttons() );
5556 }
5557
5558 void
5559 ARDOUR_UI::audioengine_became_silent ()
5560 {
5561         MessageDialog msg (string_compose (_("This is a free/demo copy of %1. It has just switched to silent mode."), PROGRAM_NAME),
5562                            true,
5563                            Gtk::MESSAGE_WARNING,
5564                            Gtk::BUTTONS_NONE,
5565                            true);
5566
5567         msg.set_title (string_compose (_("%1 is now silent"), PROGRAM_NAME));
5568
5569         Gtk::Label pay_label (string_compose (_("Please consider paying for a copy of %1 - you can pay whatever you want."), PROGRAM_NAME));
5570         Gtk::Label subscribe_label (_("Better yet become a subscriber - subscriptions start at US$1 per month."));
5571         Gtk::Button pay_button (_("Pay for a copy (via the web)"));
5572         Gtk::Button subscribe_button (_("Become a subscriber (via the web)"));
5573         Gtk::HBox pay_button_box;
5574         Gtk::HBox subscribe_button_box;
5575
5576         pay_button_box.pack_start (pay_button, true, false);
5577         subscribe_button_box.pack_start (subscribe_button, true, false);
5578
5579         bool (*openuri)(const char*) = PBD::open_uri; /* this forces selection of the const char* variant of PBD::open_uri(), which we need to avoid ambiguity below */
5580
5581         pay_button.signal_clicked().connect (sigc::hide_return (sigc::bind (sigc::ptr_fun (openuri), (const char*) "https://ardour.org/download")));
5582         subscribe_button.signal_clicked().connect (sigc::hide_return (sigc::bind (sigc::ptr_fun (openuri), (const char*) "https://community.ardour.org/s/subscribe")));
5583
5584         msg.get_vbox()->pack_start (pay_label);
5585         msg.get_vbox()->pack_start (pay_button_box);
5586         msg.get_vbox()->pack_start (subscribe_label);
5587         msg.get_vbox()->pack_start (subscribe_button_box);
5588
5589         msg.get_vbox()->show_all ();
5590
5591         msg.add_button (_("Remain silent"), Gtk::RESPONSE_CANCEL);
5592         msg.add_button (_("Save and quit"), Gtk::RESPONSE_NO);
5593         msg.add_button (_("Give me more time"), Gtk::RESPONSE_YES);
5594
5595         int r = msg.run ();
5596
5597         switch (r) {
5598         case Gtk::RESPONSE_YES:
5599                 AudioEngine::instance()->reset_silence_countdown ();
5600                 break;
5601
5602         case Gtk::RESPONSE_NO:
5603                 /* save and quit */
5604                 save_state_canfail ("");
5605                 exit (EXIT_SUCCESS);
5606                 break;
5607
5608         case Gtk::RESPONSE_CANCEL:
5609         default:
5610                 /* don't reset, save session and exit */
5611                 break;
5612         }
5613 }
5614
5615 void
5616 ARDOUR_UI::hide_application ()
5617 {
5618         Application::instance ()-> hide ();
5619 }
5620
5621 void
5622 ARDOUR_UI::setup_toplevel_window (Gtk::Window& window, const string& name, void* owner)
5623 {
5624         /* icons, titles, WM stuff */
5625
5626         static list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
5627
5628         if (window_icons.empty()) {
5629                 Glib::RefPtr<Gdk::Pixbuf> icon;
5630                 if ((icon = ::get_icon (PROGRAM_NAME "-icon_16px"))) {
5631                         window_icons.push_back (icon);
5632                 }
5633                 if ((icon = ::get_icon (PROGRAM_NAME "-icon_22px"))) {
5634                         window_icons.push_back (icon);
5635                 }
5636                 if ((icon = ::get_icon (PROGRAM_NAME "-icon_32px"))) {
5637                         window_icons.push_back (icon);
5638                 }
5639                 if ((icon = ::get_icon (PROGRAM_NAME "-icon_48px"))) {
5640                         window_icons.push_back (icon);
5641                 }
5642         }
5643
5644         if (!window_icons.empty()) {
5645                 window.set_default_icon_list (window_icons);
5646         }
5647
5648         Gtkmm2ext::WindowTitle title (Glib::get_application_name());
5649
5650         if (!name.empty()) {
5651                 title += name;
5652         }
5653
5654         window.set_title (title.get_string());
5655         window.set_wmclass (string_compose (X_("%1_%1"), downcase (std::string(PROGRAM_NAME)), downcase (name)), PROGRAM_NAME);
5656
5657         window.set_flags (CAN_FOCUS);
5658         window.add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK);
5659
5660         /* This is a hack to ensure that GTK-accelerators continue to
5661          * work. Once we switch over to entirely native bindings, this will be
5662          * unnecessary and should be removed
5663          */
5664         window.add_accel_group (ActionManager::ui_manager->get_accel_group());
5665
5666         window.signal_configure_event().connect (sigc::mem_fun (*this, &ARDOUR_UI::configure_handler));
5667         window.signal_window_state_event().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::tabbed_window_state_event_handler), owner));
5668         window.signal_key_press_event().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::key_event_handler), &window), false);
5669         window.signal_key_release_event().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::key_event_handler), &window), false);
5670 }
5671
5672 bool
5673 ARDOUR_UI::key_event_handler (GdkEventKey* ev, Gtk::Window* event_window)
5674 {
5675         Gtkmm2ext::Bindings* bindings = 0;
5676         Gtk::Window* window = 0;
5677
5678         /* until we get ardour bindings working, we are not handling key
5679          * releases yet.
5680          */
5681
5682         if (ev->type != GDK_KEY_PRESS) {
5683                 return false;
5684         }
5685
5686         if (event_window == &_main_window) {
5687
5688                 window = event_window;
5689
5690                 /* find current tab contents */
5691
5692                 Gtk::Widget* w = _tabs.get_nth_page (_tabs.get_current_page());
5693
5694                 /* see if it uses the ardour binding system */
5695
5696                 if (w) {
5697                         bindings = reinterpret_cast<Gtkmm2ext::Bindings*>(w->get_data ("ardour-bindings"));
5698                 }
5699
5700                 DEBUG_TRACE (DEBUG::Accelerators, string_compose ("main window key event, bindings = %1, global = %2\n", bindings, &global_bindings));
5701
5702         } else {
5703
5704                 window = event_window;
5705
5706                 /* see if window uses ardour binding system */
5707
5708                 bindings = reinterpret_cast<Gtkmm2ext::Bindings*>(window->get_data ("ardour-bindings"));
5709         }
5710
5711         /* An empty binding set is treated as if it doesn't exist */
5712
5713         if (bindings && bindings->empty()) {
5714                 bindings = 0;
5715         }
5716
5717         return key_press_focus_accelerator_handler (*window, ev, bindings);
5718 }
5719
5720 static Gtkmm2ext::Bindings*
5721 get_bindings_from_widget_heirarchy (GtkWidget** w)
5722 {
5723         void* p = NULL;
5724
5725         while (*w) {
5726                 if ((p = g_object_get_data (G_OBJECT(*w), "ardour-bindings")) != 0) {
5727                         break;
5728                 }
5729                 *w = gtk_widget_get_parent (*w);
5730         }
5731
5732         return reinterpret_cast<Gtkmm2ext::Bindings*> (p);
5733 }
5734
5735 bool
5736 ARDOUR_UI::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey* ev, Gtkmm2ext::Bindings* bindings)
5737 {
5738         GtkWindow* win = window.gobj();
5739         GtkWidget* focus = gtk_window_get_focus (win);
5740         GtkWidget* binding_widget = focus;
5741         bool special_handling_of_unmodified_accelerators = false;
5742         const guint mask = (Keyboard::RelevantModifierKeyMask & ~(Gdk::SHIFT_MASK|Gdk::LOCK_MASK));
5743
5744         if (focus) {
5745
5746                 /* some widget has keyboard focus */
5747
5748                 if (GTK_IS_ENTRY(focus) || Keyboard::some_magic_widget_has_focus()) {
5749
5750                         /* A particular kind of focusable widget currently has keyboard
5751                          * focus. All unmodified key events should go to that widget
5752                          * first and not be used as an accelerator by default
5753                          */
5754
5755                         special_handling_of_unmodified_accelerators = true;
5756
5757                 } else {
5758
5759                         Gtkmm2ext::Bindings* focus_bindings = get_bindings_from_widget_heirarchy (&binding_widget);
5760                         if (focus_bindings) {
5761                                 bindings = focus_bindings;
5762                                 DEBUG_TRACE (DEBUG::Accelerators, string_compose ("Switch bindings based on focus widget, now using %1\n", bindings->name()));
5763                         }
5764                 }
5765         }
5766
5767         DEBUG_TRACE (DEBUG::Accelerators, string_compose ("Win = %1 [title = %9] focus = %7 (%8) Key event: code = %2  state = %3 special handling ? %4 magic widget focus ? %5 focus widget %6 named %7 mods ? %8\n",
5768                                                           win,
5769                                                           ev->keyval,
5770                                                           Gtkmm2ext::show_gdk_event_state (ev->state),
5771                                                           special_handling_of_unmodified_accelerators,
5772                                                           Keyboard::some_magic_widget_has_focus(),
5773                                                           focus,
5774                                                           (focus ? gtk_widget_get_name (focus) : "no focus widget"),
5775                                                           ((ev->state & mask) ? "yes" : "no"),
5776                                                           window.get_title()));
5777
5778         /* This exists to allow us to override the way GTK handles
5779            key events. The normal sequence is:
5780
5781            a) event is delivered to a GtkWindow
5782            b) accelerators/mnemonics are activated
5783            c) if (b) didn't handle the event, propagate to
5784                the focus widget and/or focus chain
5785
5786            The problem with this is that if the accelerators include
5787            keys without modifiers, such as the space bar or the
5788            letter "e", then pressing the key while typing into
5789            a text entry widget results in the accelerator being
5790            activated, instead of the desired letter appearing
5791            in the text entry.
5792
5793            There is no good way of fixing this, but this
5794            represents a compromise. The idea is that
5795            key events involving modifiers (not Shift)
5796            get routed into the activation pathway first, then
5797            get propagated to the focus widget if necessary.
5798
5799            If the key event doesn't involve modifiers,
5800            we deliver to the focus widget first, thus allowing
5801            it to get "normal text" without interference
5802            from acceleration.
5803
5804            Of course, this can also be problematic: if there
5805            is a widget with focus, then it will swallow
5806            all "normal text" accelerators.
5807         */
5808
5809
5810         if (!special_handling_of_unmodified_accelerators || (ev->state & mask)) {
5811
5812                 /* no special handling or there are modifiers in effect: accelerate first */
5813
5814                 DEBUG_TRACE (DEBUG::Accelerators, "\tactivate, then propagate\n");
5815                 DEBUG_TRACE (DEBUG::Accelerators, string_compose ("\tevent send-event:%1 time:%2 length:%3 name %7 string:%4 hardware_keycode:%5 group:%6\n",
5816                                                                   ev->send_event, ev->time, ev->length, ev->string, ev->hardware_keycode, ev->group, gdk_keyval_name (ev->keyval)));
5817
5818                 DEBUG_TRACE (DEBUG::Accelerators, "\tsending to window\n");
5819                 KeyboardKey k (ev->state, ev->keyval);
5820
5821                 while (bindings) {
5822
5823                         DEBUG_TRACE (DEBUG::Accelerators, string_compose ("\tusing Ardour bindings %1 @ %2 for this event\n", bindings->name(), bindings));
5824
5825                         if (bindings->activate (k, Bindings::Press)) {
5826                                 DEBUG_TRACE (DEBUG::Accelerators, "\t\thandled\n");
5827                                 return true;
5828                         }
5829
5830                         if (binding_widget) {
5831                                 binding_widget = gtk_widget_get_parent (binding_widget);
5832                                 if (binding_widget) {
5833                                         bindings = get_bindings_from_widget_heirarchy (&binding_widget);
5834                                 } else {
5835                                         bindings = 0;
5836                                 }
5837                         } else {
5838                                 bindings = 0;
5839                         }
5840                 }
5841
5842                 DEBUG_TRACE (DEBUG::Accelerators, string_compose ("\tnot yet handled, try global bindings (%1)\n", global_bindings));
5843
5844                 if (global_bindings && global_bindings->activate (k, Bindings::Press)) {
5845                         DEBUG_TRACE (DEBUG::Accelerators, "\t\thandled\n");
5846                         return true;
5847                 }
5848
5849                 DEBUG_TRACE (DEBUG::Accelerators, "\tnot accelerated, now propagate\n");
5850
5851                 if (gtk_window_propagate_key_event (win, ev)) {
5852                         DEBUG_TRACE (DEBUG::Accelerators, "\tpropagate handled\n");
5853                         return true;
5854                 }
5855
5856         } else {
5857
5858                 /* no modifiers, propagate first */
5859
5860                 DEBUG_TRACE (DEBUG::Accelerators, "\tpropagate, then activate\n");
5861
5862                 if (gtk_window_propagate_key_event (win, ev)) {
5863                         DEBUG_TRACE (DEBUG::Accelerators, "\thandled by propagate\n");
5864                         return true;
5865                 }
5866
5867                 DEBUG_TRACE (DEBUG::Accelerators, "\tpropagation didn't handle, so activate\n");
5868                 KeyboardKey k (ev->state, ev->keyval);
5869
5870                 while (bindings) {
5871
5872                         DEBUG_TRACE (DEBUG::Accelerators, "\tusing Ardour bindings for this window\n");
5873
5874
5875                         if (bindings->activate (k, Bindings::Press)) {
5876                                 DEBUG_TRACE (DEBUG::Accelerators, "\t\thandled\n");
5877                                 return true;
5878                         }
5879
5880                         if (binding_widget) {
5881                                 binding_widget = gtk_widget_get_parent (binding_widget);
5882                                 if (binding_widget) {
5883                                         bindings = get_bindings_from_widget_heirarchy (&binding_widget);
5884                                 } else {
5885                                         bindings = 0;
5886                                 }
5887                         } else {
5888                                 bindings = 0;
5889                         }
5890                 }
5891
5892                 DEBUG_TRACE (DEBUG::Accelerators, string_compose ("\tnot yet handled, try global bindings (%1)\n", global_bindings));
5893
5894                 if (global_bindings && global_bindings->activate (k, Bindings::Press)) {
5895                         DEBUG_TRACE (DEBUG::Accelerators, "\t\thandled\n");
5896                         return true;
5897                 }
5898         }
5899
5900         DEBUG_TRACE (DEBUG::Accelerators, "\tnot handled\n");
5901         return true;
5902 }
5903
5904 void
5905 ARDOUR_UI::cancel_solo ()
5906 {
5907         if (_session) {
5908                 _session->cancel_all_solo ();
5909         }
5910 }
5911
5912 void
5913 ARDOUR_UI::reset_focus (Gtk::Widget* w)
5914 {
5915         /* this resets focus to the first focusable parent of the given widget,
5916          * or, if there is no focusable parent, cancels focus in the toplevel
5917          * window that the given widget is packed into (if there is one).
5918          */
5919
5920         if (!w) {
5921                 return;
5922         }
5923
5924         Gtk::Widget* top = w->get_toplevel();
5925
5926         if (!top || !top->is_toplevel()) {
5927                 return;
5928         }
5929
5930         w = w->get_parent ();
5931
5932         while (w) {
5933
5934                 if (w->is_toplevel()) {
5935                         /* Setting the focus widget to a Gtk::Window causes all
5936                          * subsequent calls to ::has_focus() on the nominal
5937                          * focus widget in that window to return
5938                          * false. Workaround: never set focus to the toplevel
5939                          * itself.
5940                          */
5941                         break;
5942                 }
5943
5944                 if (w->get_can_focus ()) {
5945                         Gtk::Window* win = dynamic_cast<Gtk::Window*> (top);
5946                         win->set_focus (*w);
5947                         return;
5948                 }
5949                 w = w->get_parent ();
5950         }
5951
5952         if (top == &_main_window) {
5953
5954         }
5955
5956         /* no focusable parent found, cancel focus in top level window.
5957            C++ API cannot be used for this. Thanks, references.
5958         */
5959
5960         gtk_window_set_focus (GTK_WINDOW(top->gobj()), 0);
5961
5962 }
5963
5964 void
5965 ARDOUR_UI::monitor_dim_all ()
5966 {
5967         boost::shared_ptr<Route> mon = _session->monitor_out ();
5968         if (!mon) {
5969                 return;
5970         }
5971         boost::shared_ptr<ARDOUR::MonitorProcessor> _monitor = mon->monitor_control ();
5972
5973         Glib::RefPtr<ToggleAction> tact = ActionManager::get_toggle_action (X_("Monitor"), "monitor-dim-all");
5974         _monitor->set_dim_all (tact->get_active());
5975 }
5976
5977 void
5978 ARDOUR_UI::monitor_cut_all ()
5979 {
5980         boost::shared_ptr<Route> mon = _session->monitor_out ();
5981         if (!mon) {
5982                 return;
5983         }
5984         boost::shared_ptr<ARDOUR::MonitorProcessor> _monitor = mon->monitor_control ();
5985
5986         Glib::RefPtr<ToggleAction> tact = ActionManager::get_toggle_action (X_("Monitor"), "monitor-cut-all");
5987         _monitor->set_cut_all (tact->get_active());
5988 }
5989
5990 void
5991 ARDOUR_UI::monitor_mono ()
5992 {
5993         boost::shared_ptr<Route> mon = _session->monitor_out ();
5994         if (!mon) {
5995                 return;
5996         }
5997         boost::shared_ptr<ARDOUR::MonitorProcessor> _monitor = mon->monitor_control ();
5998
5999         Glib::RefPtr<ToggleAction> tact = ActionManager::get_toggle_action (X_("Monitor"), "monitor-mono");
6000         _monitor->set_mono (tact->get_active());
6001 }
6002
6003 Gtk::Menu*
6004 ARDOUR_UI::shared_popup_menu ()
6005 {
6006         ENSURE_GUI_THREAD (*this, &ARDOUR_UI::shared_popup_menu, ignored);
6007
6008         assert (!_shared_popup_menu || !_shared_popup_menu->is_visible());
6009         delete _shared_popup_menu;
6010         _shared_popup_menu = new Gtk::Menu;
6011         return _shared_popup_menu;
6012 }