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.
31 #include <sys/resource.h>
33 #include <gtkmm/messagedialog.h>
34 #include <gtkmm/accelmap.h>
36 #include <pbd/error.h>
37 #include <pbd/compose.h>
38 #include <pbd/pathscanner.h>
39 #include <pbd/failed_constructor.h>
40 #include <pbd/enumwriter.h>
41 #include <pbd/stacktrace.h>
42 #include <gtkmm2ext/gtk_ui.h>
43 #include <gtkmm2ext/utils.h>
44 #include <gtkmm2ext/click_box.h>
45 #include <gtkmm2ext/fastmeter.h>
46 #include <gtkmm2ext/stop_signal.h>
47 #include <gtkmm2ext/popup.h>
49 #include <midi++/port.h>
50 #include <midi++/mmc.h>
52 #include <ardour/ardour.h>
53 #include <ardour/session_route.h>
54 #include <ardour/port.h>
55 #include <ardour/audioengine.h>
56 #include <ardour/playlist.h>
57 #include <ardour/utils.h>
58 #include <ardour/audio_diskstream.h>
59 #include <ardour/audiofilesource.h>
60 #include <ardour/recent_sessions.h>
61 #include <ardour/port.h>
62 #include <ardour/audio_track.h>
65 #include "ardour_ui.h"
66 #include "public_editor.h"
67 #include "audio_clock.h"
72 #include "keyboard_target.h"
73 #include "add_route_dialog.h"
74 #include "new_session_dialog.h"
77 #include "gui_thread.h"
78 #include "color_manager.h"
82 using namespace ARDOUR;
84 using namespace Gtkmm2ext;
88 ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
90 sigc::signal<void,bool> ARDOUR_UI::Blink;
91 sigc::signal<void> ARDOUR_UI::RapidScreenUpdate;
92 sigc::signal<void> ARDOUR_UI::MidRapidScreenUpdate;
93 sigc::signal<void> ARDOUR_UI::SuperRapidScreenUpdate;
94 sigc::signal<void,nframes_t> ARDOUR_UI::Clock;
96 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
98 : Gtkmm2ext::UI ("ardour", argcp, argvp, rcfile),
100 primary_clock (X_("primary"), false, X_("TransportClockDisplay"), true, false, true),
101 secondary_clock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, false, true),
102 preroll_clock (X_("preroll"), false, X_("PreRollClock"), true, true),
103 postroll_clock (X_("postroll"), false, X_("PostRollClock"), true, true),
107 adjuster_table (3, 3),
111 preroll_button (_("pre\nroll")),
112 postroll_button (_("post\nroll")),
116 big_clock (X_("bigclock"), false, "BigClockNonRecording", false, false, true),
120 time_master_button (_("time\nmaster")),
122 shuttle_units_button (_("% ")),
124 punch_in_button (_("Punch In")),
125 punch_out_button (_("Punch Out")),
126 auto_return_button (_("Auto Return")),
127 auto_play_button (_("Autuo Play")),
128 auto_input_button (_("Auto Input")),
129 click_button (_("Click")),
130 auditioning_alert_button (_("AUDITION")),
131 solo_alert_button (_("SOLO")),
134 using namespace Gtk::Menu_Helpers;
140 if (theArdourUI == 0) {
146 color_manager = new ColorManager();
148 std::string color_file = ARDOUR::find_config_file("ardour.colors");
150 color_manager->load (color_file);
155 _session_is_new = false;
156 big_clock_window = 0;
157 session_selector_window = 0;
158 last_key_press_time = 0;
159 connection_editor = 0;
160 add_route_dialog = 0;
164 open_session_selector = 0;
165 have_configure_timeout = false;
166 have_disk_overrun_displayed = false;
167 have_disk_underrun_displayed = false;
168 _will_create_new_session_automatically = false;
169 session_loaded = false;
170 last_speed_displayed = -1.0f;
171 keybindings_path = ARDOUR::find_config_file ("ardour.bindings");
173 can_save_keybindings = false;
174 Glib::signal_idle().connect (mem_fun (*this, &ARDOUR_UI::first_idle));
176 last_configure_time.tv_sec = 0;
177 last_configure_time.tv_usec = 0;
179 shuttle_grabbed = false;
181 shuttle_max_speed = 8.0f;
183 shuttle_style_menu = 0;
184 shuttle_unit_menu = 0;
186 gettimeofday (&last_peak_grab, 0);
187 gettimeofday (&last_shuttle_request, 0);
189 ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
190 ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
192 /* handle pending state with a dialog */
194 ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
196 /* have to wait for AudioEngine and Configuration before proceeding */
200 ARDOUR_UI::set_engine (AudioEngine& e)
204 engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
205 engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
206 engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
207 engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
209 ActionManager::init ();
210 new_session_dialog = new NewSessionDialog();
214 keyboard = new Keyboard;
216 if (setup_windows ()) {
217 throw failed_constructor ();
220 if (GTK_ARDOUR::show_key_actions) {
221 vector<string> names;
222 vector<string> paths;
224 vector<AccelKey> bindings;
226 ActionManager::get_all_actions (names, paths, keys, bindings);
228 vector<string>::iterator n;
229 vector<string>::iterator k;
230 for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) {
231 cerr << "Action: " << (*n) << " bound to " << (*k) << endl;
237 /* start with timecode, metering enabled
240 blink_timeout_tag = -1;
242 /* the global configuration object is now valid */
246 /* this being a GUI and all, we want peakfiles */
248 AudioFileSource::set_build_peakfiles (true);
249 AudioFileSource::set_build_missing_peakfiles (true);
251 if (AudioSource::start_peak_thread ()) {
252 throw failed_constructor();
255 /* set default clock modes */
257 primary_clock.set_mode (AudioClock::SMPTE);
258 secondary_clock.set_mode (AudioClock::BBT);
260 /* start the time-of-day-clock */
262 update_wall_clock ();
263 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
265 update_disk_space ();
267 update_sample_rate (engine->frame_rate());
269 starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
270 stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
273 ARDOUR_UI::~ARDOUR_UI ()
275 save_ardour_state ();
289 if (add_route_dialog) {
290 delete add_route_dialog;
293 AudioSource::stop_peak_thread ();
297 ARDOUR_UI::configure_timeout ()
302 if (last_configure_time.tv_sec == 0 && last_configure_time.tv_usec == 0) {
303 /* no configure events yet */
307 gettimeofday (&now, 0);
308 timersub (&now, &last_configure_time, &diff);
310 /* force a gap of 0.5 seconds since the last configure event
313 if (diff.tv_sec == 0 && diff.tv_usec < 500000) {
316 have_configure_timeout = false;
317 save_ardour_state ();
323 ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
325 if (have_configure_timeout) {
326 gettimeofday (&last_configure_time, 0);
328 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
329 have_configure_timeout = true;
336 ARDOUR_UI::save_ardour_state ()
338 if (!keyboard || !mixer || !editor) {
342 /* XXX this is all a bit dubious. add_extra_xml() uses
343 a different lifetime model from add_instant_xml().
346 XMLNode* node = new XMLNode (keyboard->get_state());
347 Config->add_extra_xml (*node);
348 Config->save_state();
350 XMLNode enode(static_cast<Stateful*>(editor)->get_state());
351 XMLNode mnode(mixer->get_state());
354 session->add_instant_xml (enode, session->path());
355 session->add_instant_xml (mnode, session->path());
357 Config->add_instant_xml (enode, get_user_ardour_path());
358 Config->add_instant_xml (mnode, get_user_ardour_path());
365 ARDOUR_UI::startup ()
367 if (engine->is_realtime()) {
369 struct rlimit limits;
371 if (getrlimit (RLIMIT_MEMLOCK, &limits)) {
375 if (limits.rlim_cur != RLIM_INFINITY) {
376 MessageDialog msg (_("WARNING: Your system has a limit for maximum amount of locked memory. "
377 "This might cause Ardour to run out of memory before your system "
378 "runs out of memory. \n\n"
379 "You can view the memory limit with 'ulimit -l', "
380 "and it is normally controlled by /etc/security/limits.conf"));
382 editor->ensure_float (msg);
391 if (session && session->dirty()) {
392 switch (ask_about_saving_session(_("quit"))) {
397 /* use the default name */
398 if (save_state_canfail ("")) {
399 /* failed - don't quit */
400 MessageDialog msg (*editor,
402 Ardour was unable to save your session.\n\n\
403 If you still wish to quit, please use the\n\n\
404 \"Just quit\" option."));
415 session->set_deletion_in_progress ();
418 Config->save_state();
423 ARDOUR_UI::ask_about_saving_session (const string & what)
425 ArdourDialog window (_("ardour: save session?"));
426 Gtk::HBox dhbox; // the hbox for the image and text
427 Gtk::Label prompt_label;
428 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_WARNING, Gtk::ICON_SIZE_DIALOG));
432 msg = string_compose(_("Don't %1"), what);
433 window.add_button (msg, RESPONSE_REJECT);
434 msg = string_compose(_("Just %1"), what);
435 window.add_button (msg, RESPONSE_APPLY);
436 msg = string_compose(_("Save and %1"), what);
437 window.add_button (msg, RESPONSE_ACCEPT);
439 window.set_default_response (RESPONSE_ACCEPT);
441 Gtk::Button noquit_button (msg);
442 noquit_button.set_name ("EditorGTKButton");
447 if (session->snap_name() == session->name()) {
450 type = _("snapshot");
452 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?"),
453 type, session->snap_name());
455 prompt_label.set_text (prompt);
456 prompt_label.set_name (X_("PrompterLabel"));
457 prompt_label.set_alignment(ALIGN_LEFT, ALIGN_TOP);
459 dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP)
461 dhbox.set_homogeneous (false);
462 dhbox.pack_start (*dimage, false, false, 5);
463 dhbox.pack_start (prompt_label, true, false, 5);
464 window.get_vbox()->pack_start (dhbox);
466 window.set_name (_("Prompter"));
467 window.set_position (Gtk::WIN_POS_MOUSE);
468 window.set_modal (true);
469 window.set_resizable (false);
472 save_the_session = 0;
474 window.set_keep_above (true);
477 ResponseType r = (ResponseType) window.run();
482 case RESPONSE_ACCEPT: // save and get out of here
484 case RESPONSE_APPLY: // get out of here
494 ARDOUR_UI::every_second ()
497 update_buffer_load ();
498 update_disk_space ();
503 ARDOUR_UI::every_point_one_seconds ()
505 update_speed_display ();
506 RapidScreenUpdate(); /* EMIT_SIGNAL */
511 ARDOUR_UI::every_point_oh_five_seconds ()
513 MidRapidScreenUpdate(); /* EMIT_SIGNAL */
518 ARDOUR_UI::every_point_zero_one_seconds ()
520 SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
525 ARDOUR_UI::update_sample_rate (nframes_t ignored)
529 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
531 if (!engine->connected()) {
533 snprintf (buf, sizeof (buf), _("disconnected"));
537 nframes_t rate = engine->frame_rate();
539 if (fmod (rate, 1000.0) != 0.0) {
540 snprintf (buf, sizeof (buf), _("%.1f kHz / %4.1f msecs"),
541 (float) rate/1000.0f,
542 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
544 snprintf (buf, sizeof (buf), _("%u kHz / %4.1f msecs"),
546 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
550 sample_rate_label.set_text (buf);
554 ARDOUR_UI::update_cpu_load ()
557 snprintf (buf, sizeof (buf), _("DSP: %.1f%%"), engine->get_cpu_load());
558 cpu_load_label.set_text (buf);
562 ARDOUR_UI::update_buffer_load ()
567 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"),
568 session->playback_load(), session->capture_load());
569 buffer_load_label.set_text (buf);
571 buffer_load_label.set_text ("");
576 ARDOUR_UI::count_recenabled_streams (Route& route)
578 Track* track = dynamic_cast<Track*>(&route);
579 if (track && track->diskstream()->record_enabled()) {
580 rec_enabled_streams += track->n_inputs();
585 ARDOUR_UI::update_disk_space()
591 nframes_t frames = session->available_capture_duration();
594 if (frames == max_frames) {
595 strcpy (buf, _("Disk: 24hrs+"));
600 nframes_t fr = session->frame_rate();
602 rec_enabled_streams = 0;
603 session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
605 if (rec_enabled_streams) {
606 frames /= rec_enabled_streams;
609 hrs = frames / (fr * 3600);
610 frames -= hrs * fr * 3600;
611 mins = frames / (fr * 60);
612 frames -= mins * fr * 60;
615 snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs);
618 disk_space_label.set_text (buf);
622 ARDOUR_UI::update_wall_clock ()
629 tm_now = localtime (&now);
631 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
632 wall_clock_label.set_text (buf);
637 ARDOUR_UI::control_methods_adjusted ()
642 which_method = (int) online_control_button->adjustment.get_value();
643 switch (which_method) {
645 allow_mmc_and_local ();
654 fatal << _("programming error: impossible control method") << endmsg;
660 ARDOUR_UI::mmc_device_id_adjusted ()
665 int dev_id = (int) mmc_id_button->adjustment.get_value();
666 mmc->set_device_id (dev_id);
672 ARDOUR_UI::session_menu (GdkEventButton *ev)
674 session_popup_menu->popup (0, 0);
679 ARDOUR_UI::redisplay_recent_sessions ()
681 vector<string *> *sessions;
682 vector<string *>::iterator i;
683 RecentSessionsSorter cmp;
685 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
686 recent_session_model->clear ();
689 ARDOUR::read_recent_sessions (rs);
692 recent_session_display.set_model (recent_session_model);
696 /* sort them alphabetically */
697 sort (rs.begin(), rs.end(), cmp);
698 sessions = new vector<string*>;
700 for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
701 sessions->push_back (new string ((*i).second));
704 for (i = sessions->begin(); i != sessions->end(); ++i) {
706 vector<string*>* states;
707 vector<const gchar*> item;
708 string fullpath = *(*i);
710 /* remove any trailing / */
712 if (fullpath[fullpath.length()-1] == '/') {
713 fullpath = fullpath.substr (0, fullpath.length()-1);
716 /* now get available states for this session */
718 if ((states = Session::possible_states (fullpath)) == 0) {
723 TreeModel::Row row = *(recent_session_model->append());
725 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
726 row[recent_session_columns.fullpath] = fullpath;
728 if (states->size() > 1) {
730 /* add the children */
732 for (vector<string*>::iterator i2 = states->begin(); i2 != states->end(); ++i2) {
734 TreeModel::Row child_row = *(recent_session_model->append (row.children()));
736 child_row[recent_session_columns.visible_name] = **i2;
737 child_row[recent_session_columns.fullpath] = fullpath;
746 recent_session_display.set_model (recent_session_model);
751 ARDOUR_UI::build_session_selector ()
753 session_selector_window = new ArdourDialog ("session selector");
755 Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
757 session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
758 session_selector_window->add_button (Stock::OPEN, RESPONSE_ACCEPT);
759 session_selector_window->set_default_response (RESPONSE_ACCEPT);
760 recent_session_model = TreeStore::create (recent_session_columns);
761 recent_session_display.set_model (recent_session_model);
762 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
763 recent_session_display.set_headers_visible (false);
764 recent_session_display.get_selection()->set_mode (SELECTION_SINGLE);
766 recent_session_display.signal_row_activated().connect (mem_fun (*this, &ARDOUR_UI::recent_session_row_activated));
768 scroller->add (recent_session_display);
769 scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
771 session_selector_window->set_name ("SessionSelectorWindow");
772 session_selector_window->set_size_request (200, 400);
773 session_selector_window->get_vbox()->pack_start (*scroller);
774 session_selector_window->show_all_children();
778 ARDOUR_UI::recent_session_row_activated (const TreePath& path, TreeViewColumn* col)
780 session_selector_window->response (RESPONSE_ACCEPT);
784 ARDOUR_UI::open_recent_session ()
786 /* popup selector window */
788 if (session_selector_window == 0) {
789 build_session_selector ();
792 redisplay_recent_sessions ();
794 ResponseType r = (ResponseType) session_selector_window->run ();
796 session_selector_window->hide();
799 case RESPONSE_ACCEPT:
805 Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
807 if (i == recent_session_model->children().end()) {
811 Glib::ustring path = (*i)[recent_session_columns.fullpath];
812 Glib::ustring state = (*i)[recent_session_columns.visible_name];
814 _session_is_new = false;
816 load_session (path, state);
820 ARDOUR_UI::filter_ardour_session_dirs (const FileFilter::Info& info)
824 if (stat (info.filename.c_str(), &statbuf) != 0) {
828 if (!S_ISDIR(statbuf.st_mode)) {
834 string session_file = info.filename;
836 session_file += Glib::path_get_basename (info.filename);
837 session_file += ".ardour";
839 if (stat (session_file.c_str(), &statbuf) != 0) {
843 return S_ISREG (statbuf.st_mode);
847 ARDOUR_UI::open_session ()
849 /* popup selector window */
851 if (open_session_selector == 0) {
853 /* ardour sessions are folders */
855 open_session_selector = new Gtk::FileChooserDialog (_("open session"), FILE_CHOOSER_ACTION_OPEN);
856 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
857 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
859 FileFilter session_filter;
860 session_filter.add_pattern ("*.ardour");
861 session_filter.set_name (_("Ardour sessions"));
862 open_session_selector->add_filter (session_filter);
863 open_session_selector->set_filter (session_filter);
866 int response = open_session_selector->run();
867 open_session_selector->hide ();
870 case RESPONSE_ACCEPT:
873 open_session_selector->hide();
877 open_session_selector->hide();
878 string session_path = open_session_selector->get_filename();
882 if (session_path.length() > 0) {
883 if (Session::find_session (session_path, path, name, isnew) == 0) {
884 _session_is_new = isnew;
885 load_session (path, name);
892 ARDOUR_UI::session_add_midi_track ()
894 cerr << _("Patience is a virtue.\n");
898 ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, uint32_t how_many)
900 list<boost::shared_ptr<AudioTrack> > tracks;
901 Session::RouteList routes;
904 warning << _("You cannot add a track or bus without a session already loaded.") << endmsg;
910 tracks = session->new_audio_track (input_channels, output_channels, mode, how_many);
912 if (tracks.size() != how_many) {
914 error << _("could not create a new audio track") << endmsg;
916 error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
922 routes = session->new_audio_route (input_channels, output_channels, how_many);
924 if (routes.size() != how_many) {
926 error << _("could not create a new audio track") << endmsg;
928 error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
934 if (need_control_room_outs) {
940 route->set_stereo_control_outs (control_lr_channels);
941 route->control_outs()->set_stereo_pan (pans, this);
943 #endif /* CONTROLOUTS */
947 MessageDialog msg (*editor,
948 _("There are insufficient JACK ports available\n\
949 to create a new track or bus.\n\
950 You should save Ardour, exit and\n\
951 restart JACK with more ports."));
957 ARDOUR_UI::do_transport_locate (nframes_t new_position)
959 nframes_t _preroll = 0;
962 // XXX CONFIG_CHANGE FIX - requires AnyTime handling
963 // _preroll = session->convert_to_frames_at (new_position, Config->get_preroll());
965 if (new_position > _preroll) {
966 new_position -= _preroll;
971 session->request_locate (new_position);
976 ARDOUR_UI::transport_goto_start ()
979 session->goto_start();
982 /* force displayed area in editor to start no matter
983 what "follow playhead" setting is.
987 editor->reset_x_origin (session->current_start_frame());
993 ARDOUR_UI::transport_goto_zero ()
996 session->request_locate (0);
999 /* force displayed area in editor to start no matter
1000 what "follow playhead" setting is.
1004 editor->reset_x_origin (0);
1010 ARDOUR_UI::transport_goto_end ()
1013 nframes_t frame = session->current_end_frame();
1014 session->request_locate (frame);
1016 /* force displayed area in editor to start no matter
1017 what "follow playhead" setting is.
1021 editor->reset_x_origin (frame);
1027 ARDOUR_UI::transport_stop ()
1033 if (session->is_auditioning()) {
1034 session->cancel_audition ();
1038 if (session->get_play_loop ()) {
1039 session->request_play_loop (false);
1042 session->request_stop ();
1046 ARDOUR_UI::transport_stop_and_forget_capture ()
1049 session->request_stop (true);
1054 ARDOUR_UI::remove_last_capture()
1057 editor->remove_last_capture();
1062 ARDOUR_UI::transport_record ()
1065 switch (session->record_status()) {
1066 case Session::Disabled:
1067 if (session->ntracks() == 0) {
1068 MessageDialog msg (*editor, _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu."));
1072 session->maybe_enable_record ();
1074 case Session::Recording:
1075 case Session::Enabled:
1076 session->disable_record (true);
1082 ARDOUR_UI::transport_roll ()
1090 rolling = session->transport_rolling ();
1092 if (session->get_play_loop()) {
1093 session->request_play_loop (false);
1094 auto_loop_button.set_active (false);
1095 roll_button.set_active (true);
1096 } else if (session->get_play_range ()) {
1097 session->request_play_range (false);
1098 play_selection_button.set_active (false);
1099 } else if (rolling) {
1100 session->request_locate (session->last_transport_start(), true);
1103 session->request_transport_speed (1.0f);
1107 ARDOUR_UI::transport_loop()
1110 if (session->get_play_loop()) {
1111 if (session->transport_rolling()) {
1112 Location * looploc = session->locations()->auto_loop_location();
1114 session->request_locate (looploc->start(), true);
1119 session->request_play_loop (true);
1125 ARDOUR_UI::transport_play_selection ()
1131 if (!session->get_play_range()) {
1132 session->request_stop ();
1135 editor->play_selection ();
1139 ARDOUR_UI::transport_rewind (int option)
1141 float current_transport_speed;
1144 current_transport_speed = session->transport_speed();
1146 if (current_transport_speed >= 0.0f) {
1149 session->request_transport_speed (-1.0f);
1152 session->request_transport_speed (-4.0f);
1155 session->request_transport_speed (-0.5f);
1160 session->request_transport_speed (current_transport_speed * 1.5f);
1166 ARDOUR_UI::transport_forward (int option)
1168 float current_transport_speed;
1171 current_transport_speed = session->transport_speed();
1173 if (current_transport_speed <= 0.0f) {
1176 session->request_transport_speed (1.0f);
1179 session->request_transport_speed (4.0f);
1182 session->request_transport_speed (0.5f);
1187 session->request_transport_speed (current_transport_speed * 1.5f);
1193 ARDOUR_UI::toggle_record_enable (uint32_t dstream)
1199 boost::shared_ptr<Route> r;
1201 if ((r = session->route_by_remote_id (dstream)) != 0) {
1205 if ((t = dynamic_cast<Track*>(r.get())) != 0) {
1206 t->diskstream()->set_record_enabled (!t->diskstream()->record_enabled());
1215 ARDOUR_UI::queue_transport_change ()
1217 Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
1221 ARDOUR_UI::map_transport_state ()
1223 float sp = session->transport_speed();
1226 transport_rolling ();
1227 } else if (sp < 0.0f) {
1228 transport_rewinding ();
1229 } else if (sp > 0.0f) {
1230 transport_forwarding ();
1232 transport_stopped ();
1237 ARDOUR_UI::allow_local_only ()
1243 ARDOUR_UI::allow_mmc_only ()
1249 ARDOUR_UI::allow_mmc_and_local ()
1255 ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg)
1257 snprintf (buf, sizeof(buf), "%s", ((GlobalClickBox *) arg)->strings[
1258 (int) adj.get_value()].c_str());
1262 ARDOUR_UI::engine_stopped ()
1264 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
1265 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1266 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1270 ARDOUR_UI::engine_running ()
1272 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
1273 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true);
1274 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
1276 Glib::RefPtr<Action> action;
1277 char* action_name = 0;
1279 switch (engine->frames_per_cycle()) {
1281 action_name = X_("JACKLatency32");
1284 action_name = X_("JACKLatency64");
1287 action_name = X_("JACKLatency128");
1290 action_name = X_("JACKLatency512");
1293 action_name = X_("JACKLatency1024");
1296 action_name = X_("JACKLatency2048");
1299 action_name = X_("JACKLatency4096");
1302 action_name = X_("JACKLatency8192");
1305 /* XXX can we do anything useful ? */
1311 action = ActionManager::get_action (X_("JACK"), action_name);
1314 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic (action);
1315 ract->set_active ();
1321 ARDOUR_UI::engine_halted ()
1323 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
1325 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1326 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1328 update_sample_rate (0);
1330 MessageDialog msg (*editor,
1332 JACK has either been shutdown or it\n\
1333 disconnected Ardour because Ardour\n\
1334 was not fast enough. You can save the\n\
1335 session and/or try to reconnect to JACK ."));
1340 ARDOUR_UI::do_engine_start ()
1348 error << _("Unable to start the session running")
1358 ARDOUR_UI::start_engine ()
1360 if (do_engine_start () == 0) {
1361 if (session && _session_is_new) {
1362 /* we need to retain initial visual
1363 settings for a new session
1365 session->save_state ("");
1373 ARDOUR_UI::update_clocks ()
1375 if (!editor || !editor->dragging_playhead()) {
1376 Clock (session->audible_frame()); /* EMIT_SIGNAL */
1381 ARDOUR_UI::start_clocking ()
1383 clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
1387 ARDOUR_UI::stop_clocking ()
1389 clock_signal_connection.disconnect ();
1393 ARDOUR_UI::toggle_clocking ()
1396 if (clock_button.get_active()) {
1405 ARDOUR_UI::_blink (void *arg)
1408 ((ARDOUR_UI *) arg)->blink ();
1415 Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
1419 ARDOUR_UI::start_blinking ()
1421 /* Start the blink signal. Everybody with a blinking widget
1422 uses Blink to drive the widget's state.
1425 if (blink_timeout_tag < 0) {
1427 blink_timeout_tag = g_timeout_add (240, _blink, this);
1432 ARDOUR_UI::stop_blinking ()
1434 if (blink_timeout_tag >= 0) {
1435 g_source_remove (blink_timeout_tag);
1436 blink_timeout_tag = -1;
1441 ARDOUR_UI::name_io_setup (AudioEngine& engine,
1447 if (io.n_inputs() == 0) {
1452 /* XXX we're not handling multiple ports yet. */
1454 const char **connections = io.input(0)->get_connections();
1456 if (connections == 0 || connections[0] == '\0') {
1459 buf = connections[0];
1466 if (io.n_outputs() == 0) {
1471 /* XXX we're not handling multiple ports yet. */
1473 const char **connections = io.output(0)->get_connections();
1475 if (connections == 0 || connections[0] == '\0') {
1478 buf = connections[0];
1486 ARDOUR_UI::snapshot_session ()
1488 ArdourPrompter prompter (true);
1492 struct tm local_time;
1495 localtime_r (&n, &local_time);
1496 strftime (timebuf, sizeof(timebuf), "%FT%T", &local_time);
1498 prompter.set_name ("Prompter");
1499 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1500 prompter.set_prompt (_("Name of New Snapshot"));
1501 prompter.set_initial_text (timebuf);
1503 switch (prompter.run()) {
1504 case RESPONSE_ACCEPT:
1505 prompter.get_result (snapname);
1506 if (snapname.length()){
1507 save_state (snapname);
1517 ARDOUR_UI::save_state (const string & name)
1519 (void) save_state_canfail (name);
1523 ARDOUR_UI::save_state_canfail (string name)
1528 if (name.length() == 0) {
1529 name = session->snap_name();
1532 if ((ret = session->save_state (name)) != 0) {
1536 save_ardour_state (); /* XXX cannot fail? yeah, right ... */
1541 ARDOUR_UI::restore_state (string name)
1544 if (name.length() == 0) {
1545 name = session->name();
1547 session->restore_state (name);
1552 ARDOUR_UI::primary_clock_value_changed ()
1555 session->request_locate (primary_clock.current_time ());
1560 ARDOUR_UI::secondary_clock_value_changed ()
1563 session->request_locate (secondary_clock.current_time ());
1568 ARDOUR_UI::rec_enable_button_blink (bool onoff, AudioDiskstream *dstream, Widget *w)
1570 if (session && dstream && dstream->record_enabled()) {
1572 Session::RecordState rs;
1574 rs = session->record_status ();
1577 case Session::Disabled:
1578 case Session::Enabled:
1579 if (w->get_state() != STATE_SELECTED) {
1580 w->set_state (STATE_SELECTED);
1584 case Session::Recording:
1585 if (w->get_state() != STATE_ACTIVE) {
1586 w->set_state (STATE_ACTIVE);
1592 if (w->get_state() != STATE_NORMAL) {
1593 w->set_state (STATE_NORMAL);
1599 ARDOUR_UI::transport_rec_enable_blink (bool onoff)
1605 switch (session->record_status()) {
1606 case Session::Enabled:
1608 rec_button.set_state (1);
1610 rec_button.set_state (0);
1614 case Session::Recording:
1615 rec_button.set_state (2);
1619 rec_button.set_state (0);
1625 ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
1633 ARDOUR_UI::start_keyboard_prefix ()
1635 keyboard->start_prefix();
1639 ARDOUR_UI::save_template ()
1642 ArdourPrompter prompter (true);
1645 prompter.set_name (X_("Prompter"));
1646 prompter.set_prompt (_("Name for mix template:"));
1647 prompter.set_initial_text(session->name() + _("-template"));
1648 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1650 switch (prompter.run()) {
1651 case RESPONSE_ACCEPT:
1652 prompter.get_result (name);
1654 if (name.length()) {
1655 session->save_template (name);
1665 ARDOUR_UI::new_session (std::string predetermined_path)
1667 string session_name;
1668 string session_path;
1670 int response = Gtk::RESPONSE_NONE;
1672 new_session_dialog->set_modal(true);
1673 new_session_dialog->set_name (predetermined_path);
1674 new_session_dialog->reset_recent();
1675 new_session_dialog->show();
1678 response = new_session_dialog->run ();
1680 _session_is_new = false;
1682 if (response == Gtk::RESPONSE_CANCEL || response == Gtk::RESPONSE_DELETE_EVENT) {
1687 new_session_dialog->hide ();
1690 } else if (response == Gtk::RESPONSE_NONE) {
1692 /* Clear was pressed */
1693 new_session_dialog->reset();
1695 } else if (response == Gtk::RESPONSE_YES) {
1697 /* YES == OPEN, but there's no enum for that */
1699 session_name = new_session_dialog->session_name();
1701 if (session_name.empty()) {
1702 response = Gtk::RESPONSE_NONE;
1706 if (session_name[0] == '/' ||
1707 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1708 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1709 load_session (Glib::path_get_dirname (session_name), session_name);
1711 session_path = new_session_dialog->session_folder();
1712 load_session (session_path, session_name);
1715 } else if (response == Gtk::RESPONSE_OK) {
1717 session_name = new_session_dialog->session_name();
1719 if (new_session_dialog->get_current_page() == 1) {
1721 /* XXX this is a bit of a hack..
1722 i really want the new sesion dialog to return RESPONSE_YES
1723 if we're on page 1 (the load page)
1724 Unfortunately i can't see how atm..
1727 if (session_name.empty()) {
1728 response = Gtk::RESPONSE_NONE;
1732 if (session_name[0] == '/' ||
1733 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1734 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1735 load_session (Glib::path_get_dirname (session_name), session_name);
1737 session_path = new_session_dialog->session_folder();
1738 load_session (session_path, session_name);
1743 if (session_name.empty()) {
1744 response = Gtk::RESPONSE_NONE;
1748 if (session_name[0] == '/' ||
1749 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1750 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1752 session_path = Glib::path_get_dirname (session_name);
1753 session_name = Glib::path_get_basename (session_name);
1757 session_path = new_session_dialog->session_folder();
1761 //XXX This is needed because session constructor wants a
1762 //non-existant path. hopefully this will be fixed at some point.
1764 session_path = Glib::build_filename (session_path, session_name);
1766 if (g_file_test (session_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
1768 Glib::ustring str = string_compose (_("This session\n%1\nalready exists. Do you want to open it?"), session_path);
1770 MessageDialog msg (str,
1772 Gtk::MESSAGE_WARNING,
1773 Gtk::BUTTONS_YES_NO,
1777 msg.set_name (X_("CleanupDialog"));
1778 msg.set_wmclass (X_("existing_session"), "Ardour");
1779 msg.set_position (Gtk::WIN_POS_MOUSE);
1781 switch (msg.run()) {
1783 load_session (session_path, session_name);
1787 response = RESPONSE_NONE;
1788 new_session_dialog->reset ();
1793 _session_is_new = true;
1795 std::string template_name = new_session_dialog->session_template_name();
1797 if (new_session_dialog->use_session_template()) {
1799 load_session (session_path, session_name, &template_name);
1805 AutoConnectOption iconnect;
1806 AutoConnectOption oconnect;
1808 if (new_session_dialog->create_control_bus()) {
1809 cchns = (uint32_t) new_session_dialog->control_channel_count();
1814 if (new_session_dialog->create_master_bus()) {
1815 mchns = (uint32_t) new_session_dialog->master_channel_count();
1820 if (new_session_dialog->connect_inputs()) {
1821 iconnect = AutoConnectPhysical;
1823 iconnect = AutoConnectOption (0);
1826 /// @todo some minor tweaks.
1828 if (new_session_dialog->connect_outs_to_master()) {
1829 oconnect = AutoConnectMaster;
1830 } else if (new_session_dialog->connect_outs_to_physical()) {
1831 oconnect = AutoConnectPhysical;
1833 oconnect = AutoConnectOption (0);
1836 uint32_t nphysin = (uint32_t) new_session_dialog->input_limit_count();
1837 uint32_t nphysout = (uint32_t) new_session_dialog->output_limit_count();
1839 build_session (session_path,
1847 engine->frame_rate() * 60 * 5);
1852 } while (response == Gtk::RESPONSE_NONE);
1856 new_session_dialog->get_window()->set_cursor();
1857 new_session_dialog->hide();
1861 ARDOUR_UI::close_session()
1868 ARDOUR_UI::load_session (const string & path, const string & snap_name, string* mix_template)
1870 Session *new_session;
1872 session_loaded = false;
1874 x = unload_session ();
1882 /* if it already exists, we must have write access */
1884 if (::access (path.c_str(), F_OK) == 0 && ::access (path.c_str(), W_OK)) {
1885 MessageDialog msg (*editor, _("You do not have write access to this session.\n"
1886 "This prevents the session from being loaded."));
1892 new_session = new Session (*engine, path, snap_name, mix_template);
1897 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
1901 connect_to_session (new_session);
1903 Config->set_current_owner (ConfigVariableBase::Interface);
1905 session_loaded = true;
1907 goto_editor_window ();
1910 session->set_clean ();
1917 ARDOUR_UI::build_session (const string & path, const string & snap_name,
1918 uint32_t control_channels,
1919 uint32_t master_channels,
1920 AutoConnectOption input_connect,
1921 AutoConnectOption output_connect,
1924 nframes_t initial_length)
1926 Session *new_session;
1929 session_loaded = false;
1930 x = unload_session ();
1937 _session_is_new = true;
1940 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
1941 control_channels, master_channels, nphysin, nphysout, initial_length);
1946 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
1950 connect_to_session (new_session);
1952 session_loaded = true;
1960 editor->show_window ();
1971 ARDOUR_UI::show_splash ()
1974 about = new About();
1975 about->signal_response().connect(mem_fun (*this, &ARDOUR_UI::about_signal_response) );
1982 ARDOUR_UI::about_signal_response(int response)
1988 ARDOUR_UI::hide_splash ()
1991 about->get_window()->set_cursor ();
1997 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title, const string & msg)
2001 removed = rep.paths.size();
2004 MessageDialog msgd (*editor,
2005 _("No audio files were ready for cleanup"),
2008 (Gtk::ButtonsType)(Gtk::BUTTONS_OK) );
2009 msgd.set_secondary_text (_("If this seems suprising, \n\
2010 check for any existing snapshots.\n\
2011 These may still include regions that\n\
2012 require some unused files to continue to exist."));
2018 ArdourDialog results (_("ardour: cleanup"), true, false);
2020 struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
2021 CleanupResultsModelColumns() {
2025 Gtk::TreeModelColumn<Glib::ustring> visible_name;
2026 Gtk::TreeModelColumn<Glib::ustring> fullpath;
2030 CleanupResultsModelColumns results_columns;
2031 Glib::RefPtr<Gtk::ListStore> results_model;
2032 Gtk::TreeView results_display;
2034 results_model = ListStore::create (results_columns);
2035 results_display.set_model (results_model);
2036 results_display.append_column (list_title, results_columns.visible_name);
2038 results_display.set_name ("CleanupResultsList");
2039 results_display.set_headers_visible (true);
2040 results_display.set_headers_clickable (false);
2041 results_display.set_reorderable (false);
2043 Gtk::ScrolledWindow list_scroller;
2046 Gtk::HBox dhbox; // the hbox for the image and text
2047 Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
2048 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO, Gtk::ICON_SIZE_DIALOG));
2050 dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
2052 if (rep.space < 1048576.0f) {
2054 txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2056 txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2060 txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2062 txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2066 dhbox.pack_start (*dimage, true, false, 5);
2067 dhbox.pack_start (txt, true, false, 5);
2069 for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2070 TreeModel::Row row = *(results_model->append());
2071 row[results_columns.visible_name] = *i;
2072 row[results_columns.fullpath] = *i;
2075 list_scroller.add (results_display);
2076 list_scroller.set_size_request (-1, 150);
2077 list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2079 dvbox.pack_start (dhbox, true, false, 5);
2080 dvbox.pack_start (list_scroller, true, false, 5);
2081 ddhbox.pack_start (dvbox, true, false, 5);
2083 results.get_vbox()->pack_start (ddhbox, true, false, 5);
2084 results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
2085 results.set_default_response (RESPONSE_CLOSE);
2086 results.set_position (Gtk::WIN_POS_MOUSE);
2087 results.show_all_children ();
2088 results.set_resizable (false);
2095 ARDOUR_UI::cleanup ()
2098 /* shouldn't happen: menu item is insensitive */
2103 MessageDialog checker (_("Are you sure you want to cleanup?"),
2105 Gtk::MESSAGE_QUESTION,
2106 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
2108 checker.set_secondary_text(_("Cleanup is a destructive operation.\n\
2109 ALL undo/redo information will be lost if you cleanup.\n\
2110 After cleanup, unused audio files will be moved to a \
2111 \"dead sounds\" location."));
2113 checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2114 checker.add_button (_("Clean Up"), RESPONSE_ACCEPT);
2115 checker.set_default_response (RESPONSE_CANCEL);
2117 checker.set_name (_("CleanupDialog"));
2118 checker.set_wmclass (X_("ardour_cleanup"), "Ardour");
2119 checker.set_position (Gtk::WIN_POS_MOUSE);
2121 switch (checker.run()) {
2122 case RESPONSE_ACCEPT:
2128 Session::cleanup_report rep;
2130 editor->prepare_for_cleanup ();
2132 if (session->cleanup_sources (rep)) {
2136 display_cleanup_results (rep,
2139 The following %1 %2 not in use and \n\
2140 have been moved to:\n\
2142 Flushing the wastebasket will \n\
2143 release an additional\n\
2144 %4 %5bytes of disk space.\n"
2149 ARDOUR_UI::flush_trash ()
2152 /* shouldn't happen: menu item is insensitive */
2156 Session::cleanup_report rep;
2158 if (session->cleanup_trash_sources (rep)) {
2162 display_cleanup_results (rep,
2164 _("The following %1 %2 deleted from\n\
2166 releasing %4 %5bytes of disk space"));
2170 ARDOUR_UI::add_route ()
2178 if (add_route_dialog == 0) {
2179 add_route_dialog = new AddRouteDialog;
2180 editor->ensure_float (*add_route_dialog);
2183 if (add_route_dialog->is_visible()) {
2184 /* we're already doing this */
2188 ResponseType r = (ResponseType) add_route_dialog->run ();
2190 add_route_dialog->hide();
2193 case RESPONSE_ACCEPT:
2200 if ((count = add_route_dialog->count()) <= 0) {
2204 uint32_t input_chan = add_route_dialog->channels ();
2205 uint32_t output_chan;
2206 string name_template = add_route_dialog->name_template ();
2207 bool track = add_route_dialog->track ();
2209 AutoConnectOption oac = Config->get_output_auto_connect();
2211 if (oac & AutoConnectMaster) {
2212 output_chan = (session->master_out() ? session->master_out()->n_inputs() : input_chan);
2214 output_chan = input_chan;
2217 /* XXX do something with name template */
2220 session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), count);
2222 session_add_audio_bus (input_chan, output_chan, count);
2227 ARDOUR_UI::mixer_settings () const
2232 node = session->instant_xml(X_("Mixer"), session->path());
2234 node = Config->instant_xml(X_("Mixer"), get_user_ardour_path());
2238 node = new XMLNode (X_("Mixer"));
2245 ARDOUR_UI::editor_settings () const
2250 node = session->instant_xml(X_("Editor"), session->path());
2252 node = Config->instant_xml(X_("Editor"), get_user_ardour_path());
2256 node = new XMLNode (X_("Editor"));
2262 ARDOUR_UI::keyboard_settings () const
2266 node = Config->extra_xml(X_("Keyboard"));
2269 node = new XMLNode (X_("Keyboard"));
2275 ARDOUR_UI::halt_on_xrun_message ()
2277 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
2279 MessageDialog msg (*editor,
2280 _("Recording was stopped because your system could not keep up."));
2285 ARDOUR_UI::disk_overrun_handler ()
2287 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2289 if (!have_disk_overrun_displayed) {
2290 have_disk_overrun_displayed = true;
2291 MessageDialog msg (*editor, X_("diskrate dialog"), _("\
2292 The disk system on your computer\n\
2293 was not able to keep up with Ardour.\n\
2295 Specifically, it failed to write data to disk\n\
2296 quickly enough to keep up with recording.\n"));
2298 have_disk_overrun_displayed = false;
2303 ARDOUR_UI::disk_underrun_handler ()
2305 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2307 if (!have_disk_underrun_displayed) {
2308 have_disk_underrun_displayed = true;
2309 MessageDialog msg (*editor,
2310 (_("The disk system on your computer\n\
2311 was not able to keep up with Ardour.\n\
2313 Specifically, it failed to read data from disk\n\
2314 quickly enough to keep up with playback.\n")));
2316 have_disk_underrun_displayed = false;
2321 ARDOUR_UI::disk_underrun_message_gone ()
2323 have_disk_underrun_displayed = false;
2327 ARDOUR_UI::disk_overrun_message_gone ()
2329 have_disk_underrun_displayed = false;
2333 ARDOUR_UI::pending_state_dialog ()
2335 ArdourDialog dialog ("pending state dialog");
2337 This session appears to have been in\n\
2338 middle of recording when ardour or\n\
2339 the computer was shutdown.\n\
2341 Ardour can recover any captured audio for\n\
2342 you, or it can ignore it. Please decide\n\
2343 what you would like to do.\n"));
2345 dialog.get_vbox()->pack_start (message);
2346 dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
2347 dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
2349 dialog.set_position (WIN_POS_CENTER);
2352 switch (dialog.run ()) {
2353 case RESPONSE_ACCEPT:
2361 ARDOUR_UI::disconnect_from_jack ()
2364 if( engine->disconnect_from_jack ()) {
2365 MessageDialog msg (*editor, _("Could not disconnect from JACK"));
2369 update_sample_rate (0);
2374 ARDOUR_UI::reconnect_to_jack ()
2377 if (engine->reconnect_to_jack ()) {
2378 MessageDialog msg (*editor, _("Could not reconnect to JACK"));
2382 update_sample_rate (0);
2387 ARDOUR_UI::cmdline_new_session (string path)
2389 if (path[0] != '/') {
2390 char buf[PATH_MAX+1];
2393 getcwd (buf, sizeof (buf));
2402 _will_create_new_session_automatically = false; /* done it */
2403 return FALSE; /* don't call it again */
2407 ARDOUR_UI::use_config ()
2409 Glib::RefPtr<Action> act;
2411 switch (Config->get_native_file_data_format ()) {
2413 act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
2416 act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
2421 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2422 ract->set_active ();
2425 switch (Config->get_native_file_header_format ()) {
2427 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
2430 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
2433 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
2436 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
2439 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
2442 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatCAF"));
2445 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatAIFF"));
2450 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2451 ract->set_active ();
2456 ARDOUR_UI::update_transport_clocks (nframes_t pos)
2458 primary_clock.set (pos);
2459 secondary_clock.set (pos);
2461 if (big_clock_window) {
2462 big_clock.set (pos);
2467 ARDOUR_UI::record_state_changed ()
2469 ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::record_state_changed));
2471 if (!session || !big_clock_window) {
2472 /* why bother - the clock isn't visible */
2476 switch (session->record_status()) {
2477 case Session::Recording:
2478 big_clock.set_widget_name ("BigClockRecording");
2481 big_clock.set_widget_name ("BigClockNonRecording");
2487 ARDOUR_UI::set_keybindings_path (string path)
2489 keybindings_path = path;
2493 ARDOUR_UI::save_keybindings ()
2495 if (can_save_keybindings) {
2496 AccelMap::save (keybindings_path);
2501 ARDOUR_UI::first_idle ()
2503 can_save_keybindings = true;
2508 ARDOUR_UI::store_clock_modes ()
2510 XMLNode* node = new XMLNode(X_("ClockModes"));
2512 for (vector<AudioClock*>::iterator x = AudioClock::clocks.begin(); x != AudioClock::clocks.end(); ++x) {
2513 node->add_property ((*x)->name().c_str(), enum_2_string ((*x)->mode()));
2516 session->add_extra_xml (*node);
2517 session->set_dirty ();