ardour
ardour_ui.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 1999-2013 Paul Davis
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 
18 */
19 
20 #ifdef WAF_BUILD
21 #include "gtk2ardour-config.h"
22 #include "gtk2ardour-version.h"
23 #endif
24 
25 #include <algorithm>
26 #include <cmath>
27 #include <iostream>
28 #include <cerrno>
29 #include <fstream>
30 
31 #ifndef PLATFORM_WINDOWS
32 #include <sys/resource.h>
33 #endif
34 
35 #include <stdint.h>
36 #include <fcntl.h>
37 #include <signal.h>
38 #include <unistd.h>
39 #include <time.h>
40 
41 #include <glib.h>
42 #include <glib/gstdio.h>
43 
44 #include <gtkmm/messagedialog.h>
45 #include <gtkmm/accelmap.h>
46 
47 #include "pbd/error.h"
48 #include "pbd/basename.h"
49 #include "pbd/compose.h"
50 #include "pbd/failed_constructor.h"
51 #include "pbd/enumwriter.h"
52 #include "pbd/memento_command.h"
53 #include "pbd/openuri.h"
54 #include "pbd/stl_delete.h"
55 #include "pbd/file_utils.h"
56 #include "pbd/localtime_r.h"
57 #include "pbd/pthread_utils.h"
58 
59 #include "gtkmm2ext/application.h"
60 #include "gtkmm2ext/bindings.h"
61 #include "gtkmm2ext/gtk_ui.h"
62 #include "gtkmm2ext/utils.h"
63 #include "gtkmm2ext/click_box.h"
64 #include "gtkmm2ext/fastmeter.h"
65 #include "gtkmm2ext/popup.h"
66 #include "gtkmm2ext/window_title.h"
67 
68 #include "ardour/ardour.h"
69 #include "ardour/audio_backend.h"
70 #include "ardour/audioengine.h"
71 #include "ardour/audiofilesource.h"
73 #include "ardour/diskstream.h"
76 #include "ardour/port.h"
77 #include "ardour/plugin_manager.h"
78 #include "ardour/process_thread.h"
79 #include "ardour/profile.h"
80 #include "ardour/recent_sessions.h"
82 #include "ardour/session_route.h"
84 #include "ardour/session_utils.h"
85 #include "ardour/slave.h"
86 #include "ardour/system_exec.h"
87 
88 #ifdef WINDOWS_VST_SUPPORT
89 #include <fst.h>
90 #endif
91 #ifdef AUDIOUNIT_SUPPORT
92 #include "ardour/audio_unit.h"
93 #endif
94 
95 #include "timecode/time.h"
96 
97 typedef uint64_t microseconds_t;
98 
99 #include "about.h"
100 #include "editing.h"
101 #include "actions.h"
102 #include "add_route_dialog.h"
103 #include "ambiguous_file_dialog.h"
104 #include "ardour_ui.h"
105 #include "audio_clock.h"
106 #include "big_clock_window.h"
107 #include "bundle_manager.h"
108 #include "engine_dialog.h"
109 #include "export_video_dialog.h"
110 #include "export_video_infobox.h"
111 #include "gain_meter.h"
112 #include "global_port_matrix.h"
113 #include "gui_object.h"
114 #include "gui_thread.h"
115 #include "keyboard.h"
116 #include "keyeditor.h"
117 #include "location_ui.h"
118 #include "main_clock.h"
119 #include "missing_file_dialog.h"
120 #include "missing_plugin_dialog.h"
121 #include "mixer_ui.h"
122 #include "mouse_cursors.h"
123 #include "nsm.h"
124 #include "opts.h"
125 #include "pingback.h"
126 #include "processor_box.h"
127 #include "prompter.h"
128 #include "public_editor.h"
129 #include "rc_option_editor.h"
130 #include "route_time_axis.h"
131 #include "route_params_ui.h"
132 #include "save_as_dialog.h"
133 #include "session_dialog.h"
134 #include "session_metadata_dialog.h"
135 #include "session_option_editor.h"
136 #include "shuttle_control.h"
137 #include "speaker_dialog.h"
138 #include "splash.h"
139 #include "startup.h"
140 #include "theme_manager.h"
141 #include "time_axis_view_item.h"
142 #include "timers.h"
143 #include "utils.h"
144 #include "video_server_dialog.h"
145 #include "add_video_dialog.h"
146 #include "transcode_video_dialog.h"
147 
148 #include "i18n.h"
149 
150 using namespace ARDOUR;
151 using namespace ARDOUR_UI_UTILS;
152 using namespace PBD;
153 using namespace Gtkmm2ext;
154 using namespace Gtk;
155 using namespace std;
156 using namespace Editing;
157 
159 
160 sigc::signal<void, framepos_t, bool, framepos_t> ARDOUR_UI::Clock;
161 sigc::signal<void> ARDOUR_UI::CloseAllDialogs;
162 
163 float ARDOUR_UI::ui_scale = 1.0;
164 
165 static bool
166 ask_about_configuration_copy (string const & old_dir, string const & new_dir, int version)
167 {
168  MessageDialog msg (string_compose (_("%1 %2.x has discovered configuration files from %1 %3.x.\n\n"
169  "Would you like these files to be copied and used for %1 %2.x?\n\n"
170  "(This will require you to restart %1.)"),
171  PROGRAM_NAME, PROGRAM_VERSION, version),
172  false, /* no markup */
173  Gtk::MESSAGE_INFO,
174  Gtk::BUTTONS_YES_NO,
175  true /* modal, though it hardly matters since it is the only window */
176  );
177 
178  msg.set_default_response (Gtk::RESPONSE_YES);
179  msg.show_all ();
180 
181  return (msg.run() == Gtk::RESPONSE_YES);
182 }
183 
184 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
185 
186  : Gtkmm2ext::UI (PROGRAM_NAME, argcp, argvp)
187  , ui_config (new UIConfiguration)
188  , session_loaded (false)
189  , gui_object_state (new GUIObjectState)
190  , primary_clock (new MainClock (X_("primary"), X_("transport"), true ))
191  , secondary_clock (new MainClock (X_("secondary"), X_("secondary"), false))
192  , big_clock (new AudioClock (X_("bigclock"), false, "big", true, true, false, false))
193  , video_timeline(0)
194  , ignore_dual_punch (false)
195  , editor (0)
196  , mixer (0)
197  , nsm (0)
198  , _was_dirty (false)
199  , _mixer_on_top (false)
200  , first_time_engine_run (true)
201  , roll_controllable (new TransportControllable ("transport roll", *this, TransportControllable::Roll))
202  , stop_controllable (new TransportControllable ("transport stop", *this, TransportControllable::Stop))
203  , goto_start_controllable (new TransportControllable ("transport goto start", *this, TransportControllable::GotoStart))
204  , goto_end_controllable (new TransportControllable ("transport goto end", *this, TransportControllable::GotoEnd))
205  , auto_loop_controllable (new TransportControllable ("transport auto loop", *this, TransportControllable::AutoLoop))
206  , play_selection_controllable (new TransportControllable ("transport play selection", *this, TransportControllable::PlaySelection))
207  , rec_controllable (new TransportControllable ("transport rec-enable", *this, TransportControllable::RecordEnable))
208  , auto_return_button (ArdourButton::led_default_elements)
209  , follow_edits_button (ArdourButton::led_default_elements)
210  , auto_input_button (ArdourButton::led_default_elements)
211  , auditioning_alert_button (_("Audition"))
212  , solo_alert_button (_("Solo"))
213  , feedback_alert_button (_("Feedback"))
214  , error_alert_button ( ArdourButton::just_led_default_elements )
215  , editor_meter(0)
216  , editor_meter_peak_display()
217  , open_session_selector (0)
218  , _numpad_locate_happening (false)
219  , _session_is_new (false)
220  , last_key_press_time (0)
221  , save_as_dialog (0)
222  , meterbridge (0)
223  , speaker_config_window (X_("speaker-config"), _("Speaker Configuration"))
224  , key_editor (X_("key-editor"), _("Key Bindings"))
225  , rc_option_editor (X_("rc-options-editor"), _("Preferences"))
226  , add_route_dialog (X_("add-routes"), _("Add Tracks/Busses"))
227  , about (X_("about"), _("About"))
228  , location_ui (X_("locations"), _("Locations"))
229  , route_params (X_("inspector"), _("Tracks and Busses"))
230  , audio_midi_setup (X_("audio-midi-setup"), _("Audio/MIDI Setup"))
231  , export_video_dialog (X_("video-export"), _("Video Export Dialog"))
232  , session_option_editor (X_("session-options-editor"), _("Properties"), boost::bind (&ARDOUR_UI::create_session_option_editor, this))
233  , add_video_dialog (X_("add-video"), _("Add Tracks/Busses"), boost::bind (&ARDOUR_UI::create_add_video_dialog, this))
234  , bundle_manager (X_("bundle-manager"), _("Bundle Manager"), boost::bind (&ARDOUR_UI::create_bundle_manager, this))
235  , big_clock_window (X_("big-clock"), _("Big Clock"), boost::bind (&ARDOUR_UI::create_big_clock_window, this))
236  , audio_port_matrix (X_("audio-connection-manager"), _("Audio Connections"), boost::bind (&ARDOUR_UI::create_global_port_matrix, this, ARDOUR::DataType::AUDIO))
237  , midi_port_matrix (X_("midi-connection-manager"), _("MIDI Connections"), boost::bind (&ARDOUR_UI::create_global_port_matrix, this, ARDOUR::DataType::MIDI))
238  , video_server_process (0)
239  , splash (0)
240  , have_configure_timeout (false)
241  , last_configure_time (0)
242  , last_peak_grab (0)
243  , have_disk_speed_dialog_displayed (false)
244  , _status_bar_visibility (X_("status-bar"))
245  , _feedback_exists (false)
246  , _log_not_acknowledged (LogLevelNone)
247 {
248  Gtkmm2ext::init (localedir);
249 
251  MessageDialog msg (string_compose (_("Your configuration files were copied. You can now restart %1."), PROGRAM_NAME), true);
252  msg.run ();
253  /* configuration was modified, exit immediately */
254  _exit (0);
255  }
256 
257  if (theArdourUI == 0) {
258  theArdourUI = this;
259  }
260 
261  ui_config->ParameterChanged.connect (sigc::mem_fun (*this, &ARDOUR_UI::parameter_changed));
262  boost::function<void (string)> pc (boost::bind (&ARDOUR_UI::parameter_changed, this, _1));
264 
272 
273  roll_button.set_name ("transport button");
274  stop_button.set_name ("transport button");
275  goto_start_button.set_name ("transport button");
276  goto_end_button.set_name ("transport button");
277  auto_loop_button.set_name ("transport button");
278  play_selection_button.set_name ("transport button");
279  rec_button.set_name ("transport recenable button");
280  midi_panic_button.set_name ("transport button");
281 
284 
286 
287  /* handle dialog requests */
288 
290 
291  /* handle pending state with a dialog (PROBLEM: needs to return a value and thus cannot be x-thread) */
292 
294 
295  /* handle Audio/MIDI setup when session requires it */
296 
298 
299  /* handle sr mismatch with a dialog (PROBLEM: needs to return a value and thus cannot be x-thread) */
300 
301  ARDOUR::Session::AskAboutSampleRateMismatch.connect_same_thread (forever_connections, boost::bind (&ARDOUR_UI::sr_mismatch_dialog, this, _1, _2));
302 
303  /* handle requests to quit (coming from JACK session) */
304 
306 
307  /* tell the user about feedback */
308 
311 
312  /* handle requests to deal with missing files */
313 
314  ARDOUR::Session::MissingFile.connect_same_thread (forever_connections, boost::bind (&ARDOUR_UI::missing_file, this, _1, _2, _3));
315 
316  /* and ambiguous files */
317 
318  ARDOUR::FileSource::AmbiguousFileName.connect_same_thread (forever_connections, boost::bind (&ARDOUR_UI::ambiguous_file, this, _1, _2));
319 
320  /* also plugin scan messages */
323 
325 
328 
329  /* lets get this party started */
330 
332  setup_profile ();
333 
334  SessionEvent::create_per_thread_pool ("GUI", 512);
335 
336  /* we like keyboards */
337 
338  keyboard = new ArdourKeyboard(*this);
339 
341  if (node) {
342  keyboard->set_state (*node, Stateful::loading_state_version);
343  }
344 
345  /* we don't like certain modifiers */
346  Bindings::set_ignored_state (GDK_LOCK_MASK|GDK_MOD2_MASK|GDK_MOD3_MASK);
347 
348  reset_dpi();
349 
351 
352  /* Set this up so that our window proxies can register actions */
353 
355 
356  /* The following must happen after ARDOUR::init() so that Config is set up */
357 
358  const XMLNode* ui_xml = Config->extra_xml (X_("UI"));
359 
360  if (ui_xml) {
361  key_editor.set_state (*ui_xml);
362  rc_option_editor.set_state (*ui_xml);
365  about.set_state (*ui_xml);
366  add_route_dialog.set_state (*ui_xml);
367  add_video_dialog.set_state (*ui_xml);
368  route_params.set_state (*ui_xml);
369  bundle_manager.set_state (*ui_xml);
370  location_ui.set_state (*ui_xml);
371  big_clock_window.set_state (*ui_xml);
372  audio_port_matrix.set_state (*ui_xml);
373  midi_port_matrix.set_state (*ui_xml);
374  export_video_dialog.set_state (*ui_xml);
375  }
376 
392 
393  /* Trigger setting up the color scheme and loading the GTK RC file */
394 
395  ARDOUR_UI::config()->load_rc_file (false);
396 
398  _process_thread->init ();
399 
400  DPIReset.connect (sigc::mem_fun (*this, &ARDOUR_UI::resize_text_widgets));
401 
402  attach_to_engine ();
403 }
404 
407 {
408  if (!_session) {
409  return 0;
410  }
411  return new GlobalPortMatrixWindow (_session, type);
412 }
413 
414 void
416 {
417  AudioEngine::instance()->Running.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::engine_running, this), gui_context());
419 }
420 
421 void
423 {
427 }
428 
429 void
431 {
432  if (first_time_engine_run) {
433  post_engine();
434  first_time_engine_run = false;
435  }
436 
437  if (_session) {
439  }
441  update_cpu_load ();
443  update_sample_rate (AudioEngine::instance()->sample_rate());
445 }
446 
447 void
448 ARDOUR_UI::engine_halted (const char* reason, bool free_reason)
449 {
451  /* we can't rely on the original string continuing to exist when we are called
452  again in the GUI thread, so make a copy and note that we need to
453  free it later.
454  */
455  char *copy = strdup (reason);
456  Gtkmm2ext::UI::instance()->call_slot (MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::engine_halted, this, copy, true));
457  return;
458  }
459 
462 
463  update_sample_rate (0);
464 
465  string msgstr;
466 
467  /* if the reason is a non-empty string, it means that the backend was shutdown
468  rather than just Ardour.
469  */
470 
471  if (strlen (reason)) {
472  msgstr = string_compose (_("The audio backend was shutdown because:\n\n%1"), reason);
473  } else {
474  msgstr = string_compose (_("\
475 The audio backend has either been shutdown or it\n\
476 disconnected %1 because %1\n\
477 was not fast enough. Try to restart\n\
478 the audio backend and save the session."), PROGRAM_NAME);
479  }
480 
481  MessageDialog msg (*editor, msgstr);
482  pop_back_splash (msg);
483  msg.run ();
484 
485  if (free_reason) {
486  free (const_cast<char*> (reason));
487  }
488 }
489 
490 void
492 {
493  /* Things to be done once (and once ONLY) after we have a backend running in the AudioEngine
494  */
495 #ifdef AUDIOUNIT_SUPPORT
496  std::string au_msg;
497  if (AUPluginInfo::au_get_crashlog(au_msg)) {
498  popup_error(_("Audio Unit Plugin Scan Failed. Automatic AU scanning has been disabled. Please see the log window for further details."));
499  error << _("Audio Unit Plugin Scan Failed:") << endmsg;
500  info << au_msg << endmsg;
501  }
502 #endif
503 
505 
506  /* connect to important signals */
507 
508  AudioEngine::instance()->Stopped.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::engine_stopped, this), gui_context());
509  AudioEngine::instance()->SampleRateChanged.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::update_sample_rate, this, _1), gui_context());
510  AudioEngine::instance()->BufferSizeChanged.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::update_sample_rate, this, _1), gui_context());
511  AudioEngine::instance()->Halted.connect_same_thread (halt_connection, boost::bind (&ARDOUR_UI::engine_halted, this, _1, false));
512  AudioEngine::instance()->BecameSilent.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::audioengine_became_silent, this), gui_context());
513 
514  _tooltips.enable();
515 
516  if (setup_windows ()) {
517  throw failed_constructor ();
518  }
519 
520  /* Do this after setup_windows (), as that's when the _status_bar_visibility is created */
521  XMLNode* n = Config->extra_xml (X_("UI"));
522  if (n) {
524  }
525 
527 
528  /* this is the first point at which all the keybindings are available */
529 
531  vector<string> names;
532  vector<string> paths;
533  vector<string> tooltips;
534  vector<string> keys;
535  vector<AccelKey> bindings;
536 
537  ActionManager::get_all_actions (names, paths, tooltips, keys, bindings);
538 
539  vector<string>::iterator n;
540  vector<string>::iterator k;
541  vector<string>::iterator p;
542  for (n = names.begin(), k = keys.begin(), p = paths.begin(); n != names.end(); ++n, ++k, ++p) {
543  cout << "Action: '" << (*n) << "' bound to '" << (*k) << "' Path: '" << (*p) << "'" << endl;
544  }
545 
547  AudioEngine::instance()->stop ();
548  exit (0);
549  }
550 
551  /* this being a GUI and all, we want peakfiles */
552 
553  AudioFileSource::set_build_peakfiles (true);
554  AudioFileSource::set_build_missing_peakfiles (true);
555 
556  /* set default clock modes */
557 
558  if (Profile->get_sae()) {
561  } else {
564  }
565 
566  /* start the time-of-day-clock */
567 
568 #ifndef GTKOSX
569  /* OS X provides a nearly-always visible wallclock, so don't be stupid */
571  Glib::signal_timeout().connect_seconds (sigc::mem_fun(*this, &ARDOUR_UI::update_wall_clock), 1);
572 #endif
573 
574  {
575  DisplaySuspender ds;
577  boost::function<void (string)> pc (boost::bind (&ARDOUR_UI::parameter_changed, this, _1));
578  Config->map_parameters (pc);
579 
581  }
582 }
583 
585 {
587 
589 
590  if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
591  // don't bother at 'real' exit. the OS cleans up for us.
592  delete big_clock;
593  delete primary_clock;
594  delete secondary_clock;
595  delete _process_thread;
596  delete gui_object_state;
597  FastMeter::flush_pattern_cache ();
598  }
599 }
600 
601 void
602 ARDOUR_UI::pop_back_splash (Gtk::Window& win)
603 {
604  if (Splash::instance()) {
606  }
607 }
608 
609 gint
611 {
612  if (last_configure_time == 0) {
613  /* no configure events yet */
614  return true;
615  }
616 
617  /* force a gap of 0.5 seconds since the last configure event
618  */
619 
620  if (get_microseconds() - last_configure_time < 500000) {
621  return true;
622  } else {
623  have_configure_timeout = false;
625  return false;
626  }
627 }
628 
629 gboolean
630 ARDOUR_UI::configure_handler (GdkEventConfigure* /*conf*/)
631 {
634  } else {
635  Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
636  have_configure_timeout = true;
637  }
638 
639  return FALSE;
640 }
641 
642 void
644 {
645  const XMLProperty* prop;
646 
647  if ((prop = node.property ("roll")) != 0) {
648  roll_controllable->set_id (prop->value());
649  }
650  if ((prop = node.property ("stop")) != 0) {
651  stop_controllable->set_id (prop->value());
652  }
653  if ((prop = node.property ("goto-start")) != 0) {
654  goto_start_controllable->set_id (prop->value());
655  }
656  if ((prop = node.property ("goto-end")) != 0) {
657  goto_end_controllable->set_id (prop->value());
658  }
659  if ((prop = node.property ("auto-loop")) != 0) {
660  auto_loop_controllable->set_id (prop->value());
661  }
662  if ((prop = node.property ("play-selection")) != 0) {
663  play_selection_controllable->set_id (prop->value());
664  }
665  if ((prop = node.property ("rec")) != 0) {
666  rec_controllable->set_id (prop->value());
667  }
668  if ((prop = node.property ("shuttle")) != 0) {
669  shuttle_box->controllable()->set_id (prop->value());
670  }
671 }
672 
673 XMLNode&
675 {
676  XMLNode* node = new XMLNode(X_("TransportControllables"));
677  char buf[64];
678 
679  roll_controllable->id().print (buf, sizeof (buf));
680  node->add_property (X_("roll"), buf);
681  stop_controllable->id().print (buf, sizeof (buf));
682  node->add_property (X_("stop"), buf);
683  goto_start_controllable->id().print (buf, sizeof (buf));
684  node->add_property (X_("goto_start"), buf);
685  goto_end_controllable->id().print (buf, sizeof (buf));
686  node->add_property (X_("goto_end"), buf);
687  auto_loop_controllable->id().print (buf, sizeof (buf));
688  node->add_property (X_("auto_loop"), buf);
689  play_selection_controllable->id().print (buf, sizeof (buf));
690  node->add_property (X_("play_selection"), buf);
691  rec_controllable->id().print (buf, sizeof (buf));
692  node->add_property (X_("rec"), buf);
693  shuttle_box->controllable()->id().print (buf, sizeof (buf));
694  node->add_property (X_("shuttle"), buf);
695 
696  return *node;
697 }
698 
699 void
700 ARDOUR_UI::save_session_at_its_request (std::string snapshot_name)
701 {
702  if (_session) {
703  _session->save_state (snapshot_name);
704  }
705 }
706 
707 gint
709 {
710  if (g_main_depth() > 1) {
711  /* inside a recursive main loop,
712  give up because we may not be able to
713  take a lock.
714  */
715  return 1;
716  }
717 
718  if (!Config->get_periodic_safety_backups()) {
719  return 1;
720  }
721 
722  if (_session) {
724  }
725 
726  return 1;
727 }
728 
729 void
731 {
733 
734  if (_session && _session->dirty()) {
735  if (_autosave_connection.connected()) {
736  _autosave_connection.disconnect();
737  }
738 
739  _autosave_connection = Glib::signal_timeout().connect (sigc::mem_fun (*this, &ARDOUR_UI::autosave_session),
740  Config->get_periodic_safety_backup_interval() * 1000);
741 
742  } else {
743  if (_autosave_connection.connected()) {
744  _autosave_connection.disconnect();
745  }
746  }
747 }
748 
749 void
751 {
752 #ifdef PHONE_HOME
753  string _annc_filename;
754 
755 #ifdef __APPLE__
756  _annc_filename = PROGRAM_NAME "_announcements_osx_";
757 #else
758  _annc_filename = PROGRAM_NAME "_announcements_linux_";
759 #endif
760  _annc_filename.append (VERSIONSTRING);
761 
762  std::string path = Glib::build_filename (user_config_directory(), _annc_filename);
763  std::ifstream announce_file (path.c_str());
764  if ( announce_file.fail() )
765  _announce_string = "";
766  else {
767  std::stringstream oss;
768  oss << announce_file.rdbuf();
769  _announce_string = oss.str();
770  }
771 
772  pingback (VERSIONSTRING, path);
773 #endif
774 }
775 
776 int
778 {
779  Application* app = Application::instance ();
780  const char *nsm_url;
781  bool brand_new_user = ArdourStartup::required ();
782 
783  app->ShouldQuit.connect (sigc::mem_fun (*this, &ARDOUR_UI::queue_finish));
784  app->ShouldLoad.connect (sigc::mem_fun (*this, &ARDOUR_UI::load_from_application_api));
785 
788  }
789 
790  app->ready ();
791 
792  /* we need to create this early because it may need to set the
793  * audio backend end up.
794  */
795 
796  try {
797  audio_midi_setup.get (true);
798  } catch (...) {
799  std::cerr << "audio-midi engine setup failed."<< std::endl;
800  return -1;
801  }
802 
803  if ((nsm_url = g_getenv ("NSM_URL")) != 0) {
804  nsm = new NSM_Client;
805  if (!nsm->init (nsm_url)) {
806  /* the ardour executable may have different names:
807  *
808  * waf's obj.target for distro versions: eg ardour4, ardourvst4
809  * Ardour4, Mixbus3 for bundled versions + full path on OSX & windows
810  * argv[0] does not apply since we need the wrapper-script (not the binary itself)
811  *
812  * The wrapper startup script should set the environment variable 'ARDOUR_SELF'
813  */
814  const char *process_name = g_getenv ("ARDOUR_SELF");
815  nsm->announce (PROGRAM_NAME, ":dirty:", process_name ? process_name : "ardour4");
816 
817  unsigned int i = 0;
818  // wait for announce reply from nsm server
819  for ( i = 0; i < 5000; ++i) {
820  nsm->check ();
821 
822  Glib::usleep (i);
823  if (nsm->is_active()) {
824  break;
825  }
826  }
827  if (i == 5000) {
828  error << _("NSM server did not announce itself") << endmsg;
829  return -1;
830  }
831  // wait for open command from nsm server
832  for ( i = 0; i < 5000; ++i) {
833  nsm->check ();
834  Glib::usleep (1000);
835  if (nsm->client_id ()) {
836  break;
837  }
838  }
839 
840  if (i == 5000) {
841  error << _("NSM: no client ID provided") << endmsg;
842  return -1;
843  }
844 
845  if (_session && nsm) {
847  } else {
848  error << _("NSM: no session created") << endmsg;
849  return -1;
850  }
851 
852  // nsm requires these actions disabled
853  vector<string> action_names;
854  action_names.push_back("SaveAs");
855  action_names.push_back("Rename");
856  action_names.push_back("New");
857  action_names.push_back("Open");
858  action_names.push_back("Recent");
859  action_names.push_back("Close");
860 
861  for (vector<string>::const_iterator n = action_names.begin(); n != action_names.end(); ++n) {
862  Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), (*n).c_str());
863  if (act) {
864  act->set_sensitive (false);
865  }
866  }
867 
868  } else {
869  delete nsm;
870  nsm = 0;
871  error << _("NSM: initialization failed") << endmsg;
872  return -1;
873  }
874 
875  } else {
876 
877  if (brand_new_user) {
878  ArdourStartup s;
879  s.present ();
880  main().run();
881  s.hide ();
882  switch (s.response ()) {
883  case Gtk::RESPONSE_OK:
884  break;
885  default:
886  return -1;
887  }
888  }
889 
890 #ifdef NO_PLUGIN_STATE
891 
894 
895  string path = Glib::build_filename (user_config_directory(), ".iknowaboutfreeversion");
896 
897  if (!Glib::file_test (path, Glib::FILE_TEST_EXISTS) && !rs.empty()) {
898 
899  /* already used Ardour, have sessions ... warn about plugin state */
900 
901  ArdourDialog d (_("Free/Demo Version Warning"), true);
902  Label l;
903  Button b (string_compose (_("Subscribe and support development of %1"), PROGRAM_NAME));
904  CheckButton c (_("Don't warn me about this again"));
905 
906  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"),
907  string_compose (_("This is a free/demo version of %1"), PROGRAM_NAME),
908  _("It will not restore OR save any plugin settings"),
909  _("If you load an existing session with plugin settings\n"
910  "they will not be used and will be lost."),
911  _("To get full access to updates without this limitation\n"
912  "consider becoming a subscriber for a low cost every month.")));
913  l.set_justify (JUSTIFY_CENTER);
914 
915  b.signal_clicked().connect (mem_fun(*this, &ARDOUR_UI::launch_subscribe));
916 
917  d.get_vbox()->pack_start (l, true, true);
918  d.get_vbox()->pack_start (b, false, false, 12);
919  d.get_vbox()->pack_start (c, false, false, 12);
920 
921  d.add_button (_("Quit now"), RESPONSE_CANCEL);
922  d.add_button (string_compose (_("Continue using %1"), PROGRAM_NAME), RESPONSE_OK);
923 
924  d.show_all ();
925 
926  c.signal_toggled().connect (sigc::hide_return (sigc::bind (sigc::ptr_fun (toggle_file_existence), path)));
927 
928  if (d.run () != RESPONSE_OK) {
929  _exit (0);
930  }
931  }
932 #endif
933 
934  /* go get a session */
935 
936  const bool new_session_required = (ARDOUR_COMMAND_LINE::new_session || brand_new_user);
937 
938  if (get_session_parameters (false, new_session_required, ARDOUR_COMMAND_LINE::load_template)) {
939  std::cerr << "Cannot get session parameters."<< std::endl;
940  return -1;
941  }
942  }
943 
944  use_config ();
945 
947 
949 
950  /* We have to do this here since goto_editor_window() ends up calling show_all() on the
951  * editor window, and we may want stuff to be hidden.
952  */
954 
955  BootMessage (string_compose (_("%1 is ready for use"), PROGRAM_NAME));
956  return 0;
957 }
958 
959 void
961 {
962 #if defined(__APPLE__) || defined(PLATFORM_WINDOWS)
963  /* OS X doesn't support mlockall(2), and so testing for memory locking capability there is pointless */
964  return;
965 #else // !__APPLE__
966 
967  XMLNode* memory_warning_node = Config->instant_xml (X_("no-memory-warning"));
968 
969  if (AudioEngine::instance()->is_realtime() && memory_warning_node == 0) {
970 
971  struct rlimit limits;
972  int64_t ram;
973  long pages, page_size;
974 #ifdef __FreeBSD__
975  size_t pages_len=sizeof(pages);
976  if ((page_size = getpagesize()) < 0 ||
977  sysctlbyname("hw.availpages", &pages, &pages_len, NULL, 0))
978 #else
979  if ((page_size = sysconf (_SC_PAGESIZE)) < 0 ||(pages = sysconf (_SC_PHYS_PAGES)) < 0)
980 #endif
981  {
982  ram = 0;
983  } else {
984  ram = (int64_t) pages * (int64_t) page_size;
985  }
986 
987  if (getrlimit (RLIMIT_MEMLOCK, &limits)) {
988  return;
989  }
990 
991  if (limits.rlim_cur != RLIM_INFINITY) {
992 
993  if (ram == 0 || ((double) limits.rlim_cur / ram) < 0.75) {
994 
995  MessageDialog msg (
997  _("WARNING: Your system has a limit for maximum amount of locked memory. "
998  "This might cause %1 to run out of memory before your system "
999  "runs out of memory. \n\n"
1000  "You can view the memory limit with 'ulimit -l', "
1001  "and it is normally controlled by %2"),
1002  PROGRAM_NAME,
1003 #ifdef __FreeBSD__
1004  X_("/etc/login.conf")
1005 #else
1006  X_(" /etc/security/limits.conf")
1007 #endif
1008  ).c_str());
1009 
1010  msg.set_default_response (RESPONSE_OK);
1011 
1012  VBox* vbox = msg.get_vbox();
1013  HBox hbox;
1014  CheckButton cb (_("Do not show this window again"));
1015  hbox.pack_start (cb, true, false);
1016  vbox->pack_start (hbox);
1017  cb.show();
1018  vbox->show();
1019  hbox.show ();
1020 
1021  pop_back_splash (msg);
1022 
1023  editor->ensure_float (msg);
1024  msg.run ();
1025 
1026  if (cb.get_active()) {
1027  XMLNode node (X_("no-memory-warning"));
1028  Config->add_instant_xml (node);
1029  }
1030  }
1031  }
1032  }
1033 #endif // !__APPLE__
1034 }
1035 
1036 
1037 void
1039 {
1040  Glib::signal_idle().connect (mem_fun (*this, &ARDOUR_UI::idle_finish));
1041 }
1042 
1043 bool
1045 {
1046  finish ();
1047  return false; /* do not call again */
1048 }
1049 
1050 void
1052 {
1053  if (_session) {
1055 
1056  if (_session->dirty()) {
1057  vector<string> actions;
1058  actions.push_back (_("Don't quit"));
1059  actions.push_back (_("Just quit"));
1060  actions.push_back (_("Save and quit"));
1061  switch (ask_about_saving_session(actions)) {
1062  case -1:
1063  return;
1064  break;
1065  case 1:
1066  /* use the default name */
1067  if (save_state_canfail ("")) {
1068  /* failed - don't quit */
1069  MessageDialog msg (*editor,
1070  string_compose (_("\
1071 %1 was unable to save your session.\n\n\
1072 If you still wish to quit, please use the\n\n\
1073 \"Just quit\" option."), PROGRAM_NAME));
1074  pop_back_splash(msg);
1075  msg.run ();
1076  return;
1077  }
1078  break;
1079  case 0:
1080  break;
1081  }
1082  }
1083 
1084  second_connection.disconnect ();
1085  point_one_second_connection.disconnect ();
1087  fps_connection.disconnect();
1088  }
1089 
1093 
1094  /* Save state before deleting the session, as that causes some
1095  windows to be destroyed before their visible state can be
1096  saved.
1097  */
1098  save_ardour_state ();
1099 
1100  close_all_dialogs ();
1101 
1102  if (_session) {
1103  _session->set_clean ();
1105  delete _session;
1106  _session = 0;
1107  }
1108 
1110  AudioEngine::instance()->stop ();
1111 #ifdef WINDOWS_VST_SUPPORT
1112  fst_stop_threading();
1113 #endif
1114  quit ();
1115 }
1116 
1117 int
1118 ARDOUR_UI::ask_about_saving_session (const vector<string>& actions)
1119 {
1120  ArdourDialog window (_("Unsaved Session"));
1121  Gtk::HBox dhbox; // the hbox for the image and text
1122  Gtk::Label prompt_label;
1123  Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_WARNING, Gtk::ICON_SIZE_DIALOG));
1124 
1125  string msg;
1126 
1127  assert (actions.size() >= 3);
1128 
1129  window.add_button (actions[0], RESPONSE_REJECT);
1130  window.add_button (actions[1], RESPONSE_APPLY);
1131  window.add_button (actions[2], RESPONSE_ACCEPT);
1132 
1133  window.set_default_response (RESPONSE_ACCEPT);
1134 
1135  Gtk::Button noquit_button (msg);
1136  noquit_button.set_name ("EditorGTKButton");
1137 
1138  string prompt;
1139 
1140  if (_session->snap_name() == _session->name()) {
1141  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?"),
1142  _session->snap_name());
1143  } else {
1144  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?"),
1145  _session->snap_name());
1146  }
1147 
1148  prompt_label.set_text (prompt);
1149  prompt_label.set_name (X_("PrompterLabel"));
1150  prompt_label.set_alignment(ALIGN_LEFT, ALIGN_TOP);
1151 
1152  dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP);
1153  dhbox.set_homogeneous (false);
1154  dhbox.pack_start (*dimage, false, false, 5);
1155  dhbox.pack_start (prompt_label, true, false, 5);
1156  window.get_vbox()->pack_start (dhbox);
1157 
1158  window.set_name (_("Prompter"));
1159  window.set_modal (true);
1160  window.set_resizable (false);
1161 
1162  dhbox.show();
1163  prompt_label.show();
1164  dimage->show();
1165  window.show();
1166  window.present ();
1167 
1168  ResponseType r = (ResponseType) window.run();
1169 
1170  window.hide ();
1171 
1172  switch (r) {
1173  case RESPONSE_ACCEPT: // save and get out of here
1174  return 1;
1175  case RESPONSE_APPLY: // get out of here
1176  return 0;
1177  default:
1178  break;
1179  }
1180 
1181  return -1;
1182 }
1183 
1184 
1185 void
1187 {
1188  update_cpu_load ();
1189  update_xrun_count ();
1190  update_buffer_load ();
1191  update_disk_space ();
1193 
1194  if (nsm && nsm->is_active ()) {
1195  nsm->check ();
1196 
1197  if (!_was_dirty && _session->dirty ()) {
1198  nsm->is_dirty ();
1199  _was_dirty = true;
1200  }
1201  else if (_was_dirty && !_session->dirty ()){
1202  nsm->is_clean ();
1203  _was_dirty = false;
1204  }
1205  }
1206 }
1207 
1208 void
1210 {
1211  // TODO get rid of this..
1212  // ShuttleControl is updated directly via TransportStateChange signal
1213 }
1214 
1215 void
1217 {
1218  // august 2007: actual update frequency: 25Hz (40ms), not 100Hz
1219 
1220  if (editor_meter && ARDOUR_UI::config()->get_show_editor_meter()) {
1221  float mpeak = editor_meter->update_meters();
1222  if (mpeak > editor_meter_max_peak) {
1223  if (mpeak >= ARDOUR_UI::config()->get_meter_peak()) {
1225  }
1226  }
1227  }
1228 }
1229 
1230 void
1232 {
1233  unsigned int interval = 40;
1234  if (!_session) return;
1235  if (_session->timecode_frames_per_second() != 0) {
1236  /* ideally we'll use a select() to sleep and not accumulate
1237  * idle time to provide a regular periodic signal.
1238  * See linux_vst_gui_support.cc 'elapsed_time_ms'.
1239  * However, that'll require a dedicated thread and cross-thread
1240  * signals to the GUI Thread..
1241  */
1242  interval = floor(500. /* update twice per FPS, since Glib::signal_timeout is very irregular */
1245  );
1246 #ifdef PLATFORM_WINDOWS
1247  // the smallest windows scheduler time-slice is ~15ms.
1248  // periodic GUI timeouts shorter than that will cause
1249  // WaitForSingleObject to spinlock (100% of one CPU Core)
1250  // and gtk never enters idle mode.
1251  // also changing timeBeginPeriod(1) does not affect that in
1252  // any beneficial way, so we just limit the max rate for now.
1253  interval = std::max(30u, interval); // at most ~33Hz.
1254 #else
1255  interval = std::max(8u, interval); // at most 120Hz.
1256 #endif
1257  }
1258  fps_connection.disconnect();
1259  Timers::set_fps_interval (interval);
1260 }
1261 
1262 void
1264 {
1265  char buf[64];
1266 
1268 
1269  if (!AudioEngine::instance()->connected()) {
1270 
1271  snprintf (buf, sizeof (buf), "%s", _("Audio: <span foreground=\"red\">none</span>"));
1272 
1273  } else {
1274 
1275  framecnt_t rate = AudioEngine::instance()->sample_rate();
1276 
1277  if (rate == 0) {
1278  /* no sample rate available */
1279  snprintf (buf, sizeof (buf), "%s", _("Audio: <span foreground=\"red\">none</span>"));
1280  } else {
1281 
1282  if (fmod (rate, 1000.0) != 0.0) {
1283  snprintf (buf, sizeof (buf), _("Audio: <span foreground=\"green\">%.1f kHz / %4.1f ms</span>"),
1284  (float) rate / 1000.0f,
1285  (AudioEngine::instance()->usecs_per_cycle() / 1000.0f));
1286  } else {
1287  snprintf (buf, sizeof (buf), _("Audio: <span foreground=\"green\">%" PRId64 " kHz / %4.1f ms</span>"),
1288  rate/1000,
1289  (AudioEngine::instance()->usecs_per_cycle() / 1000.0f));
1290  }
1291  }
1292  }
1293  sample_rate_label.set_markup (buf);
1294 }
1295 
1296 void
1298 {
1299  if (!_session) {
1300  format_label.set_text ("");
1301  return;
1302  }
1303 
1304  stringstream s;
1305  s << _("File:") << X_(" <span foreground=\"green\">");
1306 
1307  switch (_session->config.get_native_file_header_format ()) {
1308  case BWF:
1309  s << _("BWF");
1310  break;
1311  case WAVE:
1312  s << _("WAV");
1313  break;
1314  case WAVE64:
1315  s << _("WAV64");
1316  break;
1317  case CAF:
1318  s << _("CAF");
1319  break;
1320  case AIFF:
1321  s << _("AIFF");
1322  break;
1323  case iXML:
1324  s << _("iXML");
1325  break;
1326  case RF64:
1327  s << _("RF64");
1328  break;
1329  }
1330 
1331  s << " ";
1332 
1333  switch (_session->config.get_native_file_data_format ()) {
1334  case FormatFloat:
1335  s << _("32-float");
1336  break;
1337  case FormatInt24:
1338  s << _("24-int");
1339  break;
1340  case FormatInt16:
1341  s << _("16-int");
1342  break;
1343  }
1344 
1345  s << X_("</span>");
1346 
1347  format_label.set_markup (s.str ());
1348 }
1349 
1350 void
1352 {
1353  char buf[64];
1354 
1355  /* If this text is changed, the set_size_request_to_display_given_text call in ARDOUR_UI::resize_text_widgets
1356  should also be changed.
1357  */
1358 
1359  if (_session) {
1360  const unsigned int x = _session->get_xrun_count ();
1361  if (x > 9999) {
1362  snprintf (buf, sizeof (buf), _("X: <span foreground=\"%s\">&gt;10K</span>"), X_("red"));
1363  } else {
1364  snprintf (buf, sizeof (buf), _("X: <span foreground=\"%s\">%u</span>"), x > 0 ? X_("red") : X_("green"), x);
1365  }
1366  } else {
1367  snprintf (buf, sizeof (buf), _("X: <span foreground=\"%s\">?</span>"), X_("yellow"));
1368  }
1369  xrun_label.set_markup (buf);
1370  set_tip (xrun_label, _("Audio dropouts. Shift+click to reset"));
1371 }
1372 
1373 void
1375 {
1376  char buf[64];
1377 
1378  /* If this text is changed, the set_size_request_to_display_given_text call in ARDOUR_UI::resize_text_widgets
1379  should also be changed.
1380  */
1381 
1382  double const c = AudioEngine::instance()->get_dsp_load ();
1383  snprintf (buf, sizeof (buf), _("DSP: <span foreground=\"%s\">%5.1f%%</span>"), c >= 90 ? X_("red") : X_("green"), c);
1384  cpu_load_label.set_markup (buf);
1385 }
1386 
1387 void
1389 {
1390  char buf[256];
1391 
1392  uint32_t const playback = _session ? _session->playback_load () : 100;
1393  uint32_t const capture = _session ? _session->capture_load () : 100;
1394 
1395  /* If this text is changed, the set_size_request_to_display_given_text call in ARDOUR_UI::resize_text_widgets
1396  should also be changed.
1397  */
1398 
1399  if (_session) {
1400  snprintf (
1401  buf, sizeof (buf),
1402  _("Buffers: <span foreground=\"green\">p:</span><span foreground=\"%s\">%" PRIu32 "%%</span> "
1403  "<span foreground=\"green\">c:</span><span foreground=\"%s\">%" PRIu32 "%%</span>"),
1404  playback <= 5 ? X_("red") : X_("green"),
1405  playback,
1406  capture <= 5 ? X_("red") : X_("green"),
1407  capture
1408  );
1409 
1410  buffer_load_label.set_markup (buf);
1411  } else {
1412  buffer_load_label.set_text ("");
1413  }
1414 }
1415 
1416 void
1418 {
1419  Track* track = dynamic_cast<Track*>(&route);
1420  if (track && track->record_enabled()) {
1421  rec_enabled_streams += track->n_inputs().n_total();
1422  }
1423 }
1424 
1425 void
1427 {
1428  if (_session == 0) {
1429  return;
1430  }
1431 
1432  boost::optional<framecnt_t> opt_frames = _session->available_capture_duration();
1433  char buf[64];
1434  framecnt_t fr = _session->frame_rate();
1435 
1436  if (fr == 0) {
1437  /* skip update - no SR available */
1438  return;
1439  }
1440 
1441  if (!opt_frames) {
1442  /* Available space is unknown */
1443  snprintf (buf, sizeof (buf), "%s", _("Disk: <span foreground=\"green\">Unknown</span>"));
1444  } else if (opt_frames.get_value_or (0) == max_framecnt) {
1445  snprintf (buf, sizeof (buf), "%s", _("Disk: <span foreground=\"green\">24hrs+</span>"));
1446  } else {
1447  rec_enabled_streams = 0;
1449 
1450  framecnt_t frames = opt_frames.get_value_or (0);
1451 
1452  if (rec_enabled_streams) {
1453  frames /= rec_enabled_streams;
1454  }
1455 
1456  int hrs;
1457  int mins;
1458  int secs;
1459 
1460  hrs = frames / (fr * 3600);
1461 
1462  if (hrs > 24) {
1463  snprintf (buf, sizeof (buf), "%s", _("Disk: <span foreground=\"green\">&gt;24 hrs</span>"));
1464  } else {
1465  frames -= hrs * fr * 3600;
1466  mins = frames / (fr * 60);
1467  frames -= mins * fr * 60;
1468  secs = frames / fr;
1469 
1470  bool const low = (hrs == 0 && mins <= 30);
1471 
1472  snprintf (
1473  buf, sizeof(buf),
1474  _("Disk: <span foreground=\"%s\">%02dh:%02dm:%02ds</span>"),
1475  low ? X_("red") : X_("green"),
1476  hrs, mins, secs
1477  );
1478  }
1479  }
1480 
1481  disk_space_label.set_markup (buf);
1482 }
1483 
1484 void
1486 {
1487  char buf[64];
1488 
1489  if (_session) {
1490  bool matching;
1491  TimecodeSlave* tcslave;
1492  SyncSource sync_src = Config->get_sync_source();
1493 
1494  if ((sync_src == LTC || sync_src == MTC) && (tcslave = dynamic_cast<TimecodeSlave*>(_session->slave())) != 0) {
1495  matching = (tcslave->apparent_timecode_format() == _session->config.get_timecode_format());
1496  } else {
1497  matching = true;
1498  }
1499 
1500  snprintf (buf, sizeof (buf), S_("Timecode|TC: <span foreground=\"%s\">%s</span>"),
1501  matching ? X_("green") : X_("red"),
1502  Timecode::timecode_format_name (_session->config.get_timecode_format()).c_str());
1503  } else {
1504  snprintf (buf, sizeof (buf), "TC: n/a");
1505  }
1506 
1507  timecode_format_label.set_markup (buf);
1508 }
1509 
1510 gint
1512 {
1513  time_t now;
1514  struct tm *tm_now;
1515  static int last_min = -1;
1516 
1517  time (&now);
1518  tm_now = localtime (&now);
1519  if (last_min != tm_now->tm_min) {
1520  char buf[16];
1521  sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
1522  wall_clock_label.set_text (buf);
1523  last_min = tm_now->tm_min;
1524  }
1525 
1526  return TRUE;
1527 }
1528 
1529 void
1531 {
1532  std::vector<std::string> session_directories;
1534 
1535  recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
1536  recent_session_model->clear ();
1537 
1540 
1541  if (rs.empty()) {
1543  return;
1544  }
1545 
1546  // sort them alphabetically
1547  sort (rs.begin(), rs.end(), cmp);
1548 
1549  for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
1550  session_directories.push_back ((*i).second);
1551  }
1552 
1553  for (vector<std::string>::const_iterator i = session_directories.begin();
1554  i != session_directories.end(); ++i)
1555  {
1556  std::vector<std::string> state_file_paths;
1557 
1558  // now get available states for this session
1559 
1560  get_state_files_in_directory (*i, state_file_paths);
1561 
1562  vector<string> states;
1563  vector<const gchar*> item;
1564  string fullpath = *i;
1565 
1566  /* remove any trailing / */
1567 
1568  if (fullpath[fullpath.length() - 1] == '/') {
1569  fullpath = fullpath.substr (0, fullpath.length() - 1);
1570  }
1571 
1572  /* check whether session still exists */
1573  if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
1574  /* session doesn't exist */
1575  continue;
1576  }
1577 
1578  /* now get available states for this session */
1579  states = Session::possible_states (fullpath);
1580 
1581  if (states.empty()) {
1582  /* no state file? */
1583  continue;
1584  }
1585 
1586  std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
1587 
1588  Gtk::TreeModel::Row row = *(recent_session_model->append());
1589 
1590  row[recent_session_columns.fullpath] = fullpath;
1591  row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
1592 
1593  if (state_file_names.size() > 1) {
1594  // multiple session files in the session directory - show the directory name.
1595  row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
1596 
1597  // add the children
1598  for (std::vector<std::string>::iterator i2 = state_file_names.begin();
1599  i2 != state_file_names.end(); ++i2)
1600  {
1601 
1602  Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
1603 
1604  child_row[recent_session_columns.visible_name] = *i2;
1605  child_row[recent_session_columns.fullpath] = fullpath;
1606  child_row[recent_session_columns.tip] = Glib::Markup::escape_text (fullpath);
1607  }
1608  } else {
1609  // only a single session file in the directory - show its actual name.
1610  row[recent_session_columns.visible_name] = state_file_names.front ();
1611  }
1612  }
1613 
1614  recent_session_display.set_tooltip_column(1); // recent_session_columns.tip
1616 }
1617 
1618 void
1620 {
1621  session_selector_window = new ArdourDialog (_("Recent Sessions"));
1622 
1623  Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
1624 
1625  session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
1626  session_selector_window->add_button (Stock::OPEN, RESPONSE_ACCEPT);
1627  session_selector_window->set_default_response (RESPONSE_ACCEPT);
1628  recent_session_model = TreeStore::create (recent_session_columns);
1630  recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1631  recent_session_display.set_headers_visible (false);
1632  recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
1633  recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ARDOUR_UI::recent_session_row_activated));
1634 
1635  scroller->add (recent_session_display);
1636  scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1637 
1638  session_selector_window->set_name ("SessionSelectorWindow");
1639  session_selector_window->set_size_request (200, 400);
1640  session_selector_window->get_vbox()->pack_start (*scroller);
1641 
1642  recent_session_display.show();
1643  scroller->show();
1644 }
1645 
1646 void
1647 ARDOUR_UI::recent_session_row_activated (const TreePath& /*path*/, TreeViewColumn* /*col*/)
1648 {
1649  session_selector_window->response (RESPONSE_ACCEPT);
1650 }
1651 
1652 void
1654 {
1655  bool can_return = (_session != 0);
1656 
1657  if (session_selector_window == 0) {
1659  }
1660 
1662 
1663  while (true) {
1664 
1665  ResponseType r = (ResponseType) session_selector_window->run ();
1666 
1667  switch (r) {
1668  case RESPONSE_ACCEPT:
1669  break;
1670  default:
1671  if (can_return) {
1672  session_selector_window->hide();
1673  return;
1674  } else {
1675  exit (1);
1676  }
1677  }
1678 
1679  if (recent_session_display.get_selection()->count_selected_rows() == 0) {
1680  continue;
1681  }
1682 
1683  session_selector_window->hide();
1684 
1685  Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
1686 
1687  if (i == recent_session_model->children().end()) {
1688  return;
1689  }
1690 
1691  std::string path = (*i)[recent_session_columns.fullpath];
1692  std::string state = (*i)[recent_session_columns.visible_name];
1693 
1694  _session_is_new = false;
1695 
1696  if (load_session (path, state) == 0) {
1697  break;
1698  }
1699 
1700  can_return = false;
1701  }
1702 }
1703 
1704 bool
1706 {
1707  if (!AudioEngine::instance()->connected()) {
1708  MessageDialog msg (string_compose (
1709  _("%1 is not connected to any audio backend.\n"
1710  "You cannot open or close sessions in this condition"),
1711  PROGRAM_NAME));
1712  pop_back_splash (msg);
1713  msg.run ();
1714  return false;
1715  }
1716  return true;
1717 }
1718 
1719 void
1721 {
1722  if (!check_audioengine()) {
1723  return;
1724 
1725  }
1726 
1727  /* popup selector window */
1728 
1729  if (open_session_selector == 0) {
1730 
1731  /* ardour sessions are folders */
1732 
1733  open_session_selector = new Gtk::FileChooserDialog (_("Open Session"), FILE_CHOOSER_ACTION_OPEN);
1734  open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1735  open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
1736  open_session_selector->set_default_response(Gtk::RESPONSE_ACCEPT);
1737 
1738  if (_session) {
1739  string session_parent_dir = Glib::path_get_dirname(_session->path());
1740  string::size_type last_dir_sep = session_parent_dir.rfind(G_DIR_SEPARATOR);
1741  session_parent_dir = session_parent_dir.substr(0, last_dir_sep);
1742  open_session_selector->set_current_folder(session_parent_dir);
1743  } else {
1744  open_session_selector->set_current_folder(Config->get_default_session_parent_dir());
1745  }
1746 
1747  string default_session_folder = Config->get_default_session_parent_dir();
1748  try {
1749  /* add_shortcut_folder throws an exception if the folder being added already has a shortcut */
1750  open_session_selector->add_shortcut_folder (default_session_folder);
1751  }
1752  catch (Glib::Error & e) {
1753  std::cerr << "open_session_selector->add_shortcut_folder (" << default_session_folder << ") threw Glib::Error " << e.what() << std::endl;
1754  }
1755 
1756  FileFilter session_filter;
1757  session_filter.add_pattern (string_compose(X_("*%1"), ARDOUR::statefile_suffix));
1758  session_filter.set_name (string_compose (_("%1 sessions"), PROGRAM_NAME));
1759  open_session_selector->add_filter (session_filter);
1760  open_session_selector->set_filter (session_filter);
1761  }
1762 
1763  int response = open_session_selector->run();
1764  open_session_selector->hide ();
1765 
1766  switch (response) {
1767  case RESPONSE_ACCEPT:
1768  break;
1769  default:
1770  open_session_selector->hide();
1771  return;
1772  }
1773 
1774  open_session_selector->hide();
1775  string session_path = open_session_selector->get_filename();
1776  string path, name;
1777  bool isnew;
1778 
1779  if (session_path.length() > 0) {
1780  if (ARDOUR::find_session (session_path, path, name, isnew) == 0) {
1781  _session_is_new = isnew;
1782  load_session (path, name);
1783  }
1784  }
1785 }
1786 
1787 
1788 void
1789 ARDOUR_UI::session_add_mixed_track (const ChanCount& input, const ChanCount& output, RouteGroup* route_group,
1790  uint32_t how_many, const string& name_template, PluginInfoPtr instrument)
1791 {
1792  list<boost::shared_ptr<MidiTrack> > tracks;
1793 
1794  if (_session == 0) {
1795  warning << _("You cannot add a track without a session already loaded.") << endmsg;
1796  return;
1797  }
1798 
1799  try {
1800  tracks = _session->new_midi_track (input, output, instrument, ARDOUR::Normal, route_group, how_many, name_template);
1801 
1802  if (tracks.size() != how_many) {
1803  error << string_compose(P_("could not create %1 new mixed track", "could not create %1 new mixed tracks", how_many), how_many) << endmsg;
1804  }
1805  }
1806 
1807  catch (...) {
1808  MessageDialog msg (*editor,
1809  string_compose (_("There are insufficient ports available\n\
1810 to create a new track or bus.\n\
1811 You should save %1, exit and\n\
1812 restart with more ports."), PROGRAM_NAME));
1813  msg.run ();
1814  }
1815 }
1816 
1817 
1818 void
1819 ARDOUR_UI::session_add_midi_route (bool disk, RouteGroup* route_group, uint32_t how_many, const string& name_template, PluginInfoPtr instrument)
1820 {
1821  ChanCount one_midi_channel;
1822  one_midi_channel.set (DataType::MIDI, 1);
1823 
1824  if (disk) {
1825  session_add_mixed_track (one_midi_channel, one_midi_channel, route_group, how_many, name_template, instrument);
1826  }
1827 }
1828 
1829 void
1831  bool track,
1832  int32_t input_channels,
1833  int32_t output_channels,
1834  ARDOUR::TrackMode mode,
1835  RouteGroup* route_group,
1836  uint32_t how_many,
1837  string const & name_template
1838  )
1839 {
1840  list<boost::shared_ptr<AudioTrack> > tracks;
1841  RouteList routes;
1842 
1843  if (_session == 0) {
1844  warning << _("You cannot add a track or bus without a session already loaded.") << endmsg;
1845  return;
1846  }
1847 
1848  try {
1849  if (track) {
1850  tracks = _session->new_audio_track (input_channels, output_channels, mode, route_group, how_many, name_template);
1851 
1852  if (tracks.size() != how_many) {
1853  error << string_compose (P_("could not create %1 new audio track", "could not create %1 new audio tracks", how_many), how_many)
1854  << endmsg;
1855  }
1856 
1857  } else {
1858 
1859  routes = _session->new_audio_route (input_channels, output_channels, route_group, how_many, name_template);
1860 
1861  if (routes.size() != how_many) {
1862  error << string_compose (P_("could not create %1 new audio bus", "could not create %1 new audio busses", how_many), how_many)
1863  << endmsg;
1864  }
1865  }
1866  }
1867 
1868  catch (...) {
1869  MessageDialog msg (*editor,
1870  string_compose (_("There are insufficient ports available\n\
1871 to create a new track or bus.\n\
1872 You should save %1, exit and\n\
1873 restart with more ports."), PROGRAM_NAME));
1874  pop_back_splash (msg);
1875  msg.run ();
1876  }
1877 }
1878 
1879 void
1881 {
1882  if (_session) {
1883  _session->goto_start();
1884 
1885  /* force displayed area in editor to start no matter
1886  what "follow playhead" setting is.
1887  */
1888 
1889  if (editor) {
1891  }
1892  }
1893 }
1894 
1895 void
1897 {
1898  if (_session) {
1899  _session->request_locate (0);
1900 
1901  /* force displayed area in editor to start no matter
1902  what "follow playhead" setting is.
1903  */
1904 
1905  if (editor) {
1906  editor->reset_x_origin (0);
1907  }
1908  }
1909 }
1910 
1911 void
1913 {
1914  if (_session && editor) {
1915 
1916  time_t now;
1917  struct tm tmnow;
1918  framepos_t frames;
1919 
1920  time (&now);
1921  localtime_r (&now, &tmnow);
1922 
1923  int frame_rate = _session->frame_rate();
1924 
1925  if (frame_rate == 0) {
1926  /* no frame rate available */
1927  return;
1928  }
1929 
1930  frames = tmnow.tm_hour * (60 * 60 * frame_rate);
1931  frames += tmnow.tm_min * (60 * frame_rate);
1932  frames += tmnow.tm_sec * frame_rate;
1933 
1935 
1936  /* force displayed area in editor to start no matter
1937  what "follow playhead" setting is.
1938  */
1939 
1940  if (editor) {
1941  editor->center_screen (frames);
1942  }
1943  }
1944 }
1945 
1946 void
1948 {
1949  if (_session) {
1950  framepos_t const frame = _session->current_end_frame();
1951  _session->request_locate (frame);
1952 
1953  /* force displayed area in editor to start no matter
1954  what "follow playhead" setting is.
1955  */
1956 
1957  if (editor) {
1958  editor->center_screen (frame);
1959  }
1960  }
1961 }
1962 
1963 void
1965 {
1966  if (!_session) {
1967  return;
1968  }
1969 
1970  if (_session->is_auditioning()) {
1972  return;
1973  }
1974 
1975  _session->request_stop (false, true);
1976 }
1977 
1981 bool
1983 {
1984  if (!_session) {
1985  return false;
1986  }
1987 
1989  bool none_record_enabled = true;
1990 
1991  for (RouteList::iterator r = rl->begin(); r != rl->end(); ++r) {
1993  assert (t);
1994 
1995  if (t->record_enabled()) {
1996  none_record_enabled = false;
1997  break;
1998  }
1999  }
2000 
2001  if (none_record_enabled) {
2002  _session->set_record_enabled (rl, true, Session::rt_cleanup);
2003  }
2004 
2005  return none_record_enabled;
2006 }
2007 
2008 void
2010 {
2011  if (_session) {
2012  switch (_session->record_status()) {
2013  case Session::Disabled:
2014  if (_session->ntracks() == 0) {
2015  MessageDialog msg (*editor, _("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."));
2016  msg.run ();
2017  return;
2018  }
2019  if (Profile->get_trx()) {
2020  roll = trx_record_enable_all_tracks ();
2021  }
2023  if (roll) {
2024  transport_roll ();
2025  }
2026  break;
2027  case Session::Recording:
2028  if (roll) {
2030  } else {
2031  _session->disable_record (false, true);
2032  }
2033  break;
2034 
2035  case Session::Enabled:
2036  _session->disable_record (false, true);
2037  }
2038  }
2039 }
2040 
2041 void
2043 {
2044  if (!_session) {
2045  return;
2046  }
2047 
2048  if (_session->is_auditioning()) {
2049  return;
2050  }
2051 
2052 #if 0
2053  if (_session->config.get_external_sync()) {
2054  switch (Config->get_sync_source()) {
2055  case Engine:
2056  break;
2057  default:
2058  /* transport controlled by the master */
2059  return;
2060  }
2061  }
2062 #endif
2063 
2064  bool rolling = _session->transport_rolling();
2065 
2066  if (_session->get_play_loop()) {
2067 
2068  /* If loop playback is not a mode, then we should cancel
2069  it when this action is requested. If it is a mode
2070  we just leave it in place.
2071  */
2072 
2073  if (!Config->get_loop_is_mode()) {
2074  /* XXX it is not possible to just leave seamless loop and keep
2075  playing at present (nov 4th 2009)
2076  */
2077  if (!Config->get_seamless_loop()) {
2078  /* stop loop playback and stop rolling */
2079  _session->request_play_loop (false, true);
2080  } else if (rolling) {
2081  /* stop loop playback but keep rolling */
2082  _session->request_play_loop (false, false);
2083  }
2084  }
2085 
2086  } else if (_session->get_play_range () ) {
2087  /* stop playing a range if we currently are */
2088  _session->request_play_range (0, true);
2089  }
2090 
2091  if (!rolling) {
2093  }
2094 }
2095 
2096 bool
2098 {
2099  return ( editor->get_smart_mode() );
2100 }
2101 
2102 
2103 void
2104 ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode)
2105 {
2106 
2107  if (!_session) {
2108  return;
2109  }
2110 
2111  if (_session->is_auditioning()) {
2113  return;
2114  }
2115 
2116  if (_session->config.get_external_sync()) {
2117  switch (Config->get_sync_source()) {
2118  case Engine:
2119  break;
2120  default:
2121  /* transport controlled by the master */
2122  return;
2123  }
2124  }
2125 
2126  bool rolling = _session->transport_rolling();
2127  bool affect_transport = true;
2128 
2129  if (rolling && roll_out_of_bounded_mode) {
2130  /* drop out of loop/range playback but leave transport rolling */
2131  if (_session->get_play_loop()) {
2132  if (Config->get_seamless_loop()) {
2133  /* the disk buffers contain copies of the loop - we can't
2134  just keep playing, so stop the transport. the user
2135  can restart as they wish.
2136  */
2137  affect_transport = true;
2138  } else {
2139  /* disk buffers are normal, so we can keep playing */
2140  affect_transport = false;
2141  }
2142  _session->request_play_loop (false, affect_transport);
2143  } else if (_session->get_play_range ()) {
2144  affect_transport = false;
2145  _session->request_play_range (0, true);
2146  }
2147  }
2148 
2149  if (affect_transport) {
2150  if (rolling) {
2151  _session->request_stop (with_abort, true);
2152  } else {
2153  if (ARDOUR_UI::config()->get_follow_edits() && ( editor->get_selection().time.front().start == _session->transport_frame() ) ) { //if playhead is exactly at the start of a range, we can assume it was placed there by follow_edits
2155  _session->set_requested_return_frame( editor->get_selection().time.front().start ); //force an auto-return here
2156  }
2158  }
2159  }
2160 }
2161 
2162 void
2164 {
2165  Location * looploc = _session->locations()->auto_loop_location();
2166 
2167  if (!_session || !looploc) {
2168  return;
2169  }
2170 
2171  if (_session->get_play_loop()) {
2172 
2173  /* looping enabled, our job is to disable it */
2174 
2175  _session->request_play_loop (false);
2176 
2177  } else {
2178 
2179  /* looping not enabled, our job is to enable it.
2180 
2181  loop-is-NOT-mode: this action always starts the transport rolling.
2182  loop-IS-mode: this action simply sets the loop play mechanism, but
2183  does not start transport.
2184  */
2185  if (Config->get_loop_is_mode()) {
2186  _session->request_play_loop (true, false);
2187  } else {
2188  _session->request_play_loop (true, true);
2189  }
2190  }
2191 
2192  //show the loop markers
2193  looploc->set_hidden (false, this);
2194 }
2195 
2196 void
2198 {
2199  if (!_session) {
2200  return;
2201  }
2202 
2203  editor->play_selection ();
2204 }
2205 
2206 void
2208 {
2209  if (!_session) {
2210  return;
2211  }
2213 }
2214 
2215 void
2217 {
2218  float current_transport_speed;
2219 
2220  if (_session) {
2221  current_transport_speed = _session->transport_speed();
2222 
2223  if (current_transport_speed >= 0.0f) {
2224  switch (option) {
2225  case 0:
2227  break;
2228  case 1:
2230  break;
2231  case -1:
2233  break;
2234  }
2235  } else {
2236  /* speed up */
2237  _session->request_transport_speed (current_transport_speed * 1.5f);
2238  }
2239  }
2240 }
2241 
2242 void
2244 {
2245  if (!_session) {
2246  return;
2247  }
2248 
2249  float current_transport_speed = _session->transport_speed();
2250 
2251  if (current_transport_speed <= 0.0f) {
2252  switch (option) {
2253  case 0:
2255  break;
2256  case 1:
2258  break;
2259  case -1:
2261  break;
2262  }
2263  } else {
2264  /* speed up */
2265  _session->request_transport_speed (current_transport_speed * 1.5f);
2266  }
2267 }
2268 
2269 void
2271 {
2272  if (!_session) {
2273  return;
2274  }
2275 
2277 
2278  if ((r = _session->route_by_remote_id (rid)) != 0) {
2279 
2280  Track* t;
2281 
2282  if ((t = dynamic_cast<Track*>(r.get())) != 0) {
2283  t->set_record_enabled (!t->record_enabled(), this);
2284  }
2285  }
2286 }
2287 
2288 void
2290 {
2291  if (!_session) {
2296  return;
2297  }
2298 
2300 
2301  float sp = _session->transport_speed();
2302 
2303  if (sp != 0.0f) {
2304 
2305  /* we're rolling */
2306 
2307  if (_session->get_play_range()) {
2308 
2312 
2313  } else if (_session->get_play_loop ()) {
2314 
2317  if (Config->get_loop_is_mode()) {
2318  roll_button.set_active (true);
2319  } else {
2320  roll_button.set_active (false);
2321  }
2322 
2323  } else {
2324 
2325  roll_button.set_active (true);
2327  auto_loop_button.set_active (false);
2328  }
2329 
2330  if (ARDOUR_UI::config()->get_follow_edits()) {
2331  /* light up both roll and play-selection if they are joined */
2332  roll_button.set_active (true);
2334  }
2335 
2336  stop_button.set_active (false);
2337 
2338  } else {
2339 
2340  stop_button.set_active (true);
2341  roll_button.set_active (false);
2343  if (Config->get_loop_is_mode ()) {
2345  } else {
2346  auto_loop_button.set_active (false);
2347  }
2348  update_disk_space ();
2349  }
2350 }
2351 
2352 void
2354 {
2355  transport_rec_enable_blink (blink_on);
2356  solo_blink (blink_on);
2357  sync_blink (blink_on);
2358  audition_blink (blink_on);
2359  feedback_blink (blink_on);
2360  error_blink (blink_on);
2361 }
2362 
2363 void
2365 {
2366  if (!_session) return;
2367 
2368  if (editor && !editor->dragging_playhead()) {
2370  }
2371 }
2372 
2373 void
2375 {
2376  if (ui_config->get_super_rapid_clock_update()) {
2378  } else {
2380  }
2381 }
2382 
2383 void
2385 {
2386  clock_signal_connection.disconnect ();
2387 }
2388 
2389 bool
2390 ARDOUR_UI::save_as_progress_update (float fraction, int64_t cnt, int64_t total, Gtk::Label* label, Gtk::ProgressBar* bar)
2391 {
2392  char buf[256];
2393 
2394  snprintf (buf, sizeof (buf), _("Copied %" PRId64 " of %" PRId64), cnt, total);
2395 
2396  label->set_text (buf);
2397  bar->set_fraction (fraction);
2398 
2399  /* process events, redraws, etc. */
2400 
2401  while (gtk_events_pending()) {
2402  gtk_main_iteration ();
2403  }
2404 
2405  return true; /* continue with save-as */
2406 }
2407 
2408 void
2410 {
2411  if (!_session) {
2412  return;
2413  }
2414 
2415  if (!save_as_dialog) {
2417  } else {
2419  }
2420 
2421  int response = save_as_dialog->run ();
2422 
2423  save_as_dialog->hide ();
2424 
2425  switch (response) {
2426  case Gtk::RESPONSE_OK:
2427  break;
2428  default:
2429  return;
2430  }
2431 
2432  ArdourDialog progress_dialog(_("Save As"), true);
2433  Gtk::Label label;
2434  Gtk::ProgressBar progress_bar;
2435 
2436  progress_dialog.get_vbox()->pack_start (label);
2437  progress_dialog.get_vbox()->pack_start (progress_bar);
2438  label.show ();
2439  progress_bar.show ();
2440 
2441  Session::SaveAs sa;
2442 
2444  sa.new_name = save_as_dialog->new_name ();
2449 
2450  /* this signal will be emitted from within this, the calling thread,
2451  * after every file is copied. It provides information on percentage
2452  * complete (in terms of total data to copy), the number of files
2453  * copied so far, and the total number to copy.
2454  */
2455 
2456  ScopedConnection c;
2457 
2458  sa.Progress.connect_same_thread (c, boost::bind (&ARDOUR_UI::save_as_progress_update, this, _1, _2, _3, &label, &progress_bar));
2459 
2460  progress_dialog.show_all ();
2461  progress_dialog.present ();
2462 
2463  if (_session->save_as (sa)) {
2464  /* ERROR MESSAGE */
2465  MessageDialog msg (string_compose (_("Save As failed: %1"), sa.failure_message));
2466  msg.run ();
2467  }
2468 
2469  if (!sa.include_media) {
2470  unload_session (false);
2472  }
2473 }
2474 
2478 void
2479 ARDOUR_UI::snapshot_session (bool switch_to_it)
2480 {
2481  ArdourPrompter prompter (true);
2482  string snapname;
2483 
2484  prompter.set_name ("Prompter");
2485  prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
2486  if (switch_to_it) {
2487  prompter.set_title (_("Save as..."));
2488  prompter.set_prompt (_("New session name"));
2489  } else {
2490  prompter.set_title (_("Take Snapshot"));
2491  prompter.set_prompt (_("Name of new snapshot"));
2492  }
2493 
2494  if (!switch_to_it) {
2495  char timebuf[128];
2496  time_t n;
2497  struct tm local_time;
2498 
2499  time (&n);
2500  localtime_r (&n, &local_time);
2501  strftime (timebuf, sizeof(timebuf), "%FT%H.%M.%S", &local_time);
2502  prompter.set_initial_text (timebuf);
2503  }
2504 
2505  again:
2506  switch (prompter.run()) {
2507  case RESPONSE_ACCEPT:
2508  {
2509  prompter.get_result (snapname);
2510 
2511  bool do_save = (snapname.length() != 0);
2512 
2513  if (do_save) {
2514  char illegal = Session::session_name_is_legal(snapname);
2515  if (illegal) {
2516  MessageDialog msg (string_compose (_("To ensure compatibility with various systems\n"
2517  "snapshot names may not contain a '%1' character"), illegal));
2518  msg.run ();
2519  goto again;
2520  }
2521  }
2522 
2523  vector<std::string> p;
2525  vector<string> n = get_file_names_no_extension (p);
2526  if (find (n.begin(), n.end(), snapname) != n.end()) {
2527 
2528  ArdourDialog confirm (_("Confirm Snapshot Overwrite"), true);
2529  Label m (_("A snapshot already exists with that name. Do you want to overwrite it?"));
2530  confirm.get_vbox()->pack_start (m, true, true);
2531  confirm.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
2532  confirm.add_button (_("Overwrite"), Gtk::RESPONSE_ACCEPT);
2533  confirm.show_all ();
2534  switch (confirm.run()) {
2535  case RESPONSE_CANCEL:
2536  do_save = false;
2537  }
2538  }
2539 
2540  if (do_save) {
2541  save_state (snapname, switch_to_it);
2542  }
2543  break;
2544  }
2545 
2546  default:
2547  break;
2548  }
2549 }
2550 
2554 void
2556 {
2557  if (!_session) {
2558  return;
2559  }
2560 
2561  ArdourPrompter prompter (true);
2562  string name;
2563 
2564  prompter.set_name ("Prompter");
2565  prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
2566  prompter.set_title (_("Rename Session"));
2567  prompter.set_prompt (_("New session name"));
2568 
2569  again:
2570  switch (prompter.run()) {
2571  case RESPONSE_ACCEPT:
2572  {
2573  prompter.get_result (name);
2574 
2575  bool do_rename = (name.length() != 0);
2576 
2577  if (do_rename) {
2578  char illegal = Session::session_name_is_legal (name);
2579 
2580  if (illegal) {
2581  MessageDialog msg (string_compose (_("To ensure compatibility with various systems\n"
2582  "session names may not contain a '%1' character"), illegal));
2583  msg.run ();
2584  goto again;
2585  }
2586 
2587  switch (_session->rename (name)) {
2588  case -1: {
2589  MessageDialog msg (_("That name is already in use by another directory/folder. Please try again."));
2590  msg.set_position (WIN_POS_MOUSE);
2591  msg.run ();
2592  goto again;
2593  break;
2594  }
2595  case 0:
2596  break;
2597  default: {
2598  MessageDialog msg (_("Renaming this session failed.\nThings could be seriously messed up at this point"));
2599  msg.set_position (WIN_POS_MOUSE);
2600  msg.run ();
2601  break;
2602  }
2603  }
2604  }
2605 
2606  break;
2607  }
2608 
2609  default:
2610  break;
2611  }
2612 }
2613 
2614 void
2615 ARDOUR_UI::save_state (const string & name, bool switch_to_it)
2616 {
2617  XMLNode* node = new XMLNode (X_("UI"));
2618 
2619  WM::Manager::instance().add_state (*node);
2620 
2622 
2623  _session->add_extra_xml (*node);
2624 
2625  if (export_video_dialog) {
2627  }
2628 
2629  save_state_canfail (name, switch_to_it);
2630 }
2631 
2632 int
2633 ARDOUR_UI::save_state_canfail (string name, bool switch_to_it)
2634 {
2635  if (_session) {
2636  int ret;
2637 
2638  if (name.length() == 0) {
2639  name = _session->snap_name();
2640  }
2641 
2642  if ((ret = _session->save_state (name, false, switch_to_it)) != 0) {
2643  return ret;
2644  }
2645  }
2646 
2647  save_ardour_state (); /* XXX cannot fail? yeah, right ... */
2648  return 0;
2649 }
2650 
2651 void
2653 {
2654  if (_session) {
2656  }
2657 }
2658 
2659 void
2661 {
2662  if (_session) {
2664  }
2665 }
2666 
2667 void
2669 {
2670  if (_session) {
2672  }
2673 }
2674 
2675 void
2677 {
2678  if (_session == 0) {
2679  return;
2680  }
2681 
2682  if (_session->step_editing()) {
2683  return;
2684  }
2685 
2687  bool const h = _session->have_rec_enabled_track ();
2688 
2689  if (r == Session::Enabled || (r == Session::Recording && !h)) {
2690  if (onoff) {
2692  } else {
2694  }
2695  } else if (r == Session::Recording && h) {
2697  } else {
2699  }
2700 }
2701 
2702 void
2704 {
2705  ArdourPrompter prompter (true);
2706  string name;
2707 
2708  if (!check_audioengine()) {
2709  return;
2710  }
2711 
2712  prompter.set_name (X_("Prompter"));
2713  prompter.set_title (_("Save Template"));
2714  prompter.set_prompt (_("Name for template:"));
2715  prompter.set_initial_text(_session->name() + _("-template"));
2716  prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
2717 
2718  switch (prompter.run()) {
2719  case RESPONSE_ACCEPT:
2720  prompter.get_result (name);
2721 
2722  if (name.length()) {
2723  _session->save_template (name);
2724  }
2725  break;
2726 
2727  default:
2728  break;
2729  }
2730 }
2731 
2732 void
2734 {
2735  SessionMetadataEditor dialog;
2736  dialog.set_session (_session);
2737  dialog.grab_focus ();
2738  dialog.run ();
2739 }
2740 
2741 void
2743 {
2744  SessionMetadataImporter dialog;
2745  dialog.set_session (_session);
2746  dialog.run ();
2747 }
2748 
2749 bool
2750 ARDOUR_UI::ask_about_loading_existing_session (const std::string& session_path)
2751 {
2752  std::string str = string_compose (_("This session\n%1\nalready exists. Do you want to open it?"), session_path);
2753 
2754  MessageDialog msg (str,
2755  false,
2756  Gtk::MESSAGE_WARNING,
2757  Gtk::BUTTONS_YES_NO,
2758  true);
2759 
2760 
2761  msg.set_name (X_("OpenExistingDialog"));
2762  msg.set_title (_("Open Existing Session"));
2763  msg.set_wmclass (X_("existing_session"), PROGRAM_NAME);
2764  msg.set_position (Gtk::WIN_POS_CENTER);
2765  pop_back_splash (msg);
2766 
2767  switch (msg.run()) {
2768  case RESPONSE_YES:
2769  return true;
2770  break;
2771  }
2772  return false;
2773 }
2774 
2775 int
2776 ARDOUR_UI::build_session_from_dialog (SessionDialog& sd, const std::string& session_path, const std::string& session_name)
2777 {
2778  BusProfile bus_profile;
2779 
2780  if (nsm || Profile->get_sae()) {
2781 
2782  bus_profile.master_out_channels = 2;
2783  bus_profile.input_ac = AutoConnectPhysical;
2784  bus_profile.output_ac = AutoConnectMaster;
2785  bus_profile.requested_physical_in = 0; // use all available
2786  bus_profile.requested_physical_out = 0; // use all available
2787 
2788  } else {
2789 
2790  /* get settings from advanced section of NSD */
2791 
2792  if (sd.create_master_bus()) {
2793  bus_profile.master_out_channels = (uint32_t) sd.master_channel_count();
2794  } else {
2795  bus_profile.master_out_channels = 0;
2796  }
2797 
2798  if (sd.connect_inputs()) {
2799  bus_profile.input_ac = AutoConnectPhysical;
2800  } else {
2801  bus_profile.input_ac = AutoConnectOption (0);
2802  }
2803 
2804  bus_profile.output_ac = AutoConnectOption (0);
2805 
2806  if (sd.connect_outputs ()) {
2807  if (sd.connect_outs_to_master()) {
2808  bus_profile.output_ac = AutoConnectMaster;
2809  } else if (sd.connect_outs_to_physical()) {
2810  bus_profile.output_ac = AutoConnectPhysical;
2811  }
2812  }
2813 
2814  bus_profile.requested_physical_in = (uint32_t) sd.input_limit_count();
2815  bus_profile.requested_physical_out = (uint32_t) sd.output_limit_count();
2816  }
2817 
2818  if (build_session (session_path, session_name, bus_profile)) {
2819  return -1;
2820  }
2821 
2822  return 0;
2823 }
2824 
2825 void
2826 ARDOUR_UI::load_from_application_api (const std::string& path)
2827 {
2829 
2830  if (Glib::file_test (path, Glib::FILE_TEST_IS_DIR)) {
2831  /* /path/to/foo => /path/to/foo, foo */
2832  load_session (path, basename_nosuffix (path));
2833  } else {
2834  /* /path/to/foo/foo.ardour => /path/to/foo, foo */
2835  load_session (Glib::path_get_dirname (path), basename_nosuffix (path));
2836  }
2837 }
2838 
2840 int
2841 ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, string load_template)
2842 {
2843  string session_name;
2844  string session_path;
2845  string template_name;
2846  int ret = -1;
2847  bool likely_new = false;
2848  bool cancel_not_quit;
2849 
2850  /* deal with any existing DIRTY session now, rather than later. don't
2851  * treat a non-dirty session this way, so that it stays visible
2852  * as we bring up the new session dialog.
2853  */
2854 
2857  }
2858 
2859  /* if there is already a session, relabel the button
2860  on the SessionDialog so that we don't Quit directly
2861  */
2862  cancel_not_quit = (_session != 0);
2863 
2864  if (_session && _session->dirty()) {
2865  if (unload_session (false)) {
2866  /* unload cancelled by user */
2867  return 0;
2868  }
2870  }
2871 
2872  if (!load_template.empty()) {
2873  should_be_new = true;
2874  template_name = load_template;
2875  }
2876 
2878  session_path = ARDOUR_COMMAND_LINE::session_name;
2879 
2880  if (!session_path.empty()) {
2881  if (Glib::file_test (session_path.c_str(), Glib::FILE_TEST_EXISTS)) {
2882  if (Glib::file_test (session_path.c_str(), Glib::FILE_TEST_IS_REGULAR)) {
2883  /* session/snapshot file, change path to be dir */
2884  session_path = Glib::path_get_dirname (session_path);
2885  }
2886  }
2887  }
2888 
2889  SessionDialog session_dialog (should_be_new, session_name, session_path, load_template, cancel_not_quit);
2890 
2891  while (ret != 0) {
2892 
2893  if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
2894 
2895  /* if they named a specific statefile, use it, otherwise they are
2896  just giving a session folder, and we want to use it as is
2897  to find the session.
2898  */
2899 
2900  string::size_type suffix = ARDOUR_COMMAND_LINE::session_name.find (statefile_suffix);
2901 
2902  if (suffix != string::npos) {
2903  session_path = Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name);
2904  session_name = ARDOUR_COMMAND_LINE::session_name.substr (0, suffix);
2905  session_name = Glib::path_get_basename (session_name);
2906  } else {
2907  session_path = ARDOUR_COMMAND_LINE::session_name;
2908  session_name = Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name);
2909  }
2910  } else {
2911  session_path = "";
2912  session_name = "";
2913  session_dialog.clear_given ();
2914  }
2915 
2916  if (should_be_new || session_name.empty()) {
2917  /* need the dialog to get info from user */
2918 
2919  cerr << "run dialog\n";
2920 
2921  switch (session_dialog.run()) {
2922  case RESPONSE_ACCEPT:
2923  break;
2924  default:
2925  if (quit_on_cancel) {
2926  // JE - Currently (July 2014) this section can only get reached if the
2927  // user quits from the main 'Session Setup' dialog (i.e. reaching this
2928  // point does NOT indicate an abnormal termination). Therefore, let's
2929  // behave gracefully (i.e. let's do some cleanup) before we call exit()
2930  ARDOUR::cleanup ();
2931  pthread_cancel_all ();
2932 
2933  exit (1);
2934  } else {
2935  return ret;
2936  }
2937  }
2938 
2939  session_dialog.hide ();
2940  }
2941 
2942  /* if we run the startup dialog again, offer more than just "new session" */
2943 
2944  should_be_new = false;
2945 
2946  session_name = session_dialog.session_name (likely_new);
2947  session_path = session_dialog.session_folder ();
2948 
2949  if (nsm) {
2950  likely_new = true;
2951  }
2952 
2953  string::size_type suffix = session_name.find (statefile_suffix);
2954 
2955  if (suffix != string::npos) {
2956  session_name = session_name.substr (0, suffix);
2957  }
2958 
2959  /* this shouldn't happen, but we catch it just in case it does */
2960 
2961  if (session_name.empty()) {
2962  continue;
2963  }
2964 
2965  if (session_dialog.use_session_template()) {
2966  template_name = session_dialog.session_template_name();
2967  _session_is_new = true;
2968  }
2969 
2970  if (session_name[0] == G_DIR_SEPARATOR ||
2971 #ifdef PLATFORM_WINDOWS
2972  (session_name.length() > 3 && session_name[1] == ':' && session_name[2] == G_DIR_SEPARATOR)
2973 #else
2974  (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == G_DIR_SEPARATOR) ||
2975  (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == G_DIR_SEPARATOR)
2976 #endif
2977  )
2978  {
2979 
2980  /* absolute path or cwd-relative path specified for session name: infer session folder
2981  from what was given.
2982  */
2983 
2984  session_path = Glib::path_get_dirname (session_name);
2985  session_name = Glib::path_get_basename (session_name);
2986 
2987  } else {
2988 
2989  session_path = session_dialog.session_folder();
2990 
2991  char illegal = Session::session_name_is_legal (session_name);
2992 
2993  if (illegal) {
2994  MessageDialog msg (session_dialog,
2995  string_compose (_("To ensure compatibility with various systems\n"
2996  "session names may not contain a '%1' character"),
2997  illegal));
2998  msg.run ();
2999  ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
3000  continue;
3001  }
3002  }
3003 
3004  if (Glib::file_test (session_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
3005 
3006 
3007  if (likely_new && !nsm) {
3008 
3009  std::string existing = Glib::build_filename (session_path, session_name);
3010 
3011  if (!ask_about_loading_existing_session (existing)) {
3012  ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
3013  continue;
3014  }
3015  }
3016 
3017  _session_is_new = false;
3018 
3019  } else {
3020 
3021  if (!likely_new) {
3022  pop_back_splash (session_dialog);
3023  MessageDialog msg (string_compose (_("There is no existing session at \"%1\""), session_path));
3024  msg.run ();
3025  ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
3026  continue;
3027  }
3028 
3029  char illegal = Session::session_name_is_legal(session_name);
3030 
3031  if (illegal) {
3032  pop_back_splash (session_dialog);
3033  MessageDialog msg (session_dialog, string_compose(_("To ensure compatibility with various systems\n"
3034  "session names may not contain a '%1' character"), illegal));
3035  msg.run ();
3036  ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
3037  continue;
3038  }
3039 
3040  _session_is_new = true;
3041  }
3042 
3043  if (likely_new && template_name.empty()) {
3044 
3045  ret = build_session_from_dialog (session_dialog, session_path, session_name);
3046 
3047  } else {
3048 
3049  ret = load_session (session_path, session_name, template_name);
3050 
3051  if (ret == -2) {
3052  /* not connected to the AudioEngine, so quit to avoid an infinite loop */
3053  exit (1);
3054  }
3055 
3056  if (!ARDOUR_COMMAND_LINE::immediate_save.empty()) {
3058  exit (1);
3059  }
3060 
3061  /* clear this to avoid endless attempts to load the
3062  same session.
3063  */
3064 
3066  }
3067  }
3068 
3069  return ret;
3070 }
3071 
3072 void
3074 {
3075  if (!check_audioengine()) {
3076  return;
3077  }
3078 
3079  if (unload_session (true)) {
3080  return;
3081  }
3082 
3084 
3085  if (get_session_parameters (true, false)) {
3086  exit (1);
3087  }
3088 
3089  goto_editor_window ();
3090 }
3091 
3095 int
3096 ARDOUR_UI::load_session (const std::string& path, const std::string& snap_name, std::string mix_template)
3097 {
3099  int unload_status;
3100  int retval = -1;
3101 
3102  if (_session) {
3103  unload_status = unload_session ();
3104 
3105  if (unload_status < 0) {
3106  goto out;
3107  } else if (unload_status > 0) {
3108  retval = 0;
3109  goto out;
3110  }
3111  }
3112 
3113  session_loaded = false;
3114 
3115  loading_message (string_compose (_("Please wait while %1 loads your session"), PROGRAM_NAME));
3116 
3117  try {
3118  new_session = new Session (*AudioEngine::instance(), path, snap_name, 0, mix_template);
3119  }
3120 
3121  /* this one is special */
3122 
3123  catch (AudioEngine::PortRegistrationFailure& err) {
3124 
3125  MessageDialog msg (err.what(),
3126  true,
3127  Gtk::MESSAGE_INFO,
3128  Gtk::BUTTONS_CLOSE);
3129 
3130  msg.set_title (_("Port Registration Error"));
3131  msg.set_secondary_text (_("Click the Close button to try again."));
3132  msg.set_position (Gtk::WIN_POS_CENTER);
3133  pop_back_splash (msg);
3134  msg.present ();
3135 
3136  int response = msg.run ();
3137 
3138  msg.hide ();
3139 
3140  switch (response) {
3141  case RESPONSE_CANCEL:
3142  exit (1);
3143  default:
3144  break;
3145  }
3146  goto out;
3147  }
3148 
3149  catch (...) {
3150 
3151  MessageDialog msg (string_compose(
3152  _("Session \"%1 (snapshot %2)\" did not load successfully"),
3153  path, snap_name),
3154  true,
3155  Gtk::MESSAGE_INFO,
3156  BUTTONS_OK);
3157 
3158  msg.set_title (_("Loading Error"));
3159  msg.set_position (Gtk::WIN_POS_CENTER);
3160  pop_back_splash (msg);
3161  msg.present ();
3162  (void) msg.run ();
3163  msg.hide ();
3164 
3165  goto out;
3166  }
3167 
3168  {
3169  list<string> const u = new_session->unknown_processors ();
3170  if (!u.empty()) {
3172  d.run ();
3173  }
3174  }
3175 
3176  if (!new_session->writable()) {
3177  MessageDialog msg (_("This session has been opened in read-only mode.\n\nYou will not be able to record or save."),
3178  true,
3179  Gtk::MESSAGE_INFO,
3180  BUTTONS_OK);
3181 
3182  msg.set_title (_("Read-only Session"));
3183  msg.set_position (Gtk::WIN_POS_CENTER);
3184  pop_back_splash (msg);
3185  msg.present ();
3186  (void) msg.run ();
3187  msg.hide ();
3188  }
3189 
3190 
3191  /* Now the session been created, add the transport controls */
3192  new_session->add_controllable(roll_controllable);
3193  new_session->add_controllable(stop_controllable);
3198  new_session->add_controllable(rec_controllable);
3199 
3200  set_session (new_session);
3201 
3202  session_loaded = true;
3203 
3204  goto_editor_window ();
3205 
3206  if (_session) {
3207  _session->set_clean ();
3208  }
3209 
3210 #ifdef WINDOWS_VST_SUPPORT
3211  fst_stop_threading();
3212 #endif
3213 
3214  flush_pending ();
3215 
3216 #ifdef WINDOWS_VST_SUPPORT
3217  fst_start_threading();
3218 #endif
3219  retval = 0;
3220 
3221  out:
3222  return retval;
3223 }
3224 
3225 int
3226 ARDOUR_UI::build_session (const std::string& path, const std::string& snap_name, BusProfile& bus_profile)
3227 {
3229  int x;
3230 
3231  session_loaded = false;
3232  x = unload_session ();
3233 
3234  if (x < 0) {
3235  return -1;
3236  } else if (x > 0) {
3237  return 0;
3238  }
3239 
3240  _session_is_new = true;
3241 
3242  try {
3243  new_session = new Session (*AudioEngine::instance(), path, snap_name, &bus_profile);
3244  }
3245 
3246  catch (...) {
3247 
3248  MessageDialog msg (string_compose(_("Could not create session in \"%1\""), path));
3249  pop_back_splash (msg);
3250  msg.run ();
3251  return -1;
3252  }
3253 
3254  /* Give the new session the default GUI state, if such things exist */
3255 
3256  XMLNode* n;
3257  n = Config->instant_xml (X_("Editor"));
3258  if (n) {
3259  n->remove_nodes_and_delete ("Selection"); // no not apply selection to new sessions.
3260  new_session->add_instant_xml (*n, false);
3261  }
3262  n = Config->instant_xml (X_("Mixer"));
3263  if (n) {
3264  new_session->add_instant_xml (*n, false);
3265  }
3266 
3267  /* Put the playhead at 0 and scroll fully left */
3268  n = new_session->instant_xml (X_("Editor"));
3269  if (n) {
3270  n->add_property (X_("playhead"), X_("0"));
3271  n->add_property (X_("left-frame"), X_("0"));
3272  }
3273 
3274  set_session (new_session);
3275 
3276  session_loaded = true;
3277 
3278  new_session->save_state(new_session->name());
3279 
3280  return 0;
3281 }
3282 
3283 void
3285 {
3286 #ifdef __APPLE__
3287  open_uri("http://webchat.freenode.net/?channels=ardour-osx");
3288 #elif defined PLATFORM_WINDOWS
3289  open_uri("http://webchat.freenode.net/?channels=ardour-windows");
3290 #else
3291  open_uri("http://webchat.freenode.net/?channels=ardour");
3292 #endif
3293 }
3294 
3295 void
3297 {
3298  PBD::open_uri (Config->get_tutorial_manual_url());
3299 }
3300 
3301 void
3303 {
3304  PBD::open_uri (Config->get_reference_manual_url());
3305 }
3306 
3307 void
3309 {
3310  PBD::open_uri ("http://tracker.ardour.org/bug_report_page.php");
3311 }
3312 
3313 void
3315 {
3316  PBD::open_uri ("https://community.ardour.org/s/subscribe");
3317 }
3318 
3319 void
3321 {
3322 #ifdef __APPLE__
3323  PBD::open_uri ("http://manual.ardour.org/files/a3_mnemonic_cheat_sheet_osx.pdf");
3324 #else
3325  PBD::open_uri ("http://manual.ardour.org/files/a3_mnemonic_cheatsheet.pdf");
3326 #endif
3327 }
3328 
3329 void
3331 {
3332  PBD::open_uri ("http://ardour.org");
3333 }
3334 
3335 void
3337 {
3338  PBD::open_uri ("http://ardour.org/development.html");
3339 }
3340 
3341 void
3343 {
3344  PBD::open_uri ("https://community.ardour.org/forums");
3345 }
3346 
3347 void
3349 {
3350  PBD::open_uri ("http://ardour.org/reporting_bugs");
3351 }
3352 
3353 void
3354 ARDOUR_UI::loading_message (const std::string& msg)
3355 {
3357  return;
3358  }
3359 
3360  if (!splash) {
3361  show_splash ();
3362  }
3363 
3364  splash->message (msg);
3365 }
3366 
3367 void
3369 {
3370  if (splash == 0) {
3371  try {
3372  splash = new Splash;
3373  } catch (...) {
3374  return;
3375  }
3376  }
3377 
3378  splash->display ();
3379 }
3380 
3381 void
3383 {
3384  delete splash;
3385  splash = 0;
3386 }
3387 
3388 void
3389 ARDOUR_UI::display_cleanup_results (ARDOUR::CleanupReport& rep, const gchar* list_title, const bool msg_delete)
3390 {
3391  size_t removed;
3392 
3393  removed = rep.paths.size();
3394 
3395  if (removed == 0) {
3396  MessageDialog msgd (*editor,
3397  _("No files were ready for clean-up"),
3398  true,
3399  Gtk::MESSAGE_INFO,
3400  Gtk::BUTTONS_OK);
3401  msgd.set_title (_("Clean-up"));
3402  msgd.set_secondary_text (_("If this seems suprising, \n\
3403 check for any existing snapshots.\n\
3404 These may still include regions that\n\
3405 require some unused files to continue to exist."));
3406 
3407  msgd.run ();
3408  return;
3409  }
3410 
3411  ArdourDialog results (_("Clean-up"), true, false);
3412 
3413  struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
3414  CleanupResultsModelColumns() {
3415  add (visible_name);
3416  add (fullpath);
3417  }
3418  Gtk::TreeModelColumn<std::string> visible_name;
3419  Gtk::TreeModelColumn<std::string> fullpath;
3420  };
3421 
3422 
3423  CleanupResultsModelColumns results_columns;
3424  Glib::RefPtr<Gtk::ListStore> results_model;
3425  Gtk::TreeView results_display;
3426 
3427  results_model = ListStore::create (results_columns);
3428  results_display.set_model (results_model);
3429  results_display.append_column (list_title, results_columns.visible_name);
3430 
3431  results_display.set_name ("CleanupResultsList");
3432  results_display.set_headers_visible (true);
3433  results_display.set_headers_clickable (false);
3434  results_display.set_reorderable (false);
3435 
3436  Gtk::ScrolledWindow list_scroller;
3437  Gtk::Label txt;
3438  Gtk::VBox dvbox;
3439  Gtk::HBox dhbox; // the hbox for the image and text
3440  Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
3441  Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO, Gtk::ICON_SIZE_DIALOG));
3442 
3443  dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
3444 
3445  const string dead_directory = _session->session_directory().dead_path();
3446 
3447  /* subst:
3448  %1 - number of files removed
3449  %2 - location of "dead"
3450  %3 - size of files affected
3451  %4 - prefix for "bytes" to produce sensible results (e.g. mega, kilo, giga)
3452  */
3453 
3454  const char* bprefix;
3455  double space_adjusted = 0;
3456 
3457  if (rep.space < 1000) {
3458  bprefix = X_("");
3459  space_adjusted = rep.space;
3460  } else if (rep.space < 1000000) {
3461  bprefix = _("kilo");
3462  space_adjusted = floorf((float)rep.space / 1000.0);
3463  } else if (rep.space < 1000000 * 1000) {
3464  bprefix = _("mega");
3465  space_adjusted = floorf((float)rep.space / (1000.0 * 1000.0));
3466  } else {
3467  bprefix = _("giga");
3468  space_adjusted = floorf((float)rep.space / (1000.0 * 1000 * 1000.0));
3469  }
3470 
3471  if (msg_delete) {
3472  txt.set_markup (string_compose (P_("\
3473 The following file was deleted from %2,\n\
3474 releasing %3 %4bytes of disk space", "\
3475 The following %1 files were deleted from %2,\n\
3476 releasing %3 %4bytes of disk space", removed),
3477  removed, Glib::Markup::escape_text (dead_directory), space_adjusted, bprefix, PROGRAM_NAME));
3478  } else {
3479  txt.set_markup (string_compose (P_("\
3480 The following file was not in use and \n\
3481 has been moved to: %2\n\n\
3482 After a restart of %5\n\n\
3483 <span face=\"mono\">Session -> Clean-up -> Flush Wastebasket</span>\n\n\
3484 will release an additional %3 %4bytes of disk space.\n", "\
3485 The following %1 files were not in use and \n\
3486 have been moved to: %2\n\n\
3487 After a restart of %5\n\n\
3488 <span face=\"mono\">Session -> Clean-up -> Flush Wastebasket</span>\n\n\
3489 will release an additional %3 %4bytes of disk space.\n", removed),
3490  removed, Glib::Markup::escape_text (dead_directory), space_adjusted, bprefix, PROGRAM_NAME));
3491  }
3492 
3493  dhbox.pack_start (*dimage, true, false, 5);
3494  dhbox.pack_start (txt, true, false, 5);
3495 
3496  for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
3497  TreeModel::Row row = *(results_model->append());
3498  row[results_columns.visible_name] = *i;
3499  row[results_columns.fullpath] = *i;
3500  }
3501 
3502  list_scroller.add (results_display);
3503  list_scroller.set_size_request (-1, 150);
3504  list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
3505 
3506  dvbox.pack_start (dhbox, true, false, 5);
3507  dvbox.pack_start (list_scroller, true, false, 5);
3508  ddhbox.pack_start (dvbox, true, false, 5);
3509 
3510  results.get_vbox()->pack_start (ddhbox, true, false, 5);
3511  results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
3512  results.set_default_response (RESPONSE_CLOSE);
3513  results.set_position (Gtk::WIN_POS_MOUSE);
3514 
3515  results_display.show();
3516  list_scroller.show();
3517  txt.show();
3518  dvbox.show();
3519  dhbox.show();
3520  ddhbox.show();
3521  dimage->show();
3522 
3523  //results.get_vbox()->show();
3524  results.set_resizable (false);
3525 
3526  results.run ();
3527 
3528 }
3529 
3530 void
3532 {
3533  if (_session == 0) {
3534  /* shouldn't happen: menu item is insensitive */
3535  return;
3536  }
3537 
3538 
3539  MessageDialog checker (_("Are you sure you want to clean-up?"),
3540  true,
3541  Gtk::MESSAGE_QUESTION,
3542  Gtk::BUTTONS_NONE);
3543 
3544  checker.set_title (_("Clean-up"));
3545 
3546  checker.set_secondary_text(_("Clean-up is a destructive operation.\n\
3547 ALL undo/redo information will be lost if you clean-up.\n\
3548 Clean-up will move all unused files to a \"dead\" location."));
3549 
3550  checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
3551  checker.add_button (_("Clean-up"), RESPONSE_ACCEPT);
3552  checker.set_default_response (RESPONSE_CANCEL);
3553 
3554  checker.set_name (_("CleanupDialog"));
3555  checker.set_wmclass (X_("ardour_cleanup"), PROGRAM_NAME);
3556  checker.set_position (Gtk::WIN_POS_MOUSE);
3557 
3558  switch (checker.run()) {
3559  case RESPONSE_ACCEPT:
3560  break;
3561  default:
3562  return;
3563  }
3564 
3566 
3568 
3569  /* do not allow flush until a session is reloaded */
3570 
3571  Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
3572  if (act) {
3573  act->set_sensitive (false);
3574  }
3575 
3576  if (_session->cleanup_sources (rep)) {
3577  editor->finish_cleanup ();
3578  return;
3579  }
3580 
3581  editor->finish_cleanup ();
3582 
3583  checker.hide();
3584  display_cleanup_results (rep, _("Cleaned Files"), false);
3585 }
3586 
3587 void
3589 {
3590  if (_session == 0) {
3591  /* shouldn't happen: menu item is insensitive */
3592  return;
3593  }
3594 
3596 
3597  if (_session->cleanup_trash_sources (rep)) {
3598  return;
3599  }
3600 
3601  display_cleanup_results (rep, _("deleted file"), true);
3602 }
3603 
3604 void
3606 {
3607  uint32_t order_hint = UINT32_MAX;
3608 
3609  if (editor->get_selection().tracks.empty()) {
3610  return;
3611  }
3612 
3613  /*
3614  we want the new routes to have their order keys set starting from
3615  the highest order key in the selection + 1 (if available).
3616  */
3617 
3618  if (place == AddRouteDialog::AfterSelection) {
3619  RouteTimeAxisView *rtav = dynamic_cast<RouteTimeAxisView*> (editor->get_selection().tracks.back());
3620  if (rtav) {
3621  order_hint = rtav->route()->order_key();
3622  order_hint++;
3623  }
3624  } else if (place == AddRouteDialog::BeforeSelection) {
3625  RouteTimeAxisView *rtav = dynamic_cast<RouteTimeAxisView*> (editor->get_selection().tracks.front());
3626  if (rtav) {
3627  order_hint = rtav->route()->order_key();
3628  }
3629  } else if (place == AddRouteDialog::First) {
3630  order_hint = 0;
3631  } else {
3632  /* leave order_hint at UINT32_MAX */
3633  }
3634 
3635  if (order_hint == UINT32_MAX) {
3639  return;
3640  }
3641 
3642  _session->set_order_hint (order_hint);
3643 
3644  /* create a gap in the existing route order keys to accomodate new routes.*/
3646  for (RouteList::iterator ri = rd->begin(); ri != rd->end(); ++ri) {
3647  boost::shared_ptr<Route> rt (*ri);
3648 
3649  if (rt->is_monitor()) {
3650  continue;
3651  }
3652 
3653  if (rt->order_key () >= order_hint) {
3654  rt->set_order_key (rt->order_key () + add_route_dialog->count());
3655  }
3656  }
3657 }
3658 
3659 void
3660 ARDOUR_UI::add_route (Gtk::Window* /* ignored */)
3661 {
3662  int count;
3663 
3664  if (!_session) {
3665  return;
3666  }
3667 
3668  if (add_route_dialog->is_visible()) {
3669  /* we're already doing this */
3670  return;
3671  }
3672 
3673  ResponseType r = (ResponseType) add_route_dialog->run ();
3674 
3675  add_route_dialog->hide();
3676 
3677  switch (r) {
3678  case RESPONSE_ACCEPT:
3679  break;
3680  default:
3681  return;
3682  break;
3683  }
3684 
3685  if ((count = add_route_dialog->count()) <= 0) {
3686  return;
3687  }
3688 
3690 
3691  string template_path = add_route_dialog->track_template();
3692  DisplaySuspender ds;
3693 
3694  if (!template_path.empty()) {
3696  _session->new_route_from_template (count, template_path, string());
3697  } else {
3698  _session->new_route_from_template (count, template_path, add_route_dialog->name_template());
3699  }
3700  return;
3701  }
3702 
3703  ChanCount input_chan= add_route_dialog->channels ();
3704  ChanCount output_chan;
3705  string name_template = add_route_dialog->name_template ();
3707  RouteGroup* route_group = add_route_dialog->route_group ();
3708  AutoConnectOption oac = Config->get_output_auto_connect();
3709 
3710  if (oac & AutoConnectMaster) {
3711  output_chan.set (DataType::AUDIO, (_session->master_out() ? _session->master_out()->n_inputs().n_audio() : input_chan.n_audio()));
3712  output_chan.set (DataType::MIDI, 0);
3713  } else {
3714  output_chan = input_chan;
3715  }
3716 
3717  /* XXX do something with name template */
3718 
3719  switch (add_route_dialog->type_wanted()) {
3721  session_add_audio_track (input_chan.n_audio(), output_chan.n_audio(), add_route_dialog->mode(), route_group, count, name_template);
3722  break;
3724  session_add_midi_track (route_group, count, name_template, instrument);
3725  break;
3727  session_add_mixed_track (input_chan, output_chan, route_group, count, name_template, instrument);
3728  break;
3730  session_add_audio_bus (input_chan.n_audio(), output_chan.n_audio(), route_group, count, name_template);
3731  break;
3732  }
3733 }
3734 
3735 void
3737 {
3738  if (!video_server_process && ask_confirm) {
3739  warning << string_compose (_("Video-Server was not launched by %1. The request to stop it is ignored."), PROGRAM_NAME) << endmsg;
3740  }
3741  if (video_server_process) {
3742  if(ask_confirm) {
3743  ArdourDialog confirm (_("Stop Video-Server"), true);
3744  Label m (_("Do you really want to stop the Video Server?"));
3745  confirm.get_vbox()->pack_start (m, true, true);
3746  confirm.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
3747  confirm.add_button (_("Yes, Stop It"), Gtk::RESPONSE_ACCEPT);
3748  confirm.show_all ();
3749  if (confirm.run() == RESPONSE_CANCEL) {
3750  return;
3751  }
3752  }
3753  delete video_server_process;
3755  }
3756 }
3757 
3758 void
3759 ARDOUR_UI::start_video_server_menu (Gtk::Window* float_window)
3760 {
3761  ARDOUR_UI::start_video_server( float_window, true);
3762 }
3763 
3764 bool
3765 ARDOUR_UI::start_video_server (Gtk::Window* float_window, bool popup_msg)
3766 {
3767  if (!_session) {
3768  return false;
3769  }
3770  if (popup_msg) {
3772  if (video_server_process) {
3773  popup_error(_("The Video Server is already started."));
3774  } else {
3775  popup_error(_("An external Video Server is configured and can be reached. Not starting a new instance."));
3776  }
3777  }
3778  }
3779 
3780  int firsttime = 0;
3782  if (firsttime++) {
3783  warning << _("Could not connect to the Video Server. Start it or configure its access URL in Preferences.") << endmsg;
3784  }
3785  VideoServerDialog *video_server_dialog = new VideoServerDialog (_session);
3786  if (float_window) {
3787  video_server_dialog->set_transient_for (*float_window);
3788  }
3789 
3790  if (!Config->get_show_video_server_dialog() && firsttime < 2) {
3791  video_server_dialog->hide();
3792  } else {
3793  ResponseType r = (ResponseType) video_server_dialog->run ();
3794  video_server_dialog->hide();
3795  if (r != RESPONSE_ACCEPT) { return false; }
3796  if (video_server_dialog->show_again()) {
3797  Config->set_show_video_server_dialog(false);
3798  }
3799  }
3800 
3801  std::string icsd_exec = video_server_dialog->get_exec_path();
3802  std::string icsd_docroot = video_server_dialog->get_docroot();
3803  if (icsd_docroot.empty()) {
3804 #ifndef PLATFORM_WINDOWS
3805  icsd_docroot = X_("/");
3806 #else
3807  icsd_docroot = X_("C:\\");
3808 #endif
3809  }
3810 
3811  GStatBuf sb;
3812  if (g_lstat (icsd_docroot.c_str(), &sb) != 0 || !S_ISDIR(sb.st_mode)) {
3813  warning << _("Specified docroot is not an existing directory.") << endmsg;
3814  continue;
3815  }
3816 #ifndef PLATFORM_WINDOWS
3817  if ( (g_lstat (icsd_exec.c_str(), &sb) != 0)
3818  || (sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == 0 ) {
3819  warning << _("Given Video Server is not an executable file.") << endmsg;
3820  continue;
3821  }
3822 #else
3823  if ( (g_lstat (icsd_exec.c_str(), &sb) != 0)
3824  || (sb.st_mode & (S_IXUSR)) == 0 ) {
3825  warning << _("Given Video Server is not an executable file.") << endmsg;
3826  continue;
3827  }
3828 #endif
3829 
3830  char **argp;
3831  argp=(char**) calloc(9,sizeof(char*));
3832  argp[0] = strdup(icsd_exec.c_str());
3833  argp[1] = strdup("-P");
3834  argp[2] = (char*) calloc(16,sizeof(char)); snprintf(argp[2], 16, "%s", video_server_dialog->get_listenaddr().c_str());
3835  argp[3] = strdup("-p");
3836  argp[4] = (char*) calloc(6,sizeof(char)); snprintf(argp[4], 6, "%i", video_server_dialog->get_listenport());
3837  argp[5] = strdup("-C");
3838  argp[6] = (char*) calloc(6,sizeof(char)); snprintf(argp[6], 6, "%i", video_server_dialog->get_cachesize());
3839  argp[7] = strdup(icsd_docroot.c_str());
3840  argp[8] = 0;
3842 
3843  if (icsd_docroot == X_("/") || icsd_docroot == X_("C:\\")) {
3844  Config->set_video_advanced_setup(false);
3845  } else {
3846  std::ostringstream osstream;
3847  osstream << "http://localhost:" << video_server_dialog->get_listenport() << "/";
3848  Config->set_video_server_url(osstream.str());
3849  Config->set_video_server_docroot(icsd_docroot);
3850  Config->set_video_advanced_setup(true);
3851  }
3852 
3853  if (video_server_process) {
3854  delete video_server_process;
3855  }
3856 
3857  video_server_process = new ARDOUR::SystemExec(icsd_exec, argp);
3858  if (video_server_process->start()) {
3859  warning << _("Cannot launch the video-server") << endmsg;
3860  continue;
3861  }
3862  int timeout = 120; // 6 sec
3864  Glib::usleep (50000);
3865  gui_idle_handler();
3866  if (--timeout <= 0 || !video_server_process->is_running()) break;
3867  }
3868  if (timeout <= 0) {
3869  warning << _("Video-server was started but does not respond to requests...") << endmsg;
3870  } else {
3872  delete video_server_process;
3874  }
3875  }
3876  }
3877  return true;
3878 }
3879 
3880 void
3881 ARDOUR_UI::add_video (Gtk::Window* float_window)
3882 {
3883  if (!_session) {
3884  return;
3885  }
3886 
3887  if (!start_video_server(float_window, false)) {
3888  warning << _("Could not connect to the Video Server. Start it or configure its access URL in Preferences.") << endmsg;
3889  return;
3890  }
3891 
3892  if (float_window) {
3893  add_video_dialog->set_transient_for (*float_window);
3894  }
3895 
3896  if (add_video_dialog->is_visible()) {
3897  /* we're already doing this */
3898  return;
3899  }
3900 
3901  ResponseType r = (ResponseType) add_video_dialog->run ();
3902  add_video_dialog->hide();
3903  if (r != RESPONSE_ACCEPT) { return; }
3904 
3905  bool local_file, orig_local_file;
3906  std::string path = add_video_dialog->file_name(local_file);
3907 
3908  std::string orig_path = path;
3909  orig_local_file = local_file;
3910 
3911  bool auto_set_session_fps = add_video_dialog->auto_set_session_fps();
3912 
3913  if (local_file && !Glib::file_test(path, Glib::FILE_TEST_EXISTS)) {
3914  warning << string_compose(_("could not open %1"), path) << endmsg;
3915  return;
3916  }
3917  if (!local_file && path.length() == 0) {
3918  warning << _("no video-file selected") << endmsg;
3919  return;
3920  }
3921 
3922  switch (add_video_dialog->import_option()) {
3923  case VTL_IMPORT_TRANSCODE:
3924  {
3925  TranscodeVideoDialog *transcode_video_dialog;
3926  transcode_video_dialog = new TranscodeVideoDialog (_session, path);
3927  ResponseType r = (ResponseType) transcode_video_dialog->run ();
3928  transcode_video_dialog->hide();
3929  if (r != RESPONSE_ACCEPT) {
3930  delete transcode_video_dialog;
3931  return;
3932  }
3933  if (!transcode_video_dialog->get_audiofile().empty()) {
3935  transcode_video_dialog->get_audiofile(),
3937  (transcode_video_dialog->import_option() != VTL_IMPORT_NO_VIDEO)
3938  );
3939  }
3940  switch (transcode_video_dialog->import_option()) {
3941  case VTL_IMPORT_TRANSCODED:
3942  path = transcode_video_dialog->get_filename();
3943  local_file = true;
3944  break;
3945  case VTL_IMPORT_REFERENCE:
3946  break;
3947  default:
3948  delete transcode_video_dialog;
3949  return;
3950  }
3951  delete transcode_video_dialog;
3952  }
3953  break;
3954  default:
3955  case VTL_IMPORT_NONE:
3956  break;
3957  }
3958 
3959  /* strip _session->session_directory().video_path() from video file if possible */
3960  if (local_file && !path.compare(0, _session->session_directory().video_path().size(), _session->session_directory().video_path())) {
3961  path=path.substr(_session->session_directory().video_path().size());
3962  if (path.at(0) == G_DIR_SEPARATOR) {
3963  path=path.substr(1);
3964  }
3965  }
3966 
3967  video_timeline->set_update_session_fps(auto_set_session_fps);
3968  if (video_timeline->video_file_info(path, local_file)) {
3969  XMLNode* node = new XMLNode(X_("Videotimeline"));
3970  node->add_property (X_("Filename"), path);
3971  node->add_property (X_("AutoFPS"), auto_set_session_fps?X_("1"):X_("0"));
3972  node->add_property (X_("LocalFile"), local_file?X_("1"):X_("0"));
3973  if (orig_local_file) {
3974  node->add_property (X_("OriginalVideoFile"), orig_path);
3975  } else {
3976  node->remove_property (X_("OriginalVideoFile"));
3977  }
3978  _session->add_extra_xml (*node);
3979  _session->set_dirty ();
3980 
3984 
3985 
3986  if (add_video_dialog->launch_xjadeo() && local_file) {
3989  } else {
3991  }
3992  editor->toggle_ruler_video(true);
3993  }
3994 }
3995 
3996 void
3998 {
4000  editor->toggle_ruler_video(false);
4001 
4002  /* reset state */
4005 
4006  /* delete session state */
4007  XMLNode* node = new XMLNode(X_("Videotimeline"));
4008  _session->add_extra_xml(*node);
4009  node = new XMLNode(X_("Videomonitor"));
4010  _session->add_extra_xml(*node);
4011  node = new XMLNode(X_("Videoexport"));
4012  _session->add_extra_xml(*node);
4014 }
4015 
4016 void
4018 {
4019  if (localcacheonly) {
4021  } else {
4023  }
4025 }
4026 
4027 void
4029 {
4030  if (ARDOUR::Config->get_show_video_export_info()) {
4031  ExportVideoInfobox infobox (_session);
4032  Gtk::ResponseType rv = (Gtk::ResponseType) infobox.run();
4033  if (infobox.show_again()) {
4034  ARDOUR::Config->set_show_video_export_info(false);
4035  }
4036  switch (rv) {
4037  case GTK_RESPONSE_YES:
4038  PBD::open_uri (ARDOUR::Config->get_reference_manual_url() + "/video-timeline/operations/#export");
4039  break;
4040  default:
4041  break;
4042  }
4043  }
4046  export_video_dialog->run ();
4047  export_video_dialog->hide ();
4048 }
4049 
4050 XMLNode*
4052 {
4053  XMLNode* node = 0;
4054 
4055  if (_session) {
4056  node = _session->instant_xml(X_("Mixer"));
4057  } else {
4058  node = Config->instant_xml(X_("Mixer"));
4059  }
4060 
4061  if (!node) {
4062  node = new XMLNode (X_("Mixer"));
4063  }
4064 
4065  return node;
4066 }
4067 
4068 XMLNode*
4070 {
4071  XMLNode* node = 0;
4072 
4073  if (_session) {
4074  node = _session->instant_xml(X_("Editor"));
4075  } else {
4076  node = Config->instant_xml(X_("Editor"));
4077  }
4078 
4079  if (!node) {
4080  if (getenv("ARDOUR_INSTANT_XML_PATH")) {
4081  node = Config->instant_xml(getenv("ARDOUR_INSTANT_XML_PATH"));
4082  }
4083  }
4084 
4085  if (!node) {
4086  node = new XMLNode (X_("Editor"));
4087  }
4088 
4089  return node;
4090 }
4091 
4092 XMLNode*
4094 {
4095  XMLNode* node = 0;
4096 
4097  node = Config->extra_xml(X_("Keyboard"));
4098 
4099  if (!node) {
4100  node = new XMLNode (X_("Keyboard"));
4101  }
4102 
4103  return node;
4104 }
4105 
4106 void
4108 {
4109  if (_session) {
4110  Location *location = new Location (*_session, where, where, _("xrun"), Location::IsMark);
4111  _session->locations()->add (location);
4112  }
4113 }
4114 
4115 void
4117 {
4118  cerr << "HALT on xrun\n";
4119  MessageDialog msg (*editor, _("Recording was stopped because your system could not keep up."));
4120  msg.run ();
4121 }
4122 
4123 void
4125 {
4126  if (!_session) {
4127  return;
4128  }
4129 
4131 
4132  if (_session && Config->get_create_xrun_marker() && _session->actively_recording()) {
4133  create_xrun_marker(where);
4134  }
4135 
4136  if (_session && Config->get_stop_recording_on_xrun() && _session->actively_recording()) {
4138  }
4139 }
4140 
4141 void
4143 {
4145 
4148  MessageDialog* msg = new MessageDialog (*editor, string_compose (_("\
4149 The disk system on your computer\n\
4150 was not able to keep up with %1.\n\
4151 \n\
4152 Specifically, it failed to write data to disk\n\
4153 quickly enough to keep up with recording.\n"), PROGRAM_NAME));
4154  msg->signal_response().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
4155  msg->show ();
4156  }
4157 }
4158 
4159 
4160 /* TODO: this is getting elaborate enough to warrant being split into a dedicated class */
4161 static MessageDialog *scan_dlg = NULL;
4162 static ProgressBar *scan_pbar = NULL;
4163 static HBox *scan_tbox = NULL;
4164 
4165 void
4167 {
4168  PluginManager::instance().cancel_plugin_scan();
4169 }
4170 
4171 void
4173 {
4174  PluginManager::instance().cancel_plugin_timeout();
4175  scan_tbox->hide();
4176 }
4177 
4178 void
4180 {
4181  if (!scan_dlg || !scan_dlg->is_mapped() || !scan_pbar) {
4182  return;
4183  }
4184  if (timeout > 0) {
4185  scan_pbar->set_fraction ((float) timeout / (float) Config->get_vst_scan_timeout());
4186  scan_tbox->show();
4187  } else {
4188  scan_tbox->hide();
4189  }
4190  gui_idle_handler();
4191 }
4192 
4193 void
4194 ARDOUR_UI::plugin_scan_dialog (std::string type, std::string plugin, bool can_cancel)
4195 {
4196  if (type == X_("closeme") && !(scan_dlg && scan_dlg->is_mapped())) {
4197  return;
4198  }
4199 
4200  const bool cancelled = PluginManager::instance().cancelled();
4201  if (type != X_("closeme") && !ui_config->get_show_plugin_scan_window()) {
4202  if (cancelled && scan_dlg->is_mapped()) {
4203  scan_dlg->hide();
4204  gui_idle_handler();
4205  return;
4206  }
4207  if (cancelled || !can_cancel) {
4208  return;
4209  }
4210  }
4211 
4212  static Gtk::Button *cancel_button;
4213  static Gtk::Button *timeout_button;
4214  if (!scan_dlg) {
4215  scan_dlg = new MessageDialog("", false, MESSAGE_INFO, BUTTONS_NONE); // TODO manage
4216  VBox* vbox = scan_dlg->get_vbox();
4217  vbox->set_size_request(400,-1);
4218  scan_dlg->set_title (_("Scanning for plugins"));
4219 
4220  cancel_button = manage(new Gtk::Button(_("Cancel plugin scan")));
4221  cancel_button->set_name ("EditorGTKButton");
4222  cancel_button->signal_clicked().connect ( mem_fun (*this, &ARDOUR_UI::cancel_plugin_scan) );
4223  cancel_button->show();
4224 
4225  scan_dlg->get_vbox()->pack_start ( *cancel_button, PACK_SHRINK);
4226 
4227  scan_tbox = manage( new HBox() );
4228 
4229  timeout_button = manage(new Gtk::Button(_("Stop Timeout")));
4230  timeout_button->set_name ("EditorGTKButton");
4231  timeout_button->signal_clicked().connect ( mem_fun (*this, &ARDOUR_UI::cancel_plugin_timeout) );
4232  timeout_button->show();
4233 
4234  scan_pbar = manage(new ProgressBar());
4235  scan_pbar->set_orientation(Gtk::PROGRESS_RIGHT_TO_LEFT);
4236  scan_pbar->set_text(_("Scan Timeout"));
4237  scan_pbar->show();
4238 
4239  scan_tbox->pack_start (*scan_pbar, PACK_EXPAND_WIDGET, 4);
4240  scan_tbox->pack_start (*timeout_button, PACK_SHRINK, 4);
4241 
4242  scan_dlg->get_vbox()->pack_start (*scan_tbox, PACK_SHRINK, 4);
4243  }
4244 
4245  assert(scan_dlg && scan_tbox && cancel_button);
4246 
4247  if (type == X_("closeme")) {
4248  scan_dlg->hide();
4249  } else {
4250  scan_dlg->set_message(type + ": " + Glib::path_get_basename(plugin));
4251  scan_dlg->show();
4252  }
4253  if (!can_cancel || !cancelled) {
4254  scan_tbox->hide();
4255  }
4256  cancel_button->set_sensitive(can_cancel && !cancelled);
4257 
4258  gui_idle_handler();
4259 }
4260 
4261 void
4263 {
4264  int timeout = 30;
4265  /* due to idle calls, gtk_events_pending() may always return true */
4266  while (gtk_events_pending() && --timeout) {
4267  gtk_main_iteration ();
4268  }
4269 }
4270 
4271 void
4273 {
4275 
4278  MessageDialog* msg = new MessageDialog (
4279  *editor, string_compose (_("The disk system on your computer\n\
4280 was not able to keep up with %1.\n\
4281 \n\
4282 Specifically, it failed to read data from disk\n\
4283 quickly enough to keep up with playback.\n"), PROGRAM_NAME));
4284  msg->signal_response().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
4285  msg->show ();
4286  }
4287 }
4288 
4289 void
4290 ARDOUR_UI::disk_speed_dialog_gone (int /*ignored_response*/, MessageDialog* msg)
4291 {
4293  delete msg;
4294 }
4295 
4296 void
4297 ARDOUR_UI::session_dialog (std::string msg)
4298 {
4300 
4301  MessageDialog* d;
4302 
4303  if (editor) {
4304  d = new MessageDialog (*editor, msg, false, MESSAGE_INFO, BUTTONS_OK, true);
4305  } else {
4306  d = new MessageDialog (msg, false, MESSAGE_INFO, BUTTONS_OK, true);
4307  }
4308 
4309  d->show_all ();
4310  d->run ();
4311  delete d;
4312 }
4313 
4314 int
4316 {
4317  HBox* hbox = manage (new HBox());
4318  Image* image = manage (new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG));
4319  ArdourDialog dialog (_("Crash Recovery"), true);
4320  Label message (string_compose (_("\
4321 This session appears to have been in the\n\
4322 middle of recording when %1 or\n\
4323 the computer was shutdown.\n\
4324 \n\
4325 %1 can recover any captured audio for\n\
4326 you, or it can ignore it. Please decide\n\
4327 what you would like to do.\n"), PROGRAM_NAME));
4328  image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
4329  hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
4330  hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
4331  dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
4332  dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
4333  dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
4334  dialog.set_default_response (RESPONSE_ACCEPT);
4335  dialog.set_position (WIN_POS_CENTER);
4336  message.show();
4337  image->show();
4338  hbox->show();
4339 
4340  switch (dialog.run ()) {
4341  case RESPONSE_ACCEPT:
4342  return 1;
4343  default:
4344  return 0;
4345  }
4346 }
4347 
4348 int
4350 {
4351  HBox* hbox = new HBox();
4352  Image* image = new Image (Stock::DIALOG_WARNING, ICON_SIZE_DIALOG);
4353  ArdourDialog dialog (_("Sample Rate Mismatch"), true);
4354  Label message (string_compose (_("\
4355 This session was created with a sample rate of %1 Hz, but\n\
4356 %2 is currently running at %3 Hz. If you load this session,\n\
4357 audio may be played at the wrong sample rate.\n"), desired, PROGRAM_NAME, actual));
4358 
4359  image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
4360  hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
4361  hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
4362  dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
4363  dialog.add_button (_("Do not load session"), RESPONSE_REJECT);
4364  dialog.add_button (_("Load session anyway"), RESPONSE_ACCEPT);
4365  dialog.set_default_response (RESPONSE_ACCEPT);
4366  dialog.set_position (WIN_POS_CENTER);
4367  message.show();
4368  image->show();
4369  hbox->show();
4370 
4371  switch (dialog.run()) {
4372  case RESPONSE_ACCEPT:
4373  return 0;
4374  default:
4375  break;
4376  }
4377 
4378  return 1;
4379 }
4380 
4381 int
4383 {
4384  /* drop connection to AudioEngine::Halted so that we don't act
4385  * as if the engine unexpectedly shut down
4386  */
4387 
4389 
4390  if (AudioEngine::instance()->stop ()) {
4391  MessageDialog msg (*editor, _("Could not disconnect from Audio/MIDI engine"));
4392  msg.run ();
4393  return -1;
4394  } else {
4395  AudioEngine::instance()->Halted.connect_same_thread (halt_connection, boost::bind (&ARDOUR_UI::engine_halted, this, _1, false));
4396  }
4397 
4398  update_sample_rate (0);
4399  return 0;
4400 }
4401 
4402 int
4404 {
4405  if (AudioEngine::instance()->start ()) {
4406  // TODO somehow make this the topmost window (above any dialogs currently visible)
4407  if (editor) {
4408  MessageDialog msg (*editor, _("Could not reconnect to the Audio/MIDI engine"));
4409  msg.run ();
4410  } else {
4411  MessageDialog msg (_("Could not reconnect to the Audio/MIDI engine"));
4412  msg.run ();
4413  }
4414  return -1;
4415  }
4416 
4417  update_sample_rate (0);
4418  return 0;
4419 }
4420 
4421 void
4423 {
4424  XMLNode* node = Config->extra_xml (X_("TransportControllables"));
4425  if (node) {
4427  }
4428 }
4429 
4430 void
4432 {
4433  if (ui_config->get_primary_clock_delta_edit_cursor()) {
4435  } else {
4436  primary_clock->set (pos);
4437  }
4438 
4439  if (ui_config->get_secondary_clock_delta_edit_cursor()) {
4441  } else {
4442  secondary_clock->set (pos);
4443  }
4444 
4445  if (big_clock_window) {
4446  big_clock->set (pos);
4447  }
4449 }
4450 
4451 void
4453 {
4454  // XXX should really store pre-step edit status of things
4455  // we make insensitive
4456 
4457  if (yn) {
4459  rec_button.set_sensitive (false);
4460  } else {
4462  rec_button.set_sensitive (true);
4463  }
4464 }
4465 
4466 void
4468 {
4470 
4471  if (!_session || !big_clock_window) {
4472  /* why bother - the clock isn't visible */
4473  return;
4474  }
4475 
4476  if (_session->record_status () == Session::Recording && _session->have_rec_enabled_track ()) {
4477  big_clock->set_active (true);
4478  } else {
4479  big_clock->set_active (false);
4480  }
4481 }
4482 
4483 bool
4485 {
4486  if (_session) {
4487  _session->allow_auto_play (true);
4488  }
4489 
4490  if (editor) {
4491  editor->first_idle();
4492  }
4493 
4494  Keyboard::set_can_save_keybindings (true);
4495  return false;
4496 }
4497 
4498 void
4500 {
4501  XMLNode* node = new XMLNode(X_("ClockModes"));
4502 
4503  for (vector<AudioClock*>::iterator x = AudioClock::clocks.begin(); x != AudioClock::clocks.end(); ++x) {
4504  XMLNode* child = new XMLNode (X_("Clock"));
4505 
4506  child->add_property (X_("name"), (*x)->name());
4507  child->add_property (X_("mode"), enum_2_string ((*x)->mode()));
4508  child->add_property (X_("on"), ((*x)->off() ? X_("no") : X_("yes")));
4509 
4510  node->add_child_nocopy (*child);
4511  }
4512 
4513  _session->add_extra_xml (*node);
4514  _session->set_dirty ();
4515 }
4516 
4518  : Controllable (name), ui (u), type(tp)
4519 {
4520 
4521 }
4522 
4523 void
4525 {
4526  if (val < 0.5) {
4527  /* do nothing: these are radio-style actions */
4528  return;
4529  }
4530 
4531  const char *action = 0;
4532 
4533  switch (type) {
4534  case Roll:
4535  action = X_("Roll");
4536  break;
4537  case Stop:
4538  action = X_("Stop");
4539  break;
4540  case GotoStart:
4541  action = X_("GotoStart");
4542  break;
4543  case GotoEnd:
4544  action = X_("GotoEnd");
4545  break;
4546  case AutoLoop:
4547  action = X_("Loop");
4548  break;
4549  case PlaySelection:
4550  action = X_("PlaySelection");
4551  break;
4552  case RecordEnable:
4553  action = X_("Record");
4554  break;
4555  default:
4556  break;
4557  }
4558 
4559  if (action == 0) {
4560  return;
4561  }
4562 
4563  Glib::RefPtr<Action> act = ActionManager::get_action ("Transport", action);
4564 
4565  if (act) {
4566  act->activate ();
4567  }
4568 }
4569 
4570 double
4572 {
4573  float val = 0.0;
4574 
4575  switch (type) {
4576  case Roll:
4577  break;
4578  case Stop:
4579  break;
4580  case GotoStart:
4581  break;
4582  case GotoEnd:
4583  break;
4584  case AutoLoop:
4585  break;
4586  case PlaySelection:
4587  break;
4588  case RecordEnable:
4589  break;
4590  default:
4591  break;
4592  }
4593 
4594  return val;
4595 }
4596 
4597 void
4599 {
4600  if (gdk_screen_width() < 1200 || getenv ("ARDOUR_NARROW_SCREEN")) {
4602  }
4603 
4604  if (g_getenv ("ARDOUR_SAE")) {
4605  Profile->set_sae ();
4607  }
4608 
4609  if (g_getenv ("TRX")) {
4610  Profile->set_trx ();
4611  }
4612 
4613  if (g_getenv ("MIXBUS")) {
4614  Profile->set_mixbus ();
4615  }
4616 }
4617 
4618 int
4619 ARDOUR_UI::missing_file (Session*s, std::string str, DataType type)
4620 {
4621  MissingFileDialog dialog (s, str, type);
4622 
4623  dialog.show ();
4624  dialog.present ();
4625 
4626  int result = dialog.run ();
4627  dialog.hide ();
4628 
4629  switch (result) {
4630  case RESPONSE_OK:
4631  break;
4632  default:
4633  return 1; // quit entire session load
4634  }
4635 
4636  result = dialog.get_action ();
4637 
4638  return result;
4639 }
4640 
4641 int
4642 ARDOUR_UI::ambiguous_file (std::string file, std::vector<std::string> hits)
4643 {
4644  AmbiguousFileDialog dialog (file, hits);
4645 
4646  dialog.show ();
4647  dialog.present ();
4648 
4649  dialog.run ();
4650  return dialog.get_which ();
4651 }
4652 
4654 void
4656 {
4658 }
4659 
4661 void
4663 {
4665 }
4666 
4667 void
4669 {
4670  _feedback_exists = true;
4671 }
4672 
4673 void
4675 {
4676  _feedback_exists = false;
4677 }
4678 
4679 void
4681 {
4682  if (_session) {
4683  _session->midi_panic();
4684  }
4685 }
4686 
4687 void
4688 ARDOUR_UI::session_format_mismatch (std::string xml_path, std::string backup_path)
4689 {
4690  const char* start_big = "<span size=\"x-large\" weight=\"bold\">";
4691  const char* end_big = "</span>";
4692  const char* start_mono = "<tt>";
4693  const char* end_mono = "</tt>";
4694 
4695  MessageDialog msg (string_compose (_("%4This is a session from an older version of %3%5\n\n"
4696  "%3 has copied the old session file\n\n%6%1%7\n\nto\n\n%6%2%7\n\n"
4697  "From now on, use the -2000 version with older versions of %3"),
4698  xml_path, backup_path, PROGRAM_NAME,
4699  start_big, end_big,
4700  start_mono, end_mono), true);
4701 
4702  msg.run ();
4703 }
4704 
4705 
4706 void
4708 {
4709  if (!_session || !_session->master_out() || !editor_meter) return;
4711  editor_meter_max_peak = -INFINITY;
4713 }
4714 
4715 void
4717 {
4718  if (!_session || !_session->master_out()) return;
4719  if (group == _session->master_out()->route_group()) {
4720  reset_peak_display ();
4721  }
4722 }
4723 
4724 void
4726 {
4727  if (!_session || !_session->master_out()) return;
4728  if (_session->master_out().get() == route) {
4729  reset_peak_display ();
4730  }
4731 }
4732 
4733 int
4734 ARDOUR_UI::do_audio_midi_setup (uint32_t desired_sample_rate)
4735 {
4736  audio_midi_setup->set_desired_sample_rate (desired_sample_rate);
4737  audio_midi_setup->set_position (WIN_POS_CENTER);
4738 
4739  switch (audio_midi_setup->run()) {
4740  case Gtk::RESPONSE_OK:
4741  return 0;
4742  case Gtk::RESPONSE_APPLY:
4743  return 0;
4744  default:
4745  return -1;
4746  }
4747 }
4748 
4749 
4750 gint
4752 {
4753  _numpad_locate_happening = false;
4754  if (_numpad_timeout_connection.connected() )
4755  _numpad_timeout_connection.disconnect();
4756  return 1;
4757 }
4758 
4759 void
4761 {
4762  _numpad_timeout_connection.disconnect();
4763 
4766  _numpad_locate_happening = false;
4767  } else {
4768  _pending_locate_num = 0;
4769  _numpad_locate_happening = true;
4770  _numpad_timeout_connection = Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::transport_numpad_timeout), 2*1000);
4771  }
4772 }
4773 
4774 void
4776 {
4777  if ( _numpad_locate_happening ) {
4779  } else {
4780  switch (num) {
4781  case 0: toggle_roll(false, false); break;
4782  case 1: transport_rewind(1); break;
4783  case 2: transport_forward(1); break;
4784  case 3: transport_record(true); break;
4785  case 4: toggle_session_auto_loop(); break;
4786  case 5: transport_record(false); toggle_session_auto_loop(); break;
4787  case 6: toggle_punch(); break;
4788  case 7: toggle_click(); break;
4789  case 8: toggle_auto_return(); break;
4790  case 9: toggle_follow_edits(); break;
4791  }
4792  }
4793 }
4794 
4795 void
4797 {
4798  CairoWidget::set_flat_buttons( config()->get_flat_buttons() );
4799 }
4800 
4801 void
4803 {
4804  MessageDialog msg (string_compose (_("This is a free/demo copy of %1. It has just switched to silent mode."), PROGRAM_NAME),
4805  true,
4806  Gtk::MESSAGE_WARNING,
4807  Gtk::BUTTONS_NONE,
4808  true);
4809 
4810  msg.set_title (string_compose (_("%1 is now silent"), PROGRAM_NAME));
4811 
4812  Gtk::Label pay_label (string_compose (_("Please consider paying for a copy of %1 - you can pay whatever you want."), PROGRAM_NAME));
4813  Gtk::Label subscribe_label (_("Better yet become a subscriber - subscriptions start at US$1 per month."));
4814  Gtk::Button pay_button (_("Pay for a copy (via the web)"));
4815  Gtk::Button subscribe_button (_("Become a subscriber (via the web)"));
4816  Gtk::HBox pay_button_box;
4817  Gtk::HBox subscribe_button_box;
4818 
4819  pay_button_box.pack_start (pay_button, true, false);
4820  subscribe_button_box.pack_start (subscribe_button, true, false);
4821 
4822  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 */
4823 
4824  pay_button.signal_clicked().connect (sigc::hide_return (sigc::bind (sigc::ptr_fun (openuri), (const char*) "https://ardour.org/download")));
4825  subscribe_button.signal_clicked().connect (sigc::hide_return (sigc::bind (sigc::ptr_fun (openuri), (const char*) "https://community.ardour.org/s/subscribe")));
4826 
4827  msg.get_vbox()->pack_start (pay_label);
4828  msg.get_vbox()->pack_start (pay_button_box);
4829  msg.get_vbox()->pack_start (subscribe_label);
4830  msg.get_vbox()->pack_start (subscribe_button_box);
4831 
4832  msg.get_vbox()->show_all ();
4833 
4834  msg.add_button (_("Remain silent"), Gtk::RESPONSE_CANCEL);
4835  msg.add_button (_("Save and quit"), Gtk::RESPONSE_NO);
4836  msg.add_button (_("Give me more time"), Gtk::RESPONSE_YES);
4837 
4838  int r = msg.run ();
4839 
4840  switch (r) {
4841  case Gtk::RESPONSE_YES:
4842  AudioEngine::instance()->reset_silence_countdown ();
4843  break;
4844 
4845  case Gtk::RESPONSE_NO:
4846  /* save and quit */
4847  save_state_canfail ("");
4848  exit (0);
4849  break;
4850 
4851  case Gtk::RESPONSE_CANCEL:
4852  default:
4853  /* don't reset, save session and exit */
4854  break;
4855  }
4856 }
static Splash * instance()
Definition: splash.h:39
void is_clean(void)
Definition: nsmclient.cc:116
static ARDOUR_UI * ui
Definition: main.cc:76
framepos_t audible_frame() const
Definition: session.cc:1760
bool transport_rolling() const
Definition: session.h:592
void set_order_key(uint32_t)
Definition: route.cc:336
double timecode_frames_per_second() const
Definition: session_time.cc:55
framepos_t current_time(framepos_t position=0) const
boost::shared_ptr< RouteList > get_tracks() const
Definition: session.cc:4981
void update_format()
Definition: ardour_ui.cc:1297
framecnt_t nominal_frame_rate() const
Definition: session.h:367
void set_record_enabled(bool yn, void *src)
Definition: track.cc:273
bool use_session_template()
ARDOUR::ChanCount channels()
unsigned int get_xrun_count() const
Definition: session.h:599
sigc::connection second_connection
Definition: ardour_ui.h:571
void goto_editor_window()
WM::ProxyWithConstructor< BundleManager > bundle_manager
Definition: ardour_ui.h:653
void check_memory_locking()
Definition: ardour_ui.cc:960
int pending_state_dialog()
Definition: ardour_ui.cc:4315
void update_transport_clocks(framepos_t pos)
Definition: ardour_ui.cc:4431
void secondary_clock_value_changed()
Definition: ardour_ui.cc:2668
void transport_roll()
Definition: ardour_ui.cc:2042
int reconnect_to_engine()
Definition: ardour_ui.cc:4403
void set_state(XMLNode const &)
void transport_forward(int option)
Definition: ardour_ui.cc:2243
ArdourKeyboard * keyboard
Definition: ardour_ui.h:672
RecentSessionModelColumns recent_session_columns
Definition: ardour_ui.h:517
void launch_reference()
Definition: ardour_ui.cc:3302
void announce(const char *appliction_name, const char *capabilities, const char *process_name)
Definition: nsmclient.cc:74
void launch_forums()
Definition: ardour_ui.cc:3342
void set_offset(ARDOUR::frameoffset_t offset)
void transport_rec_enable_blink(bool onoff)
Definition: ardour_ui.cc:2676
std::string name() const
Definition: base_ui.h:57
void set(framepos_t, bool force=false, ARDOUR::framecnt_t offset=0)
Definition: audio_clock.cc:956
int save_template(std::string template_name)
bool get_sae() const
Definition: profile.h:48
gint autosave_session()
Definition: ardour_ui.cc:708
Gtk::TreeModelColumn< std::string > visible_name
Definition: ardour_ui.h:512
ARDOUR::frameoffset_t get_offset()
dialog-box and controller for importing video-files
void build_session_selector()
Definition: ardour_ui.cc:1619
WM::ProxyWithConstructor< SessionOptionEditor > session_option_editor
Definition: ardour_ui.h:651
virtual void embed_audio_from_video(std::string, framepos_t n=0, bool lock_position_to_video=true)=0
const char * client_id(void)
Definition: nsmclient.h:64
SyncSource
Definition: types.h:498
ARDOUR_UI(int *argcp, char **argvp[], const char *localedir)
Definition: ardour_ui.cc:184
XMLNode * editor_settings() const
Definition: ardour_ui.cc:4069
void launch_website()
Definition: ardour_ui.cc:3330
Location * auto_loop_location() const
Definition: location.cc:1359
void create_xrun_marker(framepos_t)
Definition: ardour_ui.cc:4107
void launch_chat()
Definition: ardour_ui.cc:3284
const std::string & value() const
Definition: xml++.h:159
void set_small_screen()
Definition: profile.h:44
WM::Proxy< EngineControl > audio_midi_setup
Definition: ardour_ui.h:646
void xrun_handler(framepos_t)
Definition: ardour_ui.cc:4124
MainClock * primary_clock
Definition: ardour_ui.h:229
void message(const std::string &msg)
Definition: splash.cc:223
bool first_time_engine_run
Definition: ardour_ui.h:340
sigc::connection point_one_second_connection
Definition: ardour_ui.h:572
bool create_master_bus() const
double transport_speed() const
Definition: session.h:590
void post_engine()
Definition: ardour_ui.cc:491
int get_session_parameters(bool quit_on_cancel, bool should_be_new=false, std::string load_template="")
Definition: ardour_ui.cc:2841
void maybe_write_autosave()
bool include_media() const
void set_single_package()
Definition: profile.h:56
const std::string root_path() const
bool writable() const
Definition: session.h:173
NSM_Client * nsm
Definition: ardour_ui.h:337
void midi_panic()
Definition: ardour_ui.cc:4680
static PBD::Signal2< int, framecnt_t, framecnt_t > AskAboutSampleRateMismatch
Definition: session.h:649
std::vector< Glib::RefPtr< Gtk::Action > > engine_opposite_sensitive_actions
Definition: actions.cc:62
int rename(const std::string &)
#define enum_2_string(e)
Definition: enumwriter.h:97
sigc::signal< void > DPIReset
Definition: utils.cc:68
int unload_session(bool hide_stuff=false)
void clear_meters(bool reset_highlight=true)
Definition: level_meter.cc:496
static std::vector< AudioClock * > clocks
Definition: audio_clock.h:97
int sr_mismatch_dialog(ARDOUR::framecnt_t, ARDOUR::framecnt_t)
Definition: ardour_ui.cc:4349
ArdourButton roll_button
Definition: ardour_ui.h:444
struct tm * localtime_r(const time_t *const timep, struct tm *p_tm)
Definition: localtime_r.cc:17
AutoConnectOption output_ac
Definition: types.h:586
bool actively_recording() const
Definition: session.h:280
void reset_peak_display()
Definition: ardour_ui.cc:4707
const std::string video_path() const
void step_edit_status_change(bool)
Definition: ardour_ui.cc:4452
WM::ProxyWithConstructor< GlobalPortMatrixWindow > midi_port_matrix
Definition: ardour_ui.h:656
void transport_record(bool roll)
Definition: ardour_ui.cc:2009
uint64_t microseconds_t
Definition: ardour_ui.cc:97
uint32_t capture_load()
bool get_play_loop() const
Definition: session.h:342
Definition: ardour_ui.h:130
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r)
Definition: shared_ptr.hpp:396
static PBD::Signal2< int, std::string, std::vector< std::string > > AmbiguousFileName
Definition: file_source.h:83
static ARDOUR_UI * instance()
Definition: ardour_ui.h:187
static PBD::Signal0< void > DiskUnderrun
Definition: diskstream.h:187
static void set_constant_heights()
void stop_clocking()
Definition: ardour_ui.cc:2384
bool save_as_progress_update(float fraction, int64_t cnt, int64_t total, Gtk::Label *label, Gtk::ProgressBar *bar)
Definition: ardour_ui.cc:2390
bool is_active(void)
Definition: nsmclient.h:61
void pop_back_splash(Gtk::Window &)
Definition: ardour_ui.cc:602
static PBD::Signal1< void, std::string > Dialog
Definition: session.h:184
void launch_manual()
Definition: ardour_ui.cc:3296
void launch_subscribe()
Definition: ardour_ui.cc:3314
void session_add_audio_route(bool, int32_t, int32_t, ARDOUR::TrackMode, ARDOUR::RouteGroup *, uint32_t, std::string const &)
Definition: ardour_ui.cc:1830
void update_xrun_count()
Definition: ardour_ui.cc:1351
virtual void toggle_ruler_video(bool)=0
virtual void finish_cleanup()=0
virtual void play_selection()=0
bool start_video_server(Gtk::Window *float_window, bool popup_msg)
Definition: ardour_ui.cc:3765
std::vector< Glib::RefPtr< Gtk::Action > > engine_sensitive_actions
Definition: actions.cc:61
int set_state(const XMLNode &, int version)
Definition: keyboard.cc:191
static void close_all_dialogs()
Definition: ardour_ui.h:212
void maybe_enable_record()
Definition: session.cc:1731
bool connect_outs_to_master() const
static Manager & instance()
std::deque< std::pair< std::string, std::string > > RecentSessions
LIBGTKMM2EXT_API Glib::RefPtr< Gtk::Action > get_action(const char *group, const char *name)
Definition: actions.cc:406
void export_video(bool range=false)
Definition: ardour_ui.cc:4028
void audioengine_became_silent()
Definition: ardour_ui.cc:4802
void show_splash()
Definition: ardour_ui.cc:3368
LIBARDOUR_API PBD::Signal1< void, int > PluginScanTimeout
Definition: globals.cc:137
std::string name() const
Definition: session.h:166
Splash * splash
Definition: ardour_ui.h:683
void toggle_roll(bool with_abort, bool roll_out_of_bounded_mode)
Definition: ardour_ui.cc:2104
Gtk::Window * get(bool create=false)
void set_record_enabled(boost::shared_ptr< RouteList >, bool, SessionEvent::RTeventCallback after=rt_cleanup, bool group_override=false)
void queue_finish()
Definition: ardour_ui.cc:1038
int output_limit_count() const
ARDOUR::SystemExec * video_server_process
Definition: ardour_ui.h:666
void successful_graph_sort()
Definition: ardour_ui.cc:4674
uint32_t n_audio() const
Definition: chan_count.h:63
virtual Timecode::TimecodeFormat apparent_timecode_format() const =0
tuple f
Definition: signals.py:35
LIBARDOUR_API int handle_old_configuration_files(boost::function< bool(std::string const &, std::string const &, int)> ui_handler)
Definition: globals.cc:358
bool is_auditioning() const
Definition: session.cc:4184
void transport_goto_start()
Definition: ardour_ui.cc:1880
Definition: Beats.hpp:239
LIBPBD_API Transmitter error
LIBPBD_API Transmitter warning
bool get_play_range() const
Definition: session.h:822
bool step_editing() const
Definition: session.h:913
void toggle_follow_edits()
Definition: ardour_ui2.cc:753
void flush_trash()
Definition: ardour_ui.cc:3588
UIConfiguration * ui_config
Definition: ardour_ui.h:140
void engine_stopped()
Definition: ardour_ui.cc:422
RouteList new_route_from_template(uint32_t how_many, const std::string &template_path, const std::string &name)
Definition: session.cc:2538
void finish()
Definition: ardour_ui.cc:1051
WM::Proxy< LocationUIWindow > location_ui
Definition: ardour_ui.h:644
static PBD::Signal1< int, uint32_t > AudioEngineSetupRequired
Definition: session.h:638
sigc::connection fps_connection
Definition: ardour_ui.h:574
std::ostream & endmsg(std::ostream &ostr)
Definition: transmitter.h:71
void every_second()
Definition: ardour_ui.cc:1186
SessionConfiguration config
Definition: session.h:866
Gtk::Label buffer_load_label
Definition: ardour_ui.h:558
boost::shared_ptr< TransportControllable > roll_controllable
Definition: ardour_ui.h:431
const std::string dead_path() const
void request_play_loop(bool yn, bool leave_rolling=false)
#define P_(Singular, Plural, HowMany)
Definition: i18n.h:41
void transport_play_selection()
Definition: ardour_ui.cc:2197
RecordState record_status() const
Definition: session.h:276
uint32_t playback_load()
void cancel_plugin_scan()
Definition: ardour_ui.cc:4166
virtual void center_screen(framepos_t)=0
void set_desired_sample_rate(uint32_t)
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > start
Definition: region.cc:63
PBD::Signal3< bool, float, int64_t, int64_t > Progress
Definition: session.h:420
void start_clocking()
Definition: ardour_ui.cc:2374
void session_format_mismatch(std::string, std::string)
Definition: ardour_ui.cc:4688
void show_visible() const
void request_locate(framepos_t frame, bool with_roll=false)
VtlImportOption import_option()
void goto_start()
Definition: session.cc:5032
void use_config()
Definition: ardour_ui.cc:4422
void map_transport_state()
Definition: ardour_ui.cc:2289
void register_window(ProxyBase *)
framecnt_t frame_rate() const
Definition: session.h:365
void init()
Definition: actions.cc:69
void flush_videotimeline_cache(bool localcacheonly=false)
Definition: ardour_ui.cc:4017
XMLNode * instant_xml(const std::string &str)
void disk_overrun_handler()
Definition: ardour_ui.cc:4142
void map_parameters(boost::function< void(std::string)> &)
Definition: ui_config.cc:146
float update_meters()
Definition: level_meter.cc:127
float editor_meter_max_peak
Definition: ardour_ui.h:472
void unset_active_state()
Definition: cairo_widget.h:50
#define ENSURE_GUI_THREAD(obj, method,...)
Definition: gui_thread.h:34
int build_session_from_dialog(SessionDialog &, const std::string &session_name, const std::string &session_path)
Definition: ardour_ui.cc:2776
bool no_connect_ports
Definition: opts.cc:44
GUIObjectState * gui_object_state
Definition: ardour_ui.h:227
LIBARDOUR_API PBD::Signal0< void > GUIIdle
Definition: globals.cc:138
void cancel_audition()
Definition: session.cc:4160
Gtk::Main & main() const
Definition: gtk_ui.h:147
int toggle_file_existence(string const &path)
Definition: file_utils.cc:488
void set_initial_text(std::string txt)
Definition: prompter.h:50
void reset_group_peak_display(ARDOUR::RouteGroup *)
Definition: ardour_ui.cc:4716
void reset_dpi()
Definition: utils.cc:819
virtual void set_xjadeo_sensitive(bool onoff)=0
Gtk::Label format_label
Definition: ardour_ui.h:564
void toggle_auto_return()
static UI * instance()
Definition: gtk_ui.h:119
static ARDOUR_UI * theArdourUI
Definition: ardour_ui.h:352
InsertAt insert_at()
bool dirty() const
Definition: session.h:176
void recent_session_row_activated(const Gtk::TreePath &path, Gtk::TreeViewColumn *col)
Definition: ardour_ui.cc:1647
void import_metadata()
Definition: ardour_ui.cc:2742
TypeWanted type_wanted() const
int ambiguous_file(std::string file, std::vector< std::string > hits)
Definition: ardour_ui.cc:4642
void every_point_one_seconds()
Definition: ardour_ui.cc:1209
MainClock * secondary_clock
Definition: ardour_ui.h:230
void set_transport_controllable_state(const XMLNode &)
Definition: ardour_ui.cc:643
virtual void queue_visual_videotimeline_update()=0
uint32_t n_total() const
Definition: chan_count.h:69
std::string new_name
Definition: session.h:401
ArdourButton goto_start_button
Definition: ardour_ui.h:446
XMLNode * mixer_settings() const
Definition: ardour_ui.cc:4051
virtual bool dragging_playhead() const =0
Locations * locations()
Definition: session.h:382
void update_buffer_load()
Definition: ardour_ui.cc:1388
dialog box to collect video-server settings
PBD::ScopedConnection halt_connection
Definition: ardour_ui.h:756
LIBARDOUR_API microseconds_t get_microseconds()
Definition: globals.cc:728
#define _(Text)
Definition: i18n.h:11
void save_ardour_state()
ArdourButton auto_loop_button
Definition: ardour_ui.h:448
void reset_xrun_count()
Definition: session.h:600
bool video_file_info(std::string, bool)
void record_state_changed()
Definition: ardour_ui.cc:4467
std::string _announce_string
Definition: ardour_ui.h:802
LIBGTKMM2EXT_API void set_sensitive(std::vector< Glib::RefPtr< Gtk::Action > > &actions, bool)
void save_session_at_its_request(std::string)
Definition: ardour_ui.cc:700
void start_video_server_menu(Gtk::Window *float_window)
Definition: ardour_ui.cc:3759
Definition: splash.h:33
LIBARDOUR_API std::string user_config_directory(int version=-1)
void set_flat_buttons()
Definition: ardour_ui.cc:4796
bool connect_outs_to_physical() const
void stop_video_server(bool ask_confirm=false)
Definition: ardour_ui.cc:3736
void transport_goto_zero()
Definition: ardour_ui.cc:1896
sigc::signal< void > ShouldQuit
Definition: application.h:55
WM::ProxyWithConstructor< BigClockWindow > big_clock_window
Definition: ardour_ui.h:654
bool idle_finish()
Definition: ardour_ui.cc:1044
static PBD::Signal0< void > FeedbackDetected
Definition: session.h:929
void allow_auto_play(bool yn)
Definition: getopt.h:74
bool check_announcements
Definition: opts.cc:50
void launch_howto_report()
Definition: ardour_ui.cc:3348
bool caller_is_ui_thread()
Definition: gtk_ui.cc:134
void save_state(const std::string &state_name="", bool switch_to_it=false)
Definition: ardour_ui.cc:2615
TrackMode
Definition: types.h:198
void request_stop(bool abort=false, bool clear_state=false)
int load_session(const std::string &path, const std::string &snapshot, std::string mix_template=std::string())
Definition: ardour_ui.cc:3096
static void set_flat_buttons(bool yn)
#define X_(Text)
Definition: i18n.h:13
void sync_session_state()
void close_session()
Definition: ardour_ui.cc:3073
static char * place
Definition: getopt_long.c:126
LIBARDOUR_API void init_post_engine()
Definition: globals.cc:487
int64_t framecnt_t
Definition: types.h:76
uint32_t rec_enabled_streams
Definition: ardour_ui.h:680
gboolean configure_handler(GdkEventConfigure *conf)
Definition: ardour_ui.cc:630
XMLProperty * property(const char *)
Definition: xml++.cc:413
uint32_t order_key() const
Definition: route.cc:306
ExplicitActive
Definition: widget_state.h:13
LIBARDOUR_API RCConfiguration * Config
Definition: globals.cc:119
uint32_t ntracks() const
Definition: session.cc:4870
void update_timecode_format()
Definition: ardour_ui.cc:1485
GlobalPortMatrixWindow * create_global_port_matrix(ARDOUR::DataType)
Definition: ardour_ui.cc:406
int input_limit_count() const
void gui_idle_handler()
Definition: ardour_ui.cc:4262
gint response() const
Definition: startup.h:54
static const char * localedir
Definition: load_session.cc:12
void set_prompt(std::string prompt)
Definition: prompter.h:46
ArdourButton goto_end_button
Definition: ardour_ui.h:447
gint transport_numpad_timeout()
Definition: ardour_ui.cc:4751
void plugin_scan_dialog(std::string type, std::string plugin, bool)
Definition: ardour_ui.cc:4194
bool _was_dirty
Definition: ardour_ui.h:338
VideoTimeLine * video_timeline
Definition: ardour_ui.h:236
LIBPBD_API void pthread_cancel_all()
void flush_pending()
Definition: gtk_ui.cc:681
void remove_pending_capture_state()
virtual void first_idle()=0
WM::ProxyWithConstructor< GlobalPortMatrixWindow > audio_port_matrix
Definition: ardour_ui.h:655
Gtk::Label disk_space_label
Definition: ardour_ui.h:546
sigc::connection clock_signal_connection
Definition: ardour_ui.h:377
int save_as(SaveAs &)
ArdourButton midi_panic_button
Definition: ardour_ui.h:783
void load_rc_file(bool themechange, bool allow_own=true)
Definition: ui_config.cc:656
int master_channel_count() const
void display_cleanup_results(ARDOUR::CleanupReport &rep, const gchar *list_title, const bool msg_delete)
Definition: ardour_ui.cc:3389
void session_add_midi_track(ARDOUR::RouteGroup *route_group, uint32_t how_many, std::string const &name_template, ARDOUR::PluginInfoPtr instrument)
Definition: ardour_ui.h:273
static PBD::Signal0< void > Quit
Definition: session.h:948
void rename_session()
Definition: ardour_ui.cc:2555
ImplicitActive
Definition: widget_state.h:13
framepos_t transport_frame() const
Definition: session.h:551
Definition: amp.h:29
void setup_order_hint(AddRouteDialog::InsertAt)
Definition: ardour_ui.cc:3605
boost::shared_ptr< Route > master_out() const
Definition: session.h:718
void setup_profile()
Definition: ardour_ui.cc:4598
SaveAsDialog * save_as_dialog
Definition: ardour_ui.h:625
void cleanup()
Definition: ardour_ui.cc:3531
void request_transport_speed(double speed, bool as_default=false)
void big_clock_value_changed()
Definition: ardour_ui.cc:2660
double get_value(void) const
Definition: ardour_ui.cc:4571
bool switch_to() const
void set_controllable(boost::shared_ptr< PBD::Controllable > c)
void check(int timeout=0)
Definition: nsmclient.cc:144
void session_add_midi_route(bool, ARDOUR::RouteGroup *, uint32_t, std::string const &, ARDOUR::PluginInfoPtr)
Definition: ardour_ui.cc:1819
std::string new_parent_folder
Definition: session.h:400
void set_fps_interval(unsigned int interval)
Definition: timers.cc:199
static ProgressBar * scan_pbar
Definition: ardour_ui.cc:4162
std::string path() const
Definition: session.h:165
void disk_speed_dialog_gone(int ignored_response, Gtk::MessageDialog *)
Definition: ardour_ui.cc:4290
bool check_audioengine()
Definition: ardour_ui.cc:1705
#define gui_context()
Definition: gui_thread.h:36
void audition_blink(bool)
Definition: ardour_ui2.cc:626
bool connect_outputs() const
void foreach_route(T *obj, void(T::*func)(Route &), bool sort=true)
Definition: session_route.h:33
boost::shared_ptr< TransportControllable > play_selection_controllable
Definition: ardour_ui.h:436
std::string load_template
Definition: opts.cc:49
bool name_template_is_default() const
boost::shared_ptr< TransportControllable > auto_loop_controllable
Definition: ardour_ui.h:435
AutoConnectOption input_ac
Definition: types.h:585
int do_audio_midi_setup(uint32_t)
Definition: ardour_ui.cc:4734
void toggle_record_enable(uint32_t)
Definition: ardour_ui.cc:2270
void set_nsm_state(bool state)
Definition: session.h:438
void add_controllable(boost::shared_ptr< PBD::Controllable >)
static PBD::Signal2< void, std::string, std::string > VersionMismatch
Definition: session.h:953
void disk_underrun_handler()
Definition: ardour_ui.cc:4272
boost::shared_ptr< RouteList > get_routes() const
Definition: session.h:229
VisibilityGroup _status_bar_visibility
Definition: ardour_ui.h:774
bool connect_inputs() const
uint32_t requested_physical_out
Definition: types.h:589
TransportControllable(std::string name, ARDOUR_UI &, ToggleType)
Definition: ardour_ui.cc:4517
std::string get_listenaddr()
bool record_enabled() const
Definition: track.cc:215
int64_t framepos_t
Definition: types.h:66
virtual Selection & get_selection() const =0
void save_session_as()
Definition: ardour_ui.cc:2409
void set_active_state(Gtkmm2ext::ActiveState)
virtual void play_with_preroll()=0
Gtk::Tooltips & tooltips()
Definition: ardour_ui.h:199
int cleanup_trash_sources(CleanupReport &)
int64_t frameoffset_t
Definition: types.h:71
static bool required()
Definition: startup.cc:116
RouteList new_audio_route(int input_channels, int output_channels, RouteGroup *route_group, uint32_t how_many, std::string name_template="")
Definition: session.cc:2454
bool have_disk_speed_dialog_displayed
Definition: ardour_ui.h:702
static HBox * scan_tbox
Definition: ardour_ui.cc:4163
WM::Proxy< ExportVideoDialog > export_video_dialog
Definition: ardour_ui.h:647
Definition: nsm.h:24
void remove_video()
Definition: ardour_ui.cc:3997
void transport_numpad_decimal()
Definition: ardour_ui.cc:4760
void maybe_update_session_range(framepos_t, framepos_t)
Definition: session.cc:3461
int init(const char *nsm_url)
Definition: nsmclient.cc:163
ArdourDialog * session_selector_window
Definition: ardour_ui.h:521
bool _feedback_exists
Definition: ardour_ui.h:787
LIBARDOUR_API std::vector< std::string > get_file_names_no_extension(const std::vector< std::string > &file_paths)
void hide_splash()
Definition: ardour_ui.cc:3382
ChanCount n_inputs() const
Definition: route.h:92
T * get() const
Definition: shared_ptr.hpp:268
void set_mode(Mode)
void halt_on_xrun_message()
Definition: ardour_ui.cc:4116
PBD::Signal1< void, std::string > ParameterChanged
Definition: configuration.h:44
void loading_message(const std::string &msg)
Definition: ardour_ui.cc:3354
LIBPBD_API Transmitter info
LIBPBD_API bool open_uri(const char *)
Definition: openuri.cc:41
LIBARDOUR_API RuntimeProfile * Profile
Definition: globals.cc:120
WM::Proxy< AddRouteDialog > add_route_dialog
Definition: ardour_ui.h:642
boost::shared_ptr< TransportControllable > stop_controllable
Definition: ardour_ui.h:432
void get_result(std::string &str, bool strip=true)
Definition: prompter.cc:104
virtual void toggle_xjadeo_proc(int)=0
void transport_goto_end()
Definition: ardour_ui.cc:1947
void disable_record(bool rt_context, bool force=false)
Definition: session.cc:1690
static PBD::Signal0< void > SuccessfulGraphSort
Definition: session.h:934
void launch_website_dev()
Definition: ardour_ui.cc:3336
WM::Proxy< SpeakerDialog > speaker_config_window
Definition: ardour_ui.h:639
void set_tip(Gtk::Widget &w, const gchar *tip)
LIBARDOUR_API const char *const statefile_suffix
void feedback_blink(bool)
Definition: ardour_ui2.cc:644
void call_slot(EventLoop::InvalidationRecord *, const boost::function< void()> &)
Definition: abstract_ui.cc:368
bool _session_is_new
Definition: ardour_ui.h:614
void edit_metadata()
Definition: ardour_ui.cc:2733
void primary_clock_value_changed()
Definition: ardour_ui.cc:2652
bool new_session
Definition: opts.cc:41
void setup_gtk_ardour_enums()
Definition: enums.cc:33
void set_state(const XMLNode &)
void sync_blink(bool)
Definition: ardour_ui2.cc:603
void map_transport_state()
void map_parameters(boost::function< void(std::string)> &)
sigc::connection _numpad_timeout_connection
Definition: ardour_ui.h:596
XMLProperty * add_property(const char *name, const std::string &value)
bool copy_external() const
void transport_stop()
Definition: ardour_ui.cc:1964
void feedback_detected()
Definition: ardour_ui.cc:4668
void add(Location *, bool make_current=false)
Definition: location.cc:953
sigc::signal< void, const Glib::ustring & > ShouldLoad
Definition: application.h:54
LIBPBD_API Glib::ustring basename_nosuffix(Glib::ustring)
void error_blink(bool)
Definition: ardour_ui2.cc:658
boost::shared_ptr< Route > route_by_remote_id(uint32_t id)
Definition: session.cc:3367
bool first_idle()
Definition: ardour_ui.cc:4484
static MessageDialog * scan_dlg
Definition: ardour_ui.cc:4161
std::string snap_name() const
Definition: session.h:167
gint configure_timeout()
Definition: ardour_ui.cc:610
ArdourButton play_selection_button
Definition: ardour_ui.h:449
WM::Proxy< About > about
Definition: ardour_ui.h:643
ARDOUR::framepos_t start()
LIBARDOUR_API void cleanup()
Definition: globals.cc:502
const char * name
void set_order_hint(int32_t order_hint)
Definition: session.h:249
bool get_trx() const
Definition: profile.h:50
int start(int stderr_mode=1)
Definition: system_exec.h:38
void session_add_audio_bus(int input_channels, int32_t output_channels, ARDOUR::RouteGroup *route_group, uint32_t how_many, std::string const &name_template)
Definition: ardour_ui.h:268
void add_child_nocopy(XMLNode &)
Definition: xml++.cc:357
bool show_key_actions
Definition: opts.cc:37
void transport_goto_wallclock()
Definition: ardour_ui.cc:1912
Gtk::TreeModelColumn< std::string > tip
Definition: ardour_ui.h:513
Gtk::Label xrun_label
Definition: ardour_ui.h:555
LIBGTKMM2EXT_API void init(const char *)
Definition: utils.cc:42
std::string final_session_folder_name
Definition: session.h:407
void blink_handler(bool)
Definition: ardour_ui.cc:2353
static sigc::signal< void > CloseAllDialogs
Definition: ardour_ui.h:213
framepos_t current_end_frame() const
Definition: session.cc:5048
LIBARDOUR_API int read_recent_sessions(RecentSessions &rs)
void request_play_range(std::list< AudioRange > *, bool leave_rolling=false)
bool get_smart_mode() const
Definition: ardour_ui.cc:2097
bool session_loaded
Definition: ardour_ui.h:168
void set_active(bool)
std::string track_template()
WM::Proxy< KeyEditor > key_editor
Definition: ardour_ui.h:640
bool have_configure_timeout
Definition: ardour_ui.h:695
void redisplay_recent_sessions()
Definition: ardour_ui.cc:1530
XMLNode * instant_xml(const std::string &str)
framepos_t current_start_frame() const
Definition: session.cc:5042
void count_recenabled_streams(ARDOUR::Route &)
Definition: ardour_ui.cc:1417
LIBARDOUR_API void get_state_files_in_directory(const std::string &directory_path, std::vector< std::string > &result)
ArdourButton stop_button
Definition: ardour_ui.h:445
Definition: xml++.h:95
std::string new_parent_folder() const
bool ask_about_loading_existing_session(const std::string &session_path)
Definition: ardour_ui.cc:2750
uint32_t requested_physical_in
Definition: types.h:588
RouteGroup * route_group() const
std::list< boost::shared_ptr< AudioTrack > > new_audio_track(int input_channels, int output_channels, TrackMode mode=Normal, RouteGroup *route_group=0, uint32_t how_many=1, std::string name_template="")
Definition: session.cc:2361
TimeSelection time
Definition: selection.h:83
ARDOUR::RouteGroup * route_group()
void remove_property(const std::string &)
Definition: xml++.cc:476
TrackSelection tracks
Definition: selection.h:81
void set_requested_return_frame(framepos_t return_to)
static UIConfiguration * config()
Definition: ardour_ui.h:188
void add_instant_xml(XMLNode &, bool write_to_config=true)
The instant xml file is written to the session directory.
void launch_cheat_sheet()
Definition: ardour_ui.cc:3320
virtual framepos_t get_preferred_edit_position(Editing::EditIgnoreOption=Editing::EDIT_IGNORE_NONE, bool from_context_menu=false, bool from_outside_canvas=false)=0
PBD::ScopedConnectionList forever_connections
Definition: ardour_ui.h:755
void set(DataType t, uint32_t count)
Definition: chan_count.h:58
bool copy_media() const
WM::Proxy< RCOptionEditor > rc_option_editor
Definition: ardour_ui.h:641
Gtk::TreeView recent_session_display
Definition: ardour_ui.h:518
LIBARDOUR_API PBD::Signal1< void, std::string > BootMessage
Definition: globals.cc:135
sigc::connection fps_connect(const sigc::slot< void > &slot)
Definition: timers.cc:205
void update_sample_rate(ARDOUR::framecnt_t)
Definition: ardour_ui.cc:1263
boost::optional< framecnt_t > available_capture_duration()
Definition: session.cc:4230
void session_dialog(std::string)
Definition: ardour_ui.cc:4297
std::string file_name(bool &local_file)
void engine_halted(const char *reason, bool free_reason)
Definition: ardour_ui.cc:448
void cancel_plugin_timeout()
Definition: ardour_ui.cc:4172
int setup_windows()
Definition: ardour_ui2.cc:70
boost::shared_ptr< TransportControllable > rec_controllable
Definition: ardour_ui.h:437
XMLNode * extra_xml(const std::string &str, bool add_if_missing=false)
Definition: stateful.cc:77
static void set_connecting_blocked(bool yn)
Definition: port.h:46
Definition: debug.h:30
void session_add_mixed_track(const ARDOUR::ChanCount &input, const ARDOUR::ChanCount &output, ARDOUR::RouteGroup *route_group, uint32_t how_many, std::string const &name_template, ARDOUR::PluginInfoPtr instrument)
Definition: ardour_ui.cc:1789
ARDOUR::TrackMode mode()
LIBARDOUR_API uint64_t MTC
Definition: debug.cc:39
std::string session_name
Definition: opts.cc:34
ARDOUR::ProcessThread * _process_thread
Definition: ardour_ui.h:779
bool _numpad_locate_happening
Definition: ardour_ui.h:593
virtual void ensure_float(Gtk::Window &)=0
void set_session(ARDOUR::Session *)
Gtk::TreeModelColumn< std::string > fullpath
Definition: ardour_ui.h:514
void update_disk_space()
Definition: ardour_ui.cc:1426
void transport_numpad_event(int num)
Definition: ardour_ui.cc:4775
std::list< std::string > unknown_processors() const
Definition: session.cc:5251
bool have_rec_enabled_track() const
Definition: session.cc:4907
static sigc::signal< void, framepos_t, bool, framepos_t > Clock
Definition: ardour_ui.h:210
uint32_t master_out_channels
Definition: types.h:587
void update_autosave()
Definition: ardour_ui.cc:730
boost::shared_ptr< ShuttleControllable > controllable() const
ARDOUR::framecnt_t get_duration()
void store_clock_modes()
Definition: ardour_ui.cc:4499
#define S_(Text)
Definition: i18n.h:18
std::list< boost::shared_ptr< MidiTrack > > new_midi_track(const ChanCount &input, const ChanCount &output, boost::shared_ptr< PluginInfo > instrument=boost::shared_ptr< PluginInfo >(), TrackMode mode=Normal, RouteGroup *route_group=0, uint32_t how_many=1, std::string name_template="")
Definition: session.cc:2117
sigc::signal< void, std::string > ParameterChanged
Definition: ui_config.h:78
void parameter_changed(std::string)
LIBARDOUR_API int find_session(std::string str, std::string &path, std::string &snapshot, bool &isnew)
Gtk::FileChooserDialog * open_session_selector
Definition: ardour_ui.h:522
void update_clocks()
Definition: ardour_ui.cc:2364
void transport_rewind(int option)
Definition: ardour_ui.cc:2216
PublicEditor * editor
Definition: ardour_ui.h:334
AudioClock * big_clock
Definition: ardour_ui.h:232
LIBARDOUR_API PBD::Signal3< void, std::string, std::string, bool > PluginScanMessage
Definition: globals.cc:136
void every_point_zero_something_seconds()
Definition: ardour_ui.cc:1216
WM::Proxy< RouteParams_UI > route_params
Definition: ardour_ui.h:645
ArdourButton editor_meter_peak_display
Definition: ardour_ui.h:473
virtual void set_session(ARDOUR::Session *)
Gtk::Tooltips _tooltips
Definition: ardour_ui.h:336
LIBARDOUR_API GQuark capture
Definition: operations.cc:24
void session_add_audio_track(int input_channels, int32_t output_channels, ARDOUR::TrackMode mode, ARDOUR::RouteGroup *route_group, uint32_t how_many, std::string const &name_template)
Definition: ardour_ui.h:256
int save_state(std::string snapshot_name, bool pending=false, bool switch_to_snapshot=false, bool template_only=false)
void solo_blink(bool)
Definition: ardour_ui2.cc:585
LIBGTKMM2EXT_API void get_all_actions(std::vector< std::string > &names, std::vector< std::string > &paths, std::vector< std::string > &tooltips, std::vector< std::string > &keys, std::vector< Gtk::AccelKey > &bindings)
std::string session_folder()
std::string immediate_save
Definition: opts.cc:48
std::string name_template() const
void engine_running()
Definition: ardour_ui.cc:430
int missing_file(ARDOUR::Session *s, std::string str, ARDOUR::DataType type)
Definition: ardour_ui.cc:4619
ARDOUR::PluginInfoPtr requested_instrument()
XMLNode * keyboard_settings() const
Definition: ardour_ui.cc:4093
Off
Definition: widget_state.h:13
static const framecnt_t max_framecnt
Definition: types.h:79
sigc::connection point_zero_something_second_connection
Definition: ardour_ui.h:573
static float ui_scale
Definition: ardour_ui.h:189
int cleanup_sources(CleanupReport &)
Gtk::Label cpu_load_label
Definition: ardour_ui.h:552
void quit()
Definition: gtk_ui.cc:293
void open_recent_session()
Definition: ardour_ui.cc:1653
gint update_wall_clock()
Definition: ardour_ui.cc:1511
int disconnect_from_engine()
Definition: ardour_ui.cc:4382
static PBD::Signal3< int, Session *, std::string, DataType > MissingFile
Definition: session.h:945
void drop_process_buffers()
Definition: ardour_ui.cc:4662
const SessionDirectory & session_directory() const
Definition: session.h:182
void resize_text_widgets()
int build_session(const std::string &path, const std::string &snapshot, ARDOUR::BusProfile &)
Definition: ardour_ui.cc:3226
void toggle_session_auto_loop()
Definition: ardour_ui.cc:2163
void add_state(XMLNode &) const
Slave * slave() const
Definition: session.h:905
void add_extra_xml(XMLNode &)
Definition: stateful.cc:66
Glib::RefPtr< Gtk::TreeStore > recent_session_model
Definition: ardour_ui.h:519
void remove_nodes_and_delete(const std::string &)
LevelMeterHBox * editor_meter
Definition: ardour_ui.h:471
bool trx_record_enable_all_tracks()
Definition: ardour_ui.cc:1982
void snapshot_session(bool switch_to_it)
Definition: ardour_ui.cc:2479
std::string get_exec_path()
int starting()
Definition: ardour_ui.cc:777
LIBARDOUR_API uint64_t LTC
Definition: debug.cc:40
int _pending_locate_num
Definition: ardour_ui.h:594
sigc::connection _autosave_connection
Definition: ardour_ui.h:362
#define MISSING_INVALIDATOR
Definition: event_loop.h:86
std::string session_name(bool &should_be_new)
void add_instant_xml(XMLNode &)
sigc::connection rapid_connect(const sigc::slot< void > &slot)
Definition: timers.cc:183
std::list< boost::shared_ptr< Route > > RouteList
Definition: types.h:532
boost::shared_ptr< TransportControllable > goto_start_controllable
Definition: ardour_ui.h:433
void is_dirty(void)
Definition: nsmclient.cc:107
void set_offset_locked(bool v)
int save_state_canfail(std::string state_name="", bool switch_to_it=false)
Definition: ardour_ui.cc:2633
int ask_about_saving_session(const std::vector< std::string > &actions)
Definition: ardour_ui.cc:1118
void set_fps_timeout_connection()
Definition: ardour_ui.cc:1231
void manual_seek_video_monitor(framepos_t pos)
std::string new_name() const
void apply_state(TimeSelection &tme, bool range)
void update_cpu_load()
Definition: ardour_ui.cc:1374
WM::ProxyWithConstructor< AddVideoDialog > add_video_dialog
Definition: ardour_ui.h:652
ARDOUR::microseconds_t last_configure_time
Definition: ardour_ui.h:696
void launch_tracker()
Definition: ardour_ui.cc:3308
void add_route(Gtk::Window *float_window)
Definition: ardour_ui.cc:3660
void set_hidden(bool yn, void *src)
Definition: location.cc:441
ARDOUR::Session * _session
AutoConnectOption
Definition: types.h:454
boost::shared_ptr< ARDOUR::Route > route() const
Definition: route_ui.h:76
void get_process_buffers()
Definition: ardour_ui.cc:4655
void open_session()
Definition: ardour_ui.cc:1720
Editing of options which are obtained from and written back to one of the .rc files.
void add_video(Gtk::Window *float_window)
Definition: ardour_ui.cc:3881
static PBD::Signal0< int > AskAboutPendingState
Definition: session.h:653
Gtk::Label wall_clock_label
Definition: ardour_ui.h:543
std::vector< std::string > paths
Definition: types.h:549
Definition: ardour.h:41
boost::shared_ptr< TransportControllable > goto_end_controllable
Definition: ardour_ui.h:434
XMLNode & get_state() const
Definition: gui_object.cc:119
std::string string_compose(const std::string &fmt, const T1 &o1)
Definition: compose.h:208
virtual void reset_x_origin(framepos_t frame)=0
Gtk::Label timecode_format_label
Definition: ardour_ui.h:549
void reset_route_peak_display(ARDOUR::Route *)
Definition: ardour_ui.cc:4725
Gtk::Label sample_rate_label
Definition: ardour_ui.h:561
void display()
Definition: splash.cc:202
ShuttleControl * shuttle_box
Definition: ardour_ui.h:456
virtual bool get_smart_mode() const =0
void load_from_application_api(const std::string &path)
Definition: ardour_ui.cc:2826
void set_update_session_fps(bool v=true)
XMLNode & get_transport_controllable_state()
Definition: ardour_ui.cc:674
virtual void goto_nth_marker(int nth)=0
static PBD::Signal0< void > DiskOverrun
Definition: diskstream.h:186
bool is_monitor() const
Definition: route.h:112
void pop_back_for(Gtk::Window &)
Definition: splash.cc:101
void plugin_scan_timeout(int)
Definition: ardour_ui.cc:4179
VtlTranscodeOption import_option()
void transport_play_preroll()
Definition: ardour_ui.cc:2207
virtual void prepare_for_cleanup()=0
void popup_error(const std::string &text)
Definition: gtk_ui.cc:665
std::string session_template_name()
ArdourButton rec_button
Definition: ardour_ui.h:450
void save_template()
Definition: ardour_ui.cc:2703
void check_announcements()
Definition: ardour_ui.cc:750
static bool ask_about_configuration_copy(string const &old_dir, string const &new_dir, int version)
Definition: ardour_ui.cc:166
void pingback(const string &version, const string &announce_path)
Definition: pingback.cc:174
void attach_to_engine()
Definition: ardour_ui.cc:415
bool check_server_docroot()
std::string failure_message
Definition: session.h:424
optional info box regarding video-export