2 Copyright (C) 1999-2007 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #define __STDC_FORMAT_MACROS 1
33 #include <sys/resource.h>
35 #include <gtkmm/messagedialog.h>
36 #include <gtkmm/accelmap.h>
38 #include <pbd/error.h>
39 #include <pbd/compose.h>
40 #include <pbd/failed_constructor.h>
41 #include <pbd/enumwriter.h>
42 #include <pbd/memento_command.h>
43 #include <pbd/file_utils.h>
45 #include <gtkmm2ext/gtk_ui.h>
46 #include <gtkmm2ext/utils.h>
47 #include <gtkmm2ext/click_box.h>
48 #include <gtkmm2ext/fastmeter.h>
49 #include <gtkmm2ext/stop_signal.h>
50 #include <gtkmm2ext/popup.h>
51 #include <gtkmm2ext/window_title.h>
53 #include <midi++/port.h>
54 #include <midi++/mmc.h>
56 #include <ardour/ardour.h>
57 #include <ardour/profile.h>
58 #include <ardour/session_directory.h>
59 #include <ardour/session_route.h>
60 #include <ardour/session_utils.h>
61 #include <ardour/port.h>
62 #include <ardour/audioengine.h>
63 #include <ardour/playlist.h>
64 #include <ardour/utils.h>
65 #include <ardour/audio_diskstream.h>
66 #include <ardour/audiofilesource.h>
67 #include <ardour/recent_sessions.h>
68 #include <ardour/port.h>
69 #include <ardour/audio_track.h>
70 #include <ardour/midi_track.h>
71 #include <ardour/filesystem_paths.h>
74 #include "ardour_ui.h"
75 #include "public_editor.h"
76 #include "audio_clock.h"
81 #include "add_route_dialog.h"
82 #include "new_session_dialog.h"
85 #include "gui_thread.h"
86 #include "theme_manager.h"
91 using namespace ARDOUR;
93 using namespace Gtkmm2ext;
97 ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
98 UIConfiguration *ARDOUR_UI::ui_config = 0;
100 sigc::signal<void,bool> ARDOUR_UI::Blink;
101 sigc::signal<void> ARDOUR_UI::RapidScreenUpdate;
102 sigc::signal<void> ARDOUR_UI::SuperRapidScreenUpdate;
103 sigc::signal<void,nframes_t, bool, nframes_t> ARDOUR_UI::Clock;
105 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
107 : Gtkmm2ext::UI (X_("Ardour"), argcp, argvp),
109 primary_clock (X_("primary"), false, X_("TransportClockDisplay"), true, false, true),
110 secondary_clock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, false, true),
111 preroll_clock (X_("preroll"), false, X_("PreRollClock"), true, true),
112 postroll_clock (X_("postroll"), false, X_("PostRollClock"), true, true),
116 adjuster_table (3, 3),
120 preroll_button (_("pre\nroll")),
121 postroll_button (_("post\nroll")),
125 big_clock (X_("bigclock"), false, "BigClockNonRecording", false, false, true),
129 roll_controllable ("transport roll", *this, TransportControllable::Roll),
130 stop_controllable ("transport stop", *this, TransportControllable::Stop),
131 goto_start_controllable ("transport goto start", *this, TransportControllable::GotoStart),
132 goto_end_controllable ("transport goto end", *this, TransportControllable::GotoEnd),
133 auto_loop_controllable ("transport auto loop", *this, TransportControllable::AutoLoop),
134 play_selection_controllable ("transport play selection", *this, TransportControllable::PlaySelection),
135 rec_controllable ("transport rec-enable", *this, TransportControllable::RecordEnable),
136 shuttle_controllable ("shuttle", *this, TransportControllable::ShuttleControl),
137 shuttle_controller_binding_proxy (shuttle_controllable),
139 roll_button (roll_controllable),
140 stop_button (stop_controllable),
141 goto_start_button (goto_start_controllable),
142 goto_end_button (goto_end_controllable),
143 auto_loop_button (auto_loop_controllable),
144 play_selection_button (play_selection_controllable),
145 rec_button (rec_controllable),
147 shuttle_units_button (_("% ")),
149 punch_in_button (_("Punch In")),
150 punch_out_button (_("Punch Out")),
151 auto_return_button (_("Auto Return")),
152 auto_play_button (_("Auto Play")),
153 auto_input_button (_("Auto Input")),
154 click_button (_("Click")),
155 time_master_button (_("time\nmaster")),
157 auditioning_alert_button (_("AUDITION")),
158 solo_alert_button (_("SOLO")),
161 using namespace Gtk::Menu_Helpers;
167 if (theArdourUI == 0) {
171 ui_config = new UIConfiguration();
172 theme_manager = new ThemeManager();
177 _session_is_new = false;
178 big_clock_window = 0;
179 session_selector_window = 0;
180 last_key_press_time = 0;
181 connection_editor = 0;
182 add_route_dialog = 0;
186 open_session_selector = 0;
187 have_configure_timeout = false;
188 have_disk_speed_dialog_displayed = false;
189 session_loaded = false;
190 last_speed_displayed = -1.0f;
193 sys::path key_bindings_file;
195 find_file_in_search_path (ardour_search_path() + system_config_search_path(),
196 "ardour.bindings", key_bindings_file);
198 keybindings_path = key_bindings_file.to_string();
200 /* store all bindings changes in per-user file, no matter where they were loaded from */
201 user_keybindings_path = user_config_directory().to_string ();
202 user_keybindings_path += '/';
203 user_keybindings_path += "ardour.bindings";
205 can_save_keybindings = false;
207 last_configure_time.tv_sec = 0;
208 last_configure_time.tv_usec = 0;
210 shuttle_grabbed = false;
212 shuttle_max_speed = 8.0f;
214 shuttle_style_menu = 0;
215 shuttle_unit_menu = 0;
217 gettimeofday (&last_peak_grab, 0);
218 gettimeofday (&last_shuttle_request, 0);
220 ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
221 ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
223 /* handle pending state with a dialog */
225 ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
227 /* have to wait for AudioEngine and Configuration before proceeding */
231 ARDOUR_UI::set_engine (AudioEngine& e)
235 engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
236 engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
237 engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
238 engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
240 ActionManager::init ();
241 new_session_dialog = new NewSessionDialog();
245 keyboard = new Keyboard;
247 if (setup_windows ()) {
248 throw failed_constructor ();
251 if (GTK_ARDOUR::show_key_actions) {
252 vector<string> names;
253 vector<string> paths;
255 vector<AccelKey> bindings;
257 ActionManager::get_all_actions (names, paths, keys, bindings);
259 vector<string>::iterator n;
260 vector<string>::iterator k;
261 for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) {
262 cerr << "Action: " << (*n) << " bound to " << (*k) << endl;
268 /* start with timecode, metering enabled
271 blink_timeout_tag = -1;
273 /* the global configuration object is now valid */
277 /* this being a GUI and all, we want peakfiles */
279 AudioFileSource::set_build_peakfiles (true);
280 AudioFileSource::set_build_missing_peakfiles (true);
282 /* set default clock modes */
284 primary_clock.set_mode (AudioClock::SMPTE);
285 secondary_clock.set_mode (AudioClock::BBT);
287 /* start the time-of-day-clock */
289 update_wall_clock ();
290 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
292 update_disk_space ();
294 update_sample_rate (engine->frame_rate());
296 starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
297 stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
300 ARDOUR_UI::~ARDOUR_UI ()
302 save_ardour_state ();
316 if (add_route_dialog) {
317 delete add_route_dialog;
322 ARDOUR_UI::configure_timeout ()
327 if (last_configure_time.tv_sec == 0 && last_configure_time.tv_usec == 0) {
328 /* no configure events yet */
332 gettimeofday (&now, 0);
333 timersub (&now, &last_configure_time, &diff);
335 /* force a gap of 0.5 seconds since the last configure event
338 if (diff.tv_sec == 0 && diff.tv_usec < 500000) {
341 have_configure_timeout = false;
342 save_ardour_state ();
348 ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
350 if (have_configure_timeout) {
351 gettimeofday (&last_configure_time, 0);
353 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
354 have_configure_timeout = true;
361 ARDOUR_UI::set_transport_controllable_state (const XMLNode& node)
363 const XMLProperty* prop;
365 if ((prop = node.property ("roll")) != 0) {
366 roll_controllable.set_id (prop->value());
368 if ((prop = node.property ("stop")) != 0) {
369 stop_controllable.set_id (prop->value());
371 if ((prop = node.property ("goto_start")) != 0) {
372 goto_start_controllable.set_id (prop->value());
374 if ((prop = node.property ("goto_end")) != 0) {
375 goto_end_controllable.set_id (prop->value());
377 if ((prop = node.property ("auto_loop")) != 0) {
378 auto_loop_controllable.set_id (prop->value());
380 if ((prop = node.property ("play_selection")) != 0) {
381 play_selection_controllable.set_id (prop->value());
383 if ((prop = node.property ("rec")) != 0) {
384 rec_controllable.set_id (prop->value());
386 if ((prop = node.property ("shuttle")) != 0) {
387 shuttle_controllable.set_id (prop->value());
392 ARDOUR_UI::get_transport_controllable_state ()
394 XMLNode* node = new XMLNode(X_("TransportControllables"));
397 roll_controllable.id().print (buf, sizeof (buf));
398 node->add_property (X_("roll"), buf);
399 stop_controllable.id().print (buf, sizeof (buf));
400 node->add_property (X_("stop"), buf);
401 goto_start_controllable.id().print (buf, sizeof (buf));
402 node->add_property (X_("goto_start"), buf);
403 goto_end_controllable.id().print (buf, sizeof (buf));
404 node->add_property (X_("goto_end"), buf);
405 auto_loop_controllable.id().print (buf, sizeof (buf));
406 node->add_property (X_("auto_loop"), buf);
407 play_selection_controllable.id().print (buf, sizeof (buf));
408 node->add_property (X_("play_selection"), buf);
409 rec_controllable.id().print (buf, sizeof (buf));
410 node->add_property (X_("rec"), buf);
411 shuttle_controllable.id().print (buf, sizeof (buf));
412 node->add_property (X_("shuttle"), buf);
418 ARDOUR_UI::save_ardour_state ()
420 if (!keyboard || !mixer || !editor) {
424 /* XXX this is all a bit dubious. add_extra_xml() uses
425 a different lifetime model from add_instant_xml().
428 XMLNode* node = new XMLNode (keyboard->get_state());
429 Config->add_extra_xml (*node);
430 Config->add_extra_xml (get_transport_controllable_state());
431 Config->save_state();
433 XMLNode enode(static_cast<Stateful*>(editor)->get_state());
434 XMLNode mnode(mixer->get_state());
437 session->add_instant_xml (enode);
438 session->add_instant_xml (mnode);
440 Config->add_instant_xml (enode);
441 Config->add_instant_xml (mnode);
448 ARDOUR_UI::autosave_session ()
450 if (!Config->get_periodic_safety_backups())
454 session->maybe_write_autosave();
461 ARDOUR_UI::update_autosave ()
463 ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::update_autosave));
465 if (session->dirty()) {
466 if (_autosave_connection.connected()) {
467 _autosave_connection.disconnect();
470 _autosave_connection = Glib::signal_timeout().connect (mem_fun (*this, &ARDOUR_UI::autosave_session),
471 Config->get_periodic_safety_backup_interval() * 1000);
474 if (_autosave_connection.connected()) {
475 _autosave_connection.disconnect();
481 ARDOUR_UI::startup ()
483 check_memory_locking();
487 ARDOUR_UI::no_memory_warning ()
489 XMLNode node (X_("no-memory-warning"));
490 Config->add_instant_xml (node);
494 ARDOUR_UI::check_memory_locking ()
497 /* OS X doesn't support mlockall(2), and so testing for memory locking capability there is pointless */
501 XMLNode* memory_warning_node = Config->instant_xml (X_("no-memory-warning"));
503 if (engine->is_realtime() && memory_warning_node == 0) {
505 struct rlimit limits;
507 long pages, page_size;
509 if ((page_size = sysconf (_SC_PAGESIZE)) < 0 ||(pages = sysconf (_SC_PHYS_PAGES)) < 0) {
512 ram = (int64_t) pages * (int64_t) page_size;
515 if (getrlimit (RLIMIT_MEMLOCK, &limits)) {
519 if (limits.rlim_cur != RLIM_INFINITY) {
521 if (ram == 0 || ((double) limits.rlim_cur / ram) < 0.75) {
524 MessageDialog msg (_("WARNING: Your system has a limit for maximum amount of locked memory. "
525 "This might cause Ardour to run out of memory before your system "
526 "runs out of memory. \n\n"
527 "You can view the memory limit with 'ulimit -l', "
528 "and it is normally controlled by /etc/security/limits.conf"));
530 VBox* vbox = msg.get_vbox();
532 CheckButton cb (_("Do not show this window again"));
534 cb.signal_toggled().connect (mem_fun (*this, &ARDOUR_UI::no_memory_warning));
536 hbox.pack_start (cb, true, false);
537 vbox->pack_start (hbox);
542 editor->ensure_float (msg);
554 if (session && session->dirty()) {
555 switch (ask_about_saving_session(_("quit"))) {
560 /* use the default name */
561 if (save_state_canfail ("")) {
562 /* failed - don't quit */
563 MessageDialog msg (*editor,
565 Ardour was unable to save your session.\n\n\
566 If you still wish to quit, please use the\n\n\
567 \"Just quit\" option."));
578 session->set_deletion_in_progress ();
581 Config->save_state();
582 ARDOUR_UI::config()->save_state();
587 ARDOUR_UI::ask_about_saving_session (const string & what)
589 ArdourDialog window (_("ardour: save session?"));
590 Gtk::HBox dhbox; // the hbox for the image and text
591 Gtk::Label prompt_label;
592 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_WARNING, Gtk::ICON_SIZE_DIALOG));
596 msg = string_compose(_("Don't %1"), what);
597 window.add_button (msg, RESPONSE_REJECT);
598 msg = string_compose(_("Just %1"), what);
599 window.add_button (msg, RESPONSE_APPLY);
600 msg = string_compose(_("Save and %1"), what);
601 window.add_button (msg, RESPONSE_ACCEPT);
603 window.set_default_response (RESPONSE_ACCEPT);
605 Gtk::Button noquit_button (msg);
606 noquit_button.set_name ("EditorGTKButton");
611 if (session->snap_name() == session->name()) {
614 type = _("snapshot");
616 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?"),
617 type, session->snap_name());
619 prompt_label.set_text (prompt);
620 prompt_label.set_name (X_("PrompterLabel"));
621 prompt_label.set_alignment(ALIGN_LEFT, ALIGN_TOP);
623 dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP)
625 dhbox.set_homogeneous (false);
626 dhbox.pack_start (*dimage, false, false, 5);
627 dhbox.pack_start (prompt_label, true, false, 5);
628 window.get_vbox()->pack_start (dhbox);
630 window.set_name (_("Prompter"));
631 window.set_position (Gtk::WIN_POS_MOUSE);
632 window.set_modal (true);
633 window.set_resizable (false);
640 save_the_session = 0;
642 window.set_keep_above (true);
645 ResponseType r = (ResponseType) window.run();
650 case RESPONSE_ACCEPT: // save and get out of here
652 case RESPONSE_APPLY: // get out of here
662 ARDOUR_UI::every_second ()
665 update_buffer_load ();
666 update_disk_space ();
671 ARDOUR_UI::every_point_one_seconds ()
673 update_speed_display ();
674 RapidScreenUpdate(); /* EMIT_SIGNAL */
679 ARDOUR_UI::every_point_zero_one_seconds ()
681 SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
686 ARDOUR_UI::update_sample_rate (nframes_t ignored)
690 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
692 if (!engine->connected()) {
694 snprintf (buf, sizeof (buf), _("disconnected"));
698 nframes_t rate = engine->frame_rate();
700 if (fmod (rate, 1000.0) != 0.0) {
701 snprintf (buf, sizeof (buf), _("%.1f kHz / %4.1f ms"),
702 (float) rate/1000.0f,
703 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
705 snprintf (buf, sizeof (buf), _("%u kHz / %4.1f ms"),
707 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
711 sample_rate_label.set_text (buf);
715 ARDOUR_UI::update_cpu_load ()
718 snprintf (buf, sizeof (buf), _("DSP: %5.1f%%"), engine->get_cpu_load());
719 cpu_load_label.set_text (buf);
723 ARDOUR_UI::update_buffer_load ()
728 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"),
729 session->playback_load(), session->capture_load());
730 buffer_load_label.set_text (buf);
732 buffer_load_label.set_text ("");
737 ARDOUR_UI::count_recenabled_streams (Route& route)
739 Track* track = dynamic_cast<Track*>(&route);
740 if (track && track->diskstream()->record_enabled()) {
741 rec_enabled_streams += track->n_inputs().n_total();
746 ARDOUR_UI::update_disk_space()
752 nframes_t frames = session->available_capture_duration();
755 if (frames == max_frames) {
756 strcpy (buf, _("Disk: 24hrs+"));
761 nframes_t fr = session->frame_rate();
763 rec_enabled_streams = 0;
764 session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
766 if (rec_enabled_streams) {
767 frames /= rec_enabled_streams;
770 hrs = frames / (fr * 3600);
771 frames -= hrs * fr * 3600;
772 mins = frames / (fr * 60);
773 frames -= mins * fr * 60;
776 snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs);
779 disk_space_label.set_text (buf);
783 ARDOUR_UI::update_wall_clock ()
790 tm_now = localtime (&now);
792 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
793 wall_clock_label.set_text (buf);
799 ARDOUR_UI::session_menu (GdkEventButton *ev)
801 session_popup_menu->popup (0, 0);
806 ARDOUR_UI::redisplay_recent_sessions ()
808 vector<string *> *sessions;
809 vector<string *>::iterator i;
810 RecentSessionsSorter cmp;
812 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
813 recent_session_model->clear ();
816 ARDOUR::read_recent_sessions (rs);
819 recent_session_display.set_model (recent_session_model);
823 /* sort them alphabetically */
824 sort (rs.begin(), rs.end(), cmp);
825 sessions = new vector<string*>;
827 for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
828 sessions->push_back (new string ((*i).second));
831 for (i = sessions->begin(); i != sessions->end(); ++i) {
833 vector<string*>* states;
834 vector<const gchar*> item;
835 string fullpath = *(*i);
837 /* remove any trailing / */
839 if (fullpath[fullpath.length()-1] == '/') {
840 fullpath = fullpath.substr (0, fullpath.length()-1);
843 /* now get available states for this session */
845 if ((states = Session::possible_states (fullpath)) == 0) {
850 TreeModel::Row row = *(recent_session_model->append());
852 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
853 row[recent_session_columns.fullpath] = fullpath;
855 if (states->size() > 1) {
857 /* add the children */
859 for (vector<string*>::iterator i2 = states->begin(); i2 != states->end(); ++i2) {
861 TreeModel::Row child_row = *(recent_session_model->append (row.children()));
863 child_row[recent_session_columns.visible_name] = **i2;
864 child_row[recent_session_columns.fullpath] = fullpath;
873 recent_session_display.set_model (recent_session_model);
878 ARDOUR_UI::build_session_selector ()
880 session_selector_window = new ArdourDialog ("session selector");
882 Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
884 session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
885 session_selector_window->add_button (Stock::OPEN, RESPONSE_ACCEPT);
886 session_selector_window->set_default_response (RESPONSE_ACCEPT);
887 recent_session_model = TreeStore::create (recent_session_columns);
888 recent_session_display.set_model (recent_session_model);
889 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
890 recent_session_display.set_headers_visible (false);
891 recent_session_display.get_selection()->set_mode (SELECTION_SINGLE);
893 recent_session_display.signal_row_activated().connect (mem_fun (*this, &ARDOUR_UI::recent_session_row_activated));
895 scroller->add (recent_session_display);
896 scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
898 session_selector_window->set_name ("SessionSelectorWindow");
899 session_selector_window->set_size_request (200, 400);
900 session_selector_window->get_vbox()->pack_start (*scroller);
902 recent_session_display.show();
904 //session_selector_window->get_vbox()->show();
908 ARDOUR_UI::recent_session_row_activated (const TreePath& path, TreeViewColumn* col)
910 session_selector_window->response (RESPONSE_ACCEPT);
914 ARDOUR_UI::open_recent_session ()
916 /* popup selector window */
918 if (session_selector_window == 0) {
919 build_session_selector ();
922 redisplay_recent_sessions ();
924 ResponseType r = (ResponseType) session_selector_window->run ();
926 session_selector_window->hide();
929 case RESPONSE_ACCEPT:
935 Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
937 if (i == recent_session_model->children().end()) {
941 Glib::ustring path = (*i)[recent_session_columns.fullpath];
942 Glib::ustring state = (*i)[recent_session_columns.visible_name];
944 _session_is_new = false;
946 load_session (path, state);
950 ARDOUR_UI::filter_ardour_session_dirs (const FileFilter::Info& info)
954 if (stat (info.filename.c_str(), &statbuf) != 0) {
958 if (!S_ISDIR(statbuf.st_mode)) {
964 string session_file = info.filename;
966 session_file += Glib::path_get_basename (info.filename);
967 session_file += ".ardour";
969 if (stat (session_file.c_str(), &statbuf) != 0) {
973 return S_ISREG (statbuf.st_mode);
977 ARDOUR_UI::check_audioengine ()
980 if (!engine->connected()) {
981 MessageDialog msg (_("Ardour is not connected to JACK\n"
982 "You cannot open or close sessions in this condition"));
993 ARDOUR_UI::open_session ()
995 if (!check_audioengine()) {
1000 /* popup selector window */
1002 if (open_session_selector == 0) {
1004 /* ardour sessions are folders */
1006 open_session_selector = new Gtk::FileChooserDialog (_("open session"), FILE_CHOOSER_ACTION_OPEN);
1007 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1008 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
1010 FileFilter session_filter;
1011 session_filter.add_pattern ("*.ardour");
1012 session_filter.set_name (_("Ardour sessions"));
1013 open_session_selector->add_filter (session_filter);
1014 open_session_selector->set_filter (session_filter);
1017 int response = open_session_selector->run();
1018 open_session_selector->hide ();
1021 case RESPONSE_ACCEPT:
1024 open_session_selector->hide();
1028 open_session_selector->hide();
1029 string session_path = open_session_selector->get_filename();
1033 if (session_path.length() > 0) {
1034 if (ARDOUR::find_session (session_path, path, name, isnew) == 0) {
1035 _session_is_new = isnew;
1036 load_session (path, name);
1043 ARDOUR_UI::session_add_midi_route (bool disk, uint32_t how_many)
1045 list<boost::shared_ptr<MidiTrack> > tracks;
1048 warning << _("You cannot add a track without a session already loaded.") << endmsg;
1055 tracks = session->new_midi_track (ARDOUR::Normal, how_many);
1057 if (tracks.size() != how_many) {
1058 if (how_many == 1) {
1059 error << _("could not create a new midi track") << endmsg;
1061 error << string_compose (_("could not create %1 new midi tracks"), how_many) << endmsg;
1065 if ((route = session->new_midi_route ()) == 0) {
1066 error << _("could not create new midi bus") << endmsg;
1072 MessageDialog msg (*editor,
1073 _("There are insufficient JACK ports available\n\
1074 to create a new track or bus.\n\
1075 You should save Ardour, exit and\n\
1076 restart JACK with more ports."));
1083 ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, uint32_t how_many)
1085 list<boost::shared_ptr<AudioTrack> > tracks;
1086 Session::RouteList routes;
1089 warning << _("You cannot add a track or bus without a session already loaded.") << endmsg;
1095 tracks = session->new_audio_track (input_channels, output_channels, mode, how_many);
1097 if (tracks.size() != how_many) {
1098 if (how_many == 1) {
1099 error << _("could not create a new audio track") << endmsg;
1101 error << string_compose (_("could only create %1 of %2 new audio %3"),
1102 tracks.size(), how_many, (track ? _("tracks") : _("busses"))) << endmsg;
1108 routes = session->new_audio_route (input_channels, output_channels, how_many);
1110 if (routes.size() != how_many) {
1111 if (how_many == 1) {
1112 error << _("could not create a new audio track") << endmsg;
1114 error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
1120 if (need_control_room_outs) {
1126 route->set_stereo_control_outs (control_lr_channels);
1127 route->control_outs()->set_stereo_pan (pans, this);
1129 #endif /* CONTROLOUTS */
1133 cerr << "About to complain about JACK\n";
1134 MessageDialog msg (*editor,
1135 _("There are insufficient JACK ports available\n\
1136 to create a new track or bus.\n\
1137 You should save Ardour, exit and\n\
1138 restart JACK with more ports."));
1144 ARDOUR_UI::do_transport_locate (nframes_t new_position)
1146 nframes_t _preroll = 0;
1149 // XXX CONFIG_CHANGE FIX - requires AnyTime handling
1150 // _preroll = session->convert_to_frames_at (new_position, Config->get_preroll());
1152 if (new_position > _preroll) {
1153 new_position -= _preroll;
1158 session->request_locate (new_position);
1163 ARDOUR_UI::transport_goto_start ()
1166 session->goto_start();
1169 /* force displayed area in editor to start no matter
1170 what "follow playhead" setting is.
1174 editor->reset_x_origin (session->current_start_frame());
1180 ARDOUR_UI::transport_goto_zero ()
1183 session->request_locate (0);
1186 /* force displayed area in editor to start no matter
1187 what "follow playhead" setting is.
1191 editor->reset_x_origin (0);
1197 ARDOUR_UI::transport_goto_end ()
1200 nframes_t frame = session->current_end_frame();
1201 session->request_locate (frame);
1203 /* force displayed area in editor to start no matter
1204 what "follow playhead" setting is.
1208 editor->reset_x_origin (frame);
1214 ARDOUR_UI::transport_stop ()
1220 if (session->is_auditioning()) {
1221 session->cancel_audition ();
1225 if (session->get_play_loop ()) {
1226 session->request_play_loop (false);
1229 session->request_stop ();
1233 ARDOUR_UI::transport_stop_and_forget_capture ()
1236 session->request_stop (true);
1241 ARDOUR_UI::remove_last_capture()
1244 editor->remove_last_capture();
1249 ARDOUR_UI::transport_record ()
1252 switch (session->record_status()) {
1253 case Session::Disabled:
1254 if (session->ntracks() == 0) {
1255 MessageDialog msg (*editor, _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu."));
1259 session->maybe_enable_record ();
1261 case Session::Recording:
1262 case Session::Enabled:
1263 session->disable_record (false, true);
1269 ARDOUR_UI::transport_roll ()
1277 rolling = session->transport_rolling ();
1279 if (session->get_play_loop()) {
1280 session->request_play_loop (false);
1281 auto_loop_button.set_visual_state (1);
1282 roll_button.set_visual_state (1);
1283 } else if (session->get_play_range ()) {
1284 session->request_play_range (false);
1285 play_selection_button.set_visual_state (0);
1286 } else if (rolling) {
1287 session->request_locate (session->last_transport_start(), true);
1290 session->request_transport_speed (1.0f);
1294 ARDOUR_UI::transport_loop()
1297 if (session->get_play_loop()) {
1298 if (session->transport_rolling()) {
1299 Location * looploc = session->locations()->auto_loop_location();
1301 session->request_locate (looploc->start(), true);
1306 session->request_play_loop (true);
1312 ARDOUR_UI::transport_play_selection ()
1318 if (!session->get_play_range()) {
1319 session->request_stop ();
1322 editor->play_selection ();
1326 ARDOUR_UI::transport_rewind (int option)
1328 float current_transport_speed;
1331 current_transport_speed = session->transport_speed();
1333 if (current_transport_speed >= 0.0f) {
1336 session->request_transport_speed (-1.0f);
1339 session->request_transport_speed (-4.0f);
1342 session->request_transport_speed (-0.5f);
1347 session->request_transport_speed (current_transport_speed * 1.5f);
1353 ARDOUR_UI::transport_forward (int option)
1355 float current_transport_speed;
1358 current_transport_speed = session->transport_speed();
1360 if (current_transport_speed <= 0.0f) {
1363 session->request_transport_speed (1.0f);
1366 session->request_transport_speed (4.0f);
1369 session->request_transport_speed (0.5f);
1374 session->request_transport_speed (current_transport_speed * 1.5f);
1380 ARDOUR_UI::toggle_record_enable (uint32_t dstream)
1386 boost::shared_ptr<Route> r;
1388 if ((r = session->route_by_remote_id (dstream)) != 0) {
1392 if ((t = dynamic_cast<Track*>(r.get())) != 0) {
1393 t->diskstream()->set_record_enabled (!t->diskstream()->record_enabled());
1402 ARDOUR_UI::queue_transport_change ()
1404 Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
1408 ARDOUR_UI::map_transport_state ()
1410 float sp = session->transport_speed();
1413 transport_rolling ();
1414 } else if (sp < 0.0f) {
1415 transport_rewinding ();
1416 } else if (sp > 0.0f) {
1417 transport_forwarding ();
1419 transport_stopped ();
1424 ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg)
1426 snprintf (buf, sizeof(buf), "%s", ((GlobalClickBox *) arg)->strings[
1427 (int) adj.get_value()].c_str());
1431 ARDOUR_UI::engine_stopped ()
1433 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
1434 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1435 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1439 ARDOUR_UI::engine_running ()
1441 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
1442 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true);
1443 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
1445 Glib::RefPtr<Action> action;
1446 char* action_name = 0;
1448 switch (engine->frames_per_cycle()) {
1450 action_name = X_("JACKLatency32");
1453 action_name = X_("JACKLatency64");
1456 action_name = X_("JACKLatency128");
1459 action_name = X_("JACKLatency512");
1462 action_name = X_("JACKLatency1024");
1465 action_name = X_("JACKLatency2048");
1468 action_name = X_("JACKLatency4096");
1471 action_name = X_("JACKLatency8192");
1474 /* XXX can we do anything useful ? */
1480 action = ActionManager::get_action (X_("JACK"), action_name);
1483 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic (action);
1484 ract->set_active ();
1490 ARDOUR_UI::engine_halted ()
1492 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
1494 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1495 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1497 update_sample_rate (0);
1499 MessageDialog msg (*editor,
1501 JACK has either been shutdown or it\n\
1502 disconnected Ardour because Ardour\n\
1503 was not fast enough. You can save the\n\
1504 session and/or try to reconnect to JACK ."));
1509 ARDOUR_UI::do_engine_start ()
1517 error << _("Unable to start the session running")
1527 ARDOUR_UI::setup_theme ()
1529 theme_manager->setup_theme();
1533 ARDOUR_UI::start_engine ()
1535 if (do_engine_start () == 0) {
1536 if (session && _session_is_new) {
1537 /* we need to retain initial visual
1538 settings for a new session
1540 session->save_state ("");
1548 ARDOUR_UI::update_clocks ()
1550 if (!editor || !editor->dragging_playhead()) {
1551 Clock (session->audible_frame(), false, editor->edit_cursor_position(false)); /* EMIT_SIGNAL */
1556 ARDOUR_UI::start_clocking ()
1558 clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
1562 ARDOUR_UI::stop_clocking ()
1564 clock_signal_connection.disconnect ();
1568 ARDOUR_UI::toggle_clocking ()
1571 if (clock_button.get_active()) {
1580 ARDOUR_UI::_blink (void *arg)
1583 ((ARDOUR_UI *) arg)->blink ();
1590 Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
1594 ARDOUR_UI::start_blinking ()
1596 /* Start the blink signal. Everybody with a blinking widget
1597 uses Blink to drive the widget's state.
1600 if (blink_timeout_tag < 0) {
1602 blink_timeout_tag = g_timeout_add (240, _blink, this);
1607 ARDOUR_UI::stop_blinking ()
1609 if (blink_timeout_tag >= 0) {
1610 g_source_remove (blink_timeout_tag);
1611 blink_timeout_tag = -1;
1616 ARDOUR_UI::name_io_setup (AudioEngine& engine,
1622 if (io.n_inputs().n_total() == 0) {
1627 /* XXX we're not handling multiple ports yet. */
1629 const char **connections = io.input(0)->get_connections();
1631 if (connections == 0 || connections[0] == '\0') {
1634 buf = connections[0];
1641 if (io.n_outputs().n_total() == 0) {
1646 /* XXX we're not handling multiple ports yet. */
1648 const char **connections = io.output(0)->get_connections();
1650 if (connections == 0 || connections[0] == '\0') {
1653 buf = connections[0];
1660 /** Ask the user for the name of a new shapshot and then take it.
1663 ARDOUR_UI::snapshot_session ()
1665 ArdourPrompter prompter (true);
1669 struct tm local_time;
1672 localtime_r (&n, &local_time);
1673 strftime (timebuf, sizeof(timebuf), "%FT%T", &local_time);
1675 prompter.set_name ("Prompter");
1676 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1677 prompter.set_prompt (_("Name of New Snapshot"));
1678 prompter.set_initial_text (timebuf);
1680 switch (prompter.run()) {
1681 case RESPONSE_ACCEPT:
1682 prompter.get_result (snapname);
1683 if (snapname.length()){
1684 save_state (snapname);
1694 ARDOUR_UI::save_state (const string & name)
1696 (void) save_state_canfail (name);
1700 ARDOUR_UI::save_state_canfail (string name)
1705 if (name.length() == 0) {
1706 name = session->snap_name();
1709 if ((ret = session->save_state (name)) != 0) {
1713 save_ardour_state (); /* XXX cannot fail? yeah, right ... */
1718 ARDOUR_UI::restore_state (string name)
1721 if (name.length() == 0) {
1722 name = session->name();
1724 session->restore_state (name);
1729 ARDOUR_UI::primary_clock_value_changed ()
1732 session->request_locate (primary_clock.current_time ());
1737 ARDOUR_UI::secondary_clock_value_changed ()
1740 session->request_locate (secondary_clock.current_time ());
1745 ARDOUR_UI::rec_enable_button_blink (bool onoff, AudioDiskstream *dstream, Widget *w)
1747 if (session && dstream && dstream->record_enabled()) {
1749 Session::RecordState rs;
1751 rs = session->record_status ();
1754 case Session::Disabled:
1755 case Session::Enabled:
1756 if (w->get_state() != STATE_SELECTED) {
1757 w->set_state (STATE_SELECTED);
1761 case Session::Recording:
1762 if (w->get_state() != STATE_ACTIVE) {
1763 w->set_state (STATE_ACTIVE);
1769 if (w->get_state() != STATE_NORMAL) {
1770 w->set_state (STATE_NORMAL);
1776 ARDOUR_UI::transport_rec_enable_blink (bool onoff)
1782 switch (session->record_status()) {
1783 case Session::Enabled:
1785 rec_button.set_visual_state (2);
1787 rec_button.set_visual_state (0);
1791 case Session::Recording:
1792 rec_button.set_visual_state (1);
1796 rec_button.set_visual_state (0);
1802 ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
1810 ARDOUR_UI::save_template ()
1813 ArdourPrompter prompter (true);
1816 if (!check_audioengine()) {
1820 prompter.set_name (X_("Prompter"));
1821 prompter.set_prompt (_("Name for mix template:"));
1822 prompter.set_initial_text(session->name() + _("-template"));
1823 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1825 switch (prompter.run()) {
1826 case RESPONSE_ACCEPT:
1827 prompter.get_result (name);
1829 if (name.length()) {
1830 session->save_template (name);
1840 ARDOUR_UI::new_session (std::string predetermined_path)
1842 string session_name;
1843 string session_path;
1845 if (!check_audioengine()) {
1849 int response = Gtk::RESPONSE_NONE;
1851 new_session_dialog->set_modal(true);
1852 new_session_dialog->set_name (predetermined_path);
1853 new_session_dialog->reset_recent();
1854 new_session_dialog->show();
1855 new_session_dialog->set_current_page (0);
1858 response = new_session_dialog->run ();
1860 if (!check_audioengine()) {
1861 new_session_dialog->hide ();
1865 _session_is_new = false;
1867 if (response == Gtk::RESPONSE_CANCEL || response == Gtk::RESPONSE_DELETE_EVENT) {
1872 new_session_dialog->hide ();
1875 } else if (response == Gtk::RESPONSE_NONE) {
1877 /* Clear was pressed */
1878 new_session_dialog->reset();
1880 } else if (response == Gtk::RESPONSE_YES) {
1882 /* YES == OPEN, but there's no enum for that */
1884 session_name = new_session_dialog->session_name();
1886 if (session_name.empty()) {
1887 response = Gtk::RESPONSE_NONE;
1891 if (session_name[0] == '/' ||
1892 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1893 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1894 load_session (Glib::path_get_dirname (session_name), session_name);
1896 session_path = new_session_dialog->session_folder();
1897 load_session (session_path, session_name);
1900 } else if (response == Gtk::RESPONSE_OK) {
1902 session_name = new_session_dialog->session_name();
1904 if (!new_session_dialog->on_new_session_page ()) {
1906 /* XXX this is a bit of a hack..
1907 i really want the new sesion dialog to return RESPONSE_YES
1908 if we're on page 1 (the load page)
1909 Unfortunately i can't see how atm..
1912 if (session_name.empty()) {
1913 response = Gtk::RESPONSE_NONE;
1917 if (session_name[0] == '/' ||
1918 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1919 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1920 load_session (Glib::path_get_dirname (session_name), session_name);
1922 session_path = new_session_dialog->session_folder();
1923 load_session (session_path, session_name);
1928 if (session_name.empty()) {
1929 response = Gtk::RESPONSE_NONE;
1933 if (session_name[0] == '/' ||
1934 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1935 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1937 session_path = Glib::path_get_dirname (session_name);
1938 session_name = Glib::path_get_basename (session_name);
1942 session_path = new_session_dialog->session_folder();
1946 //XXX This is needed because session constructor wants a
1947 //non-existant path. hopefully this will be fixed at some point.
1949 session_path = Glib::build_filename (session_path, session_name);
1951 if (g_file_test (session_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
1953 Glib::ustring str = string_compose (_("This session\n%1\nalready exists. Do you want to open it?"), session_path);
1955 MessageDialog msg (str,
1957 Gtk::MESSAGE_WARNING,
1958 Gtk::BUTTONS_YES_NO,
1962 msg.set_name (X_("CleanupDialog"));
1963 msg.set_wmclass (X_("existing_session"), "Ardour");
1964 msg.set_position (Gtk::WIN_POS_MOUSE);
1966 switch (msg.run()) {
1968 load_session (session_path, session_name);
1972 response = RESPONSE_NONE;
1973 new_session_dialog->reset ();
1978 _session_is_new = true;
1980 std::string template_name = new_session_dialog->session_template_name();
1982 if (new_session_dialog->use_session_template()) {
1984 load_session (session_path, session_name, &template_name);
1990 AutoConnectOption iconnect;
1991 AutoConnectOption oconnect;
1993 if (new_session_dialog->create_control_bus()) {
1994 cchns = (uint32_t) new_session_dialog->control_channel_count();
1999 if (new_session_dialog->create_master_bus()) {
2000 mchns = (uint32_t) new_session_dialog->master_channel_count();
2005 if (new_session_dialog->connect_inputs()) {
2006 iconnect = AutoConnectPhysical;
2008 iconnect = AutoConnectOption (0);
2011 /// @todo some minor tweaks.
2013 if (new_session_dialog->connect_outs_to_master()) {
2014 oconnect = AutoConnectMaster;
2015 } else if (new_session_dialog->connect_outs_to_physical()) {
2016 oconnect = AutoConnectPhysical;
2018 oconnect = AutoConnectOption (0);
2021 uint32_t nphysin = (uint32_t) new_session_dialog->input_limit_count();
2022 uint32_t nphysout = (uint32_t) new_session_dialog->output_limit_count();
2024 if (!build_session (session_path,
2032 engine->frame_rate() * 60 * 5)) {
2034 response = Gtk::RESPONSE_NONE;
2035 new_session_dialog->reset ();
2042 } while (response == Gtk::RESPONSE_NONE);
2046 new_session_dialog->get_window()->set_cursor();
2047 new_session_dialog->hide();
2052 ARDOUR_UI::close_session()
2054 if (!check_audioengine()) {
2063 ARDOUR_UI::load_session (const string & path, const string & snap_name, string* mix_template)
2065 Session *new_session;
2066 session_loaded = false;
2068 if (!check_audioengine()) {
2072 if(!unload_session ()) return -1;
2074 /* if it already exists, we must have write access */
2076 if (::access (path.c_str(), F_OK) == 0 && ::access (path.c_str(), W_OK)) {
2077 MessageDialog msg (*editor, _("You do not have write access to this session.\n"
2078 "This prevents the session from being loaded."));
2084 new_session = new Session (*engine, path, snap_name, mix_template);
2089 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
2093 connect_to_session (new_session);
2095 Config->set_current_owner (ConfigVariableBase::Interface);
2097 session_loaded = true;
2099 goto_editor_window ();
2102 session->set_clean ();
2105 editor->edit_cursor_position (true);
2110 ARDOUR_UI::build_session (const string & path, const string & snap_name,
2111 uint32_t control_channels,
2112 uint32_t master_channels,
2113 AutoConnectOption input_connect,
2114 AutoConnectOption output_connect,
2117 nframes_t initial_length)
2119 Session *new_session;
2121 if (!check_audioengine()) {
2125 session_loaded = false;
2127 if (!unload_session ()) return false;
2129 _session_is_new = true;
2132 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
2133 control_channels, master_channels, nphysin, nphysout, initial_length);
2138 MessageDialog msg (string_compose(_("Could not create session in \"%1\""), path));
2143 connect_to_session (new_session);
2145 session_loaded = true;
2153 editor->show_window ();
2164 ARDOUR_UI::show_splash ()
2167 about = new About();
2168 about->signal_response().connect(mem_fun (*this, &ARDOUR_UI::about_signal_response) );
2175 ARDOUR_UI::about_signal_response(int response)
2181 ARDOUR_UI::hide_splash ()
2184 about->get_window()->set_cursor ();
2190 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title, const string & msg)
2194 removed = rep.paths.size();
2197 MessageDialog msgd (*editor,
2198 _("No audio files were ready for cleanup"),
2201 (Gtk::ButtonsType)(Gtk::BUTTONS_OK) );
2202 msgd.set_secondary_text (_("If this seems suprising, \n\
2203 check for any existing snapshots.\n\
2204 These may still include regions that\n\
2205 require some unused files to continue to exist."));
2211 ArdourDialog results (_("ardour: cleanup"), true, false);
2213 struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
2214 CleanupResultsModelColumns() {
2218 Gtk::TreeModelColumn<Glib::ustring> visible_name;
2219 Gtk::TreeModelColumn<Glib::ustring> fullpath;
2223 CleanupResultsModelColumns results_columns;
2224 Glib::RefPtr<Gtk::ListStore> results_model;
2225 Gtk::TreeView results_display;
2227 results_model = ListStore::create (results_columns);
2228 results_display.set_model (results_model);
2229 results_display.append_column (list_title, results_columns.visible_name);
2231 results_display.set_name ("CleanupResultsList");
2232 results_display.set_headers_visible (true);
2233 results_display.set_headers_clickable (false);
2234 results_display.set_reorderable (false);
2236 Gtk::ScrolledWindow list_scroller;
2239 Gtk::HBox dhbox; // the hbox for the image and text
2240 Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
2241 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO, Gtk::ICON_SIZE_DIALOG));
2243 dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
2245 const string dead_sound_directory = session->session_directory().dead_sound_path().to_string();
2247 if (rep.space < 1048576.0f) {
2249 txt.set_text (string_compose (msg, removed, _("files were"), dead_sound_directory, (float) rep.space / 1024.0f, "kilo"));
2251 txt.set_text (string_compose (msg, removed, _("file was"), dead_sound_directory, (float) rep.space / 1024.0f, "kilo"));
2255 txt.set_text (string_compose (msg, removed, _("files were"), dead_sound_directory, (float) rep.space / 1048576.0f, "mega"));
2257 txt.set_text (string_compose (msg, removed, _("file was"), dead_sound_directory, (float) rep.space / 1048576.0f, "mega"));
2261 dhbox.pack_start (*dimage, true, false, 5);
2262 dhbox.pack_start (txt, true, false, 5);
2264 for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2265 TreeModel::Row row = *(results_model->append());
2266 row[results_columns.visible_name] = *i;
2267 row[results_columns.fullpath] = *i;
2270 list_scroller.add (results_display);
2271 list_scroller.set_size_request (-1, 150);
2272 list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2274 dvbox.pack_start (dhbox, true, false, 5);
2275 dvbox.pack_start (list_scroller, true, false, 5);
2276 ddhbox.pack_start (dvbox, true, false, 5);
2278 results.get_vbox()->pack_start (ddhbox, true, false, 5);
2279 results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
2280 results.set_default_response (RESPONSE_CLOSE);
2281 results.set_position (Gtk::WIN_POS_MOUSE);
2283 results_display.show();
2284 list_scroller.show();
2291 //results.get_vbox()->show();
2292 results.set_resizable (false);
2299 ARDOUR_UI::cleanup ()
2302 /* shouldn't happen: menu item is insensitive */
2307 MessageDialog checker (_("Are you sure you want to cleanup?"),
2309 Gtk::MESSAGE_QUESTION,
2310 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
2312 checker.set_secondary_text(_("Cleanup is a destructive operation.\n\
2313 ALL undo/redo information will be lost if you cleanup.\n\
2314 After cleanup, unused audio files will be moved to a \
2315 \"dead sounds\" location."));
2317 checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2318 checker.add_button (_("Clean Up"), RESPONSE_ACCEPT);
2319 checker.set_default_response (RESPONSE_CANCEL);
2321 checker.set_name (_("CleanupDialog"));
2322 checker.set_wmclass (X_("ardour_cleanup"), "Ardour");
2323 checker.set_position (Gtk::WIN_POS_MOUSE);
2325 switch (checker.run()) {
2326 case RESPONSE_ACCEPT:
2332 Session::cleanup_report rep;
2334 editor->prepare_for_cleanup ();
2336 /* do not allow flush until a session is reloaded */
2338 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
2340 act->set_sensitive (false);
2343 if (session->cleanup_sources (rep)) {
2348 display_cleanup_results (rep,
2351 The following %1 %2 not in use and \n\
2352 have been moved to:\n\
2354 Flushing the wastebasket will \n\
2355 release an additional\n\
2356 %4 %5bytes of disk space.\n"
2364 ARDOUR_UI::flush_trash ()
2367 /* shouldn't happen: menu item is insensitive */
2371 Session::cleanup_report rep;
2373 if (session->cleanup_trash_sources (rep)) {
2377 display_cleanup_results (rep,
2379 _("The following %1 %2 deleted from\n\
2381 releasing %4 %5bytes of disk space"));
2385 ARDOUR_UI::add_route (Gtk::Window* float_window)
2393 if (add_route_dialog == 0) {
2394 add_route_dialog = new AddRouteDialog;
2396 add_route_dialog->set_transient_for (*float_window);
2400 if (add_route_dialog->is_visible()) {
2401 /* we're already doing this */
2405 ResponseType r = (ResponseType) add_route_dialog->run ();
2407 add_route_dialog->hide();
2410 case RESPONSE_ACCEPT:
2417 if ((count = add_route_dialog->count()) <= 0) {
2421 uint32_t input_chan = add_route_dialog->channels ();
2422 uint32_t output_chan;
2423 string name_template = add_route_dialog->name_template ();
2424 bool track = add_route_dialog->track ();
2426 AutoConnectOption oac = Config->get_output_auto_connect();
2428 if (oac & AutoConnectMaster) {
2429 output_chan = (session->master_out() ? session->master_out()->n_inputs().n_audio() : input_chan);
2431 output_chan = input_chan;
2434 /* XXX do something with name template */
2436 if (add_route_dialog->type() == ARDOUR::DataType::MIDI) {
2438 session_add_midi_track(count);
2440 MessageDialog msg (*editor,
2441 _("Sorry, MIDI Busses are not supported at this time."));
2443 //session_add_midi_bus();
2447 session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), count);
2449 session_add_audio_bus (input_chan, output_chan, count);
2455 ARDOUR_UI::mixer_settings () const
2460 node = session->instant_xml(X_("Mixer"));
2462 node = Config->instant_xml(X_("Mixer"));
2466 node = new XMLNode (X_("Mixer"));
2473 ARDOUR_UI::editor_settings () const
2478 node = session->instant_xml(X_("Editor"));
2480 node = Config->instant_xml(X_("Editor"));
2484 node = new XMLNode (X_("Editor"));
2490 ARDOUR_UI::keyboard_settings () const
2494 node = Config->extra_xml(X_("Keyboard"));
2497 node = new XMLNode (X_("Keyboard"));
2503 ARDOUR_UI::halt_on_xrun_message ()
2505 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
2507 MessageDialog msg (*editor,
2508 _("Recording was stopped because your system could not keep up."));
2513 ARDOUR_UI::disk_overrun_handler ()
2515 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
2517 if (!have_disk_speed_dialog_displayed) {
2518 have_disk_speed_dialog_displayed = true;
2519 MessageDialog* msg = new MessageDialog (*editor, _("\
2520 The disk system on your computer\n\
2521 was not able to keep up with Ardour.\n\
2523 Specifically, it failed to write data to disk\n\
2524 quickly enough to keep up with recording.\n"));
2525 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
2531 ARDOUR_UI::disk_underrun_handler ()
2533 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2535 if (!have_disk_speed_dialog_displayed) {
2536 have_disk_speed_dialog_displayed = true;
2537 MessageDialog* msg = new MessageDialog (*editor,
2538 _("The disk system on your computer\n\
2539 was not able to keep up with Ardour.\n\
2541 Specifically, it failed to read data from disk\n\
2542 quickly enough to keep up with playback.\n"));
2543 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
2549 ARDOUR_UI::disk_speed_dialog_gone (int ignored_response, MessageDialog* msg)
2551 have_disk_speed_dialog_displayed = false;
2556 ARDOUR_UI::pending_state_dialog ()
2558 ArdourDialog dialog ("pending state dialog");
2560 This session appears to have been in\n\
2561 middle of recording when ardour or\n\
2562 the computer was shutdown.\n\
2564 Ardour can recover any captured audio for\n\
2565 you, or it can ignore it. Please decide\n\
2566 what you would like to do.\n"));
2568 dialog.get_vbox()->pack_start (message);
2569 dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
2570 dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
2572 dialog.set_position (WIN_POS_CENTER);
2574 //dialog.get_vbox()->show();
2576 switch (dialog.run ()) {
2577 case RESPONSE_ACCEPT:
2585 ARDOUR_UI::disconnect_from_jack ()
2588 if( engine->disconnect_from_jack ()) {
2589 MessageDialog msg (*editor, _("Could not disconnect from JACK"));
2593 update_sample_rate (0);
2598 ARDOUR_UI::reconnect_to_jack ()
2601 if (engine->reconnect_to_jack ()) {
2602 MessageDialog msg (*editor, _("Could not reconnect to JACK"));
2606 update_sample_rate (0);
2611 ARDOUR_UI::cmdline_new_session (string path)
2613 if (path[0] != '/') {
2614 char buf[PATH_MAX+1];
2617 getcwd (buf, sizeof (buf));
2626 return FALSE; /* don't call it again */
2630 ARDOUR_UI::use_config ()
2632 Glib::RefPtr<Action> act;
2634 switch (Config->get_native_file_data_format ()) {
2636 act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
2639 act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
2642 act = ActionManager::get_action (X_("options"), X_("FileDataFormat16bit"));
2647 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2648 ract->set_active ();
2651 switch (Config->get_native_file_header_format ()) {
2653 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
2656 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
2659 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
2662 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
2665 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
2668 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatCAF"));
2671 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatAIFF"));
2676 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2677 ract->set_active ();
2680 XMLNode* node = Config->extra_xml (X_("TransportControllables"));
2682 set_transport_controllable_state (*node);
2687 ARDOUR_UI::update_transport_clocks (nframes_t pos)
2689 if (Config->get_primary_clock_delta_edit_cursor()) {
2690 primary_clock.set (pos, false, editor->edit_cursor_position(false), 'p');
2692 primary_clock.set (pos, 0, true);
2695 if (Config->get_secondary_clock_delta_edit_cursor()) {
2696 secondary_clock.set (pos, false, editor->edit_cursor_position(false), 's');
2698 secondary_clock.set (pos);
2701 if (big_clock_window) {
2702 big_clock.set (pos);
2707 ARDOUR_UI::record_state_changed ()
2709 ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::record_state_changed));
2711 if (!session || !big_clock_window) {
2712 /* why bother - the clock isn't visible */
2716 switch (session->record_status()) {
2717 case Session::Recording:
2718 big_clock.set_widget_name ("BigClockRecording");
2721 big_clock.set_widget_name ("BigClockNonRecording");
2727 ARDOUR_UI::set_keybindings_path (string path)
2729 keybindings_path = path;
2733 ARDOUR_UI::save_keybindings ()
2735 if (can_save_keybindings) {
2736 AccelMap::save (user_keybindings_path);
2741 ARDOUR_UI::first_idle ()
2744 session->allow_auto_play (true);
2746 can_save_keybindings = true;
2751 ARDOUR_UI::store_clock_modes ()
2753 XMLNode* node = new XMLNode(X_("ClockModes"));
2755 for (vector<AudioClock*>::iterator x = AudioClock::clocks.begin(); x != AudioClock::clocks.end(); ++x) {
2756 node->add_property ((*x)->name().c_str(), enum_2_string ((*x)->mode()));
2759 session->add_extra_xml (*node);
2760 session->set_dirty ();
2765 ARDOUR_UI::TransportControllable::TransportControllable (std::string name, ARDOUR_UI& u, ToggleType tp)
2766 : Controllable (name), ui (u), type(tp)
2772 ARDOUR_UI::TransportControllable::set_value (float val)
2774 if (type == ShuttleControl) {
2781 fract = -((0.5f - val)/0.5f);
2783 fract = ((val - 0.5f)/0.5f);
2787 ui.set_shuttle_fract (fract);
2792 /* do nothing: these are radio-style actions */
2800 action = X_("Roll");
2803 action = X_("Stop");
2806 action = X_("Goto Start");
2809 action = X_("Goto End");
2812 action = X_("Loop");
2815 action = X_("Play Selection");
2818 action = X_("Record");
2828 Glib::RefPtr<Action> act = ActionManager::get_action ("Transport", action);
2836 ARDOUR_UI::TransportControllable::get_value (void) const
2855 case ShuttleControl:
2865 ARDOUR_UI::TransportControllable::set_id (const string& str)
2871 ARDOUR_UI::setup_profile ()
2873 if (gdk_screen_width() < 1200) {
2874 Profile->set_small_screen ();
2879 ARDOUR_UI::disable_all_plugins ()
2885 // session->begin_reversible_command (_("Disable all plugins"));
2887 boost::shared_ptr<Session::RouteList> routes = session->get_routes ();
2889 for (Session::RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
2890 // XMLNode& before = (*i)->get_redirect_state ();
2891 // session->add_command (new MementoCommand<Route>(**i, &before, 0));
2892 (*i)->disable_plugins ();
2893 // XMLNode& after = (*i)->get_redirect_state ();
2894 // session->add_command (new MementoCommand<Route>(**i, 0, &after));
2898 // session->commit_reversible_command ();
2902 ARDOUR_UI::ab_all_plugins ()
2908 boost::shared_ptr<Session::RouteList> routes = session->get_routes ();
2910 for (Session::RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
2911 (*i)->ab_plugins (ab_direction);
2914 ab_direction = !ab_direction;