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;
106 using namespace sigc;
108 ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
109 UIConfiguration *ARDOUR_UI::ui_config = 0;
111 sigc::signal<void,bool> ARDOUR_UI::Blink;
112 sigc::signal<void> ARDOUR_UI::RapidScreenUpdate;
113 sigc::signal<void> ARDOUR_UI::SuperRapidScreenUpdate;
114 sigc::signal<void,nframes_t, bool, nframes_t> ARDOUR_UI::Clock;
116 void gui_rt_cleanup (SessionEvent* ev)
118 /* a little helper function that makes sure we delete queued SessionEvents in the correct thread */
119 ENSURE_GUI_THREAD (bind (sigc::ptr_fun (&gui_rt_cleanup), ev));
123 /* wrap the above as a slot so that we can pass it to the session when queuing RT events */
124 const sigc::slot<void,SessionEvent*> gui_rt_cleanup_slot (sigc::ptr_fun (&gui_rt_cleanup));
126 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
128 : Gtkmm2ext::UI (X_("gui"), argcp, argvp),
130 primary_clock (X_("primary"), false, X_("TransportClockDisplay"), true, true, false, true),
131 secondary_clock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, true, false, true),
132 preroll_clock (X_("preroll"), false, X_("PreRollClock"), true, false, true),
133 postroll_clock (X_("postroll"), false, X_("PostRollClock"), true, false, true),
137 preroll_button (_("pre\nroll")),
138 postroll_button (_("post\nroll")),
142 big_clock (X_("bigclock"), false, "BigClockNonRecording", true, true, false, true),
146 roll_controllable (new TransportControllable ("transport roll", *this, TransportControllable::Roll)),
147 stop_controllable (new TransportControllable ("transport stop", *this, TransportControllable::Stop)),
148 goto_start_controllable (new TransportControllable ("transport goto start", *this, TransportControllable::GotoStart)),
149 goto_end_controllable (new TransportControllable ("transport goto end", *this, TransportControllable::GotoEnd)),
150 auto_loop_controllable (new TransportControllable ("transport auto loop", *this, TransportControllable::AutoLoop)),
151 play_selection_controllable (new TransportControllable ("transport play selection", *this, TransportControllable::PlaySelection)),
152 rec_controllable (new TransportControllable ("transport rec-enable", *this, TransportControllable::RecordEnable)),
153 shuttle_controllable (new TransportControllable ("shuttle", *this, TransportControllable::ShuttleControl)),
154 shuttle_controller_binding_proxy (shuttle_controllable),
156 roll_button (roll_controllable),
157 stop_button (stop_controllable),
158 goto_start_button (goto_start_controllable),
159 goto_end_button (goto_end_controllable),
160 auto_loop_button (auto_loop_controllable),
161 play_selection_button (play_selection_controllable),
162 rec_button (rec_controllable),
164 shuttle_units_button (_("% ")),
166 punch_in_button (_("Punch In")),
167 punch_out_button (_("Punch Out")),
168 auto_return_button (_("Auto Return")),
169 auto_play_button (_("Auto Play")),
170 auto_input_button (_("Auto Input")),
171 click_button (_("Click")),
172 time_master_button (_("time\nmaster")),
174 auditioning_alert_button (_("AUDITION")),
175 solo_alert_button (_("SOLO")),
177 error_log_button (_("Errors"))
180 using namespace Gtk::Menu_Helpers;
186 // _auto_display_errors = false;
188 * This was commented out as it wasn't defined
189 * in A3 IIRC. If this is not needed it should
190 * be completely removed.
198 if (theArdourUI == 0) {
202 ui_config = new UIConfiguration();
203 theme_manager = new ThemeManager();
210 _session_is_new = false;
211 big_clock_window = 0;
212 session_selector_window = 0;
213 last_key_press_time = 0;
214 _will_create_new_session_automatically = false;
215 add_route_dialog = 0;
217 rc_option_editor = 0;
218 session_option_editor = 0;
220 open_session_selector = 0;
221 have_configure_timeout = false;
222 have_disk_speed_dialog_displayed = false;
223 session_loaded = false;
224 last_speed_displayed = -1.0f;
225 ignore_dual_punch = false;
226 _mixer_on_top = false;
228 roll_button.unset_flags (Gtk::CAN_FOCUS);
229 stop_button.unset_flags (Gtk::CAN_FOCUS);
230 goto_start_button.unset_flags (Gtk::CAN_FOCUS);
231 goto_end_button.unset_flags (Gtk::CAN_FOCUS);
232 auto_loop_button.unset_flags (Gtk::CAN_FOCUS);
233 play_selection_button.unset_flags (Gtk::CAN_FOCUS);
234 rec_button.unset_flags (Gtk::CAN_FOCUS);
236 last_configure_time= 0;
238 shuttle_grabbed = false;
240 shuttle_max_speed = 8.0f;
242 shuttle_style_menu = 0;
243 shuttle_unit_menu = 0;
245 // We do not have jack linked in yet so;
247 last_shuttle_request = last_peak_grab = 0; // get_microseconds();
249 ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
250 ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
252 /* handle dialog requests */
254 ARDOUR::Session::Dialog.connect (mem_fun(*this, &ARDOUR_UI::session_dialog));
256 /* handle pending state with a dialog */
258 ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
260 /* handle sr mismatch with a dialog */
262 ARDOUR::Session::AskAboutSampleRateMismatch.connect (mem_fun(*this, &ARDOUR_UI::sr_mismatch_dialog));
264 /* lets get this party started */
267 if (ARDOUR::init (ARDOUR_COMMAND_LINE::use_vst, ARDOUR_COMMAND_LINE::try_hw_optimization)) {
268 throw failed_constructor ();
271 setup_gtk_ardour_enums ();
274 GainMeter::setup_slider_pix ();
275 RouteTimeAxisView::setup_slider_pix ();
276 SendProcessorEntry::setup_slider_pix ();
277 SessionEvent::create_per_thread_pool ("GUI", 512);
279 } catch (failed_constructor& err) {
280 error << _("could not initialize Ardour.") << endmsg;
285 /* we like keyboards */
287 keyboard = new ArdourKeyboard;
289 XMLNode* node = ARDOUR_UI::instance()->keyboard_settings();
291 keyboard->set_state (*node, Stateful::loading_state_version);
296 starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
297 stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
302 /** @return true if a session was chosen and `apply' clicked, otherwise false if `cancel' was clicked */
304 ARDOUR_UI::run_startup (bool should_be_new)
307 _startup = new ArdourStartup ();
310 _startup->set_new_only (should_be_new);
311 _startup->present ();
317 switch (_startup->response()) {
326 ARDOUR_UI::create_engine ()
328 // this gets called every time by new_session()
334 loading_message (_("Starting audio engine"));
337 engine = new ARDOUR::AudioEngine (ARDOUR_COMMAND_LINE::jack_client_name);
344 engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
345 engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
346 engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
347 engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
355 ARDOUR_UI::post_engine ()
357 /* Things to be done once we create the AudioEngine
360 MIDI::Manager::instance()->set_api_data (engine->jack());
363 ARDOUR::init_post_engine ();
365 ActionManager::init ();
368 if (setup_windows ()) {
369 throw failed_constructor ();
372 check_memory_locking();
374 /* this is the first point at which all the keybindings are available */
376 if (ARDOUR_COMMAND_LINE::show_key_actions) {
377 vector<string> names;
378 vector<string> paths;
380 vector<AccelKey> bindings;
382 ActionManager::get_all_actions (names, paths, keys, bindings);
384 vector<string>::iterator n;
385 vector<string>::iterator k;
386 for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) {
387 cerr << "Action: " << (*n) << " bound to " << (*k) << endl;
393 blink_timeout_tag = -1;
395 /* this being a GUI and all, we want peakfiles */
397 AudioFileSource::set_build_peakfiles (true);
398 AudioFileSource::set_build_missing_peakfiles (true);
400 /* set default clock modes */
402 if (Profile->get_sae()) {
403 primary_clock.set_mode (AudioClock::BBT);
404 secondary_clock.set_mode (AudioClock::MinSec);
406 primary_clock.set_mode (AudioClock::Timecode);
407 secondary_clock.set_mode (AudioClock::BBT);
410 /* start the time-of-day-clock */
413 /* OS X provides an always visible wallclock, so don't be stupid */
414 update_wall_clock ();
415 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
418 update_disk_space ();
420 update_sample_rate (engine->frame_rate());
422 Config->ParameterChanged.connect (mem_fun (*this, &ARDOUR_UI::parameter_changed));
423 Config->map_parameters (mem_fun (*this, &ARDOUR_UI::parameter_changed));
425 /* now start and maybe save state */
427 if (do_engine_start () == 0) {
428 if (session && _session_is_new) {
429 /* we need to retain initial visual
430 settings for a new session
432 session->save_state ("");
437 ARDOUR_UI::~ARDOUR_UI ()
439 save_ardour_state ();
444 delete add_route_dialog;
448 ARDOUR_UI::pop_back_splash ()
450 if (Splash::instance()) {
451 // Splash::instance()->pop_back();
452 Splash::instance()->hide ();
457 ARDOUR_UI::configure_timeout ()
459 if (last_configure_time == 0) {
460 /* no configure events yet */
464 /* force a gap of 0.5 seconds since the last configure event
467 if (get_microseconds() - last_configure_time < 500000) {
470 have_configure_timeout = false;
471 save_ardour_state ();
477 ARDOUR_UI::configure_handler (GdkEventConfigure* /*conf*/)
479 if (have_configure_timeout) {
480 last_configure_time = get_microseconds();
482 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
483 have_configure_timeout = true;
490 ARDOUR_UI::set_transport_controllable_state (const XMLNode& node)
492 const XMLProperty* prop;
494 if ((prop = node.property ("roll")) != 0) {
495 roll_controllable->set_id (prop->value());
497 if ((prop = node.property ("stop")) != 0) {
498 stop_controllable->set_id (prop->value());
500 if ((prop = node.property ("goto-start")) != 0) {
501 goto_start_controllable->set_id (prop->value());
503 if ((prop = node.property ("goto-end")) != 0) {
504 goto_end_controllable->set_id (prop->value());
506 if ((prop = node.property ("auto-loop")) != 0) {
507 auto_loop_controllable->set_id (prop->value());
509 if ((prop = node.property ("play-selection")) != 0) {
510 play_selection_controllable->set_id (prop->value());
512 if ((prop = node.property ("rec")) != 0) {
513 rec_controllable->set_id (prop->value());
515 if ((prop = node.property ("shuttle")) != 0) {
516 shuttle_controllable->set_id (prop->value());
521 ARDOUR_UI::get_transport_controllable_state ()
523 XMLNode* node = new XMLNode(X_("TransportControllables"));
526 roll_controllable->id().print (buf, sizeof (buf));
527 node->add_property (X_("roll"), buf);
528 stop_controllable->id().print (buf, sizeof (buf));
529 node->add_property (X_("stop"), buf);
530 goto_start_controllable->id().print (buf, sizeof (buf));
531 node->add_property (X_("goto_start"), buf);
532 goto_end_controllable->id().print (buf, sizeof (buf));
533 node->add_property (X_("goto_end"), buf);
534 auto_loop_controllable->id().print (buf, sizeof (buf));
535 node->add_property (X_("auto_loop"), buf);
536 play_selection_controllable->id().print (buf, sizeof (buf));
537 node->add_property (X_("play_selection"), buf);
538 rec_controllable->id().print (buf, sizeof (buf));
539 node->add_property (X_("rec"), buf);
540 shuttle_controllable->id().print (buf, sizeof (buf));
541 node->add_property (X_("shuttle"), buf);
547 ARDOUR_UI::save_ardour_state ()
549 if (!keyboard || !mixer || !editor) {
553 /* XXX this is all a bit dubious. add_extra_xml() uses
554 a different lifetime model from add_instant_xml().
557 XMLNode* node = new XMLNode (keyboard->get_state());
558 Config->add_extra_xml (*node);
559 Config->add_extra_xml (get_transport_controllable_state());
560 if (_startup && _startup->engine_control() && _startup->engine_control()->was_used()) {
561 Config->add_extra_xml (_startup->engine_control()->get_state());
563 Config->save_state();
564 ui_config->save_state ();
566 XMLNode enode(static_cast<Stateful*>(editor)->get_state());
567 XMLNode mnode(mixer->get_state());
570 session->add_instant_xml (enode);
571 session->add_instant_xml (mnode);
573 Config->add_instant_xml (enode);
574 Config->add_instant_xml (mnode);
577 Keyboard::save_keybindings ();
581 ARDOUR_UI::autosave_session ()
583 if (g_main_depth() > 1) {
584 /* inside a recursive main loop,
585 give up because we may not be able to
591 if (!Config->get_periodic_safety_backups()) {
596 session->maybe_write_autosave();
603 ARDOUR_UI::update_autosave ()
605 ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::update_autosave));
607 if (session && session->dirty()) {
608 if (_autosave_connection.connected()) {
609 _autosave_connection.disconnect();
612 _autosave_connection = Glib::signal_timeout().connect (mem_fun (*this, &ARDOUR_UI::autosave_session),
613 Config->get_periodic_safety_backup_interval() * 1000);
616 if (_autosave_connection.connected()) {
617 _autosave_connection.disconnect();
623 ARDOUR_UI::backend_audio_error (bool we_set_params, Gtk::Window* toplevel)
627 title = _("Ardour could not start JACK");
629 title = _("Ardour could not connect to JACK.");
632 MessageDialog win (title,
638 win.set_secondary_text(_("There are several possible reasons:\n\
640 1) You requested audio parameters that are not supported..\n\
641 2) JACK is running as another user.\n\
643 Please consider the possibilities, and perhaps try different parameters."));
645 win.set_secondary_text(_("There are several possible reasons:\n\
647 1) JACK is not running.\n\
648 2) JACK is running as another user, perhaps root.\n\
649 3) There is already another client called \"ardour\".\n\
651 Please consider the possibilities, and perhaps (re)start JACK."));
655 win.set_transient_for (*toplevel);
659 win.add_button (Stock::OK, RESPONSE_CLOSE);
661 win.add_button (Stock::QUIT, RESPONSE_CLOSE);
664 win.set_default_response (RESPONSE_CLOSE);
667 win.set_position (Gtk::WIN_POS_CENTER);
670 /* we just don't care about the result, but we want to block */
676 ARDOUR_UI::startup ()
678 XMLNode* audio_setup = Config->extra_xml ("AudioSetup");
680 if (audio_setup && _startup && _startup->engine_control()) {
681 _startup->engine_control()->set_state (*audio_setup);
684 if (get_session_parameters (true, ARDOUR_COMMAND_LINE::new_session)) {
690 goto_editor_window ();
692 BootMessage (_("Ardour is ready for use"));
697 ARDOUR_UI::no_memory_warning ()
699 XMLNode node (X_("no-memory-warning"));
700 Config->add_instant_xml (node);
704 ARDOUR_UI::check_memory_locking ()
707 /* OS X doesn't support mlockall(2), and so testing for memory locking capability there is pointless */
711 XMLNode* memory_warning_node = Config->instant_xml (X_("no-memory-warning"));
713 if (engine->is_realtime() && memory_warning_node == 0) {
715 struct rlimit limits;
717 long pages, page_size;
719 if ((page_size = sysconf (_SC_PAGESIZE)) < 0 ||(pages = sysconf (_SC_PHYS_PAGES)) < 0) {
722 ram = (int64_t) pages * (int64_t) page_size;
725 if (getrlimit (RLIMIT_MEMLOCK, &limits)) {
729 if (limits.rlim_cur != RLIM_INFINITY) {
731 if (ram == 0 || ((double) limits.rlim_cur / ram) < 0.75) {
734 MessageDialog msg (_("WARNING: Your system has a limit for maximum amount of locked memory. "
735 "This might cause Ardour to run out of memory before your system "
736 "runs out of memory. \n\n"
737 "You can view the memory limit with 'ulimit -l', "
738 "and it is normally controlled by /etc/security/limits.conf"));
740 VBox* vbox = msg.get_vbox();
742 CheckButton cb (_("Do not show this window again"));
744 cb.signal_toggled().connect (mem_fun (*this, &ARDOUR_UI::no_memory_warning));
746 hbox.pack_start (cb, true, false);
747 vbox->pack_start (hbox);
754 editor->ensure_float (msg);
768 if (session->transport_rolling()) {
769 session->request_stop ();
773 if (session->dirty()) {
774 switch (ask_about_saving_session(_("quit"))) {
779 /* use the default name */
780 if (save_state_canfail ("")) {
781 /* failed - don't quit */
782 MessageDialog msg (*editor,
784 Ardour was unable to save your session.\n\n\
785 If you still wish to quit, please use the\n\n\
786 \"Just quit\" option."));
797 second_connection.disconnect ();
798 point_one_second_connection.disconnect ();
799 point_oh_five_second_connection.disconnect ();
800 point_zero_one_second_connection.disconnect();
802 // session->set_deletion_in_progress ();
803 session->remove_pending_capture_state ();
808 ArdourDialog::close_all_dialogs ();
810 save_ardour_state ();
815 ARDOUR_UI::ask_about_saving_session (const string & what)
817 ArdourDialog window (_("ardour: save session?"));
818 Gtk::HBox dhbox; // the hbox for the image and text
819 Gtk::Label prompt_label;
820 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_WARNING, Gtk::ICON_SIZE_DIALOG));
824 msg = string_compose(_("Don't %1"), what);
825 window.add_button (msg, RESPONSE_REJECT);
826 msg = string_compose(_("Just %1"), what);
827 window.add_button (msg, RESPONSE_APPLY);
828 msg = string_compose(_("Save and %1"), what);
829 window.add_button (msg, RESPONSE_ACCEPT);
831 window.set_default_response (RESPONSE_ACCEPT);
833 Gtk::Button noquit_button (msg);
834 noquit_button.set_name ("EditorGTKButton");
839 if (session->snap_name() == session->name()) {
842 type = _("snapshot");
844 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?"),
845 type, session->snap_name());
847 prompt_label.set_text (prompt);
848 prompt_label.set_name (X_("PrompterLabel"));
849 prompt_label.set_alignment(ALIGN_LEFT, ALIGN_TOP);
851 dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP);
852 dhbox.set_homogeneous (false);
853 dhbox.pack_start (*dimage, false, false, 5);
854 dhbox.pack_start (prompt_label, true, false, 5);
855 window.get_vbox()->pack_start (dhbox);
857 window.set_name (_("Prompter"));
858 window.set_position (Gtk::WIN_POS_MOUSE);
859 window.set_modal (true);
860 window.set_resizable (false);
866 window.set_keep_above (true);
869 ResponseType r = (ResponseType) window.run();
874 case RESPONSE_ACCEPT: // save and get out of here
876 case RESPONSE_APPLY: // get out of here
886 ARDOUR_UI::every_second ()
889 update_buffer_load ();
890 update_disk_space ();
895 ARDOUR_UI::every_point_one_seconds ()
897 update_speed_display ();
898 RapidScreenUpdate(); /* EMIT_SIGNAL */
903 ARDOUR_UI::every_point_zero_one_seconds ()
905 // august 2007: actual update frequency: 40Hz, not 100Hz
907 SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
912 ARDOUR_UI::update_sample_rate (nframes_t ignored)
916 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
918 if (!engine->connected()) {
920 snprintf (buf, sizeof (buf), _("disconnected"));
924 nframes_t rate = engine->frame_rate();
926 if (fmod (rate, 1000.0) != 0.0) {
927 snprintf (buf, sizeof (buf), _("%.1f kHz / %4.1f ms"),
928 (float) rate/1000.0f,
929 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
931 snprintf (buf, sizeof (buf), _("%u kHz / %4.1f ms"),
933 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
937 sample_rate_label.set_text (buf);
941 ARDOUR_UI::update_cpu_load ()
944 snprintf (buf, sizeof (buf), _("DSP: %5.1f%%"), engine->get_cpu_load());
945 cpu_load_label.set_text (buf);
949 ARDOUR_UI::update_buffer_load ()
955 c = session->capture_load ();
956 p = session->playback_load ();
958 push_buffer_stats (c, p);
960 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"),
961 session->playback_load(), session->capture_load());
962 buffer_load_label.set_text (buf);
964 buffer_load_label.set_text ("");
969 ARDOUR_UI::count_recenabled_streams (Route& route)
971 Track* track = dynamic_cast<Track*>(&route);
972 if (track && track->diskstream()->record_enabled()) {
973 rec_enabled_streams += track->n_inputs().n_total();
978 ARDOUR_UI::update_disk_space()
984 nframes_t frames = session->available_capture_duration();
986 nframes_t fr = session->frame_rate();
988 if (frames == max_frames) {
989 strcpy (buf, _("Disk: 24hrs+"));
991 rec_enabled_streams = 0;
992 session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
994 if (rec_enabled_streams) {
995 frames /= rec_enabled_streams;
1002 hrs = frames / (fr * 3600);
1003 frames -= hrs * fr * 3600;
1004 mins = frames / (fr * 60);
1005 frames -= mins * fr * 60;
1008 snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs);
1011 disk_space_label.set_text (buf);
1013 // An attempt to make the disk space label flash red when space has run out.
1015 if (frames < fr * 60 * 5) {
1016 /* disk_space_box.style ("disk_space_label_empty"); */
1018 /* disk_space_box.style ("disk_space_label"); */
1024 ARDOUR_UI::update_wall_clock ()
1031 tm_now = localtime (&now);
1033 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
1034 wall_clock_label.set_text (buf);
1040 ARDOUR_UI::session_menu (GdkEventButton */*ev*/)
1042 session_popup_menu->popup (0, 0);
1047 ARDOUR_UI::redisplay_recent_sessions ()
1049 std::vector<sys::path> session_directories;
1050 RecentSessionsSorter cmp;
1052 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
1053 recent_session_model->clear ();
1055 ARDOUR::RecentSessions rs;
1056 ARDOUR::read_recent_sessions (rs);
1059 recent_session_display.set_model (recent_session_model);
1063 // sort them alphabetically
1064 sort (rs.begin(), rs.end(), cmp);
1066 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
1067 session_directories.push_back ((*i).second);
1070 for (vector<sys::path>::const_iterator i = session_directories.begin();
1071 i != session_directories.end(); ++i)
1073 std::vector<sys::path> state_file_paths;
1075 // now get available states for this session
1077 get_state_files_in_directory (*i, state_file_paths);
1079 vector<string*>* states;
1080 vector<const gchar*> item;
1081 string fullpath = (*i).to_string();
1083 /* remove any trailing / */
1085 if (fullpath[fullpath.length()-1] == '/') {
1086 fullpath = fullpath.substr (0, fullpath.length()-1);
1089 /* check whether session still exists */
1090 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
1091 /* session doesn't exist */
1092 cerr << "skipping non-existent session " << fullpath << endl;
1096 /* now get available states for this session */
1098 if ((states = Session::possible_states (fullpath)) == 0) {
1099 /* no state file? */
1103 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
1105 Gtk::TreeModel::Row row = *(recent_session_model->append());
1107 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
1108 row[recent_session_columns.fullpath] = fullpath;
1110 if (state_file_names.size() > 1) {
1114 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
1115 i2 != state_file_names.end(); ++i2)
1118 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
1120 child_row[recent_session_columns.visible_name] = *i2;
1121 child_row[recent_session_columns.fullpath] = fullpath;
1126 recent_session_display.set_model (recent_session_model);
1130 ARDOUR_UI::build_session_selector ()
1132 session_selector_window = new ArdourDialog (_("Recent Sessions"));
1134 Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
1136 session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
1137 session_selector_window->add_button (Stock::OPEN, RESPONSE_ACCEPT);
1138 session_selector_window->set_default_response (RESPONSE_ACCEPT);
1139 recent_session_model = TreeStore::create (recent_session_columns);
1140 recent_session_display.set_model (recent_session_model);
1141 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1142 recent_session_display.set_headers_visible (false);
1143 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
1144 recent_session_display.signal_row_activated().connect (mem_fun (*this, &ARDOUR_UI::recent_session_row_activated));
1146 scroller->add (recent_session_display);
1147 scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1149 session_selector_window->set_name ("SessionSelectorWindow");
1150 session_selector_window->set_size_request (200, 400);
1151 session_selector_window->get_vbox()->pack_start (*scroller);
1153 recent_session_display.show();
1155 //session_selector_window->get_vbox()->show();
1159 ARDOUR_UI::recent_session_row_activated (const TreePath& /*path*/, TreeViewColumn* /*col*/)
1161 session_selector_window->response (RESPONSE_ACCEPT);
1165 ARDOUR_UI::open_recent_session ()
1167 bool can_return = (session != 0);
1169 if (session_selector_window == 0) {
1170 build_session_selector ();
1173 redisplay_recent_sessions ();
1177 session_selector_window->set_position (WIN_POS_MOUSE);
1179 ResponseType r = (ResponseType) session_selector_window->run ();
1182 case RESPONSE_ACCEPT:
1186 session_selector_window->hide();
1193 if (recent_session_display.get_selection()->count_selected_rows() == 0) {
1197 session_selector_window->hide();
1199 Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
1201 if (i == recent_session_model->children().end()) {
1205 Glib::ustring path = (*i)[recent_session_columns.fullpath];
1206 Glib::ustring state = (*i)[recent_session_columns.visible_name];
1208 _session_is_new = false;
1210 if (load_session (path, state) == 0) {
1219 ARDOUR_UI::check_audioengine ()
1222 if (!engine->connected()) {
1223 MessageDialog msg (_("Ardour is not connected to JACK\n"
1224 "You cannot open or close sessions in this condition"));
1236 ARDOUR_UI::open_session ()
1238 if (!check_audioengine()) {
1243 /* popup selector window */
1245 if (open_session_selector == 0) {
1247 /* ardour sessions are folders */
1249 open_session_selector = new Gtk::FileChooserDialog (_("Open Session"), FILE_CHOOSER_ACTION_OPEN);
1250 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1251 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
1252 open_session_selector->set_default_response(Gtk::RESPONSE_ACCEPT);
1254 FileFilter session_filter;
1255 session_filter.add_pattern ("*.ardour");
1256 session_filter.set_name (_("Ardour sessions"));
1257 open_session_selector->add_filter (session_filter);
1258 open_session_selector->set_filter (session_filter);
1261 int response = open_session_selector->run();
1262 open_session_selector->hide ();
1265 case RESPONSE_ACCEPT:
1268 open_session_selector->hide();
1272 open_session_selector->hide();
1273 string session_path = open_session_selector->get_filename();
1277 if (session_path.length() > 0) {
1278 if (ARDOUR::find_session (session_path, path, name, isnew) == 0) {
1279 _session_is_new = isnew;
1280 load_session (path, name);
1287 ARDOUR_UI::session_add_midi_route (bool disk, RouteGroup* route_group, uint32_t how_many)
1289 list<boost::shared_ptr<MidiTrack> > tracks;
1292 warning << _("You cannot add a track without a session already loaded.") << endmsg;
1299 tracks = session->new_midi_track (ARDOUR::Normal, route_group, how_many);
1301 if (tracks.size() != how_many) {
1302 if (how_many == 1) {
1303 error << _("could not create a new midi track") << endmsg;
1305 error << string_compose (_("could not create %1 new midi tracks"), how_many) << endmsg;
1309 if ((route = session->new_midi_route ()) == 0) {
1310 error << _("could not create new midi bus") << endmsg;
1316 MessageDialog msg (*editor,
1317 _("There are insufficient JACK ports available\n\
1318 to create a new track or bus.\n\
1319 You should save Ardour, exit and\n\
1320 restart JACK with more ports."));
1327 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)
1329 list<boost::shared_ptr<AudioTrack> > tracks;
1333 warning << _("You cannot add a track or bus without a session already loaded.") << endmsg;
1339 tracks = session->new_audio_track (input_channels, output_channels, mode, route_group, how_many);
1341 if (tracks.size() != how_many) {
1342 if (how_many == 1) {
1343 error << _("could not create a new audio track") << endmsg;
1345 error << string_compose (_("could only create %1 of %2 new audio %3"),
1346 tracks.size(), how_many, (track ? _("tracks") : _("busses"))) << endmsg;
1352 routes = session->new_audio_route (aux, input_channels, output_channels, route_group, how_many);
1354 if (routes.size() != how_many) {
1355 if (how_many == 1) {
1356 error << _("could not create a new audio track") << endmsg;
1358 error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
1364 if (need_control_room_outs) {
1370 route->set_stereo_control_outs (control_lr_channels);
1371 route->control_outs()->set_stereo_pan (pans, this);
1373 #endif /* CONTROLOUTS */
1377 MessageDialog msg (*editor,
1378 _("There are insufficient JACK ports available\n\
1379 to create a new track or bus.\n\
1380 You should save Ardour, exit and\n\
1381 restart JACK with more ports."));
1388 ARDOUR_UI::do_transport_locate (nframes_t new_position)
1390 nframes_t _preroll = 0;
1393 // XXX CONFIG_CHANGE FIX - requires AnyTime handling
1394 // _preroll = session->convert_to_frames_at (new_position, Config->get_preroll());
1396 if (new_position > _preroll) {
1397 new_position -= _preroll;
1402 session->request_locate (new_position);
1407 ARDOUR_UI::transport_goto_start ()
1410 session->goto_start();
1412 /* force displayed area in editor to start no matter
1413 what "follow playhead" setting is.
1417 editor->center_screen (session->current_start_frame ());
1423 ARDOUR_UI::transport_goto_zero ()
1426 session->request_locate (0);
1429 /* force displayed area in editor to start no matter
1430 what "follow playhead" setting is.
1434 editor->reset_x_origin (0);
1440 ARDOUR_UI::transport_goto_wallclock ()
1442 if (session && editor) {
1449 localtime_r (&now, &tmnow);
1451 frames = tmnow.tm_hour * (60 * 60 * session->frame_rate());
1452 frames += tmnow.tm_min * (60 * session->frame_rate());
1453 frames += tmnow.tm_sec * session->frame_rate();
1455 session->request_locate (frames);
1457 /* force displayed area in editor to start no matter
1458 what "follow playhead" setting is.
1462 editor->center_screen (frames);
1468 ARDOUR_UI::transport_goto_end ()
1471 nframes_t const frame = session->current_end_frame();
1472 session->request_locate (frame);
1474 /* force displayed area in editor to start no matter
1475 what "follow playhead" setting is.
1479 editor->center_screen (frame);
1485 ARDOUR_UI::transport_stop ()
1491 if (session->is_auditioning()) {
1492 session->cancel_audition ();
1496 session->request_stop ();
1500 ARDOUR_UI::transport_stop_and_forget_capture ()
1503 session->request_stop (true);
1508 ARDOUR_UI::remove_last_capture()
1511 editor->remove_last_capture();
1516 ARDOUR_UI::transport_record (bool roll)
1520 switch (session->record_status()) {
1521 case Session::Disabled:
1522 if (session->ntracks() == 0) {
1523 MessageDialog msg (*editor, _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu."));
1527 session->maybe_enable_record ();
1532 case Session::Recording:
1534 session->request_stop();
1536 session->disable_record (false, true);
1540 case Session::Enabled:
1541 session->disable_record (false, true);
1544 //cerr << "ARDOUR_UI::transport_record () called roll = " << roll << " session->record_status() = " << session->record_status() << endl;
1548 ARDOUR_UI::transport_roll ()
1554 if (session->is_auditioning()) {
1558 if (session->config.get_external_sync()) {
1559 switch (session->config.get_sync_source()) {
1563 /* transport controlled by the master */
1568 bool rolling = session->transport_rolling();
1570 if (session->get_play_loop()) {
1571 session->request_play_loop (false, true);
1572 } else if (session->get_play_range ()) {
1573 session->request_play_range (false, true);
1577 session->request_transport_speed (1.0f);
1580 map_transport_state ();
1584 ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode)
1591 if (session->is_auditioning()) {
1592 session->cancel_audition ();
1596 if (session->config.get_external_sync()) {
1597 switch (session->config.get_sync_source()) {
1601 /* transport controlled by the master */
1606 bool rolling = session->transport_rolling();
1607 bool affect_transport = true;
1609 if (rolling && roll_out_of_bounded_mode) {
1610 /* drop out of loop/range playback but leave transport rolling */
1611 if (session->get_play_loop()) {
1612 if (Config->get_seamless_loop()) {
1613 /* the disk buffers contain copies of the loop - we can't
1614 just keep playing, so stop the transport. the user
1615 can restart as they wish.
1617 affect_transport = true;
1619 /* disk buffers are normal, so we can keep playing */
1620 affect_transport = false;
1622 session->request_play_loop (false, true);
1623 } else if (session->get_play_range ()) {
1624 affect_transport = false;
1625 session->request_play_range (0, true);
1629 if (affect_transport) {
1631 session->request_stop (with_abort, true);
1633 session->request_transport_speed (1.0f);
1637 map_transport_state ();
1641 ARDOUR_UI::toggle_session_auto_loop ()
1644 if (session->get_play_loop()) {
1645 if (session->transport_rolling()) {
1646 Location * looploc = session->locations()->auto_loop_location();
1648 session->request_locate (looploc->start(), true);
1651 session->request_play_loop (false);
1654 Location * looploc = session->locations()->auto_loop_location();
1656 session->request_play_loop (true);
1663 ARDOUR_UI::transport_play_selection ()
1669 editor->play_selection ();
1673 ARDOUR_UI::transport_rewind (int option)
1675 float current_transport_speed;
1678 current_transport_speed = session->transport_speed();
1680 if (current_transport_speed >= 0.0f) {
1683 session->request_transport_speed (-1.0f);
1686 session->request_transport_speed (-4.0f);
1689 session->request_transport_speed (-0.5f);
1694 session->request_transport_speed (current_transport_speed * 1.5f);
1700 ARDOUR_UI::transport_forward (int option)
1702 float current_transport_speed;
1705 current_transport_speed = session->transport_speed();
1707 if (current_transport_speed <= 0.0f) {
1710 session->request_transport_speed (1.0f);
1713 session->request_transport_speed (4.0f);
1716 session->request_transport_speed (0.5f);
1721 session->request_transport_speed (current_transport_speed * 1.5f);
1728 ARDOUR_UI::toggle_record_enable (uint32_t dstream)
1734 boost::shared_ptr<Route> r;
1736 if ((r = session->route_by_remote_id (dstream)) != 0) {
1740 if ((t = dynamic_cast<Track*>(r.get())) != 0) {
1741 t->diskstream()->set_record_enabled (!t->diskstream()->record_enabled());
1750 ARDOUR_UI::map_transport_state ()
1752 ENSURE_GUI_THREAD(mem_fun (*this, &ARDOUR_UI::map_transport_state));
1755 auto_loop_button.set_visual_state (0);
1756 play_selection_button.set_visual_state (0);
1757 roll_button.set_visual_state (0);
1758 stop_button.set_visual_state (1);
1762 float sp = session->transport_speed();
1765 shuttle_fract = SHUTTLE_FRACT_SPEED1; /* speed = 1.0, believe it or not */
1766 shuttle_box.queue_draw ();
1767 } else if (sp == 0.0f) {
1769 shuttle_box.queue_draw ();
1770 update_disk_space ();
1775 if (session->get_play_range()) {
1777 play_selection_button.set_visual_state (1);
1778 roll_button.set_visual_state (0);
1779 auto_loop_button.set_visual_state (0);
1781 } else if (session->get_play_loop ()) {
1783 auto_loop_button.set_visual_state (1);
1784 play_selection_button.set_visual_state (0);
1785 roll_button.set_visual_state (0);
1789 roll_button.set_visual_state (1);
1790 play_selection_button.set_visual_state (0);
1791 auto_loop_button.set_visual_state (0);
1794 stop_button.set_visual_state (0);
1798 stop_button.set_visual_state (1);
1799 roll_button.set_visual_state (0);
1800 play_selection_button.set_visual_state (0);
1801 auto_loop_button.set_visual_state (0);
1807 ARDOUR_UI::engine_stopped ()
1809 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
1810 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1811 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1815 ARDOUR_UI::engine_running ()
1817 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
1818 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true);
1819 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
1821 Glib::RefPtr<Action> action;
1822 const char* action_name = 0;
1824 switch (engine->frames_per_cycle()) {
1826 action_name = X_("JACKLatency32");
1829 action_name = X_("JACKLatency64");
1832 action_name = X_("JACKLatency128");
1835 action_name = X_("JACKLatency512");
1838 action_name = X_("JACKLatency1024");
1841 action_name = X_("JACKLatency2048");
1844 action_name = X_("JACKLatency4096");
1847 action_name = X_("JACKLatency8192");
1850 /* XXX can we do anything useful ? */
1856 action = ActionManager::get_action (X_("JACK"), action_name);
1859 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic (action);
1860 ract->set_active ();
1866 ARDOUR_UI::engine_halted ()
1868 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
1870 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1871 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1873 update_sample_rate (0);
1875 MessageDialog msg (*editor,
1877 JACK has either been shutdown or it\n\
1878 disconnected Ardour because Ardour\n\
1879 was not fast enough. Try to restart\n\
1880 JACK, reconnect and save the session."));
1886 ARDOUR_UI::do_engine_start ()
1894 error << _("Unable to start the session running")
1904 ARDOUR_UI::setup_theme ()
1906 theme_manager->setup_theme();
1910 ARDOUR_UI::update_clocks ()
1912 if (!editor || !editor->dragging_playhead()) {
1913 Clock (session->audible_frame(), false, editor->get_preferred_edit_position()); /* EMIT_SIGNAL */
1918 ARDOUR_UI::start_clocking ()
1920 clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
1924 ARDOUR_UI::stop_clocking ()
1926 clock_signal_connection.disconnect ();
1930 ARDOUR_UI::toggle_clocking ()
1933 if (clock_button.get_active()) {
1942 ARDOUR_UI::_blink (void *arg)
1945 ((ARDOUR_UI *) arg)->blink ();
1952 Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
1956 ARDOUR_UI::start_blinking ()
1958 /* Start the blink signal. Everybody with a blinking widget
1959 uses Blink to drive the widget's state.
1962 if (blink_timeout_tag < 0) {
1964 blink_timeout_tag = g_timeout_add (240, _blink, this);
1969 ARDOUR_UI::stop_blinking ()
1971 if (blink_timeout_tag >= 0) {
1972 g_source_remove (blink_timeout_tag);
1973 blink_timeout_tag = -1;
1978 /** Ask the user for the name of a new shapshot and then take it.
1981 ARDOUR_UI::snapshot_session ()
1983 ArdourPrompter prompter (true);
1987 struct tm local_time;
1990 localtime_r (&n, &local_time);
1991 strftime (timebuf, sizeof(timebuf), "%FT%T", &local_time);
1993 prompter.set_name ("Prompter");
1994 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1995 prompter.set_title (_("Take Snapshot"));
1996 prompter.set_prompt (_("Name of New Snapshot"));
1997 prompter.set_initial_text (timebuf);
1999 switch (prompter.run()) {
2000 case RESPONSE_ACCEPT:
2002 prompter.get_result (snapname);
2004 bool do_save = (snapname.length() != 0);
2006 vector<sys::path> p;
2007 get_state_files_in_directory (session->session_directory().root_path(), p);
2008 vector<string> n = get_file_names_no_extension (p);
2009 if (find (n.begin(), n.end(), snapname) != n.end()) {
2011 ArdourDialog confirm (_("Confirm snapshot overwrite"), true);
2012 Label m (_("A snapshot already exists with that name. Do you want to overwrite it?"));
2013 confirm.get_vbox()->pack_start (m, true, true);
2014 confirm.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
2015 confirm.add_button (_("Overwrite"), Gtk::RESPONSE_ACCEPT);
2016 confirm.show_all ();
2017 switch (confirm.run()) {
2018 case RESPONSE_CANCEL:
2024 save_state (snapname);
2035 ARDOUR_UI::save_state (const string & name)
2037 (void) save_state_canfail (name);
2041 ARDOUR_UI::save_state_canfail (string name)
2046 if (name.length() == 0) {
2047 name = session->snap_name();
2050 if ((ret = session->save_state (name)) != 0) {
2054 save_ardour_state (); /* XXX cannot fail? yeah, right ... */
2059 ARDOUR_UI::primary_clock_value_changed ()
2062 session->request_locate (primary_clock.current_time ());
2067 ARDOUR_UI::big_clock_value_changed ()
2070 session->request_locate (big_clock.current_time ());
2075 ARDOUR_UI::secondary_clock_value_changed ()
2078 session->request_locate (secondary_clock.current_time ());
2083 ARDOUR_UI::transport_rec_enable_blink (bool onoff)
2089 Session::RecordState const r = session->record_status ();
2090 bool const h = session->have_rec_enabled_diskstream ();
2092 if (r == Session::Enabled || (r == Session::Recording && !h)) {
2094 rec_button.set_visual_state (2);
2096 rec_button.set_visual_state (0);
2098 } else if (r == Session::Recording && h) {
2099 rec_button.set_visual_state (1);
2101 rec_button.set_visual_state (0);
2106 ARDOUR_UI::save_template ()
2108 ArdourPrompter prompter (true);
2111 if (!check_audioengine()) {
2115 prompter.set_name (X_("Prompter"));
2116 prompter.set_title (_("Save Mix Template"));
2117 prompter.set_prompt (_("Name for mix template:"));
2118 prompter.set_initial_text(session->name() + _("-template"));
2119 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
2121 switch (prompter.run()) {
2122 case RESPONSE_ACCEPT:
2123 prompter.get_result (name);
2125 if (name.length()) {
2126 session->save_template (name);
2136 ARDOUR_UI::edit_metadata ()
2138 SessionMetadataEditor dialog;
2139 dialog.set_session (session);
2140 editor->ensure_float (dialog);
2145 ARDOUR_UI::import_metadata ()
2147 SessionMetadataImporter dialog;
2148 dialog.set_session (session);
2149 editor->ensure_float (dialog);
2154 ARDOUR_UI::fontconfig_dialog ()
2157 /* X11 users will always have fontconfig info around, but new GTK-OSX users
2158 may not and it can take a while to build it. Warn them.
2161 Glib::ustring fontconfig = Glib::build_filename (Glib::get_home_dir(), ".fontconfig");
2163 if (!Glib::file_test (fontconfig, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
2164 MessageDialog msg (*_startup,
2165 _("Welcome to Ardour.\n\n"
2166 "The program will take a bit longer to start up\n"
2167 "while the system fonts are checked.\n\n"
2168 "This will only be done once, and you will\n"
2169 "not see this message again\n"),
2182 ARDOUR_UI::parse_cmdline_path (const Glib::ustring& cmdline_path, Glib::ustring& session_name, Glib::ustring& session_path, bool& existing_session)
2184 existing_session = false;
2186 if (Glib::file_test (cmdline_path, Glib::FILE_TEST_IS_DIR)) {
2187 session_path = cmdline_path;
2188 existing_session = true;
2189 } else if (Glib::file_test (cmdline_path, Glib::FILE_TEST_IS_REGULAR)) {
2190 session_path = Glib::path_get_dirname (string (cmdline_path));
2191 existing_session = true;
2193 /* it doesn't exist, assume the best */
2194 session_path = Glib::path_get_dirname (string (cmdline_path));
2197 session_name = basename_nosuffix (string (cmdline_path));
2201 ARDOUR_UI::load_cmdline_session (const Glib::ustring& session_name, const Glib::ustring& session_path, bool& existing_session)
2203 /* when this is called, the backend audio system must be running */
2205 /* the main idea here is to deal with the fact that a cmdline argument for the session
2206 can be interpreted in different ways - it could be a directory or a file, and before
2207 we load, we need to know both the session directory and the snapshot (statefile) within it
2208 that we are supposed to use.
2211 if (session_name.length() == 0 || session_path.length() == 0) {
2215 if (Glib::file_test (session_path, Glib::FILE_TEST_IS_DIR)) {
2217 Glib::ustring predicted_session_file;
2219 predicted_session_file = session_path;
2220 predicted_session_file += '/';
2221 predicted_session_file += session_name;
2222 predicted_session_file += ARDOUR::statefile_suffix;
2224 if (Glib::file_test (predicted_session_file, Glib::FILE_TEST_EXISTS)) {
2225 existing_session = true;
2228 } else if (Glib::file_test (session_path, Glib::FILE_TEST_EXISTS)) {
2230 if (session_path.find (ARDOUR::statefile_suffix) == session_path.length() - 7) {
2231 /* existing .ardour file */
2232 existing_session = true;
2236 existing_session = false;
2239 /* lets just try to load it */
2241 if (create_engine ()) {
2242 backend_audio_error (false, _startup);
2246 return load_session (session_path, session_name);
2250 ARDOUR_UI::ask_about_loading_existing_session (const Glib::ustring& session_path)
2252 Glib::ustring str = string_compose (_("This session\n%1\nalready exists. Do you want to open it?"), session_path);
2254 MessageDialog msg (str,
2256 Gtk::MESSAGE_WARNING,
2257 Gtk::BUTTONS_YES_NO,
2261 msg.set_name (X_("OpenExistingDialog"));
2262 msg.set_title (_("Open Existing Session"));
2263 msg.set_wmclass (X_("existing_session"), "Ardour");
2264 msg.set_position (Gtk::WIN_POS_MOUSE);
2267 switch (msg.run()) {
2276 ARDOUR_UI::build_session_from_nsd (const Glib::ustring& session_path, const Glib::ustring& session_name)
2281 AutoConnectOption iconnect;
2282 AutoConnectOption oconnect;
2286 if (Profile->get_sae()) {
2290 iconnect = AutoConnectPhysical;
2291 oconnect = AutoConnectMaster;
2292 nphysin = 0; // use all available
2293 nphysout = 0; // use all available
2297 /* get settings from advanced section of NSD */
2299 if (_startup->create_control_bus()) {
2300 cchns = (uint32_t) _startup->control_channel_count();
2305 if (_startup->create_master_bus()) {
2306 mchns = (uint32_t) _startup->master_channel_count();
2311 if (_startup->connect_inputs()) {
2312 iconnect = AutoConnectPhysical;
2314 iconnect = AutoConnectOption (0);
2317 /// @todo some minor tweaks.
2319 oconnect = AutoConnectOption (0);
2321 if (_startup->connect_outputs ()) {
2322 if (_startup->connect_outs_to_master()) {
2323 oconnect = AutoConnectMaster;
2324 } else if (_startup->connect_outs_to_physical()) {
2325 oconnect = AutoConnectPhysical;
2329 nphysin = (uint32_t) _startup->input_limit_count();
2330 nphysout = (uint32_t) _startup->output_limit_count();
2333 if (build_session (session_path,
2341 engine->frame_rate() * 60 * 5)) {
2350 ARDOUR_UI::idle_load (const Glib::ustring& path)
2353 if (Glib::file_test (path, Glib::FILE_TEST_IS_DIR)) {
2354 /* /path/to/foo => /path/to/foo, foo */
2355 load_session (path, basename_nosuffix (path));
2357 /* /path/to/foo/foo.ardour => /path/to/foo, foo */
2358 load_session (Glib::path_get_dirname (path), basename_nosuffix (path));
2362 ARDOUR_COMMAND_LINE::session_name = path;
2365 * new_session_dialog doens't exist in A3
2366 * Try to remove all references to it to
2367 * see if it will compile. NOTE: this will
2368 * likely cause a runtime issue is my somewhat
2372 //if (new_session_dialog) {
2375 /* make it break out of Dialog::run() and
2379 //new_session_dialog->response (1);
2385 ARDOUR_UI::end_loading_messages ()
2391 ARDOUR_UI::loading_message (const std::string& /*msg*/)
2394 // splash->message (msg);
2398 /** @param quit_on_cancel true if exit() should be called if the user clicks `cancel' in the new session dialog */
2400 ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new)
2402 Glib::ustring session_name;
2403 Glib::ustring session_path;
2404 Glib::ustring template_name;
2406 bool likely_new = false;
2410 if (!should_be_new && !ARDOUR_COMMAND_LINE::session_name.empty()) {
2412 /* if they named a specific statefile, use it, otherwise they are
2413 just giving a session folder, and we want to use it as is
2414 to find the session.
2417 if (ARDOUR_COMMAND_LINE::session_name.find (statefile_suffix) != string::npos) {
2418 session_path = Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name);
2420 session_path = ARDOUR_COMMAND_LINE::session_name;
2423 session_name = Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name);
2427 bool const apply = run_startup (should_be_new);
2429 if (quit_on_cancel) {
2436 /* if we run the startup dialog again, offer more than just "new session" */
2438 should_be_new = false;
2440 session_name = _startup->session_name (likely_new);
2442 /* this shouldn't happen, but we catch it just in case it does */
2444 if (session_name.empty()) {
2447 if (_startup->use_session_template()) {
2448 template_name = _startup->session_template_name();
2449 _session_is_new = true;
2452 if (session_name[0] == '/' ||
2453 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
2454 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
2456 session_path = Glib::path_get_dirname (session_name);
2457 session_name = Glib::path_get_basename (session_name);
2461 session_path = _startup->session_folder();
2465 if (create_engine ()) {
2469 if (Glib::file_test (session_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
2473 Glib::ustring existing = Glib::build_filename (session_path, session_name);
2475 if (!ask_about_loading_existing_session (existing)) {
2476 ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
2481 _session_is_new = false;
2486 MessageDialog msg (string_compose (_("There is no existing session at \"%1\""), session_path));
2488 ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
2492 _session_is_new = true;
2495 if (likely_new && template_name.empty()) {
2497 ret = build_session_from_nsd (session_path, session_name);
2501 ret = load_session (session_path, session_name, template_name);
2502 if (!ARDOUR_COMMAND_LINE::immediate_save.empty()) {
2503 session->save_state (ARDOUR_COMMAND_LINE::immediate_save, false);
2513 ARDOUR_UI::close_session()
2515 if (!check_audioengine()) {
2519 unload_session (true);
2521 ARDOUR_COMMAND_LINE::session_name = "";
2522 get_session_parameters (true, false);
2526 ARDOUR_UI::load_session (const Glib::ustring& path, const Glib::ustring& snap_name, Glib::ustring mix_template)
2528 Session *new_session;
2532 session_loaded = false;
2534 if (!check_audioengine()) {
2538 unload_status = unload_session ();
2540 if (unload_status < 0) {
2542 } else if (unload_status > 0) {
2547 loading_message (_("Please wait while Ardour loads your session"));
2550 new_session = new Session (*engine, path, snap_name, mix_template);
2553 /* this one is special */
2555 catch (AudioEngine::PortRegistrationFailure& err) {
2557 MessageDialog msg (err.what(),
2560 Gtk::BUTTONS_CLOSE);
2562 msg.set_title (_("Port Registration Error"));
2563 msg.set_secondary_text (_("Click the Close button to try again."));
2564 msg.set_position (Gtk::WIN_POS_CENTER);
2568 int response = msg.run ();
2573 case RESPONSE_CANCEL:
2583 MessageDialog msg (string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name),
2586 Gtk::BUTTONS_CLOSE);
2588 msg.set_title (_("Loading Error"));
2589 msg.set_secondary_text (_("Click the Close button to try again."));
2590 msg.set_position (Gtk::WIN_POS_CENTER);
2594 int response = msg.run ();
2599 case RESPONSE_CANCEL:
2607 connect_to_session (new_session);
2609 session_loaded = true;
2611 goto_editor_window ();
2614 session->set_clean ();
2625 ARDOUR_UI::build_session (const Glib::ustring& path, const Glib::ustring& snap_name,
2626 uint32_t control_channels,
2627 uint32_t master_channels,
2628 AutoConnectOption input_connect,
2629 AutoConnectOption output_connect,
2632 nframes_t initial_length)
2634 Session *new_session;
2637 if (!check_audioengine()) {
2641 session_loaded = false;
2643 x = unload_session ();
2651 _session_is_new = true;
2654 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
2655 control_channels, master_channels, nphysin, nphysout, initial_length);
2660 MessageDialog msg (string_compose(_("Could not create session in \"%1\""), path));
2666 connect_to_session (new_session);
2668 session_loaded = true;
2670 new_session->save_state(new_session->name());
2679 editor->show_window ();
2690 ARDOUR_UI::show_about ()
2694 about->signal_response().connect(mem_fun (*this, &ARDOUR_UI::about_signal_response) );
2701 ARDOUR_UI::hide_about ()
2704 about->get_window()->set_cursor ();
2710 ARDOUR_UI::about_signal_response (int /*response*/)
2716 ARDOUR_UI::show_splash ()
2720 splash = new Splash;
2728 splash->queue_draw ();
2729 splash->get_window()->process_updates (true);
2734 ARDOUR_UI::hide_splash ()
2742 ARDOUR_UI::display_cleanup_results (ARDOUR::CleanupReport& rep, const gchar* list_title,
2743 const string& plural_msg, const string& singular_msg)
2747 removed = rep.paths.size();
2750 MessageDialog msgd (*editor,
2751 _("No audio files were ready for cleanup"),
2754 (Gtk::ButtonsType)(Gtk::BUTTONS_OK) );
2755 msgd.set_secondary_text (_("If this seems suprising, \n\
2756 check for any existing snapshots.\n\
2757 These may still include regions that\n\
2758 require some unused files to continue to exist."));
2764 ArdourDialog results (_("ardour: cleanup"), true, false);
2766 struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
2767 CleanupResultsModelColumns() {
2771 Gtk::TreeModelColumn<Glib::ustring> visible_name;
2772 Gtk::TreeModelColumn<Glib::ustring> fullpath;
2776 CleanupResultsModelColumns results_columns;
2777 Glib::RefPtr<Gtk::ListStore> results_model;
2778 Gtk::TreeView results_display;
2780 results_model = ListStore::create (results_columns);
2781 results_display.set_model (results_model);
2782 results_display.append_column (list_title, results_columns.visible_name);
2784 results_display.set_name ("CleanupResultsList");
2785 results_display.set_headers_visible (true);
2786 results_display.set_headers_clickable (false);
2787 results_display.set_reorderable (false);
2789 Gtk::ScrolledWindow list_scroller;
2792 Gtk::HBox dhbox; // the hbox for the image and text
2793 Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
2794 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO, Gtk::ICON_SIZE_DIALOG));
2796 dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
2798 const string dead_sound_directory = session->session_directory().dead_sound_path().to_string();
2804 %1 - number of files removed
2805 %2 - location of "dead_sounds"
2806 %3 - size of files affected
2807 %4 - prefix for "bytes" to produce sensible results (e.g. mega, kilo, giga)
2810 const char* bprefix;
2812 if (rep.space < 1048576.0f) {
2813 bprefix = X_("kilo");
2814 } else if (rep.space < 1048576.0f * 1000) {
2815 bprefix = X_("mega");
2817 bprefix = X_("giga");
2821 txt.set_text (string_compose (plural_msg, removed, dead_sound_directory, (float) rep.space / 1024.0f, bprefix));
2823 txt.set_text (string_compose (singular_msg, removed, dead_sound_directory, (float) rep.space / 1024.0f, bprefix));
2826 dhbox.pack_start (*dimage, true, false, 5);
2827 dhbox.pack_start (txt, true, false, 5);
2829 for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2830 TreeModel::Row row = *(results_model->append());
2831 row[results_columns.visible_name] = *i;
2832 row[results_columns.fullpath] = *i;
2835 list_scroller.add (results_display);
2836 list_scroller.set_size_request (-1, 150);
2837 list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2839 dvbox.pack_start (dhbox, true, false, 5);
2840 dvbox.pack_start (list_scroller, true, false, 5);
2841 ddhbox.pack_start (dvbox, true, false, 5);
2843 results.get_vbox()->pack_start (ddhbox, true, false, 5);
2844 results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
2845 results.set_default_response (RESPONSE_CLOSE);
2846 results.set_position (Gtk::WIN_POS_MOUSE);
2848 results_display.show();
2849 list_scroller.show();
2856 //results.get_vbox()->show();
2857 results.set_resizable (false);
2864 ARDOUR_UI::cleanup ()
2867 /* shouldn't happen: menu item is insensitive */
2872 MessageDialog checker (_("Are you sure you want to cleanup?"),
2874 Gtk::MESSAGE_QUESTION,
2875 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
2877 checker.set_secondary_text(_("Cleanup is a destructive operation.\n\
2878 ALL undo/redo information will be lost if you cleanup.\n\
2879 After cleanup, unused audio files will be moved to a \
2880 \"dead sounds\" location."));
2882 checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2883 checker.add_button (_("Clean Up"), RESPONSE_ACCEPT);
2884 checker.set_default_response (RESPONSE_CANCEL);
2886 checker.set_name (_("CleanupDialog"));
2887 checker.set_wmclass (X_("ardour_cleanup"), "Ardour");
2888 checker.set_position (Gtk::WIN_POS_MOUSE);
2890 switch (checker.run()) {
2891 case RESPONSE_ACCEPT:
2897 ARDOUR::CleanupReport rep;
2899 editor->prepare_for_cleanup ();
2901 /* do not allow flush until a session is reloaded */
2903 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
2905 act->set_sensitive (false);
2908 if (session->cleanup_sources (rep)) {
2909 editor->finish_cleanup ();
2913 editor->finish_cleanup ();
2916 display_cleanup_results (rep,
2919 The following %1 files were not in use and \n\
2920 have been moved to:\n\
2922 Flushing the wastebasket will \n\
2923 release an additional\n\
2924 %3 %4bytes of disk space.\n"),
2926 The following file was not in use and \n \
2927 has been moved to:\n \
2929 Flushing the wastebasket will \n\
2930 release an additional\n\
2931 %3 %4bytes of disk space.\n"
2937 ARDOUR_UI::flush_trash ()
2940 /* shouldn't happen: menu item is insensitive */
2944 ARDOUR::CleanupReport rep;
2946 if (session->cleanup_trash_sources (rep)) {
2950 display_cleanup_results (rep,
2952 _("The following %1 files were deleted from\n\
2954 releasing %3 %4bytes of disk space"),
2955 _("The following file was deleted from\n\
2957 releasing %3 %4bytes of disk space"));
2961 ARDOUR_UI::add_route (Gtk::Window* float_window)
2969 if (add_route_dialog == 0) {
2970 add_route_dialog = new AddRouteDialog (*session);
2972 add_route_dialog->set_transient_for (*float_window);
2976 if (add_route_dialog->is_visible()) {
2977 /* we're already doing this */
2981 ResponseType r = (ResponseType) add_route_dialog->run ();
2983 add_route_dialog->hide();
2986 case RESPONSE_ACCEPT:
2993 if ((count = add_route_dialog->count()) <= 0) {
2997 string template_path = add_route_dialog->track_template();
2999 if (!template_path.empty()) {
3000 session->new_route_from_template (count, template_path);
3004 uint32_t input_chan = add_route_dialog->channels ();
3005 uint32_t output_chan;
3006 string name_template = add_route_dialog->name_template ();
3007 bool track = add_route_dialog->track ();
3008 bool aux = !track && add_route_dialog->aux();
3009 RouteGroup* route_group = add_route_dialog->route_group ();
3011 AutoConnectOption oac = Config->get_output_auto_connect();
3013 if (oac & AutoConnectMaster) {
3014 output_chan = (session->master_out() ? session->master_out()->n_inputs().n_audio() : input_chan);
3016 output_chan = input_chan;
3019 /* XXX do something with name template */
3021 if (add_route_dialog->type() == ARDOUR::DataType::MIDI) {
3023 session_add_midi_track (route_group, count);
3025 MessageDialog msg (*editor,
3026 _("Sorry, MIDI Busses are not supported at this time."));
3028 //session_add_midi_bus();
3032 session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), route_group, count);
3034 session_add_audio_bus (aux, input_chan, output_chan, route_group, count);
3040 ARDOUR_UI::mixer_settings () const
3045 node = session->instant_xml(X_("Mixer"));
3047 node = Config->instant_xml(X_("Mixer"));
3051 node = new XMLNode (X_("Mixer"));
3058 ARDOUR_UI::editor_settings () const
3063 node = session->instant_xml(X_("Editor"));
3065 node = Config->instant_xml(X_("Editor"));
3069 if (getenv("ARDOUR_INSTANT_XML_PATH")) {
3070 node = Config->instant_xml(getenv("ARDOUR_INSTANT_XML_PATH"));
3075 node = new XMLNode (X_("Editor"));
3082 ARDOUR_UI::keyboard_settings () const
3086 node = Config->extra_xml(X_("Keyboard"));
3089 node = new XMLNode (X_("Keyboard"));
3095 ARDOUR_UI::create_xrun_marker(nframes_t where)
3097 editor->mouse_add_new_marker (where, false, true);
3101 ARDOUR_UI::halt_on_xrun_message ()
3103 MessageDialog msg (*editor,
3104 _("Recording was stopped because your system could not keep up."));
3109 ARDOUR_UI::xrun_handler(nframes_t where)
3115 ENSURE_GUI_THREAD (bind(mem_fun(*this, &ARDOUR_UI::xrun_handler), where));
3117 if (session && Config->get_create_xrun_marker() && session->actively_recording()) {
3118 create_xrun_marker(where);
3121 if (session && Config->get_stop_recording_on_xrun() && session->actively_recording()) {
3122 halt_on_xrun_message ();
3127 ARDOUR_UI::push_buffer_stats (uint32_t capture, uint32_t playback)
3132 while (disk_buffer_stats.size() > 60) {
3133 disk_buffer_stats.pop_front ();
3136 disk_buffer_stats.push_back (DiskBufferStat (now, capture, playback));
3140 ARDOUR_UI::write_buffer_stats ()
3146 char path[PATH_MAX+1]; int fd;
3148 strcpy (path, "ardourBufferingXXXXXX");
3150 if ((fd = mkstemp (path )) < 0) {
3151 cerr << X_("cannot find temporary name for ardour buffer stats") << endl;
3159 cerr << string_compose (X_("cannot open file %1 for ardour buffer stats"), path) << endl;
3163 for (list<DiskBufferStat>::iterator i = disk_buffer_stats.begin(); i != disk_buffer_stats.end(); ++i) {
3164 localtime_r (&(*i).when, &tm);
3165 strftime (buf, sizeof (buf), "%T", &tm);
3166 fout << buf << ' ' << (*i).capture << ' ' << (*i).playback << endl;
3169 disk_buffer_stats.clear ();
3173 cerr << "Ardour buffering statistics can be found in: " << path << endl;
3177 ARDOUR_UI::disk_overrun_handler ()
3179 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
3181 write_buffer_stats ();
3183 if (!have_disk_speed_dialog_displayed) {
3184 have_disk_speed_dialog_displayed = true;
3185 MessageDialog* msg = new MessageDialog (*editor, _("\
3186 The disk system on your computer\n\
3187 was not able to keep up with Ardour.\n\
3189 Specifically, it failed to write data to disk\n\
3190 quickly enough to keep up with recording.\n"));
3191 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
3197 ARDOUR_UI::disk_underrun_handler ()
3199 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
3201 write_buffer_stats ();
3203 if (!have_disk_speed_dialog_displayed) {
3204 have_disk_speed_dialog_displayed = true;
3205 MessageDialog* msg = new MessageDialog (*editor,
3206 _("The disk system on your computer\n\
3207 was not able to keep up with Ardour.\n\
3209 Specifically, it failed to read data from disk\n\
3210 quickly enough to keep up with playback.\n"));
3211 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
3217 ARDOUR_UI::disk_speed_dialog_gone (int /*ignored_response*/, MessageDialog* msg)
3219 have_disk_speed_dialog_displayed = false;
3224 ARDOUR_UI::session_dialog (std::string msg)
3226 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::session_dialog), msg));
3231 d = new MessageDialog (*editor, msg, false, MESSAGE_INFO, BUTTONS_OK, true);
3233 d = new MessageDialog (msg, false, MESSAGE_INFO, BUTTONS_OK, true);
3242 ARDOUR_UI::pending_state_dialog ()
3244 HBox* hbox = new HBox();
3245 Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG);
3246 ArdourDialog dialog (_("Crash Recovery"), true);
3248 This session appears to have been in\n\
3249 middle of recording when ardour or\n\
3250 the computer was shutdown.\n\
3252 Ardour can recover any captured audio for\n\
3253 you, or it can ignore it. Please decide\n\
3254 what you would like to do.\n"));
3255 image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
3256 hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
3257 hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
3258 dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
3259 dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
3260 dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
3261 dialog.set_default_response (RESPONSE_ACCEPT);
3262 dialog.set_position (WIN_POS_CENTER);
3267 switch (dialog.run ()) {
3268 case RESPONSE_ACCEPT:
3276 ARDOUR_UI::sr_mismatch_dialog (nframes_t desired, nframes_t actual)
3278 HBox* hbox = new HBox();
3279 Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG);
3280 ArdourDialog dialog (_("Sample Rate Mismatch"), true);
3281 Label message (string_compose (_("\
3282 This session was created with a sample rate of %1 Hz\n\
3284 The audioengine is currently running at %2 Hz\n"), desired, actual));
3286 image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
3287 hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
3288 hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
3289 dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
3290 dialog.add_button (_("Do not load session"), RESPONSE_REJECT);
3291 dialog.add_button (_("Load session anyway"), RESPONSE_ACCEPT);
3292 dialog.set_default_response (RESPONSE_ACCEPT);
3293 dialog.set_position (WIN_POS_CENTER);
3298 switch (dialog.run ()) {
3299 case RESPONSE_ACCEPT:
3308 ARDOUR_UI::disconnect_from_jack ()
3311 if( engine->disconnect_from_jack ()) {
3312 MessageDialog msg (*editor, _("Could not disconnect from JACK"));
3316 update_sample_rate (0);
3321 ARDOUR_UI::reconnect_to_jack ()
3324 if (engine->reconnect_to_jack ()) {
3325 MessageDialog msg (*editor, _("Could not reconnect to JACK"));
3329 update_sample_rate (0);
3334 ARDOUR_UI::use_config ()
3337 XMLNode* node = Config->extra_xml (X_("TransportControllables"));
3339 set_transport_controllable_state (*node);
3344 ARDOUR_UI::update_transport_clocks (nframes_t pos)
3346 if (Config->get_primary_clock_delta_edit_cursor()) {
3347 primary_clock.set (pos, false, editor->get_preferred_edit_position(), 1);
3349 primary_clock.set (pos, 0, true);
3352 if (Config->get_secondary_clock_delta_edit_cursor()) {
3353 secondary_clock.set (pos, false, editor->get_preferred_edit_position(), 2);
3355 secondary_clock.set (pos);
3358 if (big_clock_window) {
3359 big_clock.set (pos);
3364 ARDOUR_UI::record_state_changed ()
3366 ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::record_state_changed));
3368 if (!session || !big_clock_window) {
3369 /* why bother - the clock isn't visible */
3373 Session::RecordState const r = session->record_status ();
3374 bool const h = session->have_rec_enabled_diskstream ();
3376 if (r == Session::Recording && h) {
3377 big_clock.set_widget_name ("BigClockRecording");
3379 big_clock.set_widget_name ("BigClockNonRecording");
3384 ARDOUR_UI::first_idle ()
3387 session->allow_auto_play (true);
3391 editor->first_idle();
3394 Keyboard::set_can_save_keybindings (true);
3399 ARDOUR_UI::store_clock_modes ()
3401 XMLNode* node = new XMLNode(X_("ClockModes"));
3403 for (vector<AudioClock*>::iterator x = AudioClock::clocks.begin(); x != AudioClock::clocks.end(); ++x) {
3404 node->add_property ((*x)->name().c_str(), enum_2_string ((*x)->mode()));
3407 session->add_extra_xml (*node);
3408 session->set_dirty ();
3413 ARDOUR_UI::TransportControllable::TransportControllable (std::string name, ARDOUR_UI& u, ToggleType tp)
3414 : Controllable (name), ui (u), type(tp)
3420 ARDOUR_UI::TransportControllable::set_value (float val)
3422 if (type == ShuttleControl) {
3429 fract = -((0.5f - val)/0.5f);
3431 fract = ((val - 0.5f)/0.5f);
3435 ui.set_shuttle_fract (fract);
3440 /* do nothing: these are radio-style actions */
3444 const char *action = 0;
3448 action = X_("Roll");
3451 action = X_("Stop");
3454 action = X_("Goto Start");
3457 action = X_("Goto End");
3460 action = X_("Loop");
3463 action = X_("Play Selection");
3466 action = X_("Record");
3476 Glib::RefPtr<Action> act = ActionManager::get_action ("Transport", action);
3484 ARDOUR_UI::TransportControllable::get_value (void) const
3503 case ShuttleControl:
3513 ARDOUR_UI::TransportControllable::set_id (const string& str)
3519 ARDOUR_UI::setup_profile ()
3521 if (gdk_screen_width() < 1200) {
3522 Profile->set_small_screen ();
3526 if (getenv ("ARDOUR_SAE")) {
3527 Profile->set_sae ();
3528 Profile->set_single_package ();