2 Copyright (C) 1999-2007 Paul Davis
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.
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.
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.
20 #define __STDC_FORMAT_MACROS 1
34 #include <sys/resource.h>
36 #include <gtkmm/messagedialog.h>
37 #include <gtkmm/accelmap.h>
39 #include "pbd/error.h"
40 #include "pbd/basename.h"
41 #include "pbd/compose.h"
42 #include "pbd/failed_constructor.h"
43 #include "pbd/enumwriter.h"
44 #include "pbd/memento_command.h"
45 #include "pbd/file_utils.h"
47 #include "gtkmm2ext/gtk_ui.h"
48 #include "gtkmm2ext/utils.h"
49 #include "gtkmm2ext/click_box.h"
50 #include "gtkmm2ext/fastmeter.h"
51 #include "gtkmm2ext/stop_signal.h"
52 #include "gtkmm2ext/popup.h"
53 #include "gtkmm2ext/window_title.h"
55 #include "midi++/manager.h"
57 #include "ardour/ardour.h"
58 #include "ardour/profile.h"
59 #include "ardour/session_directory.h"
60 #include "ardour/session_route.h"
61 #include "ardour/session_state_utils.h"
62 #include "ardour/session_utils.h"
63 #include "ardour/port.h"
64 #include "ardour/audioengine.h"
65 #include "ardour/playlist.h"
66 #include "ardour/utils.h"
67 #include "ardour/audio_diskstream.h"
68 #include "ardour/audiofilesource.h"
69 #include "ardour/recent_sessions.h"
70 #include "ardour/port.h"
71 #include "ardour/audio_track.h"
72 #include "ardour/midi_track.h"
73 #include "ardour/filesystem_paths.h"
74 #include "ardour/filename_extensions.h"
76 typedef uint64_t microseconds_t;
79 #include "ardour_ui.h"
80 #include "public_editor.h"
81 #include "audio_clock.h"
86 #include "add_route_dialog.h"
90 #include "gui_thread.h"
91 #include "theme_manager.h"
92 #include "bundle_manager.h"
93 #include "session_metadata_dialog.h"
94 #include "gain_meter.h"
95 #include "route_time_axis.h"
97 #include "engine_dialog.h"
98 #include "processor_box.h"
102 using namespace ARDOUR;
104 using namespace Gtkmm2ext;
107 ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
108 UIConfiguration *ARDOUR_UI::ui_config = 0;
110 sigc::signal<void,bool> ARDOUR_UI::Blink;
111 sigc::signal<void> ARDOUR_UI::RapidScreenUpdate;
112 sigc::signal<void> ARDOUR_UI::SuperRapidScreenUpdate;
113 sigc::signal<void,nframes_t, bool, nframes_t> ARDOUR_UI::Clock;
115 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
117 : Gtkmm2ext::UI (X_("gui"), argcp, argvp),
119 primary_clock (X_("primary"), false, X_("TransportClockDisplay"), true, true, false, true),
120 secondary_clock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, true, false, true),
121 preroll_clock (X_("preroll"), false, X_("PreRollClock"), true, false, true),
122 postroll_clock (X_("postroll"), false, X_("PostRollClock"), true, false, true),
126 preroll_button (_("pre\nroll")),
127 postroll_button (_("post\nroll")),
131 big_clock (X_("bigclock"), false, "BigClockNonRecording", true, true, false, true),
135 roll_controllable (new TransportControllable ("transport roll", *this, TransportControllable::Roll)),
136 stop_controllable (new TransportControllable ("transport stop", *this, TransportControllable::Stop)),
137 goto_start_controllable (new TransportControllable ("transport goto start", *this, TransportControllable::GotoStart)),
138 goto_end_controllable (new TransportControllable ("transport goto end", *this, TransportControllable::GotoEnd)),
139 auto_loop_controllable (new TransportControllable ("transport auto loop", *this, TransportControllable::AutoLoop)),
140 play_selection_controllable (new TransportControllable ("transport play selection", *this, TransportControllable::PlaySelection)),
141 rec_controllable (new TransportControllable ("transport rec-enable", *this, TransportControllable::RecordEnable)),
142 shuttle_controllable (new TransportControllable ("shuttle", *this, TransportControllable::ShuttleControl)),
143 shuttle_controller_binding_proxy (shuttle_controllable),
145 roll_button (roll_controllable),
146 stop_button (stop_controllable),
147 goto_start_button (goto_start_controllable),
148 goto_end_button (goto_end_controllable),
149 auto_loop_button (auto_loop_controllable),
150 play_selection_button (play_selection_controllable),
151 rec_button (rec_controllable),
153 shuttle_units_button (_("% ")),
155 punch_in_button (_("Punch In")),
156 punch_out_button (_("Punch Out")),
157 auto_return_button (_("Auto Return")),
158 auto_play_button (_("Auto Play")),
159 auto_input_button (_("Auto Input")),
160 click_button (_("Click")),
161 time_master_button (_("time\nmaster")),
163 auditioning_alert_button (_("AUDITION")),
164 solo_alert_button (_("SOLO")),
166 error_log_button (_("Errors"))
169 using namespace Gtk::Menu_Helpers;
175 // _auto_display_errors = false;
177 * This was commented out as it wasn't defined
178 * in A3 IIRC. If this is not needed it should
179 * be completely removed.
187 if (theArdourUI == 0) {
191 ui_config = new UIConfiguration();
192 theme_manager = new ThemeManager();
198 _session_is_new = false;
199 big_clock_window = 0;
200 session_selector_window = 0;
201 last_key_press_time = 0;
202 _will_create_new_session_automatically = false;
203 add_route_dialog = 0;
205 rc_option_editor = 0;
206 session_option_editor = 0;
208 open_session_selector = 0;
209 have_configure_timeout = false;
210 have_disk_speed_dialog_displayed = false;
211 session_loaded = false;
212 last_speed_displayed = -1.0f;
213 ignore_dual_punch = false;
214 _mixer_on_top = false;
216 roll_button.unset_flags (Gtk::CAN_FOCUS);
217 stop_button.unset_flags (Gtk::CAN_FOCUS);
218 goto_start_button.unset_flags (Gtk::CAN_FOCUS);
219 goto_end_button.unset_flags (Gtk::CAN_FOCUS);
220 auto_loop_button.unset_flags (Gtk::CAN_FOCUS);
221 play_selection_button.unset_flags (Gtk::CAN_FOCUS);
222 rec_button.unset_flags (Gtk::CAN_FOCUS);
224 last_configure_time= 0;
226 shuttle_grabbed = false;
228 shuttle_max_speed = 8.0f;
230 shuttle_style_menu = 0;
231 shuttle_unit_menu = 0;
233 // We do not have jack linked in yet so;
235 last_shuttle_request = last_peak_grab = 0; // get_microseconds();
237 ARDOUR::Diskstream::DiskOverrun.connect (sigc::mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
238 ARDOUR::Diskstream::DiskUnderrun.connect (sigc::mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
240 /* handle dialog requests */
242 ARDOUR::Session::Dialog.connect (sigc::mem_fun(*this, &ARDOUR_UI::session_dialog));
244 /* handle pending state with a dialog */
246 ARDOUR::Session::AskAboutPendingState.connect (sigc::mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
248 /* handle sr mismatch with a dialog */
250 ARDOUR::Session::AskAboutSampleRateMismatch.connect (sigc::mem_fun(*this, &ARDOUR_UI::sr_mismatch_dialog));
252 /* lets get this party started */
255 if (ARDOUR::init (ARDOUR_COMMAND_LINE::use_vst, ARDOUR_COMMAND_LINE::try_hw_optimization)) {
256 throw failed_constructor ();
259 setup_gtk_ardour_enums ();
262 GainMeter::setup_slider_pix ();
263 RouteTimeAxisView::setup_slider_pix ();
264 SendProcessorEntry::setup_slider_pix ();
265 SessionEvent::create_per_thread_pool ("GUI", 512);
267 } catch (failed_constructor& err) {
268 error << _("could not initialize Ardour.") << endmsg;
273 /* we like keyboards */
275 keyboard = new ArdourKeyboard;
277 XMLNode* node = ARDOUR_UI::instance()->keyboard_settings();
279 keyboard->set_state (*node, Stateful::loading_state_version);
284 starting.connect (sigc::mem_fun(*this, &ARDOUR_UI::startup));
285 stopping.connect (sigc::mem_fun(*this, &ARDOUR_UI::shutdown));
290 /** @return true if a session was chosen and `apply' clicked, otherwise false if `cancel' was clicked */
292 ARDOUR_UI::run_startup (bool should_be_new)
295 _startup = new ArdourStartup ();
298 _startup->set_new_only (should_be_new);
299 _startup->present ();
305 switch (_startup->response()) {
314 ARDOUR_UI::create_engine ()
316 // this gets called every time by new_session()
322 loading_message (_("Starting audio engine"));
325 engine = new ARDOUR::AudioEngine (ARDOUR_COMMAND_LINE::jack_client_name);
332 engine->Stopped.connect (sigc::mem_fun(*this, &ARDOUR_UI::engine_stopped));
333 engine->Running.connect (sigc::mem_fun(*this, &ARDOUR_UI::engine_running));
334 engine->Halted.connect (sigc::mem_fun(*this, &ARDOUR_UI::engine_halted));
335 engine->SampleRateChanged.connect (sigc::mem_fun(*this, &ARDOUR_UI::update_sample_rate));
343 ARDOUR_UI::post_engine ()
345 /* Things to be done once we create the AudioEngine
348 MIDI::Manager::instance()->set_api_data (engine->jack());
351 ARDOUR::init_post_engine ();
353 ActionManager::init ();
356 if (setup_windows ()) {
357 throw failed_constructor ();
360 check_memory_locking();
362 /* this is the first point at which all the keybindings are available */
364 if (ARDOUR_COMMAND_LINE::show_key_actions) {
365 vector<string> names;
366 vector<string> paths;
368 vector<AccelKey> bindings;
370 ActionManager::get_all_actions (names, paths, keys, bindings);
372 vector<string>::iterator n;
373 vector<string>::iterator k;
374 for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) {
375 cerr << "Action: " << (*n) << " bound to " << (*k) << endl;
381 blink_timeout_tag = -1;
383 /* this being a GUI and all, we want peakfiles */
385 AudioFileSource::set_build_peakfiles (true);
386 AudioFileSource::set_build_missing_peakfiles (true);
388 /* set default clock modes */
390 if (Profile->get_sae()) {
391 primary_clock.set_mode (AudioClock::BBT);
392 secondary_clock.set_mode (AudioClock::MinSec);
394 primary_clock.set_mode (AudioClock::Timecode);
395 secondary_clock.set_mode (AudioClock::BBT);
398 /* start the time-of-day-clock */
401 /* OS X provides an always visible wallclock, so don't be stupid */
402 update_wall_clock ();
403 Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
406 update_disk_space ();
408 update_sample_rate (engine->frame_rate());
410 Config->ParameterChanged.connect (sigc::mem_fun (*this, &ARDOUR_UI::parameter_changed));
411 boost::function<void (string)> pc (boost::bind (&ARDOUR_UI::parameter_changed, this, _1));
412 Config->map_parameters (pc);
414 /* now start and maybe save state */
416 if (do_engine_start () == 0) {
417 if (_session && _session_is_new) {
418 /* we need to retain initial visual
419 settings for a new session
421 _session->save_state ("");
426 ARDOUR_UI::~ARDOUR_UI ()
428 save_ardour_state ();
433 delete add_route_dialog;
437 ARDOUR_UI::pop_back_splash ()
439 if (Splash::instance()) {
440 // Splash::instance()->pop_back();
441 Splash::instance()->hide ();
446 ARDOUR_UI::configure_timeout ()
448 if (last_configure_time == 0) {
449 /* no configure events yet */
453 /* force a gap of 0.5 seconds since the last configure event
456 if (get_microseconds() - last_configure_time < 500000) {
459 have_configure_timeout = false;
460 save_ardour_state ();
466 ARDOUR_UI::configure_handler (GdkEventConfigure* /*conf*/)
468 if (have_configure_timeout) {
469 last_configure_time = get_microseconds();
471 Glib::signal_timeout().connect (sigc::mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
472 have_configure_timeout = true;
479 ARDOUR_UI::set_transport_controllable_state (const XMLNode& node)
481 const XMLProperty* prop;
483 if ((prop = node.property ("roll")) != 0) {
484 roll_controllable->set_id (prop->value());
486 if ((prop = node.property ("stop")) != 0) {
487 stop_controllable->set_id (prop->value());
489 if ((prop = node.property ("goto-start")) != 0) {
490 goto_start_controllable->set_id (prop->value());
492 if ((prop = node.property ("goto-end")) != 0) {
493 goto_end_controllable->set_id (prop->value());
495 if ((prop = node.property ("auto-loop")) != 0) {
496 auto_loop_controllable->set_id (prop->value());
498 if ((prop = node.property ("play-selection")) != 0) {
499 play_selection_controllable->set_id (prop->value());
501 if ((prop = node.property ("rec")) != 0) {
502 rec_controllable->set_id (prop->value());
504 if ((prop = node.property ("shuttle")) != 0) {
505 shuttle_controllable->set_id (prop->value());
510 ARDOUR_UI::get_transport_controllable_state ()
512 XMLNode* node = new XMLNode(X_("TransportControllables"));
515 roll_controllable->id().print (buf, sizeof (buf));
516 node->add_property (X_("roll"), buf);
517 stop_controllable->id().print (buf, sizeof (buf));
518 node->add_property (X_("stop"), buf);
519 goto_start_controllable->id().print (buf, sizeof (buf));
520 node->add_property (X_("goto_start"), buf);
521 goto_end_controllable->id().print (buf, sizeof (buf));
522 node->add_property (X_("goto_end"), buf);
523 auto_loop_controllable->id().print (buf, sizeof (buf));
524 node->add_property (X_("auto_loop"), buf);
525 play_selection_controllable->id().print (buf, sizeof (buf));
526 node->add_property (X_("play_selection"), buf);
527 rec_controllable->id().print (buf, sizeof (buf));
528 node->add_property (X_("rec"), buf);
529 shuttle_controllable->id().print (buf, sizeof (buf));
530 node->add_property (X_("shuttle"), buf);
536 ARDOUR_UI::save_ardour_state ()
538 if (!keyboard || !mixer || !editor) {
542 /* XXX this is all a bit dubious. add_extra_xml() uses
543 a different lifetime model from add_instant_xml().
546 XMLNode* node = new XMLNode (keyboard->get_state());
547 Config->add_extra_xml (*node);
548 Config->add_extra_xml (get_transport_controllable_state());
549 if (_startup && _startup->engine_control() && _startup->engine_control()->was_used()) {
550 Config->add_extra_xml (_startup->engine_control()->get_state());
552 Config->save_state();
553 ui_config->save_state ();
555 XMLNode enode(static_cast<Stateful*>(editor)->get_state());
556 XMLNode mnode(mixer->get_state());
559 _session->add_instant_xml (enode);
560 _session->add_instant_xml (mnode);
562 Config->add_instant_xml (enode);
563 Config->add_instant_xml (mnode);
566 Keyboard::save_keybindings ();
570 ARDOUR_UI::autosave_session ()
572 if (g_main_depth() > 1) {
573 /* inside a recursive main loop,
574 give up because we may not be able to
580 if (!Config->get_periodic_safety_backups()) {
585 _session->maybe_write_autosave();
592 ARDOUR_UI::update_autosave ()
594 ENSURE_GUI_THREAD (*this, &ARDOUR_UI::update_autosave)
596 if (_session && _session->dirty()) {
597 if (_autosave_connection.connected()) {
598 _autosave_connection.disconnect();
601 _autosave_connection = Glib::signal_timeout().connect (sigc::mem_fun (*this, &ARDOUR_UI::autosave_session),
602 Config->get_periodic_safety_backup_interval() * 1000);
605 if (_autosave_connection.connected()) {
606 _autosave_connection.disconnect();
612 ARDOUR_UI::backend_audio_error (bool we_set_params, Gtk::Window* toplevel)
616 title = _("Ardour could not start JACK");
618 title = _("Ardour could not connect to JACK.");
621 MessageDialog win (title,
627 win.set_secondary_text(_("There are several possible reasons:\n\
629 1) You requested audio parameters that are not supported..\n\
630 2) JACK is running as another user.\n\
632 Please consider the possibilities, and perhaps try different parameters."));
634 win.set_secondary_text(_("There are several possible reasons:\n\
636 1) JACK is not running.\n\
637 2) JACK is running as another user, perhaps root.\n\
638 3) There is already another client called \"ardour\".\n\
640 Please consider the possibilities, and perhaps (re)start JACK."));
644 win.set_transient_for (*toplevel);
648 win.add_button (Stock::OK, RESPONSE_CLOSE);
650 win.add_button (Stock::QUIT, RESPONSE_CLOSE);
653 win.set_default_response (RESPONSE_CLOSE);
656 win.set_position (Gtk::WIN_POS_CENTER);
659 /* we just don't care about the result, but we want to block */
665 ARDOUR_UI::startup ()
667 XMLNode* audio_setup = Config->extra_xml ("AudioSetup");
669 if (audio_setup && _startup && _startup->engine_control()) {
670 _startup->engine_control()->set_state (*audio_setup);
673 if (get_session_parameters (true, ARDOUR_COMMAND_LINE::new_session)) {
679 goto_editor_window ();
681 BootMessage (_("Ardour is ready for use"));
686 ARDOUR_UI::no_memory_warning ()
688 XMLNode node (X_("no-memory-warning"));
689 Config->add_instant_xml (node);
693 ARDOUR_UI::check_memory_locking ()
696 /* OS X doesn't support mlockall(2), and so testing for memory locking capability there is pointless */
700 XMLNode* memory_warning_node = Config->instant_xml (X_("no-memory-warning"));
702 if (engine->is_realtime() && memory_warning_node == 0) {
704 struct rlimit limits;
706 long pages, page_size;
708 if ((page_size = sysconf (_SC_PAGESIZE)) < 0 ||(pages = sysconf (_SC_PHYS_PAGES)) < 0) {
711 ram = (int64_t) pages * (int64_t) page_size;
714 if (getrlimit (RLIMIT_MEMLOCK, &limits)) {
718 if (limits.rlim_cur != RLIM_INFINITY) {
720 if (ram == 0 || ((double) limits.rlim_cur / ram) < 0.75) {
723 MessageDialog msg (_("WARNING: Your system has a limit for maximum amount of locked memory. "
724 "This might cause Ardour to run out of memory before your system "
725 "runs out of memory. \n\n"
726 "You can view the memory limit with 'ulimit -l', "
727 "and it is normally controlled by /etc/security/limits.conf"));
729 VBox* vbox = msg.get_vbox();
731 CheckButton cb (_("Do not show this window again"));
733 cb.signal_toggled().connect (sigc::mem_fun (*this, &ARDOUR_UI::no_memory_warning));
735 hbox.pack_start (cb, true, false);
736 vbox->pack_start (hbox);
743 editor->ensure_float (msg);
757 if (_session->transport_rolling()) {
758 _session->request_stop ();
762 if (_session->dirty()) {
763 switch (ask_about_saving_session(_("quit"))) {
768 /* use the default name */
769 if (save_state_canfail ("")) {
770 /* failed - don't quit */
771 MessageDialog msg (*editor,
773 Ardour was unable to save your session.\n\n\
774 If you still wish to quit, please use the\n\n\
775 \"Just quit\" option."));
786 second_connection.disconnect ();
787 point_one_second_connection.disconnect ();
788 point_oh_five_second_connection.disconnect ();
789 point_zero_one_second_connection.disconnect();
791 // _session->set_deletion_in_progress ();
792 _session->remove_pending_capture_state ();
797 ArdourDialog::close_all_dialogs ();
799 save_ardour_state ();
804 ARDOUR_UI::ask_about_saving_session (const string & what)
806 ArdourDialog window (_("ardour: save session?"));
807 Gtk::HBox dhbox; // the hbox for the image and text
808 Gtk::Label prompt_label;
809 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_WARNING, Gtk::ICON_SIZE_DIALOG));
813 msg = string_compose(_("Don't %1"), what);
814 window.add_button (msg, RESPONSE_REJECT);
815 msg = string_compose(_("Just %1"), what);
816 window.add_button (msg, RESPONSE_APPLY);
817 msg = string_compose(_("Save and %1"), what);
818 window.add_button (msg, RESPONSE_ACCEPT);
820 window.set_default_response (RESPONSE_ACCEPT);
822 Gtk::Button noquit_button (msg);
823 noquit_button.set_name ("EditorGTKButton");
828 if (_session->snap_name() == _session->name()) {
831 type = _("snapshot");
833 prompt = string_compose(_("The %1 \"%2\"\nhas not been saved.\n\nAny changes made this time\nwill be lost unless you save it.\n\nWhat do you want to do?"),
834 type, _session->snap_name());
836 prompt_label.set_text (prompt);
837 prompt_label.set_name (X_("PrompterLabel"));
838 prompt_label.set_alignment(ALIGN_LEFT, ALIGN_TOP);
840 dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP);
841 dhbox.set_homogeneous (false);
842 dhbox.pack_start (*dimage, false, false, 5);
843 dhbox.pack_start (prompt_label, true, false, 5);
844 window.get_vbox()->pack_start (dhbox);
846 window.set_name (_("Prompter"));
847 window.set_position (Gtk::WIN_POS_MOUSE);
848 window.set_modal (true);
849 window.set_resizable (false);
855 window.set_keep_above (true);
858 ResponseType r = (ResponseType) window.run();
863 case RESPONSE_ACCEPT: // save and get out of here
865 case RESPONSE_APPLY: // get out of here
875 ARDOUR_UI::every_second ()
878 update_buffer_load ();
879 update_disk_space ();
884 ARDOUR_UI::every_point_one_seconds ()
886 update_speed_display ();
887 RapidScreenUpdate(); /* EMIT_SIGNAL */
892 ARDOUR_UI::every_point_zero_one_seconds ()
894 // august 2007: actual update frequency: 40Hz, not 100Hz
896 SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
901 ARDOUR_UI::update_sample_rate (nframes_t ignored)
905 ENSURE_GUI_THREAD (*this, &ARDOUR_UI::update_sample_rate, ignored)
907 if (!engine->connected()) {
909 snprintf (buf, sizeof (buf), _("disconnected"));
913 nframes_t rate = engine->frame_rate();
915 if (fmod (rate, 1000.0) != 0.0) {
916 snprintf (buf, sizeof (buf), _("%.1f kHz / %4.1f ms"),
917 (float) rate/1000.0f,
918 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
920 snprintf (buf, sizeof (buf), _("%u kHz / %4.1f ms"),
922 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
926 sample_rate_label.set_text (buf);
930 ARDOUR_UI::update_cpu_load ()
933 snprintf (buf, sizeof (buf), _("DSP: %5.1f%%"), engine->get_cpu_load());
934 cpu_load_label.set_text (buf);
938 ARDOUR_UI::update_buffer_load ()
944 c = _session->capture_load ();
945 p = _session->playback_load ();
947 push_buffer_stats (c, p);
949 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"),
950 _session->playback_load(), _session->capture_load());
951 buffer_load_label.set_text (buf);
953 buffer_load_label.set_text ("");
958 ARDOUR_UI::count_recenabled_streams (Route& route)
960 Track* track = dynamic_cast<Track*>(&route);
961 if (track && track->diskstream()->record_enabled()) {
962 rec_enabled_streams += track->n_inputs().n_total();
967 ARDOUR_UI::update_disk_space()
973 nframes_t frames = _session->available_capture_duration();
975 nframes_t fr = _session->frame_rate();
977 if (frames == max_frames) {
978 strcpy (buf, _("Disk: 24hrs+"));
980 rec_enabled_streams = 0;
981 _session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
983 if (rec_enabled_streams) {
984 frames /= rec_enabled_streams;
991 hrs = frames / (fr * 3600);
992 frames -= hrs * fr * 3600;
993 mins = frames / (fr * 60);
994 frames -= mins * fr * 60;
997 snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs);
1000 disk_space_label.set_text (buf);
1002 // An attempt to make the disk space label flash red when space has run out.
1004 if (frames < fr * 60 * 5) {
1005 /* disk_space_box.style ("disk_space_label_empty"); */
1007 /* disk_space_box.style ("disk_space_label"); */
1013 ARDOUR_UI::update_wall_clock ()
1020 tm_now = localtime (&now);
1022 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
1023 wall_clock_label.set_text (buf);
1029 ARDOUR_UI::session_menu (GdkEventButton */*ev*/)
1031 session_popup_menu->popup (0, 0);
1036 ARDOUR_UI::redisplay_recent_sessions ()
1038 std::vector<sys::path> session_directories;
1039 RecentSessionsSorter cmp;
1041 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
1042 recent_session_model->clear ();
1044 ARDOUR::RecentSessions rs;
1045 ARDOUR::read_recent_sessions (rs);
1048 recent_session_display.set_model (recent_session_model);
1052 // sort them alphabetically
1053 sort (rs.begin(), rs.end(), cmp);
1055 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
1056 session_directories.push_back ((*i).second);
1059 for (vector<sys::path>::const_iterator i = session_directories.begin();
1060 i != session_directories.end(); ++i)
1062 std::vector<sys::path> state_file_paths;
1064 // now get available states for this session
1066 get_state_files_in_directory (*i, state_file_paths);
1068 vector<string*>* states;
1069 vector<const gchar*> item;
1070 string fullpath = (*i).to_string();
1072 /* remove any trailing / */
1074 if (fullpath[fullpath.length()-1] == '/') {
1075 fullpath = fullpath.substr (0, fullpath.length()-1);
1078 /* check whether session still exists */
1079 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
1080 /* session doesn't exist */
1081 cerr << "skipping non-existent session " << fullpath << endl;
1085 /* now get available states for this session */
1087 if ((states = Session::possible_states (fullpath)) == 0) {
1088 /* no state file? */
1092 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
1094 Gtk::TreeModel::Row row = *(recent_session_model->append());
1096 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
1097 row[recent_session_columns.fullpath] = fullpath;
1099 if (state_file_names.size() > 1) {
1103 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
1104 i2 != state_file_names.end(); ++i2)
1107 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
1109 child_row[recent_session_columns.visible_name] = *i2;
1110 child_row[recent_session_columns.fullpath] = fullpath;
1115 recent_session_display.set_model (recent_session_model);
1119 ARDOUR_UI::build_session_selector ()
1121 session_selector_window = new ArdourDialog (_("Recent Sessions"));
1123 Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
1125 session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
1126 session_selector_window->add_button (Stock::OPEN, RESPONSE_ACCEPT);
1127 session_selector_window->set_default_response (RESPONSE_ACCEPT);
1128 recent_session_model = TreeStore::create (recent_session_columns);
1129 recent_session_display.set_model (recent_session_model);
1130 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1131 recent_session_display.set_headers_visible (false);
1132 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
1133 recent_session_display.signal_row_activated().connect (sigc::mem_fun (*this, &ARDOUR_UI::recent_session_row_activated));
1135 scroller->add (recent_session_display);
1136 scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1138 session_selector_window->set_name ("SessionSelectorWindow");
1139 session_selector_window->set_size_request (200, 400);
1140 session_selector_window->get_vbox()->pack_start (*scroller);
1142 recent_session_display.show();
1144 //session_selector_window->get_vbox()->show();
1148 ARDOUR_UI::recent_session_row_activated (const TreePath& /*path*/, TreeViewColumn* /*col*/)
1150 session_selector_window->response (RESPONSE_ACCEPT);
1154 ARDOUR_UI::open_recent_session ()
1156 bool can_return = (_session != 0);
1158 if (session_selector_window == 0) {
1159 build_session_selector ();
1162 redisplay_recent_sessions ();
1166 session_selector_window->set_position (WIN_POS_MOUSE);
1168 ResponseType r = (ResponseType) session_selector_window->run ();
1171 case RESPONSE_ACCEPT:
1175 session_selector_window->hide();
1182 if (recent_session_display.get_selection()->count_selected_rows() == 0) {
1186 session_selector_window->hide();
1188 Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
1190 if (i == recent_session_model->children().end()) {
1194 Glib::ustring path = (*i)[recent_session_columns.fullpath];
1195 Glib::ustring state = (*i)[recent_session_columns.visible_name];
1197 _session_is_new = false;
1199 if (load_session (path, state) == 0) {
1208 ARDOUR_UI::check_audioengine ()
1211 if (!engine->connected()) {
1212 MessageDialog msg (_("Ardour is not connected to JACK\n"
1213 "You cannot open or close sessions in this condition"));
1225 ARDOUR_UI::open_session ()
1227 if (!check_audioengine()) {
1232 /* popup selector window */
1234 if (open_session_selector == 0) {
1236 /* ardour sessions are folders */
1238 open_session_selector = new Gtk::FileChooserDialog (_("Open Session"), FILE_CHOOSER_ACTION_OPEN);
1239 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1240 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
1241 open_session_selector->set_default_response(Gtk::RESPONSE_ACCEPT);
1243 FileFilter session_filter;
1244 session_filter.add_pattern ("*.ardour");
1245 session_filter.set_name (_("Ardour sessions"));
1246 open_session_selector->add_filter (session_filter);
1247 open_session_selector->set_filter (session_filter);
1250 int response = open_session_selector->run();
1251 open_session_selector->hide ();
1254 case RESPONSE_ACCEPT:
1257 open_session_selector->hide();
1261 open_session_selector->hide();
1262 string session_path = open_session_selector->get_filename();
1266 if (session_path.length() > 0) {
1267 if (ARDOUR::find_session (session_path, path, name, isnew) == 0) {
1268 _session_is_new = isnew;
1269 load_session (path, name);
1276 ARDOUR_UI::session_add_midi_route (bool disk, RouteGroup* route_group, uint32_t how_many)
1278 list<boost::shared_ptr<MidiTrack> > tracks;
1280 if (_session == 0) {
1281 warning << _("You cannot add a track without a session already loaded.") << endmsg;
1288 tracks = _session->new_midi_track (ARDOUR::Normal, route_group, how_many);
1290 if (tracks.size() != how_many) {
1291 if (how_many == 1) {
1292 error << _("could not create a new midi track") << endmsg;
1294 error << string_compose (_("could not create %1 new midi tracks"), how_many) << endmsg;
1298 if ((route = _session->new_midi_route ()) == 0) {
1299 error << _("could not create new midi bus") << endmsg;
1305 MessageDialog msg (*editor,
1306 _("There are insufficient JACK ports available\n\
1307 to create a new track or bus.\n\
1308 You should save Ardour, exit and\n\
1309 restart JACK with more ports."));
1316 ARDOUR_UI::session_add_audio_route (bool track, bool aux, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1318 list<boost::shared_ptr<AudioTrack> > tracks;
1321 if (_session == 0) {
1322 warning << _("You cannot add a track or bus without a session already loaded.") << endmsg;
1328 tracks = _session->new_audio_track (input_channels, output_channels, mode, route_group, how_many);
1330 if (tracks.size() != how_many) {
1331 if (how_many == 1) {
1332 error << _("could not create a new audio track") << endmsg;
1334 error << string_compose (_("could only create %1 of %2 new audio %3"),
1335 tracks.size(), how_many, (track ? _("tracks") : _("busses"))) << endmsg;
1341 routes = _session->new_audio_route (aux, input_channels, output_channels, route_group, how_many);
1343 if (routes.size() != how_many) {
1344 if (how_many == 1) {
1345 error << _("could not create a new audio track") << endmsg;
1347 error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
1353 if (need_control_room_outs) {
1359 route->set_stereo_control_outs (control_lr_channels);
1360 route->control_outs()->set_stereo_pan (pans, this);
1362 #endif /* CONTROLOUTS */
1366 MessageDialog msg (*editor,
1367 _("There are insufficient JACK ports available\n\
1368 to create a new track or bus.\n\
1369 You should save Ardour, exit and\n\
1370 restart JACK with more ports."));
1377 ARDOUR_UI::do_transport_locate (nframes_t new_position)
1379 nframes_t _preroll = 0;
1382 // XXX CONFIG_CHANGE FIX - requires AnyTime handling
1383 // _preroll = _session->convert_to_frames_at (new_position, Config->get_preroll());
1385 if (new_position > _preroll) {
1386 new_position -= _preroll;
1391 _session->request_locate (new_position);
1396 ARDOUR_UI::transport_goto_start ()
1399 _session->goto_start();
1401 /* force displayed area in editor to start no matter
1402 what "follow playhead" setting is.
1406 editor->center_screen (_session->current_start_frame ());
1412 ARDOUR_UI::transport_goto_zero ()
1415 _session->request_locate (0);
1418 /* force displayed area in editor to start no matter
1419 what "follow playhead" setting is.
1423 editor->reset_x_origin (0);
1429 ARDOUR_UI::transport_goto_wallclock ()
1431 if (_session && editor) {
1438 localtime_r (&now, &tmnow);
1440 frames = tmnow.tm_hour * (60 * 60 * _session->frame_rate());
1441 frames += tmnow.tm_min * (60 * _session->frame_rate());
1442 frames += tmnow.tm_sec * _session->frame_rate();
1444 _session->request_locate (frames);
1446 /* force displayed area in editor to start no matter
1447 what "follow playhead" setting is.
1451 editor->center_screen (frames);
1457 ARDOUR_UI::transport_goto_end ()
1460 nframes_t const frame = _session->current_end_frame();
1461 _session->request_locate (frame);
1463 /* force displayed area in editor to start no matter
1464 what "follow playhead" setting is.
1468 editor->center_screen (frame);
1474 ARDOUR_UI::transport_stop ()
1480 if (_session->is_auditioning()) {
1481 _session->cancel_audition ();
1485 _session->request_stop ();
1489 ARDOUR_UI::transport_stop_and_forget_capture ()
1492 _session->request_stop (true);
1497 ARDOUR_UI::remove_last_capture()
1500 editor->remove_last_capture();
1505 ARDOUR_UI::transport_record (bool roll)
1509 switch (_session->record_status()) {
1510 case Session::Disabled:
1511 if (_session->ntracks() == 0) {
1512 MessageDialog msg (*editor, _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu."));
1516 _session->maybe_enable_record ();
1521 case Session::Recording:
1523 _session->request_stop();
1525 _session->disable_record (false, true);
1529 case Session::Enabled:
1530 _session->disable_record (false, true);
1533 //cerr << "ARDOUR_UI::transport_record () called roll = " << roll << " _session->record_status() = " << _session->record_status() << endl;
1537 ARDOUR_UI::transport_roll ()
1543 if (_session->is_auditioning()) {
1547 if (_session->config.get_external_sync()) {
1548 switch (_session->config.get_sync_source()) {
1552 /* transport controlled by the master */
1557 bool rolling = _session->transport_rolling();
1559 if (_session->get_play_loop()) {
1560 _session->request_play_loop (false, true);
1561 } else if (_session->get_play_range ()) {
1562 _session->request_play_range (false, true);
1566 _session->request_transport_speed (1.0f);
1569 map_transport_state ();
1573 ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode)
1580 if (_session->is_auditioning()) {
1581 _session->cancel_audition ();
1585 if (_session->config.get_external_sync()) {
1586 switch (_session->config.get_sync_source()) {
1590 /* transport controlled by the master */
1595 bool rolling = _session->transport_rolling();
1596 bool affect_transport = true;
1598 if (rolling && roll_out_of_bounded_mode) {
1599 /* drop out of loop/range playback but leave transport rolling */
1600 if (_session->get_play_loop()) {
1601 if (Config->get_seamless_loop()) {
1602 /* the disk buffers contain copies of the loop - we can't
1603 just keep playing, so stop the transport. the user
1604 can restart as they wish.
1606 affect_transport = true;
1608 /* disk buffers are normal, so we can keep playing */
1609 affect_transport = false;
1611 _session->request_play_loop (false, true);
1612 } else if (_session->get_play_range ()) {
1613 affect_transport = false;
1614 _session->request_play_range (0, true);
1618 if (affect_transport) {
1620 _session->request_stop (with_abort, true);
1622 _session->request_transport_speed (1.0f);
1626 map_transport_state ();
1630 ARDOUR_UI::toggle_session_auto_loop ()
1633 if (_session->get_play_loop()) {
1634 if (_session->transport_rolling()) {
1635 Location * looploc = _session->locations()->auto_loop_location();
1637 _session->request_locate (looploc->start(), true);
1640 _session->request_play_loop (false);
1643 Location * looploc = _session->locations()->auto_loop_location();
1645 _session->request_play_loop (true);
1652 ARDOUR_UI::transport_play_selection ()
1658 editor->play_selection ();
1662 ARDOUR_UI::transport_rewind (int option)
1664 float current_transport_speed;
1667 current_transport_speed = _session->transport_speed();
1669 if (current_transport_speed >= 0.0f) {
1672 _session->request_transport_speed (-1.0f);
1675 _session->request_transport_speed (-4.0f);
1678 _session->request_transport_speed (-0.5f);
1683 _session->request_transport_speed (current_transport_speed * 1.5f);
1689 ARDOUR_UI::transport_forward (int option)
1691 float current_transport_speed;
1694 current_transport_speed = _session->transport_speed();
1696 if (current_transport_speed <= 0.0f) {
1699 _session->request_transport_speed (1.0f);
1702 _session->request_transport_speed (4.0f);
1705 _session->request_transport_speed (0.5f);
1710 _session->request_transport_speed (current_transport_speed * 1.5f);
1717 ARDOUR_UI::toggle_record_enable (uint32_t dstream)
1719 if (_session == 0) {
1723 boost::shared_ptr<Route> r;
1725 if ((r = _session->route_by_remote_id (dstream)) != 0) {
1729 if ((t = dynamic_cast<Track*>(r.get())) != 0) {
1730 t->diskstream()->set_record_enabled (!t->diskstream()->record_enabled());
1733 if (_session == 0) {
1739 ARDOUR_UI::map_transport_state ()
1741 ENSURE_GUI_THREAD (*this, &ARDOUR_UI::map_transport_state)
1744 auto_loop_button.set_visual_state (0);
1745 play_selection_button.set_visual_state (0);
1746 roll_button.set_visual_state (0);
1747 stop_button.set_visual_state (1);
1751 float sp = _session->transport_speed();
1754 shuttle_fract = SHUTTLE_FRACT_SPEED1; /* speed = 1.0, believe it or not */
1755 shuttle_box.queue_draw ();
1756 } else if (sp == 0.0f) {
1758 shuttle_box.queue_draw ();
1759 update_disk_space ();
1764 if (_session->get_play_range()) {
1766 play_selection_button.set_visual_state (1);
1767 roll_button.set_visual_state (0);
1768 auto_loop_button.set_visual_state (0);
1770 } else if (_session->get_play_loop ()) {
1772 auto_loop_button.set_visual_state (1);
1773 play_selection_button.set_visual_state (0);
1774 roll_button.set_visual_state (0);
1778 roll_button.set_visual_state (1);
1779 play_selection_button.set_visual_state (0);
1780 auto_loop_button.set_visual_state (0);
1783 stop_button.set_visual_state (0);
1787 stop_button.set_visual_state (1);
1788 roll_button.set_visual_state (0);
1789 play_selection_button.set_visual_state (0);
1790 auto_loop_button.set_visual_state (0);
1796 ARDOUR_UI::engine_stopped ()
1798 ENSURE_GUI_THREAD (*this, &ARDOUR_UI::engine_stopped)
1799 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1800 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1804 ARDOUR_UI::engine_running ()
1806 ENSURE_GUI_THREAD (*this, &ARDOUR_UI::engine_running)
1807 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true);
1808 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
1810 Glib::RefPtr<Action> action;
1811 const char* action_name = 0;
1813 switch (engine->frames_per_cycle()) {
1815 action_name = X_("JACKLatency32");
1818 action_name = X_("JACKLatency64");
1821 action_name = X_("JACKLatency128");
1824 action_name = X_("JACKLatency512");
1827 action_name = X_("JACKLatency1024");
1830 action_name = X_("JACKLatency2048");
1833 action_name = X_("JACKLatency4096");
1836 action_name = X_("JACKLatency8192");
1839 /* XXX can we do anything useful ? */
1845 action = ActionManager::get_action (X_("JACK"), action_name);
1848 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic (action);
1849 ract->set_active ();
1855 ARDOUR_UI::engine_halted ()
1857 ENSURE_GUI_THREAD (*this, &ARDOUR_UI::engine_halted)
1859 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1860 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1862 update_sample_rate (0);
1864 MessageDialog msg (*editor,
1866 JACK has either been shutdown or it\n\
1867 disconnected Ardour because Ardour\n\
1868 was not fast enough. Try to restart\n\
1869 JACK, reconnect and save the session."));
1875 ARDOUR_UI::do_engine_start ()
1883 error << _("Unable to start the session running")
1893 ARDOUR_UI::setup_theme ()
1895 theme_manager->setup_theme();
1899 ARDOUR_UI::update_clocks ()
1901 if (!editor || !editor->dragging_playhead()) {
1902 Clock (_session->audible_frame(), false, editor->get_preferred_edit_position()); /* EMIT_SIGNAL */
1907 ARDOUR_UI::start_clocking ()
1909 clock_signal_connection = RapidScreenUpdate.connect (sigc::mem_fun(*this, &ARDOUR_UI::update_clocks));
1913 ARDOUR_UI::stop_clocking ()
1915 clock_signal_connection.disconnect ();
1919 ARDOUR_UI::toggle_clocking ()
1922 if (clock_button.get_active()) {
1931 ARDOUR_UI::_blink (void *arg)
1934 ((ARDOUR_UI *) arg)->blink ();
1941 Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
1945 ARDOUR_UI::start_blinking ()
1947 /* Start the blink signal. Everybody with a blinking widget
1948 uses Blink to drive the widget's state.
1951 if (blink_timeout_tag < 0) {
1953 blink_timeout_tag = g_timeout_add (240, _blink, this);
1958 ARDOUR_UI::stop_blinking ()
1960 if (blink_timeout_tag >= 0) {
1961 g_source_remove (blink_timeout_tag);
1962 blink_timeout_tag = -1;
1967 /** Ask the user for the name of a new shapshot and then take it.
1970 ARDOUR_UI::snapshot_session ()
1972 ArdourPrompter prompter (true);
1976 struct tm local_time;
1979 localtime_r (&n, &local_time);
1980 strftime (timebuf, sizeof(timebuf), "%FT%T", &local_time);
1982 prompter.set_name ("Prompter");
1983 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1984 prompter.set_title (_("Take Snapshot"));
1985 prompter.set_prompt (_("Name of New Snapshot"));
1986 prompter.set_initial_text (timebuf);
1988 switch (prompter.run()) {
1989 case RESPONSE_ACCEPT:
1991 prompter.get_result (snapname);
1993 bool do_save = (snapname.length() != 0);
1995 vector<sys::path> p;
1996 get_state_files_in_directory (_session->session_directory().root_path(), p);
1997 vector<string> n = get_file_names_no_extension (p);
1998 if (find (n.begin(), n.end(), snapname) != n.end()) {
2000 ArdourDialog confirm (_("Confirm snapshot overwrite"), true);
2001 Label m (_("A snapshot already exists with that name. Do you want to overwrite it?"));
2002 confirm.get_vbox()->pack_start (m, true, true);
2003 confirm.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
2004 confirm.add_button (_("Overwrite"), Gtk::RESPONSE_ACCEPT);
2005 confirm.show_all ();
2006 switch (confirm.run()) {
2007 case RESPONSE_CANCEL:
2013 save_state (snapname);
2024 ARDOUR_UI::save_state (const string & name)
2026 (void) save_state_canfail (name);
2030 ARDOUR_UI::save_state_canfail (string name)
2035 if (name.length() == 0) {
2036 name = _session->snap_name();
2039 if ((ret = _session->save_state (name)) != 0) {
2043 save_ardour_state (); /* XXX cannot fail? yeah, right ... */
2048 ARDOUR_UI::primary_clock_value_changed ()
2051 _session->request_locate (primary_clock.current_time ());
2056 ARDOUR_UI::big_clock_value_changed ()
2059 _session->request_locate (big_clock.current_time ());
2064 ARDOUR_UI::secondary_clock_value_changed ()
2067 _session->request_locate (secondary_clock.current_time ());
2072 ARDOUR_UI::transport_rec_enable_blink (bool onoff)
2074 if (_session == 0) {
2078 Session::RecordState const r = _session->record_status ();
2079 bool const h = _session->have_rec_enabled_diskstream ();
2081 if (r == Session::Enabled || (r == Session::Recording && !h)) {
2083 rec_button.set_visual_state (2);
2085 rec_button.set_visual_state (0);
2087 } else if (r == Session::Recording && h) {
2088 rec_button.set_visual_state (1);
2090 rec_button.set_visual_state (0);
2095 ARDOUR_UI::save_template ()
2097 ArdourPrompter prompter (true);
2100 if (!check_audioengine()) {
2104 prompter.set_name (X_("Prompter"));
2105 prompter.set_title (_("Save Mix Template"));
2106 prompter.set_prompt (_("Name for mix template:"));
2107 prompter.set_initial_text(_session->name() + _("-template"));
2108 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
2110 switch (prompter.run()) {
2111 case RESPONSE_ACCEPT:
2112 prompter.get_result (name);
2114 if (name.length()) {
2115 _session->save_template (name);
2125 ARDOUR_UI::edit_metadata ()
2127 SessionMetadataEditor dialog;
2128 dialog.set_session (_session);
2129 editor->ensure_float (dialog);
2134 ARDOUR_UI::import_metadata ()
2136 SessionMetadataImporter dialog;
2137 dialog.set_session (_session);
2138 editor->ensure_float (dialog);
2143 ARDOUR_UI::fontconfig_dialog ()
2146 /* X11 users will always have fontconfig info around, but new GTK-OSX users
2147 may not and it can take a while to build it. Warn them.
2150 Glib::ustring fontconfig = Glib::build_filename (Glib::get_home_dir(), ".fontconfig");
2152 if (!Glib::file_test (fontconfig, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
2153 MessageDialog msg (*_startup,
2154 _("Welcome to Ardour.\n\n"
2155 "The program will take a bit longer to start up\n"
2156 "while the system fonts are checked.\n\n"
2157 "This will only be done once, and you will\n"
2158 "not see this message again\n"),
2171 ARDOUR_UI::parse_cmdline_path (const Glib::ustring& cmdline_path, Glib::ustring& session_name, Glib::ustring& session_path, bool& existing_session)
2173 existing_session = false;
2175 if (Glib::file_test (cmdline_path, Glib::FILE_TEST_IS_DIR)) {
2176 session_path = cmdline_path;
2177 existing_session = true;
2178 } else if (Glib::file_test (cmdline_path, Glib::FILE_TEST_IS_REGULAR)) {
2179 session_path = Glib::path_get_dirname (string (cmdline_path));
2180 existing_session = true;
2182 /* it doesn't exist, assume the best */
2183 session_path = Glib::path_get_dirname (string (cmdline_path));
2186 session_name = basename_nosuffix (string (cmdline_path));
2190 ARDOUR_UI::load_cmdline_session (const Glib::ustring& session_name, const Glib::ustring& session_path, bool& existing_session)
2192 /* when this is called, the backend audio system must be running */
2194 /* the main idea here is to deal with the fact that a cmdline argument for the session
2195 can be interpreted in different ways - it could be a directory or a file, and before
2196 we load, we need to know both the session directory and the snapshot (statefile) within it
2197 that we are supposed to use.
2200 if (session_name.length() == 0 || session_path.length() == 0) {
2204 if (Glib::file_test (session_path, Glib::FILE_TEST_IS_DIR)) {
2206 Glib::ustring predicted_session_file;
2208 predicted_session_file = session_path;
2209 predicted_session_file += '/';
2210 predicted_session_file += session_name;
2211 predicted_session_file += ARDOUR::statefile_suffix;
2213 if (Glib::file_test (predicted_session_file, Glib::FILE_TEST_EXISTS)) {
2214 existing_session = true;
2217 } else if (Glib::file_test (session_path, Glib::FILE_TEST_EXISTS)) {
2219 if (session_path.find (ARDOUR::statefile_suffix) == session_path.length() - 7) {
2220 /* existing .ardour file */
2221 existing_session = true;
2225 existing_session = false;
2228 /* lets just try to load it */
2230 if (create_engine ()) {
2231 backend_audio_error (false, _startup);
2235 return load_session (session_path, session_name);
2239 ARDOUR_UI::ask_about_loading_existing_session (const Glib::ustring& session_path)
2241 Glib::ustring str = string_compose (_("This session\n%1\nalready exists. Do you want to open it?"), session_path);
2243 MessageDialog msg (str,
2245 Gtk::MESSAGE_WARNING,
2246 Gtk::BUTTONS_YES_NO,
2250 msg.set_name (X_("OpenExistingDialog"));
2251 msg.set_title (_("Open Existing Session"));
2252 msg.set_wmclass (X_("existing_session"), "Ardour");
2253 msg.set_position (Gtk::WIN_POS_MOUSE);
2256 switch (msg.run()) {
2265 ARDOUR_UI::build_session_from_nsd (const Glib::ustring& session_path, const Glib::ustring& session_name)
2270 AutoConnectOption iconnect;
2271 AutoConnectOption oconnect;
2275 if (Profile->get_sae()) {
2279 iconnect = AutoConnectPhysical;
2280 oconnect = AutoConnectMaster;
2281 nphysin = 0; // use all available
2282 nphysout = 0; // use all available
2286 /* get settings from advanced section of NSD */
2288 if (_startup->create_control_bus()) {
2289 cchns = (uint32_t) _startup->control_channel_count();
2294 if (_startup->create_master_bus()) {
2295 mchns = (uint32_t) _startup->master_channel_count();
2300 if (_startup->connect_inputs()) {
2301 iconnect = AutoConnectPhysical;
2303 iconnect = AutoConnectOption (0);
2306 /// @todo some minor tweaks.
2308 oconnect = AutoConnectOption (0);
2310 if (_startup->connect_outputs ()) {
2311 if (_startup->connect_outs_to_master()) {
2312 oconnect = AutoConnectMaster;
2313 } else if (_startup->connect_outs_to_physical()) {
2314 oconnect = AutoConnectPhysical;
2318 nphysin = (uint32_t) _startup->input_limit_count();
2319 nphysout = (uint32_t) _startup->output_limit_count();
2322 if (build_session (session_path,
2330 engine->frame_rate() * 60 * 5)) {
2339 ARDOUR_UI::idle_load (const Glib::ustring& path)
2342 if (Glib::file_test (path, Glib::FILE_TEST_IS_DIR)) {
2343 /* /path/to/foo => /path/to/foo, foo */
2344 load_session (path, basename_nosuffix (path));
2346 /* /path/to/foo/foo.ardour => /path/to/foo, foo */
2347 load_session (Glib::path_get_dirname (path), basename_nosuffix (path));
2351 ARDOUR_COMMAND_LINE::session_name = path;
2354 * new_session_dialog doens't exist in A3
2355 * Try to remove all references to it to
2356 * see if it will compile. NOTE: this will
2357 * likely cause a runtime issue is my somewhat
2361 //if (new_session_dialog) {
2364 /* make it break out of Dialog::run() and
2368 //new_session_dialog->response (1);
2374 ARDOUR_UI::end_loading_messages ()
2380 ARDOUR_UI::loading_message (const std::string& /*msg*/)
2383 // splash->message (msg);
2387 /** @param quit_on_cancel true if exit() should be called if the user clicks `cancel' in the new session dialog */
2389 ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new)
2391 Glib::ustring session_name;
2392 Glib::ustring session_path;
2393 Glib::ustring template_name;
2395 bool likely_new = false;
2399 if (!should_be_new && !ARDOUR_COMMAND_LINE::session_name.empty()) {
2401 /* if they named a specific statefile, use it, otherwise they are
2402 just giving a session folder, and we want to use it as is
2403 to find the session.
2406 if (ARDOUR_COMMAND_LINE::session_name.find (statefile_suffix) != string::npos) {
2407 session_path = Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name);
2409 session_path = ARDOUR_COMMAND_LINE::session_name;
2412 session_name = Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name);
2416 bool const apply = run_startup (should_be_new);
2418 if (quit_on_cancel) {
2425 /* if we run the startup dialog again, offer more than just "new session" */
2427 should_be_new = false;
2429 session_name = _startup->session_name (likely_new);
2431 /* this shouldn't happen, but we catch it just in case it does */
2433 if (session_name.empty()) {
2436 if (_startup->use_session_template()) {
2437 template_name = _startup->session_template_name();
2438 _session_is_new = true;
2441 if (session_name[0] == '/' ||
2442 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
2443 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
2445 session_path = Glib::path_get_dirname (session_name);
2446 session_name = Glib::path_get_basename (session_name);
2450 session_path = _startup->session_folder();
2454 if (create_engine ()) {
2458 if (Glib::file_test (session_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
2462 Glib::ustring existing = Glib::build_filename (session_path, session_name);
2464 if (!ask_about_loading_existing_session (existing)) {
2465 ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
2470 _session_is_new = false;
2475 MessageDialog msg (string_compose (_("There is no existing session at \"%1\""), session_path));
2477 ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
2481 _session_is_new = true;
2484 if (likely_new && template_name.empty()) {
2486 ret = build_session_from_nsd (session_path, session_name);
2490 ret = load_session (session_path, session_name, template_name);
2491 if (!ARDOUR_COMMAND_LINE::immediate_save.empty()) {
2492 _session->save_state (ARDOUR_COMMAND_LINE::immediate_save, false);
2502 ARDOUR_UI::close_session()
2504 if (!check_audioengine()) {
2508 unload_session (true);
2510 ARDOUR_COMMAND_LINE::session_name = "";
2511 get_session_parameters (true, false);
2515 ARDOUR_UI::load_session (const Glib::ustring& path, const Glib::ustring& snap_name, Glib::ustring mix_template)
2517 Session *new_session;
2521 session_loaded = false;
2523 if (!check_audioengine()) {
2527 unload_status = unload_session ();
2529 if (unload_status < 0) {
2531 } else if (unload_status > 0) {
2536 loading_message (_("Please wait while Ardour loads your session"));
2539 new_session = new Session (*engine, path, snap_name, mix_template);
2542 /* this one is special */
2544 catch (AudioEngine::PortRegistrationFailure& err) {
2546 MessageDialog msg (err.what(),
2549 Gtk::BUTTONS_CLOSE);
2551 msg.set_title (_("Port Registration Error"));
2552 msg.set_secondary_text (_("Click the Close button to try again."));
2553 msg.set_position (Gtk::WIN_POS_CENTER);
2557 int response = msg.run ();
2562 case RESPONSE_CANCEL:
2572 MessageDialog msg (string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name),
2575 Gtk::BUTTONS_CLOSE);
2577 msg.set_title (_("Loading Error"));
2578 msg.set_secondary_text (_("Click the Close button to try again."));
2579 msg.set_position (Gtk::WIN_POS_CENTER);
2583 int response = msg.run ();
2588 case RESPONSE_CANCEL:
2596 set_session (new_session);
2598 session_loaded = true;
2600 goto_editor_window ();
2603 _session->set_clean ();
2614 ARDOUR_UI::build_session (const Glib::ustring& path, const Glib::ustring& snap_name,
2615 uint32_t control_channels,
2616 uint32_t master_channels,
2617 AutoConnectOption input_connect,
2618 AutoConnectOption output_connect,
2621 nframes_t initial_length)
2623 Session *new_session;
2626 if (!check_audioengine()) {
2630 session_loaded = false;
2632 x = unload_session ();
2640 _session_is_new = true;
2643 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
2644 control_channels, master_channels, nphysin, nphysout, initial_length);
2649 MessageDialog msg (string_compose(_("Could not create session in \"%1\""), path));
2655 set_session (new_session);
2657 session_loaded = true;
2659 new_session->save_state(new_session->name());
2668 editor->show_window ();
2679 ARDOUR_UI::show_about ()
2683 about->signal_response().connect(sigc::mem_fun (*this, &ARDOUR_UI::about_signal_response) );
2690 ARDOUR_UI::hide_about ()
2693 about->get_window()->set_cursor ();
2699 ARDOUR_UI::about_signal_response (int /*response*/)
2705 ARDOUR_UI::show_splash ()
2709 splash = new Splash;
2717 splash->queue_draw ();
2718 splash->get_window()->process_updates (true);
2723 ARDOUR_UI::hide_splash ()
2731 ARDOUR_UI::display_cleanup_results (ARDOUR::CleanupReport& rep, const gchar* list_title,
2732 const string& plural_msg, const string& singular_msg)
2736 removed = rep.paths.size();
2739 MessageDialog msgd (*editor,
2740 _("No audio files were ready for cleanup"),
2743 (Gtk::ButtonsType)(Gtk::BUTTONS_OK) );
2744 msgd.set_secondary_text (_("If this seems suprising, \n\
2745 check for any existing snapshots.\n\
2746 These may still include regions that\n\
2747 require some unused files to continue to exist."));
2753 ArdourDialog results (_("ardour: cleanup"), true, false);
2755 struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
2756 CleanupResultsModelColumns() {
2760 Gtk::TreeModelColumn<Glib::ustring> visible_name;
2761 Gtk::TreeModelColumn<Glib::ustring> fullpath;
2765 CleanupResultsModelColumns results_columns;
2766 Glib::RefPtr<Gtk::ListStore> results_model;
2767 Gtk::TreeView results_display;
2769 results_model = ListStore::create (results_columns);
2770 results_display.set_model (results_model);
2771 results_display.append_column (list_title, results_columns.visible_name);
2773 results_display.set_name ("CleanupResultsList");
2774 results_display.set_headers_visible (true);
2775 results_display.set_headers_clickable (false);
2776 results_display.set_reorderable (false);
2778 Gtk::ScrolledWindow list_scroller;
2781 Gtk::HBox dhbox; // the hbox for the image and text
2782 Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
2783 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO, Gtk::ICON_SIZE_DIALOG));
2785 dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
2787 const string dead_sound_directory = _session->session_directory().dead_sound_path().to_string();
2793 %1 - number of files removed
2794 %2 - location of "dead_sounds"
2795 %3 - size of files affected
2796 %4 - prefix for "bytes" to produce sensible results (e.g. mega, kilo, giga)
2799 const char* bprefix;
2801 if (rep.space < 1048576.0f) {
2802 bprefix = X_("kilo");
2803 } else if (rep.space < 1048576.0f * 1000) {
2804 bprefix = X_("mega");
2806 bprefix = X_("giga");
2810 txt.set_text (string_compose (plural_msg, removed, dead_sound_directory, (float) rep.space / 1024.0f, bprefix));
2812 txt.set_text (string_compose (singular_msg, removed, dead_sound_directory, (float) rep.space / 1024.0f, bprefix));
2815 dhbox.pack_start (*dimage, true, false, 5);
2816 dhbox.pack_start (txt, true, false, 5);
2818 for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2819 TreeModel::Row row = *(results_model->append());
2820 row[results_columns.visible_name] = *i;
2821 row[results_columns.fullpath] = *i;
2824 list_scroller.add (results_display);
2825 list_scroller.set_size_request (-1, 150);
2826 list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2828 dvbox.pack_start (dhbox, true, false, 5);
2829 dvbox.pack_start (list_scroller, true, false, 5);
2830 ddhbox.pack_start (dvbox, true, false, 5);
2832 results.get_vbox()->pack_start (ddhbox, true, false, 5);
2833 results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
2834 results.set_default_response (RESPONSE_CLOSE);
2835 results.set_position (Gtk::WIN_POS_MOUSE);
2837 results_display.show();
2838 list_scroller.show();
2845 //results.get_vbox()->show();
2846 results.set_resizable (false);
2853 ARDOUR_UI::cleanup ()
2855 if (_session == 0) {
2856 /* shouldn't happen: menu item is insensitive */
2861 MessageDialog checker (_("Are you sure you want to cleanup?"),
2863 Gtk::MESSAGE_QUESTION,
2864 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
2866 checker.set_secondary_text(_("Cleanup is a destructive operation.\n\
2867 ALL undo/redo information will be lost if you cleanup.\n\
2868 After cleanup, unused audio files will be moved to a \
2869 \"dead sounds\" location."));
2871 checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2872 checker.add_button (_("Clean Up"), RESPONSE_ACCEPT);
2873 checker.set_default_response (RESPONSE_CANCEL);
2875 checker.set_name (_("CleanupDialog"));
2876 checker.set_wmclass (X_("ardour_cleanup"), "Ardour");
2877 checker.set_position (Gtk::WIN_POS_MOUSE);
2879 switch (checker.run()) {
2880 case RESPONSE_ACCEPT:
2886 ARDOUR::CleanupReport rep;
2888 editor->prepare_for_cleanup ();
2890 /* do not allow flush until a session is reloaded */
2892 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
2894 act->set_sensitive (false);
2897 if (_session->cleanup_sources (rep)) {
2898 editor->finish_cleanup ();
2902 editor->finish_cleanup ();
2905 display_cleanup_results (rep,
2908 The following %1 files were not in use and \n\
2909 have been moved to:\n\
2911 Flushing the wastebasket will \n\
2912 release an additional\n\
2913 %3 %4bytes of disk space.\n"),
2915 The following file was not in use and \n \
2916 has been moved to:\n \
2918 Flushing the wastebasket will \n\
2919 release an additional\n\
2920 %3 %4bytes of disk space.\n"
2926 ARDOUR_UI::flush_trash ()
2928 if (_session == 0) {
2929 /* shouldn't happen: menu item is insensitive */
2933 ARDOUR::CleanupReport rep;
2935 if (_session->cleanup_trash_sources (rep)) {
2939 display_cleanup_results (rep,
2941 _("The following %1 files were deleted from\n\
2943 releasing %3 %4bytes of disk space"),
2944 _("The following file was deleted from\n\
2946 releasing %3 %4bytes of disk space"));
2950 ARDOUR_UI::add_route (Gtk::Window* float_window)
2958 if (add_route_dialog == 0) {
2959 add_route_dialog = new AddRouteDialog (_session);
2961 add_route_dialog->set_transient_for (*float_window);
2965 if (add_route_dialog->is_visible()) {
2966 /* we're already doing this */
2970 ResponseType r = (ResponseType) add_route_dialog->run ();
2972 add_route_dialog->hide();
2975 case RESPONSE_ACCEPT:
2982 if ((count = add_route_dialog->count()) <= 0) {
2986 string template_path = add_route_dialog->track_template();
2988 if (!template_path.empty()) {
2989 _session->new_route_from_template (count, template_path);
2993 uint32_t input_chan = add_route_dialog->channels ();
2994 uint32_t output_chan;
2995 string name_template = add_route_dialog->name_template ();
2996 bool track = add_route_dialog->track ();
2997 bool aux = !track && add_route_dialog->aux();
2998 RouteGroup* route_group = add_route_dialog->route_group ();
3000 AutoConnectOption oac = Config->get_output_auto_connect();
3002 if (oac & AutoConnectMaster) {
3003 output_chan = (_session->master_out() ? _session->master_out()->n_inputs().n_audio() : input_chan);
3005 output_chan = input_chan;
3008 /* XXX do something with name template */
3010 if (add_route_dialog->type() == ARDOUR::DataType::MIDI) {
3012 session_add_midi_track (route_group, count);
3014 MessageDialog msg (*editor,
3015 _("Sorry, MIDI Busses are not supported at this time."));
3017 //session_add_midi_bus();
3021 session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), route_group, count);
3023 session_add_audio_bus (aux, input_chan, output_chan, route_group, count);
3029 ARDOUR_UI::mixer_settings () const
3034 node = _session->instant_xml(X_("Mixer"));
3036 node = Config->instant_xml(X_("Mixer"));
3040 node = new XMLNode (X_("Mixer"));
3047 ARDOUR_UI::editor_settings () const
3052 node = _session->instant_xml(X_("Editor"));
3054 node = Config->instant_xml(X_("Editor"));
3058 if (getenv("ARDOUR_INSTANT_XML_PATH")) {
3059 node = Config->instant_xml(getenv("ARDOUR_INSTANT_XML_PATH"));
3064 node = new XMLNode (X_("Editor"));
3071 ARDOUR_UI::keyboard_settings () const
3075 node = Config->extra_xml(X_("Keyboard"));
3078 node = new XMLNode (X_("Keyboard"));
3084 ARDOUR_UI::create_xrun_marker(nframes_t where)
3086 editor->mouse_add_new_marker (where, false, true);
3090 ARDOUR_UI::halt_on_xrun_message ()
3092 MessageDialog msg (*editor,
3093 _("Recording was stopped because your system could not keep up."));
3098 ARDOUR_UI::xrun_handler(nframes_t where)
3104 ENSURE_GUI_THREAD (*this, &ARDOUR_UI::xrun_handler, where)
3106 if (_session && Config->get_create_xrun_marker() && _session->actively_recording()) {
3107 create_xrun_marker(where);
3110 if (_session && Config->get_stop_recording_on_xrun() && _session->actively_recording()) {
3111 halt_on_xrun_message ();
3116 ARDOUR_UI::push_buffer_stats (uint32_t capture, uint32_t playback)
3121 while (disk_buffer_stats.size() > 60) {
3122 disk_buffer_stats.pop_front ();
3125 disk_buffer_stats.push_back (DiskBufferStat (now, capture, playback));
3129 ARDOUR_UI::write_buffer_stats ()
3135 char path[PATH_MAX+1]; int fd;
3137 strcpy (path, "ardourBufferingXXXXXX");
3139 if ((fd = mkstemp (path )) < 0) {
3140 cerr << X_("cannot find temporary name for ardour buffer stats") << endl;
3148 cerr << string_compose (X_("cannot open file %1 for ardour buffer stats"), path) << endl;
3152 for (list<DiskBufferStat>::iterator i = disk_buffer_stats.begin(); i != disk_buffer_stats.end(); ++i) {
3153 localtime_r (&(*i).when, &tm);
3154 strftime (buf, sizeof (buf), "%T", &tm);
3155 fout << buf << ' ' << (*i).capture << ' ' << (*i).playback << endl;
3158 disk_buffer_stats.clear ();
3162 cerr << "Ardour buffering statistics can be found in: " << path << endl;
3166 ARDOUR_UI::disk_overrun_handler ()
3168 ENSURE_GUI_THREAD (*this, &ARDOUR_UI::disk_overrun_handler)
3170 write_buffer_stats ();
3172 if (!have_disk_speed_dialog_displayed) {
3173 have_disk_speed_dialog_displayed = true;
3174 MessageDialog* msg = new MessageDialog (*editor, _("\
3175 The disk system on your computer\n\
3176 was not able to keep up with Ardour.\n\
3178 Specifically, it failed to write data to disk\n\
3179 quickly enough to keep up with recording.\n"));
3180 msg->signal_response().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
3186 ARDOUR_UI::disk_underrun_handler ()
3188 ENSURE_GUI_THREAD (*this, &ARDOUR_UI::disk_underrun_handler)
3190 write_buffer_stats ();
3192 if (!have_disk_speed_dialog_displayed) {
3193 have_disk_speed_dialog_displayed = true;
3194 MessageDialog* msg = new MessageDialog (*editor,
3195 _("The disk system on your computer\n\
3196 was not able to keep up with Ardour.\n\
3198 Specifically, it failed to read data from disk\n\
3199 quickly enough to keep up with playback.\n"));
3200 msg->signal_response().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
3206 ARDOUR_UI::disk_speed_dialog_gone (int /*ignored_response*/, MessageDialog* msg)
3208 have_disk_speed_dialog_displayed = false;
3213 ARDOUR_UI::session_dialog (std::string msg)
3215 ENSURE_GUI_THREAD (*this, &ARDOUR_UI::session_dialog, msg)
3220 d = new MessageDialog (*editor, msg, false, MESSAGE_INFO, BUTTONS_OK, true);
3222 d = new MessageDialog (msg, false, MESSAGE_INFO, BUTTONS_OK, true);
3231 ARDOUR_UI::pending_state_dialog ()
3233 HBox* hbox = new HBox();
3234 Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG);
3235 ArdourDialog dialog (_("Crash Recovery"), true);
3237 This session appears to have been in\n\
3238 middle of recording when ardour or\n\
3239 the computer was shutdown.\n\
3241 Ardour can recover any captured audio for\n\
3242 you, or it can ignore it. Please decide\n\
3243 what you would like to do.\n"));
3244 image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
3245 hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
3246 hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
3247 dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
3248 dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
3249 dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
3250 dialog.set_default_response (RESPONSE_ACCEPT);
3251 dialog.set_position (WIN_POS_CENTER);
3256 switch (dialog.run ()) {
3257 case RESPONSE_ACCEPT:
3265 ARDOUR_UI::sr_mismatch_dialog (nframes_t desired, nframes_t actual)
3267 HBox* hbox = new HBox();
3268 Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG);
3269 ArdourDialog dialog (_("Sample Rate Mismatch"), true);
3270 Label message (string_compose (_("\
3271 This session was created with a sample rate of %1 Hz\n\
3273 The audioengine is currently running at %2 Hz\n"), desired, actual));
3275 image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
3276 hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
3277 hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
3278 dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
3279 dialog.add_button (_("Do not load session"), RESPONSE_REJECT);
3280 dialog.add_button (_("Load session anyway"), RESPONSE_ACCEPT);
3281 dialog.set_default_response (RESPONSE_ACCEPT);
3282 dialog.set_position (WIN_POS_CENTER);
3287 switch (dialog.run ()) {
3288 case RESPONSE_ACCEPT:
3297 ARDOUR_UI::disconnect_from_jack ()
3300 if( engine->disconnect_from_jack ()) {
3301 MessageDialog msg (*editor, _("Could not disconnect from JACK"));
3305 update_sample_rate (0);
3310 ARDOUR_UI::reconnect_to_jack ()
3313 if (engine->reconnect_to_jack ()) {
3314 MessageDialog msg (*editor, _("Could not reconnect to JACK"));
3318 update_sample_rate (0);
3323 ARDOUR_UI::use_config ()
3326 XMLNode* node = Config->extra_xml (X_("TransportControllables"));
3328 set_transport_controllable_state (*node);
3333 ARDOUR_UI::update_transport_clocks (nframes_t pos)
3335 if (Config->get_primary_clock_delta_edit_cursor()) {
3336 primary_clock.set (pos, false, editor->get_preferred_edit_position(), 1);
3338 primary_clock.set (pos, 0, true);
3341 if (Config->get_secondary_clock_delta_edit_cursor()) {
3342 secondary_clock.set (pos, false, editor->get_preferred_edit_position(), 2);
3344 secondary_clock.set (pos);
3347 if (big_clock_window) {
3348 big_clock.set (pos);
3353 ARDOUR_UI::record_state_changed ()
3355 ENSURE_GUI_THREAD (*this, &ARDOUR_UI::record_state_changed);
3357 if (!_session || !big_clock_window) {
3358 /* why bother - the clock isn't visible */
3362 Session::RecordState const r = _session->record_status ();
3363 bool const h = _session->have_rec_enabled_diskstream ();
3365 if (r == Session::Recording && h) {
3366 big_clock.set_widget_name ("BigClockRecording");
3368 big_clock.set_widget_name ("BigClockNonRecording");
3373 ARDOUR_UI::first_idle ()
3376 _session->allow_auto_play (true);
3380 editor->first_idle();
3383 Keyboard::set_can_save_keybindings (true);
3388 ARDOUR_UI::store_clock_modes ()
3390 XMLNode* node = new XMLNode(X_("ClockModes"));
3392 for (vector<AudioClock*>::iterator x = AudioClock::clocks.begin(); x != AudioClock::clocks.end(); ++x) {
3393 node->add_property ((*x)->name().c_str(), enum_2_string ((*x)->mode()));
3396 _session->add_extra_xml (*node);
3397 _session->set_dirty ();
3402 ARDOUR_UI::TransportControllable::TransportControllable (std::string name, ARDOUR_UI& u, ToggleType tp)
3403 : Controllable (name, string() /* missing URI */), ui (u), type(tp)
3409 ARDOUR_UI::TransportControllable::set_value (float val)
3411 if (type == ShuttleControl) {
3418 fract = -((0.5f - val)/0.5f);
3420 fract = ((val - 0.5f)/0.5f);
3424 ui.set_shuttle_fract (fract);
3429 /* do nothing: these are radio-style actions */
3433 const char *action = 0;
3437 action = X_("Roll");
3440 action = X_("Stop");
3443 action = X_("Goto Start");
3446 action = X_("Goto End");
3449 action = X_("Loop");
3452 action = X_("Play Selection");
3455 action = X_("Record");
3465 Glib::RefPtr<Action> act = ActionManager::get_action ("Transport", action);
3473 ARDOUR_UI::TransportControllable::get_value (void) const
3492 case ShuttleControl:
3502 ARDOUR_UI::TransportControllable::set_id (const string& str)
3508 ARDOUR_UI::setup_profile ()
3510 if (gdk_screen_width() < 1200) {
3511 Profile->set_small_screen ();
3515 if (getenv ("ARDOUR_SAE")) {
3516 Profile->set_sae ();
3517 Profile->set_single_package ();