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));
285 ARDOUR_UI::run_startup (bool should_be_new)
288 _startup = new ArdourStartup ();
291 _startup->set_new_only (should_be_new);
292 _startup->present ();
296 /* we don't return here until the startup assistant is finished */
302 ARDOUR_UI::create_engine ()
304 // this gets called every time by new_session()
310 loading_message (_("Starting audio engine"));
313 engine = new ARDOUR::AudioEngine (ARDOUR_COMMAND_LINE::jack_client_name);
320 engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
321 engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
322 engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
323 engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
331 ARDOUR_UI::post_engine ()
333 /* Things to be done once we create the AudioEngine
336 MIDI::Manager::instance()->set_api_data (engine->jack());
339 ARDOUR::init_post_engine ();
341 ActionManager::init ();
344 if (setup_windows ()) {
345 throw failed_constructor ();
348 check_memory_locking();
350 /* this is the first point at which all the keybindings are available */
352 if (ARDOUR_COMMAND_LINE::show_key_actions) {
353 vector<string> names;
354 vector<string> paths;
356 vector<AccelKey> bindings;
358 ActionManager::get_all_actions (names, paths, keys, bindings);
360 vector<string>::iterator n;
361 vector<string>::iterator k;
362 for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) {
363 cerr << "Action: " << (*n) << " bound to " << (*k) << endl;
369 blink_timeout_tag = -1;
371 /* this being a GUI and all, we want peakfiles */
373 AudioFileSource::set_build_peakfiles (true);
374 AudioFileSource::set_build_missing_peakfiles (true);
376 /* set default clock modes */
378 if (Profile->get_sae()) {
379 primary_clock.set_mode (AudioClock::BBT);
380 secondary_clock.set_mode (AudioClock::MinSec);
382 primary_clock.set_mode (AudioClock::SMPTE);
383 secondary_clock.set_mode (AudioClock::BBT);
386 /* start the time-of-day-clock */
389 /* OS X provides an always visible wallclock, so don't be stupid */
390 update_wall_clock ();
391 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
394 update_disk_space ();
396 update_sample_rate (engine->frame_rate());
398 /* now start and maybe save state */
400 if (do_engine_start () == 0) {
401 if (session && _session_is_new) {
402 /* we need to retain initial visual
403 settings for a new session
405 session->save_state ("");
410 ARDOUR_UI::~ARDOUR_UI ()
412 save_ardour_state ();
417 delete add_route_dialog;
421 ARDOUR_UI::pop_back_splash ()
423 if (Splash::instance()) {
424 // Splash::instance()->pop_back();
425 Splash::instance()->hide ();
430 ARDOUR_UI::configure_timeout ()
432 if (last_configure_time == 0) {
433 /* no configure events yet */
437 /* force a gap of 0.5 seconds since the last configure event
440 if (get_microseconds() - last_configure_time < 500000) {
443 have_configure_timeout = false;
444 save_ardour_state ();
450 ARDOUR_UI::configure_handler (GdkEventConfigure* /*conf*/)
452 if (have_configure_timeout) {
453 last_configure_time = get_microseconds();
455 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
456 have_configure_timeout = true;
463 ARDOUR_UI::set_transport_controllable_state (const XMLNode& node)
465 const XMLProperty* prop;
467 if ((prop = node.property ("roll")) != 0) {
468 roll_controllable->set_id (prop->value());
470 if ((prop = node.property ("stop")) != 0) {
471 stop_controllable->set_id (prop->value());
473 if ((prop = node.property ("goto-start")) != 0) {
474 goto_start_controllable->set_id (prop->value());
476 if ((prop = node.property ("goto-end")) != 0) {
477 goto_end_controllable->set_id (prop->value());
479 if ((prop = node.property ("auto-loop")) != 0) {
480 auto_loop_controllable->set_id (prop->value());
482 if ((prop = node.property ("play-selection")) != 0) {
483 play_selection_controllable->set_id (prop->value());
485 if ((prop = node.property ("rec")) != 0) {
486 rec_controllable->set_id (prop->value());
488 if ((prop = node.property ("shuttle")) != 0) {
489 shuttle_controllable->set_id (prop->value());
494 ARDOUR_UI::get_transport_controllable_state ()
496 XMLNode* node = new XMLNode(X_("TransportControllables"));
499 roll_controllable->id().print (buf, sizeof (buf));
500 node->add_property (X_("roll"), buf);
501 stop_controllable->id().print (buf, sizeof (buf));
502 node->add_property (X_("stop"), buf);
503 goto_start_controllable->id().print (buf, sizeof (buf));
504 node->add_property (X_("goto_start"), buf);
505 goto_end_controllable->id().print (buf, sizeof (buf));
506 node->add_property (X_("goto_end"), buf);
507 auto_loop_controllable->id().print (buf, sizeof (buf));
508 node->add_property (X_("auto_loop"), buf);
509 play_selection_controllable->id().print (buf, sizeof (buf));
510 node->add_property (X_("play_selection"), buf);
511 rec_controllable->id().print (buf, sizeof (buf));
512 node->add_property (X_("rec"), buf);
513 shuttle_controllable->id().print (buf, sizeof (buf));
514 node->add_property (X_("shuttle"), buf);
520 ARDOUR_UI::save_ardour_state ()
522 if (!keyboard || !mixer || !editor) {
526 /* XXX this is all a bit dubious. add_extra_xml() uses
527 a different lifetime model from add_instant_xml().
530 XMLNode* node = new XMLNode (keyboard->get_state());
531 Config->add_extra_xml (*node);
532 Config->add_extra_xml (get_transport_controllable_state());
533 if (_startup && _startup->engine_control() && _startup->engine_control()->was_used()) {
534 Config->add_extra_xml (_startup->engine_control()->get_state());
536 Config->save_state();
537 ui_config->save_state ();
539 XMLNode enode(static_cast<Stateful*>(editor)->get_state());
540 XMLNode mnode(mixer->get_state());
543 session->add_instant_xml (enode);
544 session->add_instant_xml (mnode);
546 Config->add_instant_xml (enode);
547 Config->add_instant_xml (mnode);
550 Keyboard::save_keybindings ();
554 ARDOUR_UI::autosave_session ()
556 if (g_main_depth() > 1) {
557 /* inside a recursive main loop,
558 give up because we may not be able to
564 if (!Config->get_periodic_safety_backups()) {
569 session->maybe_write_autosave();
576 ARDOUR_UI::update_autosave ()
578 ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::update_autosave));
580 if (session && session->dirty()) {
581 if (_autosave_connection.connected()) {
582 _autosave_connection.disconnect();
585 _autosave_connection = Glib::signal_timeout().connect (mem_fun (*this, &ARDOUR_UI::autosave_session),
586 Config->get_periodic_safety_backup_interval() * 1000);
589 if (_autosave_connection.connected()) {
590 _autosave_connection.disconnect();
596 ARDOUR_UI::backend_audio_error (bool we_set_params, Gtk::Window* toplevel)
600 title = _("Ardour could not start JACK");
602 title = _("Ardour could not connect to JACK.");
605 MessageDialog win (title,
611 win.set_secondary_text(_("There are several possible reasons:\n\
613 1) You requested audio parameters that are not supported..\n\
614 2) JACK is running as another user.\n\
616 Please consider the possibilities, and perhaps try different parameters."));
618 win.set_secondary_text(_("There are several possible reasons:\n\
620 1) JACK is not running.\n\
621 2) JACK is running as another user, perhaps root.\n\
622 3) There is already another client called \"ardour\".\n\
624 Please consider the possibilities, and perhaps (re)start JACK."));
628 win.set_transient_for (*toplevel);
632 win.add_button (Stock::OK, RESPONSE_CLOSE);
634 win.add_button (Stock::QUIT, RESPONSE_CLOSE);
637 win.set_default_response (RESPONSE_CLOSE);
640 win.set_position (Gtk::WIN_POS_CENTER);
643 /* we just don't care about the result, but we want to block */
649 ARDOUR_UI::startup ()
651 XMLNode* audio_setup = Config->extra_xml ("AudioSetup");
653 if (audio_setup && _startup && _startup->engine_control()) {
654 _startup->engine_control()->set_state (*audio_setup);
657 if (get_session_parameters (ARDOUR_COMMAND_LINE::new_session)) {
663 goto_editor_window ();
665 BootMessage (_("Ardour is ready for use"));
670 ARDOUR_UI::no_memory_warning ()
672 XMLNode node (X_("no-memory-warning"));
673 Config->add_instant_xml (node);
677 ARDOUR_UI::check_memory_locking ()
680 /* OS X doesn't support mlockall(2), and so testing for memory locking capability there is pointless */
684 XMLNode* memory_warning_node = Config->instant_xml (X_("no-memory-warning"));
686 if (engine->is_realtime() && memory_warning_node == 0) {
688 struct rlimit limits;
690 long pages, page_size;
692 if ((page_size = sysconf (_SC_PAGESIZE)) < 0 ||(pages = sysconf (_SC_PHYS_PAGES)) < 0) {
695 ram = (int64_t) pages * (int64_t) page_size;
698 if (getrlimit (RLIMIT_MEMLOCK, &limits)) {
702 if (limits.rlim_cur != RLIM_INFINITY) {
704 if (ram == 0 || ((double) limits.rlim_cur / ram) < 0.75) {
707 MessageDialog msg (_("WARNING: Your system has a limit for maximum amount of locked memory. "
708 "This might cause Ardour to run out of memory before your system "
709 "runs out of memory. \n\n"
710 "You can view the memory limit with 'ulimit -l', "
711 "and it is normally controlled by /etc/security/limits.conf"));
713 VBox* vbox = msg.get_vbox();
715 CheckButton cb (_("Do not show this window again"));
717 cb.signal_toggled().connect (mem_fun (*this, &ARDOUR_UI::no_memory_warning));
719 hbox.pack_start (cb, true, false);
720 vbox->pack_start (hbox);
727 editor->ensure_float (msg);
741 if (session->transport_rolling()) {
742 session->request_stop ();
746 if (session->dirty()) {
747 switch (ask_about_saving_session(_("quit"))) {
752 /* use the default name */
753 if (save_state_canfail ("")) {
754 /* failed - don't quit */
755 MessageDialog msg (*editor,
757 Ardour was unable to save your session.\n\n\
758 If you still wish to quit, please use the\n\n\
759 \"Just quit\" option."));
770 session->set_deletion_in_progress ();
773 ArdourDialog::close_all_dialogs ();
775 save_ardour_state ();
780 ARDOUR_UI::ask_about_saving_session (const string & what)
782 ArdourDialog window (_("ardour: save session?"));
783 Gtk::HBox dhbox; // the hbox for the image and text
784 Gtk::Label prompt_label;
785 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_WARNING, Gtk::ICON_SIZE_DIALOG));
789 msg = string_compose(_("Don't %1"), what);
790 window.add_button (msg, RESPONSE_REJECT);
791 msg = string_compose(_("Just %1"), what);
792 window.add_button (msg, RESPONSE_APPLY);
793 msg = string_compose(_("Save and %1"), what);
794 window.add_button (msg, RESPONSE_ACCEPT);
796 window.set_default_response (RESPONSE_ACCEPT);
798 Gtk::Button noquit_button (msg);
799 noquit_button.set_name ("EditorGTKButton");
804 if (session->snap_name() == session->name()) {
807 type = _("snapshot");
809 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?"),
810 type, session->snap_name());
812 prompt_label.set_text (prompt);
813 prompt_label.set_name (X_("PrompterLabel"));
814 prompt_label.set_alignment(ALIGN_LEFT, ALIGN_TOP);
816 dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP);
817 dhbox.set_homogeneous (false);
818 dhbox.pack_start (*dimage, false, false, 5);
819 dhbox.pack_start (prompt_label, true, false, 5);
820 window.get_vbox()->pack_start (dhbox);
822 window.set_name (_("Prompter"));
823 window.set_position (Gtk::WIN_POS_MOUSE);
824 window.set_modal (true);
825 window.set_resizable (false);
831 window.set_keep_above (true);
834 ResponseType r = (ResponseType) window.run();
839 case RESPONSE_ACCEPT: // save and get out of here
841 case RESPONSE_APPLY: // get out of here
851 ARDOUR_UI::every_second ()
854 update_buffer_load ();
855 update_disk_space ();
860 ARDOUR_UI::every_point_one_seconds ()
862 update_speed_display ();
863 RapidScreenUpdate(); /* EMIT_SIGNAL */
868 ARDOUR_UI::every_point_zero_one_seconds ()
870 // august 2007: actual update frequency: 40Hz, not 100Hz
872 SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
877 ARDOUR_UI::update_sample_rate (nframes_t ignored)
881 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
883 if (!engine->connected()) {
885 snprintf (buf, sizeof (buf), _("disconnected"));
889 nframes_t rate = engine->frame_rate();
891 if (fmod (rate, 1000.0) != 0.0) {
892 snprintf (buf, sizeof (buf), _("%.1f kHz / %4.1f ms"),
893 (float) rate/1000.0f,
894 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
896 snprintf (buf, sizeof (buf), _("%u kHz / %4.1f ms"),
898 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
902 sample_rate_label.set_text (buf);
906 ARDOUR_UI::update_cpu_load ()
909 snprintf (buf, sizeof (buf), _("DSP: %5.1f%%"), engine->get_cpu_load());
910 cpu_load_label.set_text (buf);
914 ARDOUR_UI::update_buffer_load ()
920 c = session->capture_load ();
921 p = session->playback_load ();
923 push_buffer_stats (c, p);
925 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"),
926 session->playback_load(), session->capture_load());
927 buffer_load_label.set_text (buf);
929 buffer_load_label.set_text ("");
934 ARDOUR_UI::count_recenabled_streams (Route& route)
936 Track* track = dynamic_cast<Track*>(&route);
937 if (track && track->diskstream()->record_enabled()) {
938 rec_enabled_streams += track->n_inputs().n_total();
943 ARDOUR_UI::update_disk_space()
949 nframes_t frames = session->available_capture_duration();
951 nframes_t fr = session->frame_rate();
953 if (frames == max_frames) {
954 strcpy (buf, _("Disk: 24hrs+"));
956 rec_enabled_streams = 0;
957 session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
959 if (rec_enabled_streams) {
960 frames /= rec_enabled_streams;
967 hrs = frames / (fr * 3600);
968 frames -= hrs * fr * 3600;
969 mins = frames / (fr * 60);
970 frames -= mins * fr * 60;
973 snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs);
976 disk_space_label.set_text (buf);
978 // An attempt to make the disk space label flash red when space has run out.
980 if (frames < fr * 60 * 5) {
981 /* disk_space_box.style ("disk_space_label_empty"); */
983 /* disk_space_box.style ("disk_space_label"); */
989 ARDOUR_UI::update_wall_clock ()
996 tm_now = localtime (&now);
998 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
999 wall_clock_label.set_text (buf);
1005 ARDOUR_UI::session_menu (GdkEventButton */*ev*/)
1007 session_popup_menu->popup (0, 0);
1012 ARDOUR_UI::redisplay_recent_sessions ()
1014 std::vector<sys::path> session_directories;
1015 RecentSessionsSorter cmp;
1017 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
1018 recent_session_model->clear ();
1020 ARDOUR::RecentSessions rs;
1021 ARDOUR::read_recent_sessions (rs);
1024 recent_session_display.set_model (recent_session_model);
1028 // sort them alphabetically
1029 sort (rs.begin(), rs.end(), cmp);
1031 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
1032 session_directories.push_back ((*i).second);
1035 for (vector<sys::path>::const_iterator i = session_directories.begin();
1036 i != session_directories.end(); ++i)
1038 std::vector<sys::path> state_file_paths;
1040 // now get available states for this session
1042 get_state_files_in_directory (*i, state_file_paths);
1044 vector<string*>* states;
1045 vector<const gchar*> item;
1046 string fullpath = (*i).to_string();
1048 /* remove any trailing / */
1050 if (fullpath[fullpath.length()-1] == '/') {
1051 fullpath = fullpath.substr (0, fullpath.length()-1);
1054 /* check whether session still exists */
1055 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
1056 /* session doesn't exist */
1057 cerr << "skipping non-existent session " << fullpath << endl;
1061 /* now get available states for this session */
1063 if ((states = Session::possible_states (fullpath)) == 0) {
1064 /* no state file? */
1068 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
1070 Gtk::TreeModel::Row row = *(recent_session_model->append());
1072 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
1073 row[recent_session_columns.fullpath] = fullpath;
1075 if (state_file_names.size() > 1) {
1079 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
1080 i2 != state_file_names.end(); ++i2)
1083 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
1085 child_row[recent_session_columns.visible_name] = *i2;
1086 child_row[recent_session_columns.fullpath] = fullpath;
1091 recent_session_display.set_model (recent_session_model);
1095 ARDOUR_UI::build_session_selector ()
1097 session_selector_window = new ArdourDialog (_("Recent Sessions"));
1099 Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
1101 session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
1102 session_selector_window->add_button (Stock::OPEN, RESPONSE_ACCEPT);
1103 session_selector_window->set_default_response (RESPONSE_ACCEPT);
1104 recent_session_model = TreeStore::create (recent_session_columns);
1105 recent_session_display.set_model (recent_session_model);
1106 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1107 recent_session_display.set_headers_visible (false);
1108 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
1109 recent_session_display.signal_row_activated().connect (mem_fun (*this, &ARDOUR_UI::recent_session_row_activated));
1111 scroller->add (recent_session_display);
1112 scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1114 session_selector_window->set_name ("SessionSelectorWindow");
1115 session_selector_window->set_size_request (200, 400);
1116 session_selector_window->get_vbox()->pack_start (*scroller);
1118 recent_session_display.show();
1120 //session_selector_window->get_vbox()->show();
1124 ARDOUR_UI::recent_session_row_activated (const TreePath& /*path*/, TreeViewColumn* /*col*/)
1126 session_selector_window->response (RESPONSE_ACCEPT);
1130 ARDOUR_UI::open_recent_session ()
1132 bool can_return = (session != 0);
1134 if (session_selector_window == 0) {
1135 build_session_selector ();
1138 redisplay_recent_sessions ();
1142 session_selector_window->set_position (WIN_POS_MOUSE);
1144 ResponseType r = (ResponseType) session_selector_window->run ();
1147 case RESPONSE_ACCEPT:
1151 session_selector_window->hide();
1158 if (recent_session_display.get_selection()->count_selected_rows() == 0) {
1162 session_selector_window->hide();
1164 Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
1166 if (i == recent_session_model->children().end()) {
1170 Glib::ustring path = (*i)[recent_session_columns.fullpath];
1171 Glib::ustring state = (*i)[recent_session_columns.visible_name];
1173 _session_is_new = false;
1175 if (load_session (path, state) == 0) {
1184 ARDOUR_UI::check_audioengine ()
1187 if (!engine->connected()) {
1188 MessageDialog msg (_("Ardour is not connected to JACK\n"
1189 "You cannot open or close sessions in this condition"));
1201 ARDOUR_UI::open_session ()
1203 if (!check_audioengine()) {
1208 /* popup selector window */
1210 if (open_session_selector == 0) {
1212 /* ardour sessions are folders */
1214 open_session_selector = new Gtk::FileChooserDialog (_("open session"), FILE_CHOOSER_ACTION_OPEN);
1215 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1216 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
1217 open_session_selector->set_default_response(Gtk::RESPONSE_ACCEPT);
1219 FileFilter session_filter;
1220 session_filter.add_pattern ("*.ardour");
1221 session_filter.set_name (_("Ardour sessions"));
1222 open_session_selector->add_filter (session_filter);
1223 open_session_selector->set_filter (session_filter);
1226 int response = open_session_selector->run();
1227 open_session_selector->hide ();
1230 case RESPONSE_ACCEPT:
1233 open_session_selector->hide();
1237 open_session_selector->hide();
1238 string session_path = open_session_selector->get_filename();
1242 if (session_path.length() > 0) {
1243 if (ARDOUR::find_session (session_path, path, name, isnew) == 0) {
1244 _session_is_new = isnew;
1245 load_session (path, name);
1252 ARDOUR_UI::session_add_midi_route (bool disk, RouteGroup* route_group, uint32_t how_many)
1254 list<boost::shared_ptr<MidiTrack> > tracks;
1257 warning << _("You cannot add a track without a session already loaded.") << endmsg;
1264 tracks = session->new_midi_track (ARDOUR::Normal, route_group, how_many);
1266 if (tracks.size() != how_many) {
1267 if (how_many == 1) {
1268 error << _("could not create a new midi track") << endmsg;
1270 error << string_compose (_("could not create %1 new midi tracks"), how_many) << endmsg;
1274 if ((route = session->new_midi_route ()) == 0) {
1275 error << _("could not create new midi bus") << endmsg;
1281 MessageDialog msg (*editor,
1282 _("There are insufficient JACK ports available\n\
1283 to create a new track or bus.\n\
1284 You should save Ardour, exit and\n\
1285 restart JACK with more ports."));
1292 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)
1294 list<boost::shared_ptr<AudioTrack> > tracks;
1298 warning << _("You cannot add a track or bus without a session already loaded.") << endmsg;
1304 tracks = session->new_audio_track (input_channels, output_channels, mode, route_group, how_many);
1306 if (tracks.size() != how_many) {
1307 if (how_many == 1) {
1308 error << _("could not create a new audio track") << endmsg;
1310 error << string_compose (_("could only create %1 of %2 new audio %3"),
1311 tracks.size(), how_many, (track ? _("tracks") : _("busses"))) << endmsg;
1317 routes = session->new_audio_route (input_channels, output_channels, route_group, how_many);
1319 if (routes.size() != how_many) {
1320 if (how_many == 1) {
1321 error << _("could not create a new audio track") << endmsg;
1323 error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
1329 if (need_control_room_outs) {
1335 route->set_stereo_control_outs (control_lr_channels);
1336 route->control_outs()->set_stereo_pan (pans, this);
1338 #endif /* CONTROLOUTS */
1342 MessageDialog msg (*editor,
1343 _("There are insufficient JACK ports available\n\
1344 to create a new track or bus.\n\
1345 You should save Ardour, exit and\n\
1346 restart JACK with more ports."));
1353 ARDOUR_UI::do_transport_locate (nframes_t new_position)
1355 nframes_t _preroll = 0;
1358 // XXX CONFIG_CHANGE FIX - requires AnyTime handling
1359 // _preroll = session->convert_to_frames_at (new_position, Config->get_preroll());
1361 if (new_position > _preroll) {
1362 new_position -= _preroll;
1367 session->request_locate (new_position);
1372 ARDOUR_UI::transport_goto_start ()
1375 session->goto_start();
1378 /* force displayed area in editor to start no matter
1379 what "follow playhead" setting is.
1383 editor->reset_x_origin (session->current_start_frame());
1389 ARDOUR_UI::transport_goto_zero ()
1392 session->request_locate (0);
1395 /* force displayed area in editor to start no matter
1396 what "follow playhead" setting is.
1400 editor->reset_x_origin (0);
1406 ARDOUR_UI::transport_goto_wallclock ()
1408 if (session && editor) {
1415 localtime_r (&now, &tmnow);
1417 frames = tmnow.tm_hour * (60 * 60 * session->frame_rate());
1418 frames += tmnow.tm_min * (60 * session->frame_rate());
1419 frames += tmnow.tm_sec * session->frame_rate();
1421 session->request_locate (frames);
1423 /* force displayed area in editor to start no matter
1424 what "follow playhead" setting is.
1428 editor->reset_x_origin (frames - (editor->current_page_frames()/2));
1434 ARDOUR_UI::transport_goto_end ()
1437 nframes_t frame = session->current_end_frame();
1438 session->request_locate (frame);
1440 /* force displayed area in editor to start no matter
1441 what "follow playhead" setting is.
1445 editor->reset_x_origin (frame);
1451 ARDOUR_UI::transport_stop ()
1457 if (session->is_auditioning()) {
1458 session->cancel_audition ();
1462 if (session->get_play_loop ()) {
1463 session->request_play_loop (false);
1466 session->request_stop ();
1470 ARDOUR_UI::transport_stop_and_forget_capture ()
1473 session->request_stop (true);
1478 ARDOUR_UI::remove_last_capture()
1481 editor->remove_last_capture();
1486 ARDOUR_UI::transport_record (bool roll)
1490 switch (session->record_status()) {
1491 case Session::Disabled:
1492 if (session->ntracks() == 0) {
1493 MessageDialog msg (*editor, _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu."));
1497 session->maybe_enable_record ();
1502 case Session::Recording:
1504 session->request_stop();
1506 session->disable_record (false, true);
1510 case Session::Enabled:
1511 session->disable_record (false, true);
1514 //cerr << "ARDOUR_UI::transport_record () called roll = " << roll << " session->record_status() = " << session->record_status() << endl;
1518 ARDOUR_UI::transport_roll ()
1526 rolling = session->transport_rolling ();
1528 //cerr << "ARDOUR_UI::transport_roll () called session->record_status() = " << session->record_status() << endl;
1530 if (session->get_play_loop()) {
1531 session->request_play_loop (false);
1532 auto_loop_button.set_visual_state (1);
1533 roll_button.set_visual_state (1);
1534 } else if (session->get_play_range ()) {
1535 session->request_play_range (false);
1536 play_selection_button.set_visual_state (0);
1537 } else if (rolling) {
1538 session->request_locate (session->last_transport_start(), true);
1541 session->request_transport_speed (1.0f);
1545 ARDOUR_UI::transport_loop()
1548 if (session->get_play_loop()) {
1549 if (session->transport_rolling()) {
1550 Location * looploc = session->locations()->auto_loop_location();
1552 session->request_locate (looploc->start(), true);
1557 session->request_play_loop (true);
1563 ARDOUR_UI::transport_play_selection ()
1569 if (!session->get_play_range()) {
1570 session->request_stop ();
1573 editor->play_selection ();
1577 ARDOUR_UI::transport_rewind (int option)
1579 float current_transport_speed;
1582 current_transport_speed = session->transport_speed();
1584 if (current_transport_speed >= 0.0f) {
1587 session->request_transport_speed (-1.0f);
1590 session->request_transport_speed (-4.0f);
1593 session->request_transport_speed (-0.5f);
1598 session->request_transport_speed (current_transport_speed * 1.5f);
1604 ARDOUR_UI::transport_forward (int option)
1606 float current_transport_speed;
1609 current_transport_speed = session->transport_speed();
1611 if (current_transport_speed <= 0.0f) {
1614 session->request_transport_speed (1.0f);
1617 session->request_transport_speed (4.0f);
1620 session->request_transport_speed (0.5f);
1625 session->request_transport_speed (current_transport_speed * 1.5f);
1631 ARDOUR_UI::toggle_record_enable (uint32_t dstream)
1637 boost::shared_ptr<Route> r;
1639 if ((r = session->route_by_remote_id (dstream)) != 0) {
1643 if ((t = dynamic_cast<Track*>(r.get())) != 0) {
1644 t->diskstream()->set_record_enabled (!t->diskstream()->record_enabled());
1653 ARDOUR_UI::queue_transport_change ()
1655 Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
1659 ARDOUR_UI::map_transport_state ()
1661 float sp = session->transport_speed();
1664 transport_rolling ();
1665 } else if (sp < 0.0f) {
1666 transport_rewinding ();
1667 } else if (sp > 0.0f) {
1668 transport_forwarding ();
1670 transport_stopped ();
1675 ARDOUR_UI::engine_stopped ()
1677 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
1678 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1679 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1683 ARDOUR_UI::engine_running ()
1685 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
1686 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true);
1687 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
1689 Glib::RefPtr<Action> action;
1690 const char* action_name = 0;
1692 switch (engine->frames_per_cycle()) {
1694 action_name = X_("JACKLatency32");
1697 action_name = X_("JACKLatency64");
1700 action_name = X_("JACKLatency128");
1703 action_name = X_("JACKLatency512");
1706 action_name = X_("JACKLatency1024");
1709 action_name = X_("JACKLatency2048");
1712 action_name = X_("JACKLatency4096");
1715 action_name = X_("JACKLatency8192");
1718 /* XXX can we do anything useful ? */
1724 action = ActionManager::get_action (X_("JACK"), action_name);
1727 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic (action);
1728 ract->set_active ();
1734 ARDOUR_UI::engine_halted ()
1736 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
1738 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1739 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1741 update_sample_rate (0);
1743 MessageDialog msg (*editor,
1745 JACK has either been shutdown or it\n\
1746 disconnected Ardour because Ardour\n\
1747 was not fast enough. Try to restart\n\
1748 JACK, reconnect and save the session."));
1754 ARDOUR_UI::do_engine_start ()
1762 error << _("Unable to start the session running")
1772 ARDOUR_UI::setup_theme ()
1774 theme_manager->setup_theme();
1778 ARDOUR_UI::update_clocks ()
1780 if (!editor || !editor->dragging_playhead()) {
1781 Clock (session->audible_frame(), false, editor->get_preferred_edit_position()); /* EMIT_SIGNAL */
1786 ARDOUR_UI::start_clocking ()
1788 clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
1792 ARDOUR_UI::stop_clocking ()
1794 clock_signal_connection.disconnect ();
1798 ARDOUR_UI::toggle_clocking ()
1801 if (clock_button.get_active()) {
1810 ARDOUR_UI::_blink (void *arg)
1813 ((ARDOUR_UI *) arg)->blink ();
1820 Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
1824 ARDOUR_UI::start_blinking ()
1826 /* Start the blink signal. Everybody with a blinking widget
1827 uses Blink to drive the widget's state.
1830 if (blink_timeout_tag < 0) {
1832 blink_timeout_tag = g_timeout_add (240, _blink, this);
1837 ARDOUR_UI::stop_blinking ()
1839 if (blink_timeout_tag >= 0) {
1840 g_source_remove (blink_timeout_tag);
1841 blink_timeout_tag = -1;
1846 /** Ask the user for the name of a new shapshot and then take it.
1849 ARDOUR_UI::snapshot_session ()
1851 ArdourPrompter prompter (true);
1855 struct tm local_time;
1858 localtime_r (&n, &local_time);
1859 strftime (timebuf, sizeof(timebuf), "%FT%T", &local_time);
1861 prompter.set_name ("Prompter");
1862 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1863 prompter.set_prompt (_("Name of New Snapshot"));
1864 prompter.set_initial_text (timebuf);
1866 switch (prompter.run()) {
1867 case RESPONSE_ACCEPT:
1869 prompter.get_result (snapname);
1871 bool do_save = (snapname.length() != 0);
1873 vector<sys::path> p;
1874 get_state_files_in_directory (session->session_directory().root_path(), p);
1875 vector<string> n = get_file_names_no_extension (p);
1876 if (find (n.begin(), n.end(), snapname) != n.end()) {
1878 ArdourDialog confirm (_("Confirm snapshot overwrite"), true);
1879 Label m (_("A snapshot already exists with that name. Do you want to overwrite it?"));
1880 confirm.get_vbox()->pack_start (m, true, true);
1881 confirm.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1882 confirm.add_button (_("Overwrite"), Gtk::RESPONSE_ACCEPT);
1883 confirm.show_all ();
1884 switch (confirm.run()) {
1885 case RESPONSE_CANCEL:
1891 save_state (snapname);
1902 ARDOUR_UI::save_state (const string & name)
1904 (void) save_state_canfail (name);
1908 ARDOUR_UI::save_state_canfail (string name)
1913 if (name.length() == 0) {
1914 name = session->snap_name();
1917 if ((ret = session->save_state (name)) != 0) {
1921 save_ardour_state (); /* XXX cannot fail? yeah, right ... */
1926 ARDOUR_UI::primary_clock_value_changed ()
1929 session->request_locate (primary_clock.current_time ());
1934 ARDOUR_UI::big_clock_value_changed ()
1937 session->request_locate (big_clock.current_time ());
1942 ARDOUR_UI::secondary_clock_value_changed ()
1945 session->request_locate (secondary_clock.current_time ());
1950 ARDOUR_UI::transport_rec_enable_blink (bool onoff)
1956 Session::RecordState const r = session->record_status ();
1957 bool const h = session->have_rec_enabled_diskstream ();
1959 if (r == Session::Enabled || (r == Session::Recording && !h)) {
1961 rec_button.set_visual_state (2);
1963 rec_button.set_visual_state (0);
1965 } else if (r == Session::Recording && h) {
1966 rec_button.set_visual_state (1);
1968 rec_button.set_visual_state (0);
1973 ARDOUR_UI::save_template ()
1976 ArdourPrompter prompter (true);
1979 if (!check_audioengine()) {
1983 prompter.set_name (X_("Prompter"));
1984 prompter.set_prompt (_("Name for mix template:"));
1985 prompter.set_initial_text(session->name() + _("-template"));
1986 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1988 switch (prompter.run()) {
1989 case RESPONSE_ACCEPT:
1990 prompter.get_result (name);
1992 if (name.length()) {
1993 session->save_template (name);
2003 ARDOUR_UI::edit_metadata ()
2005 SessionMetadataEditor dialog;
2006 dialog.set_session (session);
2007 editor->ensure_float (dialog);
2012 ARDOUR_UI::import_metadata ()
2014 SessionMetadataImporter dialog;
2015 dialog.set_session (session);
2016 editor->ensure_float (dialog);
2021 ARDOUR_UI::fontconfig_dialog ()
2024 /* X11 users will always have fontconfig info around, but new GTK-OSX users
2025 may not and it can take a while to build it. Warn them.
2028 Glib::ustring fontconfig = Glib::build_filename (Glib::get_home_dir(), ".fontconfig");
2030 if (!Glib::file_test (fontconfig, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
2031 MessageDialog msg (*_startup,
2032 _("Welcome to Ardour.\n\n"
2033 "The program will take a bit longer to start up\n"
2034 "while the system fonts are checked.\n\n"
2035 "This will only be done once, and you will\n"
2036 "not see this message again\n"),
2049 ARDOUR_UI::parse_cmdline_path (const Glib::ustring& cmdline_path, Glib::ustring& session_name, Glib::ustring& session_path, bool& existing_session)
2051 existing_session = false;
2053 if (Glib::file_test (cmdline_path, Glib::FILE_TEST_IS_DIR)) {
2054 session_path = cmdline_path;
2055 existing_session = true;
2056 } else if (Glib::file_test (cmdline_path, Glib::FILE_TEST_IS_REGULAR)) {
2057 session_path = Glib::path_get_dirname (string (cmdline_path));
2058 existing_session = true;
2060 /* it doesn't exist, assume the best */
2061 session_path = Glib::path_get_dirname (string (cmdline_path));
2064 session_name = basename_nosuffix (string (cmdline_path));
2068 ARDOUR_UI::load_cmdline_session (const Glib::ustring& session_name, const Glib::ustring& session_path, bool& existing_session)
2070 /* when this is called, the backend audio system must be running */
2072 /* the main idea here is to deal with the fact that a cmdline argument for the session
2073 can be interpreted in different ways - it could be a directory or a file, and before
2074 we load, we need to know both the session directory and the snapshot (statefile) within it
2075 that we are supposed to use.
2078 if (session_name.length() == 0 || session_path.length() == 0) {
2082 if (Glib::file_test (session_path, Glib::FILE_TEST_IS_DIR)) {
2084 Glib::ustring predicted_session_file;
2086 predicted_session_file = session_path;
2087 predicted_session_file += '/';
2088 predicted_session_file += session_name;
2089 predicted_session_file += ARDOUR::statefile_suffix;
2091 if (Glib::file_test (predicted_session_file, Glib::FILE_TEST_EXISTS)) {
2092 existing_session = true;
2095 } else if (Glib::file_test (session_path, Glib::FILE_TEST_EXISTS)) {
2097 if (session_path.find (ARDOUR::statefile_suffix) == session_path.length() - 7) {
2098 /* existing .ardour file */
2099 existing_session = true;
2103 existing_session = false;
2106 /* lets just try to load it */
2108 if (create_engine ()) {
2109 backend_audio_error (false, _startup);
2113 return load_session (session_path, session_name);
2117 ARDOUR_UI::ask_about_loading_existing_session (const Glib::ustring& session_path)
2119 Glib::ustring str = string_compose (_("This session\n%1\nalready exists. Do you want to open it?"), session_path);
2121 MessageDialog msg (str,
2123 Gtk::MESSAGE_WARNING,
2124 Gtk::BUTTONS_YES_NO,
2128 msg.set_name (X_("CleanupDialog"));
2129 msg.set_wmclass (X_("existing_session"), "Ardour");
2130 msg.set_position (Gtk::WIN_POS_MOUSE);
2133 switch (msg.run()) {
2142 ARDOUR_UI::build_session_from_nsd (const Glib::ustring& session_path, const Glib::ustring& session_name)
2147 AutoConnectOption iconnect;
2148 AutoConnectOption oconnect;
2152 if (Profile->get_sae()) {
2156 iconnect = AutoConnectPhysical;
2157 oconnect = AutoConnectMaster;
2158 nphysin = 0; // use all available
2159 nphysout = 0; // use all available
2163 /* get settings from advanced section of NSD */
2165 if (_startup->create_control_bus()) {
2166 cchns = (uint32_t) _startup->control_channel_count();
2171 if (_startup->create_master_bus()) {
2172 mchns = (uint32_t) _startup->master_channel_count();
2177 if (_startup->connect_inputs()) {
2178 iconnect = AutoConnectPhysical;
2180 iconnect = AutoConnectOption (0);
2183 /// @todo some minor tweaks.
2185 if (_startup->connect_outs_to_master()) {
2186 oconnect = AutoConnectMaster;
2187 } else if (_startup->connect_outs_to_physical()) {
2188 oconnect = AutoConnectPhysical;
2190 oconnect = AutoConnectOption (0);
2193 nphysin = (uint32_t) _startup->input_limit_count();
2194 nphysout = (uint32_t) _startup->output_limit_count();
2197 if (build_session (session_path,
2205 engine->frame_rate() * 60 * 5)) {
2214 ARDOUR_UI::idle_load (const Glib::ustring& path)
2217 if (Glib::file_test (path, Glib::FILE_TEST_IS_DIR)) {
2218 /* /path/to/foo => /path/to/foo, foo */
2219 load_session (path, basename_nosuffix (path));
2221 /* /path/to/foo/foo.ardour => /path/to/foo, foo */
2222 load_session (Glib::path_get_dirname (path), basename_nosuffix (path));
2226 ARDOUR_COMMAND_LINE::session_name = path;
2229 * new_session_dialog doens't exist in A3
2230 * Try to remove all references to it to
2231 * see if it will compile. NOTE: this will
2232 * likely cause a runtime issue is my somewhat
2236 //if (new_session_dialog) {
2239 /* make it break out of Dialog::run() and
2243 //new_session_dialog->response (1);
2249 ARDOUR_UI::end_loading_messages ()
2255 ARDOUR_UI::loading_message (const std::string& /*msg*/)
2258 // splash->message (msg);
2263 ARDOUR_UI::get_session_parameters (bool should_be_new)
2265 Glib::ustring session_name;
2266 Glib::ustring session_path;
2267 Glib::ustring template_name;
2269 bool likely_new = false;
2273 if (!should_be_new && !ARDOUR_COMMAND_LINE::session_name.empty()) {
2275 /* if they named a specific statefile, use it, otherwise they are
2276 just giving a session folder, and we want to use it as is
2277 to find the session.
2280 if (ARDOUR_COMMAND_LINE::session_name.find (statefile_suffix) != string::npos) {
2281 session_path = Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name);
2283 session_path = ARDOUR_COMMAND_LINE::session_name;
2286 session_name = Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name);
2290 run_startup (should_be_new);
2292 /* if we run the startup dialog again, offer more than just "new session" */
2294 should_be_new = false;
2296 session_name = _startup->session_name (likely_new);
2298 /* this shouldn't happen, but we catch it just in case it does */
2300 if (session_name.empty()) {
2303 if (_startup->use_session_template()) {
2304 template_name = _startup->session_template_name();
2305 _session_is_new = true;
2309 if (session_name[0] == '/' ||
2310 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
2311 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
2313 session_path = Glib::path_get_dirname (session_name);
2314 session_name = Glib::path_get_basename (session_name);
2318 session_path = _startup->session_folder();
2322 if (create_engine ()) {
2326 if (Glib::file_test (session_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
2330 Glib::ustring existing = Glib::build_filename (session_path, session_name);
2332 if (!ask_about_loading_existing_session (existing)) {
2333 ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
2338 _session_is_new = false;
2343 MessageDialog msg (string_compose (_("There is no existing session at \"%1\""), session_path));
2345 ARDOUR_COMMAND_LINE::session_name = ""; // cancel that
2349 _session_is_new = true;
2352 if (likely_new && template_name.empty()) {
2354 ret = build_session_from_nsd (session_path, session_name);
2358 ret = load_session (session_path, session_name, template_name);
2366 ARDOUR_UI::close_session()
2368 if (!check_audioengine()) {
2372 unload_session (true);
2374 ARDOUR_COMMAND_LINE::session_name = "";
2375 get_session_parameters (false);
2379 ARDOUR_UI::load_session (const Glib::ustring& path, const Glib::ustring& snap_name, Glib::ustring mix_template)
2381 Session *new_session;
2385 session_loaded = false;
2387 if (!check_audioengine()) {
2391 unload_status = unload_session ();
2393 if (unload_status < 0) {
2395 } else if (unload_status > 0) {
2400 loading_message (_("Please wait while Ardour loads your session"));
2403 new_session = new Session (*engine, path, snap_name, mix_template);
2406 /* this one is special */
2408 catch (AudioEngine::PortRegistrationFailure& err) {
2410 MessageDialog msg (err.what(),
2413 Gtk::BUTTONS_CLOSE);
2415 msg.set_title (_("Port Registration Error"));
2416 msg.set_secondary_text (_("Click the Close button to try again."));
2417 msg.set_position (Gtk::WIN_POS_CENTER);
2421 int response = msg.run ();
2426 case RESPONSE_CANCEL:
2436 MessageDialog msg (string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name),
2439 Gtk::BUTTONS_CLOSE);
2441 msg.set_title (_("Loading Error"));
2442 msg.set_secondary_text (_("Click the Close button to try again."));
2443 msg.set_position (Gtk::WIN_POS_CENTER);
2447 int response = msg.run ();
2452 case RESPONSE_CANCEL:
2460 connect_to_session (new_session);
2462 session_loaded = true;
2464 goto_editor_window ();
2467 session->set_clean ();
2478 ARDOUR_UI::build_session (const Glib::ustring& path, const Glib::ustring& snap_name,
2479 uint32_t control_channels,
2480 uint32_t master_channels,
2481 AutoConnectOption input_connect,
2482 AutoConnectOption output_connect,
2485 nframes_t initial_length)
2487 Session *new_session;
2490 if (!check_audioengine()) {
2494 session_loaded = false;
2496 x = unload_session ();
2504 _session_is_new = true;
2507 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
2508 control_channels, master_channels, nphysin, nphysout, initial_length);
2513 MessageDialog msg (string_compose(_("Could not create session in \"%1\""), path));
2519 connect_to_session (new_session);
2521 session_loaded = true;
2523 new_session->save_state(new_session->name());
2532 editor->show_window ();
2543 ARDOUR_UI::show_about ()
2547 about->signal_response().connect(mem_fun (*this, &ARDOUR_UI::about_signal_response) );
2554 ARDOUR_UI::hide_about ()
2557 about->get_window()->set_cursor ();
2563 ARDOUR_UI::about_signal_response (int /*response*/)
2569 ARDOUR_UI::show_splash ()
2573 splash = new Splash;
2581 splash->queue_draw ();
2582 splash->get_window()->process_updates (true);
2587 ARDOUR_UI::hide_splash ()
2595 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title,
2596 const string& plural_msg, const string& singular_msg)
2600 removed = rep.paths.size();
2603 MessageDialog msgd (*editor,
2604 _("No audio files were ready for cleanup"),
2607 (Gtk::ButtonsType)(Gtk::BUTTONS_OK) );
2608 msgd.set_secondary_text (_("If this seems suprising, \n\
2609 check for any existing snapshots.\n\
2610 These may still include regions that\n\
2611 require some unused files to continue to exist."));
2617 ArdourDialog results (_("ardour: cleanup"), true, false);
2619 struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
2620 CleanupResultsModelColumns() {
2624 Gtk::TreeModelColumn<Glib::ustring> visible_name;
2625 Gtk::TreeModelColumn<Glib::ustring> fullpath;
2629 CleanupResultsModelColumns results_columns;
2630 Glib::RefPtr<Gtk::ListStore> results_model;
2631 Gtk::TreeView results_display;
2633 results_model = ListStore::create (results_columns);
2634 results_display.set_model (results_model);
2635 results_display.append_column (list_title, results_columns.visible_name);
2637 results_display.set_name ("CleanupResultsList");
2638 results_display.set_headers_visible (true);
2639 results_display.set_headers_clickable (false);
2640 results_display.set_reorderable (false);
2642 Gtk::ScrolledWindow list_scroller;
2645 Gtk::HBox dhbox; // the hbox for the image and text
2646 Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
2647 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO, Gtk::ICON_SIZE_DIALOG));
2649 dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
2651 const string dead_sound_directory = session->session_directory().dead_sound_path().to_string();
2657 %1 - number of files removed
2658 %2 - location of "dead_sounds"
2659 %3 - size of files affected
2660 %4 - prefix for "bytes" to produce sensible results (e.g. mega, kilo, giga)
2663 const char* bprefix;
2665 if (rep.space < 1048576.0f) {
2666 bprefix = X_("kilo");
2667 } else if (rep.space < 1048576.0f * 1000) {
2668 bprefix = X_("mega");
2670 bprefix = X_("giga");
2674 txt.set_text (string_compose (plural_msg, removed, dead_sound_directory, (float) rep.space / 1024.0f, bprefix));
2676 txt.set_text (string_compose (singular_msg, removed, dead_sound_directory, (float) rep.space / 1024.0f, bprefix));
2679 dhbox.pack_start (*dimage, true, false, 5);
2680 dhbox.pack_start (txt, true, false, 5);
2682 for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2683 TreeModel::Row row = *(results_model->append());
2684 row[results_columns.visible_name] = *i;
2685 row[results_columns.fullpath] = *i;
2688 list_scroller.add (results_display);
2689 list_scroller.set_size_request (-1, 150);
2690 list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2692 dvbox.pack_start (dhbox, true, false, 5);
2693 dvbox.pack_start (list_scroller, true, false, 5);
2694 ddhbox.pack_start (dvbox, true, false, 5);
2696 results.get_vbox()->pack_start (ddhbox, true, false, 5);
2697 results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
2698 results.set_default_response (RESPONSE_CLOSE);
2699 results.set_position (Gtk::WIN_POS_MOUSE);
2701 results_display.show();
2702 list_scroller.show();
2709 //results.get_vbox()->show();
2710 results.set_resizable (false);
2717 ARDOUR_UI::cleanup ()
2720 /* shouldn't happen: menu item is insensitive */
2725 MessageDialog checker (_("Are you sure you want to cleanup?"),
2727 Gtk::MESSAGE_QUESTION,
2728 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
2730 checker.set_secondary_text(_("Cleanup is a destructive operation.\n\
2731 ALL undo/redo information will be lost if you cleanup.\n\
2732 After cleanup, unused audio files will be moved to a \
2733 \"dead sounds\" location."));
2735 checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2736 checker.add_button (_("Clean Up"), RESPONSE_ACCEPT);
2737 checker.set_default_response (RESPONSE_CANCEL);
2739 checker.set_name (_("CleanupDialog"));
2740 checker.set_wmclass (X_("ardour_cleanup"), "Ardour");
2741 checker.set_position (Gtk::WIN_POS_MOUSE);
2743 switch (checker.run()) {
2744 case RESPONSE_ACCEPT:
2750 Session::cleanup_report rep;
2752 editor->prepare_for_cleanup ();
2754 /* do not allow flush until a session is reloaded */
2756 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
2758 act->set_sensitive (false);
2761 if (session->cleanup_sources (rep)) {
2762 editor->finish_cleanup ();
2766 editor->finish_cleanup ();
2769 display_cleanup_results (rep,
2772 The following %1 files were not in use and \n\
2773 have been moved to:\n\
2775 Flushing the wastebasket will \n\
2776 release an additional\n\
2777 %3 %4bytes of disk space.\n"),
2779 The following file was not in use and \n \
2780 has been moved to:\n \
2782 Flushing the wastebasket will \n\
2783 release an additional\n\
2784 %3 %4bytes of disk space.\n"
2790 ARDOUR_UI::flush_trash ()
2793 /* shouldn't happen: menu item is insensitive */
2797 Session::cleanup_report rep;
2799 if (session->cleanup_trash_sources (rep)) {
2803 display_cleanup_results (rep,
2805 _("The following %1 files were deleted from\n\
2807 releasing %3 %4bytes of disk space"),
2808 _("The following file was deleted from\n\
2810 releasing %3 %4bytes of disk space"));
2814 ARDOUR_UI::add_route (Gtk::Window* float_window)
2822 if (add_route_dialog == 0) {
2823 add_route_dialog = new AddRouteDialog (*session);
2825 add_route_dialog->set_transient_for (*float_window);
2829 if (add_route_dialog->is_visible()) {
2830 /* we're already doing this */
2834 ResponseType r = (ResponseType) add_route_dialog->run ();
2836 add_route_dialog->hide();
2839 case RESPONSE_ACCEPT:
2846 if ((count = add_route_dialog->count()) <= 0) {
2850 string template_path = add_route_dialog->track_template();
2852 if (!template_path.empty()) {
2853 session->new_route_from_template (count, template_path);
2857 uint32_t input_chan = add_route_dialog->channels ();
2858 uint32_t output_chan;
2859 string name_template = add_route_dialog->name_template ();
2860 bool track = add_route_dialog->track ();
2861 RouteGroup* route_group = add_route_dialog->route_group ();
2863 AutoConnectOption oac = Config->get_output_auto_connect();
2865 if (oac & AutoConnectMaster) {
2866 output_chan = (session->master_out() ? session->master_out()->n_inputs().n_audio() : input_chan);
2868 output_chan = input_chan;
2871 /* XXX do something with name template */
2873 if (add_route_dialog->type() == ARDOUR::DataType::MIDI) {
2875 session_add_midi_track (route_group, count);
2877 MessageDialog msg (*editor,
2878 _("Sorry, MIDI Busses are not supported at this time."));
2880 //session_add_midi_bus();
2884 session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), route_group, count);
2886 session_add_audio_bus (input_chan, output_chan, route_group, count);
2892 ARDOUR_UI::mixer_settings () const
2897 node = session->instant_xml(X_("Mixer"));
2899 node = Config->instant_xml(X_("Mixer"));
2903 node = new XMLNode (X_("Mixer"));
2910 ARDOUR_UI::editor_settings () const
2915 node = session->instant_xml(X_("Editor"));
2917 node = Config->instant_xml(X_("Editor"));
2921 if (getenv("ARDOUR_INSTANT_XML_PATH")) {
2922 node = Config->instant_xml(getenv("ARDOUR_INSTANT_XML_PATH"));
2927 node = new XMLNode (X_("Editor"));
2934 ARDOUR_UI::keyboard_settings () const
2938 node = Config->extra_xml(X_("Keyboard"));
2941 node = new XMLNode (X_("Keyboard"));
2947 ARDOUR_UI::create_xrun_marker(nframes_t where)
2949 editor->mouse_add_new_marker (where, false, true);
2953 ARDOUR_UI::halt_on_xrun_message ()
2955 MessageDialog msg (*editor,
2956 _("Recording was stopped because your system could not keep up."));
2961 ARDOUR_UI::xrun_handler(nframes_t where)
2967 ENSURE_GUI_THREAD (bind(mem_fun(*this, &ARDOUR_UI::xrun_handler), where));
2969 if (session && Config->get_create_xrun_marker() && session->actively_recording()) {
2970 create_xrun_marker(where);
2973 if (session && Config->get_stop_recording_on_xrun() && session->actively_recording()) {
2974 halt_on_xrun_message ();
2979 ARDOUR_UI::push_buffer_stats (uint32_t capture, uint32_t playback)
2984 while (disk_buffer_stats.size() > 60) {
2985 disk_buffer_stats.pop_front ();
2988 disk_buffer_stats.push_back (DiskBufferStat (now, capture, playback));
2992 ARDOUR_UI::write_buffer_stats ()
2997 char* tmplt = (char*)calloc(strlen("ardourXXXXXX"), sizeof(char));
2998 int fd = mkstemp (tmplt);
3000 cerr << X_("cannot find temporary name for ardour buffer stats") << endl;
3004 FILE* fout = fdopen (fd, "w");
3006 cerr << string_compose (X_("cannot open file %1 for ardour buffer stats"), tmplt) << endl;
3010 for (list<DiskBufferStat>::iterator i = disk_buffer_stats.begin(); i != disk_buffer_stats.end(); ++i) {
3011 std::ostringstream ss;
3012 localtime_r (&(*i).when, &tm);
3013 strftime (buf, sizeof (buf), "%T", &tm);
3014 fprintf(fout, "%s %u %u\n", buf, (*i).capture, (*i).playback);
3017 disk_buffer_stats.clear ();
3022 cerr << "Ardour buffering statistics can be found in: " << tmplt << endl;
3027 ARDOUR_UI::disk_overrun_handler ()
3029 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
3031 write_buffer_stats ();
3033 if (!have_disk_speed_dialog_displayed) {
3034 have_disk_speed_dialog_displayed = true;
3035 MessageDialog* msg = new MessageDialog (*editor, _("\
3036 The disk system on your computer\n\
3037 was not able to keep up with Ardour.\n\
3039 Specifically, it failed to write data to disk\n\
3040 quickly enough to keep up with recording.\n"));
3041 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
3047 ARDOUR_UI::disk_underrun_handler ()
3049 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
3051 write_buffer_stats ();
3053 if (!have_disk_speed_dialog_displayed) {
3054 have_disk_speed_dialog_displayed = true;
3055 MessageDialog* msg = new MessageDialog (*editor,
3056 _("The disk system on your computer\n\
3057 was not able to keep up with Ardour.\n\
3059 Specifically, it failed to read data from disk\n\
3060 quickly enough to keep up with playback.\n"));
3061 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
3067 ARDOUR_UI::disk_speed_dialog_gone (int /*ignored_response*/, MessageDialog* msg)
3069 have_disk_speed_dialog_displayed = false;
3074 ARDOUR_UI::session_dialog (std::string msg)
3076 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::session_dialog), msg));
3081 d = new MessageDialog (*editor, msg, false, MESSAGE_INFO, BUTTONS_OK, true);
3083 d = new MessageDialog (msg, false, MESSAGE_INFO, BUTTONS_OK, true);
3092 ARDOUR_UI::pending_state_dialog ()
3094 HBox* hbox = new HBox();
3095 Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG);
3096 ArdourDialog dialog (_("Crash Recovery"), true);
3098 This session appears to have been in\n\
3099 middle of recording when ardour or\n\
3100 the computer was shutdown.\n\
3102 Ardour can recover any captured audio for\n\
3103 you, or it can ignore it. Please decide\n\
3104 what you would like to do.\n"));
3105 image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
3106 hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
3107 hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
3108 dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
3109 dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
3110 dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
3111 dialog.set_default_response (RESPONSE_ACCEPT);
3112 dialog.set_position (WIN_POS_CENTER);
3117 switch (dialog.run ()) {
3118 case RESPONSE_ACCEPT:
3126 ARDOUR_UI::sr_mismatch_dialog (nframes_t desired, nframes_t actual)
3128 HBox* hbox = new HBox();
3129 Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG);
3130 ArdourDialog dialog (_("Sample Rate Mismatch"), true);
3131 Label message (string_compose (_("\
3132 This session was created with a sample rate of %1 Hz\n\
3134 The audioengine is currently running at %2 Hz\n"), desired, actual));
3136 image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
3137 hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
3138 hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
3139 dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
3140 dialog.add_button (_("Do not load session"), RESPONSE_REJECT);
3141 dialog.add_button (_("Load session anyway"), RESPONSE_ACCEPT);
3142 dialog.set_default_response (RESPONSE_ACCEPT);
3143 dialog.set_position (WIN_POS_CENTER);
3148 switch (dialog.run ()) {
3149 case RESPONSE_ACCEPT:
3158 ARDOUR_UI::disconnect_from_jack ()
3161 if( engine->disconnect_from_jack ()) {
3162 MessageDialog msg (*editor, _("Could not disconnect from JACK"));
3166 update_sample_rate (0);
3171 ARDOUR_UI::reconnect_to_jack ()
3174 if (engine->reconnect_to_jack ()) {
3175 MessageDialog msg (*editor, _("Could not reconnect to JACK"));
3179 update_sample_rate (0);
3184 ARDOUR_UI::use_config ()
3187 XMLNode* node = Config->extra_xml (X_("TransportControllables"));
3189 set_transport_controllable_state (*node);
3194 ARDOUR_UI::update_transport_clocks (nframes_t pos)
3196 if (Config->get_primary_clock_delta_edit_cursor()) {
3197 primary_clock.set (pos, false, editor->get_preferred_edit_position(), 1);
3199 primary_clock.set (pos, 0, true);
3202 if (Config->get_secondary_clock_delta_edit_cursor()) {
3203 secondary_clock.set (pos, false, editor->get_preferred_edit_position(), 2);
3205 secondary_clock.set (pos);
3208 if (big_clock_window) {
3209 big_clock.set (pos);
3214 ARDOUR_UI::record_state_changed ()
3216 ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::record_state_changed));
3218 if (!session || !big_clock_window) {
3219 /* why bother - the clock isn't visible */
3223 Session::RecordState const r = session->record_status ();
3224 bool const h = session->have_rec_enabled_diskstream ();
3226 if (r == Session::Recording && h) {
3227 big_clock.set_widget_name ("BigClockRecording");
3229 big_clock.set_widget_name ("BigClockNonRecording");
3234 ARDOUR_UI::first_idle ()
3237 session->allow_auto_play (true);
3241 editor->first_idle();
3244 Keyboard::set_can_save_keybindings (true);
3249 ARDOUR_UI::store_clock_modes ()
3251 XMLNode* node = new XMLNode(X_("ClockModes"));
3253 for (vector<AudioClock*>::iterator x = AudioClock::clocks.begin(); x != AudioClock::clocks.end(); ++x) {
3254 node->add_property ((*x)->name().c_str(), enum_2_string ((*x)->mode()));
3257 session->add_extra_xml (*node);
3258 session->set_dirty ();
3263 ARDOUR_UI::TransportControllable::TransportControllable (std::string name, ARDOUR_UI& u, ToggleType tp)
3264 : Controllable (name), ui (u), type(tp)
3270 ARDOUR_UI::TransportControllable::set_value (float val)
3272 if (type == ShuttleControl) {
3279 fract = -((0.5f - val)/0.5f);
3281 fract = ((val - 0.5f)/0.5f);
3285 ui.set_shuttle_fract (fract);
3290 /* do nothing: these are radio-style actions */
3294 const char *action = 0;
3298 action = X_("Roll");
3301 action = X_("Stop");
3304 action = X_("Goto Start");
3307 action = X_("Goto End");
3310 action = X_("Loop");
3313 action = X_("Play Selection");
3316 action = X_("Record");
3326 Glib::RefPtr<Action> act = ActionManager::get_action ("Transport", action);
3334 ARDOUR_UI::TransportControllable::get_value (void) const
3353 case ShuttleControl:
3363 ARDOUR_UI::TransportControllable::set_id (const string& str)
3369 ARDOUR_UI::setup_profile ()
3371 if (gdk_screen_width() < 1200) {
3372 Profile->set_small_screen ();
3376 if (getenv ("ARDOUR_SAE")) {
3377 Profile->set_sae ();
3378 Profile->set_single_package ();