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.
31 #include <pbd/error.h>
32 #include <pbd/compose.h>
33 #include <pbd/basename.h>
34 #include <pbd/pathscanner.h>
35 #include <pbd/failed_constructor.h>
36 #include <gtkmm2ext/gtk_ui.h>
37 #include <gtkmm2ext/pix.h>
38 #include <gtkmm2ext/utils.h>
39 #include <gtkmm2ext/click_box.h>
40 #include <gtkmm2ext/fastmeter.h>
41 #include <gtkmm2ext/stop_signal.h>
42 #include <gtkmm2ext/popup.h>
44 #include <midi++/port.h>
45 #include <midi++/mmc.h>
47 #include <ardour/ardour.h>
48 #include <ardour/port.h>
49 #include <ardour/audioengine.h>
50 #include <ardour/playlist.h>
51 #include <ardour/utils.h>
52 #include <ardour/diskstream.h>
53 #include <ardour/filesource.h>
54 #include <ardour/recent_sessions.h>
55 #include <ardour/session_diskstream.h>
56 #include <ardour/port.h>
57 #include <ardour/audio_track.h>
60 #include "ardour_ui.h"
61 #include "ardour_message.h"
62 #include "public_editor.h"
63 #include "audio_clock.h"
68 #include "keyboard_target.h"
69 #include "add_route_dialog.h"
70 #include "new_session_dialog.h"
73 #include "gui_thread.h"
74 #include "meter_xpms.h"
78 using namespace ARDOUR;
79 using namespace Gtkmm2ext;
83 ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
85 sigc::signal<void,bool> ARDOUR_UI::Blink;
86 sigc::signal<void> ARDOUR_UI::RapidScreenUpdate;
87 sigc::signal<void> ARDOUR_UI::SuperRapidScreenUpdate;
88 sigc::signal<void,jack_nframes_t> ARDOUR_UI::Clock;
90 static const char* channel_setup_names[] = {
101 vector<string> channel_combo_strings;
103 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
105 : Gtkmm2ext::UI ("ardour", argcp, argvp, rcfile),
107 primary_clock (X_("TransportClockDisplay"), true, false, true),
108 secondary_clock (X_("SecondaryClockDisplay"), true, false, true),
109 preroll_clock (X_("PreRollClock"), true, true),
110 postroll_clock (X_("PostRollClock"), true, true),
114 adjuster_table (3, 3),
118 preroll_button (_("pre\nroll")),
119 postroll_button (_("post\nroll")),
123 big_clock ("BigClockDisplay", true),
127 time_master_button (_("time\nmaster")),
129 shuttle_units_button (_("% ")),
131 punch_in_button (_("punch\nin")),
132 punch_out_button (_("punch\nout")),
133 auto_return_button (_("auto\nreturn")),
134 auto_play_button (_("auto\nplay")),
135 auto_input_button (_("auto\ninput")),
136 click_button (_("click")),
137 auditioning_alert_button (_("AUDITIONING")),
138 solo_alert_button (_("SOLO")),
142 using namespace Gtk::Menu_Helpers;
146 /* actually, its already loaded, but ... */
148 cerr << "Loading UI configuration file " << rcfile << endl;
152 if (theArdourUI == 0) {
156 ActionManager::init ();
158 m_new_session_dialog = 0;
159 m_new_session_dialog_ref = NewSessionDialogFactory::create();
160 m_new_session_dialog_ref->get_widget_derived (NewSessionDialogFactory::top_level_widget_name(), m_new_session_dialog);
164 _session_is_new = false;
165 big_clock_window = 0;
166 session_selector_window = 0;
167 last_key_press_time = 0;
168 connection_editor = 0;
169 add_route_dialog = 0;
174 open_session_selector = 0;
175 have_configure_timeout = false;
176 have_disk_overrun_displayed = false;
177 have_disk_underrun_displayed = false;
178 _will_create_new_session_automatically = false;
179 session_loaded = false;
180 last_speed_displayed = -1.0f;
182 last_configure_time.tv_sec = 0;
183 last_configure_time.tv_usec = 0;
185 shuttle_grabbed = false;
188 set_shuttle_units (Percentage);
189 set_shuttle_behaviour (Sprung);
191 shuttle_style_menu = 0;
192 shuttle_unit_menu = 0;
194 gettimeofday (&last_peak_grab, 0);
195 gettimeofday (&last_shuttle_request, 0);
197 ARDOUR::DiskStream::CannotRecordNoInput.connect (mem_fun(*this, &ARDOUR_UI::cannot_record_no_input));
198 ARDOUR::DiskStream::DeleteSources.connect (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread));
199 ARDOUR::DiskStream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
200 ARDOUR::DiskStream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
202 /* handle pending state with a dialog */
204 ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
206 channel_combo_strings = internationalize (channel_setup_names);
208 /* have to wait for AudioEngine and Configuration before proceeding */
212 ARDOUR_UI::cannot_record_no_input (DiskStream* ds)
214 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::cannot_record_no_input), ds));
216 string msg = string_compose (_("\
217 You cannot record-enable\n\
219 because it has no input connections.\n\
220 You would be wasting space recording silence."),
223 ArdourMessage message (editor, X_("cannotrecord"), msg);
227 ARDOUR_UI::set_engine (AudioEngine& e)
231 engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
232 engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
233 engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
234 engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
238 keyboard = new Keyboard;
239 install_keybindings ();
241 FastMeter::set_vertical_xpm (v_meter_strip_xpm);
242 FastMeter::set_horizontal_xpm (h_meter_strip_xpm);
244 if (setup_windows ()) {
245 throw failed_constructor ();
248 if (GTK_ARDOUR::show_key_actions) {
249 vector<string> names;
250 vector<string> paths;
252 vector<AccelKey> bindings;
254 ActionManager::get_all_actions (names, paths, keys, bindings);
256 vector<string>::iterator n;
257 vector<string>::iterator k;
258 for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) {
259 cerr << "Action: " << (*n) << " bound to " << (*k) << endl;
265 /* start with timecode, metering enabled
268 blink_timeout_tag = -1;
270 /* this being a GUI and all, we want peakfiles */
272 FileSource::set_build_peakfiles (true);
273 FileSource::set_build_missing_peakfiles (true);
275 if (Source::start_peak_thread ()) {
276 throw failed_constructor();
279 /* start the time-of-day-clock */
281 update_wall_clock ();
282 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
284 update_disk_space ();
286 update_sample_rate (engine->frame_rate());
288 starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
289 stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
292 ARDOUR_UI::~ARDOUR_UI ()
294 save_ardour_state ();
308 if (add_route_dialog) {
309 delete add_route_dialog;
312 Source::stop_peak_thread ();
316 ARDOUR_UI::configure_timeout ()
321 if (last_configure_time.tv_sec == 0 && last_configure_time.tv_usec == 0) {
322 /* no configure events yet */
326 gettimeofday (&now, 0);
327 timersub (&now, &last_configure_time, &diff);
329 /* force a gap of 0.5 seconds since the last configure event
332 if (diff.tv_sec == 0 && diff.tv_usec < 500000) {
335 have_configure_timeout = false;
336 save_ardour_state ();
342 ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
344 if (have_configure_timeout) {
345 gettimeofday (&last_configure_time, 0);
347 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
348 have_configure_timeout = true;
355 ARDOUR_UI::save_ardour_state ()
357 if (!keyboard || !mixer || !editor) {
361 /* XXX this is all a bit dubious. add_extra_xml() uses
362 a different lifetime model from add_instant_xml().
365 XMLNode* node = new XMLNode (keyboard->get_state());
366 Config->add_extra_xml (*node);
367 Config->save_state();
369 XMLNode& enode (static_cast<Stateful*>(editor)->get_state());
370 XMLNode& mnode (mixer->get_state());
373 session->add_instant_xml(enode, session->path());
374 session->add_instant_xml(mnode, session->path());
376 Config->add_instant_xml(enode, Config->get_user_ardour_path());
377 Config->add_instant_xml(mnode, Config->get_user_ardour_path());
382 ARDOUR_UI::startup ()
384 /* Once the UI is up and running, start the audio engine. Doing
385 this before the UI is up and running can cause problems
386 when not running with SCHED_FIFO, because the amount of
387 CPU and disk work needed to get the UI started can interfere
388 with the scheduling of the audio thread.
391 Glib::signal_idle().connect (mem_fun(*this, &ARDOUR_UI::start_engine));
397 if (session && session->dirty()) {
398 switch (ask_about_saving_session(_("quit"))) {
403 /* use the default name */
404 if (save_state_canfail ("")) {
405 /* failed - don't quit */
406 ArdourMessage (editor, X_("badsave dialog"),
408 Ardour was unable to save your session.\n\n\
409 If you still wish to quit, please use the\n\n\
410 \"Just quit\" option."));
423 ARDOUR_UI::ask_about_saving_session (const string & what)
425 ArdourDialog window (_("ardour: save session?"));
426 Gtk::Label prompt_label;
429 msg = string_compose(_("Save and %1"), what);
430 window.add_button (msg, RESPONSE_ACCEPT);
431 msg = string_compose(_("Just %1"), what);
432 window.add_button (msg, RESPONSE_APPLY);
433 msg = string_compose(_("Don't %1"), what);
434 window.add_button (msg, RESPONSE_REJECT);
436 Gtk::Button noquit_button (msg);
437 noquit_button.set_name ("EditorGTKButton");
442 if (session->snap_name() == session->name()) {
445 type = _("snapshot");
447 prompt = string_compose(_("The %1\n\"%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?"),
448 type, session->snap_name());
450 prompt_label.set_text (prompt);
451 prompt_label.set_alignment (0.5, 0.5);
452 prompt_label.set_name (X_("PrompterLabel"));
454 window.get_vbox()->pack_start (prompt_label);
456 window.set_name (_("Prompter"));
457 window.set_position (Gtk::WIN_POS_MOUSE);
458 window.set_modal (true);
461 save_the_session = 0;
463 editor->ensure_float (window);
465 ResponseType r = (ResponseType) window.run();
470 case RESPONSE_ACCEPT: // save and get out of here
472 case RESPONSE_APPLY: // get out of here
482 ARDOUR_UI::every_second ()
485 update_buffer_load ();
486 update_disk_space ();
487 // update_disk_rate ();
492 ARDOUR_UI::every_point_one_seconds ()
497 /* do not attempt to grab peak power more than once per cycle.
500 gettimeofday (&now, 0);
501 timersub (&now, &last_peak_grab, &diff);
503 if ((diff.tv_usec + (diff.tv_sec * 1000000)) >= engine->usecs_per_cycle()) {
504 IO::GrabPeakPower(); /* EMIT_SIGNAL */
505 last_peak_grab = now;
508 update_speed_display ();
509 RapidScreenUpdate(); /* EMIT_SIGNAL */
514 ARDOUR_UI::every_point_zero_one_seconds ()
516 SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
521 ARDOUR_UI::update_sample_rate (jack_nframes_t ignored)
525 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
527 if (!engine->connected()) {
529 snprintf (buf, sizeof (buf), _("disconnected"));
533 jack_nframes_t rate = engine->frame_rate();
535 if (fmod (rate, 1000.0) != 0.0) {
536 snprintf (buf, sizeof (buf), _("SR: %.1f kHz / %4.1f msecs"),
537 (float) rate/1000.0f,
538 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
540 snprintf (buf, sizeof (buf), _("SR: %u kHz / %4.1f msecs"),
542 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
546 sample_rate_label.set_text (buf);
550 ARDOUR_UI::update_cpu_load ()
553 snprintf (buf, sizeof (buf), _("DSP Load: %.1f%%"), engine->get_cpu_load());
554 cpu_load_label.set_text (buf);
558 ARDOUR_UI::update_disk_rate ()
563 snprintf (buf, sizeof (buf), _("Disk r:%5.1f w:%5.1f MB/s"),
564 session->read_data_rate()/1048576.0f, session->write_data_rate()/1048576.0f);
565 disk_rate_label.set_text (buf);
567 disk_rate_label.set_text ("");
572 ARDOUR_UI::update_buffer_load ()
577 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"),
578 session->playback_load(), session->capture_load());
579 buffer_load_label.set_text (buf);
581 buffer_load_label.set_text ("");
586 ARDOUR_UI::count_recenabled_diskstreams (DiskStream& ds)
588 if (ds.record_enabled()) {
589 rec_enabled_diskstreams++;
594 ARDOUR_UI::update_disk_space()
600 jack_nframes_t frames = session->available_capture_duration();
603 if (frames == max_frames) {
604 strcpy (buf, _("space: 24hrs+"));
609 jack_nframes_t fr = session->frame_rate();
611 if (session->actively_recording()){
613 rec_enabled_diskstreams = 0;
614 session->foreach_diskstream (this, &ARDOUR_UI::count_recenabled_diskstreams);
616 if (rec_enabled_diskstreams) {
617 frames /= rec_enabled_diskstreams;
622 /* hmmm. shall we divide by the route count? or the diskstream count?
623 or what? for now, do nothing ...
628 hrs = frames / (fr * 3600);
629 frames -= hrs * fr * 3600;
630 mins = frames / (fr * 60);
631 frames -= mins * fr * 60;
634 snprintf (buf, sizeof(buf), _("space: %02dh:%02dm:%02ds"), hrs, mins, secs);
637 disk_space_label.set_text (buf);
641 ARDOUR_UI::update_wall_clock ()
648 tm_now = localtime (&now);
650 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
651 wall_clock_label.set_text (buf);
657 ARDOUR_UI::toggle_recording_plugins ()
659 /* XXX use toggle_some_session_state */
665 session->set_recording_plugins (!session->get_recording_plugins());
669 ARDOUR_UI::toggle_auto_play ()
672 toggle_some_session_state (auto_play_button,
673 &Session::get_auto_play,
674 &Session::set_auto_play);
678 ARDOUR_UI::toggle_auto_return ()
681 toggle_some_session_state (auto_return_button,
682 &Session::get_auto_return,
683 &Session::set_auto_return);
687 ARDOUR_UI::toggle_click ()
689 toggle_some_session_state (click_button,
690 &Session::get_clicking,
691 &Session::set_clicking);
695 ARDOUR_UI::toggle_session_auto_loop ()
698 if (session->get_auto_loop()) {
699 if (session->transport_rolling()) {
703 session->request_auto_loop (false);
707 session->request_auto_loop (true);
713 ARDOUR_UI::toggle_session_punch_in ()
716 session->set_punch_in (!session->get_punch_in());
721 ARDOUR_UI::toggle_punch_out ()
723 toggle_some_session_state (punch_out_button,
724 &Session::get_punch_out,
725 &Session::set_punch_out);
729 ARDOUR_UI::toggle_punch_in ()
731 toggle_some_session_state (punch_in_button,
732 &Session::get_punch_in,
733 &Session::set_punch_in);
737 ARDOUR_UI::map_button_state ()
740 map_some_session_state (auto_return_button,
741 &Session::get_auto_return);
742 map_some_session_state (auto_play_button,
743 &Session::get_auto_play);
744 map_some_session_state (auto_input_button,
745 &Session::get_auto_input);
746 map_some_session_state (punch_in_button,
747 &Session::get_punch_in);
748 map_some_session_state (punch_out_button,
749 &Session::get_punch_out);
750 map_some_session_state (click_button,
751 &Session::get_clicking);
755 ARDOUR_UI::queue_map_control_change (Session::ControlType t)
757 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::map_control_change), t));
761 ARDOUR_UI::map_control_change (Session::ControlType t)
764 case Session::AutoPlay:
765 map_some_session_state (auto_play_button, &Session::get_auto_play);
768 case Session::AutoLoop:
771 case Session::AutoReturn:
772 map_some_session_state (auto_return_button, &Session::get_auto_return);
775 case Session::AutoInput:
776 map_some_session_state (auto_input_button, &Session::get_auto_input);
779 case Session::PunchOut:
780 map_some_session_state (punch_in_button, &Session::get_punch_out);
783 case Session::PunchIn:
784 map_some_session_state (punch_in_button, &Session::get_punch_in);
787 case Session::Clicking:
788 map_some_session_state (click_button, &Session::get_clicking);
791 case Session::SlaveType:
792 // map_some_session_state (mtc_slave_button, &Session::get_mtc_slave);
795 case Session::SendMTC:
796 // map_some_session_state (send_mtc_button, &Session::get_send_mtc);
799 case Session::SendMMC:
800 // map_some_session_state (send_mmc_button, &Session::get_send_mmc);
803 case Session::MMCControl:
804 // map_some_session_state (mmc_control_button, &Session::get_mmc_control);
807 case Session::MidiFeedback:
808 // map_some_session_state (mmc_control_button, &Session::get_mmc_control);
810 case Session::MidiControl:
811 // map_some_session_state (mmc_control_button, &Session::get_mmc_control);
817 case Session::RecordingPlugins:
820 case Session::CrossFadesActive:
823 case Session::EditingMode:
826 case Session::PlayRange:
829 case Session::AlignChoice:
830 /* don't care, this is handled by the options editor */
832 case Session::SeamlessLoop:
833 /* don't care, this is handled by the options editor */
840 ARDOUR_UI::control_methods_adjusted ()
845 which_method = (int) online_control_button->adjustment.get_value();
846 switch (which_method) {
848 allow_mmc_and_local ();
857 fatal << _("programming error: impossible control method") << endmsg;
863 ARDOUR_UI::mmc_device_id_adjusted ()
868 int dev_id = (int) mmc_id_button->adjustment.get_value();
869 mmc->set_device_id (dev_id);
875 ARDOUR_UI::map_some_session_state (ToggleButton& button,
876 bool (Session::*get)() const)
885 if (button.get_active() != (x = (session->*get)())) {
886 button.set_active (x);
891 ARDOUR_UI::toggle_some_session_state (ToggleButton& button,
892 bool (Session::*get)() const,
893 void (Session::*set)(bool))
903 button_state = button.get_active ();
904 session_state = (session->*get)();
906 if (button_state != session_state) {
907 (session->*set) (button_state);
910 /* check that it worked, and reverse
911 the button state if it didn't
914 if ((session->*get)() != button_state) {
915 button->set_active (!button_state);
923 ARDOUR_UI::session_menu (GdkEventButton *ev)
925 session_popup_menu->popup (0, 0);
930 ARDOUR_UI::redisplay_recent_sessions ()
932 vector<string *> *sessions;
933 vector<string *>::iterator i;
934 RecentSessionsSorter cmp;
936 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
937 recent_session_model->clear ();
940 ARDOUR::read_recent_sessions (rs);
943 recent_session_display.set_model (recent_session_model);
947 /* sort them alphabetically */
948 sort (rs.begin(), rs.end(), cmp);
949 sessions = new vector<string*>;
951 for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
952 sessions->push_back (new string ((*i).second));
955 for (i = sessions->begin(); i != sessions->end(); ++i) {
957 vector<string*>* states;
958 vector<const gchar*> item;
959 string fullpath = *(*i);
961 /* remove any trailing / */
963 if (fullpath[fullpath.length()-1] == '/') {
964 fullpath = fullpath.substr (0, fullpath.length()-1);
967 /* now get available states for this session */
969 if ((states = Session::possible_states (fullpath)) == 0) {
974 TreeModel::Row row = *(recent_session_model->append());
976 row[recent_session_columns.visible_name] = PBD::basename (fullpath);
977 row[recent_session_columns.fullpath] = fullpath;
979 if (states->size() > 1) {
981 /* add the children */
983 for (vector<string*>::iterator i2 = states->begin(); i2 != states->end(); ++i2) {
985 TreeModel::Row child_row = *(recent_session_model->append (row.children()));
987 child_row[recent_session_columns.visible_name] = **i2;
988 child_row[recent_session_columns.fullpath] = fullpath;
997 recent_session_display.set_model (recent_session_model);
1002 ARDOUR_UI::build_session_selector ()
1004 session_selector_window = new ArdourDialog ("session selector");
1006 Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
1008 session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
1009 session_selector_window->add_button (Stock::OK, RESPONSE_ACCEPT);
1011 recent_session_model = TreeStore::create (recent_session_columns);
1012 recent_session_display.set_model (recent_session_model);
1013 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1014 recent_session_display.set_headers_visible (false);
1016 scroller->add (recent_session_display);
1017 scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1019 session_selector_window->set_name ("SessionSelectorWindow");
1020 session_selector_window->set_size_request (200, 400);
1021 session_selector_window->get_vbox()->pack_start (*scroller);
1022 session_selector_window->show_all_children();
1026 ARDOUR_UI::open_recent_session ()
1028 /* popup selector window */
1030 if (session_selector_window == 0) {
1031 build_session_selector ();
1034 redisplay_recent_sessions ();
1036 ResponseType r = (ResponseType) session_selector_window->run ();
1038 session_selector_window->hide();
1041 case RESPONSE_ACCEPT:
1047 Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
1049 if (i == recent_session_model->children().end()) {
1053 Glib::ustring path = (*i)[recent_session_columns.fullpath];
1054 Glib::ustring state = (*i)[recent_session_columns.visible_name];
1056 _session_is_new = false;
1058 load_session (path, state);
1062 ARDOUR_UI::filter_ardour_session_dirs (const FileFilter::Info& info)
1064 struct stat statbuf;
1066 if (stat (info.filename.c_str(), &statbuf) != 0) {
1070 if (!S_ISDIR(statbuf.st_mode)) {
1074 string session_file = info.filename;
1075 session_file += '/';
1076 session_file += PBD::basename (info.filename);
1077 session_file += ".ardour";
1079 if (stat (session_file.c_str(), &statbuf) != 0) {
1083 return S_ISREG (statbuf.st_mode);
1087 ARDOUR_UI::open_session ()
1089 /* popup selector window */
1091 if (open_session_selector == 0) {
1093 /* ardour sessions are folders */
1095 open_session_selector = new Gtk::FileChooserDialog (_("open session"), FILE_CHOOSER_ACTION_OPEN);
1096 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1097 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
1099 FileFilter session_filter;
1100 session_filter.add_pattern ("*.ardour");
1101 session_filter.set_name (_("Ardour sessions"));
1102 open_session_selector->add_filter (session_filter);
1103 open_session_selector->set_filter (session_filter);
1106 int response = open_session_selector->run();
1107 open_session_selector->hide ();
1110 case RESPONSE_ACCEPT:
1113 open_session_selector->hide();
1117 open_session_selector->hide();
1118 string session_path = open_session_selector->get_filename();
1122 if (session_path.length() > 0) {
1123 if (Session::find_session (session_path, path, name, isnew) == 0) {
1124 _session_is_new = isnew;
1125 load_session (path, name);
1132 ARDOUR_UI::session_add_midi_track ()
1134 cerr << _("Patience is a virtue.\n");
1138 ARDOUR_UI::session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels)
1143 warning << _("You cannot add a track without a session already loaded.") << endmsg;
1149 if ((route = session->new_audio_track (input_channels, output_channels)) == 0) {
1150 error << _("could not create new audio track") << endmsg;
1153 if ((route = session->new_audio_route (input_channels, output_channels)) == 0) {
1154 error << _("could not create new audio bus") << endmsg;
1159 if (need_control_room_outs) {
1165 route->set_stereo_control_outs (control_lr_channels);
1166 route->control_outs()->set_stereo_pan (pans, this);
1168 #endif /* CONTROLOUTS */
1172 ArdourMessage msg (editor, X_("noport dialog"),
1173 _("There are insufficient JACK ports available\n\
1174 to create a new track or bus.\n\
1175 You should save Ardour, exit and\n\
1176 restart JACK with more ports."));
1181 ARDOUR_UI::diskstream_added (DiskStream* ds)
1186 ARDOUR_UI::do_transport_locate (jack_nframes_t new_position)
1188 jack_nframes_t _preroll;
1191 _preroll = session->convert_to_frames_at (new_position, session->preroll);
1193 if (new_position > _preroll) {
1194 new_position -= _preroll;
1199 session->request_locate (new_position);
1204 ARDOUR_UI::transport_goto_start ()
1207 session->request_locate (0);
1210 /* force displayed area in editor to start no matter
1211 what "follow playhead" setting is.
1215 editor->reposition_x_origin (0);
1221 ARDOUR_UI::transport_goto_end ()
1224 jack_nframes_t frame = session->current_end_frame();
1225 session->request_locate (frame);
1227 /* force displayed area in editor to start no matter
1228 what "follow playhead" setting is.
1232 editor->reposition_x_origin (frame);
1238 ARDOUR_UI::transport_stop ()
1244 if (session->is_auditioning()) {
1245 session->cancel_audition ();
1249 if (session->get_auto_loop()) {
1250 session->request_auto_loop (false);
1253 session->request_stop ();
1257 ARDOUR_UI::transport_stop_and_forget_capture ()
1260 session->request_stop (true);
1265 ARDOUR_UI::remove_last_capture()
1268 editor->remove_last_capture();
1273 ARDOUR_UI::transport_record ()
1276 switch (session->record_status()) {
1277 case Session::Disabled:
1278 if (session->ntracks() == 0) {
1279 string txt = _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu.");
1280 ArdourMessage msg (editor, X_("cannotrecenable"), txt);
1283 session->maybe_enable_record ();
1285 case Session::Recording:
1286 case Session::Enabled:
1287 session->disable_record ();
1293 ARDOUR_UI::transport_roll ()
1301 rolling = session->transport_rolling ();
1303 if (session->get_auto_loop()) {
1304 session->request_auto_loop (false);
1305 auto_loop_button.set_active (false);
1306 roll_button.set_active (true);
1307 } else if (session->get_play_range ()) {
1308 session->request_play_range (false);
1309 play_selection_button.set_active (false);
1310 } else if (rolling) {
1311 session->request_locate (session->last_transport_start(), true);
1314 session->request_transport_speed (1.0f);
1318 ARDOUR_UI::transport_loop()
1321 if (session->get_auto_loop()) {
1322 if (session->transport_rolling()) {
1323 Location * looploc = session->locations()->auto_loop_location();
1325 session->request_locate (looploc->start(), true);
1330 session->request_auto_loop (true);
1336 ARDOUR_UI::transport_play_selection ()
1342 if (!session->get_play_range()) {
1343 session->request_stop ();
1346 editor->play_selection ();
1350 ARDOUR_UI::transport_rewind (int option)
1352 float current_transport_speed;
1355 current_transport_speed = session->transport_speed();
1357 if (current_transport_speed >= 0.0f) {
1360 session->request_transport_speed (-1.0f);
1363 session->request_transport_speed (-4.0f);
1366 session->request_transport_speed (-0.5f);
1371 session->request_transport_speed (current_transport_speed * 1.5f);
1377 ARDOUR_UI::transport_forward (int option)
1379 float current_transport_speed;
1382 current_transport_speed = session->transport_speed();
1384 if (current_transport_speed <= 0.0f) {
1387 session->request_transport_speed (1.0f);
1390 session->request_transport_speed (4.0f);
1393 session->request_transport_speed (0.5f);
1398 session->request_transport_speed (current_transport_speed * 1.5f);
1404 ARDOUR_UI::toggle_monitor_enable (guint32 dstream)
1412 if ((ds = session->diskstream_by_id (dstream)) != 0) {
1413 Port *port = ds->io()->input (0);
1414 port->request_monitor_input (!port->monitoring_input());
1419 ARDOUR_UI::toggle_record_enable (guint32 dstream)
1427 if ((ds = session->diskstream_by_id (dstream)) != 0) {
1428 ds->set_record_enabled (!ds->record_enabled(), this);
1433 ARDOUR_UI::queue_transport_change ()
1435 Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
1439 ARDOUR_UI::map_transport_state ()
1441 float sp = session->transport_speed();
1444 transport_rolling ();
1445 } else if (sp < 0.0f) {
1446 transport_rewinding ();
1447 } else if (sp > 0.0f) {
1448 transport_forwarding ();
1450 transport_stopped ();
1455 ARDOUR_UI::send_all_midi_feedback ()
1458 session->send_all_midi_feedback();
1463 ARDOUR_UI::allow_local_only ()
1469 ARDOUR_UI::allow_mmc_only ()
1475 ARDOUR_UI::allow_mmc_and_local ()
1481 ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg)
1483 snprintf (buf, sizeof(buf), "%s", ((GlobalClickBox *) arg)->strings[
1484 (int) adj.get_value()].c_str());
1488 ARDOUR_UI::engine_stopped ()
1490 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
1491 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1492 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1497 ARDOUR_UI::engine_running ()
1499 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
1500 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true);
1501 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
1505 ARDOUR_UI::engine_halted ()
1507 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
1509 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1510 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1512 update_sample_rate (0);
1514 ArdourMessage msg (editor, X_("halted"),
1516 JACK has either been shutdown or it\n\
1517 disconnected Ardour because Ardour\n\
1518 was not fast enough. You can save the\n\
1519 session and/or try to reconnect to JACK ."));
1523 ARDOUR_UI::do_engine_start ()
1529 catch (AudioEngine::PortRegistrationFailure& err) {
1531 error << _("Unable to create all required ports")
1539 error << _("Unable to start the session running")
1549 ARDOUR_UI::start_engine ()
1551 if (do_engine_start () == 0) {
1552 if (session && _session_is_new) {
1553 /* we need to retain initial visual
1554 settings for a new session
1556 session->save_state ("");
1559 /* there is too much going on, in too many threads, for us to
1560 end up with a clean session. So wait 1 second after loading,
1561 and fix it up. its ugly, but until i come across a better
1562 solution, its what we have.
1565 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::make_session_clean), 1000);
1572 ARDOUR_UI::update_clocks ()
1574 Clock (session->audible_frame()); /* EMIT_SIGNAL */
1578 ARDOUR_UI::start_clocking ()
1580 clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
1584 ARDOUR_UI::stop_clocking ()
1586 clock_signal_connection.disconnect ();
1590 ARDOUR_UI::toggle_clocking ()
1593 if (clock_button.get_active()) {
1602 ARDOUR_UI::_blink (void *arg)
1605 ((ARDOUR_UI *) arg)->blink ();
1612 Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
1616 ARDOUR_UI::start_blinking ()
1618 /* Start the blink signal. Everybody with a blinking widget
1619 uses Blink to drive the widget's state.
1622 if (blink_timeout_tag < 0) {
1624 blink_timeout_tag = gtk_timeout_add (240, _blink, this);
1629 ARDOUR_UI::stop_blinking ()
1631 if (blink_timeout_tag >= 0) {
1632 gtk_timeout_remove (blink_timeout_tag);
1633 blink_timeout_tag = -1;
1639 ARDOUR_UI::add_diskstream_to_menu (DiskStream& dstream)
1641 using namespace Gtk;
1642 using namespace Menu_Helpers;
1644 if (dstream.hidden()) {
1648 MenuList& items = diskstream_menu->items();
1649 items.push_back (MenuElem (dstream.name(), bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), (gint32) dstream.id())));
1653 ARDOUR_UI::diskstream_selected (gint32 id)
1655 selected_dstream = id;
1660 ARDOUR_UI::select_diskstream (GdkEventButton *ev)
1662 using namespace Gtk;
1663 using namespace Menu_Helpers;
1669 diskstream_menu = new Menu();
1670 diskstream_menu->set_name ("ArdourContextMenu");
1671 using namespace Gtk;
1672 using namespace Menu_Helpers;
1674 MenuList& items = diskstream_menu->items();
1675 items.push_back (MenuElem (_("No Stream"), (bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), -1))));
1677 session->foreach_diskstream (this, &ARDOUR_UI::add_diskstream_to_menu);
1680 diskstream_menu->popup (ev->button, ev->time);
1682 diskstream_menu->popup (0, 0);
1685 selected_dstream = -1;
1689 delete diskstream_menu;
1691 return selected_dstream;
1695 ARDOUR_UI::name_io_setup (AudioEngine& engine,
1701 if (io.n_inputs() == 0) {
1706 /* XXX we're not handling multiple ports yet. */
1708 const char **connections = io.input(0)->get_connections();
1710 if (connections == 0 || connections[0] == '\0') {
1713 buf = connections[0];
1720 if (io.n_outputs() == 0) {
1725 /* XXX we're not handling multiple ports yet. */
1727 const char **connections = io.output(0)->get_connections();
1729 if (connections == 0 || connections[0] == '\0') {
1732 buf = connections[0];
1740 ARDOUR_UI::snapshot_session ()
1742 ArdourPrompter prompter (true);
1749 now = now.substr (0, now.length() - 1);
1751 prompter.set_name ("Prompter");
1752 prompter.set_prompt (_("Name for snapshot"));
1753 prompter.set_initial_text (now);
1755 switch (prompter.run()) {
1756 case RESPONSE_ACCEPT:
1757 prompter.get_result (snapname);
1758 if (snapname.length()){
1759 save_state (snapname);
1769 ARDOUR_UI::save_state (const string & name)
1771 (void) save_state_canfail (name);
1775 ARDOUR_UI::save_state_canfail (string name)
1780 if (name.length() == 0) {
1781 name = session->snap_name();
1784 if ((ret = session->save_state (name)) != 0) {
1788 save_ardour_state (); /* XXX cannot fail? yeah, right ... */
1793 ARDOUR_UI::restore_state (string name)
1796 if (name.length() == 0) {
1797 name = session->name();
1799 session->restore_state (name);
1804 ARDOUR_UI::primary_clock_value_changed ()
1807 session->request_locate (primary_clock.current_time ());
1812 ARDOUR_UI::secondary_clock_value_changed ()
1815 session->request_locate (secondary_clock.current_time ());
1820 ARDOUR_UI::rec_enable_button_blink (bool onoff, DiskStream *dstream, Widget *w)
1822 if (session && dstream && dstream->record_enabled()) {
1824 Session::RecordState rs;
1826 rs = session->record_status ();
1829 case Session::Disabled:
1830 case Session::Enabled:
1831 if (w->get_state() != STATE_SELECTED) {
1832 w->set_state (STATE_SELECTED);
1836 case Session::Recording:
1837 if (w->get_state() != STATE_ACTIVE) {
1838 w->set_state (STATE_ACTIVE);
1844 if (w->get_state() != STATE_NORMAL) {
1845 w->set_state (STATE_NORMAL);
1851 ARDOUR_UI::transport_rec_enable_blink (bool onoff)
1857 switch (session->record_status()) {
1858 case Session::Enabled:
1860 rec_button.set_state (1);
1862 rec_button.set_state (0);
1866 case Session::Recording:
1867 rec_button.set_state (2);
1871 rec_button.set_state (0);
1877 ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
1885 ARDOUR_UI::start_keyboard_prefix ()
1887 keyboard->start_prefix();
1891 ARDOUR_UI::save_template ()
1894 ArdourPrompter prompter (true);
1897 prompter.set_name (X_("Prompter"));
1898 prompter.set_prompt (_("Name for mix template:"));
1899 prompter.set_initial_text(session->name() + _("-template"));
1901 switch (prompter.run()) {
1902 case RESPONSE_ACCEPT:
1903 prompter.get_result (name);
1905 if (name.length()) {
1906 session->save_template (name);
1916 ARDOUR_UI::new_session (bool startup, std::string predetermined_path)
1918 m_new_session_dialog->show_all();
1919 m_new_session_dialog->set_transient_for(*editor);
1920 m_new_session_dialog->set_name(predetermined_path);
1922 int response = Gtk::RESPONSE_CANCEL;
1925 response = m_new_session_dialog->run ();
1927 if(response == Gtk::RESPONSE_OK) {
1929 _session_is_new = true;
1931 std::string session_name = m_new_session_dialog->session_name();
1932 std::string session_path = m_new_session_dialog->session_folder();
1935 XXX This is needed because session constructor wants a
1936 non-existant path. hopefully this will be fixed at some point.
1938 session_path = Glib::build_filename(session_path, session_name);
1940 std::string template_name = m_new_session_dialog->session_template_name();
1942 if (m_new_session_dialog->use_session_template()) {
1944 load_session (session_path, session_name, &template_name);
1950 Session::AutoConnectOption iconnect;
1951 Session::AutoConnectOption oconnect;
1953 if (m_new_session_dialog->create_control_bus()) {
1954 cchns = (uint32_t) m_new_session_dialog->control_channel_count();
1959 if (m_new_session_dialog->create_master_bus()) {
1960 mchns = (uint32_t) m_new_session_dialog->master_channel_count();
1965 if (m_new_session_dialog->connect_inputs()) {
1966 iconnect = Session::AutoConnectPhysical;
1968 iconnect = Session::AutoConnectOption (0);
1971 /// @todo some minor tweaks.
1973 if (m_new_session_dialog->connect_outs_to_master()) {
1974 oconnect = Session::AutoConnectMaster;
1975 } else if (m_new_session_dialog->connect_outs_to_physical()) {
1976 oconnect = Session::AutoConnectPhysical;
1978 oconnect = Session::AutoConnectOption (0);
1981 uint32_t nphysin = (uint32_t) m_new_session_dialog->input_limit_count();
1982 uint32_t nphysout = (uint32_t) m_new_session_dialog->output_limit_count();
1984 build_session (session_path,
1992 engine->frame_rate() * 60 * 5);
1996 } while(response == Gtk::RESPONSE_HELP);
1997 m_new_session_dialog->hide_all();
2001 ARDOUR_UI::load_session (const string & path, const string & snap_name, string* mix_template)
2003 Session *new_session;
2005 session_loaded = false;
2006 x = unload_session ();
2014 /* if it already exists, we must have write access */
2016 if (::access (path.c_str(), F_OK) == 0 && ::access (path.c_str(), W_OK)) {
2017 ArdourMessage msg (editor, X_("noaccess dialog"), _("\
2018 You do not have write access to this session.\n\
2019 This prevents the session from being loaded."));
2024 new_session = new Session (*engine, path, snap_name, mix_template);
2029 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
2033 connect_to_session (new_session);
2035 //if (engine->running()) {
2036 //mixer->show_window();
2038 session_loaded = true;
2043 ARDOUR_UI::make_session_clean ()
2046 session->set_clean ();
2053 ARDOUR_UI::build_session (const string & path, const string & snap_name,
2054 uint32_t control_channels,
2055 uint32_t master_channels,
2056 Session::AutoConnectOption input_connect,
2057 Session::AutoConnectOption output_connect,
2060 jack_nframes_t initial_length)
2062 Session *new_session;
2065 session_loaded = false;
2066 x = unload_session ();
2073 _session_is_new = true;
2076 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
2077 control_channels, master_channels, nphysin, nphysout, initial_length);
2082 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
2086 connect_to_session (new_session);
2088 //if (engine->running()) {
2089 //mixer->show_window();
2091 session_loaded = true;
2099 editor->show_window ();
2103 if (session && mixer) {
2104 // mixer->show_window ();
2113 ARDOUR_UI::show_splash ()
2116 about = new About();
2122 ARDOUR_UI::hide_splash ()
2130 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title, const string & msg)
2134 removed = rep.paths.size();
2137 ArdourMessage msg (editor, X_("cleanupresults"),
2139 No audio files were ready for cleanup\n\n\
2140 If this seems suprising, check for any existing\n\
2141 snapshots. These may still include regions that\n\
2142 require some unused files to continue to exist."));
2146 ArdourDialog results (_("ardour: cleanup"), true);
2148 struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
2149 CleanupResultsModelColumns() {
2153 Gtk::TreeModelColumn<Glib::ustring> visible_name;
2154 Gtk::TreeModelColumn<Glib::ustring> fullpath;
2158 Glib::RefPtr<Gtk::ListStore> results_model;
2159 CleanupResultsModelColumns results_columns;
2160 Gtk::TreeView results_display;
2162 results_model = ListStore::create (results_columns);
2163 results_display.set_model (results_model);
2164 results_display.append_column (list_title, results_columns.visible_name);
2165 results_display.set_headers_visible (true);
2167 Gtk::ScrolledWindow list_scroller;
2170 if (rep.space < 1048576.0f) {
2172 txt.set_text (string_compose (msg, removed, _("files"), (float) rep.space / 1024.0f, "kilo"));
2174 txt.set_text (string_compose (msg, removed, _("file"), (float) rep.space / 1024.0f, "kilo"));
2178 txt.set_text (string_compose (msg, removed, _("files"), (float) rep.space / 1048576.0f, "mega"));
2180 txt.set_text (string_compose (msg, removed, _("file"), (float) rep.space / 1048576.0f, "mega"));
2184 results.get_vbox()->pack_start (txt, false, false);
2186 for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2187 TreeModel::Row row = *(results_model->append());
2188 row[results_columns.visible_name] = *i;
2189 row[results_columns.fullpath] = *i;
2192 list_scroller.add (results_display);
2193 list_scroller.set_size_request (-1, 250);
2194 list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2196 results.get_vbox()->pack_start (list_scroller, true, true);
2197 results.add_button (Stock::OK, RESPONSE_ACCEPT);
2198 results.set_position (Gtk::WIN_POS_MOUSE);
2204 ARDOUR_UI::cleanup ()
2207 /* shouldn't happen: menu item is insensitive */
2211 ArdourDialog checker (_("ardour cleanup"));
2212 Gtk::Label label (_("\
2213 Cleanup is a destructive operation.\n\
2214 ALL undo/redo information will be lost if you cleanup.\n\
2215 Unused audio files will be moved to a \"dead sounds\" location."));
2217 checker.get_vbox()->pack_start (label, false, false);
2218 checker.add_button (Stock::OK, RESPONSE_ACCEPT);
2219 checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2221 checker.set_name (_("CleanupDialog"));
2222 checker.set_wmclass (_("ardour_cleanup"), "Ardour");
2223 checker.set_position (Gtk::WIN_POS_MOUSE);
2225 switch (checker.run()) {
2226 case RESPONSE_ACCEPT:
2232 Session::cleanup_report rep;
2234 editor->prepare_for_cleanup ();
2236 if (session->cleanup_sources (rep)) {
2240 display_cleanup_results (rep,
2243 The following %1 %2 were not in use.\n\
2244 The next time you flush the wastebasket\n\
2245 it will release an additional %3 %4bytes\n\
2251 ARDOUR_UI::flush_trash ()
2254 /* shouldn't happen: menu item is insensitive */
2258 Session::cleanup_report rep;
2260 if (session->cleanup_trash_sources (rep)) {
2264 display_cleanup_results (rep,
2266 _("The following %1 file%2 were deleted, releasing %3 %4bytes of disk space"));
2270 ARDOUR_UI::add_route ()
2278 if (add_route_dialog == 0) {
2279 add_route_dialog = new AddRouteDialog;
2280 editor->ensure_float (*add_route_dialog);
2283 if (add_route_dialog->is_visible()) {
2284 /* we're already doing this */
2288 ResponseType r = (ResponseType) add_route_dialog->run ();
2290 add_route_dialog->hide();
2293 case RESPONSE_ACCEPT:
2300 if ((count = add_route_dialog->count()) <= 0) {
2304 uint32_t input_chan = add_route_dialog->channels ();
2305 uint32_t output_chan;
2306 string name_template = add_route_dialog->name_template ();
2307 bool track = add_route_dialog->track ();
2309 Session::AutoConnectOption oac = session->get_output_auto_connect();
2311 if (oac & Session::AutoConnectMaster) {
2312 output_chan = (session->master_out() ? session->master_out()->n_inputs() : input_chan);
2314 output_chan = input_chan;
2317 /* XXX do something with name template */
2321 session_add_audio_track (input_chan, output_chan);
2323 session_add_audio_bus (input_chan, output_chan);
2327 while (Main::events_pending()) {
2334 ARDOUR_UI::mixer_settings () const
2339 node = session->instant_xml(X_("Mixer"), session->path());
2341 node = Config->instant_xml(X_("Mixer"), Config->get_user_ardour_path());
2345 node = new XMLNode (X_("Mixer"));
2352 ARDOUR_UI::editor_settings () const
2357 node = session->instant_xml(X_("Editor"), session->path());
2359 node = Config->instant_xml(X_("Editor"), Config->get_user_ardour_path());
2363 node = new XMLNode (X_("Editor"));
2369 ARDOUR_UI::keyboard_settings () const
2373 node = Config->extra_xml(X_("Keyboard"));
2376 node = new XMLNode (X_("Keyboard"));
2382 ARDOUR_UI::halt_on_xrun_message ()
2384 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
2386 ArdourMessage msg (editor, X_("haltonxrun"),
2387 _("Recording was stopped because your system could not keep up."));
2391 ARDOUR_UI::delete_sources_in_the_right_thread (list<ARDOUR::Source*>* deletion_list)
2393 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread), deletion_list));
2395 for (list<Source*>::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) {
2399 delete deletion_list;
2403 ARDOUR_UI::disk_overrun_handler ()
2405 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2407 if (!have_disk_overrun_displayed) {
2408 have_disk_overrun_displayed = true;
2409 ArdourMessage msg (editor, X_("diskrate dialog"), _("\
2410 The disk system on your computer\n\
2411 was not able to keep up with Ardour.\n\
2413 Specifically, it failed to write data to disk\n\
2414 quickly enough to keep up with recording.\n"));
2415 have_disk_overrun_displayed = false;
2420 ARDOUR_UI::disk_underrun_handler ()
2422 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2424 if (!have_disk_underrun_displayed) {
2425 have_disk_underrun_displayed = true;
2426 ArdourMessage msg (editor, X_("diskrate2 dialog"),
2427 (_("The disk system on your computer\n\
2428 was not able to keep up with Ardour.\n\
2430 Specifically, it failed to read data from disk\n\
2431 quickly enough to keep up with playback.\n")));
2432 have_disk_underrun_displayed = false;
2437 ARDOUR_UI::disk_underrun_message_gone ()
2439 have_disk_underrun_displayed = false;
2443 ARDOUR_UI::disk_overrun_message_gone ()
2445 have_disk_underrun_displayed = false;
2449 ARDOUR_UI::pending_state_dialog ()
2451 ArdourDialog dialog ("pending state dialog");
2453 This session appears to have been in\n\
2454 middle of recording when ardour or\n\
2455 the computer was shutdown.\n\
2457 Ardour can recover any captured audio for\n\
2458 you, or it can ignore it. Please decide\n\
2459 what you would like to do.\n"));
2461 dialog.get_vbox()->pack_start (message);
2462 dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
2463 dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
2465 dialog.set_position (WIN_POS_CENTER);
2468 switch (dialog.run ()) {
2469 case RESPONSE_ACCEPT:
2480 ARDOUR_UI::disconnect_from_jack ()
2483 if( engine->disconnect_from_jack ()) {
2484 ArdourMessage msg (editor, X_("nojack dialog"),
2485 _("Could not disconnect from JACK"));
2488 update_sample_rate (0);
2493 ARDOUR_UI::reconnect_to_jack ()
2496 if (engine->reconnect_to_jack ()) {
2497 ArdourMessage msg (editor, X_("nojack dialog"),
2498 _("Could not reconnect to JACK"));
2501 update_sample_rate (0);
2506 ARDOUR_UI::set_jack_buffer_size (jack_nframes_t nframes)
2508 engine->request_buffer_size (nframes);
2509 update_sample_rate (0);
2513 ARDOUR_UI::cmdline_new_session (string path)
2515 if (path[0] != '/') {
2516 char buf[PATH_MAX+1];
2519 getcwd (buf, sizeof (buf));
2526 new_session (false, path);
2528 _will_create_new_session_automatically = false; /* done it */
2529 return FALSE; /* don't call it again */