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, true, false, true),
121 secondary_clock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, true, false, true),
122 preroll_clock (X_("preroll"), false, X_("PreRollClock"), true, false, true),
123 postroll_clock (X_("postroll"), false, X_("PostRollClock"), true, false, true),
127 preroll_button (_("pre\nroll")),
128 postroll_button (_("post\nroll")),
132 big_clock (X_("bigclock"), false, "BigClockNonRecording", true, 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 ();
267 SessionEvent::create_per_thread_pool ("GUI", 512);
269 } catch (failed_constructor& err) {
270 error << _("could not initialize Ardour.") << endmsg;
275 /* we like keyboards */
277 keyboard = new Keyboard;
281 starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
282 stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
287 /** @return true if a session was chosen and `apply' clicked, otherwise false if `cancel' was clicked */
289 ARDOUR_UI::run_startup (bool should_be_new)
292 _startup = new ArdourStartup ();
295 _startup->set_new_only (should_be_new);
296 _startup->present ();
302 switch (_startup->response()) {
311 ARDOUR_UI::create_engine ()
313 // this gets called every time by new_session()
319 loading_message (_("Starting audio engine"));
322 engine = new ARDOUR::AudioEngine (ARDOUR_COMMAND_LINE::jack_client_name);
329 engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
330 engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
331 engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
332 engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
340 ARDOUR_UI::post_engine ()
342 /* Things to be done once we create the AudioEngine
345 MIDI::Manager::instance()->set_api_data (engine->jack());
348 ARDOUR::init_post_engine ();
350 ActionManager::init ();
353 if (setup_windows ()) {
354 throw failed_constructor ();
357 check_memory_locking();
359 /* this is the first point at which all the keybindings are available */
361 if (ARDOUR_COMMAND_LINE::show_key_actions) {
362 vector<string> names;
363 vector<string> paths;
365 vector<AccelKey> bindings;
367 ActionManager::get_all_actions (names, paths, keys, bindings);
369 vector<string>::iterator n;
370 vector<string>::iterator k;
371 for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) {
372 cerr << "Action: " << (*n) << " bound to " << (*k) << endl;
378 blink_timeout_tag = -1;
380 /* this being a GUI and all, we want peakfiles */
382 AudioFileSource::set_build_peakfiles (true);
383 AudioFileSource::set_build_missing_peakfiles (true);
385 /* set default clock modes */
387 if (Profile->get_sae()) {
388 primary_clock.set_mode (AudioClock::BBT);
389 secondary_clock.set_mode (AudioClock::MinSec);
391 primary_clock.set_mode (AudioClock::Timecode);
392 secondary_clock.set_mode (AudioClock::BBT);
395 /* start the time-of-day-clock */
398 /* OS X provides an always visible wallclock, so don't be stupid */
399 update_wall_clock ();
400 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
403 update_disk_space ();
405 update_sample_rate (engine->frame_rate());
407 Config->ParameterChanged.connect (mem_fun (*this, &ARDOUR_UI::parameter_changed));
408 Config->map_parameters (mem_fun (*this, &ARDOUR_UI::parameter_changed));
410 /* now start and maybe save state */
412 if (do_engine_start () == 0) {
413 if (session && _session_is_new) {
414 /* we need to retain initial visual
415 settings for a new session
417 session->save_state ("");
422 ARDOUR_UI::~ARDOUR_UI ()
424 save_ardour_state ();
429 delete add_route_dialog;
433 ARDOUR_UI::pop_back_splash ()
435 if (Splash::instance()) {
436 // Splash::instance()->pop_back();
437 Splash::instance()->hide ();
442 ARDOUR_UI::configure_timeout ()
444 if (last_configure_time == 0) {
445 /* no configure events yet */
449 /* force a gap of 0.5 seconds since the last configure event
452 if (get_microseconds() - last_configure_time < 500000) {
455 have_configure_timeout = false;
456 save_ardour_state ();
462 ARDOUR_UI::configure_handler (GdkEventConfigure* /*conf*/)
464 if (have_configure_timeout) {
465 last_configure_time = get_microseconds();
467 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
468 have_configure_timeout = true;
475 ARDOUR_UI::set_transport_controllable_state (const XMLNode& node)
477 const XMLProperty* prop;
479 if ((prop = node.property ("roll")) != 0) {
480 roll_controllable->set_id (prop->value());
482 if ((prop = node.property ("stop")) != 0) {
483 stop_controllable->set_id (prop->value());
485 if ((prop = node.property ("goto-start")) != 0) {
486 goto_start_controllable->set_id (prop->value());
488 if ((prop = node.property ("goto-end")) != 0) {
489 goto_end_controllable->set_id (prop->value());
491 if ((prop = node.property ("auto-loop")) != 0) {
492 auto_loop_controllable->set_id (prop->value());
494 if ((prop = node.property ("play-selection")) != 0) {
495 play_selection_controllable->set_id (prop->value());
497 if ((prop = node.property ("rec")) != 0) {
498 rec_controllable->set_id (prop->value());
500 if ((prop = node.property ("shuttle")) != 0) {
501 shuttle_controllable->set_id (prop->value());
506 ARDOUR_UI::get_transport_controllable_state ()
508 XMLNode* node = new XMLNode(X_("TransportControllables"));
511 roll_controllable->id().print (buf, sizeof (buf));
512 node->add_property (X_("roll"), buf);
513 stop_controllable->id().print (buf, sizeof (buf));
514 node->add_property (X_("stop"), buf);
515 goto_start_controllable->id().print (buf, sizeof (buf));
516 node->add_property (X_("goto_start"), buf);
517 goto_end_controllable->id().print (buf, sizeof (buf));
518 node->add_property (X_("goto_end"), buf);
519 auto_loop_controllable->id().print (buf, sizeof (buf));
520 node->add_property (X_("auto_loop"), buf);
521 play_selection_controllable->id().print (buf, sizeof (buf));
522 node->add_property (X_("play_selection"), buf);
523 rec_controllable->id().print (buf, sizeof (buf));
524 node->add_property (X_("rec"), buf);
525 shuttle_controllable->id().print (buf, sizeof (buf));
526 node->add_property (X_("shuttle"), buf);
532 ARDOUR_UI::save_ardour_state ()
534 if (!keyboard || !mixer || !editor) {
538 /* XXX this is all a bit dubious. add_extra_xml() uses
539 a different lifetime model from add_instant_xml().
542 XMLNode* node = new XMLNode (keyboard->get_state());
543 Config->add_extra_xml (*node);
544 Config->add_extra_xml (get_transport_controllable_state());
545 if (_startup && _startup->engine_control() && _startup->engine_control()->was_used()) {
546 Config->add_extra_xml (_startup->engine_control()->get_state());
548 Config->save_state();
549 ui_config->save_state ();
551 XMLNode enode(static_cast<Stateful*>(editor)->get_state());
552 XMLNode mnode(mixer->get_state());
555 session->add_instant_xml (enode);
556 session->add_instant_xml (mnode);
558 Config->add_instant_xml (enode);
559 Config->add_instant_xml (mnode);
562 Keyboard::save_keybindings ();
566 ARDOUR_UI::autosave_session ()
568 if (g_main_depth() > 1) {
569 /* inside a recursive main loop,
570 give up because we may not be able to
576 if (!Config->get_periodic_safety_backups()) {
581 session->maybe_write_autosave();
588 ARDOUR_UI::update_autosave ()
590 ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::update_autosave));
592 if (session && session->dirty()) {
593 if (_autosave_connection.connected()) {
594 _autosave_connection.disconnect();
597 _autosave_connection = Glib::signal_timeout().connect (mem_fun (*this, &ARDOUR_UI::autosave_session),
598 Config->get_periodic_safety_backup_interval() * 1000);
601 if (_autosave_connection.connected()) {
602 _autosave_connection.disconnect();
608 ARDOUR_UI::backend_audio_error (bool we_set_params, Gtk::Window* toplevel)
612 title = _("Ardour could not start JACK");
614 title = _("Ardour could not connect to JACK.");
617 MessageDialog win (title,
623 win.set_secondary_text(_("There are several possible reasons:\n\
625 1) You requested audio parameters that are not supported..\n\
626 2) JACK is running as another user.\n\
628 Please consider the possibilities, and perhaps try different parameters."));
630 win.set_secondary_text(_("There are several possible reasons:\n\
632 1) JACK is not running.\n\
633 2) JACK is running as another user, perhaps root.\n\
634 3) There is already another client called \"ardour\".\n\
636 Please consider the possibilities, and perhaps (re)start JACK."));
640 win.set_transient_for (*toplevel);
644 win.add_button (Stock::OK, RESPONSE_CLOSE);
646 win.add_button (Stock::QUIT, RESPONSE_CLOSE);
649 win.set_default_response (RESPONSE_CLOSE);
652 win.set_position (Gtk::WIN_POS_CENTER);
655 /* we just don't care about the result, but we want to block */
661 ARDOUR_UI::startup ()
663 XMLNode* audio_setup = Config->extra_xml ("AudioSetup");
665 if (audio_setup && _startup && _startup->engine_control()) {
666 _startup->engine_control()->set_state (*audio_setup);
669 if (get_session_parameters (true, ARDOUR_COMMAND_LINE::new_session)) {
675 goto_editor_window ();
677 BootMessage (_("Ardour is ready for use"));
682 ARDOUR_UI::no_memory_warning ()
684 XMLNode node (X_("no-memory-warning"));
685 Config->add_instant_xml (node);
689 ARDOUR_UI::check_memory_locking ()
692 /* OS X doesn't support mlockall(2), and so testing for memory locking capability there is pointless */
696 XMLNode* memory_warning_node = Config->instant_xml (X_("no-memory-warning"));
698 if (engine->is_realtime() && memory_warning_node == 0) {
700 struct rlimit limits;
702 long pages, page_size;
704 if ((page_size = sysconf (_SC_PAGESIZE)) < 0 ||(pages = sysconf (_SC_PHYS_PAGES)) < 0) {
707 ram = (int64_t) pages * (int64_t) page_size;
710 if (getrlimit (RLIMIT_MEMLOCK, &limits)) {
714 if (limits.rlim_cur != RLIM_INFINITY) {
716 if (ram == 0 || ((double) limits.rlim_cur / ram) < 0.75) {
719 MessageDialog msg (_("WARNING: Your system has a limit for maximum amount of locked memory. "
720 "This might cause Ardour to run out of memory before your system "
721 "runs out of memory. \n\n"
722 "You can view the memory limit with 'ulimit -l', "
723 "and it is normally controlled by /etc/security/limits.conf"));
725 VBox* vbox = msg.get_vbox();
727 CheckButton cb (_("Do not show this window again"));
729 cb.signal_toggled().connect (mem_fun (*this, &ARDOUR_UI::no_memory_warning));
731 hbox.pack_start (cb, true, false);
732 vbox->pack_start (hbox);
739 editor->ensure_float (msg);
753 if (session->transport_rolling()) {
754 session->request_stop ();
758 if (session->dirty()) {
759 switch (ask_about_saving_session(_("quit"))) {
764 /* use the default name */
765 if (save_state_canfail ("")) {
766 /* failed - don't quit */
767 MessageDialog msg (*editor,
769 Ardour was unable to save your session.\n\n\
770 If you still wish to quit, please use the\n\n\
771 \"Just quit\" option."));
782 second_connection.disconnect ();
783 point_one_second_connection.disconnect ();
784 point_oh_five_second_connection.disconnect ();
785 point_zero_one_second_connection.disconnect();
787 // session->set_deletion_in_progress ();
788 session->remove_pending_capture_state ();
793 ArdourDialog::close_all_dialogs ();
795 save_ardour_state ();
800 ARDOUR_UI::ask_about_saving_session (const string & what)
802 ArdourDialog window (_("ardour: save session?"));
803 Gtk::HBox dhbox; // the hbox for the image and text
804 Gtk::Label prompt_label;
805 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_WARNING, Gtk::ICON_SIZE_DIALOG));
809 msg = string_compose(_("Don't %1"), what);
810 window.add_button (msg, RESPONSE_REJECT);
811 msg = string_compose(_("Just %1"), what);
812 window.add_button (msg, RESPONSE_APPLY);
813 msg = string_compose(_("Save and %1"), what);
814 window.add_button (msg, RESPONSE_ACCEPT);
816 window.set_default_response (RESPONSE_ACCEPT);
818 Gtk::Button noquit_button (msg);
819 noquit_button.set_name ("EditorGTKButton");
824 if (session->snap_name() == session->name()) {
827 type = _("snapshot");
829 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?"),
830 type, session->snap_name());
832 prompt_label.set_text (prompt);
833 prompt_label.set_name (X_("PrompterLabel"));
834 prompt_label.set_alignment(ALIGN_LEFT, ALIGN_TOP);
836 dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP);
837 dhbox.set_homogeneous (false);
838 dhbox.pack_start (*dimage, false, false, 5);
839 dhbox.pack_start (prompt_label, true, false, 5);
840 window.get_vbox()->pack_start (dhbox);
842 window.set_name (_("Prompter"));
843 window.set_position (Gtk::WIN_POS_MOUSE);
844 window.set_modal (true);
845 window.set_resizable (false);
851 window.set_keep_above (true);
854 ResponseType r = (ResponseType) window.run();
859 case RESPONSE_ACCEPT: // save and get out of here
861 case RESPONSE_APPLY: // get out of here
871 ARDOUR_UI::every_second ()
874 update_buffer_load ();
875 update_disk_space ();
880 ARDOUR_UI::every_point_one_seconds ()
882 update_speed_display ();
883 RapidScreenUpdate(); /* EMIT_SIGNAL */
888 ARDOUR_UI::every_point_zero_one_seconds ()
890 // august 2007: actual update frequency: 40Hz, not 100Hz
892 SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
897 ARDOUR_UI::update_sample_rate (nframes_t ignored)
901 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
903 if (!engine->connected()) {
905 snprintf (buf, sizeof (buf), _("disconnected"));
909 nframes_t rate = engine->frame_rate();
911 if (fmod (rate, 1000.0) != 0.0) {
912 snprintf (buf, sizeof (buf), _("%.1f kHz / %4.1f ms"),
913 (float) rate/1000.0f,
914 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
916 snprintf (buf, sizeof (buf), _("%u kHz / %4.1f ms"),
918 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
922 sample_rate_label.set_text (buf);
926 ARDOUR_UI::update_cpu_load ()
929 snprintf (buf, sizeof (buf), _("DSP: %5.1f%%"), engine->get_cpu_load());
930 cpu_load_label.set_text (buf);
934 ARDOUR_UI::update_buffer_load ()
940 c = session->capture_load ();
941 p = session->playback_load ();
943 push_buffer_stats (c, p);
945 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"),
946 session->playback_load(), session->capture_load());
947 buffer_load_label.set_text (buf);
949 buffer_load_label.set_text ("");
954 ARDOUR_UI::count_recenabled_streams (Route& route)
956 Track* track = dynamic_cast<Track*>(&route);
957 if (track && track->diskstream()->record_enabled()) {
958 rec_enabled_streams += track->n_inputs().n_total();
963 ARDOUR_UI::update_disk_space()
969 nframes_t frames = session->available_capture_duration();
971 nframes_t fr = session->frame_rate();
973 if (frames == max_frames) {
974 strcpy (buf, _("Disk: 24hrs+"));
976 rec_enabled_streams = 0;
977 session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
979 if (rec_enabled_streams) {
980 frames /= rec_enabled_streams;
987 hrs = frames / (fr * 3600);
988 frames -= hrs * fr * 3600;
989 mins = frames / (fr * 60);
990 frames -= mins * fr * 60;
993 snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs);
996 disk_space_label.set_text (buf);
998 // An attempt to make the disk space label flash red when space has run out.
1000 if (frames < fr * 60 * 5) {
1001 /* disk_space_box.style ("disk_space_label_empty"); */
1003 /* disk_space_box.style ("disk_space_label"); */
1009 ARDOUR_UI::update_wall_clock ()
1016 tm_now = localtime (&now);
1018 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
1019 wall_clock_label.set_text (buf);
1025 ARDOUR_UI::session_menu (GdkEventButton */*ev*/)
1027 session_popup_menu->popup (0, 0);
1032 ARDOUR_UI::redisplay_recent_sessions ()
1034 std::vector<sys::path> session_directories;
1035 RecentSessionsSorter cmp;
1037 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
1038 recent_session_model->clear ();
1040 ARDOUR::RecentSessions rs;
1041 ARDOUR::read_recent_sessions (rs);
1044 recent_session_display.set_model (recent_session_model);
1048 // sort them alphabetically
1049 sort (rs.begin(), rs.end(), cmp);
1051 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
1052 session_directories.push_back ((*i).second);
1055 for (vector<sys::path>::const_iterator i = session_directories.begin();
1056 i != session_directories.end(); ++i)
1058 std::vector<sys::path> state_file_paths;
1060 // now get available states for this session
1062 get_state_files_in_directory (*i, state_file_paths);
1064 vector<string*>* states;
1065 vector<const gchar*> item;
1066 string fullpath = (*i).to_string();
1068 /* remove any trailing / */
1070 if (fullpath[fullpath.length()-1] == '/') {
1071 fullpath = fullpath.substr (0, fullpath.length()-1);
1074 /* check whether session still exists */
1075 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
1076 /* session doesn't exist */
1077 cerr << "skipping non-existent session " << fullpath << endl;
1081 /* now get available states for this session */
1083 if ((states = Session::possible_states (fullpath)) == 0) {
1084 /* no state file? */
1088 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
1090 Gtk::TreeModel::Row row = *(recent_session_model->append());
1092 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
1093 row[recent_session_columns.fullpath] = fullpath;
1095 if (state_file_names.size() > 1) {
1099 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
1100 i2 != state_file_names.end(); ++i2)
1103 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
1105 child_row[recent_session_columns.visible_name] = *i2;
1106 child_row[recent_session_columns.fullpath] = fullpath;
1111 recent_session_display.set_model (recent_session_model);
1115 ARDOUR_UI::build_session_selector ()
1117 session_selector_window = new ArdourDialog (_("Recent Sessions"));
1119 Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
1121 session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
1122 session_selector_window->add_button (Stock::OPEN, RESPONSE_ACCEPT);
1123 session_selector_window->set_default_response (RESPONSE_ACCEPT);
1124 recent_session_model = TreeStore::create (recent_session_columns);
1125 recent_session_display.set_model (recent_session_model);
1126 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1127 recent_session_display.set_headers_visible (false);
1128 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
1129 recent_session_display.signal_row_activated().connect (mem_fun (*this, &ARDOUR_UI::recent_session_row_activated));
1131 scroller->add (recent_session_display);
1132 scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1134 session_selector_window->set_name ("SessionSelectorWindow");
1135 session_selector_window->set_size_request (200, 400);
1136 session_selector_window->get_vbox()->pack_start (*scroller);
1138 recent_session_display.show();
1140 //session_selector_window->get_vbox()->show();
1144 ARDOUR_UI::recent_session_row_activated (const TreePath& /*path*/, TreeViewColumn* /*col*/)
1146 session_selector_window->response (RESPONSE_ACCEPT);
1150 ARDOUR_UI::open_recent_session ()
1152 bool can_return = (session != 0);
1154 if (session_selector_window == 0) {
1155 build_session_selector ();
1158 redisplay_recent_sessions ();
1162 session_selector_window->set_position (WIN_POS_MOUSE);
1164 ResponseType r = (ResponseType) session_selector_window->run ();
1167 case RESPONSE_ACCEPT:
1171 session_selector_window->hide();
1178 if (recent_session_display.get_selection()->count_selected_rows() == 0) {
1182 session_selector_window->hide();
1184 Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
1186 if (i == recent_session_model->children().end()) {
1190 Glib::ustring path = (*i)[recent_session_columns.fullpath];
1191 Glib::ustring state = (*i)[recent_session_columns.visible_name];
1193 _session_is_new = false;
1195 if (load_session (path, state) == 0) {
1204 ARDOUR_UI::check_audioengine ()
1207 if (!engine->connected()) {
1208 MessageDialog msg (_("Ardour is not connected to JACK\n"
1209 "You cannot open or close sessions in this condition"));
1221 ARDOUR_UI::open_session ()
1223 if (!check_audioengine()) {
1228 /* popup selector window */
1230 if (open_session_selector == 0) {
1232 /* ardour sessions are folders */
1234 open_session_selector = new Gtk::FileChooserDialog (_("Open Session"), FILE_CHOOSER_ACTION_OPEN);
1235 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1236 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
1237 open_session_selector->set_default_response(Gtk::RESPONSE_ACCEPT);
1239 FileFilter session_filter;
1240 session_filter.add_pattern ("*.ardour");
1241 session_filter.set_name (_("Ardour sessions"));
1242 open_session_selector->add_filter (session_filter);
1243 open_session_selector->set_filter (session_filter);
1246 int response = open_session_selector->run();
1247 open_session_selector->hide ();
1250 case RESPONSE_ACCEPT:
1253 open_session_selector->hide();
1257 open_session_selector->hide();
1258 string session_path = open_session_selector->get_filename();
1262 if (session_path.length() > 0) {
1263 if (ARDOUR::find_session (session_path, path, name, isnew) == 0) {
1264 _session_is_new = isnew;
1265 load_session (path, name);
1272 ARDOUR_UI::session_add_midi_route (bool disk, RouteGroup* route_group, uint32_t how_many)
1274 list<boost::shared_ptr<MidiTrack> > tracks;
1277 warning << _("You cannot add a track without a session already loaded.") << endmsg;
1284 tracks = session->new_midi_track (ARDOUR::Normal, route_group, how_many);
1286 if (tracks.size() != how_many) {
1287 if (how_many == 1) {
1288 error << _("could not create a new midi track") << endmsg;
1290 error << string_compose (_("could not create %1 new midi tracks"), how_many) << endmsg;
1294 if ((route = session->new_midi_route ()) == 0) {
1295 error << _("could not create new midi bus") << endmsg;
1301 MessageDialog msg (*editor,
1302 _("There are insufficient JACK ports available\n\
1303 to create a new track or bus.\n\
1304 You should save Ardour, exit and\n\
1305 restart JACK with more ports."));
1312 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)
1314 list<boost::shared_ptr<AudioTrack> > tracks;
1318 warning << _("You cannot add a track or bus without a session already loaded.") << endmsg;
1324 tracks = session->new_audio_track (input_channels, output_channels, mode, route_group, how_many);
1326 if (tracks.size() != how_many) {
1327 if (how_many == 1) {
1328 error << _("could not create a new audio track") << endmsg;
1330 error << string_compose (_("could only create %1 of %2 new audio %3"),
1331 tracks.size(), how_many, (track ? _("tracks") : _("busses"))) << endmsg;
1337 routes = session->new_audio_route (aux, input_channels, output_channels, route_group, how_many);
1339 if (routes.size() != how_many) {
1340 if (how_many == 1) {
1341 error << _("could not create a new audio track") << endmsg;
1343 error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
1349 if (need_control_room_outs) {
1355 route->set_stereo_control_outs (control_lr_channels);
1356 route->control_outs()->set_stereo_pan (pans, this);
1358 #endif /* CONTROLOUTS */
1362 MessageDialog msg (*editor,
1363 _("There are insufficient JACK ports available\n\
1364 to create a new track or bus.\n\
1365 You should save Ardour, exit and\n\
1366 restart JACK with more ports."));
1373 ARDOUR_UI::do_transport_locate (nframes_t new_position)
1375 nframes_t _preroll = 0;
1378 // XXX CONFIG_CHANGE FIX - requires AnyTime handling
1379 // _preroll = session->convert_to_frames_at (new_position, Config->get_preroll());
1381 if (new_position > _preroll) {
1382 new_position -= _preroll;
1387 session->request_locate (new_position);
1392 ARDOUR_UI::transport_goto_start ()
1395 session->goto_start();
1397 /* force displayed area in editor to start no matter
1398 what "follow playhead" setting is.
1402 editor->center_screen (session->current_start_frame ());
1408 ARDOUR_UI::transport_goto_zero ()
1411 session->request_locate (0);
1414 /* force displayed area in editor to start no matter
1415 what "follow playhead" setting is.
1419 editor->reset_x_origin (0);
1425 ARDOUR_UI::transport_goto_wallclock ()
1427 if (session && editor) {
1434 localtime_r (&now, &tmnow);
1436 frames = tmnow.tm_hour * (60 * 60 * session->frame_rate());
1437 frames += tmnow.tm_min * (60 * session->frame_rate());
1438 frames += tmnow.tm_sec * session->frame_rate();
1440 session->request_locate (frames);
1442 /* force displayed area in editor to start no matter
1443 what "follow playhead" setting is.
1447 editor->center_screen (frames);
1453 ARDOUR_UI::transport_goto_end ()
1456 nframes_t const frame = session->current_end_frame();
1457 session->request_locate (frame);
1459 /* force displayed area in editor to start no matter
1460 what "follow playhead" setting is.
1464 editor->center_screen (frame);
1470 ARDOUR_UI::transport_stop ()
1476 if (session->is_auditioning()) {
1477 session->cancel_audition ();
1481 session->request_stop ();
1485 ARDOUR_UI::transport_stop_and_forget_capture ()
1488 session->request_stop (true);
1493 ARDOUR_UI::remove_last_capture()
1496 editor->remove_last_capture();
1501 ARDOUR_UI::transport_record (bool roll)
1505 switch (session->record_status()) {
1506 case Session::Disabled:
1507 if (session->ntracks() == 0) {
1508 MessageDialog msg (*editor, _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu."));
1512 session->maybe_enable_record ();
1517 case Session::Recording:
1519 session->request_stop();
1521 session->disable_record (false, true);
1525 case Session::Enabled:
1526 session->disable_record (false, true);
1529 //cerr << "ARDOUR_UI::transport_record () called roll = " << roll << " session->record_status() = " << session->record_status() << endl;
1533 ARDOUR_UI::transport_roll ()
1539 if (session->is_auditioning()) {
1543 if (session->config.get_external_sync()) {
1544 switch (session->config.get_sync_source()) {
1548 /* transport controlled by the master */
1553 bool rolling = session->transport_rolling();
1555 if (session->get_play_loop()) {
1556 session->request_play_loop (false, true);
1557 } else if (session->get_play_range ()) {
1558 session->request_play_range (false, true);
1562 session->request_transport_speed (1.0f);
1565 map_transport_state ();
1569 ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode)
1576 if (session->is_auditioning()) {
1577 session->cancel_audition ();
1581 if (session->config.get_external_sync()) {
1582 switch (session->config.get_sync_source()) {
1586 /* transport controlled by the master */
1591 bool rolling = session->transport_rolling();
1592 bool affect_transport = true;
1594 if (rolling && roll_out_of_bounded_mode) {
1595 /* drop out of loop/range playback but leave transport rolling */
1596 if (session->get_play_loop()) {
1597 if (Config->get_seamless_loop()) {
1598 /* the disk buffers contain copies of the loop - we can't
1599 just keep playing, so stop the transport. the user
1600 can restart as they wish.
1602 affect_transport = true;
1604 /* disk buffers are normal, so we can keep playing */
1605 affect_transport = false;
1607 session->request_play_loop (false, true);
1608 } else if (session->get_play_range ()) {
1609 affect_transport = false;
1610 session->request_play_range (0, true);
1614 if (affect_transport) {
1616 session->request_stop (with_abort, true);
1618 session->request_transport_speed (1.0f);
1622 map_transport_state ();
1626 ARDOUR_UI::toggle_session_auto_loop ()
1629 if (session->get_play_loop()) {
1630 if (session->transport_rolling()) {
1631 Location * looploc = session->locations()->auto_loop_location();
1633 session->request_locate (looploc->start(), true);
1636 session->request_play_loop (false);
1639 Location * looploc = session->locations()->auto_loop_location();
1641 session->request_play_loop (true);
1648 ARDOUR_UI::transport_play_selection ()
1654 editor->play_selection ();
1658 ARDOUR_UI::transport_rewind (int option)
1660 float current_transport_speed;
1663 current_transport_speed = session->transport_speed();
1665 if (current_transport_speed >= 0.0f) {
1668 session->request_transport_speed (-1.0f);
1671 session->request_transport_speed (-4.0f);
1674 session->request_transport_speed (-0.5f);
1679 session->request_transport_speed (current_transport_speed * 1.5f);
1685 ARDOUR_UI::transport_forward (int option)
1687 float current_transport_speed;
1690 current_transport_speed = session->transport_speed();
1692 if (current_transport_speed <= 0.0f) {
1695 session->request_transport_speed (1.0f);
1698 session->request_transport_speed (4.0f);
1701 session->request_transport_speed (0.5f);
1706 session->request_transport_speed (current_transport_speed * 1.5f);
1713 ARDOUR_UI::toggle_record_enable (uint32_t dstream)
1719 boost::shared_ptr<Route> r;
1721 if ((r = session->route_by_remote_id (dstream)) != 0) {
1725 if ((t = dynamic_cast<Track*>(r.get())) != 0) {
1726 t->diskstream()->set_record_enabled (!t->diskstream()->record_enabled());
1735 ARDOUR_UI::map_transport_state ()
1737 ENSURE_GUI_THREAD(mem_fun (*this, &ARDOUR_UI::map_transport_state));
1740 auto_loop_button.set_visual_state (0);
1741 play_selection_button.set_visual_state (0);
1742 roll_button.set_visual_state (0);
1743 stop_button.set_visual_state (1);
1747 float sp = session->transport_speed();
1750 shuttle_fract = SHUTTLE_FRACT_SPEED1; /* speed = 1.0, believe it or not */
1751 shuttle_box.queue_draw ();
1752 } else if (sp == 0.0f) {
1754 shuttle_box.queue_draw ();
1755 update_disk_space ();
1760 if (session->get_play_range()) {
1762 play_selection_button.set_visual_state (1);
1763 roll_button.set_visual_state (0);
1764 auto_loop_button.set_visual_state (0);
1766 } else if (session->get_play_loop ()) {
1768 auto_loop_button.set_visual_state (1);
1769 play_selection_button.set_visual_state (0);
1770 roll_button.set_visual_state (0);
1774 roll_button.set_visual_state (1);
1775 play_selection_button.set_visual_state (0);
1776 auto_loop_button.set_visual_state (0);
1779 stop_button.set_visual_state (0);
1783 stop_button.set_visual_state (1);
1784 roll_button.set_visual_state (0);
1785 play_selection_button.set_visual_state (0);
1786 auto_loop_button.set_visual_state (0);
1792 ARDOUR_UI::engine_stopped ()
1794 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
1795 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1796 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1800 ARDOUR_UI::engine_running ()
1802 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
1803 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true);
1804 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
1806 Glib::RefPtr<Action> action;
1807 const char* action_name = 0;
1809 switch (engine->frames_per_cycle()) {
1811 action_name = X_("JACKLatency32");
1814 action_name = X_("JACKLatency64");
1817 action_name = X_("JACKLatency128");
1820 action_name = X_("JACKLatency512");
1823 action_name = X_("JACKLatency1024");
1826 action_name = X_("JACKLatency2048");
1829 action_name = X_("JACKLatency4096");
1832 action_name = X_("JACKLatency8192");
1835 /* XXX can we do anything useful ? */
1841 action = ActionManager::get_action (X_("JACK"), action_name);
1844 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic (action);
1845 ract->set_active ();
1851 ARDOUR_UI::engine_halted ()
1853 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
1855 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1856 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1858 update_sample_rate (0);
1860 MessageDialog msg (*editor,
1862 JACK has either been shutdown or it\n\
1863 disconnected Ardour because Ardour\n\
1864 was not fast enough. Try to restart\n\
1865 JACK, reconnect and save the session."));
1871 ARDOUR_UI::do_engine_start ()
1879 error << _("Unable to start the session running")
1889 ARDOUR_UI::setup_theme ()
1891 theme_manager->setup_theme();
1895 ARDOUR_UI::update_clocks ()
1897 if (!editor || !editor->dragging_playhead()) {
1898 Clock (session->audible_frame(), false, editor->get_preferred_edit_position()); /* EMIT_SIGNAL */
1903 ARDOUR_UI::start_clocking ()
1905 clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
1909 ARDOUR_UI::stop_clocking ()
1911 clock_signal_connection.disconnect ();
1915 ARDOUR_UI::toggle_clocking ()
1918 if (clock_button.get_active()) {
1927 ARDOUR_UI::_blink (void *arg)
1930 ((ARDOUR_UI *) arg)->blink ();
1937 Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
1941 ARDOUR_UI::start_blinking ()
1943 /* Start the blink signal. Everybody with a blinking widget
1944 uses Blink to drive the widget's state.
1947 if (blink_timeout_tag < 0) {
1949 blink_timeout_tag = g_timeout_add (240, _blink, this);
1954 ARDOUR_UI::stop_blinking ()
1956 if (blink_timeout_tag >= 0) {
1957 g_source_remove (blink_timeout_tag);
1958 blink_timeout_tag = -1;
1963 /** Ask the user for the name of a new shapshot and then take it.
1966 ARDOUR_UI::snapshot_session ()
1968 ArdourPrompter prompter (true);
1972 struct tm local_time;
1975 localtime_r (&n, &local_time);
1976 strftime (timebuf, sizeof(timebuf), "%FT%T", &local_time);
1978 prompter.set_name ("Prompter");
1979 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1980 prompter.set_title (_("Take Snapshot"));
1981 prompter.set_prompt (_("Name of New Snapshot"));
1982 prompter.set_initial_text (timebuf);
1984 switch (prompter.run()) {
1985 case RESPONSE_ACCEPT:
1987 prompter.get_result (snapname);
1989 bool do_save = (snapname.length() != 0);
1991 vector<sys::path> p;
1992 get_state_files_in_directory (session->session_directory().root_path(), p);
1993 vector<string> n = get_file_names_no_extension (p);
1994 if (find (n.begin(), n.end(), snapname) != n.end()) {
1996 ArdourDialog confirm (_("Confirm snapshot overwrite"), true);
1997 Label m (_("A snapshot already exists with that name. Do you want to overwrite it?"));
1998 confirm.get_vbox()->pack_start (m, true, true);
1999 confirm.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
2000 confirm.add_button (_("Overwrite"), Gtk::RESPONSE_ACCEPT);
2001 confirm.show_all ();
2002 switch (confirm.run()) {
2003 case RESPONSE_CANCEL:
2009 save_state (snapname);
2020 ARDOUR_UI::save_state (const string & name)
2022 (void) save_state_canfail (name);
2026 ARDOUR_UI::save_state_canfail (string name)
2031 if (name.length() == 0) {
2032 name = session->snap_name();
2035 if ((ret = session->save_state (name)) != 0) {
2039 save_ardour_state (); /* XXX cannot fail? yeah, right ... */
2044 ARDOUR_UI::primary_clock_value_changed ()
2047 session->request_locate (primary_clock.current_time ());
2052 ARDOUR_UI::big_clock_value_changed ()
2055 session->request_locate (big_clock.current_time ());
2060 ARDOUR_UI::secondary_clock_value_changed ()
2063 session->request_locate (secondary_clock.current_time ());
2068 ARDOUR_UI::transport_rec_enable_blink (bool onoff)
2074 Session::RecordState const r = session->record_status ();
2075 bool const h = session->have_rec_enabled_diskstream ();
2077 if (r == Session::Enabled || (r == Session::Recording && !h)) {
2079 rec_button.set_visual_state (2);
2081 rec_button.set_visual_state (0);
2083 } else if (r == Session::Recording && h) {
2084 rec_button.set_visual_state (1);
2086 rec_button.set_visual_state (0);
2091 ARDOUR_UI::save_template ()
2093 ArdourPrompter prompter (true);
2096 if (!check_audioengine()) {
2100 prompter.set_name (X_("Prompter"));
2101 prompter.set_title (_("Save Mix Template"));
2102 prompter.set_prompt (_("Name for mix template:"));
2103 prompter.set_initial_text(session->name() + _("-template"));
2104 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
2106 switch (prompter.run()) {
2107 case RESPONSE_ACCEPT:
2108 prompter.get_result (name);
2110 if (name.length()) {
2111 session->save_template (name);
2121 ARDOUR_UI::edit_metadata ()
2123 SessionMetadataEditor dialog;
2124 dialog.set_session (session);
2125 editor->ensure_float (dialog);
2130 ARDOUR_UI::import_metadata ()
2132 SessionMetadataImporter dialog;
2133 dialog.set_session (session);
2134 editor->ensure_float (dialog);
2139 ARDOUR_UI::fontconfig_dialog ()
2142 /* X11 users will always have fontconfig info around, but new GTK-OSX users
2143 may not and it can take a while to build it. Warn them.
2146 Glib::ustring fontconfig = Glib::build_filename (Glib::get_home_dir(), ".fontconfig");
2148 if (!Glib::file_test (fontconfig, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
2149 MessageDialog msg (*_startup,
2150 _("Welcome to Ardour.\n\n"
2151 "The program will take a bit longer to start up\n"
2152 "while the system fonts are checked.\n\n"
2153 "This will only be done once, and you will\n"
2154 "not see this message again\n"),
2167 ARDOUR_UI::parse_cmdline_path (const Glib::ustring& cmdline_path, Glib::ustring& session_name, Glib::ustring& session_path, bool& existing_session)
2169 existing_session = false;
2171 if (Glib::file_test (cmdline_path, Glib::FILE_TEST_IS_DIR)) {
2172 session_path = cmdline_path;
2173 existing_session = true;
2174 } else if (Glib::file_test (cmdline_path, Glib::FILE_TEST_IS_REGULAR)) {
2175 session_path = Glib::path_get_dirname (string (cmdline_path));
2176 existing_session = true;
2178 /* it doesn't exist, assume the best */
2179 session_path = Glib::path_get_dirname (string (cmdline_path));
2182 session_name = basename_nosuffix (string (cmdline_path));
2186 ARDOUR_UI::load_cmdline_session (const Glib::ustring& session_name, const Glib::ustring& session_path, bool& existing_session)
2188 /* when this is called, the backend audio system must be running */
2190 /* the main idea here is to deal with the fact that a cmdline argument for the session
2191 can be interpreted in different ways - it could be a directory or a file, and before
2192 we load, we need to know both the session directory and the snapshot (statefile) within it
2193 that we are supposed to use.
2196 if (session_name.length() == 0 || session_path.length() == 0) {
2200 if (Glib::file_test (session_path, Glib::FILE_TEST_IS_DIR)) {
2202 Glib::ustring predicted_session_file;
2204 predicted_session_file = session_path;
2205 predicted_session_file += '/';
2206 predicted_session_file += session_name;
2207 predicted_session_file += ARDOUR::statefile_suffix;
2209 if (Glib::file_test (predicted_session_file, Glib::FILE_TEST_EXISTS)) {
2210 existing_session = true;
2213 } else if (Glib::file_test (session_path, Glib::FILE_TEST_EXISTS)) {
2215 if (session_path.find (ARDOUR::statefile_suffix) == session_path.length() - 7) {
2216 /* existing .ardour file */
2217 existing_session = true;
2221 existing_session = false;
2224 /* lets just try to load it */
2226 if (create_engine ()) {
2227 backend_audio_error (false, _startup);
2231 return load_session (session_path, session_name);
2235 ARDOUR_UI::ask_about_loading_existing_session (const Glib::ustring& session_path)
2237 Glib::ustring str = string_compose (_("This session\n%1\nalready exists. Do you want to open it?"), session_path);
2239 MessageDialog msg (str,
2241 Gtk::MESSAGE_WARNING,
2242 Gtk::BUTTONS_YES_NO,
2246 msg.set_name (X_("OpenExistingDialog"));
2247 msg.set_title (_("Open Existing Session"));
2248 msg.set_wmclass (X_("existing_session"), "Ardour");
2249 msg.set_position (Gtk::WIN_POS_MOUSE);
2252 switch (msg.run()) {
2261 ARDOUR_UI::build_session_from_nsd (const Glib::ustring& session_path, const Glib::ustring& session_name)
2266 AutoConnectOption iconnect;
2267 AutoConnectOption oconnect;
2271 if (Profile->get_sae()) {
2275 iconnect = AutoConnectPhysical;
2276 oconnect = AutoConnectMaster;
2277 nphysin = 0; // use all available
2278 nphysout = 0; // use all available
2282 /* get settings from advanced section of NSD */
2284 if (_startup->create_control_bus()) {
2285 cchns = (uint32_t) _startup->control_channel_count();
2290 if (_startup->create_master_bus()) {
2291 mchns = (uint32_t) _startup->master_channel_count();
2296 if (_startup->connect_inputs()) {
2297 iconnect = AutoConnectPhysical;
2299 iconnect = AutoConnectOption (0);
2302 /// @todo some minor tweaks.
2304 oconnect = AutoConnectOption (0);
2306 if (_startup->connect_outputs ()) {
2307 if (_startup->connect_outs_to_master()) {
2308 oconnect = AutoConnectMaster;
2309 } else if (_startup->connect_outs_to_physical()) {
2310 oconnect = AutoConnectPhysical;
2314 nphysin = (uint32_t) _startup->input_limit_count();
2315 nphysout = (uint32_t) _startup->output_limit_count();
2318 if (build_session (session_path,
2326 engine->frame_rate() * 60 * 5)) {
2335 ARDOUR_UI::idle_load (const Glib::ustring& path)
2338 if (Glib::file_test (path, Glib::FILE_TEST_IS_DIR)) {
2339 /* /path/to/foo => /path/to/foo, foo */
2340 load_session (path, basename_nosuffix (path));
2342 /* /path/to/foo/foo.ardour => /path/to/foo, foo */
2343 load_session (Glib::path_get_dirname (path), basename_nosuffix (path));
2347 ARDOUR_COMMAND_LINE::session_name = path;
2350 * new_session_dialog doens't exist in A3
2351 * Try to remove all references to it to
2352 * see if it will compile. NOTE: this will
2353 * likely cause a runtime issue is my somewhat
2357 //if (new_session_dialog) {
2360 /* make it break out of Dialog::run() and
2364 //new_session_dialog->response (1);
2370 ARDOUR_UI::end_loading_messages ()
2376 ARDOUR_UI::loading_message (const std::string& /*msg*/)
2379 // splash->message (msg);
2383 /** @param quit_on_cancel true if exit() should be called if the user clicks `cancel' in the new session dialog */
2385 ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new)
2387 Glib::ustring session_name;
2388 Glib::ustring session_path;
2389 Glib::ustring template_name;
2391 bool likely_new = false;
2395 if (!should_be_new && !ARDOUR_COMMAND_LINE::session_name.empty()) {
2397 /* if they named a specific statefile, use it, otherwise they are
2398 just giving a session folder, and we want to use it as is
2399 to find the session.
2402 if (ARDOUR_COMMAND_LINE::session_name.find (statefile_suffix) != string::npos) {
2403 session_path = Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name);
2405 session_path = ARDOUR_COMMAND_LINE::session_name;
2408 session_name = Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name);
2412 bool const apply = run_startup (should_be_new);
2414 if (quit_on_cancel) {
2421 /* if we run the startup dialog again, offer more than just "new session" */
2423 should_be_new = false;
2425 session_name = _startup->session_name (likely_new);
2427 /* this shouldn't happen, but we catch it just in case it does */
2429 if (session_name.empty()) {
2432 if (_startup->use_session_template()) {
2433 template_name = _startup->session_template_name();
2434 _session_is_new = true;
2437 if (session_name[0] == '/' ||
2438 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
2439 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
2441 session_path = Glib::path_get_dirname (session_name);
2442 session_name = Glib::path_get_basename (session_name);
2446 session_path = _startup->session_folder();
2450 if (create_engine ()) {
2454 if (Glib::file_test (session_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
2458 Glib::ustring existing = Glib::build_filename (session_path, session_name);
2460 if (!ask_about_loading_existing_session (existing)) {
2461 ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
2466 _session_is_new = false;
2471 MessageDialog msg (string_compose (_("There is no existing session at \"%1\""), session_path));
2473 ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
2477 _session_is_new = true;
2480 if (likely_new && template_name.empty()) {
2482 ret = build_session_from_nsd (session_path, session_name);
2486 ret = load_session (session_path, session_name, template_name);
2487 if (!ARDOUR_COMMAND_LINE::immediate_save.empty()) {
2488 session->save_state (ARDOUR_COMMAND_LINE::immediate_save, false);
2498 ARDOUR_UI::close_session()
2500 if (!check_audioengine()) {
2504 unload_session (true);
2506 ARDOUR_COMMAND_LINE::session_name = "";
2507 get_session_parameters (true, false);
2511 ARDOUR_UI::load_session (const Glib::ustring& path, const Glib::ustring& snap_name, Glib::ustring mix_template)
2513 Session *new_session;
2517 session_loaded = false;
2519 if (!check_audioengine()) {
2523 unload_status = unload_session ();
2525 if (unload_status < 0) {
2527 } else if (unload_status > 0) {
2532 loading_message (_("Please wait while Ardour loads your session"));
2535 new_session = new Session (*engine, path, snap_name, mix_template);
2538 /* this one is special */
2540 catch (AudioEngine::PortRegistrationFailure& err) {
2542 MessageDialog msg (err.what(),
2545 Gtk::BUTTONS_CLOSE);
2547 msg.set_title (_("Port Registration Error"));
2548 msg.set_secondary_text (_("Click the Close button to try again."));
2549 msg.set_position (Gtk::WIN_POS_CENTER);
2553 int response = msg.run ();
2558 case RESPONSE_CANCEL:
2568 MessageDialog msg (string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name),
2571 Gtk::BUTTONS_CLOSE);
2573 msg.set_title (_("Loading Error"));
2574 msg.set_secondary_text (_("Click the Close button to try again."));
2575 msg.set_position (Gtk::WIN_POS_CENTER);
2579 int response = msg.run ();
2584 case RESPONSE_CANCEL:
2592 connect_to_session (new_session);
2594 session_loaded = true;
2596 goto_editor_window ();
2599 session->set_clean ();
2610 ARDOUR_UI::build_session (const Glib::ustring& path, const Glib::ustring& snap_name,
2611 uint32_t control_channels,
2612 uint32_t master_channels,
2613 AutoConnectOption input_connect,
2614 AutoConnectOption output_connect,
2617 nframes_t initial_length)
2619 Session *new_session;
2622 if (!check_audioengine()) {
2626 session_loaded = false;
2628 x = unload_session ();
2636 _session_is_new = true;
2639 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
2640 control_channels, master_channels, nphysin, nphysout, initial_length);
2645 MessageDialog msg (string_compose(_("Could not create session in \"%1\""), path));
2651 connect_to_session (new_session);
2653 session_loaded = true;
2655 new_session->save_state(new_session->name());
2664 editor->show_window ();
2675 ARDOUR_UI::show_about ()
2679 about->signal_response().connect(mem_fun (*this, &ARDOUR_UI::about_signal_response) );
2686 ARDOUR_UI::hide_about ()
2689 about->get_window()->set_cursor ();
2695 ARDOUR_UI::about_signal_response (int /*response*/)
2701 ARDOUR_UI::show_splash ()
2705 splash = new Splash;
2713 splash->queue_draw ();
2714 splash->get_window()->process_updates (true);
2719 ARDOUR_UI::hide_splash ()
2727 ARDOUR_UI::display_cleanup_results (ARDOUR::CleanupReport& rep, const gchar* list_title,
2728 const string& plural_msg, const string& singular_msg)
2732 removed = rep.paths.size();
2735 MessageDialog msgd (*editor,
2736 _("No audio files were ready for cleanup"),
2739 (Gtk::ButtonsType)(Gtk::BUTTONS_OK) );
2740 msgd.set_secondary_text (_("If this seems suprising, \n\
2741 check for any existing snapshots.\n\
2742 These may still include regions that\n\
2743 require some unused files to continue to exist."));
2749 ArdourDialog results (_("ardour: cleanup"), true, false);
2751 struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
2752 CleanupResultsModelColumns() {
2756 Gtk::TreeModelColumn<Glib::ustring> visible_name;
2757 Gtk::TreeModelColumn<Glib::ustring> fullpath;
2761 CleanupResultsModelColumns results_columns;
2762 Glib::RefPtr<Gtk::ListStore> results_model;
2763 Gtk::TreeView results_display;
2765 results_model = ListStore::create (results_columns);
2766 results_display.set_model (results_model);
2767 results_display.append_column (list_title, results_columns.visible_name);
2769 results_display.set_name ("CleanupResultsList");
2770 results_display.set_headers_visible (true);
2771 results_display.set_headers_clickable (false);
2772 results_display.set_reorderable (false);
2774 Gtk::ScrolledWindow list_scroller;
2777 Gtk::HBox dhbox; // the hbox for the image and text
2778 Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
2779 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO, Gtk::ICON_SIZE_DIALOG));
2781 dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
2783 const string dead_sound_directory = session->session_directory().dead_sound_path().to_string();
2789 %1 - number of files removed
2790 %2 - location of "dead_sounds"
2791 %3 - size of files affected
2792 %4 - prefix for "bytes" to produce sensible results (e.g. mega, kilo, giga)
2795 const char* bprefix;
2797 if (rep.space < 1048576.0f) {
2798 bprefix = X_("kilo");
2799 } else if (rep.space < 1048576.0f * 1000) {
2800 bprefix = X_("mega");
2802 bprefix = X_("giga");
2806 txt.set_text (string_compose (plural_msg, removed, dead_sound_directory, (float) rep.space / 1024.0f, bprefix));
2808 txt.set_text (string_compose (singular_msg, removed, dead_sound_directory, (float) rep.space / 1024.0f, bprefix));
2811 dhbox.pack_start (*dimage, true, false, 5);
2812 dhbox.pack_start (txt, true, false, 5);
2814 for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2815 TreeModel::Row row = *(results_model->append());
2816 row[results_columns.visible_name] = *i;
2817 row[results_columns.fullpath] = *i;
2820 list_scroller.add (results_display);
2821 list_scroller.set_size_request (-1, 150);
2822 list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2824 dvbox.pack_start (dhbox, true, false, 5);
2825 dvbox.pack_start (list_scroller, true, false, 5);
2826 ddhbox.pack_start (dvbox, true, false, 5);
2828 results.get_vbox()->pack_start (ddhbox, true, false, 5);
2829 results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
2830 results.set_default_response (RESPONSE_CLOSE);
2831 results.set_position (Gtk::WIN_POS_MOUSE);
2833 results_display.show();
2834 list_scroller.show();
2841 //results.get_vbox()->show();
2842 results.set_resizable (false);
2849 ARDOUR_UI::cleanup ()
2852 /* shouldn't happen: menu item is insensitive */
2857 MessageDialog checker (_("Are you sure you want to cleanup?"),
2859 Gtk::MESSAGE_QUESTION,
2860 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
2862 checker.set_secondary_text(_("Cleanup is a destructive operation.\n\
2863 ALL undo/redo information will be lost if you cleanup.\n\
2864 After cleanup, unused audio files will be moved to a \
2865 \"dead sounds\" location."));
2867 checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2868 checker.add_button (_("Clean Up"), RESPONSE_ACCEPT);
2869 checker.set_default_response (RESPONSE_CANCEL);
2871 checker.set_name (_("CleanupDialog"));
2872 checker.set_wmclass (X_("ardour_cleanup"), "Ardour");
2873 checker.set_position (Gtk::WIN_POS_MOUSE);
2875 switch (checker.run()) {
2876 case RESPONSE_ACCEPT:
2882 ARDOUR::CleanupReport rep;
2884 editor->prepare_for_cleanup ();
2886 /* do not allow flush until a session is reloaded */
2888 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
2890 act->set_sensitive (false);
2893 if (session->cleanup_sources (rep)) {
2894 editor->finish_cleanup ();
2898 editor->finish_cleanup ();
2901 display_cleanup_results (rep,
2904 The following %1 files were not in use and \n\
2905 have been moved to:\n\
2907 Flushing the wastebasket will \n\
2908 release an additional\n\
2909 %3 %4bytes of disk space.\n"),
2911 The following file was not in use and \n \
2912 has been moved to:\n \
2914 Flushing the wastebasket will \n\
2915 release an additional\n\
2916 %3 %4bytes of disk space.\n"
2922 ARDOUR_UI::flush_trash ()
2925 /* shouldn't happen: menu item is insensitive */
2929 ARDOUR::CleanupReport rep;
2931 if (session->cleanup_trash_sources (rep)) {
2935 display_cleanup_results (rep,
2937 _("The following %1 files were deleted from\n\
2939 releasing %3 %4bytes of disk space"),
2940 _("The following file was deleted from\n\
2942 releasing %3 %4bytes of disk space"));
2946 ARDOUR_UI::add_route (Gtk::Window* float_window)
2954 if (add_route_dialog == 0) {
2955 add_route_dialog = new AddRouteDialog (*session);
2957 add_route_dialog->set_transient_for (*float_window);
2961 if (add_route_dialog->is_visible()) {
2962 /* we're already doing this */
2966 ResponseType r = (ResponseType) add_route_dialog->run ();
2968 add_route_dialog->hide();
2971 case RESPONSE_ACCEPT:
2978 if ((count = add_route_dialog->count()) <= 0) {
2982 string template_path = add_route_dialog->track_template();
2984 if (!template_path.empty()) {
2985 session->new_route_from_template (count, template_path);
2989 uint32_t input_chan = add_route_dialog->channels ();
2990 uint32_t output_chan;
2991 string name_template = add_route_dialog->name_template ();
2992 bool track = add_route_dialog->track ();
2993 bool aux = !track && add_route_dialog->aux();
2994 RouteGroup* route_group = add_route_dialog->route_group ();
2996 AutoConnectOption oac = Config->get_output_auto_connect();
2998 if (oac & AutoConnectMaster) {
2999 output_chan = (session->master_out() ? session->master_out()->n_inputs().n_audio() : input_chan);
3001 output_chan = input_chan;
3004 /* XXX do something with name template */
3006 if (add_route_dialog->type() == ARDOUR::DataType::MIDI) {
3008 session_add_midi_track (route_group, count);
3010 MessageDialog msg (*editor,
3011 _("Sorry, MIDI Busses are not supported at this time."));
3013 //session_add_midi_bus();
3017 session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), route_group, count);
3019 session_add_audio_bus (aux, input_chan, output_chan, route_group, count);
3025 ARDOUR_UI::mixer_settings () const
3030 node = session->instant_xml(X_("Mixer"));
3032 node = Config->instant_xml(X_("Mixer"));
3036 node = new XMLNode (X_("Mixer"));
3043 ARDOUR_UI::editor_settings () const
3048 node = session->instant_xml(X_("Editor"));
3050 node = Config->instant_xml(X_("Editor"));
3054 if (getenv("ARDOUR_INSTANT_XML_PATH")) {
3055 node = Config->instant_xml(getenv("ARDOUR_INSTANT_XML_PATH"));
3060 node = new XMLNode (X_("Editor"));
3067 ARDOUR_UI::keyboard_settings () const
3071 node = Config->extra_xml(X_("Keyboard"));
3074 node = new XMLNode (X_("Keyboard"));
3080 ARDOUR_UI::create_xrun_marker(nframes_t where)
3082 editor->mouse_add_new_marker (where, false, true);
3086 ARDOUR_UI::halt_on_xrun_message ()
3088 MessageDialog msg (*editor,
3089 _("Recording was stopped because your system could not keep up."));
3094 ARDOUR_UI::xrun_handler(nframes_t where)
3100 ENSURE_GUI_THREAD (bind(mem_fun(*this, &ARDOUR_UI::xrun_handler), where));
3102 if (session && Config->get_create_xrun_marker() && session->actively_recording()) {
3103 create_xrun_marker(where);
3106 if (session && Config->get_stop_recording_on_xrun() && session->actively_recording()) {
3107 halt_on_xrun_message ();
3112 ARDOUR_UI::push_buffer_stats (uint32_t capture, uint32_t playback)
3117 while (disk_buffer_stats.size() > 60) {
3118 disk_buffer_stats.pop_front ();
3121 disk_buffer_stats.push_back (DiskBufferStat (now, capture, playback));
3125 ARDOUR_UI::write_buffer_stats ()
3131 char path[PATH_MAX+1]; int fd;
3133 strcpy (path, "ardourBufferingXXXXXX");
3135 if ((fd = mkstemp (path )) < 0) {
3136 cerr << X_("cannot find temporary name for ardour buffer stats") << endl;
3144 cerr << string_compose (X_("cannot open file %1 for ardour buffer stats"), path) << endl;
3148 for (list<DiskBufferStat>::iterator i = disk_buffer_stats.begin(); i != disk_buffer_stats.end(); ++i) {
3149 localtime_r (&(*i).when, &tm);
3150 strftime (buf, sizeof (buf), "%T", &tm);
3151 fout << buf << ' ' << (*i).capture << ' ' << (*i).playback << endl;
3154 disk_buffer_stats.clear ();
3158 cerr << "Ardour buffering statistics can be found in: " << path << endl;
3162 ARDOUR_UI::disk_overrun_handler ()
3164 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
3166 write_buffer_stats ();
3168 if (!have_disk_speed_dialog_displayed) {
3169 have_disk_speed_dialog_displayed = true;
3170 MessageDialog* msg = new MessageDialog (*editor, _("\
3171 The disk system on your computer\n\
3172 was not able to keep up with Ardour.\n\
3174 Specifically, it failed to write data to disk\n\
3175 quickly enough to keep up with recording.\n"));
3176 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
3182 ARDOUR_UI::disk_underrun_handler ()
3184 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
3186 write_buffer_stats ();
3188 if (!have_disk_speed_dialog_displayed) {
3189 have_disk_speed_dialog_displayed = true;
3190 MessageDialog* msg = new MessageDialog (*editor,
3191 _("The disk system on your computer\n\
3192 was not able to keep up with Ardour.\n\
3194 Specifically, it failed to read data from disk\n\
3195 quickly enough to keep up with playback.\n"));
3196 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
3202 ARDOUR_UI::disk_speed_dialog_gone (int /*ignored_response*/, MessageDialog* msg)
3204 have_disk_speed_dialog_displayed = false;
3209 ARDOUR_UI::session_dialog (std::string msg)
3211 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::session_dialog), msg));
3216 d = new MessageDialog (*editor, msg, false, MESSAGE_INFO, BUTTONS_OK, true);
3218 d = new MessageDialog (msg, false, MESSAGE_INFO, BUTTONS_OK, true);
3227 ARDOUR_UI::pending_state_dialog ()
3229 HBox* hbox = new HBox();
3230 Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG);
3231 ArdourDialog dialog (_("Crash Recovery"), true);
3233 This session appears to have been in\n\
3234 middle of recording when ardour or\n\
3235 the computer was shutdown.\n\
3237 Ardour can recover any captured audio for\n\
3238 you, or it can ignore it. Please decide\n\
3239 what you would like to do.\n"));
3240 image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
3241 hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
3242 hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
3243 dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
3244 dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
3245 dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
3246 dialog.set_default_response (RESPONSE_ACCEPT);
3247 dialog.set_position (WIN_POS_CENTER);
3252 switch (dialog.run ()) {
3253 case RESPONSE_ACCEPT:
3261 ARDOUR_UI::sr_mismatch_dialog (nframes_t desired, nframes_t actual)
3263 HBox* hbox = new HBox();
3264 Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG);
3265 ArdourDialog dialog (_("Sample Rate Mismatch"), true);
3266 Label message (string_compose (_("\
3267 This session was created with a sample rate of %1 Hz\n\
3269 The audioengine is currently running at %2 Hz\n"), desired, actual));
3271 image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
3272 hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
3273 hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
3274 dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
3275 dialog.add_button (_("Do not load session"), RESPONSE_REJECT);
3276 dialog.add_button (_("Load session anyway"), RESPONSE_ACCEPT);
3277 dialog.set_default_response (RESPONSE_ACCEPT);
3278 dialog.set_position (WIN_POS_CENTER);
3283 switch (dialog.run ()) {
3284 case RESPONSE_ACCEPT:
3293 ARDOUR_UI::disconnect_from_jack ()
3296 if( engine->disconnect_from_jack ()) {
3297 MessageDialog msg (*editor, _("Could not disconnect from JACK"));
3301 update_sample_rate (0);
3306 ARDOUR_UI::reconnect_to_jack ()
3309 if (engine->reconnect_to_jack ()) {
3310 MessageDialog msg (*editor, _("Could not reconnect to JACK"));
3314 update_sample_rate (0);
3319 ARDOUR_UI::use_config ()
3322 XMLNode* node = Config->extra_xml (X_("TransportControllables"));
3324 set_transport_controllable_state (*node);
3329 ARDOUR_UI::update_transport_clocks (nframes_t pos)
3331 if (Config->get_primary_clock_delta_edit_cursor()) {
3332 primary_clock.set (pos, false, editor->get_preferred_edit_position(), 1);
3334 primary_clock.set (pos, 0, true);
3337 if (Config->get_secondary_clock_delta_edit_cursor()) {
3338 secondary_clock.set (pos, false, editor->get_preferred_edit_position(), 2);
3340 secondary_clock.set (pos);
3343 if (big_clock_window) {
3344 big_clock.set (pos);
3349 ARDOUR_UI::record_state_changed ()
3351 ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::record_state_changed));
3353 if (!session || !big_clock_window) {
3354 /* why bother - the clock isn't visible */
3358 Session::RecordState const r = session->record_status ();
3359 bool const h = session->have_rec_enabled_diskstream ();
3361 if (r == Session::Recording && h) {
3362 big_clock.set_widget_name ("BigClockRecording");
3364 big_clock.set_widget_name ("BigClockNonRecording");
3369 ARDOUR_UI::first_idle ()
3372 session->allow_auto_play (true);
3376 editor->first_idle();
3379 Keyboard::set_can_save_keybindings (true);
3384 ARDOUR_UI::store_clock_modes ()
3386 XMLNode* node = new XMLNode(X_("ClockModes"));
3388 for (vector<AudioClock*>::iterator x = AudioClock::clocks.begin(); x != AudioClock::clocks.end(); ++x) {
3389 node->add_property ((*x)->name().c_str(), enum_2_string ((*x)->mode()));
3392 session->add_extra_xml (*node);
3393 session->set_dirty ();
3398 ARDOUR_UI::TransportControllable::TransportControllable (std::string name, ARDOUR_UI& u, ToggleType tp)
3399 : Controllable (name), ui (u), type(tp)
3405 ARDOUR_UI::TransportControllable::set_value (float val)
3407 if (type == ShuttleControl) {
3414 fract = -((0.5f - val)/0.5f);
3416 fract = ((val - 0.5f)/0.5f);
3420 ui.set_shuttle_fract (fract);
3425 /* do nothing: these are radio-style actions */
3429 const char *action = 0;
3433 action = X_("Roll");
3436 action = X_("Stop");
3439 action = X_("Goto Start");
3442 action = X_("Goto End");
3445 action = X_("Loop");
3448 action = X_("Play Selection");
3451 action = X_("Record");
3461 Glib::RefPtr<Action> act = ActionManager::get_action ("Transport", action);
3469 ARDOUR_UI::TransportControllable::get_value (void) const
3488 case ShuttleControl:
3498 ARDOUR_UI::TransportControllable::set_id (const string& str)
3504 ARDOUR_UI::setup_profile ()
3506 if (gdk_screen_width() < 1200) {
3507 Profile->set_small_screen ();
3511 if (getenv ("ARDOUR_SAE")) {
3512 Profile->set_sae ();
3513 Profile->set_single_package ();