2 Copyright (C) 1999-2007 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 #include <sys/resource.h>
33 #include <gtkmm/messagedialog.h>
34 #include <gtkmm/accelmap.h>
36 #include <pbd/error.h>
37 #include <pbd/compose.h>
38 #include <pbd/pathscanner.h>
39 #include <pbd/failed_constructor.h>
40 #include <pbd/enumwriter.h>
41 #include <pbd/stacktrace.h>
42 #include <gtkmm2ext/gtk_ui.h>
43 #include <gtkmm2ext/utils.h>
44 #include <gtkmm2ext/click_box.h>
45 #include <gtkmm2ext/fastmeter.h>
46 #include <gtkmm2ext/stop_signal.h>
47 #include <gtkmm2ext/popup.h>
49 #include <midi++/port.h>
50 #include <midi++/mmc.h>
52 #include <ardour/ardour.h>
53 #include <ardour/session_route.h>
54 #include <ardour/port.h>
55 #include <ardour/audioengine.h>
56 #include <ardour/playlist.h>
57 #include <ardour/utils.h>
58 #include <ardour/audio_diskstream.h>
59 #include <ardour/audiofilesource.h>
60 #include <ardour/recent_sessions.h>
61 #include <ardour/port.h>
62 #include <ardour/audio_track.h>
65 #include "ardour_ui.h"
66 #include "public_editor.h"
67 #include "audio_clock.h"
72 #include "add_route_dialog.h"
73 #include "new_session_dialog.h"
76 #include "gui_thread.h"
77 #include "color_manager.h"
81 using namespace ARDOUR;
83 using namespace Gtkmm2ext;
87 ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
89 sigc::signal<void,bool> ARDOUR_UI::Blink;
90 sigc::signal<void> ARDOUR_UI::RapidScreenUpdate;
91 sigc::signal<void> ARDOUR_UI::MidRapidScreenUpdate;
92 sigc::signal<void> ARDOUR_UI::SuperRapidScreenUpdate;
93 sigc::signal<void,nframes_t> ARDOUR_UI::Clock;
95 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
97 : Gtkmm2ext::UI ("ardour", argcp, argvp, rcfile),
99 primary_clock (X_("primary"), false, X_("TransportClockDisplay"), true, false, true),
100 secondary_clock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, false, true),
101 preroll_clock (X_("preroll"), false, X_("PreRollClock"), true, true),
102 postroll_clock (X_("postroll"), false, X_("PostRollClock"), true, true),
106 adjuster_table (3, 3),
110 preroll_button (_("pre\nroll")),
111 postroll_button (_("post\nroll")),
115 big_clock (X_("bigclock"), false, "BigClockNonRecording", false, false, true),
119 roll_controllable ("transport roll", *this, TransportControllable::Roll),
120 stop_controllable ("transport stop", *this, TransportControllable::Stop),
121 goto_start_controllable ("transport goto start", *this, TransportControllable::GotoStart),
122 goto_end_controllable ("transport goto end", *this, TransportControllable::GotoEnd),
123 auto_loop_controllable ("transport auto loop", *this, TransportControllable::AutoLoop),
124 play_selection_controllable ("transport play selection", *this, TransportControllable::PlaySelection),
125 rec_controllable ("transport rec-enable", *this, TransportControllable::RecordEnable),
126 shuttle_controllable ("shuttle", *this, TransportControllable::ShuttleControl),
127 shuttle_controller_binding_proxy (shuttle_controllable),
129 roll_button (roll_controllable),
130 stop_button (stop_controllable),
131 goto_start_button (goto_start_controllable),
132 goto_end_button (goto_end_controllable),
133 auto_loop_button (auto_loop_controllable),
134 play_selection_button (play_selection_controllable),
135 rec_button (rec_controllable),
137 shuttle_units_button (_("% ")),
139 punch_in_button (_("Punch In")),
140 punch_out_button (_("Punch Out")),
141 auto_return_button (_("Auto Return")),
142 auto_play_button (_("Auto Play")),
143 auto_input_button (_("Auto Input")),
144 click_button (_("Click")),
145 time_master_button (_("time\nmaster")),
147 auditioning_alert_button (_("AUDITION")),
148 solo_alert_button (_("SOLO")),
151 using namespace Gtk::Menu_Helpers;
157 if (theArdourUI == 0) {
163 color_manager = new ColorManager();
165 std::string color_file = ARDOUR::find_config_file("ardour.colors");
167 color_manager->load (color_file);
172 _session_is_new = false;
173 big_clock_window = 0;
174 session_selector_window = 0;
175 last_key_press_time = 0;
176 connection_editor = 0;
177 add_route_dialog = 0;
181 open_session_selector = 0;
182 have_configure_timeout = false;
183 have_disk_speed_dialog_displayed = false;
184 _will_create_new_session_automatically = false;
185 session_loaded = false;
186 last_speed_displayed = -1.0f;
187 keybindings_path = ARDOUR::find_config_file ("ardour.bindings");
189 can_save_keybindings = false;
190 Glib::signal_idle().connect (mem_fun (*this, &ARDOUR_UI::first_idle));
192 last_configure_time.tv_sec = 0;
193 last_configure_time.tv_usec = 0;
195 shuttle_grabbed = false;
197 shuttle_max_speed = 8.0f;
199 shuttle_style_menu = 0;
200 shuttle_unit_menu = 0;
202 gettimeofday (&last_peak_grab, 0);
203 gettimeofday (&last_shuttle_request, 0);
205 ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
206 ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
208 /* handle pending state with a dialog */
210 ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
212 /* have to wait for AudioEngine and Configuration before proceeding */
216 ARDOUR_UI::set_engine (AudioEngine& e)
220 engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
221 engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
222 engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
223 engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
225 ActionManager::init ();
226 new_session_dialog = new NewSessionDialog();
230 keyboard = new Keyboard;
232 if (setup_windows ()) {
233 throw failed_constructor ();
236 if (GTK_ARDOUR::show_key_actions) {
237 vector<string> names;
238 vector<string> paths;
240 vector<AccelKey> bindings;
242 ActionManager::get_all_actions (names, paths, keys, bindings);
244 vector<string>::iterator n;
245 vector<string>::iterator k;
246 for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) {
247 cerr << "Action: " << (*n) << " bound to " << (*k) << endl;
253 /* start with timecode, metering enabled
256 blink_timeout_tag = -1;
258 /* the global configuration object is now valid */
262 /* this being a GUI and all, we want peakfiles */
264 AudioFileSource::set_build_peakfiles (true);
265 AudioFileSource::set_build_missing_peakfiles (true);
267 if (AudioSource::start_peak_thread ()) {
268 throw failed_constructor();
271 /* set default clock modes */
273 primary_clock.set_mode (AudioClock::SMPTE);
274 secondary_clock.set_mode (AudioClock::BBT);
276 /* start the time-of-day-clock */
278 update_wall_clock ();
279 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
281 update_disk_space ();
283 update_sample_rate (engine->frame_rate());
285 starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
286 stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
289 ARDOUR_UI::~ARDOUR_UI ()
291 save_ardour_state ();
305 if (add_route_dialog) {
306 delete add_route_dialog;
309 AudioSource::stop_peak_thread ();
313 ARDOUR_UI::configure_timeout ()
318 if (last_configure_time.tv_sec == 0 && last_configure_time.tv_usec == 0) {
319 /* no configure events yet */
323 gettimeofday (&now, 0);
324 timersub (&now, &last_configure_time, &diff);
326 /* force a gap of 0.5 seconds since the last configure event
329 if (diff.tv_sec == 0 && diff.tv_usec < 500000) {
332 have_configure_timeout = false;
333 save_ardour_state ();
339 ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
341 if (have_configure_timeout) {
342 gettimeofday (&last_configure_time, 0);
344 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
345 have_configure_timeout = true;
352 ARDOUR_UI::set_transport_controllable_state (const XMLNode& node)
354 const XMLProperty* prop;
356 if ((prop = node.property ("roll")) != 0) {
357 roll_controllable.set_id (prop->value());
359 if ((prop = node.property ("stop")) != 0) {
360 stop_controllable.set_id (prop->value());
362 if ((prop = node.property ("goto_start")) != 0) {
363 goto_start_controllable.set_id (prop->value());
365 if ((prop = node.property ("goto_end")) != 0) {
366 goto_end_controllable.set_id (prop->value());
368 if ((prop = node.property ("auto_loop")) != 0) {
369 auto_loop_controllable.set_id (prop->value());
371 if ((prop = node.property ("play_selection")) != 0) {
372 play_selection_controllable.set_id (prop->value());
374 if ((prop = node.property ("rec")) != 0) {
375 rec_controllable.set_id (prop->value());
377 if ((prop = node.property ("shuttle")) != 0) {
378 shuttle_controllable.set_id (prop->value());
383 ARDOUR_UI::get_transport_controllable_state ()
385 XMLNode* node = new XMLNode(X_("TransportControllables"));
388 roll_controllable.id().print (buf, sizeof (buf));
389 node->add_property (X_("roll"), buf);
390 stop_controllable.id().print (buf, sizeof (buf));
391 node->add_property (X_("stop"), buf);
392 goto_start_controllable.id().print (buf, sizeof (buf));
393 node->add_property (X_("goto_start"), buf);
394 goto_end_controllable.id().print (buf, sizeof (buf));
395 node->add_property (X_("goto_end"), buf);
396 auto_loop_controllable.id().print (buf, sizeof (buf));
397 node->add_property (X_("auto_loop"), buf);
398 play_selection_controllable.id().print (buf, sizeof (buf));
399 node->add_property (X_("play_selection"), buf);
400 rec_controllable.id().print (buf, sizeof (buf));
401 node->add_property (X_("rec"), buf);
402 shuttle_controllable.id().print (buf, sizeof (buf));
403 node->add_property (X_("shuttle"), buf);
409 ARDOUR_UI::save_ardour_state ()
411 if (!keyboard || !mixer || !editor) {
415 /* XXX this is all a bit dubious. add_extra_xml() uses
416 a different lifetime model from add_instant_xml().
419 XMLNode* node = new XMLNode (keyboard->get_state());
420 Config->add_extra_xml (*node);
421 Config->add_extra_xml (get_transport_controllable_state());
422 Config->save_state();
424 XMLNode enode(static_cast<Stateful*>(editor)->get_state());
425 XMLNode mnode(mixer->get_state());
428 session->add_instant_xml (enode, session->path());
429 session->add_instant_xml (mnode, session->path());
431 Config->add_instant_xml (enode, get_user_ardour_path());
432 Config->add_instant_xml (mnode, get_user_ardour_path());
439 ARDOUR_UI::startup ()
441 if (engine->is_realtime()) {
443 struct rlimit limits;
445 if (getrlimit (RLIMIT_MEMLOCK, &limits)) {
449 if (limits.rlim_cur != RLIM_INFINITY) {
450 MessageDialog msg (_("WARNING: Your system has a limit for maximum amount of locked memory. "
451 "This might cause Ardour to run out of memory before your system "
452 "runs out of memory. \n\n"
453 "You can view the memory limit with 'ulimit -l', "
454 "and it is normally controlled by /etc/security/limits.conf"));
456 editor->ensure_float (msg);
465 if (session && session->dirty()) {
466 switch (ask_about_saving_session(_("quit"))) {
471 /* use the default name */
472 if (save_state_canfail ("")) {
473 /* failed - don't quit */
474 MessageDialog msg (*editor,
476 Ardour was unable to save your session.\n\n\
477 If you still wish to quit, please use the\n\n\
478 \"Just quit\" option."));
489 session->set_deletion_in_progress ();
492 Config->save_state();
497 ARDOUR_UI::ask_about_saving_session (const string & what)
499 ArdourDialog window (_("ardour: save session?"));
500 Gtk::HBox dhbox; // the hbox for the image and text
501 Gtk::Label prompt_label;
502 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_WARNING, Gtk::ICON_SIZE_DIALOG));
506 msg = string_compose(_("Don't %1"), what);
507 window.add_button (msg, RESPONSE_REJECT);
508 msg = string_compose(_("Just %1"), what);
509 window.add_button (msg, RESPONSE_APPLY);
510 msg = string_compose(_("Save and %1"), what);
511 window.add_button (msg, RESPONSE_ACCEPT);
513 window.set_default_response (RESPONSE_ACCEPT);
515 Gtk::Button noquit_button (msg);
516 noquit_button.set_name ("EditorGTKButton");
521 if (session->snap_name() == session->name()) {
524 type = _("snapshot");
526 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?"),
527 type, session->snap_name());
529 prompt_label.set_text (prompt);
530 prompt_label.set_name (X_("PrompterLabel"));
531 prompt_label.set_alignment(ALIGN_LEFT, ALIGN_TOP);
533 dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP)
535 dhbox.set_homogeneous (false);
536 dhbox.pack_start (*dimage, false, false, 5);
537 dhbox.pack_start (prompt_label, true, false, 5);
538 window.get_vbox()->pack_start (dhbox);
540 window.set_name (_("Prompter"));
541 window.set_position (Gtk::WIN_POS_MOUSE);
542 window.set_modal (true);
543 window.set_resizable (false);
546 save_the_session = 0;
548 window.set_keep_above (true);
551 ResponseType r = (ResponseType) window.run();
556 case RESPONSE_ACCEPT: // save and get out of here
558 case RESPONSE_APPLY: // get out of here
568 ARDOUR_UI::every_second ()
571 update_buffer_load ();
572 update_disk_space ();
577 ARDOUR_UI::every_point_one_seconds ()
579 update_speed_display ();
580 RapidScreenUpdate(); /* EMIT_SIGNAL */
585 ARDOUR_UI::every_point_oh_five_seconds ()
587 MidRapidScreenUpdate(); /* EMIT_SIGNAL */
592 ARDOUR_UI::every_point_zero_one_seconds ()
594 SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
599 ARDOUR_UI::update_sample_rate (nframes_t ignored)
603 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
605 if (!engine->connected()) {
607 snprintf (buf, sizeof (buf), _("disconnected"));
611 nframes_t rate = engine->frame_rate();
613 if (fmod (rate, 1000.0) != 0.0) {
614 snprintf (buf, sizeof (buf), _("%.1f kHz / %4.1f msecs"),
615 (float) rate/1000.0f,
616 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
618 snprintf (buf, sizeof (buf), _("%u kHz / %4.1f msecs"),
620 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
624 sample_rate_label.set_text (buf);
628 ARDOUR_UI::update_cpu_load ()
631 snprintf (buf, sizeof (buf), _("DSP: %.1f%%"), engine->get_cpu_load());
632 cpu_load_label.set_text (buf);
636 ARDOUR_UI::update_buffer_load ()
641 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"),
642 session->playback_load(), session->capture_load());
643 buffer_load_label.set_text (buf);
645 buffer_load_label.set_text ("");
650 ARDOUR_UI::count_recenabled_streams (Route& route)
652 Track* track = dynamic_cast<Track*>(&route);
653 if (track && track->diskstream()->record_enabled()) {
654 rec_enabled_streams += track->n_inputs();
659 ARDOUR_UI::update_disk_space()
665 nframes_t frames = session->available_capture_duration();
668 if (frames == max_frames) {
669 strcpy (buf, _("Disk: 24hrs+"));
674 nframes_t fr = session->frame_rate();
676 rec_enabled_streams = 0;
677 session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
679 if (rec_enabled_streams) {
680 frames /= rec_enabled_streams;
683 hrs = frames / (fr * 3600);
684 frames -= hrs * fr * 3600;
685 mins = frames / (fr * 60);
686 frames -= mins * fr * 60;
689 snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs);
692 disk_space_label.set_text (buf);
696 ARDOUR_UI::update_wall_clock ()
703 tm_now = localtime (&now);
705 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
706 wall_clock_label.set_text (buf);
711 ARDOUR_UI::control_methods_adjusted ()
716 which_method = (int) online_control_button->adjustment.get_value();
717 switch (which_method) {
719 allow_mmc_and_local ();
728 fatal << _("programming error: impossible control method") << endmsg;
734 ARDOUR_UI::mmc_device_id_adjusted ()
739 int dev_id = (int) mmc_id_button->adjustment.get_value();
740 mmc->set_device_id (dev_id);
746 ARDOUR_UI::session_menu (GdkEventButton *ev)
748 session_popup_menu->popup (0, 0);
753 ARDOUR_UI::redisplay_recent_sessions ()
755 vector<string *> *sessions;
756 vector<string *>::iterator i;
757 RecentSessionsSorter cmp;
759 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
760 recent_session_model->clear ();
763 ARDOUR::read_recent_sessions (rs);
766 recent_session_display.set_model (recent_session_model);
770 /* sort them alphabetically */
771 sort (rs.begin(), rs.end(), cmp);
772 sessions = new vector<string*>;
774 for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
775 sessions->push_back (new string ((*i).second));
778 for (i = sessions->begin(); i != sessions->end(); ++i) {
780 vector<string*>* states;
781 vector<const gchar*> item;
782 string fullpath = *(*i);
784 /* remove any trailing / */
786 if (fullpath[fullpath.length()-1] == '/') {
787 fullpath = fullpath.substr (0, fullpath.length()-1);
790 /* now get available states for this session */
792 if ((states = Session::possible_states (fullpath)) == 0) {
797 TreeModel::Row row = *(recent_session_model->append());
799 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
800 row[recent_session_columns.fullpath] = fullpath;
802 if (states->size() > 1) {
804 /* add the children */
806 for (vector<string*>::iterator i2 = states->begin(); i2 != states->end(); ++i2) {
808 TreeModel::Row child_row = *(recent_session_model->append (row.children()));
810 child_row[recent_session_columns.visible_name] = **i2;
811 child_row[recent_session_columns.fullpath] = fullpath;
820 recent_session_display.set_model (recent_session_model);
825 ARDOUR_UI::build_session_selector ()
827 session_selector_window = new ArdourDialog ("session selector");
829 Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
831 session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
832 session_selector_window->add_button (Stock::OPEN, RESPONSE_ACCEPT);
833 session_selector_window->set_default_response (RESPONSE_ACCEPT);
834 recent_session_model = TreeStore::create (recent_session_columns);
835 recent_session_display.set_model (recent_session_model);
836 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
837 recent_session_display.set_headers_visible (false);
838 recent_session_display.get_selection()->set_mode (SELECTION_SINGLE);
840 recent_session_display.signal_row_activated().connect (mem_fun (*this, &ARDOUR_UI::recent_session_row_activated));
842 scroller->add (recent_session_display);
843 scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
845 session_selector_window->set_name ("SessionSelectorWindow");
846 session_selector_window->set_size_request (200, 400);
847 session_selector_window->get_vbox()->pack_start (*scroller);
848 session_selector_window->show_all_children();
852 ARDOUR_UI::recent_session_row_activated (const TreePath& path, TreeViewColumn* col)
854 session_selector_window->response (RESPONSE_ACCEPT);
858 ARDOUR_UI::open_recent_session ()
860 /* popup selector window */
862 if (session_selector_window == 0) {
863 build_session_selector ();
866 redisplay_recent_sessions ();
868 ResponseType r = (ResponseType) session_selector_window->run ();
870 session_selector_window->hide();
873 case RESPONSE_ACCEPT:
879 Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
881 if (i == recent_session_model->children().end()) {
885 Glib::ustring path = (*i)[recent_session_columns.fullpath];
886 Glib::ustring state = (*i)[recent_session_columns.visible_name];
888 _session_is_new = false;
890 load_session (path, state);
894 ARDOUR_UI::filter_ardour_session_dirs (const FileFilter::Info& info)
898 if (stat (info.filename.c_str(), &statbuf) != 0) {
902 if (!S_ISDIR(statbuf.st_mode)) {
908 string session_file = info.filename;
910 session_file += Glib::path_get_basename (info.filename);
911 session_file += ".ardour";
913 if (stat (session_file.c_str(), &statbuf) != 0) {
917 return S_ISREG (statbuf.st_mode);
921 ARDOUR_UI::open_session ()
923 /* popup selector window */
925 if (open_session_selector == 0) {
927 /* ardour sessions are folders */
929 open_session_selector = new Gtk::FileChooserDialog (_("open session"), FILE_CHOOSER_ACTION_OPEN);
930 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
931 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
933 FileFilter session_filter;
934 session_filter.add_pattern ("*.ardour");
935 session_filter.set_name (_("Ardour sessions"));
936 open_session_selector->add_filter (session_filter);
937 open_session_selector->set_filter (session_filter);
940 int response = open_session_selector->run();
941 open_session_selector->hide ();
944 case RESPONSE_ACCEPT:
947 open_session_selector->hide();
951 open_session_selector->hide();
952 string session_path = open_session_selector->get_filename();
956 if (session_path.length() > 0) {
957 if (Session::find_session (session_path, path, name, isnew) == 0) {
958 _session_is_new = isnew;
959 load_session (path, name);
966 ARDOUR_UI::session_add_midi_track ()
968 cerr << _("Patience is a virtue.\n");
972 ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, uint32_t how_many)
974 list<boost::shared_ptr<AudioTrack> > tracks;
975 Session::RouteList routes;
978 warning << _("You cannot add a track or bus without a session already loaded.") << endmsg;
984 tracks = session->new_audio_track (input_channels, output_channels, mode, how_many);
986 if (tracks.size() != how_many) {
988 error << _("could not create a new audio track") << endmsg;
990 error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
996 routes = session->new_audio_route (input_channels, output_channels, how_many);
998 if (routes.size() != how_many) {
1000 error << _("could not create a new audio track") << endmsg;
1002 error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
1008 if (need_control_room_outs) {
1014 route->set_stereo_control_outs (control_lr_channels);
1015 route->control_outs()->set_stereo_pan (pans, this);
1017 #endif /* CONTROLOUTS */
1021 MessageDialog msg (*editor,
1022 _("There are insufficient JACK ports available\n\
1023 to create a new track or bus.\n\
1024 You should save Ardour, exit and\n\
1025 restart JACK with more ports."));
1031 ARDOUR_UI::do_transport_locate (nframes_t new_position)
1033 nframes_t _preroll = 0;
1036 // XXX CONFIG_CHANGE FIX - requires AnyTime handling
1037 // _preroll = session->convert_to_frames_at (new_position, Config->get_preroll());
1039 if (new_position > _preroll) {
1040 new_position -= _preroll;
1045 session->request_locate (new_position);
1050 ARDOUR_UI::transport_goto_start ()
1053 session->goto_start();
1056 /* force displayed area in editor to start no matter
1057 what "follow playhead" setting is.
1061 editor->reset_x_origin (session->current_start_frame());
1067 ARDOUR_UI::transport_goto_zero ()
1070 session->request_locate (0);
1073 /* force displayed area in editor to start no matter
1074 what "follow playhead" setting is.
1078 editor->reset_x_origin (0);
1084 ARDOUR_UI::transport_goto_end ()
1087 nframes_t frame = session->current_end_frame();
1088 session->request_locate (frame);
1090 /* force displayed area in editor to start no matter
1091 what "follow playhead" setting is.
1095 editor->reset_x_origin (frame);
1101 ARDOUR_UI::transport_stop ()
1107 if (session->is_auditioning()) {
1108 session->cancel_audition ();
1112 if (session->get_play_loop ()) {
1113 session->request_play_loop (false);
1116 session->request_stop ();
1120 ARDOUR_UI::transport_stop_and_forget_capture ()
1123 session->request_stop (true);
1128 ARDOUR_UI::remove_last_capture()
1131 editor->remove_last_capture();
1136 ARDOUR_UI::transport_record ()
1138 cerr << "transport record\n";
1141 switch (session->record_status()) {
1142 case Session::Disabled:
1143 if (session->ntracks() == 0) {
1144 MessageDialog msg (*editor, _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu."));
1148 session->maybe_enable_record ();
1150 case Session::Recording:
1151 case Session::Enabled:
1152 session->disable_record (true);
1158 ARDOUR_UI::transport_roll ()
1166 rolling = session->transport_rolling ();
1168 if (session->get_play_loop()) {
1169 session->request_play_loop (false);
1170 auto_loop_button.set_visual_state (1);
1171 roll_button.set_visual_state (1);
1172 } else if (session->get_play_range ()) {
1173 session->request_play_range (false);
1174 play_selection_button.set_visual_state (0);
1175 } else if (rolling) {
1176 session->request_locate (session->last_transport_start(), true);
1179 session->request_transport_speed (1.0f);
1183 ARDOUR_UI::transport_loop()
1186 if (session->get_play_loop()) {
1187 if (session->transport_rolling()) {
1188 Location * looploc = session->locations()->auto_loop_location();
1190 session->request_locate (looploc->start(), true);
1195 session->request_play_loop (true);
1201 ARDOUR_UI::transport_play_selection ()
1207 if (!session->get_play_range()) {
1208 session->request_stop ();
1211 editor->play_selection ();
1215 ARDOUR_UI::transport_rewind (int option)
1217 float current_transport_speed;
1220 current_transport_speed = session->transport_speed();
1222 if (current_transport_speed >= 0.0f) {
1225 session->request_transport_speed (-1.0f);
1228 session->request_transport_speed (-4.0f);
1231 session->request_transport_speed (-0.5f);
1236 session->request_transport_speed (current_transport_speed * 1.5f);
1242 ARDOUR_UI::transport_forward (int option)
1244 float current_transport_speed;
1247 current_transport_speed = session->transport_speed();
1249 if (current_transport_speed <= 0.0f) {
1252 session->request_transport_speed (1.0f);
1255 session->request_transport_speed (4.0f);
1258 session->request_transport_speed (0.5f);
1263 session->request_transport_speed (current_transport_speed * 1.5f);
1269 ARDOUR_UI::toggle_record_enable (uint32_t dstream)
1275 boost::shared_ptr<Route> r;
1277 if ((r = session->route_by_remote_id (dstream)) != 0) {
1281 if ((t = dynamic_cast<Track*>(r.get())) != 0) {
1282 t->diskstream()->set_record_enabled (!t->diskstream()->record_enabled());
1291 ARDOUR_UI::queue_transport_change ()
1293 Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
1297 ARDOUR_UI::map_transport_state ()
1299 float sp = session->transport_speed();
1302 transport_rolling ();
1303 } else if (sp < 0.0f) {
1304 transport_rewinding ();
1305 } else if (sp > 0.0f) {
1306 transport_forwarding ();
1308 transport_stopped ();
1313 ARDOUR_UI::allow_local_only ()
1319 ARDOUR_UI::allow_mmc_only ()
1325 ARDOUR_UI::allow_mmc_and_local ()
1331 ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg)
1333 snprintf (buf, sizeof(buf), "%s", ((GlobalClickBox *) arg)->strings[
1334 (int) adj.get_value()].c_str());
1338 ARDOUR_UI::engine_stopped ()
1340 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
1341 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1342 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1346 ARDOUR_UI::engine_running ()
1348 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
1349 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true);
1350 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
1352 Glib::RefPtr<Action> action;
1353 char* action_name = 0;
1355 switch (engine->frames_per_cycle()) {
1357 action_name = X_("JACKLatency32");
1360 action_name = X_("JACKLatency64");
1363 action_name = X_("JACKLatency128");
1366 action_name = X_("JACKLatency512");
1369 action_name = X_("JACKLatency1024");
1372 action_name = X_("JACKLatency2048");
1375 action_name = X_("JACKLatency4096");
1378 action_name = X_("JACKLatency8192");
1381 /* XXX can we do anything useful ? */
1387 action = ActionManager::get_action (X_("JACK"), action_name);
1390 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic (action);
1391 ract->set_active ();
1397 ARDOUR_UI::engine_halted ()
1399 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
1401 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1402 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1404 update_sample_rate (0);
1406 MessageDialog msg (*editor,
1408 JACK has either been shutdown or it\n\
1409 disconnected Ardour because Ardour\n\
1410 was not fast enough. You can save the\n\
1411 session and/or try to reconnect to JACK ."));
1416 ARDOUR_UI::do_engine_start ()
1424 error << _("Unable to start the session running")
1434 ARDOUR_UI::start_engine ()
1436 if (do_engine_start () == 0) {
1437 if (session && _session_is_new) {
1438 /* we need to retain initial visual
1439 settings for a new session
1441 session->save_state ("");
1449 ARDOUR_UI::update_clocks ()
1451 if (!editor || !editor->dragging_playhead()) {
1452 Clock (session->audible_frame()); /* EMIT_SIGNAL */
1457 ARDOUR_UI::start_clocking ()
1459 clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
1463 ARDOUR_UI::stop_clocking ()
1465 clock_signal_connection.disconnect ();
1469 ARDOUR_UI::toggle_clocking ()
1472 if (clock_button.get_active()) {
1481 ARDOUR_UI::_blink (void *arg)
1484 ((ARDOUR_UI *) arg)->blink ();
1491 Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
1495 ARDOUR_UI::start_blinking ()
1497 /* Start the blink signal. Everybody with a blinking widget
1498 uses Blink to drive the widget's state.
1501 if (blink_timeout_tag < 0) {
1503 blink_timeout_tag = g_timeout_add (240, _blink, this);
1508 ARDOUR_UI::stop_blinking ()
1510 if (blink_timeout_tag >= 0) {
1511 g_source_remove (blink_timeout_tag);
1512 blink_timeout_tag = -1;
1517 ARDOUR_UI::name_io_setup (AudioEngine& engine,
1523 if (io.n_inputs() == 0) {
1528 /* XXX we're not handling multiple ports yet. */
1530 const char **connections = io.input(0)->get_connections();
1532 if (connections == 0 || connections[0] == '\0') {
1535 buf = connections[0];
1542 if (io.n_outputs() == 0) {
1547 /* XXX we're not handling multiple ports yet. */
1549 const char **connections = io.output(0)->get_connections();
1551 if (connections == 0 || connections[0] == '\0') {
1554 buf = connections[0];
1562 ARDOUR_UI::snapshot_session ()
1564 ArdourPrompter prompter (true);
1568 struct tm local_time;
1571 localtime_r (&n, &local_time);
1572 strftime (timebuf, sizeof(timebuf), "%FT%T", &local_time);
1574 prompter.set_name ("Prompter");
1575 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1576 prompter.set_prompt (_("Name of New Snapshot"));
1577 prompter.set_initial_text (timebuf);
1579 switch (prompter.run()) {
1580 case RESPONSE_ACCEPT:
1581 prompter.get_result (snapname);
1582 if (snapname.length()){
1583 save_state (snapname);
1593 ARDOUR_UI::save_state (const string & name)
1595 (void) save_state_canfail (name);
1599 ARDOUR_UI::save_state_canfail (string name)
1604 if (name.length() == 0) {
1605 name = session->snap_name();
1608 if ((ret = session->save_state (name)) != 0) {
1612 save_ardour_state (); /* XXX cannot fail? yeah, right ... */
1617 ARDOUR_UI::restore_state (string name)
1620 if (name.length() == 0) {
1621 name = session->name();
1623 session->restore_state (name);
1628 ARDOUR_UI::primary_clock_value_changed ()
1631 session->request_locate (primary_clock.current_time ());
1636 ARDOUR_UI::secondary_clock_value_changed ()
1639 session->request_locate (secondary_clock.current_time ());
1644 ARDOUR_UI::rec_enable_button_blink (bool onoff, AudioDiskstream *dstream, Widget *w)
1646 if (session && dstream && dstream->record_enabled()) {
1648 Session::RecordState rs;
1650 rs = session->record_status ();
1653 case Session::Disabled:
1654 case Session::Enabled:
1655 if (w->get_state() != STATE_SELECTED) {
1656 w->set_state (STATE_SELECTED);
1660 case Session::Recording:
1661 if (w->get_state() != STATE_ACTIVE) {
1662 w->set_state (STATE_ACTIVE);
1668 if (w->get_state() != STATE_NORMAL) {
1669 w->set_state (STATE_NORMAL);
1675 ARDOUR_UI::transport_rec_enable_blink (bool onoff)
1681 switch (session->record_status()) {
1682 case Session::Enabled:
1684 rec_button.set_visual_state (2);
1686 rec_button.set_visual_state (0);
1690 case Session::Recording:
1691 rec_button.set_visual_state (1);
1695 rec_button.set_visual_state (0);
1701 ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
1709 ARDOUR_UI::save_template ()
1712 ArdourPrompter prompter (true);
1715 prompter.set_name (X_("Prompter"));
1716 prompter.set_prompt (_("Name for mix template:"));
1717 prompter.set_initial_text(session->name() + _("-template"));
1718 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1720 switch (prompter.run()) {
1721 case RESPONSE_ACCEPT:
1722 prompter.get_result (name);
1724 if (name.length()) {
1725 session->save_template (name);
1735 ARDOUR_UI::new_session (std::string predetermined_path)
1737 string session_name;
1738 string session_path;
1740 int response = Gtk::RESPONSE_NONE;
1742 new_session_dialog->set_modal(true);
1743 new_session_dialog->set_name (predetermined_path);
1744 new_session_dialog->reset_recent();
1745 new_session_dialog->show();
1748 response = new_session_dialog->run ();
1750 _session_is_new = false;
1752 if (response == Gtk::RESPONSE_CANCEL || response == Gtk::RESPONSE_DELETE_EVENT) {
1757 new_session_dialog->hide ();
1760 } else if (response == Gtk::RESPONSE_NONE) {
1762 /* Clear was pressed */
1763 new_session_dialog->reset();
1765 } else if (response == Gtk::RESPONSE_YES) {
1767 /* YES == OPEN, but there's no enum for that */
1769 session_name = new_session_dialog->session_name();
1771 if (session_name.empty()) {
1772 response = Gtk::RESPONSE_NONE;
1776 if (session_name[0] == '/' ||
1777 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1778 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1779 load_session (Glib::path_get_dirname (session_name), session_name);
1781 session_path = new_session_dialog->session_folder();
1782 load_session (session_path, session_name);
1785 } else if (response == Gtk::RESPONSE_OK) {
1787 session_name = new_session_dialog->session_name();
1789 if (new_session_dialog->get_current_page() == 1) {
1791 /* XXX this is a bit of a hack..
1792 i really want the new sesion dialog to return RESPONSE_YES
1793 if we're on page 1 (the load page)
1794 Unfortunately i can't see how atm..
1797 if (session_name.empty()) {
1798 response = Gtk::RESPONSE_NONE;
1802 if (session_name[0] == '/' ||
1803 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1804 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1805 load_session (Glib::path_get_dirname (session_name), session_name);
1807 session_path = new_session_dialog->session_folder();
1808 load_session (session_path, session_name);
1813 if (session_name.empty()) {
1814 response = Gtk::RESPONSE_NONE;
1818 if (session_name[0] == '/' ||
1819 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1820 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1822 session_path = Glib::path_get_dirname (session_name);
1823 session_name = Glib::path_get_basename (session_name);
1827 session_path = new_session_dialog->session_folder();
1831 //XXX This is needed because session constructor wants a
1832 //non-existant path. hopefully this will be fixed at some point.
1834 session_path = Glib::build_filename (session_path, session_name);
1836 if (g_file_test (session_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
1838 Glib::ustring str = string_compose (_("This session\n%1\nalready exists. Do you want to open it?"), session_path);
1840 MessageDialog msg (str,
1842 Gtk::MESSAGE_WARNING,
1843 Gtk::BUTTONS_YES_NO,
1847 msg.set_name (X_("CleanupDialog"));
1848 msg.set_wmclass (X_("existing_session"), "Ardour");
1849 msg.set_position (Gtk::WIN_POS_MOUSE);
1851 switch (msg.run()) {
1853 load_session (session_path, session_name);
1857 response = RESPONSE_NONE;
1858 new_session_dialog->reset ();
1863 _session_is_new = true;
1865 std::string template_name = new_session_dialog->session_template_name();
1867 if (new_session_dialog->use_session_template()) {
1869 load_session (session_path, session_name, &template_name);
1875 AutoConnectOption iconnect;
1876 AutoConnectOption oconnect;
1878 if (new_session_dialog->create_control_bus()) {
1879 cchns = (uint32_t) new_session_dialog->control_channel_count();
1884 if (new_session_dialog->create_master_bus()) {
1885 mchns = (uint32_t) new_session_dialog->master_channel_count();
1890 if (new_session_dialog->connect_inputs()) {
1891 iconnect = AutoConnectPhysical;
1893 iconnect = AutoConnectOption (0);
1896 /// @todo some minor tweaks.
1898 if (new_session_dialog->connect_outs_to_master()) {
1899 oconnect = AutoConnectMaster;
1900 } else if (new_session_dialog->connect_outs_to_physical()) {
1901 oconnect = AutoConnectPhysical;
1903 oconnect = AutoConnectOption (0);
1906 uint32_t nphysin = (uint32_t) new_session_dialog->input_limit_count();
1907 uint32_t nphysout = (uint32_t) new_session_dialog->output_limit_count();
1909 build_session (session_path,
1917 engine->frame_rate() * 60 * 5);
1922 } while (response == Gtk::RESPONSE_NONE);
1926 new_session_dialog->get_window()->set_cursor();
1927 new_session_dialog->hide();
1931 ARDOUR_UI::close_session()
1938 ARDOUR_UI::load_session (const string & path, const string & snap_name, string* mix_template)
1940 Session *new_session;
1942 session_loaded = false;
1944 x = unload_session ();
1952 /* if it already exists, we must have write access */
1954 if (::access (path.c_str(), F_OK) == 0 && ::access (path.c_str(), W_OK)) {
1955 MessageDialog msg (*editor, _("You do not have write access to this session.\n"
1956 "This prevents the session from being loaded."));
1962 new_session = new Session (*engine, path, snap_name, mix_template);
1967 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
1971 connect_to_session (new_session);
1973 Config->set_current_owner (ConfigVariableBase::Interface);
1975 session_loaded = true;
1977 goto_editor_window ();
1980 session->set_clean ();
1987 ARDOUR_UI::build_session (const string & path, const string & snap_name,
1988 uint32_t control_channels,
1989 uint32_t master_channels,
1990 AutoConnectOption input_connect,
1991 AutoConnectOption output_connect,
1994 nframes_t initial_length)
1996 Session *new_session;
1999 session_loaded = false;
2000 x = unload_session ();
2007 _session_is_new = true;
2010 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
2011 control_channels, master_channels, nphysin, nphysout, initial_length);
2016 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
2020 connect_to_session (new_session);
2022 session_loaded = true;
2030 editor->show_window ();
2041 ARDOUR_UI::show_splash ()
2044 about = new About();
2045 about->signal_response().connect(mem_fun (*this, &ARDOUR_UI::about_signal_response) );
2052 ARDOUR_UI::about_signal_response(int response)
2058 ARDOUR_UI::hide_splash ()
2061 about->get_window()->set_cursor ();
2067 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title, const string & msg)
2071 removed = rep.paths.size();
2074 MessageDialog msgd (*editor,
2075 _("No audio files were ready for cleanup"),
2078 (Gtk::ButtonsType)(Gtk::BUTTONS_OK) );
2079 msgd.set_secondary_text (_("If this seems suprising, \n\
2080 check for any existing snapshots.\n\
2081 These may still include regions that\n\
2082 require some unused files to continue to exist."));
2088 ArdourDialog results (_("ardour: cleanup"), true, false);
2090 struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
2091 CleanupResultsModelColumns() {
2095 Gtk::TreeModelColumn<Glib::ustring> visible_name;
2096 Gtk::TreeModelColumn<Glib::ustring> fullpath;
2100 CleanupResultsModelColumns results_columns;
2101 Glib::RefPtr<Gtk::ListStore> results_model;
2102 Gtk::TreeView results_display;
2104 results_model = ListStore::create (results_columns);
2105 results_display.set_model (results_model);
2106 results_display.append_column (list_title, results_columns.visible_name);
2108 results_display.set_name ("CleanupResultsList");
2109 results_display.set_headers_visible (true);
2110 results_display.set_headers_clickable (false);
2111 results_display.set_reorderable (false);
2113 Gtk::ScrolledWindow list_scroller;
2116 Gtk::HBox dhbox; // the hbox for the image and text
2117 Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
2118 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO, Gtk::ICON_SIZE_DIALOG));
2120 dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
2122 if (rep.space < 1048576.0f) {
2124 txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2126 txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2130 txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2132 txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2136 dhbox.pack_start (*dimage, true, false, 5);
2137 dhbox.pack_start (txt, true, false, 5);
2139 for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2140 TreeModel::Row row = *(results_model->append());
2141 row[results_columns.visible_name] = *i;
2142 row[results_columns.fullpath] = *i;
2145 list_scroller.add (results_display);
2146 list_scroller.set_size_request (-1, 150);
2147 list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2149 dvbox.pack_start (dhbox, true, false, 5);
2150 dvbox.pack_start (list_scroller, true, false, 5);
2151 ddhbox.pack_start (dvbox, true, false, 5);
2153 results.get_vbox()->pack_start (ddhbox, true, false, 5);
2154 results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
2155 results.set_default_response (RESPONSE_CLOSE);
2156 results.set_position (Gtk::WIN_POS_MOUSE);
2157 results.show_all_children ();
2158 results.set_resizable (false);
2165 ARDOUR_UI::cleanup ()
2168 /* shouldn't happen: menu item is insensitive */
2173 MessageDialog checker (_("Are you sure you want to cleanup?"),
2175 Gtk::MESSAGE_QUESTION,
2176 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
2178 checker.set_secondary_text(_("Cleanup is a destructive operation.\n\
2179 ALL undo/redo information will be lost if you cleanup.\n\
2180 After cleanup, unused audio files will be moved to a \
2181 \"dead sounds\" location."));
2183 checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2184 checker.add_button (_("Clean Up"), RESPONSE_ACCEPT);
2185 checker.set_default_response (RESPONSE_CANCEL);
2187 checker.set_name (_("CleanupDialog"));
2188 checker.set_wmclass (X_("ardour_cleanup"), "Ardour");
2189 checker.set_position (Gtk::WIN_POS_MOUSE);
2191 switch (checker.run()) {
2192 case RESPONSE_ACCEPT:
2198 Session::cleanup_report rep;
2200 editor->prepare_for_cleanup ();
2202 /* do not allow flush until a session is reloaded */
2204 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
2206 act->set_sensitive (false);
2209 if (session->cleanup_sources (rep)) {
2214 display_cleanup_results (rep,
2217 The following %1 %2 not in use and \n\
2218 have been moved to:\n\
2220 Flushing the wastebasket will \n\
2221 release an additional\n\
2222 %4 %5bytes of disk space.\n"
2230 ARDOUR_UI::flush_trash ()
2233 /* shouldn't happen: menu item is insensitive */
2237 Session::cleanup_report rep;
2239 if (session->cleanup_trash_sources (rep)) {
2243 display_cleanup_results (rep,
2245 _("The following %1 %2 deleted from\n\
2247 releasing %4 %5bytes of disk space"));
2251 ARDOUR_UI::add_route ()
2259 if (add_route_dialog == 0) {
2260 add_route_dialog = new AddRouteDialog;
2261 editor->ensure_float (*add_route_dialog);
2264 if (add_route_dialog->is_visible()) {
2265 /* we're already doing this */
2269 ResponseType r = (ResponseType) add_route_dialog->run ();
2271 add_route_dialog->hide();
2274 case RESPONSE_ACCEPT:
2281 if ((count = add_route_dialog->count()) <= 0) {
2285 uint32_t input_chan = add_route_dialog->channels ();
2286 uint32_t output_chan;
2287 string name_template = add_route_dialog->name_template ();
2288 bool track = add_route_dialog->track ();
2290 AutoConnectOption oac = Config->get_output_auto_connect();
2292 if (oac & AutoConnectMaster) {
2293 output_chan = (session->master_out() ? session->master_out()->n_inputs() : input_chan);
2295 output_chan = input_chan;
2298 /* XXX do something with name template */
2301 session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), count);
2303 session_add_audio_bus (input_chan, output_chan, count);
2308 ARDOUR_UI::mixer_settings () const
2313 node = session->instant_xml(X_("Mixer"), session->path());
2315 node = Config->instant_xml(X_("Mixer"), get_user_ardour_path());
2319 node = new XMLNode (X_("Mixer"));
2326 ARDOUR_UI::editor_settings () const
2331 node = session->instant_xml(X_("Editor"), session->path());
2333 node = Config->instant_xml(X_("Editor"), get_user_ardour_path());
2337 node = new XMLNode (X_("Editor"));
2343 ARDOUR_UI::keyboard_settings () const
2347 node = Config->extra_xml(X_("Keyboard"));
2350 node = new XMLNode (X_("Keyboard"));
2356 ARDOUR_UI::halt_on_xrun_message ()
2358 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
2360 MessageDialog msg (*editor,
2361 _("Recording was stopped because your system could not keep up."));
2366 ARDOUR_UI::disk_overrun_handler ()
2368 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
2370 if (!have_disk_speed_dialog_displayed) {
2371 have_disk_speed_dialog_displayed = true;
2372 MessageDialog* msg = new MessageDialog (*editor, X_("diskrate dialog"), _("\
2373 The disk system on your computer\n\
2374 was not able to keep up with Ardour.\n\
2376 Specifically, it failed to write data to disk\n\
2377 quickly enough to keep up with recording.\n"));
2378 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
2384 ARDOUR_UI::disk_underrun_handler ()
2386 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2388 if (!have_disk_speed_dialog_displayed) {
2389 have_disk_speed_dialog_displayed = true;
2390 MessageDialog* msg = new MessageDialog (*editor,
2391 _("The disk system on your computer\n\
2392 was not able to keep up with Ardour.\n\
2394 Specifically, it failed to read data from disk\n\
2395 quickly enough to keep up with playback.\n"));
2396 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
2402 ARDOUR_UI::disk_speed_dialog_gone (int ignored_response, MessageDialog* msg)
2404 have_disk_speed_dialog_displayed = false;
2409 ARDOUR_UI::pending_state_dialog ()
2411 ArdourDialog dialog ("pending state dialog");
2413 This session appears to have been in\n\
2414 middle of recording when ardour or\n\
2415 the computer was shutdown.\n\
2417 Ardour can recover any captured audio for\n\
2418 you, or it can ignore it. Please decide\n\
2419 what you would like to do.\n"));
2421 dialog.get_vbox()->pack_start (message);
2422 dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
2423 dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
2425 dialog.set_position (WIN_POS_CENTER);
2428 switch (dialog.run ()) {
2429 case RESPONSE_ACCEPT:
2437 ARDOUR_UI::disconnect_from_jack ()
2440 if( engine->disconnect_from_jack ()) {
2441 MessageDialog msg (*editor, _("Could not disconnect from JACK"));
2445 update_sample_rate (0);
2450 ARDOUR_UI::reconnect_to_jack ()
2453 if (engine->reconnect_to_jack ()) {
2454 MessageDialog msg (*editor, _("Could not reconnect to JACK"));
2458 update_sample_rate (0);
2463 ARDOUR_UI::cmdline_new_session (string path)
2465 if (path[0] != '/') {
2466 char buf[PATH_MAX+1];
2469 getcwd (buf, sizeof (buf));
2478 _will_create_new_session_automatically = false; /* done it */
2479 return FALSE; /* don't call it again */
2483 ARDOUR_UI::use_config ()
2485 Glib::RefPtr<Action> act;
2487 switch (Config->get_native_file_data_format ()) {
2489 act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
2492 act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
2497 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2498 ract->set_active ();
2501 switch (Config->get_native_file_header_format ()) {
2503 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
2506 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
2509 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
2512 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
2515 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
2518 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatCAF"));
2521 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatAIFF"));
2526 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2527 ract->set_active ();
2530 XMLNode* node = Config->extra_xml (X_("TransportControllables"));
2532 set_transport_controllable_state (*node);
2537 ARDOUR_UI::update_transport_clocks (nframes_t pos)
2539 primary_clock.set (pos);
2540 secondary_clock.set (pos);
2542 if (big_clock_window) {
2543 big_clock.set (pos);
2548 ARDOUR_UI::record_state_changed ()
2550 ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::record_state_changed));
2552 if (!session || !big_clock_window) {
2553 /* why bother - the clock isn't visible */
2557 switch (session->record_status()) {
2558 case Session::Recording:
2559 big_clock.set_widget_name ("BigClockRecording");
2562 big_clock.set_widget_name ("BigClockNonRecording");
2568 ARDOUR_UI::set_keybindings_path (string path)
2570 keybindings_path = path;
2574 ARDOUR_UI::save_keybindings ()
2576 if (can_save_keybindings) {
2577 AccelMap::save (keybindings_path);
2582 ARDOUR_UI::first_idle ()
2584 can_save_keybindings = true;
2589 ARDOUR_UI::store_clock_modes ()
2591 XMLNode* node = new XMLNode(X_("ClockModes"));
2593 for (vector<AudioClock*>::iterator x = AudioClock::clocks.begin(); x != AudioClock::clocks.end(); ++x) {
2594 node->add_property ((*x)->name().c_str(), enum_2_string ((*x)->mode()));
2597 session->add_extra_xml (*node);
2598 session->set_dirty ();
2603 ARDOUR_UI::TransportControllable::TransportControllable (std::string name, ARDOUR_UI& u, ToggleType tp)
2604 : Controllable (name), ui (u), type(tp)
2610 ARDOUR_UI::TransportControllable::set_value (float val)
2612 if (type == ShuttleControl) {
2619 fract = -((0.5f - val)/0.5f);
2621 fract = ((val - 0.5f)/0.5f);
2625 ui.set_shuttle_fract (fract);
2630 /* do nothing: these are radio-style actions */
2638 action = X_("Roll");
2641 action = X_("Stop");
2644 action = X_("Goto Start");
2647 action = X_("Goto End");
2650 action = X_("Loop");
2653 action = X_("Play Selection");
2656 action = X_("Record");
2666 Glib::RefPtr<Action> act = ActionManager::get_action ("Transport", action);
2674 ARDOUR_UI::TransportControllable::get_value (void) const
2693 case ShuttleControl:
2703 ARDOUR_UI::TransportControllable::set_id (const string& str)