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 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
118 : Gtkmm2ext::UI (X_("Ardour"), argcp, argvp),
120 primary_clock (X_("primary"), false, X_("TransportClockDisplay"), true, false, true),
121 secondary_clock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, false, true),
122 preroll_clock (X_("preroll"), false, X_("PreRollClock"), true, true),
123 postroll_clock (X_("postroll"), false, X_("PostRollClock"), true, true),
127 preroll_button (_("pre\nroll")),
128 postroll_button (_("post\nroll")),
132 big_clock (X_("bigclock"), false, "BigClockNonRecording", true, false, true),
136 roll_controllable (new TransportControllable ("transport roll", *this, TransportControllable::Roll)),
137 stop_controllable (new TransportControllable ("transport stop", *this, TransportControllable::Stop)),
138 goto_start_controllable (new TransportControllable ("transport goto start", *this, TransportControllable::GotoStart)),
139 goto_end_controllable (new TransportControllable ("transport goto end", *this, TransportControllable::GotoEnd)),
140 auto_loop_controllable (new TransportControllable ("transport auto loop", *this, TransportControllable::AutoLoop)),
141 play_selection_controllable (new TransportControllable ("transport play selection", *this, TransportControllable::PlaySelection)),
142 rec_controllable (new TransportControllable ("transport rec-enable", *this, TransportControllable::RecordEnable)),
143 shuttle_controllable (new TransportControllable ("shuttle", *this, TransportControllable::ShuttleControl)),
144 shuttle_controller_binding_proxy (shuttle_controllable),
146 roll_button (roll_controllable),
147 stop_button (stop_controllable),
148 goto_start_button (goto_start_controllable),
149 goto_end_button (goto_end_controllable),
150 auto_loop_button (auto_loop_controllable),
151 play_selection_button (play_selection_controllable),
152 rec_button (rec_controllable),
154 shuttle_units_button (_("% ")),
156 punch_in_button (_("Punch In")),
157 punch_out_button (_("Punch Out")),
158 auto_return_button (_("Auto Return")),
159 auto_play_button (_("Auto Play")),
160 auto_input_button (_("Auto Input")),
161 click_button (_("Click")),
162 time_master_button (_("time\nmaster")),
164 auditioning_alert_button (_("AUDITION")),
165 solo_alert_button (_("SOLO")),
167 error_log_button (_("Errors"))
170 using namespace Gtk::Menu_Helpers;
176 // _auto_display_errors = false;
178 * This was commented out as it wasn't defined
179 * in A3 IIRC. If this is not needed it should
180 * be completely removed.
188 if (theArdourUI == 0) {
192 ui_config = new UIConfiguration();
193 theme_manager = new ThemeManager();
200 _session_is_new = false;
201 big_clock_window = 0;
202 session_selector_window = 0;
203 last_key_press_time = 0;
204 _will_create_new_session_automatically = false;
205 add_route_dialog = 0;
207 rc_option_editor = 0;
208 session_option_editor = 0;
210 open_session_selector = 0;
211 have_configure_timeout = false;
212 have_disk_speed_dialog_displayed = false;
213 session_loaded = false;
214 last_speed_displayed = -1.0f;
215 ignore_dual_punch = false;
216 _mixer_on_top = false;
218 roll_button.unset_flags (Gtk::CAN_FOCUS);
219 stop_button.unset_flags (Gtk::CAN_FOCUS);
220 goto_start_button.unset_flags (Gtk::CAN_FOCUS);
221 goto_end_button.unset_flags (Gtk::CAN_FOCUS);
222 auto_loop_button.unset_flags (Gtk::CAN_FOCUS);
223 play_selection_button.unset_flags (Gtk::CAN_FOCUS);
224 rec_button.unset_flags (Gtk::CAN_FOCUS);
226 last_configure_time= 0;
228 shuttle_grabbed = false;
230 shuttle_max_speed = 8.0f;
232 shuttle_style_menu = 0;
233 shuttle_unit_menu = 0;
235 // We do not have jack linked in yet so;
237 last_shuttle_request = last_peak_grab = 0; // get_microseconds();
239 ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
240 ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
242 /* handle dialog requests */
244 ARDOUR::Session::Dialog.connect (mem_fun(*this, &ARDOUR_UI::session_dialog));
246 /* handle pending state with a dialog */
248 ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
250 /* handle sr mismatch with a dialog */
252 ARDOUR::Session::AskAboutSampleRateMismatch.connect (mem_fun(*this, &ARDOUR_UI::sr_mismatch_dialog));
254 /* lets get this party started */
257 if (ARDOUR::init (ARDOUR_COMMAND_LINE::use_vst, ARDOUR_COMMAND_LINE::try_hw_optimization)) {
258 throw failed_constructor ();
261 setup_gtk_ardour_enums ();
264 GainMeter::setup_slider_pix ();
265 RouteTimeAxisView::setup_slider_pix ();
266 SendProcessorEntry::setup_slider_pix ();
268 } catch (failed_constructor& err) {
269 error << _("could not initialize Ardour.") << endmsg;
274 /* we like keyboards */
276 keyboard = new Keyboard;
280 starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
281 stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
286 /** @return true if a session was chosen and `apply' clicked, otherwise false if `cancel' was clicked */
288 ARDOUR_UI::run_startup (bool should_be_new)
291 _startup = new ArdourStartup ();
294 _startup->set_new_only (should_be_new);
295 _startup->present ();
299 /* we don't return here until the startup assistant is finished */
303 return _startup->applying ();
307 ARDOUR_UI::create_engine ()
309 // this gets called every time by new_session()
315 loading_message (_("Starting audio engine"));
318 engine = new ARDOUR::AudioEngine (ARDOUR_COMMAND_LINE::jack_client_name);
325 engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
326 engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
327 engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
328 engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
336 ARDOUR_UI::post_engine ()
338 /* Things to be done once we create the AudioEngine
341 MIDI::Manager::instance()->set_api_data (engine->jack());
344 ARDOUR::init_post_engine ();
346 ActionManager::init ();
349 if (setup_windows ()) {
350 throw failed_constructor ();
353 check_memory_locking();
355 /* this is the first point at which all the keybindings are available */
357 if (ARDOUR_COMMAND_LINE::show_key_actions) {
358 vector<string> names;
359 vector<string> paths;
361 vector<AccelKey> bindings;
363 ActionManager::get_all_actions (names, paths, keys, bindings);
365 vector<string>::iterator n;
366 vector<string>::iterator k;
367 for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) {
368 cerr << "Action: " << (*n) << " bound to " << (*k) << endl;
374 blink_timeout_tag = -1;
376 /* this being a GUI and all, we want peakfiles */
378 AudioFileSource::set_build_peakfiles (true);
379 AudioFileSource::set_build_missing_peakfiles (true);
381 /* set default clock modes */
383 if (Profile->get_sae()) {
384 primary_clock.set_mode (AudioClock::BBT);
385 secondary_clock.set_mode (AudioClock::MinSec);
387 primary_clock.set_mode (AudioClock::Timecode);
388 secondary_clock.set_mode (AudioClock::BBT);
391 /* start the time-of-day-clock */
394 /* OS X provides an always visible wallclock, so don't be stupid */
395 update_wall_clock ();
396 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
399 update_disk_space ();
401 update_sample_rate (engine->frame_rate());
403 Config->ParameterChanged.connect (mem_fun (*this, &ARDOUR_UI::parameter_changed));
404 Config->map_parameters (mem_fun (*this, &ARDOUR_UI::parameter_changed));
406 /* now start and maybe save state */
408 if (do_engine_start () == 0) {
409 if (session && _session_is_new) {
410 /* we need to retain initial visual
411 settings for a new session
413 session->save_state ("");
418 ARDOUR_UI::~ARDOUR_UI ()
420 save_ardour_state ();
425 delete add_route_dialog;
429 ARDOUR_UI::pop_back_splash ()
431 if (Splash::instance()) {
432 // Splash::instance()->pop_back();
433 Splash::instance()->hide ();
438 ARDOUR_UI::configure_timeout ()
440 if (last_configure_time == 0) {
441 /* no configure events yet */
445 /* force a gap of 0.5 seconds since the last configure event
448 if (get_microseconds() - last_configure_time < 500000) {
451 have_configure_timeout = false;
452 save_ardour_state ();
458 ARDOUR_UI::configure_handler (GdkEventConfigure* /*conf*/)
460 if (have_configure_timeout) {
461 last_configure_time = get_microseconds();
463 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
464 have_configure_timeout = true;
471 ARDOUR_UI::set_transport_controllable_state (const XMLNode& node)
473 const XMLProperty* prop;
475 if ((prop = node.property ("roll")) != 0) {
476 roll_controllable->set_id (prop->value());
478 if ((prop = node.property ("stop")) != 0) {
479 stop_controllable->set_id (prop->value());
481 if ((prop = node.property ("goto-start")) != 0) {
482 goto_start_controllable->set_id (prop->value());
484 if ((prop = node.property ("goto-end")) != 0) {
485 goto_end_controllable->set_id (prop->value());
487 if ((prop = node.property ("auto-loop")) != 0) {
488 auto_loop_controllable->set_id (prop->value());
490 if ((prop = node.property ("play-selection")) != 0) {
491 play_selection_controllable->set_id (prop->value());
493 if ((prop = node.property ("rec")) != 0) {
494 rec_controllable->set_id (prop->value());
496 if ((prop = node.property ("shuttle")) != 0) {
497 shuttle_controllable->set_id (prop->value());
502 ARDOUR_UI::get_transport_controllable_state ()
504 XMLNode* node = new XMLNode(X_("TransportControllables"));
507 roll_controllable->id().print (buf, sizeof (buf));
508 node->add_property (X_("roll"), buf);
509 stop_controllable->id().print (buf, sizeof (buf));
510 node->add_property (X_("stop"), buf);
511 goto_start_controllable->id().print (buf, sizeof (buf));
512 node->add_property (X_("goto_start"), buf);
513 goto_end_controllable->id().print (buf, sizeof (buf));
514 node->add_property (X_("goto_end"), buf);
515 auto_loop_controllable->id().print (buf, sizeof (buf));
516 node->add_property (X_("auto_loop"), buf);
517 play_selection_controllable->id().print (buf, sizeof (buf));
518 node->add_property (X_("play_selection"), buf);
519 rec_controllable->id().print (buf, sizeof (buf));
520 node->add_property (X_("rec"), buf);
521 shuttle_controllable->id().print (buf, sizeof (buf));
522 node->add_property (X_("shuttle"), buf);
528 ARDOUR_UI::save_ardour_state ()
530 if (!keyboard || !mixer || !editor) {
534 /* XXX this is all a bit dubious. add_extra_xml() uses
535 a different lifetime model from add_instant_xml().
538 XMLNode* node = new XMLNode (keyboard->get_state());
539 Config->add_extra_xml (*node);
540 Config->add_extra_xml (get_transport_controllable_state());
541 if (_startup && _startup->engine_control() && _startup->engine_control()->was_used()) {
542 Config->add_extra_xml (_startup->engine_control()->get_state());
544 Config->save_state();
545 ui_config->save_state ();
547 XMLNode enode(static_cast<Stateful*>(editor)->get_state());
548 XMLNode mnode(mixer->get_state());
551 session->add_instant_xml (enode);
552 session->add_instant_xml (mnode);
554 Config->add_instant_xml (enode);
555 Config->add_instant_xml (mnode);
558 Keyboard::save_keybindings ();
562 ARDOUR_UI::autosave_session ()
564 if (g_main_depth() > 1) {
565 /* inside a recursive main loop,
566 give up because we may not be able to
572 if (!Config->get_periodic_safety_backups()) {
577 session->maybe_write_autosave();
584 ARDOUR_UI::update_autosave ()
586 ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::update_autosave));
588 if (session && session->dirty()) {
589 if (_autosave_connection.connected()) {
590 _autosave_connection.disconnect();
593 _autosave_connection = Glib::signal_timeout().connect (mem_fun (*this, &ARDOUR_UI::autosave_session),
594 Config->get_periodic_safety_backup_interval() * 1000);
597 if (_autosave_connection.connected()) {
598 _autosave_connection.disconnect();
604 ARDOUR_UI::backend_audio_error (bool we_set_params, Gtk::Window* toplevel)
608 title = _("Ardour could not start JACK");
610 title = _("Ardour could not connect to JACK.");
613 MessageDialog win (title,
619 win.set_secondary_text(_("There are several possible reasons:\n\
621 1) You requested audio parameters that are not supported..\n\
622 2) JACK is running as another user.\n\
624 Please consider the possibilities, and perhaps try different parameters."));
626 win.set_secondary_text(_("There are several possible reasons:\n\
628 1) JACK is not running.\n\
629 2) JACK is running as another user, perhaps root.\n\
630 3) There is already another client called \"ardour\".\n\
632 Please consider the possibilities, and perhaps (re)start JACK."));
636 win.set_transient_for (*toplevel);
640 win.add_button (Stock::OK, RESPONSE_CLOSE);
642 win.add_button (Stock::QUIT, RESPONSE_CLOSE);
645 win.set_default_response (RESPONSE_CLOSE);
648 win.set_position (Gtk::WIN_POS_CENTER);
651 /* we just don't care about the result, but we want to block */
657 ARDOUR_UI::startup ()
659 XMLNode* audio_setup = Config->extra_xml ("AudioSetup");
661 if (audio_setup && _startup && _startup->engine_control()) {
662 _startup->engine_control()->set_state (*audio_setup);
665 if (get_session_parameters (true, ARDOUR_COMMAND_LINE::new_session)) {
671 goto_editor_window ();
673 BootMessage (_("Ardour is ready for use"));
678 ARDOUR_UI::no_memory_warning ()
680 XMLNode node (X_("no-memory-warning"));
681 Config->add_instant_xml (node);
685 ARDOUR_UI::check_memory_locking ()
688 /* OS X doesn't support mlockall(2), and so testing for memory locking capability there is pointless */
692 XMLNode* memory_warning_node = Config->instant_xml (X_("no-memory-warning"));
694 if (engine->is_realtime() && memory_warning_node == 0) {
696 struct rlimit limits;
698 long pages, page_size;
700 if ((page_size = sysconf (_SC_PAGESIZE)) < 0 ||(pages = sysconf (_SC_PHYS_PAGES)) < 0) {
703 ram = (int64_t) pages * (int64_t) page_size;
706 if (getrlimit (RLIMIT_MEMLOCK, &limits)) {
710 if (limits.rlim_cur != RLIM_INFINITY) {
712 if (ram == 0 || ((double) limits.rlim_cur / ram) < 0.75) {
715 MessageDialog msg (_("WARNING: Your system has a limit for maximum amount of locked memory. "
716 "This might cause Ardour to run out of memory before your system "
717 "runs out of memory. \n\n"
718 "You can view the memory limit with 'ulimit -l', "
719 "and it is normally controlled by /etc/security/limits.conf"));
721 VBox* vbox = msg.get_vbox();
723 CheckButton cb (_("Do not show this window again"));
725 cb.signal_toggled().connect (mem_fun (*this, &ARDOUR_UI::no_memory_warning));
727 hbox.pack_start (cb, true, false);
728 vbox->pack_start (hbox);
735 editor->ensure_float (msg);
749 if (session->transport_rolling()) {
750 session->request_stop ();
754 if (session->dirty()) {
755 switch (ask_about_saving_session(_("quit"))) {
760 /* use the default name */
761 if (save_state_canfail ("")) {
762 /* failed - don't quit */
763 MessageDialog msg (*editor,
765 Ardour was unable to save your session.\n\n\
766 If you still wish to quit, please use the\n\n\
767 \"Just quit\" option."));
778 // session->set_deletion_in_progress ();
782 ArdourDialog::close_all_dialogs ();
784 save_ardour_state ();
789 ARDOUR_UI::ask_about_saving_session (const string & what)
791 ArdourDialog window (_("ardour: save session?"));
792 Gtk::HBox dhbox; // the hbox for the image and text
793 Gtk::Label prompt_label;
794 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_WARNING, Gtk::ICON_SIZE_DIALOG));
798 msg = string_compose(_("Don't %1"), what);
799 window.add_button (msg, RESPONSE_REJECT);
800 msg = string_compose(_("Just %1"), what);
801 window.add_button (msg, RESPONSE_APPLY);
802 msg = string_compose(_("Save and %1"), what);
803 window.add_button (msg, RESPONSE_ACCEPT);
805 window.set_default_response (RESPONSE_ACCEPT);
807 Gtk::Button noquit_button (msg);
808 noquit_button.set_name ("EditorGTKButton");
813 if (session->snap_name() == session->name()) {
816 type = _("snapshot");
818 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?"),
819 type, session->snap_name());
821 prompt_label.set_text (prompt);
822 prompt_label.set_name (X_("PrompterLabel"));
823 prompt_label.set_alignment(ALIGN_LEFT, ALIGN_TOP);
825 dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP);
826 dhbox.set_homogeneous (false);
827 dhbox.pack_start (*dimage, false, false, 5);
828 dhbox.pack_start (prompt_label, true, false, 5);
829 window.get_vbox()->pack_start (dhbox);
831 window.set_name (_("Prompter"));
832 window.set_position (Gtk::WIN_POS_MOUSE);
833 window.set_modal (true);
834 window.set_resizable (false);
840 window.set_keep_above (true);
843 ResponseType r = (ResponseType) window.run();
848 case RESPONSE_ACCEPT: // save and get out of here
850 case RESPONSE_APPLY: // get out of here
860 ARDOUR_UI::every_second ()
863 update_buffer_load ();
864 update_disk_space ();
869 ARDOUR_UI::every_point_one_seconds ()
871 update_speed_display ();
872 RapidScreenUpdate(); /* EMIT_SIGNAL */
877 ARDOUR_UI::every_point_zero_one_seconds ()
879 // august 2007: actual update frequency: 40Hz, not 100Hz
881 SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
886 ARDOUR_UI::update_sample_rate (nframes_t ignored)
890 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
892 if (!engine->connected()) {
894 snprintf (buf, sizeof (buf), _("disconnected"));
898 nframes_t rate = engine->frame_rate();
900 if (fmod (rate, 1000.0) != 0.0) {
901 snprintf (buf, sizeof (buf), _("%.1f kHz / %4.1f ms"),
902 (float) rate/1000.0f,
903 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
905 snprintf (buf, sizeof (buf), _("%u kHz / %4.1f ms"),
907 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
911 sample_rate_label.set_text (buf);
915 ARDOUR_UI::update_cpu_load ()
918 snprintf (buf, sizeof (buf), _("DSP: %5.1f%%"), engine->get_cpu_load());
919 cpu_load_label.set_text (buf);
923 ARDOUR_UI::update_buffer_load ()
929 c = session->capture_load ();
930 p = session->playback_load ();
932 push_buffer_stats (c, p);
934 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"),
935 session->playback_load(), session->capture_load());
936 buffer_load_label.set_text (buf);
938 buffer_load_label.set_text ("");
943 ARDOUR_UI::count_recenabled_streams (Route& route)
945 Track* track = dynamic_cast<Track*>(&route);
946 if (track && track->diskstream()->record_enabled()) {
947 rec_enabled_streams += track->n_inputs().n_total();
952 ARDOUR_UI::update_disk_space()
958 nframes_t frames = session->available_capture_duration();
960 nframes_t fr = session->frame_rate();
962 if (frames == max_frames) {
963 strcpy (buf, _("Disk: 24hrs+"));
965 rec_enabled_streams = 0;
966 session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
968 if (rec_enabled_streams) {
969 frames /= rec_enabled_streams;
976 hrs = frames / (fr * 3600);
977 frames -= hrs * fr * 3600;
978 mins = frames / (fr * 60);
979 frames -= mins * fr * 60;
982 snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs);
985 disk_space_label.set_text (buf);
987 // An attempt to make the disk space label flash red when space has run out.
989 if (frames < fr * 60 * 5) {
990 /* disk_space_box.style ("disk_space_label_empty"); */
992 /* disk_space_box.style ("disk_space_label"); */
998 ARDOUR_UI::update_wall_clock ()
1005 tm_now = localtime (&now);
1007 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
1008 wall_clock_label.set_text (buf);
1014 ARDOUR_UI::session_menu (GdkEventButton */*ev*/)
1016 session_popup_menu->popup (0, 0);
1021 ARDOUR_UI::redisplay_recent_sessions ()
1023 std::vector<sys::path> session_directories;
1024 RecentSessionsSorter cmp;
1026 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
1027 recent_session_model->clear ();
1029 ARDOUR::RecentSessions rs;
1030 ARDOUR::read_recent_sessions (rs);
1033 recent_session_display.set_model (recent_session_model);
1037 // sort them alphabetically
1038 sort (rs.begin(), rs.end(), cmp);
1040 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
1041 session_directories.push_back ((*i).second);
1044 for (vector<sys::path>::const_iterator i = session_directories.begin();
1045 i != session_directories.end(); ++i)
1047 std::vector<sys::path> state_file_paths;
1049 // now get available states for this session
1051 get_state_files_in_directory (*i, state_file_paths);
1053 vector<string*>* states;
1054 vector<const gchar*> item;
1055 string fullpath = (*i).to_string();
1057 /* remove any trailing / */
1059 if (fullpath[fullpath.length()-1] == '/') {
1060 fullpath = fullpath.substr (0, fullpath.length()-1);
1063 /* check whether session still exists */
1064 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
1065 /* session doesn't exist */
1066 cerr << "skipping non-existent session " << fullpath << endl;
1070 /* now get available states for this session */
1072 if ((states = Session::possible_states (fullpath)) == 0) {
1073 /* no state file? */
1077 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
1079 Gtk::TreeModel::Row row = *(recent_session_model->append());
1081 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
1082 row[recent_session_columns.fullpath] = fullpath;
1084 if (state_file_names.size() > 1) {
1088 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
1089 i2 != state_file_names.end(); ++i2)
1092 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
1094 child_row[recent_session_columns.visible_name] = *i2;
1095 child_row[recent_session_columns.fullpath] = fullpath;
1100 recent_session_display.set_model (recent_session_model);
1104 ARDOUR_UI::build_session_selector ()
1106 session_selector_window = new ArdourDialog (_("Recent Sessions"));
1108 Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
1110 session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
1111 session_selector_window->add_button (Stock::OPEN, RESPONSE_ACCEPT);
1112 session_selector_window->set_default_response (RESPONSE_ACCEPT);
1113 recent_session_model = TreeStore::create (recent_session_columns);
1114 recent_session_display.set_model (recent_session_model);
1115 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1116 recent_session_display.set_headers_visible (false);
1117 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
1118 recent_session_display.signal_row_activated().connect (mem_fun (*this, &ARDOUR_UI::recent_session_row_activated));
1120 scroller->add (recent_session_display);
1121 scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1123 session_selector_window->set_name ("SessionSelectorWindow");
1124 session_selector_window->set_size_request (200, 400);
1125 session_selector_window->get_vbox()->pack_start (*scroller);
1127 recent_session_display.show();
1129 //session_selector_window->get_vbox()->show();
1133 ARDOUR_UI::recent_session_row_activated (const TreePath& /*path*/, TreeViewColumn* /*col*/)
1135 session_selector_window->response (RESPONSE_ACCEPT);
1139 ARDOUR_UI::open_recent_session ()
1141 bool can_return = (session != 0);
1143 if (session_selector_window == 0) {
1144 build_session_selector ();
1147 redisplay_recent_sessions ();
1151 session_selector_window->set_position (WIN_POS_MOUSE);
1153 ResponseType r = (ResponseType) session_selector_window->run ();
1156 case RESPONSE_ACCEPT:
1160 session_selector_window->hide();
1167 if (recent_session_display.get_selection()->count_selected_rows() == 0) {
1171 session_selector_window->hide();
1173 Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
1175 if (i == recent_session_model->children().end()) {
1179 Glib::ustring path = (*i)[recent_session_columns.fullpath];
1180 Glib::ustring state = (*i)[recent_session_columns.visible_name];
1182 _session_is_new = false;
1184 if (load_session (path, state) == 0) {
1193 ARDOUR_UI::check_audioengine ()
1196 if (!engine->connected()) {
1197 MessageDialog msg (_("Ardour is not connected to JACK\n"
1198 "You cannot open or close sessions in this condition"));
1210 ARDOUR_UI::open_session ()
1212 if (!check_audioengine()) {
1217 /* popup selector window */
1219 if (open_session_selector == 0) {
1221 /* ardour sessions are folders */
1223 open_session_selector = new Gtk::FileChooserDialog (_("Open Session"), FILE_CHOOSER_ACTION_OPEN);
1224 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1225 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
1226 open_session_selector->set_default_response(Gtk::RESPONSE_ACCEPT);
1228 FileFilter session_filter;
1229 session_filter.add_pattern ("*.ardour");
1230 session_filter.set_name (_("Ardour sessions"));
1231 open_session_selector->add_filter (session_filter);
1232 open_session_selector->set_filter (session_filter);
1235 int response = open_session_selector->run();
1236 open_session_selector->hide ();
1239 case RESPONSE_ACCEPT:
1242 open_session_selector->hide();
1246 open_session_selector->hide();
1247 string session_path = open_session_selector->get_filename();
1251 if (session_path.length() > 0) {
1252 if (ARDOUR::find_session (session_path, path, name, isnew) == 0) {
1253 _session_is_new = isnew;
1254 load_session (path, name);
1261 ARDOUR_UI::session_add_midi_route (bool disk, RouteGroup* route_group, uint32_t how_many)
1263 list<boost::shared_ptr<MidiTrack> > tracks;
1266 warning << _("You cannot add a track without a session already loaded.") << endmsg;
1273 tracks = session->new_midi_track (ARDOUR::Normal, route_group, how_many);
1275 if (tracks.size() != how_many) {
1276 if (how_many == 1) {
1277 error << _("could not create a new midi track") << endmsg;
1279 error << string_compose (_("could not create %1 new midi tracks"), how_many) << endmsg;
1283 if ((route = session->new_midi_route ()) == 0) {
1284 error << _("could not create new midi bus") << endmsg;
1290 MessageDialog msg (*editor,
1291 _("There are insufficient JACK ports available\n\
1292 to create a new track or bus.\n\
1293 You should save Ardour, exit and\n\
1294 restart JACK with more ports."));
1301 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)
1303 list<boost::shared_ptr<AudioTrack> > tracks;
1307 warning << _("You cannot add a track or bus without a session already loaded.") << endmsg;
1313 tracks = session->new_audio_track (input_channels, output_channels, mode, route_group, how_many);
1315 if (tracks.size() != how_many) {
1316 if (how_many == 1) {
1317 error << _("could not create a new audio track") << endmsg;
1319 error << string_compose (_("could only create %1 of %2 new audio %3"),
1320 tracks.size(), how_many, (track ? _("tracks") : _("busses"))) << endmsg;
1326 routes = session->new_audio_route (aux, input_channels, output_channels, route_group, how_many);
1328 if (routes.size() != how_many) {
1329 if (how_many == 1) {
1330 error << _("could not create a new audio track") << endmsg;
1332 error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
1338 if (need_control_room_outs) {
1344 route->set_stereo_control_outs (control_lr_channels);
1345 route->control_outs()->set_stereo_pan (pans, this);
1347 #endif /* CONTROLOUTS */
1351 MessageDialog msg (*editor,
1352 _("There are insufficient JACK ports available\n\
1353 to create a new track or bus.\n\
1354 You should save Ardour, exit and\n\
1355 restart JACK with more ports."));
1362 ARDOUR_UI::do_transport_locate (nframes_t new_position)
1364 nframes_t _preroll = 0;
1367 // XXX CONFIG_CHANGE FIX - requires AnyTime handling
1368 // _preroll = session->convert_to_frames_at (new_position, Config->get_preroll());
1370 if (new_position > _preroll) {
1371 new_position -= _preroll;
1376 session->request_locate (new_position);
1381 ARDOUR_UI::transport_goto_start ()
1384 session->goto_start();
1387 /* force displayed area in editor to start no matter
1388 what "follow playhead" setting is.
1392 editor->reset_x_origin (session->current_start_frame());
1398 ARDOUR_UI::transport_goto_zero ()
1401 session->request_locate (0);
1404 /* force displayed area in editor to start no matter
1405 what "follow playhead" setting is.
1409 editor->reset_x_origin (0);
1415 ARDOUR_UI::transport_goto_wallclock ()
1417 if (session && editor) {
1424 localtime_r (&now, &tmnow);
1426 frames = tmnow.tm_hour * (60 * 60 * session->frame_rate());
1427 frames += tmnow.tm_min * (60 * session->frame_rate());
1428 frames += tmnow.tm_sec * session->frame_rate();
1430 session->request_locate (frames);
1432 /* force displayed area in editor to start no matter
1433 what "follow playhead" setting is.
1437 editor->reset_x_origin (frames - (editor->current_page_frames()/2));
1443 ARDOUR_UI::transport_goto_end ()
1446 nframes_t frame = session->current_end_frame();
1447 session->request_locate (frame);
1449 /* force displayed area in editor to start no matter
1450 what "follow playhead" setting is.
1454 editor->reset_x_origin (frame);
1460 ARDOUR_UI::transport_stop ()
1466 if (session->is_auditioning()) {
1467 session->cancel_audition ();
1471 session->request_stop ();
1475 ARDOUR_UI::transport_stop_and_forget_capture ()
1478 session->request_stop (true);
1483 ARDOUR_UI::remove_last_capture()
1486 editor->remove_last_capture();
1491 ARDOUR_UI::transport_record (bool roll)
1495 switch (session->record_status()) {
1496 case Session::Disabled:
1497 if (session->ntracks() == 0) {
1498 MessageDialog msg (*editor, _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu."));
1502 session->maybe_enable_record ();
1507 case Session::Recording:
1509 session->request_stop();
1511 session->disable_record (false, true);
1515 case Session::Enabled:
1516 session->disable_record (false, true);
1519 //cerr << "ARDOUR_UI::transport_record () called roll = " << roll << " session->record_status() = " << session->record_status() << endl;
1523 ARDOUR_UI::transport_roll ()
1529 if (session->is_auditioning()) {
1533 if (session->config.get_external_sync()) {
1534 switch (session->config.get_sync_source()) {
1538 /* transport controlled by the master */
1543 bool rolling = session->transport_rolling();
1545 if (session->get_play_loop()) {
1546 session->request_play_loop (false, true);
1547 } else if (session->get_play_range ()) {
1548 session->request_play_range (false, true);
1552 session->request_transport_speed (1.0f);
1555 map_transport_state ();
1559 ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode)
1566 if (session->is_auditioning()) {
1567 session->cancel_audition ();
1571 if (session->config.get_external_sync()) {
1572 switch (session->config.get_sync_source()) {
1576 /* transport controlled by the master */
1581 bool rolling = session->transport_rolling();
1582 bool affect_transport = true;
1584 if (rolling && roll_out_of_bounded_mode) {
1585 /* drop out of loop/range playback but leave transport rolling */
1586 if (session->get_play_loop()) {
1587 if (Config->get_seamless_loop()) {
1588 /* the disk buffers contain copies of the loop - we can't
1589 just keep playing, so stop the transport. the user
1590 can restart as they wish.
1592 affect_transport = true;
1594 /* disk buffers are normal, so we can keep playing */
1595 affect_transport = false;
1597 session->request_play_loop (false, true);
1598 } else if (session->get_play_range ()) {
1599 affect_transport = false;
1600 session->request_play_range (0, true);
1604 if (affect_transport) {
1606 session->request_stop (with_abort, true);
1608 session->request_transport_speed (1.0f);
1612 map_transport_state ();
1616 ARDOUR_UI::toggle_session_auto_loop ()
1619 if (session->get_play_loop()) {
1620 if (session->transport_rolling()) {
1621 Location * looploc = session->locations()->auto_loop_location();
1623 session->request_locate (looploc->start(), true);
1626 session->request_play_loop (false);
1629 Location * looploc = session->locations()->auto_loop_location();
1631 session->request_play_loop (true);
1638 ARDOUR_UI::transport_play_selection ()
1644 editor->play_selection ();
1648 ARDOUR_UI::transport_rewind (int option)
1650 float current_transport_speed;
1653 current_transport_speed = session->transport_speed();
1655 if (current_transport_speed >= 0.0f) {
1658 session->request_transport_speed (-1.0f);
1661 session->request_transport_speed (-4.0f);
1664 session->request_transport_speed (-0.5f);
1669 session->request_transport_speed (current_transport_speed * 1.5f);
1675 ARDOUR_UI::transport_forward (int option)
1677 float current_transport_speed;
1680 current_transport_speed = session->transport_speed();
1682 if (current_transport_speed <= 0.0f) {
1685 session->request_transport_speed (1.0f);
1688 session->request_transport_speed (4.0f);
1691 session->request_transport_speed (0.5f);
1696 session->request_transport_speed (current_transport_speed * 1.5f);
1703 ARDOUR_UI::toggle_record_enable (uint32_t dstream)
1709 boost::shared_ptr<Route> r;
1711 if ((r = session->route_by_remote_id (dstream)) != 0) {
1715 if ((t = dynamic_cast<Track*>(r.get())) != 0) {
1716 t->diskstream()->set_record_enabled (!t->diskstream()->record_enabled());
1725 ARDOUR_UI::map_transport_state ()
1727 ENSURE_GUI_THREAD(mem_fun (*this, &ARDOUR_UI::map_transport_state));
1730 auto_loop_button.set_visual_state (0);
1731 play_selection_button.set_visual_state (0);
1732 roll_button.set_visual_state (0);
1733 stop_button.set_visual_state (1);
1737 float sp = session->transport_speed();
1740 shuttle_fract = SHUTTLE_FRACT_SPEED1; /* speed = 1.0, believe it or not */
1741 shuttle_box.queue_draw ();
1742 } else if (sp == 0.0f) {
1744 shuttle_box.queue_draw ();
1745 update_disk_space ();
1750 if (session->get_play_range()) {
1752 play_selection_button.set_visual_state (1);
1753 roll_button.set_visual_state (0);
1754 auto_loop_button.set_visual_state (0);
1756 } else if (session->get_play_loop ()) {
1758 auto_loop_button.set_visual_state (1);
1759 play_selection_button.set_visual_state (0);
1760 roll_button.set_visual_state (0);
1764 roll_button.set_visual_state (1);
1765 play_selection_button.set_visual_state (0);
1766 auto_loop_button.set_visual_state (0);
1769 stop_button.set_visual_state (0);
1773 stop_button.set_visual_state (1);
1774 roll_button.set_visual_state (0);
1775 play_selection_button.set_visual_state (0);
1776 auto_loop_button.set_visual_state (0);
1782 ARDOUR_UI::engine_stopped ()
1784 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
1785 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1786 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1790 ARDOUR_UI::engine_running ()
1792 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
1793 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true);
1794 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
1796 Glib::RefPtr<Action> action;
1797 const char* action_name = 0;
1799 switch (engine->frames_per_cycle()) {
1801 action_name = X_("JACKLatency32");
1804 action_name = X_("JACKLatency64");
1807 action_name = X_("JACKLatency128");
1810 action_name = X_("JACKLatency512");
1813 action_name = X_("JACKLatency1024");
1816 action_name = X_("JACKLatency2048");
1819 action_name = X_("JACKLatency4096");
1822 action_name = X_("JACKLatency8192");
1825 /* XXX can we do anything useful ? */
1831 action = ActionManager::get_action (X_("JACK"), action_name);
1834 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic (action);
1835 ract->set_active ();
1841 ARDOUR_UI::engine_halted ()
1843 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
1845 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1846 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1848 update_sample_rate (0);
1850 MessageDialog msg (*editor,
1852 JACK has either been shutdown or it\n\
1853 disconnected Ardour because Ardour\n\
1854 was not fast enough. Try to restart\n\
1855 JACK, reconnect and save the session."));
1861 ARDOUR_UI::do_engine_start ()
1869 error << _("Unable to start the session running")
1879 ARDOUR_UI::setup_theme ()
1881 theme_manager->setup_theme();
1885 ARDOUR_UI::update_clocks ()
1887 if (!editor || !editor->dragging_playhead()) {
1888 Clock (session->audible_frame(), false, editor->get_preferred_edit_position()); /* EMIT_SIGNAL */
1893 ARDOUR_UI::start_clocking ()
1895 clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
1899 ARDOUR_UI::stop_clocking ()
1901 clock_signal_connection.disconnect ();
1905 ARDOUR_UI::toggle_clocking ()
1908 if (clock_button.get_active()) {
1917 ARDOUR_UI::_blink (void *arg)
1920 ((ARDOUR_UI *) arg)->blink ();
1927 Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
1931 ARDOUR_UI::start_blinking ()
1933 /* Start the blink signal. Everybody with a blinking widget
1934 uses Blink to drive the widget's state.
1937 if (blink_timeout_tag < 0) {
1939 blink_timeout_tag = g_timeout_add (240, _blink, this);
1944 ARDOUR_UI::stop_blinking ()
1946 if (blink_timeout_tag >= 0) {
1947 g_source_remove (blink_timeout_tag);
1948 blink_timeout_tag = -1;
1953 /** Ask the user for the name of a new shapshot and then take it.
1956 ARDOUR_UI::snapshot_session ()
1958 ArdourPrompter prompter (true);
1962 struct tm local_time;
1965 localtime_r (&n, &local_time);
1966 strftime (timebuf, sizeof(timebuf), "%FT%T", &local_time);
1968 prompter.set_name ("Prompter");
1969 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1970 prompter.set_title (_("Take Snapshot"));
1971 prompter.set_prompt (_("Name of New Snapshot"));
1972 prompter.set_initial_text (timebuf);
1974 switch (prompter.run()) {
1975 case RESPONSE_ACCEPT:
1977 prompter.get_result (snapname);
1979 bool do_save = (snapname.length() != 0);
1981 vector<sys::path> p;
1982 get_state_files_in_directory (session->session_directory().root_path(), p);
1983 vector<string> n = get_file_names_no_extension (p);
1984 if (find (n.begin(), n.end(), snapname) != n.end()) {
1986 ArdourDialog confirm (_("Confirm snapshot overwrite"), true);
1987 Label m (_("A snapshot already exists with that name. Do you want to overwrite it?"));
1988 confirm.get_vbox()->pack_start (m, true, true);
1989 confirm.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1990 confirm.add_button (_("Overwrite"), Gtk::RESPONSE_ACCEPT);
1991 confirm.show_all ();
1992 switch (confirm.run()) {
1993 case RESPONSE_CANCEL:
1999 save_state (snapname);
2010 ARDOUR_UI::save_state (const string & name)
2012 (void) save_state_canfail (name);
2016 ARDOUR_UI::save_state_canfail (string name)
2021 if (name.length() == 0) {
2022 name = session->snap_name();
2025 if ((ret = session->save_state (name)) != 0) {
2029 save_ardour_state (); /* XXX cannot fail? yeah, right ... */
2034 ARDOUR_UI::primary_clock_value_changed ()
2037 session->request_locate (primary_clock.current_time ());
2042 ARDOUR_UI::big_clock_value_changed ()
2045 session->request_locate (big_clock.current_time ());
2050 ARDOUR_UI::secondary_clock_value_changed ()
2053 session->request_locate (secondary_clock.current_time ());
2058 ARDOUR_UI::transport_rec_enable_blink (bool onoff)
2064 Session::RecordState const r = session->record_status ();
2065 bool const h = session->have_rec_enabled_diskstream ();
2067 if (r == Session::Enabled || (r == Session::Recording && !h)) {
2069 rec_button.set_visual_state (2);
2071 rec_button.set_visual_state (0);
2073 } else if (r == Session::Recording && h) {
2074 rec_button.set_visual_state (1);
2076 rec_button.set_visual_state (0);
2081 ARDOUR_UI::save_template ()
2083 ArdourPrompter prompter (true);
2086 if (!check_audioengine()) {
2090 prompter.set_name (X_("Prompter"));
2091 prompter.set_title (_("Save Mix Template"));
2092 prompter.set_prompt (_("Name for mix template:"));
2093 prompter.set_initial_text(session->name() + _("-template"));
2094 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
2096 switch (prompter.run()) {
2097 case RESPONSE_ACCEPT:
2098 prompter.get_result (name);
2100 if (name.length()) {
2101 session->save_template (name);
2111 ARDOUR_UI::edit_metadata ()
2113 SessionMetadataEditor dialog;
2114 dialog.set_session (session);
2115 editor->ensure_float (dialog);
2120 ARDOUR_UI::import_metadata ()
2122 SessionMetadataImporter dialog;
2123 dialog.set_session (session);
2124 editor->ensure_float (dialog);
2129 ARDOUR_UI::fontconfig_dialog ()
2132 /* X11 users will always have fontconfig info around, but new GTK-OSX users
2133 may not and it can take a while to build it. Warn them.
2136 Glib::ustring fontconfig = Glib::build_filename (Glib::get_home_dir(), ".fontconfig");
2138 if (!Glib::file_test (fontconfig, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
2139 MessageDialog msg (*_startup,
2140 _("Welcome to Ardour.\n\n"
2141 "The program will take a bit longer to start up\n"
2142 "while the system fonts are checked.\n\n"
2143 "This will only be done once, and you will\n"
2144 "not see this message again\n"),
2157 ARDOUR_UI::parse_cmdline_path (const Glib::ustring& cmdline_path, Glib::ustring& session_name, Glib::ustring& session_path, bool& existing_session)
2159 existing_session = false;
2161 if (Glib::file_test (cmdline_path, Glib::FILE_TEST_IS_DIR)) {
2162 session_path = cmdline_path;
2163 existing_session = true;
2164 } else if (Glib::file_test (cmdline_path, Glib::FILE_TEST_IS_REGULAR)) {
2165 session_path = Glib::path_get_dirname (string (cmdline_path));
2166 existing_session = true;
2168 /* it doesn't exist, assume the best */
2169 session_path = Glib::path_get_dirname (string (cmdline_path));
2172 session_name = basename_nosuffix (string (cmdline_path));
2176 ARDOUR_UI::load_cmdline_session (const Glib::ustring& session_name, const Glib::ustring& session_path, bool& existing_session)
2178 /* when this is called, the backend audio system must be running */
2180 /* the main idea here is to deal with the fact that a cmdline argument for the session
2181 can be interpreted in different ways - it could be a directory or a file, and before
2182 we load, we need to know both the session directory and the snapshot (statefile) within it
2183 that we are supposed to use.
2186 if (session_name.length() == 0 || session_path.length() == 0) {
2190 if (Glib::file_test (session_path, Glib::FILE_TEST_IS_DIR)) {
2192 Glib::ustring predicted_session_file;
2194 predicted_session_file = session_path;
2195 predicted_session_file += '/';
2196 predicted_session_file += session_name;
2197 predicted_session_file += ARDOUR::statefile_suffix;
2199 if (Glib::file_test (predicted_session_file, Glib::FILE_TEST_EXISTS)) {
2200 existing_session = true;
2203 } else if (Glib::file_test (session_path, Glib::FILE_TEST_EXISTS)) {
2205 if (session_path.find (ARDOUR::statefile_suffix) == session_path.length() - 7) {
2206 /* existing .ardour file */
2207 existing_session = true;
2211 existing_session = false;
2214 /* lets just try to load it */
2216 if (create_engine ()) {
2217 backend_audio_error (false, _startup);
2221 return load_session (session_path, session_name);
2225 ARDOUR_UI::ask_about_loading_existing_session (const Glib::ustring& session_path)
2227 Glib::ustring str = string_compose (_("This session\n%1\nalready exists. Do you want to open it?"), session_path);
2229 MessageDialog msg (str,
2231 Gtk::MESSAGE_WARNING,
2232 Gtk::BUTTONS_YES_NO,
2236 msg.set_name (X_("OpenExistingDialog"));
2237 msg.set_title (_("Open Existing Session"));
2238 msg.set_wmclass (X_("existing_session"), "Ardour");
2239 msg.set_position (Gtk::WIN_POS_MOUSE);
2242 switch (msg.run()) {
2251 ARDOUR_UI::build_session_from_nsd (const Glib::ustring& session_path, const Glib::ustring& session_name)
2256 AutoConnectOption iconnect;
2257 AutoConnectOption oconnect;
2261 if (Profile->get_sae()) {
2265 iconnect = AutoConnectPhysical;
2266 oconnect = AutoConnectMaster;
2267 nphysin = 0; // use all available
2268 nphysout = 0; // use all available
2272 /* get settings from advanced section of NSD */
2274 if (_startup->create_control_bus()) {
2275 cchns = (uint32_t) _startup->control_channel_count();
2280 if (_startup->create_master_bus()) {
2281 mchns = (uint32_t) _startup->master_channel_count();
2286 if (_startup->connect_inputs()) {
2287 iconnect = AutoConnectPhysical;
2289 iconnect = AutoConnectOption (0);
2292 /// @todo some minor tweaks.
2294 oconnect = AutoConnectOption (0);
2296 if (_startup->connect_outputs ()) {
2297 if (_startup->connect_outs_to_master()) {
2298 oconnect = AutoConnectMaster;
2299 } else if (_startup->connect_outs_to_physical()) {
2300 oconnect = AutoConnectPhysical;
2304 nphysin = (uint32_t) _startup->input_limit_count();
2305 nphysout = (uint32_t) _startup->output_limit_count();
2308 if (build_session (session_path,
2316 engine->frame_rate() * 60 * 5)) {
2325 ARDOUR_UI::idle_load (const Glib::ustring& path)
2328 if (Glib::file_test (path, Glib::FILE_TEST_IS_DIR)) {
2329 /* /path/to/foo => /path/to/foo, foo */
2330 load_session (path, basename_nosuffix (path));
2332 /* /path/to/foo/foo.ardour => /path/to/foo, foo */
2333 load_session (Glib::path_get_dirname (path), basename_nosuffix (path));
2337 ARDOUR_COMMAND_LINE::session_name = path;
2340 * new_session_dialog doens't exist in A3
2341 * Try to remove all references to it to
2342 * see if it will compile. NOTE: this will
2343 * likely cause a runtime issue is my somewhat
2347 //if (new_session_dialog) {
2350 /* make it break out of Dialog::run() and
2354 //new_session_dialog->response (1);
2360 ARDOUR_UI::end_loading_messages ()
2366 ARDOUR_UI::loading_message (const std::string& /*msg*/)
2369 // splash->message (msg);
2373 /** @param quit_on_cancel true if exit() should be called if the user clicks `cancel' in the new session dialog */
2375 ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new)
2377 Glib::ustring session_name;
2378 Glib::ustring session_path;
2379 Glib::ustring template_name;
2381 bool likely_new = false;
2385 if (!should_be_new && !ARDOUR_COMMAND_LINE::session_name.empty()) {
2387 /* if they named a specific statefile, use it, otherwise they are
2388 just giving a session folder, and we want to use it as is
2389 to find the session.
2392 if (ARDOUR_COMMAND_LINE::session_name.find (statefile_suffix) != string::npos) {
2393 session_path = Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name);
2395 session_path = ARDOUR_COMMAND_LINE::session_name;
2398 session_name = Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name);
2402 bool const apply = run_startup (should_be_new);
2404 if (quit_on_cancel) {
2411 /* if we run the startup dialog again, offer more than just "new session" */
2413 should_be_new = false;
2415 session_name = _startup->session_name (likely_new);
2417 /* this shouldn't happen, but we catch it just in case it does */
2419 if (session_name.empty()) {
2422 if (_startup->use_session_template()) {
2423 template_name = _startup->session_template_name();
2424 _session_is_new = true;
2427 if (session_name[0] == '/' ||
2428 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
2429 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
2431 session_path = Glib::path_get_dirname (session_name);
2432 session_name = Glib::path_get_basename (session_name);
2436 session_path = _startup->session_folder();
2440 if (create_engine ()) {
2444 if (Glib::file_test (session_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
2448 Glib::ustring existing = Glib::build_filename (session_path, session_name);
2450 if (!ask_about_loading_existing_session (existing)) {
2451 ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
2456 _session_is_new = false;
2461 MessageDialog msg (string_compose (_("There is no existing session at \"%1\""), session_path));
2463 ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
2467 _session_is_new = true;
2470 if (likely_new && template_name.empty()) {
2472 ret = build_session_from_nsd (session_path, session_name);
2476 ret = load_session (session_path, session_name, template_name);
2477 if (!ARDOUR_COMMAND_LINE::immediate_save.empty()) {
2478 session->save_state (ARDOUR_COMMAND_LINE::immediate_save, false);
2488 ARDOUR_UI::close_session()
2490 if (!check_audioengine()) {
2494 unload_session (true);
2496 ARDOUR_COMMAND_LINE::session_name = "";
2497 get_session_parameters (true, false);
2501 ARDOUR_UI::load_session (const Glib::ustring& path, const Glib::ustring& snap_name, Glib::ustring mix_template)
2503 Session *new_session;
2507 session_loaded = false;
2509 if (!check_audioengine()) {
2513 unload_status = unload_session ();
2515 if (unload_status < 0) {
2517 } else if (unload_status > 0) {
2522 loading_message (_("Please wait while Ardour loads your session"));
2525 new_session = new Session (*engine, path, snap_name, mix_template);
2528 /* this one is special */
2530 catch (AudioEngine::PortRegistrationFailure& err) {
2532 MessageDialog msg (err.what(),
2535 Gtk::BUTTONS_CLOSE);
2537 msg.set_title (_("Port Registration Error"));
2538 msg.set_secondary_text (_("Click the Close button to try again."));
2539 msg.set_position (Gtk::WIN_POS_CENTER);
2543 int response = msg.run ();
2548 case RESPONSE_CANCEL:
2558 MessageDialog msg (string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name),
2561 Gtk::BUTTONS_CLOSE);
2563 msg.set_title (_("Loading Error"));
2564 msg.set_secondary_text (_("Click the Close button to try again."));
2565 msg.set_position (Gtk::WIN_POS_CENTER);
2569 int response = msg.run ();
2574 case RESPONSE_CANCEL:
2582 connect_to_session (new_session);
2584 session_loaded = true;
2586 goto_editor_window ();
2589 session->set_clean ();
2600 ARDOUR_UI::build_session (const Glib::ustring& path, const Glib::ustring& snap_name,
2601 uint32_t control_channels,
2602 uint32_t master_channels,
2603 AutoConnectOption input_connect,
2604 AutoConnectOption output_connect,
2607 nframes_t initial_length)
2609 Session *new_session;
2612 if (!check_audioengine()) {
2616 session_loaded = false;
2618 x = unload_session ();
2626 _session_is_new = true;
2629 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
2630 control_channels, master_channels, nphysin, nphysout, initial_length);
2635 MessageDialog msg (string_compose(_("Could not create session in \"%1\""), path));
2641 connect_to_session (new_session);
2643 session_loaded = true;
2645 new_session->save_state(new_session->name());
2654 editor->show_window ();
2665 ARDOUR_UI::show_about ()
2669 about->signal_response().connect(mem_fun (*this, &ARDOUR_UI::about_signal_response) );
2676 ARDOUR_UI::hide_about ()
2679 about->get_window()->set_cursor ();
2685 ARDOUR_UI::about_signal_response (int /*response*/)
2691 ARDOUR_UI::show_splash ()
2695 splash = new Splash;
2703 splash->queue_draw ();
2704 splash->get_window()->process_updates (true);
2709 ARDOUR_UI::hide_splash ()
2717 ARDOUR_UI::display_cleanup_results (ARDOUR::CleanupReport& rep, const gchar* list_title,
2718 const string& plural_msg, const string& singular_msg)
2722 removed = rep.paths.size();
2725 MessageDialog msgd (*editor,
2726 _("No audio files were ready for cleanup"),
2729 (Gtk::ButtonsType)(Gtk::BUTTONS_OK) );
2730 msgd.set_secondary_text (_("If this seems suprising, \n\
2731 check for any existing snapshots.\n\
2732 These may still include regions that\n\
2733 require some unused files to continue to exist."));
2739 ArdourDialog results (_("ardour: cleanup"), true, false);
2741 struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
2742 CleanupResultsModelColumns() {
2746 Gtk::TreeModelColumn<Glib::ustring> visible_name;
2747 Gtk::TreeModelColumn<Glib::ustring> fullpath;
2751 CleanupResultsModelColumns results_columns;
2752 Glib::RefPtr<Gtk::ListStore> results_model;
2753 Gtk::TreeView results_display;
2755 results_model = ListStore::create (results_columns);
2756 results_display.set_model (results_model);
2757 results_display.append_column (list_title, results_columns.visible_name);
2759 results_display.set_name ("CleanupResultsList");
2760 results_display.set_headers_visible (true);
2761 results_display.set_headers_clickable (false);
2762 results_display.set_reorderable (false);
2764 Gtk::ScrolledWindow list_scroller;
2767 Gtk::HBox dhbox; // the hbox for the image and text
2768 Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
2769 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO, Gtk::ICON_SIZE_DIALOG));
2771 dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
2773 const string dead_sound_directory = session->session_directory().dead_sound_path().to_string();
2779 %1 - number of files removed
2780 %2 - location of "dead_sounds"
2781 %3 - size of files affected
2782 %4 - prefix for "bytes" to produce sensible results (e.g. mega, kilo, giga)
2785 const char* bprefix;
2787 if (rep.space < 1048576.0f) {
2788 bprefix = X_("kilo");
2789 } else if (rep.space < 1048576.0f * 1000) {
2790 bprefix = X_("mega");
2792 bprefix = X_("giga");
2796 txt.set_text (string_compose (plural_msg, removed, dead_sound_directory, (float) rep.space / 1024.0f, bprefix));
2798 txt.set_text (string_compose (singular_msg, removed, dead_sound_directory, (float) rep.space / 1024.0f, bprefix));
2801 dhbox.pack_start (*dimage, true, false, 5);
2802 dhbox.pack_start (txt, true, false, 5);
2804 for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2805 TreeModel::Row row = *(results_model->append());
2806 row[results_columns.visible_name] = *i;
2807 row[results_columns.fullpath] = *i;
2810 list_scroller.add (results_display);
2811 list_scroller.set_size_request (-1, 150);
2812 list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2814 dvbox.pack_start (dhbox, true, false, 5);
2815 dvbox.pack_start (list_scroller, true, false, 5);
2816 ddhbox.pack_start (dvbox, true, false, 5);
2818 results.get_vbox()->pack_start (ddhbox, true, false, 5);
2819 results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
2820 results.set_default_response (RESPONSE_CLOSE);
2821 results.set_position (Gtk::WIN_POS_MOUSE);
2823 results_display.show();
2824 list_scroller.show();
2831 //results.get_vbox()->show();
2832 results.set_resizable (false);
2839 ARDOUR_UI::cleanup ()
2842 /* shouldn't happen: menu item is insensitive */
2847 MessageDialog checker (_("Are you sure you want to cleanup?"),
2849 Gtk::MESSAGE_QUESTION,
2850 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
2852 checker.set_secondary_text(_("Cleanup is a destructive operation.\n\
2853 ALL undo/redo information will be lost if you cleanup.\n\
2854 After cleanup, unused audio files will be moved to a \
2855 \"dead sounds\" location."));
2857 checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2858 checker.add_button (_("Clean Up"), RESPONSE_ACCEPT);
2859 checker.set_default_response (RESPONSE_CANCEL);
2861 checker.set_name (_("CleanupDialog"));
2862 checker.set_wmclass (X_("ardour_cleanup"), "Ardour");
2863 checker.set_position (Gtk::WIN_POS_MOUSE);
2865 switch (checker.run()) {
2866 case RESPONSE_ACCEPT:
2872 ARDOUR::CleanupReport rep;
2874 editor->prepare_for_cleanup ();
2876 /* do not allow flush until a session is reloaded */
2878 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
2880 act->set_sensitive (false);
2883 if (session->cleanup_sources (rep)) {
2884 editor->finish_cleanup ();
2888 editor->finish_cleanup ();
2891 display_cleanup_results (rep,
2894 The following %1 files were not in use and \n\
2895 have been moved to:\n\
2897 Flushing the wastebasket will \n\
2898 release an additional\n\
2899 %3 %4bytes of disk space.\n"),
2901 The following file was not in use and \n \
2902 has been moved to:\n \
2904 Flushing the wastebasket will \n\
2905 release an additional\n\
2906 %3 %4bytes of disk space.\n"
2912 ARDOUR_UI::flush_trash ()
2915 /* shouldn't happen: menu item is insensitive */
2919 ARDOUR::CleanupReport rep;
2921 if (session->cleanup_trash_sources (rep)) {
2925 display_cleanup_results (rep,
2927 _("The following %1 files were deleted from\n\
2929 releasing %3 %4bytes of disk space"),
2930 _("The following file was deleted from\n\
2932 releasing %3 %4bytes of disk space"));
2936 ARDOUR_UI::add_route (Gtk::Window* float_window)
2944 if (add_route_dialog == 0) {
2945 add_route_dialog = new AddRouteDialog (*session);
2947 add_route_dialog->set_transient_for (*float_window);
2951 if (add_route_dialog->is_visible()) {
2952 /* we're already doing this */
2956 ResponseType r = (ResponseType) add_route_dialog->run ();
2958 add_route_dialog->hide();
2961 case RESPONSE_ACCEPT:
2968 if ((count = add_route_dialog->count()) <= 0) {
2972 string template_path = add_route_dialog->track_template();
2974 if (!template_path.empty()) {
2975 session->new_route_from_template (count, template_path);
2979 uint32_t input_chan = add_route_dialog->channels ();
2980 uint32_t output_chan;
2981 string name_template = add_route_dialog->name_template ();
2982 bool track = add_route_dialog->track ();
2983 bool aux = !track && add_route_dialog->aux();
2984 RouteGroup* route_group = add_route_dialog->route_group ();
2986 AutoConnectOption oac = Config->get_output_auto_connect();
2988 if (oac & AutoConnectMaster) {
2989 output_chan = (session->master_out() ? session->master_out()->n_inputs().n_audio() : input_chan);
2991 output_chan = input_chan;
2994 /* XXX do something with name template */
2996 if (add_route_dialog->type() == ARDOUR::DataType::MIDI) {
2998 session_add_midi_track (route_group, count);
3000 MessageDialog msg (*editor,
3001 _("Sorry, MIDI Busses are not supported at this time."));
3003 //session_add_midi_bus();
3007 session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), route_group, count);
3009 session_add_audio_bus (aux, input_chan, output_chan, route_group, count);
3015 ARDOUR_UI::mixer_settings () const
3020 node = session->instant_xml(X_("Mixer"));
3022 node = Config->instant_xml(X_("Mixer"));
3026 node = new XMLNode (X_("Mixer"));
3033 ARDOUR_UI::editor_settings () const
3038 node = session->instant_xml(X_("Editor"));
3040 node = Config->instant_xml(X_("Editor"));
3044 if (getenv("ARDOUR_INSTANT_XML_PATH")) {
3045 node = Config->instant_xml(getenv("ARDOUR_INSTANT_XML_PATH"));
3050 node = new XMLNode (X_("Editor"));
3057 ARDOUR_UI::keyboard_settings () const
3061 node = Config->extra_xml(X_("Keyboard"));
3064 node = new XMLNode (X_("Keyboard"));
3070 ARDOUR_UI::create_xrun_marker(nframes_t where)
3072 editor->mouse_add_new_marker (where, false, true);
3076 ARDOUR_UI::halt_on_xrun_message ()
3078 MessageDialog msg (*editor,
3079 _("Recording was stopped because your system could not keep up."));
3084 ARDOUR_UI::xrun_handler(nframes_t where)
3090 ENSURE_GUI_THREAD (bind(mem_fun(*this, &ARDOUR_UI::xrun_handler), where));
3092 if (session && Config->get_create_xrun_marker() && session->actively_recording()) {
3093 create_xrun_marker(where);
3096 if (session && Config->get_stop_recording_on_xrun() && session->actively_recording()) {
3097 halt_on_xrun_message ();
3102 ARDOUR_UI::push_buffer_stats (uint32_t capture, uint32_t playback)
3107 while (disk_buffer_stats.size() > 60) {
3108 disk_buffer_stats.pop_front ();
3111 disk_buffer_stats.push_back (DiskBufferStat (now, capture, playback));
3115 ARDOUR_UI::write_buffer_stats ()
3121 char path[PATH_MAX+1]; int fd;
3123 strcpy (path, "ardourBufferingXXXXXX");
3125 if ((fd = mkstemp (path )) < 0) {
3126 cerr << X_("cannot find temporary name for ardour buffer stats") << endl;
3134 cerr << string_compose (X_("cannot open file %1 for ardour buffer stats"), path) << endl;
3138 for (list<DiskBufferStat>::iterator i = disk_buffer_stats.begin(); i != disk_buffer_stats.end(); ++i) {
3139 localtime_r (&(*i).when, &tm);
3140 strftime (buf, sizeof (buf), "%T", &tm);
3141 fout << buf << ' ' << (*i).capture << ' ' << (*i).playback << endl;
3144 disk_buffer_stats.clear ();
3148 cerr << "Ardour buffering statistics can be found in: " << path << endl;
3152 ARDOUR_UI::disk_overrun_handler ()
3154 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
3156 write_buffer_stats ();
3158 if (!have_disk_speed_dialog_displayed) {
3159 have_disk_speed_dialog_displayed = true;
3160 MessageDialog* msg = new MessageDialog (*editor, _("\
3161 The disk system on your computer\n\
3162 was not able to keep up with Ardour.\n\
3164 Specifically, it failed to write data to disk\n\
3165 quickly enough to keep up with recording.\n"));
3166 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
3172 ARDOUR_UI::disk_underrun_handler ()
3174 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
3176 write_buffer_stats ();
3178 if (!have_disk_speed_dialog_displayed) {
3179 have_disk_speed_dialog_displayed = true;
3180 MessageDialog* msg = new MessageDialog (*editor,
3181 _("The disk system on your computer\n\
3182 was not able to keep up with Ardour.\n\
3184 Specifically, it failed to read data from disk\n\
3185 quickly enough to keep up with playback.\n"));
3186 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
3192 ARDOUR_UI::disk_speed_dialog_gone (int /*ignored_response*/, MessageDialog* msg)
3194 have_disk_speed_dialog_displayed = false;
3199 ARDOUR_UI::session_dialog (std::string msg)
3201 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::session_dialog), msg));
3206 d = new MessageDialog (*editor, msg, false, MESSAGE_INFO, BUTTONS_OK, true);
3208 d = new MessageDialog (msg, false, MESSAGE_INFO, BUTTONS_OK, true);
3217 ARDOUR_UI::pending_state_dialog ()
3219 HBox* hbox = new HBox();
3220 Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG);
3221 ArdourDialog dialog (_("Crash Recovery"), true);
3223 This session appears to have been in\n\
3224 middle of recording when ardour or\n\
3225 the computer was shutdown.\n\
3227 Ardour can recover any captured audio for\n\
3228 you, or it can ignore it. Please decide\n\
3229 what you would like to do.\n"));
3230 image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
3231 hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
3232 hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
3233 dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
3234 dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
3235 dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
3236 dialog.set_default_response (RESPONSE_ACCEPT);
3237 dialog.set_position (WIN_POS_CENTER);
3242 switch (dialog.run ()) {
3243 case RESPONSE_ACCEPT:
3251 ARDOUR_UI::sr_mismatch_dialog (nframes_t desired, nframes_t actual)
3253 HBox* hbox = new HBox();
3254 Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG);
3255 ArdourDialog dialog (_("Sample Rate Mismatch"), true);
3256 Label message (string_compose (_("\
3257 This session was created with a sample rate of %1 Hz\n\
3259 The audioengine is currently running at %2 Hz\n"), desired, actual));
3261 image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
3262 hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
3263 hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
3264 dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
3265 dialog.add_button (_("Do not load session"), RESPONSE_REJECT);
3266 dialog.add_button (_("Load session anyway"), RESPONSE_ACCEPT);
3267 dialog.set_default_response (RESPONSE_ACCEPT);
3268 dialog.set_position (WIN_POS_CENTER);
3273 switch (dialog.run ()) {
3274 case RESPONSE_ACCEPT:
3283 ARDOUR_UI::disconnect_from_jack ()
3286 if( engine->disconnect_from_jack ()) {
3287 MessageDialog msg (*editor, _("Could not disconnect from JACK"));
3291 update_sample_rate (0);
3296 ARDOUR_UI::reconnect_to_jack ()
3299 if (engine->reconnect_to_jack ()) {
3300 MessageDialog msg (*editor, _("Could not reconnect to JACK"));
3304 update_sample_rate (0);
3309 ARDOUR_UI::use_config ()
3312 XMLNode* node = Config->extra_xml (X_("TransportControllables"));
3314 set_transport_controllable_state (*node);
3319 ARDOUR_UI::update_transport_clocks (nframes_t pos)
3321 if (Config->get_primary_clock_delta_edit_cursor()) {
3322 primary_clock.set (pos, false, editor->get_preferred_edit_position(), 1);
3324 primary_clock.set (pos, 0, true);
3327 if (Config->get_secondary_clock_delta_edit_cursor()) {
3328 secondary_clock.set (pos, false, editor->get_preferred_edit_position(), 2);
3330 secondary_clock.set (pos);
3333 if (big_clock_window) {
3334 big_clock.set (pos);
3339 ARDOUR_UI::record_state_changed ()
3341 ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::record_state_changed));
3343 if (!session || !big_clock_window) {
3344 /* why bother - the clock isn't visible */
3348 Session::RecordState const r = session->record_status ();
3349 bool const h = session->have_rec_enabled_diskstream ();
3351 if (r == Session::Recording && h) {
3352 big_clock.set_widget_name ("BigClockRecording");
3354 big_clock.set_widget_name ("BigClockNonRecording");
3359 ARDOUR_UI::first_idle ()
3362 session->allow_auto_play (true);
3366 editor->first_idle();
3369 Keyboard::set_can_save_keybindings (true);
3374 ARDOUR_UI::store_clock_modes ()
3376 XMLNode* node = new XMLNode(X_("ClockModes"));
3378 for (vector<AudioClock*>::iterator x = AudioClock::clocks.begin(); x != AudioClock::clocks.end(); ++x) {
3379 node->add_property ((*x)->name().c_str(), enum_2_string ((*x)->mode()));
3382 session->add_extra_xml (*node);
3383 session->set_dirty ();
3388 ARDOUR_UI::TransportControllable::TransportControllable (std::string name, ARDOUR_UI& u, ToggleType tp)
3389 : Controllable (name), ui (u), type(tp)
3395 ARDOUR_UI::TransportControllable::set_value (float val)
3397 if (type == ShuttleControl) {
3404 fract = -((0.5f - val)/0.5f);
3406 fract = ((val - 0.5f)/0.5f);
3410 ui.set_shuttle_fract (fract);
3415 /* do nothing: these are radio-style actions */
3419 const char *action = 0;
3423 action = X_("Roll");
3426 action = X_("Stop");
3429 action = X_("Goto Start");
3432 action = X_("Goto End");
3435 action = X_("Loop");
3438 action = X_("Play Selection");
3441 action = X_("Record");
3451 Glib::RefPtr<Action> act = ActionManager::get_action ("Transport", action);
3459 ARDOUR_UI::TransportControllable::get_value (void) const
3478 case ShuttleControl:
3488 ARDOUR_UI::TransportControllable::set_id (const string& str)
3494 ARDOUR_UI::setup_profile ()
3496 if (gdk_screen_width() < 1200) {
3497 Profile->set_small_screen ();
3501 if (getenv ("ARDOUR_SAE")) {
3502 Profile->set_sae ();
3503 Profile->set_single_package ();