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"
101 using namespace ARDOUR;
103 using namespace Gtkmm2ext;
105 using namespace sigc;
107 ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
108 UIConfiguration *ARDOUR_UI::ui_config = 0;
110 sigc::signal<void,bool> ARDOUR_UI::Blink;
111 sigc::signal<void> ARDOUR_UI::RapidScreenUpdate;
112 sigc::signal<void> ARDOUR_UI::SuperRapidScreenUpdate;
113 sigc::signal<void,nframes_t, bool, nframes_t> ARDOUR_UI::Clock;
115 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
117 : Gtkmm2ext::UI (X_("Ardour"), argcp, argvp),
119 primary_clock (X_("primary"), false, X_("TransportClockDisplay"), true, false, true),
120 secondary_clock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, false, true),
121 preroll_clock (X_("preroll"), false, X_("PreRollClock"), true, true),
122 postroll_clock (X_("postroll"), false, X_("PostRollClock"), true, true),
126 preroll_button (_("pre\nroll")),
127 postroll_button (_("post\nroll")),
131 big_clock (X_("bigclock"), false, "BigClockNonRecording", true, false, true),
135 roll_controllable (new TransportControllable ("transport roll", *this, TransportControllable::Roll)),
136 stop_controllable (new TransportControllable ("transport stop", *this, TransportControllable::Stop)),
137 goto_start_controllable (new TransportControllable ("transport goto start", *this, TransportControllable::GotoStart)),
138 goto_end_controllable (new TransportControllable ("transport goto end", *this, TransportControllable::GotoEnd)),
139 auto_loop_controllable (new TransportControllable ("transport auto loop", *this, TransportControllable::AutoLoop)),
140 play_selection_controllable (new TransportControllable ("transport play selection", *this, TransportControllable::PlaySelection)),
141 rec_controllable (new TransportControllable ("transport rec-enable", *this, TransportControllable::RecordEnable)),
142 shuttle_controllable (new TransportControllable ("shuttle", *this, TransportControllable::ShuttleControl)),
143 shuttle_controller_binding_proxy (shuttle_controllable),
145 roll_button (roll_controllable),
146 stop_button (stop_controllable),
147 goto_start_button (goto_start_controllable),
148 goto_end_button (goto_end_controllable),
149 auto_loop_button (auto_loop_controllable),
150 play_selection_button (play_selection_controllable),
151 rec_button (rec_controllable),
153 shuttle_units_button (_("% ")),
155 punch_in_button (_("Punch In")),
156 punch_out_button (_("Punch Out")),
157 auto_return_button (_("Auto Return")),
158 auto_play_button (_("Auto Play")),
159 auto_input_button (_("Auto Input")),
160 click_button (_("Click")),
161 time_master_button (_("time\nmaster")),
163 auditioning_alert_button (_("AUDITION")),
164 solo_alert_button (_("SOLO")),
166 error_log_button (_("Errors"))
169 using namespace Gtk::Menu_Helpers;
175 // _auto_display_errors = false;
177 * This was commented out as it wasn't defined
178 * in A3 IIRC. If this is not needed it should
179 * be completely removed.
187 if (theArdourUI == 0) {
191 ui_config = new UIConfiguration();
192 theme_manager = new ThemeManager();
199 _session_is_new = false;
200 big_clock_window = 0;
201 session_selector_window = 0;
202 last_key_press_time = 0;
203 _will_create_new_session_automatically = false;
204 add_route_dialog = 0;
206 rc_option_editor = 0;
207 session_option_editor = 0;
209 open_session_selector = 0;
210 have_configure_timeout = false;
211 have_disk_speed_dialog_displayed = false;
212 session_loaded = false;
213 last_speed_displayed = -1.0f;
214 ignore_dual_punch = false;
215 _mixer_on_top = false;
217 roll_button.unset_flags (Gtk::CAN_FOCUS);
218 stop_button.unset_flags (Gtk::CAN_FOCUS);
219 goto_start_button.unset_flags (Gtk::CAN_FOCUS);
220 goto_end_button.unset_flags (Gtk::CAN_FOCUS);
221 auto_loop_button.unset_flags (Gtk::CAN_FOCUS);
222 play_selection_button.unset_flags (Gtk::CAN_FOCUS);
223 rec_button.unset_flags (Gtk::CAN_FOCUS);
225 last_configure_time= 0;
227 shuttle_grabbed = false;
229 shuttle_max_speed = 8.0f;
231 shuttle_style_menu = 0;
232 shuttle_unit_menu = 0;
234 // We do not have jack linked in yet so;
236 last_shuttle_request = last_peak_grab = 0; // get_microseconds();
238 ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
239 ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
241 /* handle dialog requests */
243 ARDOUR::Session::Dialog.connect (mem_fun(*this, &ARDOUR_UI::session_dialog));
245 /* handle pending state with a dialog */
247 ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
249 /* handle sr mismatch with a dialog */
251 ARDOUR::Session::AskAboutSampleRateMismatch.connect (mem_fun(*this, &ARDOUR_UI::sr_mismatch_dialog));
253 /* lets get this party started */
256 if (ARDOUR::init (ARDOUR_COMMAND_LINE::use_vst, ARDOUR_COMMAND_LINE::try_hw_optimization)) {
257 throw failed_constructor ();
260 setup_gtk_ardour_enums ();
263 GainMeter::setup_slider_pix ();
264 RouteTimeAxisView::setup_slider_pix ();
266 } catch (failed_constructor& err) {
267 error << _("could not initialize Ardour.") << endmsg;
272 /* we like keyboards */
274 keyboard = new Keyboard;
278 starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
279 stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
284 /** @return true if a session was chosen and `apply' clicked, otherwise false if `cancel' was clicked */
286 ARDOUR_UI::run_startup (bool should_be_new)
289 _startup = new ArdourStartup ();
292 _startup->set_new_only (should_be_new);
293 _startup->present ();
297 /* we don't return here until the startup assistant is finished */
301 return _startup->applying ();
305 ARDOUR_UI::create_engine ()
307 // this gets called every time by new_session()
313 loading_message (_("Starting audio engine"));
316 engine = new ARDOUR::AudioEngine (ARDOUR_COMMAND_LINE::jack_client_name);
323 engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
324 engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
325 engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
326 engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
334 ARDOUR_UI::post_engine ()
336 /* Things to be done once we create the AudioEngine
339 MIDI::Manager::instance()->set_api_data (engine->jack());
342 ARDOUR::init_post_engine ();
344 ActionManager::init ();
347 if (setup_windows ()) {
348 throw failed_constructor ();
351 check_memory_locking();
353 /* this is the first point at which all the keybindings are available */
355 if (ARDOUR_COMMAND_LINE::show_key_actions) {
356 vector<string> names;
357 vector<string> paths;
359 vector<AccelKey> bindings;
361 ActionManager::get_all_actions (names, paths, keys, bindings);
363 vector<string>::iterator n;
364 vector<string>::iterator k;
365 for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) {
366 cerr << "Action: " << (*n) << " bound to " << (*k) << endl;
372 blink_timeout_tag = -1;
374 /* this being a GUI and all, we want peakfiles */
376 AudioFileSource::set_build_peakfiles (true);
377 AudioFileSource::set_build_missing_peakfiles (true);
379 /* set default clock modes */
381 if (Profile->get_sae()) {
382 primary_clock.set_mode (AudioClock::BBT);
383 secondary_clock.set_mode (AudioClock::MinSec);
385 primary_clock.set_mode (AudioClock::Timecode);
386 secondary_clock.set_mode (AudioClock::BBT);
389 /* start the time-of-day-clock */
392 /* OS X provides an always visible wallclock, so don't be stupid */
393 update_wall_clock ();
394 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
397 update_disk_space ();
399 update_sample_rate (engine->frame_rate());
401 /* now start and maybe save state */
403 if (do_engine_start () == 0) {
404 if (session && _session_is_new) {
405 /* we need to retain initial visual
406 settings for a new session
408 session->save_state ("");
413 ARDOUR_UI::~ARDOUR_UI ()
415 save_ardour_state ();
420 delete add_route_dialog;
424 ARDOUR_UI::pop_back_splash ()
426 if (Splash::instance()) {
427 // Splash::instance()->pop_back();
428 Splash::instance()->hide ();
433 ARDOUR_UI::configure_timeout ()
435 if (last_configure_time == 0) {
436 /* no configure events yet */
440 /* force a gap of 0.5 seconds since the last configure event
443 if (get_microseconds() - last_configure_time < 500000) {
446 have_configure_timeout = false;
447 save_ardour_state ();
453 ARDOUR_UI::configure_handler (GdkEventConfigure* /*conf*/)
455 if (have_configure_timeout) {
456 last_configure_time = get_microseconds();
458 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
459 have_configure_timeout = true;
466 ARDOUR_UI::set_transport_controllable_state (const XMLNode& node)
468 const XMLProperty* prop;
470 if ((prop = node.property ("roll")) != 0) {
471 roll_controllable->set_id (prop->value());
473 if ((prop = node.property ("stop")) != 0) {
474 stop_controllable->set_id (prop->value());
476 if ((prop = node.property ("goto-start")) != 0) {
477 goto_start_controllable->set_id (prop->value());
479 if ((prop = node.property ("goto-end")) != 0) {
480 goto_end_controllable->set_id (prop->value());
482 if ((prop = node.property ("auto-loop")) != 0) {
483 auto_loop_controllable->set_id (prop->value());
485 if ((prop = node.property ("play-selection")) != 0) {
486 play_selection_controllable->set_id (prop->value());
488 if ((prop = node.property ("rec")) != 0) {
489 rec_controllable->set_id (prop->value());
491 if ((prop = node.property ("shuttle")) != 0) {
492 shuttle_controllable->set_id (prop->value());
497 ARDOUR_UI::get_transport_controllable_state ()
499 XMLNode* node = new XMLNode(X_("TransportControllables"));
502 roll_controllable->id().print (buf, sizeof (buf));
503 node->add_property (X_("roll"), buf);
504 stop_controllable->id().print (buf, sizeof (buf));
505 node->add_property (X_("stop"), buf);
506 goto_start_controllable->id().print (buf, sizeof (buf));
507 node->add_property (X_("goto_start"), buf);
508 goto_end_controllable->id().print (buf, sizeof (buf));
509 node->add_property (X_("goto_end"), buf);
510 auto_loop_controllable->id().print (buf, sizeof (buf));
511 node->add_property (X_("auto_loop"), buf);
512 play_selection_controllable->id().print (buf, sizeof (buf));
513 node->add_property (X_("play_selection"), buf);
514 rec_controllable->id().print (buf, sizeof (buf));
515 node->add_property (X_("rec"), buf);
516 shuttle_controllable->id().print (buf, sizeof (buf));
517 node->add_property (X_("shuttle"), buf);
523 ARDOUR_UI::save_ardour_state ()
525 if (!keyboard || !mixer || !editor) {
529 /* XXX this is all a bit dubious. add_extra_xml() uses
530 a different lifetime model from add_instant_xml().
533 XMLNode* node = new XMLNode (keyboard->get_state());
534 Config->add_extra_xml (*node);
535 Config->add_extra_xml (get_transport_controllable_state());
536 if (_startup && _startup->engine_control() && _startup->engine_control()->was_used()) {
537 Config->add_extra_xml (_startup->engine_control()->get_state());
539 Config->save_state();
540 ui_config->save_state ();
542 XMLNode enode(static_cast<Stateful*>(editor)->get_state());
543 XMLNode mnode(mixer->get_state());
546 session->add_instant_xml (enode);
547 session->add_instant_xml (mnode);
549 Config->add_instant_xml (enode);
550 Config->add_instant_xml (mnode);
553 Keyboard::save_keybindings ();
557 ARDOUR_UI::autosave_session ()
559 if (g_main_depth() > 1) {
560 /* inside a recursive main loop,
561 give up because we may not be able to
567 if (!Config->get_periodic_safety_backups()) {
572 session->maybe_write_autosave();
579 ARDOUR_UI::update_autosave ()
581 ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::update_autosave));
583 if (session && session->dirty()) {
584 if (_autosave_connection.connected()) {
585 _autosave_connection.disconnect();
588 _autosave_connection = Glib::signal_timeout().connect (mem_fun (*this, &ARDOUR_UI::autosave_session),
589 Config->get_periodic_safety_backup_interval() * 1000);
592 if (_autosave_connection.connected()) {
593 _autosave_connection.disconnect();
599 ARDOUR_UI::backend_audio_error (bool we_set_params, Gtk::Window* toplevel)
603 title = _("Ardour could not start JACK");
605 title = _("Ardour could not connect to JACK.");
608 MessageDialog win (title,
614 win.set_secondary_text(_("There are several possible reasons:\n\
616 1) You requested audio parameters that are not supported..\n\
617 2) JACK is running as another user.\n\
619 Please consider the possibilities, and perhaps try different parameters."));
621 win.set_secondary_text(_("There are several possible reasons:\n\
623 1) JACK is not running.\n\
624 2) JACK is running as another user, perhaps root.\n\
625 3) There is already another client called \"ardour\".\n\
627 Please consider the possibilities, and perhaps (re)start JACK."));
631 win.set_transient_for (*toplevel);
635 win.add_button (Stock::OK, RESPONSE_CLOSE);
637 win.add_button (Stock::QUIT, RESPONSE_CLOSE);
640 win.set_default_response (RESPONSE_CLOSE);
643 win.set_position (Gtk::WIN_POS_CENTER);
646 /* we just don't care about the result, but we want to block */
652 ARDOUR_UI::startup ()
654 XMLNode* audio_setup = Config->extra_xml ("AudioSetup");
656 if (audio_setup && _startup && _startup->engine_control()) {
657 _startup->engine_control()->set_state (*audio_setup);
660 if (get_session_parameters (true, ARDOUR_COMMAND_LINE::new_session)) {
666 goto_editor_window ();
668 BootMessage (_("Ardour is ready for use"));
673 ARDOUR_UI::no_memory_warning ()
675 XMLNode node (X_("no-memory-warning"));
676 Config->add_instant_xml (node);
680 ARDOUR_UI::check_memory_locking ()
683 /* OS X doesn't support mlockall(2), and so testing for memory locking capability there is pointless */
687 XMLNode* memory_warning_node = Config->instant_xml (X_("no-memory-warning"));
689 if (engine->is_realtime() && memory_warning_node == 0) {
691 struct rlimit limits;
693 long pages, page_size;
695 if ((page_size = sysconf (_SC_PAGESIZE)) < 0 ||(pages = sysconf (_SC_PHYS_PAGES)) < 0) {
698 ram = (int64_t) pages * (int64_t) page_size;
701 if (getrlimit (RLIMIT_MEMLOCK, &limits)) {
705 if (limits.rlim_cur != RLIM_INFINITY) {
707 if (ram == 0 || ((double) limits.rlim_cur / ram) < 0.75) {
710 MessageDialog msg (_("WARNING: Your system has a limit for maximum amount of locked memory. "
711 "This might cause Ardour to run out of memory before your system "
712 "runs out of memory. \n\n"
713 "You can view the memory limit with 'ulimit -l', "
714 "and it is normally controlled by /etc/security/limits.conf"));
716 VBox* vbox = msg.get_vbox();
718 CheckButton cb (_("Do not show this window again"));
720 cb.signal_toggled().connect (mem_fun (*this, &ARDOUR_UI::no_memory_warning));
722 hbox.pack_start (cb, true, false);
723 vbox->pack_start (hbox);
730 editor->ensure_float (msg);
744 if (session->transport_rolling()) {
745 session->request_stop ();
749 if (session->dirty()) {
750 switch (ask_about_saving_session(_("quit"))) {
755 /* use the default name */
756 if (save_state_canfail ("")) {
757 /* failed - don't quit */
758 MessageDialog msg (*editor,
760 Ardour was unable to save your session.\n\n\
761 If you still wish to quit, please use the\n\n\
762 \"Just quit\" option."));
773 session->set_deletion_in_progress ();
776 ArdourDialog::close_all_dialogs ();
778 save_ardour_state ();
783 ARDOUR_UI::ask_about_saving_session (const string & what)
785 ArdourDialog window (_("ardour: save session?"));
786 Gtk::HBox dhbox; // the hbox for the image and text
787 Gtk::Label prompt_label;
788 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_WARNING, Gtk::ICON_SIZE_DIALOG));
792 msg = string_compose(_("Don't %1"), what);
793 window.add_button (msg, RESPONSE_REJECT);
794 msg = string_compose(_("Just %1"), what);
795 window.add_button (msg, RESPONSE_APPLY);
796 msg = string_compose(_("Save and %1"), what);
797 window.add_button (msg, RESPONSE_ACCEPT);
799 window.set_default_response (RESPONSE_ACCEPT);
801 Gtk::Button noquit_button (msg);
802 noquit_button.set_name ("EditorGTKButton");
807 if (session->snap_name() == session->name()) {
810 type = _("snapshot");
812 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?"),
813 type, session->snap_name());
815 prompt_label.set_text (prompt);
816 prompt_label.set_name (X_("PrompterLabel"));
817 prompt_label.set_alignment(ALIGN_LEFT, ALIGN_TOP);
819 dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP);
820 dhbox.set_homogeneous (false);
821 dhbox.pack_start (*dimage, false, false, 5);
822 dhbox.pack_start (prompt_label, true, false, 5);
823 window.get_vbox()->pack_start (dhbox);
825 window.set_name (_("Prompter"));
826 window.set_position (Gtk::WIN_POS_MOUSE);
827 window.set_modal (true);
828 window.set_resizable (false);
834 window.set_keep_above (true);
837 ResponseType r = (ResponseType) window.run();
842 case RESPONSE_ACCEPT: // save and get out of here
844 case RESPONSE_APPLY: // get out of here
854 ARDOUR_UI::every_second ()
857 update_buffer_load ();
858 update_disk_space ();
863 ARDOUR_UI::every_point_one_seconds ()
865 update_speed_display ();
866 RapidScreenUpdate(); /* EMIT_SIGNAL */
871 ARDOUR_UI::every_point_zero_one_seconds ()
873 // august 2007: actual update frequency: 40Hz, not 100Hz
875 SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
880 ARDOUR_UI::update_sample_rate (nframes_t ignored)
884 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
886 if (!engine->connected()) {
888 snprintf (buf, sizeof (buf), _("disconnected"));
892 nframes_t rate = engine->frame_rate();
894 if (fmod (rate, 1000.0) != 0.0) {
895 snprintf (buf, sizeof (buf), _("%.1f kHz / %4.1f ms"),
896 (float) rate/1000.0f,
897 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
899 snprintf (buf, sizeof (buf), _("%u kHz / %4.1f ms"),
901 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
905 sample_rate_label.set_text (buf);
909 ARDOUR_UI::update_cpu_load ()
912 snprintf (buf, sizeof (buf), _("DSP: %5.1f%%"), engine->get_cpu_load());
913 cpu_load_label.set_text (buf);
917 ARDOUR_UI::update_buffer_load ()
923 c = session->capture_load ();
924 p = session->playback_load ();
926 push_buffer_stats (c, p);
928 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"),
929 session->playback_load(), session->capture_load());
930 buffer_load_label.set_text (buf);
932 buffer_load_label.set_text ("");
937 ARDOUR_UI::count_recenabled_streams (Route& route)
939 Track* track = dynamic_cast<Track*>(&route);
940 if (track && track->diskstream()->record_enabled()) {
941 rec_enabled_streams += track->n_inputs().n_total();
946 ARDOUR_UI::update_disk_space()
952 nframes_t frames = session->available_capture_duration();
954 nframes_t fr = session->frame_rate();
956 if (frames == max_frames) {
957 strcpy (buf, _("Disk: 24hrs+"));
959 rec_enabled_streams = 0;
960 session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
962 if (rec_enabled_streams) {
963 frames /= rec_enabled_streams;
970 hrs = frames / (fr * 3600);
971 frames -= hrs * fr * 3600;
972 mins = frames / (fr * 60);
973 frames -= mins * fr * 60;
976 snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs);
979 disk_space_label.set_text (buf);
981 // An attempt to make the disk space label flash red when space has run out.
983 if (frames < fr * 60 * 5) {
984 /* disk_space_box.style ("disk_space_label_empty"); */
986 /* disk_space_box.style ("disk_space_label"); */
992 ARDOUR_UI::update_wall_clock ()
999 tm_now = localtime (&now);
1001 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
1002 wall_clock_label.set_text (buf);
1008 ARDOUR_UI::session_menu (GdkEventButton */*ev*/)
1010 session_popup_menu->popup (0, 0);
1015 ARDOUR_UI::redisplay_recent_sessions ()
1017 std::vector<sys::path> session_directories;
1018 RecentSessionsSorter cmp;
1020 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
1021 recent_session_model->clear ();
1023 ARDOUR::RecentSessions rs;
1024 ARDOUR::read_recent_sessions (rs);
1027 recent_session_display.set_model (recent_session_model);
1031 // sort them alphabetically
1032 sort (rs.begin(), rs.end(), cmp);
1034 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
1035 session_directories.push_back ((*i).second);
1038 for (vector<sys::path>::const_iterator i = session_directories.begin();
1039 i != session_directories.end(); ++i)
1041 std::vector<sys::path> state_file_paths;
1043 // now get available states for this session
1045 get_state_files_in_directory (*i, state_file_paths);
1047 vector<string*>* states;
1048 vector<const gchar*> item;
1049 string fullpath = (*i).to_string();
1051 /* remove any trailing / */
1053 if (fullpath[fullpath.length()-1] == '/') {
1054 fullpath = fullpath.substr (0, fullpath.length()-1);
1057 /* check whether session still exists */
1058 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
1059 /* session doesn't exist */
1060 cerr << "skipping non-existent session " << fullpath << endl;
1064 /* now get available states for this session */
1066 if ((states = Session::possible_states (fullpath)) == 0) {
1067 /* no state file? */
1071 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
1073 Gtk::TreeModel::Row row = *(recent_session_model->append());
1075 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
1076 row[recent_session_columns.fullpath] = fullpath;
1078 if (state_file_names.size() > 1) {
1082 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
1083 i2 != state_file_names.end(); ++i2)
1086 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
1088 child_row[recent_session_columns.visible_name] = *i2;
1089 child_row[recent_session_columns.fullpath] = fullpath;
1094 recent_session_display.set_model (recent_session_model);
1098 ARDOUR_UI::build_session_selector ()
1100 session_selector_window = new ArdourDialog (_("Recent Sessions"));
1102 Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
1104 session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
1105 session_selector_window->add_button (Stock::OPEN, RESPONSE_ACCEPT);
1106 session_selector_window->set_default_response (RESPONSE_ACCEPT);
1107 recent_session_model = TreeStore::create (recent_session_columns);
1108 recent_session_display.set_model (recent_session_model);
1109 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1110 recent_session_display.set_headers_visible (false);
1111 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
1112 recent_session_display.signal_row_activated().connect (mem_fun (*this, &ARDOUR_UI::recent_session_row_activated));
1114 scroller->add (recent_session_display);
1115 scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1117 session_selector_window->set_name ("SessionSelectorWindow");
1118 session_selector_window->set_size_request (200, 400);
1119 session_selector_window->get_vbox()->pack_start (*scroller);
1121 recent_session_display.show();
1123 //session_selector_window->get_vbox()->show();
1127 ARDOUR_UI::recent_session_row_activated (const TreePath& /*path*/, TreeViewColumn* /*col*/)
1129 session_selector_window->response (RESPONSE_ACCEPT);
1133 ARDOUR_UI::open_recent_session ()
1135 bool can_return = (session != 0);
1137 if (session_selector_window == 0) {
1138 build_session_selector ();
1141 redisplay_recent_sessions ();
1145 session_selector_window->set_position (WIN_POS_MOUSE);
1147 ResponseType r = (ResponseType) session_selector_window->run ();
1150 case RESPONSE_ACCEPT:
1154 session_selector_window->hide();
1161 if (recent_session_display.get_selection()->count_selected_rows() == 0) {
1165 session_selector_window->hide();
1167 Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
1169 if (i == recent_session_model->children().end()) {
1173 Glib::ustring path = (*i)[recent_session_columns.fullpath];
1174 Glib::ustring state = (*i)[recent_session_columns.visible_name];
1176 _session_is_new = false;
1178 if (load_session (path, state) == 0) {
1187 ARDOUR_UI::check_audioengine ()
1190 if (!engine->connected()) {
1191 MessageDialog msg (_("Ardour is not connected to JACK\n"
1192 "You cannot open or close sessions in this condition"));
1204 ARDOUR_UI::open_session ()
1206 if (!check_audioengine()) {
1211 /* popup selector window */
1213 if (open_session_selector == 0) {
1215 /* ardour sessions are folders */
1217 open_session_selector = new Gtk::FileChooserDialog (_("Open Session"), FILE_CHOOSER_ACTION_OPEN);
1218 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1219 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
1220 open_session_selector->set_default_response(Gtk::RESPONSE_ACCEPT);
1222 FileFilter session_filter;
1223 session_filter.add_pattern ("*.ardour");
1224 session_filter.set_name (_("Ardour sessions"));
1225 open_session_selector->add_filter (session_filter);
1226 open_session_selector->set_filter (session_filter);
1229 int response = open_session_selector->run();
1230 open_session_selector->hide ();
1233 case RESPONSE_ACCEPT:
1236 open_session_selector->hide();
1240 open_session_selector->hide();
1241 string session_path = open_session_selector->get_filename();
1245 if (session_path.length() > 0) {
1246 if (ARDOUR::find_session (session_path, path, name, isnew) == 0) {
1247 _session_is_new = isnew;
1248 load_session (path, name);
1255 ARDOUR_UI::session_add_midi_route (bool disk, RouteGroup* route_group, uint32_t how_many)
1257 list<boost::shared_ptr<MidiTrack> > tracks;
1260 warning << _("You cannot add a track without a session already loaded.") << endmsg;
1267 tracks = session->new_midi_track (ARDOUR::Normal, route_group, how_many);
1269 if (tracks.size() != how_many) {
1270 if (how_many == 1) {
1271 error << _("could not create a new midi track") << endmsg;
1273 error << string_compose (_("could not create %1 new midi tracks"), how_many) << endmsg;
1277 if ((route = session->new_midi_route ()) == 0) {
1278 error << _("could not create new midi bus") << endmsg;
1284 MessageDialog msg (*editor,
1285 _("There are insufficient JACK ports available\n\
1286 to create a new track or bus.\n\
1287 You should save Ardour, exit and\n\
1288 restart JACK with more ports."));
1295 ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, RouteGroup* route_group, uint32_t how_many)
1297 list<boost::shared_ptr<AudioTrack> > tracks;
1301 warning << _("You cannot add a track or bus without a session already loaded.") << endmsg;
1307 tracks = session->new_audio_track (input_channels, output_channels, mode, route_group, how_many);
1309 if (tracks.size() != how_many) {
1310 if (how_many == 1) {
1311 error << _("could not create a new audio track") << endmsg;
1313 error << string_compose (_("could only create %1 of %2 new audio %3"),
1314 tracks.size(), how_many, (track ? _("tracks") : _("busses"))) << endmsg;
1320 routes = session->new_audio_route (input_channels, output_channels, route_group, how_many);
1322 if (routes.size() != how_many) {
1323 if (how_many == 1) {
1324 error << _("could not create a new audio track") << endmsg;
1326 error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
1332 if (need_control_room_outs) {
1338 route->set_stereo_control_outs (control_lr_channels);
1339 route->control_outs()->set_stereo_pan (pans, this);
1341 #endif /* CONTROLOUTS */
1345 MessageDialog msg (*editor,
1346 _("There are insufficient JACK ports available\n\
1347 to create a new track or bus.\n\
1348 You should save Ardour, exit and\n\
1349 restart JACK with more ports."));
1356 ARDOUR_UI::do_transport_locate (nframes_t new_position)
1358 nframes_t _preroll = 0;
1361 // XXX CONFIG_CHANGE FIX - requires AnyTime handling
1362 // _preroll = session->convert_to_frames_at (new_position, Config->get_preroll());
1364 if (new_position > _preroll) {
1365 new_position -= _preroll;
1370 session->request_locate (new_position);
1375 ARDOUR_UI::transport_goto_start ()
1378 session->goto_start();
1381 /* force displayed area in editor to start no matter
1382 what "follow playhead" setting is.
1386 editor->reset_x_origin (session->current_start_frame());
1392 ARDOUR_UI::transport_goto_zero ()
1395 session->request_locate (0);
1398 /* force displayed area in editor to start no matter
1399 what "follow playhead" setting is.
1403 editor->reset_x_origin (0);
1409 ARDOUR_UI::transport_goto_wallclock ()
1411 if (session && editor) {
1418 localtime_r (&now, &tmnow);
1420 frames = tmnow.tm_hour * (60 * 60 * session->frame_rate());
1421 frames += tmnow.tm_min * (60 * session->frame_rate());
1422 frames += tmnow.tm_sec * session->frame_rate();
1424 session->request_locate (frames);
1426 /* force displayed area in editor to start no matter
1427 what "follow playhead" setting is.
1431 editor->reset_x_origin (frames - (editor->current_page_frames()/2));
1437 ARDOUR_UI::transport_goto_end ()
1440 nframes_t frame = session->current_end_frame();
1441 session->request_locate (frame);
1443 /* force displayed area in editor to start no matter
1444 what "follow playhead" setting is.
1448 editor->reset_x_origin (frame);
1454 ARDOUR_UI::transport_stop ()
1460 if (session->is_auditioning()) {
1461 session->cancel_audition ();
1465 session->request_stop ();
1469 ARDOUR_UI::transport_stop_and_forget_capture ()
1472 session->request_stop (true);
1477 ARDOUR_UI::remove_last_capture()
1480 editor->remove_last_capture();
1485 ARDOUR_UI::transport_record (bool roll)
1489 switch (session->record_status()) {
1490 case Session::Disabled:
1491 if (session->ntracks() == 0) {
1492 MessageDialog msg (*editor, _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu."));
1496 session->maybe_enable_record ();
1501 case Session::Recording:
1503 session->request_stop();
1505 session->disable_record (false, true);
1509 case Session::Enabled:
1510 session->disable_record (false, true);
1513 //cerr << "ARDOUR_UI::transport_record () called roll = " << roll << " session->record_status() = " << session->record_status() << endl;
1517 ARDOUR_UI::transport_roll ()
1523 if (session->is_auditioning()) {
1527 switch (Config->get_slave_source()) {
1532 /* transport controlled by the master */
1536 bool rolling = session->transport_rolling();
1538 if (session->get_play_loop()) {
1539 session->request_play_loop (false, true);
1540 } else if (session->get_play_range ()) {
1541 session->request_play_range (false, true);
1545 session->request_transport_speed (1.0f);
1548 map_transport_state ();
1552 ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode)
1559 if (session->is_auditioning()) {
1560 session->cancel_audition ();
1564 switch (Config->get_slave_source()) {
1569 /* transport controlled by the master */
1573 bool rolling = session->transport_rolling();
1574 bool affect_transport = true;
1576 if (rolling && roll_out_of_bounded_mode) {
1577 /* drop out of loop/range playback but leave transport rolling */
1578 if (session->get_play_loop()) {
1579 if (Config->get_seamless_loop()) {
1580 /* the disk buffers contain copies of the loop - we can't
1581 just keep playing, so stop the transport. the user
1582 can restart as they wish.
1584 affect_transport = true;
1586 /* disk buffers are normal, so we can keep playing */
1587 affect_transport = false;
1589 session->request_play_loop (false, true);
1590 } else if (session->get_play_range ()) {
1591 affect_transport = false;
1592 session->request_play_range (0, true);
1596 if (affect_transport) {
1598 session->request_stop (with_abort, true);
1600 session->request_transport_speed (1.0f);
1604 map_transport_state ();
1608 ARDOUR_UI::toggle_session_auto_loop ()
1611 if (session->get_play_loop()) {
1612 if (session->transport_rolling()) {
1613 Location * looploc = session->locations()->auto_loop_location();
1615 session->request_locate (looploc->start(), true);
1618 session->request_play_loop (false);
1621 Location * looploc = session->locations()->auto_loop_location();
1623 session->request_play_loop (true);
1630 ARDOUR_UI::transport_play_selection ()
1636 editor->play_selection ();
1640 ARDOUR_UI::transport_rewind (int option)
1642 float current_transport_speed;
1645 current_transport_speed = session->transport_speed();
1647 if (current_transport_speed >= 0.0f) {
1650 session->request_transport_speed (-1.0f);
1653 session->request_transport_speed (-4.0f);
1656 session->request_transport_speed (-0.5f);
1661 session->request_transport_speed (current_transport_speed * 1.5f);
1667 ARDOUR_UI::transport_forward (int option)
1669 float current_transport_speed;
1672 current_transport_speed = session->transport_speed();
1674 if (current_transport_speed <= 0.0f) {
1677 session->request_transport_speed (1.0f);
1680 session->request_transport_speed (4.0f);
1683 session->request_transport_speed (0.5f);
1688 session->request_transport_speed (current_transport_speed * 1.5f);
1695 ARDOUR_UI::toggle_record_enable (uint32_t dstream)
1701 boost::shared_ptr<Route> r;
1703 if ((r = session->route_by_remote_id (dstream)) != 0) {
1707 if ((t = dynamic_cast<Track*>(r.get())) != 0) {
1708 t->diskstream()->set_record_enabled (!t->diskstream()->record_enabled());
1717 ARDOUR_UI::map_transport_state ()
1719 ENSURE_GUI_THREAD(mem_fun (*this, &ARDOUR_UI::map_transport_state));
1722 auto_loop_button.set_visual_state (0);
1723 play_selection_button.set_visual_state (0);
1724 roll_button.set_visual_state (0);
1725 stop_button.set_visual_state (1);
1729 float sp = session->transport_speed();
1732 shuttle_fract = SHUTTLE_FRACT_SPEED1; /* speed = 1.0, believe it or not */
1733 shuttle_box.queue_draw ();
1734 } else if (sp == 0.0f) {
1736 shuttle_box.queue_draw ();
1737 update_disk_space ();
1742 if (session->get_play_range()) {
1744 play_selection_button.set_visual_state (1);
1745 roll_button.set_visual_state (0);
1746 auto_loop_button.set_visual_state (0);
1748 } else if (session->get_play_loop ()) {
1750 auto_loop_button.set_visual_state (1);
1751 play_selection_button.set_visual_state (0);
1752 roll_button.set_visual_state (0);
1756 roll_button.set_visual_state (1);
1757 play_selection_button.set_visual_state (0);
1758 auto_loop_button.set_visual_state (0);
1761 stop_button.set_visual_state (0);
1765 stop_button.set_visual_state (1);
1766 roll_button.set_visual_state (0);
1767 play_selection_button.set_visual_state (0);
1768 auto_loop_button.set_visual_state (0);
1774 ARDOUR_UI::engine_stopped ()
1776 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
1777 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1778 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1782 ARDOUR_UI::engine_running ()
1784 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
1785 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true);
1786 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
1788 Glib::RefPtr<Action> action;
1789 const char* action_name = 0;
1791 switch (engine->frames_per_cycle()) {
1793 action_name = X_("JACKLatency32");
1796 action_name = X_("JACKLatency64");
1799 action_name = X_("JACKLatency128");
1802 action_name = X_("JACKLatency512");
1805 action_name = X_("JACKLatency1024");
1808 action_name = X_("JACKLatency2048");
1811 action_name = X_("JACKLatency4096");
1814 action_name = X_("JACKLatency8192");
1817 /* XXX can we do anything useful ? */
1823 action = ActionManager::get_action (X_("JACK"), action_name);
1826 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic (action);
1827 ract->set_active ();
1833 ARDOUR_UI::engine_halted ()
1835 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
1837 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1838 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1840 update_sample_rate (0);
1842 MessageDialog msg (*editor,
1844 JACK has either been shutdown or it\n\
1845 disconnected Ardour because Ardour\n\
1846 was not fast enough. Try to restart\n\
1847 JACK, reconnect and save the session."));
1853 ARDOUR_UI::do_engine_start ()
1861 error << _("Unable to start the session running")
1871 ARDOUR_UI::setup_theme ()
1873 theme_manager->setup_theme();
1877 ARDOUR_UI::update_clocks ()
1879 if (!editor || !editor->dragging_playhead()) {
1880 Clock (session->audible_frame(), false, editor->get_preferred_edit_position()); /* EMIT_SIGNAL */
1885 ARDOUR_UI::start_clocking ()
1887 clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
1891 ARDOUR_UI::stop_clocking ()
1893 clock_signal_connection.disconnect ();
1897 ARDOUR_UI::toggle_clocking ()
1900 if (clock_button.get_active()) {
1909 ARDOUR_UI::_blink (void *arg)
1912 ((ARDOUR_UI *) arg)->blink ();
1919 Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
1923 ARDOUR_UI::start_blinking ()
1925 /* Start the blink signal. Everybody with a blinking widget
1926 uses Blink to drive the widget's state.
1929 if (blink_timeout_tag < 0) {
1931 blink_timeout_tag = g_timeout_add (240, _blink, this);
1936 ARDOUR_UI::stop_blinking ()
1938 if (blink_timeout_tag >= 0) {
1939 g_source_remove (blink_timeout_tag);
1940 blink_timeout_tag = -1;
1945 /** Ask the user for the name of a new shapshot and then take it.
1948 ARDOUR_UI::snapshot_session ()
1950 ArdourPrompter prompter (true);
1954 struct tm local_time;
1957 localtime_r (&n, &local_time);
1958 strftime (timebuf, sizeof(timebuf), "%FT%T", &local_time);
1960 prompter.set_name ("Prompter");
1961 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1962 prompter.set_title (_("Take Snapshot"));
1963 prompter.set_prompt (_("Name of New Snapshot"));
1964 prompter.set_initial_text (timebuf);
1966 switch (prompter.run()) {
1967 case RESPONSE_ACCEPT:
1969 prompter.get_result (snapname);
1971 bool do_save = (snapname.length() != 0);
1973 vector<sys::path> p;
1974 get_state_files_in_directory (session->session_directory().root_path(), p);
1975 vector<string> n = get_file_names_no_extension (p);
1976 if (find (n.begin(), n.end(), snapname) != n.end()) {
1978 ArdourDialog confirm (_("Confirm snapshot overwrite"), true);
1979 Label m (_("A snapshot already exists with that name. Do you want to overwrite it?"));
1980 confirm.get_vbox()->pack_start (m, true, true);
1981 confirm.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1982 confirm.add_button (_("Overwrite"), Gtk::RESPONSE_ACCEPT);
1983 confirm.show_all ();
1984 switch (confirm.run()) {
1985 case RESPONSE_CANCEL:
1991 save_state (snapname);
2002 ARDOUR_UI::save_state (const string & name)
2004 (void) save_state_canfail (name);
2008 ARDOUR_UI::save_state_canfail (string name)
2013 if (name.length() == 0) {
2014 name = session->snap_name();
2017 if ((ret = session->save_state (name)) != 0) {
2021 save_ardour_state (); /* XXX cannot fail? yeah, right ... */
2026 ARDOUR_UI::primary_clock_value_changed ()
2029 session->request_locate (primary_clock.current_time ());
2034 ARDOUR_UI::big_clock_value_changed ()
2037 session->request_locate (big_clock.current_time ());
2042 ARDOUR_UI::secondary_clock_value_changed ()
2045 session->request_locate (secondary_clock.current_time ());
2050 ARDOUR_UI::transport_rec_enable_blink (bool onoff)
2056 Session::RecordState const r = session->record_status ();
2057 bool const h = session->have_rec_enabled_diskstream ();
2059 if (r == Session::Enabled || (r == Session::Recording && !h)) {
2061 rec_button.set_visual_state (2);
2063 rec_button.set_visual_state (0);
2065 } else if (r == Session::Recording && h) {
2066 rec_button.set_visual_state (1);
2068 rec_button.set_visual_state (0);
2073 ARDOUR_UI::save_template ()
2075 ArdourPrompter prompter (true);
2078 if (!check_audioengine()) {
2082 prompter.set_name (X_("Prompter"));
2083 prompter.set_title (_("Save Mix Template"));
2084 prompter.set_prompt (_("Name for mix template:"));
2085 prompter.set_initial_text(session->name() + _("-template"));
2086 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
2088 switch (prompter.run()) {
2089 case RESPONSE_ACCEPT:
2090 prompter.get_result (name);
2092 if (name.length()) {
2093 session->save_template (name);
2103 ARDOUR_UI::edit_metadata ()
2105 SessionMetadataEditor dialog;
2106 dialog.set_session (session);
2107 editor->ensure_float (dialog);
2112 ARDOUR_UI::import_metadata ()
2114 SessionMetadataImporter dialog;
2115 dialog.set_session (session);
2116 editor->ensure_float (dialog);
2121 ARDOUR_UI::fontconfig_dialog ()
2124 /* X11 users will always have fontconfig info around, but new GTK-OSX users
2125 may not and it can take a while to build it. Warn them.
2128 Glib::ustring fontconfig = Glib::build_filename (Glib::get_home_dir(), ".fontconfig");
2130 if (!Glib::file_test (fontconfig, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
2131 MessageDialog msg (*_startup,
2132 _("Welcome to Ardour.\n\n"
2133 "The program will take a bit longer to start up\n"
2134 "while the system fonts are checked.\n\n"
2135 "This will only be done once, and you will\n"
2136 "not see this message again\n"),
2149 ARDOUR_UI::parse_cmdline_path (const Glib::ustring& cmdline_path, Glib::ustring& session_name, Glib::ustring& session_path, bool& existing_session)
2151 existing_session = false;
2153 if (Glib::file_test (cmdline_path, Glib::FILE_TEST_IS_DIR)) {
2154 session_path = cmdline_path;
2155 existing_session = true;
2156 } else if (Glib::file_test (cmdline_path, Glib::FILE_TEST_IS_REGULAR)) {
2157 session_path = Glib::path_get_dirname (string (cmdline_path));
2158 existing_session = true;
2160 /* it doesn't exist, assume the best */
2161 session_path = Glib::path_get_dirname (string (cmdline_path));
2164 session_name = basename_nosuffix (string (cmdline_path));
2168 ARDOUR_UI::load_cmdline_session (const Glib::ustring& session_name, const Glib::ustring& session_path, bool& existing_session)
2170 /* when this is called, the backend audio system must be running */
2172 /* the main idea here is to deal with the fact that a cmdline argument for the session
2173 can be interpreted in different ways - it could be a directory or a file, and before
2174 we load, we need to know both the session directory and the snapshot (statefile) within it
2175 that we are supposed to use.
2178 if (session_name.length() == 0 || session_path.length() == 0) {
2182 if (Glib::file_test (session_path, Glib::FILE_TEST_IS_DIR)) {
2184 Glib::ustring predicted_session_file;
2186 predicted_session_file = session_path;
2187 predicted_session_file += '/';
2188 predicted_session_file += session_name;
2189 predicted_session_file += ARDOUR::statefile_suffix;
2191 if (Glib::file_test (predicted_session_file, Glib::FILE_TEST_EXISTS)) {
2192 existing_session = true;
2195 } else if (Glib::file_test (session_path, Glib::FILE_TEST_EXISTS)) {
2197 if (session_path.find (ARDOUR::statefile_suffix) == session_path.length() - 7) {
2198 /* existing .ardour file */
2199 existing_session = true;
2203 existing_session = false;
2206 /* lets just try to load it */
2208 if (create_engine ()) {
2209 backend_audio_error (false, _startup);
2213 return load_session (session_path, session_name);
2217 ARDOUR_UI::ask_about_loading_existing_session (const Glib::ustring& session_path)
2219 Glib::ustring str = string_compose (_("This session\n%1\nalready exists. Do you want to open it?"), session_path);
2221 MessageDialog msg (str,
2223 Gtk::MESSAGE_WARNING,
2224 Gtk::BUTTONS_YES_NO,
2228 msg.set_name (X_("CleanupDialog"));
2229 msg.set_title (_("Cleanup Unused Sources"));
2230 msg.set_wmclass (X_("existing_session"), "Ardour");
2231 msg.set_position (Gtk::WIN_POS_MOUSE);
2234 switch (msg.run()) {
2243 ARDOUR_UI::build_session_from_nsd (const Glib::ustring& session_path, const Glib::ustring& session_name)
2248 AutoConnectOption iconnect;
2249 AutoConnectOption oconnect;
2253 if (Profile->get_sae()) {
2257 iconnect = AutoConnectPhysical;
2258 oconnect = AutoConnectMaster;
2259 nphysin = 0; // use all available
2260 nphysout = 0; // use all available
2264 /* get settings from advanced section of NSD */
2266 if (_startup->create_control_bus()) {
2267 cchns = (uint32_t) _startup->control_channel_count();
2272 if (_startup->create_master_bus()) {
2273 mchns = (uint32_t) _startup->master_channel_count();
2278 if (_startup->connect_inputs()) {
2279 iconnect = AutoConnectPhysical;
2281 iconnect = AutoConnectOption (0);
2284 /// @todo some minor tweaks.
2286 oconnect = AutoConnectOption (0);
2288 if (_startup->connect_outputs ()) {
2289 if (_startup->connect_outs_to_master()) {
2290 oconnect = AutoConnectMaster;
2291 } else if (_startup->connect_outs_to_physical()) {
2292 oconnect = AutoConnectPhysical;
2296 nphysin = (uint32_t) _startup->input_limit_count();
2297 nphysout = (uint32_t) _startup->output_limit_count();
2300 if (build_session (session_path,
2308 engine->frame_rate() * 60 * 5)) {
2317 ARDOUR_UI::idle_load (const Glib::ustring& path)
2320 if (Glib::file_test (path, Glib::FILE_TEST_IS_DIR)) {
2321 /* /path/to/foo => /path/to/foo, foo */
2322 load_session (path, basename_nosuffix (path));
2324 /* /path/to/foo/foo.ardour => /path/to/foo, foo */
2325 load_session (Glib::path_get_dirname (path), basename_nosuffix (path));
2329 ARDOUR_COMMAND_LINE::session_name = path;
2332 * new_session_dialog doens't exist in A3
2333 * Try to remove all references to it to
2334 * see if it will compile. NOTE: this will
2335 * likely cause a runtime issue is my somewhat
2339 //if (new_session_dialog) {
2342 /* make it break out of Dialog::run() and
2346 //new_session_dialog->response (1);
2352 ARDOUR_UI::end_loading_messages ()
2358 ARDOUR_UI::loading_message (const std::string& /*msg*/)
2361 // splash->message (msg);
2365 /** @param quit_on_cancel true if exit() should be called if the user clicks `cancel' in the new session dialog */
2367 ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new)
2369 Glib::ustring session_name;
2370 Glib::ustring session_path;
2371 Glib::ustring template_name;
2373 bool likely_new = false;
2377 if (!should_be_new && !ARDOUR_COMMAND_LINE::session_name.empty()) {
2379 /* if they named a specific statefile, use it, otherwise they are
2380 just giving a session folder, and we want to use it as is
2381 to find the session.
2384 if (ARDOUR_COMMAND_LINE::session_name.find (statefile_suffix) != string::npos) {
2385 session_path = Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name);
2387 session_path = ARDOUR_COMMAND_LINE::session_name;
2390 session_name = Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name);
2394 bool const apply = run_startup (should_be_new);
2396 if (quit_on_cancel) {
2403 /* if we run the startup dialog again, offer more than just "new session" */
2405 should_be_new = false;
2407 session_name = _startup->session_name (likely_new);
2409 /* this shouldn't happen, but we catch it just in case it does */
2411 if (session_name.empty()) {
2414 if (_startup->use_session_template()) {
2415 template_name = _startup->session_template_name();
2416 _session_is_new = true;
2419 if (session_name[0] == '/' ||
2420 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
2421 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
2423 session_path = Glib::path_get_dirname (session_name);
2424 session_name = Glib::path_get_basename (session_name);
2428 session_path = _startup->session_folder();
2432 if (create_engine ()) {
2436 if (Glib::file_test (session_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
2440 Glib::ustring existing = Glib::build_filename (session_path, session_name);
2442 if (!ask_about_loading_existing_session (existing)) {
2443 ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
2448 _session_is_new = false;
2453 MessageDialog msg (string_compose (_("There is no existing session at \"%1\""), session_path));
2455 ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
2459 _session_is_new = true;
2462 if (likely_new && template_name.empty()) {
2464 ret = build_session_from_nsd (session_path, session_name);
2468 ret = load_session (session_path, session_name, template_name);
2469 if (!ARDOUR_COMMAND_LINE::immediate_save.empty()) {
2470 session->save_state (ARDOUR_COMMAND_LINE::immediate_save, false);
2480 ARDOUR_UI::close_session()
2482 if (!check_audioengine()) {
2486 unload_session (true);
2488 ARDOUR_COMMAND_LINE::session_name = "";
2489 get_session_parameters (true, false);
2493 ARDOUR_UI::load_session (const Glib::ustring& path, const Glib::ustring& snap_name, Glib::ustring mix_template)
2495 Session *new_session;
2499 session_loaded = false;
2501 if (!check_audioengine()) {
2505 unload_status = unload_session ();
2507 if (unload_status < 0) {
2509 } else if (unload_status > 0) {
2514 loading_message (_("Please wait while Ardour loads your session"));
2517 new_session = new Session (*engine, path, snap_name, mix_template);
2520 /* this one is special */
2522 catch (AudioEngine::PortRegistrationFailure& err) {
2524 MessageDialog msg (err.what(),
2527 Gtk::BUTTONS_CLOSE);
2529 msg.set_title (_("Port Registration Error"));
2530 msg.set_secondary_text (_("Click the Close button to try again."));
2531 msg.set_position (Gtk::WIN_POS_CENTER);
2535 int response = msg.run ();
2540 case RESPONSE_CANCEL:
2550 MessageDialog msg (string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name),
2553 Gtk::BUTTONS_CLOSE);
2555 msg.set_title (_("Loading Error"));
2556 msg.set_secondary_text (_("Click the Close button to try again."));
2557 msg.set_position (Gtk::WIN_POS_CENTER);
2561 int response = msg.run ();
2566 case RESPONSE_CANCEL:
2574 connect_to_session (new_session);
2576 session_loaded = true;
2578 goto_editor_window ();
2581 session->set_clean ();
2592 ARDOUR_UI::build_session (const Glib::ustring& path, const Glib::ustring& snap_name,
2593 uint32_t control_channels,
2594 uint32_t master_channels,
2595 AutoConnectOption input_connect,
2596 AutoConnectOption output_connect,
2599 nframes_t initial_length)
2601 Session *new_session;
2604 if (!check_audioengine()) {
2608 session_loaded = false;
2610 x = unload_session ();
2618 _session_is_new = true;
2621 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
2622 control_channels, master_channels, nphysin, nphysout, initial_length);
2627 MessageDialog msg (string_compose(_("Could not create session in \"%1\""), path));
2633 connect_to_session (new_session);
2635 session_loaded = true;
2637 new_session->save_state(new_session->name());
2646 editor->show_window ();
2657 ARDOUR_UI::show_about ()
2661 about->signal_response().connect(mem_fun (*this, &ARDOUR_UI::about_signal_response) );
2668 ARDOUR_UI::hide_about ()
2671 about->get_window()->set_cursor ();
2677 ARDOUR_UI::about_signal_response (int /*response*/)
2683 ARDOUR_UI::show_splash ()
2687 splash = new Splash;
2695 splash->queue_draw ();
2696 splash->get_window()->process_updates (true);
2701 ARDOUR_UI::hide_splash ()
2709 ARDOUR_UI::display_cleanup_results (ARDOUR::CleanupReport& rep, const gchar* list_title,
2710 const string& plural_msg, const string& singular_msg)
2714 removed = rep.paths.size();
2717 MessageDialog msgd (*editor,
2718 _("No audio files were ready for cleanup"),
2721 (Gtk::ButtonsType)(Gtk::BUTTONS_OK) );
2722 msgd.set_secondary_text (_("If this seems suprising, \n\
2723 check for any existing snapshots.\n\
2724 These may still include regions that\n\
2725 require some unused files to continue to exist."));
2731 ArdourDialog results (_("ardour: cleanup"), true, false);
2733 struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
2734 CleanupResultsModelColumns() {
2738 Gtk::TreeModelColumn<Glib::ustring> visible_name;
2739 Gtk::TreeModelColumn<Glib::ustring> fullpath;
2743 CleanupResultsModelColumns results_columns;
2744 Glib::RefPtr<Gtk::ListStore> results_model;
2745 Gtk::TreeView results_display;
2747 results_model = ListStore::create (results_columns);
2748 results_display.set_model (results_model);
2749 results_display.append_column (list_title, results_columns.visible_name);
2751 results_display.set_name ("CleanupResultsList");
2752 results_display.set_headers_visible (true);
2753 results_display.set_headers_clickable (false);
2754 results_display.set_reorderable (false);
2756 Gtk::ScrolledWindow list_scroller;
2759 Gtk::HBox dhbox; // the hbox for the image and text
2760 Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
2761 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO, Gtk::ICON_SIZE_DIALOG));
2763 dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
2765 const string dead_sound_directory = session->session_directory().dead_sound_path().to_string();
2771 %1 - number of files removed
2772 %2 - location of "dead_sounds"
2773 %3 - size of files affected
2774 %4 - prefix for "bytes" to produce sensible results (e.g. mega, kilo, giga)
2777 const char* bprefix;
2779 if (rep.space < 1048576.0f) {
2780 bprefix = X_("kilo");
2781 } else if (rep.space < 1048576.0f * 1000) {
2782 bprefix = X_("mega");
2784 bprefix = X_("giga");
2788 txt.set_text (string_compose (plural_msg, removed, dead_sound_directory, (float) rep.space / 1024.0f, bprefix));
2790 txt.set_text (string_compose (singular_msg, removed, dead_sound_directory, (float) rep.space / 1024.0f, bprefix));
2793 dhbox.pack_start (*dimage, true, false, 5);
2794 dhbox.pack_start (txt, true, false, 5);
2796 for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2797 TreeModel::Row row = *(results_model->append());
2798 row[results_columns.visible_name] = *i;
2799 row[results_columns.fullpath] = *i;
2802 list_scroller.add (results_display);
2803 list_scroller.set_size_request (-1, 150);
2804 list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2806 dvbox.pack_start (dhbox, true, false, 5);
2807 dvbox.pack_start (list_scroller, true, false, 5);
2808 ddhbox.pack_start (dvbox, true, false, 5);
2810 results.get_vbox()->pack_start (ddhbox, true, false, 5);
2811 results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
2812 results.set_default_response (RESPONSE_CLOSE);
2813 results.set_position (Gtk::WIN_POS_MOUSE);
2815 results_display.show();
2816 list_scroller.show();
2823 //results.get_vbox()->show();
2824 results.set_resizable (false);
2831 ARDOUR_UI::cleanup ()
2834 /* shouldn't happen: menu item is insensitive */
2839 MessageDialog checker (_("Are you sure you want to cleanup?"),
2841 Gtk::MESSAGE_QUESTION,
2842 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
2844 checker.set_secondary_text(_("Cleanup is a destructive operation.\n\
2845 ALL undo/redo information will be lost if you cleanup.\n\
2846 After cleanup, unused audio files will be moved to a \
2847 \"dead sounds\" location."));
2849 checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2850 checker.add_button (_("Clean Up"), RESPONSE_ACCEPT);
2851 checker.set_default_response (RESPONSE_CANCEL);
2853 checker.set_name (_("CleanupDialog"));
2854 checker.set_wmclass (X_("ardour_cleanup"), "Ardour");
2855 checker.set_position (Gtk::WIN_POS_MOUSE);
2857 switch (checker.run()) {
2858 case RESPONSE_ACCEPT:
2864 ARDOUR::CleanupReport rep;
2866 editor->prepare_for_cleanup ();
2868 /* do not allow flush until a session is reloaded */
2870 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
2872 act->set_sensitive (false);
2875 if (session->cleanup_sources (rep)) {
2876 editor->finish_cleanup ();
2880 editor->finish_cleanup ();
2883 display_cleanup_results (rep,
2886 The following %1 files were not in use and \n\
2887 have been moved to:\n\
2889 Flushing the wastebasket will \n\
2890 release an additional\n\
2891 %3 %4bytes of disk space.\n"),
2893 The following file was not in use and \n \
2894 has been moved to:\n \
2896 Flushing the wastebasket will \n\
2897 release an additional\n\
2898 %3 %4bytes of disk space.\n"
2904 ARDOUR_UI::flush_trash ()
2907 /* shouldn't happen: menu item is insensitive */
2911 ARDOUR::CleanupReport rep;
2913 if (session->cleanup_trash_sources (rep)) {
2917 display_cleanup_results (rep,
2919 _("The following %1 files were deleted from\n\
2921 releasing %3 %4bytes of disk space"),
2922 _("The following file was deleted from\n\
2924 releasing %3 %4bytes of disk space"));
2928 ARDOUR_UI::add_route (Gtk::Window* float_window)
2936 if (add_route_dialog == 0) {
2937 add_route_dialog = new AddRouteDialog (*session);
2939 add_route_dialog->set_transient_for (*float_window);
2943 if (add_route_dialog->is_visible()) {
2944 /* we're already doing this */
2948 ResponseType r = (ResponseType) add_route_dialog->run ();
2950 add_route_dialog->hide();
2953 case RESPONSE_ACCEPT:
2960 if ((count = add_route_dialog->count()) <= 0) {
2964 string template_path = add_route_dialog->track_template();
2966 if (!template_path.empty()) {
2967 session->new_route_from_template (count, template_path);
2971 uint32_t input_chan = add_route_dialog->channels ();
2972 uint32_t output_chan;
2973 string name_template = add_route_dialog->name_template ();
2974 bool track = add_route_dialog->track ();
2975 RouteGroup* route_group = add_route_dialog->route_group ();
2977 AutoConnectOption oac = Config->get_output_auto_connect();
2979 if (oac & AutoConnectMaster) {
2980 output_chan = (session->master_out() ? session->master_out()->n_inputs().n_audio() : input_chan);
2982 output_chan = input_chan;
2985 /* XXX do something with name template */
2987 if (add_route_dialog->type() == ARDOUR::DataType::MIDI) {
2989 session_add_midi_track (route_group, count);
2991 MessageDialog msg (*editor,
2992 _("Sorry, MIDI Busses are not supported at this time."));
2994 //session_add_midi_bus();
2998 session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), route_group, count);
3000 session_add_audio_bus (input_chan, output_chan, route_group, count);
3006 ARDOUR_UI::mixer_settings () const
3011 node = session->instant_xml(X_("Mixer"));
3013 node = Config->instant_xml(X_("Mixer"));
3017 node = new XMLNode (X_("Mixer"));
3024 ARDOUR_UI::editor_settings () const
3029 node = session->instant_xml(X_("Editor"));
3031 node = Config->instant_xml(X_("Editor"));
3035 if (getenv("ARDOUR_INSTANT_XML_PATH")) {
3036 node = Config->instant_xml(getenv("ARDOUR_INSTANT_XML_PATH"));
3041 node = new XMLNode (X_("Editor"));
3048 ARDOUR_UI::keyboard_settings () const
3052 node = Config->extra_xml(X_("Keyboard"));
3055 node = new XMLNode (X_("Keyboard"));
3061 ARDOUR_UI::create_xrun_marker(nframes_t where)
3063 editor->mouse_add_new_marker (where, false, true);
3067 ARDOUR_UI::halt_on_xrun_message ()
3069 MessageDialog msg (*editor,
3070 _("Recording was stopped because your system could not keep up."));
3075 ARDOUR_UI::xrun_handler(nframes_t where)
3081 ENSURE_GUI_THREAD (bind(mem_fun(*this, &ARDOUR_UI::xrun_handler), where));
3083 if (session && Config->get_create_xrun_marker() && session->actively_recording()) {
3084 create_xrun_marker(where);
3087 if (session && Config->get_stop_recording_on_xrun() && session->actively_recording()) {
3088 halt_on_xrun_message ();
3093 ARDOUR_UI::push_buffer_stats (uint32_t capture, uint32_t playback)
3098 while (disk_buffer_stats.size() > 60) {
3099 disk_buffer_stats.pop_front ();
3102 disk_buffer_stats.push_back (DiskBufferStat (now, capture, playback));
3106 ARDOUR_UI::write_buffer_stats ()
3112 char path[PATH_MAX+1]; int fd;
3114 strcpy (path, "ardourBufferingXXXXXX");
3116 if ((fd = mkstemp (path )) < 0) {
3117 cerr << X_("cannot find temporary name for ardour buffer stats") << endl;
3125 cerr << string_compose (X_("cannot open file %1 for ardour buffer stats"), path) << endl;
3129 for (list<DiskBufferStat>::iterator i = disk_buffer_stats.begin(); i != disk_buffer_stats.end(); ++i) {
3130 localtime_r (&(*i).when, &tm);
3131 strftime (buf, sizeof (buf), "%T", &tm);
3132 fout << buf << ' ' << (*i).capture << ' ' << (*i).playback << endl;
3135 disk_buffer_stats.clear ();
3139 cerr << "Ardour buffering statistics can be found in: " << path << endl;
3143 ARDOUR_UI::disk_overrun_handler ()
3145 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
3147 write_buffer_stats ();
3149 if (!have_disk_speed_dialog_displayed) {
3150 have_disk_speed_dialog_displayed = true;
3151 MessageDialog* msg = new MessageDialog (*editor, _("\
3152 The disk system on your computer\n\
3153 was not able to keep up with Ardour.\n\
3155 Specifically, it failed to write data to disk\n\
3156 quickly enough to keep up with recording.\n"));
3157 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
3163 ARDOUR_UI::disk_underrun_handler ()
3165 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
3167 write_buffer_stats ();
3169 if (!have_disk_speed_dialog_displayed) {
3170 have_disk_speed_dialog_displayed = true;
3171 MessageDialog* msg = new MessageDialog (*editor,
3172 _("The disk system on your computer\n\
3173 was not able to keep up with Ardour.\n\
3175 Specifically, it failed to read data from disk\n\
3176 quickly enough to keep up with playback.\n"));
3177 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
3183 ARDOUR_UI::disk_speed_dialog_gone (int /*ignored_response*/, MessageDialog* msg)
3185 have_disk_speed_dialog_displayed = false;
3190 ARDOUR_UI::session_dialog (std::string msg)
3192 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::session_dialog), msg));
3197 d = new MessageDialog (*editor, msg, false, MESSAGE_INFO, BUTTONS_OK, true);
3199 d = new MessageDialog (msg, false, MESSAGE_INFO, BUTTONS_OK, true);
3208 ARDOUR_UI::pending_state_dialog ()
3210 HBox* hbox = new HBox();
3211 Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG);
3212 ArdourDialog dialog (_("Crash Recovery"), true);
3214 This session appears to have been in\n\
3215 middle of recording when ardour or\n\
3216 the computer was shutdown.\n\
3218 Ardour can recover any captured audio for\n\
3219 you, or it can ignore it. Please decide\n\
3220 what you would like to do.\n"));
3221 image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
3222 hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
3223 hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
3224 dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
3225 dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
3226 dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
3227 dialog.set_default_response (RESPONSE_ACCEPT);
3228 dialog.set_position (WIN_POS_CENTER);
3233 switch (dialog.run ()) {
3234 case RESPONSE_ACCEPT:
3242 ARDOUR_UI::sr_mismatch_dialog (nframes_t desired, nframes_t actual)
3244 HBox* hbox = new HBox();
3245 Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG);
3246 ArdourDialog dialog (_("Sample Rate Mismatch"), true);
3247 Label message (string_compose (_("\
3248 This session was created with a sample rate of %1 Hz\n\
3250 The audioengine is currently running at %2 Hz\n"), desired, actual));
3252 image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
3253 hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
3254 hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
3255 dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
3256 dialog.add_button (_("Do not load session"), RESPONSE_REJECT);
3257 dialog.add_button (_("Load session anyway"), RESPONSE_ACCEPT);
3258 dialog.set_default_response (RESPONSE_ACCEPT);
3259 dialog.set_position (WIN_POS_CENTER);
3264 switch (dialog.run ()) {
3265 case RESPONSE_ACCEPT:
3274 ARDOUR_UI::disconnect_from_jack ()
3277 if( engine->disconnect_from_jack ()) {
3278 MessageDialog msg (*editor, _("Could not disconnect from JACK"));
3282 update_sample_rate (0);
3287 ARDOUR_UI::reconnect_to_jack ()
3290 if (engine->reconnect_to_jack ()) {
3291 MessageDialog msg (*editor, _("Could not reconnect to JACK"));
3295 update_sample_rate (0);
3300 ARDOUR_UI::use_config ()
3303 XMLNode* node = Config->extra_xml (X_("TransportControllables"));
3305 set_transport_controllable_state (*node);
3310 ARDOUR_UI::update_transport_clocks (nframes_t pos)
3312 if (Config->get_primary_clock_delta_edit_cursor()) {
3313 primary_clock.set (pos, false, editor->get_preferred_edit_position(), 1);
3315 primary_clock.set (pos, 0, true);
3318 if (Config->get_secondary_clock_delta_edit_cursor()) {
3319 secondary_clock.set (pos, false, editor->get_preferred_edit_position(), 2);
3321 secondary_clock.set (pos);
3324 if (big_clock_window) {
3325 big_clock.set (pos);
3330 ARDOUR_UI::record_state_changed ()
3332 ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::record_state_changed));
3334 if (!session || !big_clock_window) {
3335 /* why bother - the clock isn't visible */
3339 Session::RecordState const r = session->record_status ();
3340 bool const h = session->have_rec_enabled_diskstream ();
3342 if (r == Session::Recording && h) {
3343 big_clock.set_widget_name ("BigClockRecording");
3345 big_clock.set_widget_name ("BigClockNonRecording");
3350 ARDOUR_UI::first_idle ()
3353 session->allow_auto_play (true);
3357 editor->first_idle();
3360 Keyboard::set_can_save_keybindings (true);
3365 ARDOUR_UI::store_clock_modes ()
3367 XMLNode* node = new XMLNode(X_("ClockModes"));
3369 for (vector<AudioClock*>::iterator x = AudioClock::clocks.begin(); x != AudioClock::clocks.end(); ++x) {
3370 node->add_property ((*x)->name().c_str(), enum_2_string ((*x)->mode()));
3373 session->add_extra_xml (*node);
3374 session->set_dirty ();
3379 ARDOUR_UI::TransportControllable::TransportControllable (std::string name, ARDOUR_UI& u, ToggleType tp)
3380 : Controllable (name), ui (u), type(tp)
3386 ARDOUR_UI::TransportControllable::set_value (float val)
3388 if (type == ShuttleControl) {
3395 fract = -((0.5f - val)/0.5f);
3397 fract = ((val - 0.5f)/0.5f);
3401 ui.set_shuttle_fract (fract);
3406 /* do nothing: these are radio-style actions */
3410 const char *action = 0;
3414 action = X_("Roll");
3417 action = X_("Stop");
3420 action = X_("Goto Start");
3423 action = X_("Goto End");
3426 action = X_("Loop");
3429 action = X_("Play Selection");
3432 action = X_("Record");
3442 Glib::RefPtr<Action> act = ActionManager::get_action ("Transport", action);
3450 ARDOUR_UI::TransportControllable::get_value (void) const
3469 case ShuttleControl:
3479 ARDOUR_UI::TransportControllable::set_id (const string& str)
3485 ARDOUR_UI::setup_profile ()
3487 if (gdk_screen_width() < 1200) {
3488 Profile->set_small_screen ();
3492 if (getenv ("ARDOUR_SAE")) {
3493 Profile->set_sae ();
3494 Profile->set_single_package ();