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"
87 #include "new_session_dialog.h"
91 #include "gui_thread.h"
92 #include "theme_manager.h"
93 #include "bundle_manager.h"
94 #include "session_metadata_dialog.h"
95 #include "gain_meter.h"
96 #include "route_time_axis.h"
100 using namespace ARDOUR;
102 using namespace Gtkmm2ext;
104 using namespace sigc;
106 ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
107 UIConfiguration *ARDOUR_UI::ui_config = 0;
109 sigc::signal<void,bool> ARDOUR_UI::Blink;
110 sigc::signal<void> ARDOUR_UI::RapidScreenUpdate;
111 sigc::signal<void> ARDOUR_UI::SuperRapidScreenUpdate;
112 sigc::signal<void,nframes_t, bool, nframes_t> ARDOUR_UI::Clock;
114 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
116 : Gtkmm2ext::UI (X_("Ardour"), argcp, argvp),
118 primary_clock (X_("primary"), false, X_("TransportClockDisplay"), true, false, true),
119 secondary_clock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, false, true),
120 preroll_clock (X_("preroll"), false, X_("PreRollClock"), true, true),
121 postroll_clock (X_("postroll"), false, X_("PostRollClock"), true, true),
125 preroll_button (_("pre\nroll")),
126 postroll_button (_("post\nroll")),
130 big_clock (X_("bigclock"), false, "BigClockNonRecording", true, false, true),
134 roll_controllable (new TransportControllable ("transport roll", *this, TransportControllable::Roll)),
135 stop_controllable (new TransportControllable ("transport stop", *this, TransportControllable::Stop)),
136 goto_start_controllable (new TransportControllable ("transport goto start", *this, TransportControllable::GotoStart)),
137 goto_end_controllable (new TransportControllable ("transport goto end", *this, TransportControllable::GotoEnd)),
138 auto_loop_controllable (new TransportControllable ("transport auto loop", *this, TransportControllable::AutoLoop)),
139 play_selection_controllable (new TransportControllable ("transport play selection", *this, TransportControllable::PlaySelection)),
140 rec_controllable (new TransportControllable ("transport rec-enable", *this, TransportControllable::RecordEnable)),
141 shuttle_controllable (new TransportControllable ("shuttle", *this, TransportControllable::ShuttleControl)),
142 shuttle_controller_binding_proxy (shuttle_controllable),
144 roll_button (roll_controllable),
145 stop_button (stop_controllable),
146 goto_start_button (goto_start_controllable),
147 goto_end_button (goto_end_controllable),
148 auto_loop_button (auto_loop_controllable),
149 play_selection_button (play_selection_controllable),
150 rec_button (rec_controllable),
152 shuttle_units_button (_("% ")),
154 punch_in_button (_("Punch In")),
155 punch_out_button (_("Punch Out")),
156 auto_return_button (_("Auto Return")),
157 auto_play_button (_("Auto Play")),
158 auto_input_button (_("Auto Input")),
159 click_button (_("Click")),
160 time_master_button (_("time\nmaster")),
162 auditioning_alert_button (_("AUDITION")),
163 solo_alert_button (_("SOLO")),
165 error_log_button (_("Errors"))
168 using namespace Gtk::Menu_Helpers;
174 _auto_display_errors = false;
180 if (ARDOUR_COMMAND_LINE::session_name.length()) {
181 /* only show this if we're not going to post the new session dialog */
185 if (theArdourUI == 0) {
189 ui_config = new UIConfiguration();
190 theme_manager = new ThemeManager();
197 _session_is_new = false;
198 big_clock_window = 0;
199 session_selector_window = 0;
200 last_key_press_time = 0;
201 connection_editor = 0;
202 _will_create_new_session_automatically = false;
203 new_session_dialog = 0;
204 add_route_dialog = 0;
208 open_session_selector = 0;
209 have_configure_timeout = false;
210 have_disk_speed_dialog_displayed = false;
211 session_loaded = false;
212 last_speed_displayed = -1.0f;
213 ignore_dual_punch = false;
214 _mixer_on_top = false;
216 roll_button.unset_flags (Gtk::CAN_FOCUS);
217 stop_button.unset_flags (Gtk::CAN_FOCUS);
218 goto_start_button.unset_flags (Gtk::CAN_FOCUS);
219 goto_end_button.unset_flags (Gtk::CAN_FOCUS);
220 auto_loop_button.unset_flags (Gtk::CAN_FOCUS);
221 play_selection_button.unset_flags (Gtk::CAN_FOCUS);
222 rec_button.unset_flags (Gtk::CAN_FOCUS);
224 last_configure_time= 0;
226 shuttle_grabbed = false;
228 shuttle_max_speed = 8.0f;
230 shuttle_style_menu = 0;
231 shuttle_unit_menu = 0;
233 // We do not have jack linked in yet so;
235 last_shuttle_request = last_peak_grab = 0; // get_microseconds();
237 ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
238 ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
240 /* handle dialog requests */
242 ARDOUR::Session::Dialog.connect (mem_fun(*this, &ARDOUR_UI::session_dialog));
244 /* handle pending state with a dialog */
246 ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
248 /* handle sr mismatch with a dialog */
250 ARDOUR::Session::AskAboutSampleRateMismatch.connect (mem_fun(*this, &ARDOUR_UI::sr_mismatch_dialog));
252 /* lets get this party started */
255 if (ARDOUR::init (ARDOUR_COMMAND_LINE::use_vst, ARDOUR_COMMAND_LINE::try_hw_optimization)) {
256 throw failed_constructor ();
259 setup_gtk_ardour_enums ();
260 Config->set_current_owner (ConfigVariableBase::Interface);
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::create_engine ()
287 // this gets called every time by new_session()
293 loading_message (_("Starting audio engine"));
296 engine = new ARDOUR::AudioEngine (ARDOUR_COMMAND_LINE::jack_client_name);
303 engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
304 engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
305 engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
306 engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
314 ARDOUR_UI::post_engine ()
316 /* Things to be done once we create the AudioEngine
319 MIDI::Manager::instance()->set_api_data (engine->jack());
322 ActionManager::init ();
325 if (setup_windows ()) {
326 throw failed_constructor ();
329 check_memory_locking();
331 /* this is the first point at which all the keybindings are available */
333 if (ARDOUR_COMMAND_LINE::show_key_actions) {
334 vector<string> names;
335 vector<string> paths;
337 vector<AccelKey> bindings;
339 ActionManager::get_all_actions (names, paths, keys, bindings);
341 vector<string>::iterator n;
342 vector<string>::iterator k;
343 for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) {
344 cerr << "Action: " << (*n) << " bound to " << (*k) << endl;
350 blink_timeout_tag = -1;
352 /* the global configuration object is now valid */
356 /* this being a GUI and all, we want peakfiles */
358 AudioFileSource::set_build_peakfiles (true);
359 AudioFileSource::set_build_missing_peakfiles (true);
361 /* set default clock modes */
363 if (Profile->get_sae()) {
364 primary_clock.set_mode (AudioClock::BBT);
365 secondary_clock.set_mode (AudioClock::MinSec);
367 primary_clock.set_mode (AudioClock::SMPTE);
368 secondary_clock.set_mode (AudioClock::BBT);
371 /* start the time-of-day-clock */
374 /* OS X provides an always visible wallclock, so don't be stupid */
375 update_wall_clock ();
376 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
379 update_disk_space ();
381 update_sample_rate (engine->frame_rate());
383 /* now start and maybe save state */
385 if (do_engine_start () == 0) {
386 if (session && _session_is_new) {
387 /* we need to retain initial visual
388 settings for a new session
390 session->save_state ("");
395 ARDOUR_UI::~ARDOUR_UI ()
397 save_ardour_state ();
411 if (add_route_dialog) {
412 delete add_route_dialog;
416 if (new_session_dialog) {
417 delete new_session_dialog;
422 ARDOUR_UI::pop_back_splash ()
424 if (Splash::instance()) {
425 // Splash::instance()->pop_back();
426 Splash::instance()->hide ();
431 ARDOUR_UI::configure_timeout ()
433 if (last_configure_time == 0) {
434 /* no configure events yet */
438 /* force a gap of 0.5 seconds since the last configure event
441 if (get_microseconds() - last_configure_time < 500000) {
444 have_configure_timeout = false;
445 save_ardour_state ();
451 ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
453 if (have_configure_timeout) {
454 last_configure_time = get_microseconds();
456 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
457 have_configure_timeout = true;
464 ARDOUR_UI::set_transport_controllable_state (const XMLNode& node)
466 const XMLProperty* prop;
468 if ((prop = node.property ("roll")) != 0) {
469 roll_controllable->set_id (prop->value());
471 if ((prop = node.property ("stop")) != 0) {
472 stop_controllable->set_id (prop->value());
474 if ((prop = node.property ("goto-start")) != 0) {
475 goto_start_controllable->set_id (prop->value());
477 if ((prop = node.property ("goto-end")) != 0) {
478 goto_end_controllable->set_id (prop->value());
480 if ((prop = node.property ("auto-loop")) != 0) {
481 auto_loop_controllable->set_id (prop->value());
483 if ((prop = node.property ("play-selection")) != 0) {
484 play_selection_controllable->set_id (prop->value());
486 if ((prop = node.property ("rec")) != 0) {
487 rec_controllable->set_id (prop->value());
489 if ((prop = node.property ("shuttle")) != 0) {
490 shuttle_controllable->set_id (prop->value());
495 ARDOUR_UI::get_transport_controllable_state ()
497 XMLNode* node = new XMLNode(X_("TransportControllables"));
500 roll_controllable->id().print (buf, sizeof (buf));
501 node->add_property (X_("roll"), buf);
502 stop_controllable->id().print (buf, sizeof (buf));
503 node->add_property (X_("stop"), buf);
504 goto_start_controllable->id().print (buf, sizeof (buf));
505 node->add_property (X_("goto_start"), buf);
506 goto_end_controllable->id().print (buf, sizeof (buf));
507 node->add_property (X_("goto_end"), buf);
508 auto_loop_controllable->id().print (buf, sizeof (buf));
509 node->add_property (X_("auto_loop"), buf);
510 play_selection_controllable->id().print (buf, sizeof (buf));
511 node->add_property (X_("play_selection"), buf);
512 rec_controllable->id().print (buf, sizeof (buf));
513 node->add_property (X_("rec"), buf);
514 shuttle_controllable->id().print (buf, sizeof (buf));
515 node->add_property (X_("shuttle"), buf);
521 ARDOUR_UI::save_ardour_state ()
523 if (!keyboard || !mixer || !editor) {
527 /* XXX this is all a bit dubious. add_extra_xml() uses
528 a different lifetime model from add_instant_xml().
531 XMLNode* node = new XMLNode (keyboard->get_state());
532 Config->add_extra_xml (*node);
533 Config->add_extra_xml (get_transport_controllable_state());
534 if (new_session_dialog && new_session_dialog->engine_control.was_used()) {
535 Config->add_extra_xml (new_session_dialog->engine_control.get_state());
537 Config->save_state();
538 ui_config->save_state ();
540 XMLNode enode(static_cast<Stateful*>(editor)->get_state());
541 XMLNode mnode(mixer->get_state());
544 session->add_instant_xml (enode);
545 session->add_instant_xml (mnode);
547 Config->add_instant_xml (enode);
548 Config->add_instant_xml (mnode);
551 Keyboard::save_keybindings ();
555 ARDOUR_UI::autosave_session ()
557 if (g_main_depth() > 1) {
558 /* inside a recursive main loop,
559 give up because we may not be able to
565 if (!Config->get_periodic_safety_backups()) {
570 session->maybe_write_autosave();
577 ARDOUR_UI::update_autosave ()
579 ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::update_autosave));
581 if (session->dirty()) {
582 if (_autosave_connection.connected()) {
583 _autosave_connection.disconnect();
586 _autosave_connection = Glib::signal_timeout().connect (mem_fun (*this, &ARDOUR_UI::autosave_session),
587 Config->get_periodic_safety_backup_interval() * 1000);
590 if (_autosave_connection.connected()) {
591 _autosave_connection.disconnect();
597 ARDOUR_UI::backend_audio_error (bool we_set_params, Gtk::Window* toplevel)
601 title = _("Ardour could not start JACK");
603 title = _("Ardour could not connect to JACK.");
606 MessageDialog win (title,
612 win.set_secondary_text(_("There are several possible reasons:\n\
614 1) You requested audio parameters that are not supported..\n\
615 2) JACK is running as another user.\n\
617 Please consider the possibilities, and perhaps try different parameters."));
619 win.set_secondary_text(_("There are several possible reasons:\n\
621 1) JACK is not running.\n\
622 2) JACK is running as another user, perhaps root.\n\
623 3) There is already another client called \"ardour\".\n\
625 Please consider the possibilities, and perhaps (re)start JACK."));
629 win.set_transient_for (*toplevel);
633 win.add_button (Stock::OK, RESPONSE_CLOSE);
635 win.add_button (Stock::QUIT, RESPONSE_CLOSE);
638 win.set_default_response (RESPONSE_CLOSE);
641 win.set_position (Gtk::WIN_POS_CENTER);
644 /* we just don't care about the result, but we want to block */
650 ARDOUR_UI::startup ()
654 new_session_dialog = new NewSessionDialog();
656 bool backend_audio_is_running = EngineControl::engine_running();
657 XMLNode* audio_setup = Config->extra_xml ("AudioSetup");
660 new_session_dialog->engine_control.set_state (*audio_setup);
663 if (!get_session_parameters (backend_audio_is_running, ARDOUR_COMMAND_LINE::new_session)) {
667 BootMessage (_("Ardour is ready for use"));
672 ARDOUR_UI::no_memory_warning ()
674 XMLNode node (X_("no-memory-warning"));
675 Config->add_instant_xml (node);
679 ARDOUR_UI::check_memory_locking ()
682 /* OS X doesn't support mlockall(2), and so testing for memory locking capability there is pointless */
686 XMLNode* memory_warning_node = Config->instant_xml (X_("no-memory-warning"));
688 if (engine->is_realtime() && memory_warning_node == 0) {
690 struct rlimit limits;
692 long pages, page_size;
694 if ((page_size = sysconf (_SC_PAGESIZE)) < 0 ||(pages = sysconf (_SC_PHYS_PAGES)) < 0) {
697 ram = (int64_t) pages * (int64_t) page_size;
700 if (getrlimit (RLIMIT_MEMLOCK, &limits)) {
704 if (limits.rlim_cur != RLIM_INFINITY) {
706 if (ram == 0 || ((double) limits.rlim_cur / ram) < 0.75) {
709 MessageDialog msg (_("WARNING: Your system has a limit for maximum amount of locked memory. "
710 "This might cause Ardour to run out of memory before your system "
711 "runs out of memory. \n\n"
712 "You can view the memory limit with 'ulimit -l', "
713 "and it is normally controlled by /etc/security/limits.conf"));
715 VBox* vbox = msg.get_vbox();
717 CheckButton cb (_("Do not show this window again"));
719 cb.signal_toggled().connect (mem_fun (*this, &ARDOUR_UI::no_memory_warning));
721 hbox.pack_start (cb, true, false);
722 vbox->pack_start (hbox);
729 editor->ensure_float (msg);
743 if (session->transport_rolling()) {
744 session->request_stop ();
748 if (session->dirty()) {
749 switch (ask_about_saving_session(_("quit"))) {
754 /* use the default name */
755 if (save_state_canfail ("")) {
756 /* failed - don't quit */
757 MessageDialog msg (*editor,
759 Ardour was unable to save your session.\n\n\
760 If you still wish to quit, please use the\n\n\
761 \"Just quit\" option."));
772 session->set_deletion_in_progress ();
775 ArdourDialog::close_all_dialogs ();
777 save_ardour_state ();
782 ARDOUR_UI::ask_about_saving_session (const string & what)
784 ArdourDialog window (_("ardour: save session?"));
785 Gtk::HBox dhbox; // the hbox for the image and text
786 Gtk::Label prompt_label;
787 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_WARNING, Gtk::ICON_SIZE_DIALOG));
791 msg = string_compose(_("Don't %1"), what);
792 window.add_button (msg, RESPONSE_REJECT);
793 msg = string_compose(_("Just %1"), what);
794 window.add_button (msg, RESPONSE_APPLY);
795 msg = string_compose(_("Save and %1"), what);
796 window.add_button (msg, RESPONSE_ACCEPT);
798 window.set_default_response (RESPONSE_ACCEPT);
800 Gtk::Button noquit_button (msg);
801 noquit_button.set_name ("EditorGTKButton");
806 if (session->snap_name() == session->name()) {
809 type = _("snapshot");
811 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?"),
812 type, session->snap_name());
814 prompt_label.set_text (prompt);
815 prompt_label.set_name (X_("PrompterLabel"));
816 prompt_label.set_alignment(ALIGN_LEFT, ALIGN_TOP);
818 dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP);
819 dhbox.set_homogeneous (false);
820 dhbox.pack_start (*dimage, false, false, 5);
821 dhbox.pack_start (prompt_label, true, false, 5);
822 window.get_vbox()->pack_start (dhbox);
824 window.set_name (_("Prompter"));
825 window.set_position (Gtk::WIN_POS_MOUSE);
826 window.set_modal (true);
827 window.set_resizable (false);
833 window.set_keep_above (true);
836 ResponseType r = (ResponseType) window.run();
841 case RESPONSE_ACCEPT: // save and get out of here
843 case RESPONSE_APPLY: // get out of here
853 ARDOUR_UI::every_second ()
856 update_buffer_load ();
857 update_disk_space ();
862 ARDOUR_UI::every_point_one_seconds ()
864 update_speed_display ();
865 RapidScreenUpdate(); /* EMIT_SIGNAL */
870 ARDOUR_UI::every_point_zero_one_seconds ()
872 // august 2007: actual update frequency: 40Hz, not 100Hz
874 SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
879 ARDOUR_UI::update_sample_rate (nframes_t ignored)
883 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
885 if (!engine->connected()) {
887 snprintf (buf, sizeof (buf), _("disconnected"));
891 nframes_t rate = engine->frame_rate();
893 if (fmod (rate, 1000.0) != 0.0) {
894 snprintf (buf, sizeof (buf), _("%.1f kHz / %4.1f ms"),
895 (float) rate/1000.0f,
896 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
898 snprintf (buf, sizeof (buf), _("%u kHz / %4.1f ms"),
900 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
904 sample_rate_label.set_text (buf);
908 ARDOUR_UI::update_cpu_load ()
911 snprintf (buf, sizeof (buf), _("DSP: %5.1f%%"), engine->get_cpu_load());
912 cpu_load_label.set_text (buf);
916 ARDOUR_UI::update_buffer_load ()
921 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"),
922 session->playback_load(), session->capture_load());
923 buffer_load_label.set_text (buf);
925 buffer_load_label.set_text ("");
930 ARDOUR_UI::count_recenabled_streams (Route& route)
932 Track* track = dynamic_cast<Track*>(&route);
933 if (track && track->diskstream()->record_enabled()) {
934 rec_enabled_streams += track->n_inputs().n_total();
939 ARDOUR_UI::update_disk_space()
945 nframes_t frames = session->available_capture_duration();
947 nframes_t fr = session->frame_rate();
949 if (frames == max_frames) {
950 strcpy (buf, _("Disk: 24hrs+"));
952 rec_enabled_streams = 0;
953 session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
955 if (rec_enabled_streams) {
956 frames /= rec_enabled_streams;
963 hrs = frames / (fr * 3600);
964 frames -= hrs * fr * 3600;
965 mins = frames / (fr * 60);
966 frames -= mins * fr * 60;
969 snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs);
972 disk_space_label.set_text (buf);
974 // An attempt to make the disk space label flash red when space has run out.
976 if (frames < fr * 60 * 5) {
977 /* disk_space_box.style ("disk_space_label_empty"); */
979 /* disk_space_box.style ("disk_space_label"); */
985 ARDOUR_UI::update_wall_clock ()
992 tm_now = localtime (&now);
994 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
995 wall_clock_label.set_text (buf);
1001 ARDOUR_UI::session_menu (GdkEventButton *ev)
1003 session_popup_menu->popup (0, 0);
1008 ARDOUR_UI::redisplay_recent_sessions ()
1010 std::vector<sys::path> session_directories;
1011 RecentSessionsSorter cmp;
1013 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
1014 recent_session_model->clear ();
1016 ARDOUR::RecentSessions rs;
1017 ARDOUR::read_recent_sessions (rs);
1020 recent_session_display.set_model (recent_session_model);
1024 // sort them alphabetically
1025 sort (rs.begin(), rs.end(), cmp);
1027 for (ARDOUR::RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
1028 session_directories.push_back ((*i).second);
1031 for (vector<sys::path>::const_iterator i = session_directories.begin();
1032 i != session_directories.end(); ++i)
1034 std::vector<sys::path> state_file_paths;
1036 // now get available states for this session
1038 get_state_files_in_directory (*i, state_file_paths);
1040 vector<string*>* states;
1041 vector<const gchar*> item;
1042 string fullpath = (*i).to_string();
1044 /* remove any trailing / */
1046 if (fullpath[fullpath.length()-1] == '/') {
1047 fullpath = fullpath.substr (0, fullpath.length()-1);
1050 /* check whether session still exists */
1051 if (!Glib::file_test(fullpath.c_str(), Glib::FILE_TEST_EXISTS)) {
1052 /* session doesn't exist */
1053 cerr << "skipping non-existent session " << fullpath << endl;
1057 /* now get available states for this session */
1059 if ((states = Session::possible_states (fullpath)) == 0) {
1060 /* no state file? */
1064 std::vector<string> state_file_names(get_file_names_no_extension (state_file_paths));
1066 Gtk::TreeModel::Row row = *(recent_session_model->append());
1068 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
1069 row[recent_session_columns.fullpath] = fullpath;
1071 if (state_file_names.size() > 1) {
1075 for (std::vector<std::string>::iterator i2 = state_file_names.begin();
1076 i2 != state_file_names.end(); ++i2)
1079 Gtk::TreeModel::Row child_row = *(recent_session_model->append (row.children()));
1081 child_row[recent_session_columns.visible_name] = *i2;
1082 child_row[recent_session_columns.fullpath] = fullpath;
1087 recent_session_display.set_model (recent_session_model);
1091 ARDOUR_UI::build_session_selector ()
1093 session_selector_window = new ArdourDialog ("session selector");
1095 Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
1097 session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
1098 session_selector_window->add_button (Stock::OPEN, RESPONSE_ACCEPT);
1099 session_selector_window->set_default_response (RESPONSE_ACCEPT);
1100 recent_session_model = TreeStore::create (recent_session_columns);
1101 recent_session_display.set_model (recent_session_model);
1102 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1103 recent_session_display.set_headers_visible (false);
1104 recent_session_display.get_selection()->set_mode (SELECTION_BROWSE);
1105 recent_session_display.signal_row_activated().connect (mem_fun (*this, &ARDOUR_UI::recent_session_row_activated));
1107 scroller->add (recent_session_display);
1108 scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1110 session_selector_window->set_name ("SessionSelectorWindow");
1111 session_selector_window->set_size_request (200, 400);
1112 session_selector_window->get_vbox()->pack_start (*scroller);
1114 recent_session_display.show();
1116 //session_selector_window->get_vbox()->show();
1120 ARDOUR_UI::recent_session_row_activated (const TreePath& path, TreeViewColumn* col)
1122 session_selector_window->response (RESPONSE_ACCEPT);
1126 ARDOUR_UI::open_recent_session ()
1128 bool can_return = (session != 0);
1130 if (session_selector_window == 0) {
1131 build_session_selector ();
1134 redisplay_recent_sessions ();
1138 session_selector_window->set_position (WIN_POS_MOUSE);
1140 ResponseType r = (ResponseType) session_selector_window->run ();
1143 case RESPONSE_ACCEPT:
1147 session_selector_window->hide();
1154 if (recent_session_display.get_selection()->count_selected_rows() == 0) {
1158 session_selector_window->hide();
1160 Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
1162 if (i == recent_session_model->children().end()) {
1166 Glib::ustring path = (*i)[recent_session_columns.fullpath];
1167 Glib::ustring state = (*i)[recent_session_columns.visible_name];
1169 _session_is_new = false;
1171 if (load_session (path, state) == 0) {
1180 ARDOUR_UI::check_audioengine ()
1183 if (!engine->connected()) {
1184 MessageDialog msg (_("Ardour is not connected to JACK\n"
1185 "You cannot open or close sessions in this condition"));
1197 ARDOUR_UI::open_session ()
1199 if (!check_audioengine()) {
1204 /* popup selector window */
1206 if (open_session_selector == 0) {
1208 /* ardour sessions are folders */
1210 open_session_selector = new Gtk::FileChooserDialog (_("open session"), FILE_CHOOSER_ACTION_OPEN);
1211 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1212 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
1213 open_session_selector->set_default_response(Gtk::RESPONSE_ACCEPT);
1215 FileFilter session_filter;
1216 session_filter.add_pattern ("*.ardour");
1217 session_filter.set_name (_("Ardour sessions"));
1218 open_session_selector->add_filter (session_filter);
1219 open_session_selector->set_filter (session_filter);
1222 int response = open_session_selector->run();
1223 open_session_selector->hide ();
1226 case RESPONSE_ACCEPT:
1229 open_session_selector->hide();
1233 open_session_selector->hide();
1234 string session_path = open_session_selector->get_filename();
1238 if (session_path.length() > 0) {
1239 if (ARDOUR::find_session (session_path, path, name, isnew) == 0) {
1240 _session_is_new = isnew;
1241 load_session (path, name);
1248 ARDOUR_UI::session_add_midi_route (bool disk, uint32_t how_many)
1250 list<boost::shared_ptr<MidiTrack> > tracks;
1253 warning << _("You cannot add a track without a session already loaded.") << endmsg;
1260 tracks = session->new_midi_track (ARDOUR::Normal, how_many);
1262 if (tracks.size() != how_many) {
1263 if (how_many == 1) {
1264 error << _("could not create a new midi track") << endmsg;
1266 error << string_compose (_("could not create %1 new midi tracks"), how_many) << endmsg;
1270 if ((route = session->new_midi_route ()) == 0) {
1271 error << _("could not create new midi bus") << endmsg;
1277 MessageDialog msg (*editor,
1278 _("There are insufficient JACK ports available\n\
1279 to create a new track or bus.\n\
1280 You should save Ardour, exit and\n\
1281 restart JACK with more ports."));
1288 ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, uint32_t how_many)
1290 list<boost::shared_ptr<AudioTrack> > tracks;
1291 Session::RouteList routes;
1294 warning << _("You cannot add a track or bus without a session already loaded.") << endmsg;
1300 tracks = session->new_audio_track (input_channels, output_channels, mode, how_many);
1302 if (tracks.size() != how_many) {
1303 if (how_many == 1) {
1304 error << _("could not create a new audio track") << endmsg;
1306 error << string_compose (_("could only create %1 of %2 new audio %3"),
1307 tracks.size(), how_many, (track ? _("tracks") : _("busses"))) << endmsg;
1313 routes = session->new_audio_route (input_channels, output_channels, how_many);
1315 if (routes.size() != how_many) {
1316 if (how_many == 1) {
1317 error << _("could not create a new audio track") << endmsg;
1319 error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
1325 if (need_control_room_outs) {
1331 route->set_stereo_control_outs (control_lr_channels);
1332 route->control_outs()->set_stereo_pan (pans, this);
1334 #endif /* CONTROLOUTS */
1338 MessageDialog msg (*editor,
1339 _("There are insufficient JACK ports available\n\
1340 to create a new track or bus.\n\
1341 You should save Ardour, exit and\n\
1342 restart JACK with more ports."));
1349 ARDOUR_UI::do_transport_locate (nframes_t new_position)
1351 nframes_t _preroll = 0;
1354 // XXX CONFIG_CHANGE FIX - requires AnyTime handling
1355 // _preroll = session->convert_to_frames_at (new_position, Config->get_preroll());
1357 if (new_position > _preroll) {
1358 new_position -= _preroll;
1363 session->request_locate (new_position);
1368 ARDOUR_UI::transport_goto_start ()
1371 session->goto_start();
1374 /* force displayed area in editor to start no matter
1375 what "follow playhead" setting is.
1379 editor->reset_x_origin (session->current_start_frame());
1385 ARDOUR_UI::transport_goto_zero ()
1388 session->request_locate (0);
1391 /* force displayed area in editor to start no matter
1392 what "follow playhead" setting is.
1396 editor->reset_x_origin (0);
1402 ARDOUR_UI::transport_goto_wallclock ()
1404 if (session && editor) {
1411 localtime_r (&now, &tmnow);
1413 frames = tmnow.tm_hour * (60 * 60 * session->frame_rate());
1414 frames += tmnow.tm_min * (60 * session->frame_rate());
1415 frames += tmnow.tm_sec * session->frame_rate();
1417 session->request_locate (frames);
1419 /* force displayed area in editor to start no matter
1420 what "follow playhead" setting is.
1424 editor->reset_x_origin (frames - (editor->current_page_frames()/2));
1430 ARDOUR_UI::transport_goto_end ()
1433 nframes_t frame = session->current_end_frame();
1434 session->request_locate (frame);
1436 /* force displayed area in editor to start no matter
1437 what "follow playhead" setting is.
1441 editor->reset_x_origin (frame);
1447 ARDOUR_UI::transport_stop ()
1453 if (session->is_auditioning()) {
1454 session->cancel_audition ();
1458 if (session->get_play_loop ()) {
1459 session->request_play_loop (false);
1462 session->request_stop ();
1466 ARDOUR_UI::transport_stop_and_forget_capture ()
1469 session->request_stop (true);
1474 ARDOUR_UI::remove_last_capture()
1477 editor->remove_last_capture();
1482 ARDOUR_UI::transport_record (bool roll)
1486 switch (session->record_status()) {
1487 case Session::Disabled:
1488 if (session->ntracks() == 0) {
1489 MessageDialog msg (*editor, _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu."));
1493 session->maybe_enable_record ();
1498 case Session::Recording:
1500 session->request_stop();
1502 session->disable_record (false, true);
1506 case Session::Enabled:
1507 session->disable_record (false, true);
1510 //cerr << "ARDOUR_UI::transport_record () called roll = " << roll << " session->record_status() = " << session->record_status() << endl;
1514 ARDOUR_UI::transport_roll ()
1522 rolling = session->transport_rolling ();
1524 //cerr << "ARDOUR_UI::transport_roll () called session->record_status() = " << session->record_status() << endl;
1526 if (session->get_play_loop()) {
1527 session->request_play_loop (false);
1528 auto_loop_button.set_visual_state (1);
1529 roll_button.set_visual_state (1);
1530 } else if (session->get_play_range ()) {
1531 session->request_play_range (false);
1532 play_selection_button.set_visual_state (0);
1533 } else if (rolling) {
1534 session->request_locate (session->last_transport_start(), true);
1537 session->request_transport_speed (1.0f);
1541 ARDOUR_UI::transport_loop()
1544 if (session->get_play_loop()) {
1545 if (session->transport_rolling()) {
1546 Location * looploc = session->locations()->auto_loop_location();
1548 session->request_locate (looploc->start(), true);
1553 session->request_play_loop (true);
1559 ARDOUR_UI::transport_play_selection ()
1565 if (!session->get_play_range()) {
1566 session->request_stop ();
1569 editor->play_selection ();
1573 ARDOUR_UI::transport_rewind (int option)
1575 float current_transport_speed;
1578 current_transport_speed = session->transport_speed();
1580 if (current_transport_speed >= 0.0f) {
1583 session->request_transport_speed (-1.0f);
1586 session->request_transport_speed (-4.0f);
1589 session->request_transport_speed (-0.5f);
1594 session->request_transport_speed (current_transport_speed * 1.5f);
1600 ARDOUR_UI::transport_forward (int option)
1602 float current_transport_speed;
1605 current_transport_speed = session->transport_speed();
1607 if (current_transport_speed <= 0.0f) {
1610 session->request_transport_speed (1.0f);
1613 session->request_transport_speed (4.0f);
1616 session->request_transport_speed (0.5f);
1621 session->request_transport_speed (current_transport_speed * 1.5f);
1627 ARDOUR_UI::toggle_record_enable (uint32_t dstream)
1633 boost::shared_ptr<Route> r;
1635 if ((r = session->route_by_remote_id (dstream)) != 0) {
1639 if ((t = dynamic_cast<Track*>(r.get())) != 0) {
1640 t->diskstream()->set_record_enabled (!t->diskstream()->record_enabled());
1649 ARDOUR_UI::queue_transport_change ()
1651 Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
1655 ARDOUR_UI::map_transport_state ()
1657 float sp = session->transport_speed();
1660 transport_rolling ();
1661 } else if (sp < 0.0f) {
1662 transport_rewinding ();
1663 } else if (sp > 0.0f) {
1664 transport_forwarding ();
1666 transport_stopped ();
1671 ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg)
1673 snprintf (buf, sizeof(buf), "%s", ((GlobalClickBox *) arg)->strings[
1674 (int) adj.get_value()].c_str());
1678 ARDOUR_UI::engine_stopped ()
1680 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
1681 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1682 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1686 ARDOUR_UI::engine_running ()
1688 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
1689 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true);
1690 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
1692 Glib::RefPtr<Action> action;
1693 const char* action_name = 0;
1695 switch (engine->frames_per_cycle()) {
1697 action_name = X_("JACKLatency32");
1700 action_name = X_("JACKLatency64");
1703 action_name = X_("JACKLatency128");
1706 action_name = X_("JACKLatency512");
1709 action_name = X_("JACKLatency1024");
1712 action_name = X_("JACKLatency2048");
1715 action_name = X_("JACKLatency4096");
1718 action_name = X_("JACKLatency8192");
1721 /* XXX can we do anything useful ? */
1727 action = ActionManager::get_action (X_("JACK"), action_name);
1730 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic (action);
1731 ract->set_active ();
1737 ARDOUR_UI::engine_halted ()
1739 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
1741 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1742 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1744 update_sample_rate (0);
1746 MessageDialog msg (*editor,
1748 JACK has either been shutdown or it\n\
1749 disconnected Ardour because Ardour\n\
1750 was not fast enough. Try to restart\n\
1751 JACK, reconnect and save the session."));
1757 ARDOUR_UI::do_engine_start ()
1765 error << _("Unable to start the session running")
1775 ARDOUR_UI::setup_theme ()
1777 theme_manager->setup_theme();
1781 ARDOUR_UI::update_clocks ()
1783 if (!editor || !editor->dragging_playhead()) {
1784 Clock (session->audible_frame(), false, editor->get_preferred_edit_position()); /* EMIT_SIGNAL */
1789 ARDOUR_UI::start_clocking ()
1791 clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
1795 ARDOUR_UI::stop_clocking ()
1797 clock_signal_connection.disconnect ();
1801 ARDOUR_UI::toggle_clocking ()
1804 if (clock_button.get_active()) {
1813 ARDOUR_UI::_blink (void *arg)
1816 ((ARDOUR_UI *) arg)->blink ();
1823 Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
1827 ARDOUR_UI::start_blinking ()
1829 /* Start the blink signal. Everybody with a blinking widget
1830 uses Blink to drive the widget's state.
1833 if (blink_timeout_tag < 0) {
1835 blink_timeout_tag = g_timeout_add (240, _blink, this);
1840 ARDOUR_UI::stop_blinking ()
1842 if (blink_timeout_tag >= 0) {
1843 g_source_remove (blink_timeout_tag);
1844 blink_timeout_tag = -1;
1849 ARDOUR_UI::name_io_setup (AudioEngine& engine,
1854 vector<string> connections;
1857 if (io.n_inputs().n_total() == 0) {
1862 /* XXX we're not handling multiple ports yet. */
1864 if (io.input(0)->get_connections(connections) == 0) {
1867 buf = connections.front();
1872 if (io.n_outputs().n_total() == 0) {
1877 /* XXX we're not handling multiple ports yet. */
1879 if (io.output(0)->get_connections(connections) == 0) {
1882 buf = connections.front();
1887 /** Ask the user for the name of a new shapshot and then take it.
1890 ARDOUR_UI::snapshot_session ()
1892 ArdourPrompter prompter (true);
1896 struct tm local_time;
1899 localtime_r (&n, &local_time);
1900 strftime (timebuf, sizeof(timebuf), "%FT%T", &local_time);
1902 prompter.set_name ("Prompter");
1903 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1904 prompter.set_prompt (_("Name of New Snapshot"));
1905 prompter.set_initial_text (timebuf);
1907 switch (prompter.run()) {
1908 case RESPONSE_ACCEPT:
1909 prompter.get_result (snapname);
1910 if (snapname.length()){
1911 save_state (snapname);
1921 ARDOUR_UI::save_state (const string & name)
1923 (void) save_state_canfail (name);
1927 ARDOUR_UI::save_state_canfail (string name)
1932 if (name.length() == 0) {
1933 name = session->snap_name();
1936 if ((ret = session->save_state (name)) != 0) {
1940 save_ardour_state (); /* XXX cannot fail? yeah, right ... */
1945 ARDOUR_UI::primary_clock_value_changed ()
1948 session->request_locate (primary_clock.current_time ());
1953 ARDOUR_UI::big_clock_value_changed ()
1956 session->request_locate (big_clock.current_time ());
1961 ARDOUR_UI::secondary_clock_value_changed ()
1964 session->request_locate (secondary_clock.current_time ());
1969 ARDOUR_UI::transport_rec_enable_blink (bool onoff)
1975 switch (session->record_status()) {
1976 case Session::Enabled:
1978 rec_button.set_visual_state (2);
1980 rec_button.set_visual_state (0);
1984 case Session::Recording:
1985 rec_button.set_visual_state (1);
1989 rec_button.set_visual_state (0);
1995 ARDOUR_UI::save_template ()
1998 ArdourPrompter prompter (true);
2001 if (!check_audioengine()) {
2005 prompter.set_name (X_("Prompter"));
2006 prompter.set_prompt (_("Name for mix template:"));
2007 prompter.set_initial_text(session->name() + _("-template"));
2008 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
2010 switch (prompter.run()) {
2011 case RESPONSE_ACCEPT:
2012 prompter.get_result (name);
2014 if (name.length()) {
2015 session->save_template (name);
2025 ARDOUR_UI::edit_metadata ()
2027 SessionMetadataEditor dialog;
2028 dialog.set_session (session);
2029 editor->ensure_float (dialog);
2034 ARDOUR_UI::import_metadata ()
2036 SessionMetadataImporter dialog;
2037 dialog.set_session (session);
2038 editor->ensure_float (dialog);
2043 ARDOUR_UI::fontconfig_dialog ()
2046 /* X11 users will always have fontconfig info around, but new GTK-OSX users
2047 may not and it can take a while to build it. Warn them.
2050 Glib::ustring fontconfig = Glib::build_filename (Glib::get_home_dir(), ".fontconfig");
2052 if (!Glib::file_test (fontconfig, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) {
2053 MessageDialog msg (*new_session_dialog,
2054 _("Welcome to Ardour.\n\n"
2055 "The program will take a bit longer to start up\n"
2056 "while the system fonts are checked.\n\n"
2057 "This will only be done once, and you will\n"
2058 "not see this message again\n"),
2071 ARDOUR_UI::parse_cmdline_path (const Glib::ustring& cmdline_path, Glib::ustring& session_name, Glib::ustring& session_path, bool& existing_session)
2073 existing_session = false;
2075 if (Glib::file_test (cmdline_path, Glib::FILE_TEST_IS_DIR)) {
2076 session_path = cmdline_path;
2077 existing_session = true;
2078 } else if (Glib::file_test (cmdline_path, Glib::FILE_TEST_IS_REGULAR)) {
2079 session_path = Glib::path_get_dirname (string (cmdline_path));
2080 existing_session = true;
2082 /* it doesn't exist, assume the best */
2083 session_path = Glib::path_get_dirname (string (cmdline_path));
2086 session_name = basename_nosuffix (string (cmdline_path));
2090 ARDOUR_UI::load_cmdline_session (const Glib::ustring& session_name, const Glib::ustring& session_path, bool& existing_session)
2092 /* when this is called, the backend audio system must be running */
2094 /* the main idea here is to deal with the fact that a cmdline argument for the session
2095 can be interpreted in different ways - it could be a directory or a file, and before
2096 we load, we need to know both the session directory and the snapshot (statefile) within it
2097 that we are supposed to use.
2100 if (session_name.length() == 0 || session_path.length() == 0) {
2104 if (Glib::file_test (session_path, Glib::FILE_TEST_IS_DIR)) {
2106 Glib::ustring predicted_session_file;
2108 predicted_session_file = session_path;
2109 predicted_session_file += '/';
2110 predicted_session_file += session_name;
2111 predicted_session_file += ARDOUR::statefile_suffix;
2113 if (Glib::file_test (predicted_session_file, Glib::FILE_TEST_EXISTS)) {
2114 existing_session = true;
2117 } else if (Glib::file_test (session_path, Glib::FILE_TEST_EXISTS)) {
2119 if (session_path.find (ARDOUR::statefile_suffix) == session_path.length() - 7) {
2120 /* existing .ardour file */
2121 existing_session = true;
2125 existing_session = false;
2128 /* lets just try to load it */
2130 if (create_engine ()) {
2131 backend_audio_error (false, new_session_dialog);
2135 return load_session (session_path, session_name);
2139 ARDOUR_UI::ask_about_loading_existing_session (const Glib::ustring& session_path)
2141 Glib::ustring str = string_compose (_("This session\n%1\nalready exists. Do you want to open it?"), session_path);
2143 MessageDialog msg (str,
2145 Gtk::MESSAGE_WARNING,
2146 Gtk::BUTTONS_YES_NO,
2150 msg.set_name (X_("CleanupDialog"));
2151 msg.set_wmclass (X_("existing_session"), "Ardour");
2152 msg.set_position (Gtk::WIN_POS_MOUSE);
2155 switch (msg.run()) {
2164 ARDOUR_UI::build_session_from_nsd (const Glib::ustring& session_path, const Glib::ustring& session_name)
2169 AutoConnectOption iconnect;
2170 AutoConnectOption oconnect;
2174 if (Profile->get_sae()) {
2178 iconnect = AutoConnectPhysical;
2179 oconnect = AutoConnectMaster;
2180 nphysin = 0; // use all available
2181 nphysout = 0; // use all available
2185 /* get settings from advanced section of NSD */
2187 if (new_session_dialog->create_control_bus()) {
2188 cchns = (uint32_t) new_session_dialog->control_channel_count();
2193 if (new_session_dialog->create_master_bus()) {
2194 mchns = (uint32_t) new_session_dialog->master_channel_count();
2199 if (new_session_dialog->connect_inputs()) {
2200 iconnect = AutoConnectPhysical;
2202 iconnect = AutoConnectOption (0);
2205 /// @todo some minor tweaks.
2207 if (new_session_dialog->connect_outs_to_master()) {
2208 oconnect = AutoConnectMaster;
2209 } else if (new_session_dialog->connect_outs_to_physical()) {
2210 oconnect = AutoConnectPhysical;
2212 oconnect = AutoConnectOption (0);
2215 nphysin = (uint32_t) new_session_dialog->input_limit_count();
2216 nphysout = (uint32_t) new_session_dialog->output_limit_count();
2219 if (build_session (session_path,
2227 engine->frame_rate() * 60 * 5)) {
2236 ARDOUR_UI::end_loading_messages ()
2242 ARDOUR_UI::loading_message (const std::string& msg)
2245 splash->message (msg);
2250 ARDOUR_UI::idle_load (const Glib::ustring& path)
2253 if (Glib::file_test (path, Glib::FILE_TEST_IS_DIR)) {
2254 /* /path/to/foo => /path/to/foo, foo */
2255 load_session (path, basename_nosuffix (path));
2257 /* /path/to/foo/foo.ardour => /path/to/foo, foo */
2258 load_session (Glib::path_get_dirname (path), basename_nosuffix (path));
2262 ARDOUR_COMMAND_LINE::session_name = path;
2264 if (new_session_dialog) {
2267 /* make it break out of Dialog::run() and
2271 new_session_dialog->response (1);
2277 ARDOUR_UI::get_session_parameters (bool backend_audio_is_running, bool should_be_new)
2279 bool existing_session = false;
2280 Glib::ustring session_name;
2281 Glib::ustring session_path;
2282 Glib::ustring template_name;
2286 response = Gtk::RESPONSE_NONE;
2288 if (!ARDOUR_COMMAND_LINE::session_name.empty()) {
2290 parse_cmdline_path (ARDOUR_COMMAND_LINE::session_name, session_name, session_path, existing_session);
2292 /* don't ever reuse this */
2294 ARDOUR_COMMAND_LINE::session_name = string();
2296 if (existing_session && backend_audio_is_running) {
2298 /* just load the thing already */
2300 if (load_cmdline_session (session_name, session_path, existing_session) == 0) {
2305 /* make the NSD use whatever information we have */
2307 new_session_dialog->set_session_name (session_name);
2308 new_session_dialog->set_session_folder (session_path);
2311 /* loading failed, or we need the NSD for something */
2313 new_session_dialog->set_modal (false);
2314 new_session_dialog->set_position (WIN_POS_CENTER);
2315 new_session_dialog->set_current_page (0);
2316 new_session_dialog->set_existing_session (existing_session);
2317 new_session_dialog->reset_recent();
2320 new_session_dialog->set_have_engine (backend_audio_is_running);
2321 new_session_dialog->present ();
2322 end_loading_messages ();
2323 response = new_session_dialog->run ();
2325 _session_is_new = false;
2327 /* handle possible negative responses */
2331 /* sent by idle_load, meaning restart the whole process again */
2332 new_session_dialog->hide();
2333 new_session_dialog->reset();
2337 case Gtk::RESPONSE_CANCEL:
2338 case Gtk::RESPONSE_DELETE_EVENT:
2340 if (engine && engine->running()) {
2341 engine->stop (true);
2345 new_session_dialog->hide ();
2348 case Gtk::RESPONSE_NONE:
2349 /* "Clear" was pressed */
2353 fontconfig_dialog();
2355 if (!backend_audio_is_running) {
2356 int ret = new_session_dialog->engine_control.setup_engine ();
2359 } else if (ret > 0) {
2360 response = Gtk::RESPONSE_REJECT;
2365 if (create_engine ()) {
2367 backend_audio_error (!backend_audio_is_running, new_session_dialog);
2370 new_session_dialog->set_existing_session (false);
2371 new_session_dialog->set_current_page (2);
2373 response = Gtk::RESPONSE_NONE;
2377 backend_audio_is_running = true;
2379 if (response == Gtk::RESPONSE_OK) {
2381 session_name = new_session_dialog->session_name();
2383 if (session_name.empty()) {
2384 response = Gtk::RESPONSE_NONE;
2388 /* if the user mistakenly typed path information into the session filename entry,
2389 convert what they typed into a path & a name
2392 if (session_name[0] == '/' ||
2393 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
2394 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
2396 session_path = Glib::path_get_dirname (session_name);
2397 session_name = Glib::path_get_basename (session_name);
2401 session_path = new_session_dialog->session_folder();
2404 template_name = Glib::ustring();
2405 switch (new_session_dialog->which_page()) {
2407 case NewSessionDialog::OpenPage:
2408 case NewSessionDialog::EnginePage:
2412 case NewSessionDialog::NewPage: /* nominally the "new" session creator, but could be in use for an old session */
2414 should_be_new = true;
2416 //XXX This is needed because session constructor wants a
2417 //non-existant path. hopefully this will be fixed at some point.
2419 session_path = Glib::build_filename (session_path, session_name);
2421 if (Glib::file_test (session_path, Glib::FileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
2423 if (ask_about_loading_existing_session (session_path)) {
2426 response = RESPONSE_NONE;
2431 _session_is_new = true;
2433 if (new_session_dialog->use_session_template()) {
2435 template_name = new_session_dialog->session_template_name();
2439 if (build_session_from_nsd (session_path, session_name)) {
2440 response = RESPONSE_NONE;
2452 new_session_dialog->hide ();
2454 if (load_session (session_path, session_name, template_name)) {
2456 response = Gtk::RESPONSE_NONE;
2460 if (response == Gtk::RESPONSE_NONE) {
2461 new_session_dialog->set_existing_session (false);
2462 new_session_dialog->reset ();
2466 } while (response == Gtk::RESPONSE_NONE || response == Gtk::RESPONSE_REJECT);
2470 new_session_dialog->hide();
2471 new_session_dialog->reset();
2472 goto_editor_window ();
2477 ARDOUR_UI::close_session()
2479 if (!check_audioengine()) {
2483 unload_session (true);
2485 get_session_parameters (true, false);
2489 ARDOUR_UI::load_session (const Glib::ustring& path, const Glib::ustring& snap_name, Glib::ustring mix_template)
2491 Session *new_session;
2495 session_loaded = false;
2497 if (!check_audioengine()) {
2501 unload_status = unload_session ();
2503 if (unload_status < 0) {
2505 } else if (unload_status > 0) {
2510 /* if it already exists, we must have write access */
2512 if (Glib::file_test (path.c_str(), Glib::FILE_TEST_EXISTS) && ::access (path.c_str(), W_OK)) {
2513 MessageDialog msg (*editor, _("You do not have write access to this session.\n"
2514 "This prevents the session from being loaded."));
2520 loading_message (_("Please wait while Ardour loads your session"));
2523 new_session = new Session (*engine, path, snap_name, mix_template);
2526 /* this one is special */
2528 catch (AudioEngine::PortRegistrationFailure& err) {
2530 MessageDialog msg (err.what(),
2533 Gtk::BUTTONS_CLOSE);
2535 msg.set_title (_("Port Registration Error"));
2536 msg.set_secondary_text (_("Click the Close button to try again."));
2537 msg.set_position (Gtk::WIN_POS_CENTER);
2541 int response = msg.run ();
2546 case RESPONSE_CANCEL:
2556 MessageDialog msg (string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name),
2559 Gtk::BUTTONS_CLOSE);
2561 msg.set_title (_("Loading Error"));
2562 msg.set_secondary_text (_("Click the Close button to try again."));
2563 msg.set_position (Gtk::WIN_POS_CENTER);
2567 int response = msg.run ();
2572 case RESPONSE_CANCEL:
2580 connect_to_session (new_session);
2582 Config->set_current_owner (ConfigVariableBase::Interface);
2584 session_loaded = true;
2586 goto_editor_window ();
2589 session->set_clean ();
2600 ARDOUR_UI::build_session (const Glib::ustring& path, const Glib::ustring& snap_name,
2601 uint32_t control_channels,
2602 uint32_t master_channels,
2603 AutoConnectOption input_connect,
2604 AutoConnectOption output_connect,
2607 nframes_t initial_length)
2609 Session *new_session;
2612 if (!check_audioengine()) {
2616 session_loaded = false;
2618 x = unload_session ();
2626 _session_is_new = true;
2629 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
2630 control_channels, master_channels, nphysin, nphysout, initial_length);
2635 MessageDialog msg (string_compose(_("Could not create session in \"%1\""), path));
2641 connect_to_session (new_session);
2643 session_loaded = true;
2645 new_session->save_state(new_session->name());
2654 editor->show_window ();
2665 ARDOUR_UI::show_about ()
2669 about->signal_response().connect(mem_fun (*this, &ARDOUR_UI::about_signal_response) );
2676 ARDOUR_UI::hide_about ()
2679 about->get_window()->set_cursor ();
2685 ARDOUR_UI::about_signal_response(int response)
2691 ARDOUR_UI::show_splash ()
2695 splash = new Splash;
2703 splash->queue_draw ();
2704 splash->get_window()->process_updates (true);
2709 ARDOUR_UI::hide_splash ()
2717 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title, const string & msg)
2721 removed = rep.paths.size();
2724 MessageDialog msgd (*editor,
2725 _("No audio files were ready for cleanup"),
2728 (Gtk::ButtonsType)(Gtk::BUTTONS_OK) );
2729 msgd.set_secondary_text (_("If this seems suprising, \n\
2730 check for any existing snapshots.\n\
2731 These may still include regions that\n\
2732 require some unused files to continue to exist."));
2738 ArdourDialog results (_("ardour: cleanup"), true, false);
2740 struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
2741 CleanupResultsModelColumns() {
2745 Gtk::TreeModelColumn<Glib::ustring> visible_name;
2746 Gtk::TreeModelColumn<Glib::ustring> fullpath;
2750 CleanupResultsModelColumns results_columns;
2751 Glib::RefPtr<Gtk::ListStore> results_model;
2752 Gtk::TreeView results_display;
2754 results_model = ListStore::create (results_columns);
2755 results_display.set_model (results_model);
2756 results_display.append_column (list_title, results_columns.visible_name);
2758 results_display.set_name ("CleanupResultsList");
2759 results_display.set_headers_visible (true);
2760 results_display.set_headers_clickable (false);
2761 results_display.set_reorderable (false);
2763 Gtk::ScrolledWindow list_scroller;
2766 Gtk::HBox dhbox; // the hbox for the image and text
2767 Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
2768 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO, Gtk::ICON_SIZE_DIALOG));
2770 dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
2772 const string dead_sound_directory = session->session_directory().dead_sound_path().to_string();
2774 if (rep.space < 1048576.0f) {
2776 txt.set_text (string_compose (msg, removed, _("files were"), dead_sound_directory, (float) rep.space / 1024.0f, "kilo"));
2778 txt.set_text (string_compose (msg, removed, _("file was"), dead_sound_directory, (float) rep.space / 1024.0f, "kilo"));
2782 txt.set_text (string_compose (msg, removed, _("files were"), dead_sound_directory, (float) rep.space / 1048576.0f, "mega"));
2784 txt.set_text (string_compose (msg, removed, _("file was"), dead_sound_directory, (float) rep.space / 1048576.0f, "mega"));
2788 dhbox.pack_start (*dimage, true, false, 5);
2789 dhbox.pack_start (txt, true, false, 5);
2791 for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2792 TreeModel::Row row = *(results_model->append());
2793 row[results_columns.visible_name] = *i;
2794 row[results_columns.fullpath] = *i;
2797 list_scroller.add (results_display);
2798 list_scroller.set_size_request (-1, 150);
2799 list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2801 dvbox.pack_start (dhbox, true, false, 5);
2802 dvbox.pack_start (list_scroller, true, false, 5);
2803 ddhbox.pack_start (dvbox, true, false, 5);
2805 results.get_vbox()->pack_start (ddhbox, true, false, 5);
2806 results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
2807 results.set_default_response (RESPONSE_CLOSE);
2808 results.set_position (Gtk::WIN_POS_MOUSE);
2810 results_display.show();
2811 list_scroller.show();
2818 //results.get_vbox()->show();
2819 results.set_resizable (false);
2826 ARDOUR_UI::cleanup ()
2829 /* shouldn't happen: menu item is insensitive */
2834 MessageDialog checker (_("Are you sure you want to cleanup?"),
2836 Gtk::MESSAGE_QUESTION,
2837 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
2839 checker.set_secondary_text(_("Cleanup is a destructive operation.\n\
2840 ALL undo/redo information will be lost if you cleanup.\n\
2841 After cleanup, unused audio files will be moved to a \
2842 \"dead sounds\" location."));
2844 checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2845 checker.add_button (_("Clean Up"), RESPONSE_ACCEPT);
2846 checker.set_default_response (RESPONSE_CANCEL);
2848 checker.set_name (_("CleanupDialog"));
2849 checker.set_wmclass (X_("ardour_cleanup"), "Ardour");
2850 checker.set_position (Gtk::WIN_POS_MOUSE);
2852 switch (checker.run()) {
2853 case RESPONSE_ACCEPT:
2859 Session::cleanup_report rep;
2861 editor->prepare_for_cleanup ();
2863 /* do not allow flush until a session is reloaded */
2865 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
2867 act->set_sensitive (false);
2870 if (session->cleanup_sources (rep)) {
2871 editor->finish_cleanup ();
2875 editor->finish_cleanup ();
2878 display_cleanup_results (rep,
2881 The following %1 %2 not in use and \n\
2882 have been moved to:\n\
2884 Flushing the wastebasket will \n\
2885 release an additional\n\
2886 %4 %5bytes of disk space.\n"
2892 ARDOUR_UI::flush_trash ()
2895 /* shouldn't happen: menu item is insensitive */
2899 Session::cleanup_report rep;
2901 if (session->cleanup_trash_sources (rep)) {
2905 display_cleanup_results (rep,
2907 _("The following %1 %2 deleted from\n\
2909 releasing %4 %5bytes of disk space"));
2913 ARDOUR_UI::add_route (Gtk::Window* float_window)
2921 if (add_route_dialog == 0) {
2922 add_route_dialog = new AddRouteDialog;
2924 add_route_dialog->set_transient_for (*float_window);
2928 if (add_route_dialog->is_visible()) {
2929 /* we're already doing this */
2933 ResponseType r = (ResponseType) add_route_dialog->run ();
2935 add_route_dialog->hide();
2938 case RESPONSE_ACCEPT:
2945 if ((count = add_route_dialog->count()) <= 0) {
2949 uint32_t input_chan = add_route_dialog->channels ();
2950 uint32_t output_chan;
2951 string name_template = add_route_dialog->name_template ();
2952 bool track = add_route_dialog->track ();
2954 AutoConnectOption oac = Config->get_output_auto_connect();
2956 if (oac & AutoConnectMaster) {
2957 output_chan = (session->master_out() ? session->master_out()->n_inputs().n_audio() : input_chan);
2959 output_chan = input_chan;
2962 /* XXX do something with name template */
2964 if (add_route_dialog->type() == ARDOUR::DataType::MIDI) {
2966 session_add_midi_track(count);
2968 MessageDialog msg (*editor,
2969 _("Sorry, MIDI Busses are not supported at this time."));
2971 //session_add_midi_bus();
2975 session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), count);
2977 session_add_audio_bus (input_chan, output_chan, count);
2983 ARDOUR_UI::mixer_settings () const
2988 node = session->instant_xml(X_("Mixer"));
2990 node = Config->instant_xml(X_("Mixer"));
2994 node = new XMLNode (X_("Mixer"));
3001 ARDOUR_UI::editor_settings () const
3006 node = session->instant_xml(X_("Editor"));
3008 node = Config->instant_xml(X_("Editor"));
3012 if (getenv("ARDOUR_INSTANT_XML_PATH")) {
3013 node = Config->instant_xml(getenv("ARDOUR_INSTANT_XML_PATH"));
3018 node = new XMLNode (X_("Editor"));
3025 ARDOUR_UI::keyboard_settings () const
3029 node = Config->extra_xml(X_("Keyboard"));
3032 node = new XMLNode (X_("Keyboard"));
3038 ARDOUR_UI::create_xrun_marker(nframes_t where)
3040 editor->mouse_add_new_marker (where, false, true);
3044 ARDOUR_UI::halt_on_xrun_message ()
3046 MessageDialog msg (*editor,
3047 _("Recording was stopped because your system could not keep up."));
3052 ARDOUR_UI::xrun_handler(nframes_t where)
3058 ENSURE_GUI_THREAD (bind(mem_fun(*this, &ARDOUR_UI::xrun_handler), where));
3060 if (session && Config->get_create_xrun_marker() && session->actively_recording()) {
3061 create_xrun_marker(where);
3064 if (session && Config->get_stop_recording_on_xrun() && session->actively_recording()) {
3065 halt_on_xrun_message ();
3070 ARDOUR_UI::disk_overrun_handler ()
3072 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
3074 if (!have_disk_speed_dialog_displayed) {
3075 have_disk_speed_dialog_displayed = true;
3076 MessageDialog* msg = new MessageDialog (*editor, _("\
3077 The disk system on your computer\n\
3078 was not able to keep up with Ardour.\n\
3080 Specifically, it failed to write data to disk\n\
3081 quickly enough to keep up with recording.\n"));
3082 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
3088 ARDOUR_UI::disk_underrun_handler ()
3090 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
3092 if (!have_disk_speed_dialog_displayed) {
3093 have_disk_speed_dialog_displayed = true;
3094 MessageDialog* msg = new MessageDialog (*editor,
3095 _("The disk system on your computer\n\
3096 was not able to keep up with Ardour.\n\
3098 Specifically, it failed to read data from disk\n\
3099 quickly enough to keep up with playback.\n"));
3100 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
3106 ARDOUR_UI::disk_speed_dialog_gone (int ignored_response, MessageDialog* msg)
3108 have_disk_speed_dialog_displayed = false;
3113 ARDOUR_UI::session_dialog (std::string msg)
3115 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::session_dialog), msg));
3120 d = new MessageDialog (*editor, msg, false, MESSAGE_INFO, BUTTONS_OK, true);
3122 d = new MessageDialog (msg, false, MESSAGE_INFO, BUTTONS_OK, true);
3131 ARDOUR_UI::pending_state_dialog ()
3133 HBox* hbox = new HBox();
3134 Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG);
3135 ArdourDialog dialog (_("Crash Recovery"), true);
3137 This session appears to have been in\n\
3138 middle of recording when ardour or\n\
3139 the computer was shutdown.\n\
3141 Ardour can recover any captured audio for\n\
3142 you, or it can ignore it. Please decide\n\
3143 what you would like to do.\n"));
3144 image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
3145 hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
3146 hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
3147 dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
3148 dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
3149 dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
3150 dialog.set_default_response (RESPONSE_ACCEPT);
3151 dialog.set_position (WIN_POS_CENTER);
3156 switch (dialog.run ()) {
3157 case RESPONSE_ACCEPT:
3165 ARDOUR_UI::sr_mismatch_dialog (nframes_t desired, nframes_t actual)
3167 HBox* hbox = new HBox();
3168 Image* image = new Image (Stock::DIALOG_QUESTION, ICON_SIZE_DIALOG);
3169 ArdourDialog dialog (_("Sample Rate Mismatch"), true);
3170 Label message (string_compose (_("\
3171 This session was created with a sample rate of %1 Hz\n\
3173 The audioengine is currently running at %2 Hz\n"), desired, actual));
3175 image->set_alignment(ALIGN_CENTER, ALIGN_TOP);
3176 hbox->pack_start (*image, PACK_EXPAND_WIDGET, 12);
3177 hbox->pack_end (message, PACK_EXPAND_PADDING, 12);
3178 dialog.get_vbox()->pack_start(*hbox, PACK_EXPAND_PADDING, 6);
3179 dialog.add_button (_("Do not load session"), RESPONSE_REJECT);
3180 dialog.add_button (_("Load session anyway"), RESPONSE_ACCEPT);
3181 dialog.set_default_response (RESPONSE_ACCEPT);
3182 dialog.set_position (WIN_POS_CENTER);
3187 switch (dialog.run ()) {
3188 case RESPONSE_ACCEPT:
3197 ARDOUR_UI::disconnect_from_jack ()
3200 if( engine->disconnect_from_jack ()) {
3201 MessageDialog msg (*editor, _("Could not disconnect from JACK"));
3205 update_sample_rate (0);
3210 ARDOUR_UI::reconnect_to_jack ()
3213 if (engine->reconnect_to_jack ()) {
3214 MessageDialog msg (*editor, _("Could not reconnect to JACK"));
3218 update_sample_rate (0);
3223 ARDOUR_UI::use_config ()
3225 Glib::RefPtr<Action> act;
3227 switch (Config->get_native_file_data_format ()) {
3229 act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
3232 act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
3235 act = ActionManager::get_action (X_("options"), X_("FileDataFormat16bit"));
3240 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
3241 ract->set_active ();
3244 switch (Config->get_native_file_header_format ()) {
3246 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
3249 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
3252 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
3255 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
3258 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
3261 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatCAF"));
3264 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatAIFF"));
3269 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
3270 ract->set_active ();
3273 XMLNode* node = Config->extra_xml (X_("TransportControllables"));
3275 set_transport_controllable_state (*node);
3280 ARDOUR_UI::update_transport_clocks (nframes_t pos)
3282 if (Config->get_primary_clock_delta_edit_cursor()) {
3283 primary_clock.set (pos, false, editor->get_preferred_edit_position(), 1);
3285 primary_clock.set (pos, 0, true);
3288 if (Config->get_secondary_clock_delta_edit_cursor()) {
3289 secondary_clock.set (pos, false, editor->get_preferred_edit_position(), 2);
3291 secondary_clock.set (pos);
3294 if (big_clock_window) {
3295 big_clock.set (pos);
3300 ARDOUR_UI::record_state_changed ()
3302 ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::record_state_changed));
3304 if (!session || !big_clock_window) {
3305 /* why bother - the clock isn't visible */
3309 switch (session->record_status()) {
3310 case Session::Recording:
3311 big_clock.set_widget_name ("BigClockRecording");
3314 big_clock.set_widget_name ("BigClockNonRecording");
3320 ARDOUR_UI::first_idle ()
3323 session->allow_auto_play (true);
3327 editor->first_idle();
3330 Keyboard::set_can_save_keybindings (true);
3335 ARDOUR_UI::store_clock_modes ()
3337 XMLNode* node = new XMLNode(X_("ClockModes"));
3339 for (vector<AudioClock*>::iterator x = AudioClock::clocks.begin(); x != AudioClock::clocks.end(); ++x) {
3340 node->add_property ((*x)->name().c_str(), enum_2_string ((*x)->mode()));
3343 session->add_extra_xml (*node);
3344 session->set_dirty ();
3349 ARDOUR_UI::TransportControllable::TransportControllable (std::string name, ARDOUR_UI& u, ToggleType tp)
3350 : Controllable (name), ui (u), type(tp)
3356 ARDOUR_UI::TransportControllable::set_value (float val)
3358 if (type == ShuttleControl) {
3365 fract = -((0.5f - val)/0.5f);
3367 fract = ((val - 0.5f)/0.5f);
3371 ui.set_shuttle_fract (fract);
3376 /* do nothing: these are radio-style actions */
3380 const char *action = 0;
3384 action = X_("Roll");
3387 action = X_("Stop");
3390 action = X_("Goto Start");
3393 action = X_("Goto End");
3396 action = X_("Loop");
3399 action = X_("Play Selection");
3402 action = X_("Record");
3412 Glib::RefPtr<Action> act = ActionManager::get_action ("Transport", action);
3420 ARDOUR_UI::TransportControllable::get_value (void) const
3439 case ShuttleControl:
3449 ARDOUR_UI::TransportControllable::set_id (const string& str)
3455 ARDOUR_UI::setup_profile ()
3457 if (gdk_screen_width() < 1200) {
3458 Profile->set_small_screen ();
3462 if (getenv ("ARDOUR_SAE")) {
3463 Profile->set_sae ();
3464 Profile->set_single_package ();