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.
30 #include <sys/resource.h>
32 #include <gtkmm/messagedialog.h>
33 #include <gtkmm/accelmap.h>
35 #include <pbd/error.h>
36 #include <pbd/compose.h>
37 #include <pbd/pathscanner.h>
38 #include <pbd/failed_constructor.h>
39 #include <pbd/enumwriter.h>
40 #include <pbd/stacktrace.h>
41 #include <gtkmm2ext/gtk_ui.h>
42 #include <gtkmm2ext/utils.h>
43 #include <gtkmm2ext/click_box.h>
44 #include <gtkmm2ext/fastmeter.h>
45 #include <gtkmm2ext/stop_signal.h>
46 #include <gtkmm2ext/popup.h>
48 #include <midi++/port.h>
49 #include <midi++/mmc.h>
51 #include <ardour/ardour.h>
52 #include <ardour/session_route.h>
53 #include <ardour/port.h>
54 #include <ardour/audioengine.h>
55 #include <ardour/playlist.h>
56 #include <ardour/utils.h>
57 #include <ardour/audio_diskstream.h>
58 #include <ardour/audiofilesource.h>
59 #include <ardour/recent_sessions.h>
60 #include <ardour/port.h>
61 #include <ardour/audio_track.h>
64 #include "ardour_ui.h"
65 #include "public_editor.h"
66 #include "audio_clock.h"
71 #include "add_route_dialog.h"
72 #include "new_session_dialog.h"
75 #include "gui_thread.h"
76 #include "color_manager.h"
80 using namespace ARDOUR;
82 using namespace Gtkmm2ext;
86 ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
88 sigc::signal<void,bool> ARDOUR_UI::Blink;
89 sigc::signal<void> ARDOUR_UI::RapidScreenUpdate;
90 sigc::signal<void> ARDOUR_UI::MidRapidScreenUpdate;
91 sigc::signal<void> ARDOUR_UI::SuperRapidScreenUpdate;
92 sigc::signal<void,nframes_t> ARDOUR_UI::Clock;
94 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
96 : Gtkmm2ext::UI ("ardour", argcp, argvp, rcfile),
98 primary_clock (X_("primary"), false, X_("TransportClockDisplay"), true, false, true),
99 secondary_clock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, false, true),
100 preroll_clock (X_("preroll"), false, X_("PreRollClock"), true, true),
101 postroll_clock (X_("postroll"), false, X_("PostRollClock"), true, true),
105 adjuster_table (3, 3),
109 preroll_button (_("pre\nroll")),
110 postroll_button (_("post\nroll")),
114 big_clock (X_("bigclock"), false, "BigClockNonRecording", false, false, true),
118 roll_controllable ("transport roll", *this, TransportControllable::Roll),
119 stop_controllable ("transport stop", *this, TransportControllable::Stop),
120 goto_start_controllable ("transport goto start", *this, TransportControllable::GotoStart),
121 goto_end_controllable ("transport goto end", *this, TransportControllable::GotoEnd),
122 auto_loop_controllable ("transport auto loop", *this, TransportControllable::AutoLoop),
123 play_selection_controllable ("transport play selection", *this, TransportControllable::PlaySelection),
124 rec_controllable ("transport rec-enable", *this, TransportControllable::RecordEnable),
125 shuttle_controllable ("shuttle", *this, TransportControllable::ShuttleControl),
126 shuttle_controller_binding_proxy (shuttle_controllable),
128 roll_button (roll_controllable),
129 stop_button (stop_controllable),
130 goto_start_button (goto_start_controllable),
131 goto_end_button (goto_end_controllable),
132 auto_loop_button (auto_loop_controllable),
133 play_selection_button (play_selection_controllable),
134 rec_button (rec_controllable),
136 shuttle_units_button (_("% ")),
138 punch_in_button (_("Punch In")),
139 punch_out_button (_("Punch Out")),
140 auto_return_button (_("Auto Return")),
141 auto_play_button (_("Auto Play")),
142 auto_input_button (_("Auto Input")),
143 click_button (_("Click")),
144 time_master_button (_("time\nmaster")),
146 auditioning_alert_button (_("AUDITION")),
147 solo_alert_button (_("SOLO")),
150 using namespace Gtk::Menu_Helpers;
156 if (theArdourUI == 0) {
162 color_manager = new ColorManager();
164 std::string color_file = ARDOUR::find_config_file("ardour.colors");
166 color_manager->load (color_file);
171 _session_is_new = false;
172 big_clock_window = 0;
173 session_selector_window = 0;
174 last_key_press_time = 0;
175 connection_editor = 0;
176 add_route_dialog = 0;
180 open_session_selector = 0;
181 have_configure_timeout = false;
182 have_disk_speed_dialog_displayed = false;
183 _will_create_new_session_automatically = false;
184 session_loaded = false;
185 last_speed_displayed = -1.0f;
186 keybindings_path = ARDOUR::find_config_file ("ardour.bindings");
188 can_save_keybindings = false;
189 Glib::signal_idle().connect (mem_fun (*this, &ARDOUR_UI::first_idle));
191 last_configure_time.tv_sec = 0;
192 last_configure_time.tv_usec = 0;
194 shuttle_grabbed = false;
196 shuttle_max_speed = 8.0f;
198 shuttle_style_menu = 0;
199 shuttle_unit_menu = 0;
201 gettimeofday (&last_peak_grab, 0);
202 gettimeofday (&last_shuttle_request, 0);
204 ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
205 ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
207 /* handle pending state with a dialog */
209 ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
211 /* have to wait for AudioEngine and Configuration before proceeding */
215 ARDOUR_UI::set_engine (AudioEngine& e)
219 engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
220 engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
221 engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
222 engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
224 ActionManager::init ();
225 new_session_dialog = new NewSessionDialog();
229 keyboard = new Keyboard;
231 if (setup_windows ()) {
232 throw failed_constructor ();
235 if (GTK_ARDOUR::show_key_actions) {
236 vector<string> names;
237 vector<string> paths;
239 vector<AccelKey> bindings;
241 ActionManager::get_all_actions (names, paths, keys, bindings);
243 vector<string>::iterator n;
244 vector<string>::iterator k;
245 for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) {
246 cerr << "Action: " << (*n) << " bound to " << (*k) << endl;
252 /* start with timecode, metering enabled
255 blink_timeout_tag = -1;
257 /* the global configuration object is now valid */
261 /* this being a GUI and all, we want peakfiles */
263 AudioFileSource::set_build_peakfiles (true);
264 AudioFileSource::set_build_missing_peakfiles (true);
266 /* set default clock modes */
268 primary_clock.set_mode (AudioClock::SMPTE);
269 secondary_clock.set_mode (AudioClock::BBT);
271 /* start the time-of-day-clock */
273 update_wall_clock ();
274 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
276 update_disk_space ();
278 update_sample_rate (engine->frame_rate());
280 starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
281 stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
284 ARDOUR_UI::~ARDOUR_UI ()
286 save_ardour_state ();
300 if (add_route_dialog) {
301 delete add_route_dialog;
306 ARDOUR_UI::configure_timeout ()
311 if (last_configure_time.tv_sec == 0 && last_configure_time.tv_usec == 0) {
312 /* no configure events yet */
316 gettimeofday (&now, 0);
317 timersub (&now, &last_configure_time, &diff);
319 /* force a gap of 0.5 seconds since the last configure event
322 if (diff.tv_sec == 0 && diff.tv_usec < 500000) {
325 have_configure_timeout = false;
326 save_ardour_state ();
332 ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
334 if (have_configure_timeout) {
335 gettimeofday (&last_configure_time, 0);
337 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
338 have_configure_timeout = true;
345 ARDOUR_UI::set_transport_controllable_state (const XMLNode& node)
347 const XMLProperty* prop;
349 if ((prop = node.property ("roll")) != 0) {
350 roll_controllable.set_id (prop->value());
352 if ((prop = node.property ("stop")) != 0) {
353 stop_controllable.set_id (prop->value());
355 if ((prop = node.property ("goto_start")) != 0) {
356 goto_start_controllable.set_id (prop->value());
358 if ((prop = node.property ("goto_end")) != 0) {
359 goto_end_controllable.set_id (prop->value());
361 if ((prop = node.property ("auto_loop")) != 0) {
362 auto_loop_controllable.set_id (prop->value());
364 if ((prop = node.property ("play_selection")) != 0) {
365 play_selection_controllable.set_id (prop->value());
367 if ((prop = node.property ("rec")) != 0) {
368 rec_controllable.set_id (prop->value());
370 if ((prop = node.property ("shuttle")) != 0) {
371 shuttle_controllable.set_id (prop->value());
376 ARDOUR_UI::get_transport_controllable_state ()
378 XMLNode* node = new XMLNode(X_("TransportControllables"));
381 roll_controllable.id().print (buf, sizeof (buf));
382 node->add_property (X_("roll"), buf);
383 stop_controllable.id().print (buf, sizeof (buf));
384 node->add_property (X_("stop"), buf);
385 goto_start_controllable.id().print (buf, sizeof (buf));
386 node->add_property (X_("goto_start"), buf);
387 goto_end_controllable.id().print (buf, sizeof (buf));
388 node->add_property (X_("goto_end"), buf);
389 auto_loop_controllable.id().print (buf, sizeof (buf));
390 node->add_property (X_("auto_loop"), buf);
391 play_selection_controllable.id().print (buf, sizeof (buf));
392 node->add_property (X_("play_selection"), buf);
393 rec_controllable.id().print (buf, sizeof (buf));
394 node->add_property (X_("rec"), buf);
395 shuttle_controllable.id().print (buf, sizeof (buf));
396 node->add_property (X_("shuttle"), buf);
402 ARDOUR_UI::save_ardour_state ()
404 if (!keyboard || !mixer || !editor) {
408 /* XXX this is all a bit dubious. add_extra_xml() uses
409 a different lifetime model from add_instant_xml().
412 XMLNode* node = new XMLNode (keyboard->get_state());
413 Config->add_extra_xml (*node);
414 Config->add_extra_xml (get_transport_controllable_state());
415 Config->save_state();
417 XMLNode enode(static_cast<Stateful*>(editor)->get_state());
418 XMLNode mnode(mixer->get_state());
421 session->add_instant_xml (enode, session->path());
422 session->add_instant_xml (mnode, session->path());
424 Config->add_instant_xml (enode, get_user_ardour_path());
425 Config->add_instant_xml (mnode, get_user_ardour_path());
432 ARDOUR_UI::startup ()
434 check_memory_locking();
438 ARDOUR_UI::no_memory_warning ()
440 XMLNode node (X_("no-memory-warning"));
441 Config->add_instant_xml (node, get_user_ardour_path());
445 ARDOUR_UI::check_memory_locking ()
448 /* OS X doesn't support mlockall(2), and so testing for memory locking capability there is pointless */
452 XMLNode* memory_warning_node = Config->instant_xml (X_("no-memory-warning"), get_user_ardour_path());
454 if (engine->is_realtime() && memory_warning_node == 0) {
456 struct rlimit limits;
458 long pages, page_size;
460 if ((page_size = sysconf (_SC_PAGESIZE)) < 0 ||(pages = sysconf (_SC_PHYS_PAGES)) < 0) {
463 ram = (int64_t) pages * (int64_t) page_size;
466 if (getrlimit (RLIMIT_MEMLOCK, &limits)) {
470 if (limits.rlim_cur != RLIM_INFINITY) {
472 if (ram == 0 || ((double) limits.rlim_cur / ram) < 0.75) {
475 MessageDialog msg (_("WARNING: Your system has a limit for maximum amount of locked memory. "
476 "This might cause Ardour to run out of memory before your system "
477 "runs out of memory. \n\n"
478 "You can view the memory limit with 'ulimit -l', "
479 "and it is normally controlled by /etc/security/limits.conf"));
481 VBox* vbox = msg.get_vbox();
483 CheckButton cb (_("Do not show this window again"));
485 cb.signal_toggled().connect (mem_fun (*this, &ARDOUR_UI::no_memory_warning));
487 hbox.pack_start (cb, true, false);
488 vbox->pack_start (hbox);
491 editor->ensure_float (msg);
503 if (session && session->dirty()) {
504 switch (ask_about_saving_session(_("quit"))) {
509 /* use the default name */
510 if (save_state_canfail ("")) {
511 /* failed - don't quit */
512 MessageDialog msg (*editor,
514 Ardour was unable to save your session.\n\n\
515 If you still wish to quit, please use the\n\n\
516 \"Just quit\" option."));
527 session->set_deletion_in_progress ();
530 Config->save_state();
535 ARDOUR_UI::ask_about_saving_session (const string & what)
537 ArdourDialog window (_("ardour: save session?"));
538 Gtk::HBox dhbox; // the hbox for the image and text
539 Gtk::Label prompt_label;
540 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_WARNING, Gtk::ICON_SIZE_DIALOG));
544 msg = string_compose(_("Don't %1"), what);
545 window.add_button (msg, RESPONSE_REJECT);
546 msg = string_compose(_("Just %1"), what);
547 window.add_button (msg, RESPONSE_APPLY);
548 msg = string_compose(_("Save and %1"), what);
549 window.add_button (msg, RESPONSE_ACCEPT);
551 window.set_default_response (RESPONSE_ACCEPT);
553 Gtk::Button noquit_button (msg);
554 noquit_button.set_name ("EditorGTKButton");
559 if (session->snap_name() == session->name()) {
562 type = _("snapshot");
564 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?"),
565 type, session->snap_name());
567 prompt_label.set_text (prompt);
568 prompt_label.set_name (X_("PrompterLabel"));
569 prompt_label.set_alignment(ALIGN_LEFT, ALIGN_TOP);
571 dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP)
573 dhbox.set_homogeneous (false);
574 dhbox.pack_start (*dimage, false, false, 5);
575 dhbox.pack_start (prompt_label, true, false, 5);
576 window.get_vbox()->pack_start (dhbox);
578 window.set_name (_("Prompter"));
579 window.set_position (Gtk::WIN_POS_MOUSE);
580 window.set_modal (true);
581 window.set_resizable (false);
584 save_the_session = 0;
586 window.set_keep_above (true);
589 ResponseType r = (ResponseType) window.run();
594 case RESPONSE_ACCEPT: // save and get out of here
596 case RESPONSE_APPLY: // get out of here
606 ARDOUR_UI::every_second ()
609 update_buffer_load ();
610 update_disk_space ();
615 ARDOUR_UI::every_point_one_seconds ()
617 update_speed_display ();
618 RapidScreenUpdate(); /* EMIT_SIGNAL */
623 ARDOUR_UI::every_point_oh_five_seconds ()
625 MidRapidScreenUpdate(); /* EMIT_SIGNAL */
630 ARDOUR_UI::every_point_zero_one_seconds ()
632 SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
637 ARDOUR_UI::update_sample_rate (nframes_t ignored)
641 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
643 if (!engine->connected()) {
645 snprintf (buf, sizeof (buf), _("disconnected"));
649 nframes_t rate = engine->frame_rate();
651 if (fmod (rate, 1000.0) != 0.0) {
652 snprintf (buf, sizeof (buf), _("%.1f kHz / %4.1f msecs"),
653 (float) rate/1000.0f,
654 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
656 snprintf (buf, sizeof (buf), _("%u kHz / %4.1f msecs"),
658 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
662 sample_rate_label.set_text (buf);
666 ARDOUR_UI::update_cpu_load ()
669 snprintf (buf, sizeof (buf), _("DSP: %.1f%%"), engine->get_cpu_load());
670 cpu_load_label.set_text (buf);
674 ARDOUR_UI::update_buffer_load ()
679 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"),
680 session->playback_load(), session->capture_load());
681 buffer_load_label.set_text (buf);
683 buffer_load_label.set_text ("");
688 ARDOUR_UI::count_recenabled_streams (Route& route)
690 Track* track = dynamic_cast<Track*>(&route);
691 if (track && track->diskstream()->record_enabled()) {
692 rec_enabled_streams += track->n_inputs();
697 ARDOUR_UI::update_disk_space()
703 nframes_t frames = session->available_capture_duration();
706 if (frames == max_frames) {
707 strcpy (buf, _("Disk: 24hrs+"));
712 nframes_t fr = session->frame_rate();
714 rec_enabled_streams = 0;
715 session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
717 if (rec_enabled_streams) {
718 frames /= rec_enabled_streams;
721 hrs = frames / (fr * 3600);
722 frames -= hrs * fr * 3600;
723 mins = frames / (fr * 60);
724 frames -= mins * fr * 60;
727 snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs);
730 disk_space_label.set_text (buf);
734 ARDOUR_UI::update_wall_clock ()
741 tm_now = localtime (&now);
743 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
744 wall_clock_label.set_text (buf);
750 ARDOUR_UI::session_menu (GdkEventButton *ev)
752 session_popup_menu->popup (0, 0);
757 ARDOUR_UI::redisplay_recent_sessions ()
759 vector<string *> *sessions;
760 vector<string *>::iterator i;
761 RecentSessionsSorter cmp;
763 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
764 recent_session_model->clear ();
767 ARDOUR::read_recent_sessions (rs);
770 recent_session_display.set_model (recent_session_model);
774 /* sort them alphabetically */
775 sort (rs.begin(), rs.end(), cmp);
776 sessions = new vector<string*>;
778 for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
779 sessions->push_back (new string ((*i).second));
782 for (i = sessions->begin(); i != sessions->end(); ++i) {
784 vector<string*>* states;
785 vector<const gchar*> item;
786 string fullpath = *(*i);
788 /* remove any trailing / */
790 if (fullpath[fullpath.length()-1] == '/') {
791 fullpath = fullpath.substr (0, fullpath.length()-1);
794 /* now get available states for this session */
796 if ((states = Session::possible_states (fullpath)) == 0) {
801 TreeModel::Row row = *(recent_session_model->append());
803 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
804 row[recent_session_columns.fullpath] = fullpath;
806 if (states->size() > 1) {
808 /* add the children */
810 for (vector<string*>::iterator i2 = states->begin(); i2 != states->end(); ++i2) {
812 TreeModel::Row child_row = *(recent_session_model->append (row.children()));
814 child_row[recent_session_columns.visible_name] = **i2;
815 child_row[recent_session_columns.fullpath] = fullpath;
824 recent_session_display.set_model (recent_session_model);
829 ARDOUR_UI::build_session_selector ()
831 session_selector_window = new ArdourDialog ("session selector");
833 Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
835 session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
836 session_selector_window->add_button (Stock::OPEN, RESPONSE_ACCEPT);
837 session_selector_window->set_default_response (RESPONSE_ACCEPT);
838 recent_session_model = TreeStore::create (recent_session_columns);
839 recent_session_display.set_model (recent_session_model);
840 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
841 recent_session_display.set_headers_visible (false);
842 recent_session_display.get_selection()->set_mode (SELECTION_SINGLE);
844 recent_session_display.signal_row_activated().connect (mem_fun (*this, &ARDOUR_UI::recent_session_row_activated));
846 scroller->add (recent_session_display);
847 scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
849 session_selector_window->set_name ("SessionSelectorWindow");
850 session_selector_window->set_size_request (200, 400);
851 session_selector_window->get_vbox()->pack_start (*scroller);
852 session_selector_window->show_all_children();
856 ARDOUR_UI::recent_session_row_activated (const TreePath& path, TreeViewColumn* col)
858 session_selector_window->response (RESPONSE_ACCEPT);
862 ARDOUR_UI::open_recent_session ()
864 /* popup selector window */
866 if (session_selector_window == 0) {
867 build_session_selector ();
870 redisplay_recent_sessions ();
872 ResponseType r = (ResponseType) session_selector_window->run ();
874 session_selector_window->hide();
877 case RESPONSE_ACCEPT:
883 Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
885 if (i == recent_session_model->children().end()) {
889 Glib::ustring path = (*i)[recent_session_columns.fullpath];
890 Glib::ustring state = (*i)[recent_session_columns.visible_name];
892 _session_is_new = false;
894 load_session (path, state);
898 ARDOUR_UI::filter_ardour_session_dirs (const FileFilter::Info& info)
902 if (stat (info.filename.c_str(), &statbuf) != 0) {
906 if (!S_ISDIR(statbuf.st_mode)) {
912 string session_file = info.filename;
914 session_file += Glib::path_get_basename (info.filename);
915 session_file += ".ardour";
917 if (stat (session_file.c_str(), &statbuf) != 0) {
921 return S_ISREG (statbuf.st_mode);
925 ARDOUR_UI::open_session ()
927 /* popup selector window */
929 if (open_session_selector == 0) {
931 /* ardour sessions are folders */
933 open_session_selector = new Gtk::FileChooserDialog (_("open session"), FILE_CHOOSER_ACTION_OPEN);
934 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
935 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
937 FileFilter session_filter;
938 session_filter.add_pattern ("*.ardour");
939 session_filter.set_name (_("Ardour sessions"));
940 open_session_selector->add_filter (session_filter);
941 open_session_selector->set_filter (session_filter);
944 int response = open_session_selector->run();
945 open_session_selector->hide ();
948 case RESPONSE_ACCEPT:
951 open_session_selector->hide();
955 open_session_selector->hide();
956 string session_path = open_session_selector->get_filename();
960 if (session_path.length() > 0) {
961 if (Session::find_session (session_path, path, name, isnew) == 0) {
962 _session_is_new = isnew;
963 load_session (path, name);
970 ARDOUR_UI::session_add_midi_track ()
972 cerr << _("Patience is a virtue.\n");
976 ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, uint32_t how_many)
978 list<boost::shared_ptr<AudioTrack> > tracks;
979 Session::RouteList routes;
982 warning << _("You cannot add a track or bus without a session already loaded.") << endmsg;
988 tracks = session->new_audio_track (input_channels, output_channels, mode, how_many);
990 if (tracks.size() != how_many) {
992 error << _("could not create a new audio track") << endmsg;
994 error << string_compose (_("could only create %1 of %2 new audio %3"),
995 tracks.size(), how_many, (track ? _("tracks") : _("busses"))) << endmsg;
1001 routes = session->new_audio_route (input_channels, output_channels, how_many);
1003 if (routes.size() != how_many) {
1004 if (how_many == 1) {
1005 error << _("could not create a new audio track") << endmsg;
1007 error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
1013 if (need_control_room_outs) {
1019 route->set_stereo_control_outs (control_lr_channels);
1020 route->control_outs()->set_stereo_pan (pans, this);
1022 #endif /* CONTROLOUTS */
1026 cerr << "About to complain about JACK\n";
1027 MessageDialog msg (*editor,
1028 _("There are insufficient JACK ports available\n\
1029 to create a new track or bus.\n\
1030 You should save Ardour, exit and\n\
1031 restart JACK with more ports."));
1037 ARDOUR_UI::do_transport_locate (nframes_t new_position)
1039 nframes_t _preroll = 0;
1042 // XXX CONFIG_CHANGE FIX - requires AnyTime handling
1043 // _preroll = session->convert_to_frames_at (new_position, Config->get_preroll());
1045 if (new_position > _preroll) {
1046 new_position -= _preroll;
1051 session->request_locate (new_position);
1056 ARDOUR_UI::transport_goto_start ()
1059 session->goto_start();
1062 /* force displayed area in editor to start no matter
1063 what "follow playhead" setting is.
1067 editor->reset_x_origin (session->current_start_frame());
1073 ARDOUR_UI::transport_goto_zero ()
1076 session->request_locate (0);
1079 /* force displayed area in editor to start no matter
1080 what "follow playhead" setting is.
1084 editor->reset_x_origin (0);
1090 ARDOUR_UI::transport_goto_end ()
1093 nframes_t frame = session->current_end_frame();
1094 session->request_locate (frame);
1096 /* force displayed area in editor to start no matter
1097 what "follow playhead" setting is.
1101 editor->reset_x_origin (frame);
1107 ARDOUR_UI::transport_stop ()
1113 if (session->is_auditioning()) {
1114 session->cancel_audition ();
1118 if (session->get_play_loop ()) {
1119 session->request_play_loop (false);
1122 session->request_stop ();
1126 ARDOUR_UI::transport_stop_and_forget_capture ()
1129 session->request_stop (true);
1134 ARDOUR_UI::remove_last_capture()
1137 editor->remove_last_capture();
1142 ARDOUR_UI::transport_record ()
1145 switch (session->record_status()) {
1146 case Session::Disabled:
1147 if (session->ntracks() == 0) {
1148 MessageDialog msg (*editor, _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu."));
1152 session->maybe_enable_record ();
1154 case Session::Recording:
1155 case Session::Enabled:
1156 session->disable_record (true);
1162 ARDOUR_UI::transport_roll ()
1170 rolling = session->transport_rolling ();
1172 if (session->get_play_loop()) {
1173 session->request_play_loop (false);
1174 auto_loop_button.set_visual_state (1);
1175 roll_button.set_visual_state (1);
1176 } else if (session->get_play_range ()) {
1177 session->request_play_range (false);
1178 play_selection_button.set_visual_state (0);
1179 } else if (rolling) {
1180 session->request_locate (session->last_transport_start(), true);
1183 session->request_transport_speed (1.0f);
1187 ARDOUR_UI::transport_loop()
1190 if (session->get_play_loop()) {
1191 if (session->transport_rolling()) {
1192 Location * looploc = session->locations()->auto_loop_location();
1194 session->request_locate (looploc->start(), true);
1199 session->request_play_loop (true);
1205 ARDOUR_UI::transport_play_selection ()
1211 if (!session->get_play_range()) {
1212 session->request_stop ();
1215 editor->play_selection ();
1219 ARDOUR_UI::transport_rewind (int option)
1221 float current_transport_speed;
1224 current_transport_speed = session->transport_speed();
1226 if (current_transport_speed >= 0.0f) {
1229 session->request_transport_speed (-1.0f);
1232 session->request_transport_speed (-4.0f);
1235 session->request_transport_speed (-0.5f);
1240 session->request_transport_speed (current_transport_speed * 1.5f);
1246 ARDOUR_UI::transport_forward (int option)
1248 float current_transport_speed;
1251 current_transport_speed = session->transport_speed();
1253 if (current_transport_speed <= 0.0f) {
1256 session->request_transport_speed (1.0f);
1259 session->request_transport_speed (4.0f);
1262 session->request_transport_speed (0.5f);
1267 session->request_transport_speed (current_transport_speed * 1.5f);
1273 ARDOUR_UI::toggle_record_enable (uint32_t dstream)
1279 boost::shared_ptr<Route> r;
1281 if ((r = session->route_by_remote_id (dstream)) != 0) {
1285 if ((t = dynamic_cast<Track*>(r.get())) != 0) {
1286 t->diskstream()->set_record_enabled (!t->diskstream()->record_enabled());
1295 ARDOUR_UI::queue_transport_change ()
1297 Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
1301 ARDOUR_UI::map_transport_state ()
1303 float sp = session->transport_speed();
1306 transport_rolling ();
1307 } else if (sp < 0.0f) {
1308 transport_rewinding ();
1309 } else if (sp > 0.0f) {
1310 transport_forwarding ();
1312 transport_stopped ();
1317 ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg)
1319 snprintf (buf, sizeof(buf), "%s", ((GlobalClickBox *) arg)->strings[
1320 (int) adj.get_value()].c_str());
1324 ARDOUR_UI::engine_stopped ()
1326 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
1327 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1328 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1332 ARDOUR_UI::engine_running ()
1334 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
1335 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true);
1336 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
1338 Glib::RefPtr<Action> action;
1339 char* action_name = 0;
1341 switch (engine->frames_per_cycle()) {
1343 action_name = X_("JACKLatency32");
1346 action_name = X_("JACKLatency64");
1349 action_name = X_("JACKLatency128");
1352 action_name = X_("JACKLatency512");
1355 action_name = X_("JACKLatency1024");
1358 action_name = X_("JACKLatency2048");
1361 action_name = X_("JACKLatency4096");
1364 action_name = X_("JACKLatency8192");
1367 /* XXX can we do anything useful ? */
1373 action = ActionManager::get_action (X_("JACK"), action_name);
1376 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic (action);
1377 ract->set_active ();
1383 ARDOUR_UI::engine_halted ()
1385 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
1387 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1388 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1390 update_sample_rate (0);
1392 MessageDialog msg (*editor,
1394 JACK has either been shutdown or it\n\
1395 disconnected Ardour because Ardour\n\
1396 was not fast enough. You can save the\n\
1397 session and/or try to reconnect to JACK ."));
1402 ARDOUR_UI::do_engine_start ()
1410 error << _("Unable to start the session running")
1420 ARDOUR_UI::start_engine ()
1422 if (do_engine_start () == 0) {
1423 if (session && _session_is_new) {
1424 /* we need to retain initial visual
1425 settings for a new session
1427 session->save_state ("");
1435 ARDOUR_UI::update_clocks ()
1437 if (!editor || !editor->dragging_playhead()) {
1438 Clock (session->audible_frame()); /* EMIT_SIGNAL */
1443 ARDOUR_UI::start_clocking ()
1445 clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
1449 ARDOUR_UI::stop_clocking ()
1451 clock_signal_connection.disconnect ();
1455 ARDOUR_UI::toggle_clocking ()
1458 if (clock_button.get_active()) {
1467 ARDOUR_UI::_blink (void *arg)
1470 ((ARDOUR_UI *) arg)->blink ();
1477 Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
1481 ARDOUR_UI::start_blinking ()
1483 /* Start the blink signal. Everybody with a blinking widget
1484 uses Blink to drive the widget's state.
1487 if (blink_timeout_tag < 0) {
1489 blink_timeout_tag = g_timeout_add (240, _blink, this);
1494 ARDOUR_UI::stop_blinking ()
1496 if (blink_timeout_tag >= 0) {
1497 g_source_remove (blink_timeout_tag);
1498 blink_timeout_tag = -1;
1503 ARDOUR_UI::name_io_setup (AudioEngine& engine,
1509 if (io.n_inputs() == 0) {
1514 /* XXX we're not handling multiple ports yet. */
1516 const char **connections = io.input(0)->get_connections();
1518 if (connections == 0 || connections[0] == '\0') {
1521 buf = connections[0];
1528 if (io.n_outputs() == 0) {
1533 /* XXX we're not handling multiple ports yet. */
1535 const char **connections = io.output(0)->get_connections();
1537 if (connections == 0 || connections[0] == '\0') {
1540 buf = connections[0];
1548 ARDOUR_UI::snapshot_session ()
1550 ArdourPrompter prompter (true);
1554 struct tm local_time;
1557 localtime_r (&n, &local_time);
1558 strftime (timebuf, sizeof(timebuf), "%FT%T", &local_time);
1560 prompter.set_name ("Prompter");
1561 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1562 prompter.set_prompt (_("Name of New Snapshot"));
1563 prompter.set_initial_text (timebuf);
1565 switch (prompter.run()) {
1566 case RESPONSE_ACCEPT:
1567 prompter.get_result (snapname);
1568 if (snapname.length()){
1569 save_state (snapname);
1579 ARDOUR_UI::save_state (const string & name)
1581 (void) save_state_canfail (name);
1585 ARDOUR_UI::save_state_canfail (string name)
1590 if (name.length() == 0) {
1591 name = session->snap_name();
1594 if ((ret = session->save_state (name)) != 0) {
1598 save_ardour_state (); /* XXX cannot fail? yeah, right ... */
1603 ARDOUR_UI::restore_state (string name)
1606 if (name.length() == 0) {
1607 name = session->name();
1609 session->restore_state (name);
1614 ARDOUR_UI::primary_clock_value_changed ()
1617 session->request_locate (primary_clock.current_time ());
1622 ARDOUR_UI::secondary_clock_value_changed ()
1625 session->request_locate (secondary_clock.current_time ());
1630 ARDOUR_UI::rec_enable_button_blink (bool onoff, AudioDiskstream *dstream, Widget *w)
1632 if (session && dstream && dstream->record_enabled()) {
1634 Session::RecordState rs;
1636 rs = session->record_status ();
1639 case Session::Disabled:
1640 case Session::Enabled:
1641 if (w->get_state() != STATE_SELECTED) {
1642 w->set_state (STATE_SELECTED);
1646 case Session::Recording:
1647 if (w->get_state() != STATE_ACTIVE) {
1648 w->set_state (STATE_ACTIVE);
1654 if (w->get_state() != STATE_NORMAL) {
1655 w->set_state (STATE_NORMAL);
1661 ARDOUR_UI::transport_rec_enable_blink (bool onoff)
1667 switch (session->record_status()) {
1668 case Session::Enabled:
1670 rec_button.set_visual_state (2);
1672 rec_button.set_visual_state (0);
1676 case Session::Recording:
1677 rec_button.set_visual_state (1);
1681 rec_button.set_visual_state (0);
1687 ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
1695 ARDOUR_UI::save_template ()
1698 ArdourPrompter prompter (true);
1701 prompter.set_name (X_("Prompter"));
1702 prompter.set_prompt (_("Name for mix template:"));
1703 prompter.set_initial_text(session->name() + _("-template"));
1704 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1706 switch (prompter.run()) {
1707 case RESPONSE_ACCEPT:
1708 prompter.get_result (name);
1710 if (name.length()) {
1711 session->save_template (name);
1721 ARDOUR_UI::new_session (std::string predetermined_path)
1723 string session_name;
1724 string session_path;
1726 if (!engine->connected()) {
1727 MessageDialog msg (_("Ardour is not connected to JACK at this time. Creating new sessions is not possible."));
1732 int response = Gtk::RESPONSE_NONE;
1734 new_session_dialog->set_modal(true);
1735 new_session_dialog->set_name (predetermined_path);
1736 new_session_dialog->reset_recent();
1737 new_session_dialog->show();
1740 response = new_session_dialog->run ();
1742 if (!engine->connected()) {
1743 new_session_dialog->hide ();
1744 MessageDialog msg (_("Ardour is not connected to JACK at this time. Creating new sessions is not possible."));
1749 _session_is_new = false;
1751 if (response == Gtk::RESPONSE_CANCEL || response == Gtk::RESPONSE_DELETE_EVENT) {
1756 new_session_dialog->hide ();
1759 } else if (response == Gtk::RESPONSE_NONE) {
1761 /* Clear was pressed */
1762 new_session_dialog->reset();
1764 } else if (response == Gtk::RESPONSE_YES) {
1766 /* YES == OPEN, but there's no enum for that */
1768 session_name = new_session_dialog->session_name();
1770 if (session_name.empty()) {
1771 response = Gtk::RESPONSE_NONE;
1775 if (session_name[0] == '/' ||
1776 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1777 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1778 load_session (Glib::path_get_dirname (session_name), session_name);
1780 session_path = new_session_dialog->session_folder();
1781 load_session (session_path, session_name);
1784 } else if (response == Gtk::RESPONSE_OK) {
1786 session_name = new_session_dialog->session_name();
1788 if (new_session_dialog->get_current_page() == 1) {
1790 /* XXX this is a bit of a hack..
1791 i really want the new sesion dialog to return RESPONSE_YES
1792 if we're on page 1 (the load page)
1793 Unfortunately i can't see how atm..
1796 if (session_name.empty()) {
1797 response = Gtk::RESPONSE_NONE;
1801 if (session_name[0] == '/' ||
1802 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1803 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1804 load_session (Glib::path_get_dirname (session_name), session_name);
1806 session_path = new_session_dialog->session_folder();
1807 load_session (session_path, session_name);
1812 if (session_name.empty()) {
1813 response = Gtk::RESPONSE_NONE;
1817 if (session_name[0] == '/' ||
1818 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1819 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1821 session_path = Glib::path_get_dirname (session_name);
1822 session_name = Glib::path_get_basename (session_name);
1826 session_path = new_session_dialog->session_folder();
1830 //XXX This is needed because session constructor wants a
1831 //non-existant path. hopefully this will be fixed at some point.
1833 session_path = Glib::build_filename (session_path, session_name);
1835 if (g_file_test (session_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
1837 Glib::ustring str = string_compose (_("This session\n%1\nalready exists. Do you want to open it?"), session_path);
1839 MessageDialog msg (str,
1841 Gtk::MESSAGE_WARNING,
1842 Gtk::BUTTONS_YES_NO,
1846 msg.set_name (X_("CleanupDialog"));
1847 msg.set_wmclass (X_("existing_session"), "Ardour");
1848 msg.set_position (Gtk::WIN_POS_MOUSE);
1850 switch (msg.run()) {
1852 load_session (session_path, session_name);
1856 response = RESPONSE_NONE;
1857 new_session_dialog->reset ();
1862 _session_is_new = true;
1864 std::string template_name = new_session_dialog->session_template_name();
1866 if (new_session_dialog->use_session_template()) {
1868 load_session (session_path, session_name, &template_name);
1874 AutoConnectOption iconnect;
1875 AutoConnectOption oconnect;
1877 if (new_session_dialog->create_control_bus()) {
1878 cchns = (uint32_t) new_session_dialog->control_channel_count();
1883 if (new_session_dialog->create_master_bus()) {
1884 mchns = (uint32_t) new_session_dialog->master_channel_count();
1889 if (new_session_dialog->connect_inputs()) {
1890 iconnect = AutoConnectPhysical;
1892 iconnect = AutoConnectOption (0);
1895 /// @todo some minor tweaks.
1897 if (new_session_dialog->connect_outs_to_master()) {
1898 oconnect = AutoConnectMaster;
1899 } else if (new_session_dialog->connect_outs_to_physical()) {
1900 oconnect = AutoConnectPhysical;
1902 oconnect = AutoConnectOption (0);
1905 uint32_t nphysin = (uint32_t) new_session_dialog->input_limit_count();
1906 uint32_t nphysout = (uint32_t) new_session_dialog->output_limit_count();
1908 if (build_session (session_path,
1916 engine->frame_rate() * 60 * 5)) {
1918 response = Gtk::RESPONSE_NONE;
1919 new_session_dialog->reset ();
1926 } while (response == Gtk::RESPONSE_NONE);
1930 new_session_dialog->get_window()->set_cursor();
1931 new_session_dialog->hide();
1935 ARDOUR_UI::close_session()
1942 ARDOUR_UI::load_session (const string & path, const string & snap_name, string* mix_template)
1944 Session *new_session;
1946 session_loaded = false;
1948 x = unload_session ();
1956 /* if it already exists, we must have write access */
1958 if (::access (path.c_str(), F_OK) == 0 && ::access (path.c_str(), W_OK)) {
1959 MessageDialog msg (*editor, _("You do not have write access to this session.\n"
1960 "This prevents the session from being loaded."));
1966 new_session = new Session (*engine, path, snap_name, mix_template);
1971 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
1975 connect_to_session (new_session);
1977 Config->set_current_owner (ConfigVariableBase::Interface);
1979 session_loaded = true;
1981 goto_editor_window ();
1984 session->set_clean ();
1987 editor->edit_cursor_position (true);
1992 ARDOUR_UI::build_session (const string & path, const string & snap_name,
1993 uint32_t control_channels,
1994 uint32_t master_channels,
1995 AutoConnectOption input_connect,
1996 AutoConnectOption output_connect,
1999 nframes_t initial_length)
2001 Session *new_session;
2004 session_loaded = false;
2005 x = unload_session ();
2012 _session_is_new = true;
2015 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
2016 control_channels, master_channels, nphysin, nphysout, initial_length);
2021 MessageDialog msg (string_compose(_("Could not create session in \"%1\""), path));
2026 connect_to_session (new_session);
2028 session_loaded = true;
2036 editor->show_window ();
2047 ARDOUR_UI::show_splash ()
2050 about = new About();
2051 about->signal_response().connect(mem_fun (*this, &ARDOUR_UI::about_signal_response) );
2058 ARDOUR_UI::about_signal_response(int response)
2064 ARDOUR_UI::hide_splash ()
2067 about->get_window()->set_cursor ();
2073 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title, const string & msg)
2077 removed = rep.paths.size();
2080 MessageDialog msgd (*editor,
2081 _("No audio files were ready for cleanup"),
2084 (Gtk::ButtonsType)(Gtk::BUTTONS_OK) );
2085 msgd.set_secondary_text (_("If this seems suprising, \n\
2086 check for any existing snapshots.\n\
2087 These may still include regions that\n\
2088 require some unused files to continue to exist."));
2094 ArdourDialog results (_("ardour: cleanup"), true, false);
2096 struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
2097 CleanupResultsModelColumns() {
2101 Gtk::TreeModelColumn<Glib::ustring> visible_name;
2102 Gtk::TreeModelColumn<Glib::ustring> fullpath;
2106 CleanupResultsModelColumns results_columns;
2107 Glib::RefPtr<Gtk::ListStore> results_model;
2108 Gtk::TreeView results_display;
2110 results_model = ListStore::create (results_columns);
2111 results_display.set_model (results_model);
2112 results_display.append_column (list_title, results_columns.visible_name);
2114 results_display.set_name ("CleanupResultsList");
2115 results_display.set_headers_visible (true);
2116 results_display.set_headers_clickable (false);
2117 results_display.set_reorderable (false);
2119 Gtk::ScrolledWindow list_scroller;
2122 Gtk::HBox dhbox; // the hbox for the image and text
2123 Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
2124 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO, Gtk::ICON_SIZE_DIALOG));
2126 dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
2128 if (rep.space < 1048576.0f) {
2130 txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2132 txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2136 txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2138 txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2142 dhbox.pack_start (*dimage, true, false, 5);
2143 dhbox.pack_start (txt, true, false, 5);
2145 for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2146 TreeModel::Row row = *(results_model->append());
2147 row[results_columns.visible_name] = *i;
2148 row[results_columns.fullpath] = *i;
2151 list_scroller.add (results_display);
2152 list_scroller.set_size_request (-1, 150);
2153 list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2155 dvbox.pack_start (dhbox, true, false, 5);
2156 dvbox.pack_start (list_scroller, true, false, 5);
2157 ddhbox.pack_start (dvbox, true, false, 5);
2159 results.get_vbox()->pack_start (ddhbox, true, false, 5);
2160 results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
2161 results.set_default_response (RESPONSE_CLOSE);
2162 results.set_position (Gtk::WIN_POS_MOUSE);
2163 results.show_all_children ();
2164 results.set_resizable (false);
2171 ARDOUR_UI::cleanup ()
2174 /* shouldn't happen: menu item is insensitive */
2179 MessageDialog checker (_("Are you sure you want to cleanup?"),
2181 Gtk::MESSAGE_QUESTION,
2182 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
2184 checker.set_secondary_text(_("Cleanup is a destructive operation.\n\
2185 ALL undo/redo information will be lost if you cleanup.\n\
2186 After cleanup, unused audio files will be moved to a \
2187 \"dead sounds\" location."));
2189 checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2190 checker.add_button (_("Clean Up"), RESPONSE_ACCEPT);
2191 checker.set_default_response (RESPONSE_CANCEL);
2193 checker.set_name (_("CleanupDialog"));
2194 checker.set_wmclass (X_("ardour_cleanup"), "Ardour");
2195 checker.set_position (Gtk::WIN_POS_MOUSE);
2197 switch (checker.run()) {
2198 case RESPONSE_ACCEPT:
2204 Session::cleanup_report rep;
2206 editor->prepare_for_cleanup ();
2208 /* do not allow flush until a session is reloaded */
2210 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
2212 act->set_sensitive (false);
2215 if (session->cleanup_sources (rep)) {
2220 display_cleanup_results (rep,
2223 The following %1 %2 not in use and \n\
2224 have been moved to:\n\
2226 Flushing the wastebasket will \n\
2227 release an additional\n\
2228 %4 %5bytes of disk space.\n"
2236 ARDOUR_UI::flush_trash ()
2239 /* shouldn't happen: menu item is insensitive */
2243 Session::cleanup_report rep;
2245 if (session->cleanup_trash_sources (rep)) {
2249 display_cleanup_results (rep,
2251 _("The following %1 %2 deleted from\n\
2253 releasing %4 %5bytes of disk space"));
2257 ARDOUR_UI::add_route (Gtk::Window* float_window)
2265 if (add_route_dialog == 0) {
2266 add_route_dialog = new AddRouteDialog;
2268 add_route_dialog->set_transient_for (*float_window);
2272 if (add_route_dialog->is_visible()) {
2273 /* we're already doing this */
2277 ResponseType r = (ResponseType) add_route_dialog->run ();
2279 add_route_dialog->hide();
2282 case RESPONSE_ACCEPT:
2289 if ((count = add_route_dialog->count()) <= 0) {
2293 uint32_t input_chan = add_route_dialog->channels ();
2294 uint32_t output_chan;
2295 string name_template = add_route_dialog->name_template ();
2296 bool track = add_route_dialog->track ();
2298 AutoConnectOption oac = Config->get_output_auto_connect();
2300 if (oac & AutoConnectMaster) {
2301 output_chan = (session->master_out() ? session->master_out()->n_inputs() : input_chan);
2303 output_chan = input_chan;
2306 /* XXX do something with name template */
2309 session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), count);
2311 session_add_audio_bus (input_chan, output_chan, count);
2316 ARDOUR_UI::mixer_settings () const
2321 node = session->instant_xml(X_("Mixer"), session->path());
2323 node = Config->instant_xml(X_("Mixer"), get_user_ardour_path());
2327 node = new XMLNode (X_("Mixer"));
2334 ARDOUR_UI::editor_settings () const
2339 node = session->instant_xml(X_("Editor"), session->path());
2341 node = Config->instant_xml(X_("Editor"), get_user_ardour_path());
2345 node = new XMLNode (X_("Editor"));
2351 ARDOUR_UI::keyboard_settings () const
2355 node = Config->extra_xml(X_("Keyboard"));
2358 node = new XMLNode (X_("Keyboard"));
2364 ARDOUR_UI::halt_on_xrun_message ()
2366 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
2368 MessageDialog msg (*editor,
2369 _("Recording was stopped because your system could not keep up."));
2374 ARDOUR_UI::disk_overrun_handler ()
2376 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
2378 if (!have_disk_speed_dialog_displayed) {
2379 have_disk_speed_dialog_displayed = true;
2380 MessageDialog* msg = new MessageDialog (*editor, X_("diskrate dialog"), _("\
2381 The disk system on your computer\n\
2382 was not able to keep up with Ardour.\n\
2384 Specifically, it failed to write data to disk\n\
2385 quickly enough to keep up with recording.\n"));
2386 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
2392 ARDOUR_UI::disk_underrun_handler ()
2394 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2396 if (!have_disk_speed_dialog_displayed) {
2397 have_disk_speed_dialog_displayed = true;
2398 MessageDialog* msg = new MessageDialog (*editor,
2399 _("The disk system on your computer\n\
2400 was not able to keep up with Ardour.\n\
2402 Specifically, it failed to read data from disk\n\
2403 quickly enough to keep up with playback.\n"));
2404 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
2410 ARDOUR_UI::disk_speed_dialog_gone (int ignored_response, MessageDialog* msg)
2412 have_disk_speed_dialog_displayed = false;
2417 ARDOUR_UI::pending_state_dialog ()
2419 ArdourDialog dialog ("pending state dialog");
2421 This session appears to have been in\n\
2422 middle of recording when ardour or\n\
2423 the computer was shutdown.\n\
2425 Ardour can recover any captured audio for\n\
2426 you, or it can ignore it. Please decide\n\
2427 what you would like to do.\n"));
2429 dialog.get_vbox()->pack_start (message);
2430 dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
2431 dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
2433 dialog.set_position (WIN_POS_CENTER);
2436 switch (dialog.run ()) {
2437 case RESPONSE_ACCEPT:
2445 ARDOUR_UI::disconnect_from_jack ()
2448 if( engine->disconnect_from_jack ()) {
2449 MessageDialog msg (*editor, _("Could not disconnect from JACK"));
2453 update_sample_rate (0);
2458 ARDOUR_UI::reconnect_to_jack ()
2461 if (engine->reconnect_to_jack ()) {
2462 MessageDialog msg (*editor, _("Could not reconnect to JACK"));
2466 update_sample_rate (0);
2471 ARDOUR_UI::cmdline_new_session (string path)
2473 if (path[0] != '/') {
2474 char buf[PATH_MAX+1];
2477 getcwd (buf, sizeof (buf));
2486 _will_create_new_session_automatically = false; /* done it */
2487 return FALSE; /* don't call it again */
2491 ARDOUR_UI::use_config ()
2493 Glib::RefPtr<Action> act;
2495 switch (Config->get_native_file_data_format ()) {
2497 act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
2500 act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
2505 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2506 ract->set_active ();
2509 switch (Config->get_native_file_header_format ()) {
2511 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
2514 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
2517 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
2520 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
2523 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
2526 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatCAF"));
2529 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatAIFF"));
2534 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2535 ract->set_active ();
2538 XMLNode* node = Config->extra_xml (X_("TransportControllables"));
2540 set_transport_controllable_state (*node);
2545 ARDOUR_UI::update_transport_clocks (nframes_t pos)
2547 primary_clock.set (pos);
2548 secondary_clock.set (pos);
2550 if (big_clock_window) {
2551 big_clock.set (pos);
2556 ARDOUR_UI::record_state_changed ()
2558 ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::record_state_changed));
2560 if (!session || !big_clock_window) {
2561 /* why bother - the clock isn't visible */
2565 switch (session->record_status()) {
2566 case Session::Recording:
2567 big_clock.set_widget_name ("BigClockRecording");
2570 big_clock.set_widget_name ("BigClockNonRecording");
2576 ARDOUR_UI::set_keybindings_path (string path)
2578 keybindings_path = path;
2582 ARDOUR_UI::save_keybindings ()
2584 if (can_save_keybindings) {
2585 AccelMap::save (keybindings_path);
2590 ARDOUR_UI::first_idle ()
2592 can_save_keybindings = true;
2597 ARDOUR_UI::store_clock_modes ()
2599 XMLNode* node = new XMLNode(X_("ClockModes"));
2601 for (vector<AudioClock*>::iterator x = AudioClock::clocks.begin(); x != AudioClock::clocks.end(); ++x) {
2602 node->add_property ((*x)->name().c_str(), enum_2_string ((*x)->mode()));
2605 session->add_extra_xml (*node);
2606 session->set_dirty ();
2611 ARDOUR_UI::TransportControllable::TransportControllable (std::string name, ARDOUR_UI& u, ToggleType tp)
2612 : Controllable (name), ui (u), type(tp)
2618 ARDOUR_UI::TransportControllable::set_value (float val)
2620 if (type == ShuttleControl) {
2627 fract = -((0.5f - val)/0.5f);
2629 fract = ((val - 0.5f)/0.5f);
2633 ui.set_shuttle_fract (fract);
2638 /* do nothing: these are radio-style actions */
2646 action = X_("Roll");
2649 action = X_("Stop");
2652 action = X_("Goto Start");
2655 action = X_("Goto End");
2658 action = X_("Loop");
2661 action = X_("Play Selection");
2664 action = X_("Record");
2674 Glib::RefPtr<Action> act = ActionManager::get_action ("Transport", action);
2682 ARDOUR_UI::TransportControllable::get_value (void) const
2701 case ShuttleControl:
2711 ARDOUR_UI::TransportControllable::set_id (const string& str)