2 Copyright (C) 1999-2002 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.
21 #define __STDC_FORMAT_MACROS 1
34 #include <gtkmm/messagedialog.h>
35 #include <gtkmm/accelmap.h>
37 #include <pbd/error.h>
38 #include <pbd/compose.h>
39 #include <pbd/pathscanner.h>
40 #include <pbd/failed_constructor.h>
41 #include <pbd/enumwriter.h>
42 #include <pbd/stacktrace.h>
43 #include <gtkmm2ext/gtk_ui.h>
44 #include <gtkmm2ext/utils.h>
45 #include <gtkmm2ext/click_box.h>
46 #include <gtkmm2ext/fastmeter.h>
47 #include <gtkmm2ext/stop_signal.h>
48 #include <gtkmm2ext/popup.h>
50 #include <midi++/port.h>
51 #include <midi++/mmc.h>
53 #include <ardour/ardour.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/session_route.h>
62 #include <ardour/port.h>
63 #include <ardour/audio_track.h>
64 #include <ardour/midi_track.h>
67 #include "ardour_ui.h"
68 #include "public_editor.h"
69 #include "audio_clock.h"
74 #include "keyboard_target.h"
75 #include "add_route_dialog.h"
76 #include "new_session_dialog.h"
79 #include "gui_thread.h"
80 #include "color_manager.h"
84 using namespace ARDOUR;
86 using namespace Gtkmm2ext;
90 ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
92 sigc::signal<void,bool> ARDOUR_UI::Blink;
93 sigc::signal<void> ARDOUR_UI::RapidScreenUpdate;
94 sigc::signal<void> ARDOUR_UI::SuperRapidScreenUpdate;
95 sigc::signal<void,nframes_t> ARDOUR_UI::Clock;
97 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
99 : Gtkmm2ext::UI ("ardour", argcp, argvp, rcfile),
101 primary_clock (X_("primary"), false, X_("TransportClockDisplay"), true, false, true),
102 secondary_clock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, false, true),
103 preroll_clock (X_("preroll"), false, X_("PreRollClock"), true, true),
104 postroll_clock (X_("postroll"), false, X_("PostRollClock"), true, true),
108 adjuster_table (3, 3),
112 preroll_button (_("pre\nroll")),
113 postroll_button (_("post\nroll")),
117 big_clock (X_("bigclock"), false, "BigClockNonRecording", false, false, true),
121 time_master_button (_("time\nmaster")),
123 shuttle_units_button (_("% ")),
125 punch_in_button (_("Punch In")),
126 punch_out_button (_("Punch Out")),
127 auto_return_button (_("Auto Return")),
128 auto_play_button (_("Autuo Play")),
129 auto_input_button (_("Auto Input")),
130 click_button (_("Click")),
131 auditioning_alert_button (_("AUDITION")),
132 solo_alert_button (_("SOLO")),
135 using namespace Gtk::Menu_Helpers;
141 if (theArdourUI == 0) {
147 color_manager = new ColorManager();
149 std::string color_file = ARDOUR::find_config_file("ardour.colors");
151 color_manager->load (color_file);
156 _session_is_new = false;
157 big_clock_window = 0;
158 session_selector_window = 0;
159 last_key_press_time = 0;
160 connection_editor = 0;
161 add_route_dialog = 0;
165 open_session_selector = 0;
166 have_configure_timeout = false;
167 have_disk_overrun_displayed = false;
168 have_disk_underrun_displayed = false;
169 _will_create_new_session_automatically = false;
170 session_loaded = false;
171 last_speed_displayed = -1.0f;
172 keybindings_path = ARDOUR::find_config_file ("ardour.bindings");
174 can_save_keybindings = false;
175 Glib::signal_idle().connect (mem_fun (*this, &ARDOUR_UI::first_idle));
177 last_configure_time.tv_sec = 0;
178 last_configure_time.tv_usec = 0;
180 shuttle_grabbed = false;
182 shuttle_max_speed = 8.0f;
184 shuttle_style_menu = 0;
185 shuttle_unit_menu = 0;
187 gettimeofday (&last_peak_grab, 0);
188 gettimeofday (&last_shuttle_request, 0);
190 ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
191 ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
193 /* handle pending state with a dialog */
195 ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
197 /* have to wait for AudioEngine and Configuration before proceeding */
201 ARDOUR_UI::set_engine (AudioEngine& e)
205 engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
206 engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
207 engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
208 engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
210 ActionManager::init ();
211 new_session_dialog = new NewSessionDialog();
215 keyboard = new Keyboard;
217 if (setup_windows ()) {
218 throw failed_constructor ();
221 if (GTK_ARDOUR::show_key_actions) {
222 vector<string> names;
223 vector<string> paths;
225 vector<AccelKey> bindings;
227 ActionManager::get_all_actions (names, paths, keys, bindings);
229 vector<string>::iterator n;
230 vector<string>::iterator k;
231 for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) {
232 cerr << "Action: " << (*n) << " bound to " << (*k) << endl;
238 /* start with timecode, metering enabled
241 blink_timeout_tag = -1;
243 /* the global configuration object is now valid */
247 /* this being a GUI and all, we want peakfiles */
249 AudioFileSource::set_build_peakfiles (true);
250 AudioFileSource::set_build_missing_peakfiles (true);
252 if (AudioSource::start_peak_thread ()) {
253 throw failed_constructor();
256 /* set default clock modes */
258 primary_clock.set_mode (AudioClock::SMPTE);
259 secondary_clock.set_mode (AudioClock::BBT);
261 /* start the time-of-day-clock */
263 update_wall_clock ();
264 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
266 update_disk_space ();
268 update_sample_rate (engine->frame_rate());
270 starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
271 stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
274 ARDOUR_UI::~ARDOUR_UI ()
276 save_ardour_state ();
290 if (add_route_dialog) {
291 delete add_route_dialog;
294 AudioSource::stop_peak_thread ();
298 ARDOUR_UI::configure_timeout ()
303 if (last_configure_time.tv_sec == 0 && last_configure_time.tv_usec == 0) {
304 /* no configure events yet */
308 gettimeofday (&now, 0);
309 timersub (&now, &last_configure_time, &diff);
311 /* force a gap of 0.5 seconds since the last configure event
314 if (diff.tv_sec == 0 && diff.tv_usec < 500000) {
317 have_configure_timeout = false;
318 save_ardour_state ();
324 ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
326 if (have_configure_timeout) {
327 gettimeofday (&last_configure_time, 0);
329 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
330 have_configure_timeout = true;
337 ARDOUR_UI::save_ardour_state ()
339 if (!keyboard || !mixer || !editor) {
343 /* XXX this is all a bit dubious. add_extra_xml() uses
344 a different lifetime model from add_instant_xml().
347 XMLNode* node = new XMLNode (keyboard->get_state());
348 Config->add_extra_xml (*node);
349 Config->save_state();
351 XMLNode enode(static_cast<Stateful*>(editor)->get_state());
352 XMLNode mnode(mixer->get_state());
355 session->add_instant_xml (enode, session->path());
356 session->add_instant_xml (mnode, session->path());
358 Config->add_instant_xml (enode, get_user_ardour_path());
359 Config->add_instant_xml (mnode, get_user_ardour_path());
366 ARDOUR_UI::startup ()
374 if (session && session->dirty()) {
375 switch (ask_about_saving_session(_("quit"))) {
380 /* use the default name */
381 if (save_state_canfail ("")) {
382 /* failed - don't quit */
383 MessageDialog msg (*editor,
385 Ardour was unable to save your session.\n\n\
386 If you still wish to quit, please use the\n\n\
387 \"Just quit\" option."));
398 session->set_deletion_in_progress ();
401 Config->save_state();
406 ARDOUR_UI::ask_about_saving_session (const string & what)
408 ArdourDialog window (_("ardour: save session?"));
409 Gtk::HBox dhbox; // the hbox for the image and text
410 Gtk::Label prompt_label;
411 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_WARNING, Gtk::ICON_SIZE_DIALOG));
415 msg = string_compose(_("Don't %1"), what);
416 window.add_button (msg, RESPONSE_REJECT);
417 msg = string_compose(_("Just %1"), what);
418 window.add_button (msg, RESPONSE_APPLY);
419 msg = string_compose(_("Save and %1"), what);
420 window.add_button (msg, RESPONSE_ACCEPT);
422 window.set_default_response (RESPONSE_ACCEPT);
424 Gtk::Button noquit_button (msg);
425 noquit_button.set_name ("EditorGTKButton");
430 if (session->snap_name() == session->name()) {
433 type = _("snapshot");
435 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?"),
436 type, session->snap_name());
438 prompt_label.set_text (prompt);
439 prompt_label.set_name (X_("PrompterLabel"));
440 prompt_label.set_alignment(ALIGN_LEFT, ALIGN_TOP);
442 dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP)
444 dhbox.set_homogeneous (false);
445 dhbox.pack_start (*dimage, false, false, 5);
446 dhbox.pack_start (prompt_label, true, false, 5);
447 window.get_vbox()->pack_start (dhbox);
449 window.set_name (_("Prompter"));
450 window.set_position (Gtk::WIN_POS_MOUSE);
451 window.set_modal (true);
452 window.set_resizable (false);
455 save_the_session = 0;
457 window.set_keep_above (true);
460 ResponseType r = (ResponseType) window.run();
465 case RESPONSE_ACCEPT: // save and get out of here
467 case RESPONSE_APPLY: // get out of here
477 ARDOUR_UI::every_second ()
480 update_buffer_load ();
481 update_disk_space ();
486 ARDOUR_UI::every_point_one_seconds ()
488 update_speed_display ();
489 RapidScreenUpdate(); /* EMIT_SIGNAL */
494 ARDOUR_UI::every_point_zero_one_seconds ()
496 SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
501 ARDOUR_UI::update_sample_rate (nframes_t ignored)
505 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
507 if (!engine->connected()) {
509 snprintf (buf, sizeof (buf), _("disconnected"));
513 nframes_t rate = engine->frame_rate();
515 if (fmod (rate, 1000.0) != 0.0) {
516 snprintf (buf, sizeof (buf), _("%.1f kHz / %4.1f msecs"),
517 (float) rate/1000.0f,
518 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
520 snprintf (buf, sizeof (buf), _("%u kHz / %4.1f msecs"),
522 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
526 sample_rate_label.set_text (buf);
530 ARDOUR_UI::update_cpu_load ()
533 snprintf (buf, sizeof (buf), _("DSP: %.1f%%"), engine->get_cpu_load());
534 cpu_load_label.set_text (buf);
538 ARDOUR_UI::update_buffer_load ()
543 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"),
544 session->playback_load(), session->capture_load());
545 buffer_load_label.set_text (buf);
547 buffer_load_label.set_text ("");
552 ARDOUR_UI::count_recenabled_streams (Route& route)
554 Track* track = dynamic_cast<Track*>(&route);
555 if (track && track->diskstream()->record_enabled()) {
556 rec_enabled_streams += track->n_inputs().get_total();
561 ARDOUR_UI::update_disk_space()
567 nframes_t frames = session->available_capture_duration();
570 if (frames == max_frames) {
571 strcpy (buf, _("Disk: 24hrs+"));
576 nframes_t fr = session->frame_rate();
578 rec_enabled_streams = 0;
579 session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
581 if (rec_enabled_streams) {
582 frames /= rec_enabled_streams;
585 hrs = frames / (fr * 3600);
586 frames -= hrs * fr * 3600;
587 mins = frames / (fr * 60);
588 frames -= mins * fr * 60;
591 snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs);
594 disk_space_label.set_text (buf);
598 ARDOUR_UI::update_wall_clock ()
605 tm_now = localtime (&now);
607 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
608 wall_clock_label.set_text (buf);
613 ARDOUR_UI::control_methods_adjusted ()
618 which_method = (int) online_control_button->adjustment.get_value();
619 switch (which_method) {
621 allow_mmc_and_local ();
630 fatal << _("programming error: impossible control method") << endmsg;
636 ARDOUR_UI::mmc_device_id_adjusted ()
641 int dev_id = (int) mmc_id_button->adjustment.get_value();
642 mmc->set_device_id (dev_id);
648 ARDOUR_UI::session_menu (GdkEventButton *ev)
650 session_popup_menu->popup (0, 0);
655 ARDOUR_UI::redisplay_recent_sessions ()
657 vector<string *> *sessions;
658 vector<string *>::iterator i;
659 RecentSessionsSorter cmp;
661 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
662 recent_session_model->clear ();
665 ARDOUR::read_recent_sessions (rs);
668 recent_session_display.set_model (recent_session_model);
672 /* sort them alphabetically */
673 sort (rs.begin(), rs.end(), cmp);
674 sessions = new vector<string*>;
676 for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
677 sessions->push_back (new string ((*i).second));
680 for (i = sessions->begin(); i != sessions->end(); ++i) {
682 vector<string*>* states;
683 vector<const gchar*> item;
684 string fullpath = *(*i);
686 /* remove any trailing / */
688 if (fullpath[fullpath.length()-1] == '/') {
689 fullpath = fullpath.substr (0, fullpath.length()-1);
692 /* now get available states for this session */
694 if ((states = Session::possible_states (fullpath)) == 0) {
699 TreeModel::Row row = *(recent_session_model->append());
701 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
702 row[recent_session_columns.fullpath] = fullpath;
704 if (states->size() > 1) {
706 /* add the children */
708 for (vector<string*>::iterator i2 = states->begin(); i2 != states->end(); ++i2) {
710 TreeModel::Row child_row = *(recent_session_model->append (row.children()));
712 child_row[recent_session_columns.visible_name] = **i2;
713 child_row[recent_session_columns.fullpath] = fullpath;
722 recent_session_display.set_model (recent_session_model);
727 ARDOUR_UI::build_session_selector ()
729 session_selector_window = new ArdourDialog ("session selector");
731 Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
733 session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
734 session_selector_window->add_button (Stock::OPEN, RESPONSE_ACCEPT);
735 session_selector_window->set_default_response (RESPONSE_ACCEPT);
736 recent_session_model = TreeStore::create (recent_session_columns);
737 recent_session_display.set_model (recent_session_model);
738 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
739 recent_session_display.set_headers_visible (false);
740 recent_session_display.get_selection()->set_mode (SELECTION_SINGLE);
742 recent_session_display.signal_row_activated().connect (mem_fun (*this, &ARDOUR_UI::recent_session_row_activated));
744 scroller->add (recent_session_display);
745 scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
747 session_selector_window->set_name ("SessionSelectorWindow");
748 session_selector_window->set_size_request (200, 400);
749 session_selector_window->get_vbox()->pack_start (*scroller);
750 session_selector_window->show_all_children();
754 ARDOUR_UI::recent_session_row_activated (const TreePath& path, TreeViewColumn* col)
756 session_selector_window->response (RESPONSE_ACCEPT);
760 ARDOUR_UI::open_recent_session ()
762 /* popup selector window */
764 if (session_selector_window == 0) {
765 build_session_selector ();
768 redisplay_recent_sessions ();
770 ResponseType r = (ResponseType) session_selector_window->run ();
772 session_selector_window->hide();
775 case RESPONSE_ACCEPT:
781 Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
783 if (i == recent_session_model->children().end()) {
787 Glib::ustring path = (*i)[recent_session_columns.fullpath];
788 Glib::ustring state = (*i)[recent_session_columns.visible_name];
790 _session_is_new = false;
792 load_session (path, state);
796 ARDOUR_UI::filter_ardour_session_dirs (const FileFilter::Info& info)
800 if (stat (info.filename.c_str(), &statbuf) != 0) {
804 if (!S_ISDIR(statbuf.st_mode)) {
810 string session_file = info.filename;
812 session_file += Glib::path_get_basename (info.filename);
813 session_file += ".ardour";
815 if (stat (session_file.c_str(), &statbuf) != 0) {
819 return S_ISREG (statbuf.st_mode);
823 ARDOUR_UI::open_session ()
825 /* popup selector window */
827 if (open_session_selector == 0) {
829 /* ardour sessions are folders */
831 open_session_selector = new Gtk::FileChooserDialog (_("open session"), FILE_CHOOSER_ACTION_OPEN);
832 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
833 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
835 FileFilter session_filter;
836 session_filter.add_pattern ("*.ardour");
837 session_filter.set_name (_("Ardour sessions"));
838 open_session_selector->add_filter (session_filter);
839 open_session_selector->set_filter (session_filter);
842 int response = open_session_selector->run();
843 open_session_selector->hide ();
846 case RESPONSE_ACCEPT:
849 open_session_selector->hide();
853 open_session_selector->hide();
854 string session_path = open_session_selector->get_filename();
858 if (session_path.length() > 0) {
859 if (Session::find_session (session_path, path, name, isnew) == 0) {
860 _session_is_new = isnew;
861 load_session (path, name);
868 ARDOUR_UI::session_add_midi_route (bool disk, uint32_t how_many)
870 list<boost::shared_ptr<MidiTrack> > tracks;
873 warning << _("You cannot add a track without a session already loaded.") << endmsg;
880 tracks = session->new_midi_track (ARDOUR::Normal, how_many);
882 if (tracks.size() != how_many) {
884 error << _("could not create a new midi track") << endmsg;
886 error << string_compose (_("could not create %1 new midi tracks"), how_many) << endmsg;
890 if ((route = session->new_midi_route ()) == 0) {
891 error << _("could not create new midi bus") << endmsg;
897 MessageDialog msg (*editor,
898 _("There are insufficient JACK ports available\n\
899 to create a new track or bus.\n\
900 You should save Ardour, exit and\n\
901 restart JACK with more ports."));
908 ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, uint32_t how_many)
910 list<boost::shared_ptr<AudioTrack> > tracks;
911 Session::RouteList routes;
914 warning << _("You cannot add a track or bus without a session already loaded.") << endmsg;
920 tracks = session->new_audio_track (input_channels, output_channels, mode, how_many);
922 if (tracks.size() != how_many) {
924 error << _("could not create a new audio track") << endmsg;
926 error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
932 routes = session->new_audio_route (input_channels, output_channels, how_many);
934 if (routes.size() != how_many) {
936 error << _("could not create a new audio track") << endmsg;
938 error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
944 if (need_control_room_outs) {
950 route->set_stereo_control_outs (control_lr_channels);
951 route->control_outs()->set_stereo_pan (pans, this);
953 #endif /* CONTROLOUTS */
957 MessageDialog msg (*editor,
958 _("There are insufficient JACK ports available\n\
959 to create a new track or bus.\n\
960 You should save Ardour, exit and\n\
961 restart JACK with more ports."));
967 ARDOUR_UI::do_transport_locate (nframes_t new_position)
969 nframes_t _preroll = 0;
972 // XXX CONFIG_CHANGE FIX - requires AnyTime handling
973 // _preroll = session->convert_to_frames_at (new_position, Config->get_preroll());
975 if (new_position > _preroll) {
976 new_position -= _preroll;
981 session->request_locate (new_position);
986 ARDOUR_UI::transport_goto_start ()
989 session->goto_start();
992 /* force displayed area in editor to start no matter
993 what "follow playhead" setting is.
997 editor->reposition_x_origin (session->current_start_frame());
1003 ARDOUR_UI::transport_goto_zero ()
1006 session->request_locate (0);
1009 /* force displayed area in editor to start no matter
1010 what "follow playhead" setting is.
1014 editor->reposition_x_origin (0);
1020 ARDOUR_UI::transport_goto_end ()
1023 nframes_t frame = session->current_end_frame();
1024 session->request_locate (frame);
1026 /* force displayed area in editor to start no matter
1027 what "follow playhead" setting is.
1031 editor->reposition_x_origin (frame);
1037 ARDOUR_UI::transport_stop ()
1043 if (session->is_auditioning()) {
1044 session->cancel_audition ();
1048 if (session->get_play_loop ()) {
1049 session->request_play_loop (false);
1052 session->request_stop ();
1056 ARDOUR_UI::transport_stop_and_forget_capture ()
1059 session->request_stop (true);
1064 ARDOUR_UI::remove_last_capture()
1067 editor->remove_last_capture();
1072 ARDOUR_UI::transport_record ()
1075 switch (session->record_status()) {
1076 case Session::Disabled:
1077 if (session->ntracks() == 0) {
1078 MessageDialog msg (*editor, _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu."));
1082 session->maybe_enable_record ();
1084 case Session::Recording:
1085 case Session::Enabled:
1086 session->disable_record (true);
1092 ARDOUR_UI::transport_roll ()
1100 rolling = session->transport_rolling ();
1102 if (session->get_play_loop()) {
1103 session->request_play_loop (false);
1104 auto_loop_button.set_active (false);
1105 roll_button.set_active (true);
1106 } else if (session->get_play_range ()) {
1107 session->request_play_range (false);
1108 play_selection_button.set_active (false);
1109 } else if (rolling) {
1110 session->request_locate (session->last_transport_start(), true);
1113 session->request_transport_speed (1.0f);
1117 ARDOUR_UI::transport_loop()
1120 if (session->get_play_loop()) {
1121 if (session->transport_rolling()) {
1122 Location * looploc = session->locations()->auto_loop_location();
1124 session->request_locate (looploc->start(), true);
1129 session->request_play_loop (true);
1135 ARDOUR_UI::transport_play_selection ()
1141 if (!session->get_play_range()) {
1142 session->request_stop ();
1145 editor->play_selection ();
1149 ARDOUR_UI::transport_rewind (int option)
1151 float current_transport_speed;
1154 current_transport_speed = session->transport_speed();
1156 if (current_transport_speed >= 0.0f) {
1159 session->request_transport_speed (-1.0f);
1162 session->request_transport_speed (-4.0f);
1165 session->request_transport_speed (-0.5f);
1170 session->request_transport_speed (current_transport_speed * 1.5f);
1176 ARDOUR_UI::transport_forward (int option)
1178 float current_transport_speed;
1181 current_transport_speed = session->transport_speed();
1183 if (current_transport_speed <= 0.0f) {
1186 session->request_transport_speed (1.0f);
1189 session->request_transport_speed (4.0f);
1192 session->request_transport_speed (0.5f);
1197 session->request_transport_speed (current_transport_speed * 1.5f);
1203 ARDOUR_UI::toggle_record_enable (uint32_t dstream)
1209 boost::shared_ptr<Route> r;
1211 if ((r = session->route_by_remote_id (dstream)) != 0) {
1215 if ((t = dynamic_cast<Track*>(r.get())) != 0) {
1216 t->diskstream()->set_record_enabled (!t->diskstream()->record_enabled());
1225 ARDOUR_UI::queue_transport_change ()
1227 Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
1231 ARDOUR_UI::map_transport_state ()
1233 float sp = session->transport_speed();
1236 transport_rolling ();
1237 } else if (sp < 0.0f) {
1238 transport_rewinding ();
1239 } else if (sp > 0.0f) {
1240 transport_forwarding ();
1242 transport_stopped ();
1247 ARDOUR_UI::allow_local_only ()
1253 ARDOUR_UI::allow_mmc_only ()
1259 ARDOUR_UI::allow_mmc_and_local ()
1265 ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg)
1267 snprintf (buf, sizeof(buf), "%s", ((GlobalClickBox *) arg)->strings[
1268 (int) adj.get_value()].c_str());
1272 ARDOUR_UI::engine_stopped ()
1274 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
1275 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1276 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1280 ARDOUR_UI::engine_running ()
1282 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
1283 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true);
1284 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
1288 ARDOUR_UI::engine_halted ()
1290 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
1292 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1293 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1295 update_sample_rate (0);
1297 MessageDialog msg (*editor,
1299 JACK has either been shutdown or it\n\
1300 disconnected Ardour because Ardour\n\
1301 was not fast enough. You can save the\n\
1302 session and/or try to reconnect to JACK ."));
1307 ARDOUR_UI::do_engine_start ()
1315 error << _("Unable to start the session running")
1325 ARDOUR_UI::start_engine ()
1327 if (do_engine_start () == 0) {
1328 if (session && _session_is_new) {
1329 /* we need to retain initial visual
1330 settings for a new session
1332 session->save_state ("");
1340 ARDOUR_UI::update_clocks ()
1342 if (!editor || !editor->dragging_playhead()) {
1343 Clock (session->audible_frame()); /* EMIT_SIGNAL */
1348 ARDOUR_UI::start_clocking ()
1350 clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
1354 ARDOUR_UI::stop_clocking ()
1356 clock_signal_connection.disconnect ();
1360 ARDOUR_UI::toggle_clocking ()
1363 if (clock_button.get_active()) {
1372 ARDOUR_UI::_blink (void *arg)
1375 ((ARDOUR_UI *) arg)->blink ();
1382 Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
1386 ARDOUR_UI::start_blinking ()
1388 /* Start the blink signal. Everybody with a blinking widget
1389 uses Blink to drive the widget's state.
1392 if (blink_timeout_tag < 0) {
1394 blink_timeout_tag = g_timeout_add (240, _blink, this);
1399 ARDOUR_UI::stop_blinking ()
1401 if (blink_timeout_tag >= 0) {
1402 g_source_remove (blink_timeout_tag);
1403 blink_timeout_tag = -1;
1408 ARDOUR_UI::name_io_setup (AudioEngine& engine,
1414 if (io.n_inputs().get_total() == 0) {
1419 /* XXX we're not handling multiple ports yet. */
1421 const char **connections = io.input(0)->get_connections();
1423 if (connections == 0 || connections[0] == '\0') {
1426 buf = connections[0];
1433 if (io.n_outputs().get_total() == 0) {
1438 /* XXX we're not handling multiple ports yet. */
1440 const char **connections = io.output(0)->get_connections();
1442 if (connections == 0 || connections[0] == '\0') {
1445 buf = connections[0];
1453 ARDOUR_UI::snapshot_session ()
1455 ArdourPrompter prompter (true);
1462 now = now.substr (20, 4) + now.substr (3, 16) + " (" + now.substr (0, 3) + ")";
1464 prompter.set_name ("Prompter");
1465 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1466 prompter.set_prompt (_("Name of New Snapshot"));
1467 prompter.set_initial_text (now);
1469 switch (prompter.run()) {
1470 case RESPONSE_ACCEPT:
1471 prompter.get_result (snapname);
1472 if (snapname.length()){
1473 save_state (snapname);
1483 ARDOUR_UI::save_state (const string & name)
1485 (void) save_state_canfail (name);
1489 ARDOUR_UI::save_state_canfail (string name)
1494 if (name.length() == 0) {
1495 name = session->snap_name();
1498 if ((ret = session->save_state (name)) != 0) {
1502 save_ardour_state (); /* XXX cannot fail? yeah, right ... */
1507 ARDOUR_UI::restore_state (string name)
1510 if (name.length() == 0) {
1511 name = session->name();
1513 session->restore_state (name);
1518 ARDOUR_UI::primary_clock_value_changed ()
1521 session->request_locate (primary_clock.current_time ());
1526 ARDOUR_UI::secondary_clock_value_changed ()
1529 session->request_locate (secondary_clock.current_time ());
1534 ARDOUR_UI::rec_enable_button_blink (bool onoff, AudioDiskstream *dstream, Widget *w)
1536 if (session && dstream && dstream->record_enabled()) {
1538 Session::RecordState rs;
1540 rs = session->record_status ();
1543 case Session::Disabled:
1544 case Session::Enabled:
1545 if (w->get_state() != STATE_SELECTED) {
1546 w->set_state (STATE_SELECTED);
1550 case Session::Recording:
1551 if (w->get_state() != STATE_ACTIVE) {
1552 w->set_state (STATE_ACTIVE);
1558 if (w->get_state() != STATE_NORMAL) {
1559 w->set_state (STATE_NORMAL);
1565 ARDOUR_UI::transport_rec_enable_blink (bool onoff)
1571 switch (session->record_status()) {
1572 case Session::Enabled:
1574 rec_button.set_state (1);
1576 rec_button.set_state (0);
1580 case Session::Recording:
1581 rec_button.set_state (2);
1585 rec_button.set_state (0);
1591 ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
1599 ARDOUR_UI::start_keyboard_prefix ()
1601 keyboard->start_prefix();
1605 ARDOUR_UI::save_template ()
1608 ArdourPrompter prompter (true);
1611 prompter.set_name (X_("Prompter"));
1612 prompter.set_prompt (_("Name for mix template:"));
1613 prompter.set_initial_text(session->name() + _("-template"));
1614 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1616 switch (prompter.run()) {
1617 case RESPONSE_ACCEPT:
1618 prompter.get_result (name);
1620 if (name.length()) {
1621 session->save_template (name);
1631 ARDOUR_UI::new_session (std::string predetermined_path)
1633 string session_name;
1634 string session_path;
1636 int response = Gtk::RESPONSE_NONE;
1638 new_session_dialog->set_modal(true);
1639 new_session_dialog->set_name (predetermined_path);
1640 new_session_dialog->reset_recent();
1641 new_session_dialog->show();
1644 response = new_session_dialog->run ();
1646 _session_is_new = false;
1648 if (response == Gtk::RESPONSE_CANCEL || response == Gtk::RESPONSE_DELETE_EVENT) {
1653 new_session_dialog->hide ();
1656 } else if (response == Gtk::RESPONSE_NONE) {
1658 /* Clear was pressed */
1659 new_session_dialog->reset();
1661 } else if (response == Gtk::RESPONSE_YES) {
1663 /* YES == OPEN, but there's no enum for that */
1665 session_name = new_session_dialog->session_name();
1667 if (session_name.empty()) {
1668 response = Gtk::RESPONSE_NONE;
1672 if (session_name[0] == '/' ||
1673 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1674 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1675 load_session (Glib::path_get_dirname (session_name), session_name);
1677 session_path = new_session_dialog->session_folder();
1678 load_session (session_path, session_name);
1681 } else if (response == Gtk::RESPONSE_OK) {
1683 session_name = new_session_dialog->session_name();
1685 if (new_session_dialog->get_current_page() == 1) {
1687 /* XXX this is a bit of a hack..
1688 i really want the new sesion dialog to return RESPONSE_YES
1689 if we're on page 1 (the load page)
1690 Unfortunately i can't see how atm..
1693 if (session_name.empty()) {
1694 response = Gtk::RESPONSE_NONE;
1698 if (session_name[0] == '/' ||
1699 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1700 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1701 load_session (Glib::path_get_dirname (session_name), session_name);
1703 session_path = new_session_dialog->session_folder();
1704 load_session (session_path, session_name);
1709 if (session_name.empty()) {
1710 response = Gtk::RESPONSE_NONE;
1714 if (session_name[0] == '/' ||
1715 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1716 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1718 session_path = Glib::path_get_dirname (session_name);
1719 session_name = Glib::path_get_basename (session_name);
1723 session_path = new_session_dialog->session_folder();
1727 //XXX This is needed because session constructor wants a
1728 //non-existant path. hopefully this will be fixed at some point.
1730 session_path = Glib::build_filename (session_path, session_name);
1732 if (g_file_test (session_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
1734 Glib::ustring str = string_compose (_("This session\n%1\nalready exists. Do you want to open it?"), session_path);
1736 MessageDialog msg (str,
1738 Gtk::MESSAGE_WARNING,
1739 Gtk::BUTTONS_YES_NO,
1743 msg.set_name (X_("CleanupDialog"));
1744 msg.set_wmclass (X_("existing_session"), "Ardour");
1745 msg.set_position (Gtk::WIN_POS_MOUSE);
1747 switch (msg.run()) {
1749 load_session (session_path, session_name);
1753 response = RESPONSE_NONE;
1754 new_session_dialog->reset ();
1759 _session_is_new = true;
1761 std::string template_name = new_session_dialog->session_template_name();
1763 if (new_session_dialog->use_session_template()) {
1765 load_session (session_path, session_name, &template_name);
1771 AutoConnectOption iconnect;
1772 AutoConnectOption oconnect;
1774 if (new_session_dialog->create_control_bus()) {
1775 cchns = (uint32_t) new_session_dialog->control_channel_count();
1780 if (new_session_dialog->create_master_bus()) {
1781 mchns = (uint32_t) new_session_dialog->master_channel_count();
1786 if (new_session_dialog->connect_inputs()) {
1787 iconnect = AutoConnectPhysical;
1789 iconnect = AutoConnectOption (0);
1792 /// @todo some minor tweaks.
1794 if (new_session_dialog->connect_outs_to_master()) {
1795 oconnect = AutoConnectMaster;
1796 } else if (new_session_dialog->connect_outs_to_physical()) {
1797 oconnect = AutoConnectPhysical;
1799 oconnect = AutoConnectOption (0);
1802 uint32_t nphysin = (uint32_t) new_session_dialog->input_limit_count();
1803 uint32_t nphysout = (uint32_t) new_session_dialog->output_limit_count();
1805 build_session (session_path,
1813 engine->frame_rate() * 60 * 5);
1818 } while (response == Gtk::RESPONSE_NONE);
1822 new_session_dialog->get_window()->set_cursor();
1823 new_session_dialog->hide();
1827 ARDOUR_UI::close_session()
1834 ARDOUR_UI::load_session (const string & path, const string & snap_name, string* mix_template)
1836 Session *new_session;
1838 session_loaded = false;
1840 x = unload_session ();
1848 /* if it already exists, we must have write access */
1850 if (::access (path.c_str(), F_OK) == 0 && ::access (path.c_str(), W_OK)) {
1851 MessageDialog msg (*editor, _("You do not have write access to this session.\n"
1852 "This prevents the session from being loaded."));
1858 new_session = new Session (*engine, path, snap_name, mix_template);
1863 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
1867 connect_to_session (new_session);
1869 Config->set_current_owner (ConfigVariableBase::Interface);
1871 session_loaded = true;
1873 goto_editor_window ();
1876 session->set_clean ();
1883 ARDOUR_UI::build_session (const string & path, const string & snap_name,
1884 uint32_t control_channels,
1885 uint32_t master_channels,
1886 AutoConnectOption input_connect,
1887 AutoConnectOption output_connect,
1890 nframes_t initial_length)
1892 Session *new_session;
1895 session_loaded = false;
1896 x = unload_session ();
1903 _session_is_new = true;
1906 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
1907 control_channels, master_channels, nphysin, nphysout, initial_length);
1912 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
1916 connect_to_session (new_session);
1918 session_loaded = true;
1926 editor->show_window ();
1937 ARDOUR_UI::show_splash ()
1940 about = new About();
1941 about->signal_response().connect(mem_fun (*this, &ARDOUR_UI::about_signal_response) );
1948 ARDOUR_UI::about_signal_response(int response)
1954 ARDOUR_UI::hide_splash ()
1957 about->get_window()->set_cursor ();
1963 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title, const string & msg)
1967 removed = rep.paths.size();
1970 MessageDialog msgd (*editor,
1971 _("No audio files were ready for cleanup"),
1974 (Gtk::ButtonsType)(Gtk::BUTTONS_OK) );
1975 msgd.set_secondary_text (_("If this seems suprising, \n\
1976 check for any existing snapshots.\n\
1977 These may still include regions that\n\
1978 require some unused files to continue to exist."));
1984 ArdourDialog results (_("ardour: cleanup"), true, false);
1986 struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
1987 CleanupResultsModelColumns() {
1991 Gtk::TreeModelColumn<Glib::ustring> visible_name;
1992 Gtk::TreeModelColumn<Glib::ustring> fullpath;
1996 CleanupResultsModelColumns results_columns;
1997 Glib::RefPtr<Gtk::ListStore> results_model;
1998 Gtk::TreeView results_display;
2000 results_model = ListStore::create (results_columns);
2001 results_display.set_model (results_model);
2002 results_display.append_column (list_title, results_columns.visible_name);
2004 results_display.set_name ("CleanupResultsList");
2005 results_display.set_headers_visible (true);
2006 results_display.set_headers_clickable (false);
2007 results_display.set_reorderable (false);
2009 Gtk::ScrolledWindow list_scroller;
2012 Gtk::HBox dhbox; // the hbox for the image and text
2013 Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
2014 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO, Gtk::ICON_SIZE_DIALOG));
2016 dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
2018 if (rep.space < 1048576.0f) {
2020 txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2022 txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2026 txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2028 txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2032 dhbox.pack_start (*dimage, true, false, 5);
2033 dhbox.pack_start (txt, true, false, 5);
2035 for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2036 TreeModel::Row row = *(results_model->append());
2037 row[results_columns.visible_name] = *i;
2038 row[results_columns.fullpath] = *i;
2041 list_scroller.add (results_display);
2042 list_scroller.set_size_request (-1, 150);
2043 list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2045 dvbox.pack_start (dhbox, true, false, 5);
2046 dvbox.pack_start (list_scroller, true, false, 5);
2047 ddhbox.pack_start (dvbox, true, false, 5);
2049 results.get_vbox()->pack_start (ddhbox, true, false, 5);
2050 results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
2051 results.set_default_response (RESPONSE_CLOSE);
2052 results.set_position (Gtk::WIN_POS_MOUSE);
2053 results.show_all_children ();
2054 results.set_resizable (false);
2061 ARDOUR_UI::cleanup ()
2064 /* shouldn't happen: menu item is insensitive */
2069 MessageDialog checker (_("Are you sure you want to cleanup?"),
2071 Gtk::MESSAGE_QUESTION,
2072 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
2074 checker.set_secondary_text(_("Cleanup is a destructive operation.\n\
2075 ALL undo/redo information will be lost if you cleanup.\n\
2076 After cleanup, unused audio files will be moved to a \
2077 \"dead sounds\" location."));
2079 checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2080 checker.add_button (_("Clean Up"), RESPONSE_ACCEPT);
2081 checker.set_default_response (RESPONSE_CANCEL);
2083 checker.set_name (_("CleanupDialog"));
2084 checker.set_wmclass (X_("ardour_cleanup"), "Ardour");
2085 checker.set_position (Gtk::WIN_POS_MOUSE);
2087 switch (checker.run()) {
2088 case RESPONSE_ACCEPT:
2094 Session::cleanup_report rep;
2096 editor->prepare_for_cleanup ();
2098 if (session->cleanup_sources (rep)) {
2102 display_cleanup_results (rep,
2105 The following %1 %2 not in use and \n\
2106 have been moved to:\n\
2108 Flushing the wastebasket will \n\
2109 release an additional\n\
2110 %4 %5bytes of disk space.\n"
2115 ARDOUR_UI::flush_trash ()
2118 /* shouldn't happen: menu item is insensitive */
2122 Session::cleanup_report rep;
2124 if (session->cleanup_trash_sources (rep)) {
2128 display_cleanup_results (rep,
2130 _("The following %1 %2 deleted from\n\
2132 releasing %4 %5bytes of disk space"));
2136 ARDOUR_UI::add_route ()
2144 if (add_route_dialog == 0) {
2145 add_route_dialog = new AddRouteDialog;
2146 editor->ensure_float (*add_route_dialog);
2149 if (add_route_dialog->is_visible()) {
2150 /* we're already doing this */
2154 ResponseType r = (ResponseType) add_route_dialog->run ();
2156 add_route_dialog->hide();
2159 case RESPONSE_ACCEPT:
2166 if ((count = add_route_dialog->count()) <= 0) {
2170 uint32_t input_chan = add_route_dialog->channels ();
2171 uint32_t output_chan;
2172 string name_template = add_route_dialog->name_template ();
2173 bool track = add_route_dialog->track ();
2175 AutoConnectOption oac = Config->get_output_auto_connect();
2177 if (oac & AutoConnectMaster) {
2178 output_chan = (session->master_out() ? session->master_out()->n_inputs().get(DataType::AUDIO) : input_chan);
2180 output_chan = input_chan;
2183 /* XXX do something with name template */
2185 if (add_route_dialog->type() == ARDOUR::DataType::MIDI) {
2187 session_add_midi_track(count);
2189 MessageDialog msg (*editor,
2190 _("Sorry, MIDI Busses are not supported at this time."));
2192 //session_add_midi_bus();
2196 session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), count);
2198 session_add_audio_bus (input_chan, output_chan, count);
2204 ARDOUR_UI::mixer_settings () const
2209 node = session->instant_xml(X_("Mixer"), session->path());
2211 node = Config->instant_xml(X_("Mixer"), get_user_ardour_path());
2215 node = new XMLNode (X_("Mixer"));
2222 ARDOUR_UI::editor_settings () const
2227 node = session->instant_xml(X_("Editor"), session->path());
2229 node = Config->instant_xml(X_("Editor"), get_user_ardour_path());
2233 node = new XMLNode (X_("Editor"));
2239 ARDOUR_UI::keyboard_settings () const
2243 node = Config->extra_xml(X_("Keyboard"));
2246 node = new XMLNode (X_("Keyboard"));
2252 ARDOUR_UI::halt_on_xrun_message ()
2254 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
2256 MessageDialog msg (*editor,
2257 _("Recording was stopped because your system could not keep up."));
2262 ARDOUR_UI::disk_overrun_handler ()
2264 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2266 if (!have_disk_overrun_displayed) {
2267 have_disk_overrun_displayed = true;
2268 MessageDialog msg (*editor, X_("diskrate dialog"), _("\
2269 The disk system on your computer\n\
2270 was not able to keep up with Ardour.\n\
2272 Specifically, it failed to write data to disk\n\
2273 quickly enough to keep up with recording.\n"));
2275 have_disk_overrun_displayed = false;
2280 ARDOUR_UI::disk_underrun_handler ()
2282 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2284 if (!have_disk_underrun_displayed) {
2285 have_disk_underrun_displayed = true;
2286 MessageDialog msg (*editor,
2287 (_("The disk system on your computer\n\
2288 was not able to keep up with Ardour.\n\
2290 Specifically, it failed to read data from disk\n\
2291 quickly enough to keep up with playback.\n")));
2293 have_disk_underrun_displayed = false;
2298 ARDOUR_UI::disk_underrun_message_gone ()
2300 have_disk_underrun_displayed = false;
2304 ARDOUR_UI::disk_overrun_message_gone ()
2306 have_disk_underrun_displayed = false;
2310 ARDOUR_UI::pending_state_dialog ()
2312 ArdourDialog dialog ("pending state dialog");
2314 This session appears to have been in\n\
2315 middle of recording when ardour or\n\
2316 the computer was shutdown.\n\
2318 Ardour can recover any captured audio for\n\
2319 you, or it can ignore it. Please decide\n\
2320 what you would like to do.\n"));
2322 dialog.get_vbox()->pack_start (message);
2323 dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
2324 dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
2326 dialog.set_position (WIN_POS_CENTER);
2329 switch (dialog.run ()) {
2330 case RESPONSE_ACCEPT:
2338 ARDOUR_UI::disconnect_from_jack ()
2341 if( engine->disconnect_from_jack ()) {
2342 MessageDialog msg (*editor, _("Could not disconnect from JACK"));
2346 update_sample_rate (0);
2351 ARDOUR_UI::reconnect_to_jack ()
2354 if (engine->reconnect_to_jack ()) {
2355 MessageDialog msg (*editor, _("Could not reconnect to JACK"));
2359 update_sample_rate (0);
2364 ARDOUR_UI::set_jack_buffer_size (nframes_t nframes)
2366 engine->request_buffer_size (nframes);
2367 update_sample_rate (0);
2371 ARDOUR_UI::cmdline_new_session (string path)
2373 if (path[0] != '/') {
2374 char buf[PATH_MAX+1];
2377 getcwd (buf, sizeof (buf));
2386 _will_create_new_session_automatically = false; /* done it */
2387 return FALSE; /* don't call it again */
2391 ARDOUR_UI::use_config ()
2393 Glib::RefPtr<Action> act;
2395 switch (Config->get_native_file_data_format ()) {
2397 act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
2400 act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
2405 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2406 ract->set_active ();
2409 switch (Config->get_native_file_header_format ()) {
2411 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
2414 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
2417 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
2420 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
2423 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
2426 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatCAF"));
2429 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatAIFF"));
2434 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2435 ract->set_active ();
2440 ARDOUR_UI::update_transport_clocks (nframes_t pos)
2442 primary_clock.set (pos);
2443 secondary_clock.set (pos);
2445 if (big_clock_window) {
2446 big_clock.set (pos);
2451 ARDOUR_UI::record_state_changed ()
2453 ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::record_state_changed));
2455 if (!session || !big_clock_window) {
2456 /* why bother - the clock isn't visible */
2460 switch (session->record_status()) {
2461 case Session::Recording:
2462 big_clock.set_widget_name ("BigClockRecording");
2465 big_clock.set_widget_name ("BigClockNonRecording");
2471 ARDOUR_UI::set_keybindings_path (string path)
2473 keybindings_path = path;
2477 ARDOUR_UI::save_keybindings ()
2479 if (can_save_keybindings) {
2480 AccelMap::save (keybindings_path);
2485 ARDOUR_UI::first_idle ()
2487 can_save_keybindings = true;
2492 ARDOUR_UI::store_clock_modes ()
2494 XMLNode* node = new XMLNode(X_("ClockModes"));
2496 for (vector<AudioClock*>::iterator x = AudioClock::clocks.begin(); x != AudioClock::clocks.end(); ++x) {
2497 node->add_property ((*x)->name().c_str(), enum_2_string ((*x)->mode()));
2500 session->add_extra_xml (*node);
2501 session->set_dirty ();