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_overrun_displayed = false;
184 have_disk_underrun_displayed = false;
185 _will_create_new_session_automatically = false;
186 session_loaded = false;
187 last_speed_displayed = -1.0f;
188 keybindings_path = ARDOUR::find_config_file ("ardour.bindings");
190 can_save_keybindings = false;
191 Glib::signal_idle().connect (mem_fun (*this, &ARDOUR_UI::first_idle));
193 last_configure_time.tv_sec = 0;
194 last_configure_time.tv_usec = 0;
196 shuttle_grabbed = false;
198 shuttle_max_speed = 8.0f;
200 shuttle_style_menu = 0;
201 shuttle_unit_menu = 0;
203 gettimeofday (&last_peak_grab, 0);
204 gettimeofday (&last_shuttle_request, 0);
206 ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
207 ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
209 /* handle pending state with a dialog */
211 ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
213 /* have to wait for AudioEngine and Configuration before proceeding */
217 ARDOUR_UI::set_engine (AudioEngine& e)
221 engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
222 engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
223 engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
224 engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
226 ActionManager::init ();
227 new_session_dialog = new NewSessionDialog();
231 keyboard = new Keyboard;
233 if (setup_windows ()) {
234 throw failed_constructor ();
237 if (GTK_ARDOUR::show_key_actions) {
238 vector<string> names;
239 vector<string> paths;
241 vector<AccelKey> bindings;
243 ActionManager::get_all_actions (names, paths, keys, bindings);
245 vector<string>::iterator n;
246 vector<string>::iterator k;
247 for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) {
248 cerr << "Action: " << (*n) << " bound to " << (*k) << endl;
254 /* start with timecode, metering enabled
257 blink_timeout_tag = -1;
259 /* the global configuration object is now valid */
263 /* this being a GUI and all, we want peakfiles */
265 AudioFileSource::set_build_peakfiles (true);
266 AudioFileSource::set_build_missing_peakfiles (true);
268 if (AudioSource::start_peak_thread ()) {
269 throw failed_constructor();
272 /* set default clock modes */
274 primary_clock.set_mode (AudioClock::SMPTE);
275 secondary_clock.set_mode (AudioClock::BBT);
277 /* start the time-of-day-clock */
279 update_wall_clock ();
280 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
282 update_disk_space ();
284 update_sample_rate (engine->frame_rate());
286 starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
287 stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
290 ARDOUR_UI::~ARDOUR_UI ()
292 save_ardour_state ();
306 if (add_route_dialog) {
307 delete add_route_dialog;
310 AudioSource::stop_peak_thread ();
314 ARDOUR_UI::configure_timeout ()
319 if (last_configure_time.tv_sec == 0 && last_configure_time.tv_usec == 0) {
320 /* no configure events yet */
324 gettimeofday (&now, 0);
325 timersub (&now, &last_configure_time, &diff);
327 /* force a gap of 0.5 seconds since the last configure event
330 if (diff.tv_sec == 0 && diff.tv_usec < 500000) {
333 have_configure_timeout = false;
334 save_ardour_state ();
340 ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
342 if (have_configure_timeout) {
343 gettimeofday (&last_configure_time, 0);
345 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
346 have_configure_timeout = true;
353 ARDOUR_UI::set_transport_controllable_state (const XMLNode& node)
355 const XMLProperty* prop;
357 if ((prop = node.property ("roll")) != 0) {
358 roll_controllable.set_id (prop->value());
360 if ((prop = node.property ("stop")) != 0) {
361 stop_controllable.set_id (prop->value());
363 if ((prop = node.property ("goto_start")) != 0) {
364 goto_start_controllable.set_id (prop->value());
366 if ((prop = node.property ("goto_end")) != 0) {
367 goto_end_controllable.set_id (prop->value());
369 if ((prop = node.property ("auto_loop")) != 0) {
370 auto_loop_controllable.set_id (prop->value());
372 if ((prop = node.property ("play_selection")) != 0) {
373 play_selection_controllable.set_id (prop->value());
375 if ((prop = node.property ("rec")) != 0) {
376 rec_controllable.set_id (prop->value());
378 if ((prop = node.property ("shuttle")) != 0) {
379 shuttle_controllable.set_id (prop->value());
384 ARDOUR_UI::get_transport_controllable_state ()
386 XMLNode* node = new XMLNode(X_("TransportControllables"));
389 roll_controllable.id().print (buf, sizeof (buf));
390 node->add_property (X_("roll"), buf);
391 stop_controllable.id().print (buf, sizeof (buf));
392 node->add_property (X_("stop"), buf);
393 goto_start_controllable.id().print (buf, sizeof (buf));
394 node->add_property (X_("goto_start"), buf);
395 goto_end_controllable.id().print (buf, sizeof (buf));
396 node->add_property (X_("goto_end"), buf);
397 auto_loop_controllable.id().print (buf, sizeof (buf));
398 node->add_property (X_("auto_loop"), buf);
399 play_selection_controllable.id().print (buf, sizeof (buf));
400 node->add_property (X_("play_selection"), buf);
401 rec_controllable.id().print (buf, sizeof (buf));
402 node->add_property (X_("rec"), buf);
403 shuttle_controllable.id().print (buf, sizeof (buf));
404 node->add_property (X_("shuttle"), buf);
410 ARDOUR_UI::save_ardour_state ()
412 if (!keyboard || !mixer || !editor) {
416 /* XXX this is all a bit dubious. add_extra_xml() uses
417 a different lifetime model from add_instant_xml().
420 XMLNode* node = new XMLNode (keyboard->get_state());
421 Config->add_extra_xml (*node);
422 Config->add_extra_xml (get_transport_controllable_state());
423 Config->save_state();
425 XMLNode enode(static_cast<Stateful*>(editor)->get_state());
426 XMLNode mnode(mixer->get_state());
429 session->add_instant_xml (enode, session->path());
430 session->add_instant_xml (mnode, session->path());
432 Config->add_instant_xml (enode, get_user_ardour_path());
433 Config->add_instant_xml (mnode, get_user_ardour_path());
440 ARDOUR_UI::startup ()
442 if (engine->is_realtime()) {
444 struct rlimit limits;
446 if (getrlimit (RLIMIT_MEMLOCK, &limits)) {
450 if (limits.rlim_cur != RLIM_INFINITY) {
451 MessageDialog msg (_("WARNING: Your system has a limit for maximum amount of locked memory. "
452 "This might cause Ardour to run out of memory before your system "
453 "runs out of memory. \n\n"
454 "You can view the memory limit with 'ulimit -l', "
455 "and it is normally controlled by /etc/security/limits.conf"));
457 editor->ensure_float (msg);
466 if (session && session->dirty()) {
467 switch (ask_about_saving_session(_("quit"))) {
472 /* use the default name */
473 if (save_state_canfail ("")) {
474 /* failed - don't quit */
475 MessageDialog msg (*editor,
477 Ardour was unable to save your session.\n\n\
478 If you still wish to quit, please use the\n\n\
479 \"Just quit\" option."));
490 session->set_deletion_in_progress ();
493 Config->save_state();
498 ARDOUR_UI::ask_about_saving_session (const string & what)
500 ArdourDialog window (_("ardour: save session?"));
501 Gtk::HBox dhbox; // the hbox for the image and text
502 Gtk::Label prompt_label;
503 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_WARNING, Gtk::ICON_SIZE_DIALOG));
507 msg = string_compose(_("Don't %1"), what);
508 window.add_button (msg, RESPONSE_REJECT);
509 msg = string_compose(_("Just %1"), what);
510 window.add_button (msg, RESPONSE_APPLY);
511 msg = string_compose(_("Save and %1"), what);
512 window.add_button (msg, RESPONSE_ACCEPT);
514 window.set_default_response (RESPONSE_ACCEPT);
516 Gtk::Button noquit_button (msg);
517 noquit_button.set_name ("EditorGTKButton");
522 if (session->snap_name() == session->name()) {
525 type = _("snapshot");
527 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?"),
528 type, session->snap_name());
530 prompt_label.set_text (prompt);
531 prompt_label.set_name (X_("PrompterLabel"));
532 prompt_label.set_alignment(ALIGN_LEFT, ALIGN_TOP);
534 dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP)
536 dhbox.set_homogeneous (false);
537 dhbox.pack_start (*dimage, false, false, 5);
538 dhbox.pack_start (prompt_label, true, false, 5);
539 window.get_vbox()->pack_start (dhbox);
541 window.set_name (_("Prompter"));
542 window.set_position (Gtk::WIN_POS_MOUSE);
543 window.set_modal (true);
544 window.set_resizable (false);
547 save_the_session = 0;
549 window.set_keep_above (true);
552 ResponseType r = (ResponseType) window.run();
557 case RESPONSE_ACCEPT: // save and get out of here
559 case RESPONSE_APPLY: // get out of here
569 ARDOUR_UI::every_second ()
572 update_buffer_load ();
573 update_disk_space ();
578 ARDOUR_UI::every_point_one_seconds ()
580 update_speed_display ();
581 RapidScreenUpdate(); /* EMIT_SIGNAL */
586 ARDOUR_UI::every_point_oh_five_seconds ()
588 MidRapidScreenUpdate(); /* EMIT_SIGNAL */
593 ARDOUR_UI::every_point_zero_one_seconds ()
595 SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
600 ARDOUR_UI::update_sample_rate (nframes_t ignored)
604 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
606 if (!engine->connected()) {
608 snprintf (buf, sizeof (buf), _("disconnected"));
612 nframes_t rate = engine->frame_rate();
614 if (fmod (rate, 1000.0) != 0.0) {
615 snprintf (buf, sizeof (buf), _("%.1f kHz / %4.1f msecs"),
616 (float) rate/1000.0f,
617 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
619 snprintf (buf, sizeof (buf), _("%u kHz / %4.1f msecs"),
621 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
625 sample_rate_label.set_text (buf);
629 ARDOUR_UI::update_cpu_load ()
632 snprintf (buf, sizeof (buf), _("DSP: %.1f%%"), engine->get_cpu_load());
633 cpu_load_label.set_text (buf);
637 ARDOUR_UI::update_buffer_load ()
642 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"),
643 session->playback_load(), session->capture_load());
644 buffer_load_label.set_text (buf);
646 buffer_load_label.set_text ("");
651 ARDOUR_UI::count_recenabled_streams (Route& route)
653 Track* track = dynamic_cast<Track*>(&route);
654 if (track && track->diskstream()->record_enabled()) {
655 rec_enabled_streams += track->n_inputs();
660 ARDOUR_UI::update_disk_space()
666 nframes_t frames = session->available_capture_duration();
669 if (frames == max_frames) {
670 strcpy (buf, _("Disk: 24hrs+"));
675 nframes_t fr = session->frame_rate();
677 rec_enabled_streams = 0;
678 session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
680 if (rec_enabled_streams) {
681 frames /= rec_enabled_streams;
684 hrs = frames / (fr * 3600);
685 frames -= hrs * fr * 3600;
686 mins = frames / (fr * 60);
687 frames -= mins * fr * 60;
690 snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs);
693 disk_space_label.set_text (buf);
697 ARDOUR_UI::update_wall_clock ()
704 tm_now = localtime (&now);
706 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
707 wall_clock_label.set_text (buf);
712 ARDOUR_UI::control_methods_adjusted ()
717 which_method = (int) online_control_button->adjustment.get_value();
718 switch (which_method) {
720 allow_mmc_and_local ();
729 fatal << _("programming error: impossible control method") << endmsg;
735 ARDOUR_UI::mmc_device_id_adjusted ()
740 int dev_id = (int) mmc_id_button->adjustment.get_value();
741 mmc->set_device_id (dev_id);
747 ARDOUR_UI::session_menu (GdkEventButton *ev)
749 session_popup_menu->popup (0, 0);
754 ARDOUR_UI::redisplay_recent_sessions ()
756 vector<string *> *sessions;
757 vector<string *>::iterator i;
758 RecentSessionsSorter cmp;
760 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
761 recent_session_model->clear ();
764 ARDOUR::read_recent_sessions (rs);
767 recent_session_display.set_model (recent_session_model);
771 /* sort them alphabetically */
772 sort (rs.begin(), rs.end(), cmp);
773 sessions = new vector<string*>;
775 for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
776 sessions->push_back (new string ((*i).second));
779 for (i = sessions->begin(); i != sessions->end(); ++i) {
781 vector<string*>* states;
782 vector<const gchar*> item;
783 string fullpath = *(*i);
785 /* remove any trailing / */
787 if (fullpath[fullpath.length()-1] == '/') {
788 fullpath = fullpath.substr (0, fullpath.length()-1);
791 /* now get available states for this session */
793 if ((states = Session::possible_states (fullpath)) == 0) {
798 TreeModel::Row row = *(recent_session_model->append());
800 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
801 row[recent_session_columns.fullpath] = fullpath;
803 if (states->size() > 1) {
805 /* add the children */
807 for (vector<string*>::iterator i2 = states->begin(); i2 != states->end(); ++i2) {
809 TreeModel::Row child_row = *(recent_session_model->append (row.children()));
811 child_row[recent_session_columns.visible_name] = **i2;
812 child_row[recent_session_columns.fullpath] = fullpath;
821 recent_session_display.set_model (recent_session_model);
826 ARDOUR_UI::build_session_selector ()
828 session_selector_window = new ArdourDialog ("session selector");
830 Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
832 session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
833 session_selector_window->add_button (Stock::OPEN, RESPONSE_ACCEPT);
834 session_selector_window->set_default_response (RESPONSE_ACCEPT);
835 recent_session_model = TreeStore::create (recent_session_columns);
836 recent_session_display.set_model (recent_session_model);
837 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
838 recent_session_display.set_headers_visible (false);
839 recent_session_display.get_selection()->set_mode (SELECTION_SINGLE);
841 recent_session_display.signal_row_activated().connect (mem_fun (*this, &ARDOUR_UI::recent_session_row_activated));
843 scroller->add (recent_session_display);
844 scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
846 session_selector_window->set_name ("SessionSelectorWindow");
847 session_selector_window->set_size_request (200, 400);
848 session_selector_window->get_vbox()->pack_start (*scroller);
849 session_selector_window->show_all_children();
853 ARDOUR_UI::recent_session_row_activated (const TreePath& path, TreeViewColumn* col)
855 session_selector_window->response (RESPONSE_ACCEPT);
859 ARDOUR_UI::open_recent_session ()
861 /* popup selector window */
863 if (session_selector_window == 0) {
864 build_session_selector ();
867 redisplay_recent_sessions ();
869 ResponseType r = (ResponseType) session_selector_window->run ();
871 session_selector_window->hide();
874 case RESPONSE_ACCEPT:
880 Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
882 if (i == recent_session_model->children().end()) {
886 Glib::ustring path = (*i)[recent_session_columns.fullpath];
887 Glib::ustring state = (*i)[recent_session_columns.visible_name];
889 _session_is_new = false;
891 load_session (path, state);
895 ARDOUR_UI::filter_ardour_session_dirs (const FileFilter::Info& info)
899 if (stat (info.filename.c_str(), &statbuf) != 0) {
903 if (!S_ISDIR(statbuf.st_mode)) {
909 string session_file = info.filename;
911 session_file += Glib::path_get_basename (info.filename);
912 session_file += ".ardour";
914 if (stat (session_file.c_str(), &statbuf) != 0) {
918 return S_ISREG (statbuf.st_mode);
922 ARDOUR_UI::open_session ()
924 /* popup selector window */
926 if (open_session_selector == 0) {
928 /* ardour sessions are folders */
930 open_session_selector = new Gtk::FileChooserDialog (_("open session"), FILE_CHOOSER_ACTION_OPEN);
931 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
932 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
934 FileFilter session_filter;
935 session_filter.add_pattern ("*.ardour");
936 session_filter.set_name (_("Ardour sessions"));
937 open_session_selector->add_filter (session_filter);
938 open_session_selector->set_filter (session_filter);
941 int response = open_session_selector->run();
942 open_session_selector->hide ();
945 case RESPONSE_ACCEPT:
948 open_session_selector->hide();
952 open_session_selector->hide();
953 string session_path = open_session_selector->get_filename();
957 if (session_path.length() > 0) {
958 if (Session::find_session (session_path, path, name, isnew) == 0) {
959 _session_is_new = isnew;
960 load_session (path, name);
967 ARDOUR_UI::session_add_midi_track ()
969 cerr << _("Patience is a virtue.\n");
973 ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, uint32_t how_many)
975 list<boost::shared_ptr<AudioTrack> > tracks;
976 Session::RouteList routes;
979 warning << _("You cannot add a track or bus without a session already loaded.") << endmsg;
985 tracks = session->new_audio_track (input_channels, output_channels, mode, how_many);
987 if (tracks.size() != how_many) {
989 error << _("could not create a new audio track") << endmsg;
991 error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
997 routes = session->new_audio_route (input_channels, output_channels, how_many);
999 if (routes.size() != how_many) {
1000 if (how_many == 1) {
1001 error << _("could not create a new audio track") << endmsg;
1003 error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
1009 if (need_control_room_outs) {
1015 route->set_stereo_control_outs (control_lr_channels);
1016 route->control_outs()->set_stereo_pan (pans, this);
1018 #endif /* CONTROLOUTS */
1022 MessageDialog msg (*editor,
1023 _("There are insufficient JACK ports available\n\
1024 to create a new track or bus.\n\
1025 You should save Ardour, exit and\n\
1026 restart JACK with more ports."));
1032 ARDOUR_UI::do_transport_locate (nframes_t new_position)
1034 nframes_t _preroll = 0;
1037 // XXX CONFIG_CHANGE FIX - requires AnyTime handling
1038 // _preroll = session->convert_to_frames_at (new_position, Config->get_preroll());
1040 if (new_position > _preroll) {
1041 new_position -= _preroll;
1046 session->request_locate (new_position);
1051 ARDOUR_UI::transport_goto_start ()
1054 session->goto_start();
1057 /* force displayed area in editor to start no matter
1058 what "follow playhead" setting is.
1062 editor->reset_x_origin (session->current_start_frame());
1068 ARDOUR_UI::transport_goto_zero ()
1071 session->request_locate (0);
1074 /* force displayed area in editor to start no matter
1075 what "follow playhead" setting is.
1079 editor->reset_x_origin (0);
1085 ARDOUR_UI::transport_goto_end ()
1088 nframes_t frame = session->current_end_frame();
1089 session->request_locate (frame);
1091 /* force displayed area in editor to start no matter
1092 what "follow playhead" setting is.
1096 editor->reset_x_origin (frame);
1102 ARDOUR_UI::transport_stop ()
1108 if (session->is_auditioning()) {
1109 session->cancel_audition ();
1113 if (session->get_play_loop ()) {
1114 session->request_play_loop (false);
1117 session->request_stop ();
1121 ARDOUR_UI::transport_stop_and_forget_capture ()
1124 session->request_stop (true);
1129 ARDOUR_UI::remove_last_capture()
1132 editor->remove_last_capture();
1137 ARDOUR_UI::transport_record ()
1139 cerr << "transport record\n";
1142 switch (session->record_status()) {
1143 case Session::Disabled:
1144 if (session->ntracks() == 0) {
1145 MessageDialog msg (*editor, _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu."));
1149 session->maybe_enable_record ();
1151 case Session::Recording:
1152 case Session::Enabled:
1153 session->disable_record (true);
1159 ARDOUR_UI::transport_roll ()
1167 rolling = session->transport_rolling ();
1169 if (session->get_play_loop()) {
1170 session->request_play_loop (false);
1171 auto_loop_button.set_visual_state (1);
1172 roll_button.set_visual_state (1);
1173 } else if (session->get_play_range ()) {
1174 session->request_play_range (false);
1175 play_selection_button.set_visual_state (0);
1176 } else if (rolling) {
1177 session->request_locate (session->last_transport_start(), true);
1180 session->request_transport_speed (1.0f);
1184 ARDOUR_UI::transport_loop()
1187 if (session->get_play_loop()) {
1188 if (session->transport_rolling()) {
1189 Location * looploc = session->locations()->auto_loop_location();
1191 session->request_locate (looploc->start(), true);
1196 session->request_play_loop (true);
1202 ARDOUR_UI::transport_play_selection ()
1208 if (!session->get_play_range()) {
1209 session->request_stop ();
1212 editor->play_selection ();
1216 ARDOUR_UI::transport_rewind (int option)
1218 float current_transport_speed;
1221 current_transport_speed = session->transport_speed();
1223 if (current_transport_speed >= 0.0f) {
1226 session->request_transport_speed (-1.0f);
1229 session->request_transport_speed (-4.0f);
1232 session->request_transport_speed (-0.5f);
1237 session->request_transport_speed (current_transport_speed * 1.5f);
1243 ARDOUR_UI::transport_forward (int option)
1245 float current_transport_speed;
1248 current_transport_speed = session->transport_speed();
1250 if (current_transport_speed <= 0.0f) {
1253 session->request_transport_speed (1.0f);
1256 session->request_transport_speed (4.0f);
1259 session->request_transport_speed (0.5f);
1264 session->request_transport_speed (current_transport_speed * 1.5f);
1270 ARDOUR_UI::toggle_record_enable (uint32_t dstream)
1276 boost::shared_ptr<Route> r;
1278 if ((r = session->route_by_remote_id (dstream)) != 0) {
1282 if ((t = dynamic_cast<Track*>(r.get())) != 0) {
1283 t->diskstream()->set_record_enabled (!t->diskstream()->record_enabled());
1292 ARDOUR_UI::queue_transport_change ()
1294 Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
1298 ARDOUR_UI::map_transport_state ()
1300 float sp = session->transport_speed();
1303 transport_rolling ();
1304 } else if (sp < 0.0f) {
1305 transport_rewinding ();
1306 } else if (sp > 0.0f) {
1307 transport_forwarding ();
1309 transport_stopped ();
1314 ARDOUR_UI::allow_local_only ()
1320 ARDOUR_UI::allow_mmc_only ()
1326 ARDOUR_UI::allow_mmc_and_local ()
1332 ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg)
1334 snprintf (buf, sizeof(buf), "%s", ((GlobalClickBox *) arg)->strings[
1335 (int) adj.get_value()].c_str());
1339 ARDOUR_UI::engine_stopped ()
1341 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
1342 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1343 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1347 ARDOUR_UI::engine_running ()
1349 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
1350 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true);
1351 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
1353 Glib::RefPtr<Action> action;
1354 char* action_name = 0;
1356 switch (engine->frames_per_cycle()) {
1358 action_name = X_("JACKLatency32");
1361 action_name = X_("JACKLatency64");
1364 action_name = X_("JACKLatency128");
1367 action_name = X_("JACKLatency512");
1370 action_name = X_("JACKLatency1024");
1373 action_name = X_("JACKLatency2048");
1376 action_name = X_("JACKLatency4096");
1379 action_name = X_("JACKLatency8192");
1382 /* XXX can we do anything useful ? */
1388 action = ActionManager::get_action (X_("JACK"), action_name);
1391 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic (action);
1392 ract->set_active ();
1398 ARDOUR_UI::engine_halted ()
1400 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
1402 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1403 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1405 update_sample_rate (0);
1407 MessageDialog msg (*editor,
1409 JACK has either been shutdown or it\n\
1410 disconnected Ardour because Ardour\n\
1411 was not fast enough. You can save the\n\
1412 session and/or try to reconnect to JACK ."));
1417 ARDOUR_UI::do_engine_start ()
1425 error << _("Unable to start the session running")
1435 ARDOUR_UI::start_engine ()
1437 if (do_engine_start () == 0) {
1438 if (session && _session_is_new) {
1439 /* we need to retain initial visual
1440 settings for a new session
1442 session->save_state ("");
1450 ARDOUR_UI::update_clocks ()
1452 if (!editor || !editor->dragging_playhead()) {
1453 Clock (session->audible_frame()); /* EMIT_SIGNAL */
1458 ARDOUR_UI::start_clocking ()
1460 clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
1464 ARDOUR_UI::stop_clocking ()
1466 clock_signal_connection.disconnect ();
1470 ARDOUR_UI::toggle_clocking ()
1473 if (clock_button.get_active()) {
1482 ARDOUR_UI::_blink (void *arg)
1485 ((ARDOUR_UI *) arg)->blink ();
1492 // Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
1496 ARDOUR_UI::start_blinking ()
1498 /* Start the blink signal. Everybody with a blinking widget
1499 uses Blink to drive the widget's state.
1502 if (blink_timeout_tag < 0) {
1504 blink_timeout_tag = g_timeout_add (240, _blink, this);
1509 ARDOUR_UI::stop_blinking ()
1511 if (blink_timeout_tag >= 0) {
1512 g_source_remove (blink_timeout_tag);
1513 blink_timeout_tag = -1;
1518 ARDOUR_UI::name_io_setup (AudioEngine& engine,
1524 if (io.n_inputs() == 0) {
1529 /* XXX we're not handling multiple ports yet. */
1531 const char **connections = io.input(0)->get_connections();
1533 if (connections == 0 || connections[0] == '\0') {
1536 buf = connections[0];
1543 if (io.n_outputs() == 0) {
1548 /* XXX we're not handling multiple ports yet. */
1550 const char **connections = io.output(0)->get_connections();
1552 if (connections == 0 || connections[0] == '\0') {
1555 buf = connections[0];
1563 ARDOUR_UI::snapshot_session ()
1565 ArdourPrompter prompter (true);
1569 struct tm local_time;
1572 localtime_r (&n, &local_time);
1573 strftime (timebuf, sizeof(timebuf), "%FT%T", &local_time);
1575 prompter.set_name ("Prompter");
1576 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1577 prompter.set_prompt (_("Name of New Snapshot"));
1578 prompter.set_initial_text (timebuf);
1580 switch (prompter.run()) {
1581 case RESPONSE_ACCEPT:
1582 prompter.get_result (snapname);
1583 if (snapname.length()){
1584 save_state (snapname);
1594 ARDOUR_UI::save_state (const string & name)
1596 (void) save_state_canfail (name);
1600 ARDOUR_UI::save_state_canfail (string name)
1605 if (name.length() == 0) {
1606 name = session->snap_name();
1609 if ((ret = session->save_state (name)) != 0) {
1613 save_ardour_state (); /* XXX cannot fail? yeah, right ... */
1618 ARDOUR_UI::restore_state (string name)
1621 if (name.length() == 0) {
1622 name = session->name();
1624 session->restore_state (name);
1629 ARDOUR_UI::primary_clock_value_changed ()
1632 session->request_locate (primary_clock.current_time ());
1637 ARDOUR_UI::secondary_clock_value_changed ()
1640 session->request_locate (secondary_clock.current_time ());
1645 ARDOUR_UI::rec_enable_button_blink (bool onoff, AudioDiskstream *dstream, Widget *w)
1647 if (session && dstream && dstream->record_enabled()) {
1649 Session::RecordState rs;
1651 rs = session->record_status ();
1654 case Session::Disabled:
1655 case Session::Enabled:
1656 if (w->get_state() != STATE_SELECTED) {
1657 w->set_state (STATE_SELECTED);
1661 case Session::Recording:
1662 if (w->get_state() != STATE_ACTIVE) {
1663 w->set_state (STATE_ACTIVE);
1669 if (w->get_state() != STATE_NORMAL) {
1670 w->set_state (STATE_NORMAL);
1676 ARDOUR_UI::transport_rec_enable_blink (bool onoff)
1682 switch (session->record_status()) {
1683 case Session::Enabled:
1685 rec_button.set_visual_state (2);
1687 rec_button.set_visual_state (0);
1691 case Session::Recording:
1692 rec_button.set_visual_state (1);
1696 rec_button.set_visual_state (0);
1702 ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
1710 ARDOUR_UI::save_template ()
1713 ArdourPrompter prompter (true);
1716 prompter.set_name (X_("Prompter"));
1717 prompter.set_prompt (_("Name for mix template:"));
1718 prompter.set_initial_text(session->name() + _("-template"));
1719 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1721 switch (prompter.run()) {
1722 case RESPONSE_ACCEPT:
1723 prompter.get_result (name);
1725 if (name.length()) {
1726 session->save_template (name);
1736 ARDOUR_UI::new_session (std::string predetermined_path)
1738 string session_name;
1739 string session_path;
1741 int response = Gtk::RESPONSE_NONE;
1743 new_session_dialog->set_modal(true);
1744 new_session_dialog->set_name (predetermined_path);
1745 new_session_dialog->reset_recent();
1746 new_session_dialog->show();
1749 response = new_session_dialog->run ();
1751 _session_is_new = false;
1753 if (response == Gtk::RESPONSE_CANCEL || response == Gtk::RESPONSE_DELETE_EVENT) {
1758 new_session_dialog->hide ();
1761 } else if (response == Gtk::RESPONSE_NONE) {
1763 /* Clear was pressed */
1764 new_session_dialog->reset();
1766 } else if (response == Gtk::RESPONSE_YES) {
1768 /* YES == OPEN, but there's no enum for that */
1770 session_name = new_session_dialog->session_name();
1772 if (session_name.empty()) {
1773 response = Gtk::RESPONSE_NONE;
1777 if (session_name[0] == '/' ||
1778 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1779 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1780 load_session (Glib::path_get_dirname (session_name), session_name);
1782 session_path = new_session_dialog->session_folder();
1783 load_session (session_path, session_name);
1786 } else if (response == Gtk::RESPONSE_OK) {
1788 session_name = new_session_dialog->session_name();
1790 if (new_session_dialog->get_current_page() == 1) {
1792 /* XXX this is a bit of a hack..
1793 i really want the new sesion dialog to return RESPONSE_YES
1794 if we're on page 1 (the load page)
1795 Unfortunately i can't see how atm..
1798 if (session_name.empty()) {
1799 response = Gtk::RESPONSE_NONE;
1803 if (session_name[0] == '/' ||
1804 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1805 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1806 load_session (Glib::path_get_dirname (session_name), session_name);
1808 session_path = new_session_dialog->session_folder();
1809 load_session (session_path, session_name);
1814 if (session_name.empty()) {
1815 response = Gtk::RESPONSE_NONE;
1819 if (session_name[0] == '/' ||
1820 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1821 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1823 session_path = Glib::path_get_dirname (session_name);
1824 session_name = Glib::path_get_basename (session_name);
1828 session_path = new_session_dialog->session_folder();
1832 //XXX This is needed because session constructor wants a
1833 //non-existant path. hopefully this will be fixed at some point.
1835 session_path = Glib::build_filename (session_path, session_name);
1837 if (g_file_test (session_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
1839 Glib::ustring str = string_compose (_("This session\n%1\nalready exists. Do you want to open it?"), session_path);
1841 MessageDialog msg (str,
1843 Gtk::MESSAGE_WARNING,
1844 Gtk::BUTTONS_YES_NO,
1848 msg.set_name (X_("CleanupDialog"));
1849 msg.set_wmclass (X_("existing_session"), "Ardour");
1850 msg.set_position (Gtk::WIN_POS_MOUSE);
1852 switch (msg.run()) {
1854 load_session (session_path, session_name);
1858 response = RESPONSE_NONE;
1859 new_session_dialog->reset ();
1864 _session_is_new = true;
1866 std::string template_name = new_session_dialog->session_template_name();
1868 if (new_session_dialog->use_session_template()) {
1870 load_session (session_path, session_name, &template_name);
1876 AutoConnectOption iconnect;
1877 AutoConnectOption oconnect;
1879 if (new_session_dialog->create_control_bus()) {
1880 cchns = (uint32_t) new_session_dialog->control_channel_count();
1885 if (new_session_dialog->create_master_bus()) {
1886 mchns = (uint32_t) new_session_dialog->master_channel_count();
1891 if (new_session_dialog->connect_inputs()) {
1892 iconnect = AutoConnectPhysical;
1894 iconnect = AutoConnectOption (0);
1897 /// @todo some minor tweaks.
1899 if (new_session_dialog->connect_outs_to_master()) {
1900 oconnect = AutoConnectMaster;
1901 } else if (new_session_dialog->connect_outs_to_physical()) {
1902 oconnect = AutoConnectPhysical;
1904 oconnect = AutoConnectOption (0);
1907 uint32_t nphysin = (uint32_t) new_session_dialog->input_limit_count();
1908 uint32_t nphysout = (uint32_t) new_session_dialog->output_limit_count();
1910 build_session (session_path,
1918 engine->frame_rate() * 60 * 5);
1923 } while (response == Gtk::RESPONSE_NONE);
1927 new_session_dialog->get_window()->set_cursor();
1928 new_session_dialog->hide();
1932 ARDOUR_UI::close_session()
1939 ARDOUR_UI::load_session (const string & path, const string & snap_name, string* mix_template)
1941 Session *new_session;
1943 session_loaded = false;
1945 x = unload_session ();
1953 /* if it already exists, we must have write access */
1955 if (::access (path.c_str(), F_OK) == 0 && ::access (path.c_str(), W_OK)) {
1956 MessageDialog msg (*editor, _("You do not have write access to this session.\n"
1957 "This prevents the session from being loaded."));
1963 new_session = new Session (*engine, path, snap_name, mix_template);
1968 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
1972 connect_to_session (new_session);
1974 Config->set_current_owner (ConfigVariableBase::Interface);
1976 session_loaded = true;
1978 goto_editor_window ();
1981 session->set_clean ();
1988 ARDOUR_UI::build_session (const string & path, const string & snap_name,
1989 uint32_t control_channels,
1990 uint32_t master_channels,
1991 AutoConnectOption input_connect,
1992 AutoConnectOption output_connect,
1995 nframes_t initial_length)
1997 Session *new_session;
2000 session_loaded = false;
2001 x = unload_session ();
2008 _session_is_new = true;
2011 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
2012 control_channels, master_channels, nphysin, nphysout, initial_length);
2017 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
2021 connect_to_session (new_session);
2023 session_loaded = true;
2031 editor->show_window ();
2042 ARDOUR_UI::show_splash ()
2045 about = new About();
2046 about->signal_response().connect(mem_fun (*this, &ARDOUR_UI::about_signal_response) );
2053 ARDOUR_UI::about_signal_response(int response)
2059 ARDOUR_UI::hide_splash ()
2062 about->get_window()->set_cursor ();
2068 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title, const string & msg)
2072 removed = rep.paths.size();
2075 MessageDialog msgd (*editor,
2076 _("No audio files were ready for cleanup"),
2079 (Gtk::ButtonsType)(Gtk::BUTTONS_OK) );
2080 msgd.set_secondary_text (_("If this seems suprising, \n\
2081 check for any existing snapshots.\n\
2082 These may still include regions that\n\
2083 require some unused files to continue to exist."));
2089 ArdourDialog results (_("ardour: cleanup"), true, false);
2091 struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
2092 CleanupResultsModelColumns() {
2096 Gtk::TreeModelColumn<Glib::ustring> visible_name;
2097 Gtk::TreeModelColumn<Glib::ustring> fullpath;
2101 CleanupResultsModelColumns results_columns;
2102 Glib::RefPtr<Gtk::ListStore> results_model;
2103 Gtk::TreeView results_display;
2105 results_model = ListStore::create (results_columns);
2106 results_display.set_model (results_model);
2107 results_display.append_column (list_title, results_columns.visible_name);
2109 results_display.set_name ("CleanupResultsList");
2110 results_display.set_headers_visible (true);
2111 results_display.set_headers_clickable (false);
2112 results_display.set_reorderable (false);
2114 Gtk::ScrolledWindow list_scroller;
2117 Gtk::HBox dhbox; // the hbox for the image and text
2118 Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
2119 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO, Gtk::ICON_SIZE_DIALOG));
2121 dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
2123 if (rep.space < 1048576.0f) {
2125 txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2127 txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2131 txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2133 txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2137 dhbox.pack_start (*dimage, true, false, 5);
2138 dhbox.pack_start (txt, true, false, 5);
2140 for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2141 TreeModel::Row row = *(results_model->append());
2142 row[results_columns.visible_name] = *i;
2143 row[results_columns.fullpath] = *i;
2146 list_scroller.add (results_display);
2147 list_scroller.set_size_request (-1, 150);
2148 list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2150 dvbox.pack_start (dhbox, true, false, 5);
2151 dvbox.pack_start (list_scroller, true, false, 5);
2152 ddhbox.pack_start (dvbox, true, false, 5);
2154 results.get_vbox()->pack_start (ddhbox, true, false, 5);
2155 results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
2156 results.set_default_response (RESPONSE_CLOSE);
2157 results.set_position (Gtk::WIN_POS_MOUSE);
2158 results.show_all_children ();
2159 results.set_resizable (false);
2166 ARDOUR_UI::cleanup ()
2169 /* shouldn't happen: menu item is insensitive */
2174 MessageDialog checker (_("Are you sure you want to cleanup?"),
2176 Gtk::MESSAGE_QUESTION,
2177 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
2179 checker.set_secondary_text(_("Cleanup is a destructive operation.\n\
2180 ALL undo/redo information will be lost if you cleanup.\n\
2181 After cleanup, unused audio files will be moved to a \
2182 \"dead sounds\" location."));
2184 checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2185 checker.add_button (_("Clean Up"), RESPONSE_ACCEPT);
2186 checker.set_default_response (RESPONSE_CANCEL);
2188 checker.set_name (_("CleanupDialog"));
2189 checker.set_wmclass (X_("ardour_cleanup"), "Ardour");
2190 checker.set_position (Gtk::WIN_POS_MOUSE);
2192 switch (checker.run()) {
2193 case RESPONSE_ACCEPT:
2199 Session::cleanup_report rep;
2201 editor->prepare_for_cleanup ();
2203 /* do not allow flush until a session is reloaded */
2205 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
2207 act->set_sensitive (false);
2210 if (session->cleanup_sources (rep)) {
2215 display_cleanup_results (rep,
2218 The following %1 %2 not in use and \n\
2219 have been moved to:\n\
2221 Flushing the wastebasket will \n\
2222 release an additional\n\
2223 %4 %5bytes of disk space.\n"
2231 ARDOUR_UI::flush_trash ()
2234 /* shouldn't happen: menu item is insensitive */
2238 Session::cleanup_report rep;
2240 if (session->cleanup_trash_sources (rep)) {
2244 display_cleanup_results (rep,
2246 _("The following %1 %2 deleted from\n\
2248 releasing %4 %5bytes of disk space"));
2252 ARDOUR_UI::add_route ()
2260 if (add_route_dialog == 0) {
2261 add_route_dialog = new AddRouteDialog;
2262 editor->ensure_float (*add_route_dialog);
2265 if (add_route_dialog->is_visible()) {
2266 /* we're already doing this */
2270 ResponseType r = (ResponseType) add_route_dialog->run ();
2272 add_route_dialog->hide();
2275 case RESPONSE_ACCEPT:
2282 if ((count = add_route_dialog->count()) <= 0) {
2286 uint32_t input_chan = add_route_dialog->channels ();
2287 uint32_t output_chan;
2288 string name_template = add_route_dialog->name_template ();
2289 bool track = add_route_dialog->track ();
2291 AutoConnectOption oac = Config->get_output_auto_connect();
2293 if (oac & AutoConnectMaster) {
2294 output_chan = (session->master_out() ? session->master_out()->n_inputs() : input_chan);
2296 output_chan = input_chan;
2299 /* XXX do something with name template */
2302 session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), count);
2304 session_add_audio_bus (input_chan, output_chan, count);
2309 ARDOUR_UI::mixer_settings () const
2314 node = session->instant_xml(X_("Mixer"), session->path());
2316 node = Config->instant_xml(X_("Mixer"), get_user_ardour_path());
2320 node = new XMLNode (X_("Mixer"));
2327 ARDOUR_UI::editor_settings () const
2332 node = session->instant_xml(X_("Editor"), session->path());
2334 node = Config->instant_xml(X_("Editor"), get_user_ardour_path());
2338 node = new XMLNode (X_("Editor"));
2344 ARDOUR_UI::keyboard_settings () const
2348 node = Config->extra_xml(X_("Keyboard"));
2351 node = new XMLNode (X_("Keyboard"));
2357 ARDOUR_UI::halt_on_xrun_message ()
2359 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
2361 MessageDialog msg (*editor,
2362 _("Recording was stopped because your system could not keep up."));
2367 ARDOUR_UI::disk_overrun_handler ()
2369 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2371 if (!have_disk_overrun_displayed) {
2372 have_disk_overrun_displayed = true;
2373 MessageDialog msg (*editor, X_("diskrate dialog"), _("\
2374 The disk system on your computer\n\
2375 was not able to keep up with Ardour.\n\
2377 Specifically, it failed to write data to disk\n\
2378 quickly enough to keep up with recording.\n"));
2380 have_disk_overrun_displayed = false;
2385 ARDOUR_UI::disk_underrun_handler ()
2387 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2389 if (!have_disk_underrun_displayed) {
2390 have_disk_underrun_displayed = true;
2391 MessageDialog msg (*editor,
2392 (_("The disk system on your computer\n\
2393 was not able to keep up with Ardour.\n\
2395 Specifically, it failed to read data from disk\n\
2396 quickly enough to keep up with playback.\n")));
2398 have_disk_underrun_displayed = false;
2403 ARDOUR_UI::disk_underrun_message_gone ()
2405 have_disk_underrun_displayed = false;
2409 ARDOUR_UI::disk_overrun_message_gone ()
2411 have_disk_underrun_displayed = false;
2415 ARDOUR_UI::pending_state_dialog ()
2417 ArdourDialog dialog ("pending state dialog");
2419 This session appears to have been in\n\
2420 middle of recording when ardour or\n\
2421 the computer was shutdown.\n\
2423 Ardour can recover any captured audio for\n\
2424 you, or it can ignore it. Please decide\n\
2425 what you would like to do.\n"));
2427 dialog.get_vbox()->pack_start (message);
2428 dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
2429 dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
2431 dialog.set_position (WIN_POS_CENTER);
2434 switch (dialog.run ()) {
2435 case RESPONSE_ACCEPT:
2443 ARDOUR_UI::disconnect_from_jack ()
2446 if( engine->disconnect_from_jack ()) {
2447 MessageDialog msg (*editor, _("Could not disconnect from JACK"));
2451 update_sample_rate (0);
2456 ARDOUR_UI::reconnect_to_jack ()
2459 if (engine->reconnect_to_jack ()) {
2460 MessageDialog msg (*editor, _("Could not reconnect to JACK"));
2464 update_sample_rate (0);
2469 ARDOUR_UI::cmdline_new_session (string path)
2471 if (path[0] != '/') {
2472 char buf[PATH_MAX+1];
2475 getcwd (buf, sizeof (buf));
2484 _will_create_new_session_automatically = false; /* done it */
2485 return FALSE; /* don't call it again */
2489 ARDOUR_UI::use_config ()
2491 Glib::RefPtr<Action> act;
2493 switch (Config->get_native_file_data_format ()) {
2495 act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
2498 act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
2503 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2504 ract->set_active ();
2507 switch (Config->get_native_file_header_format ()) {
2509 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
2512 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
2515 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
2518 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
2521 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
2524 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatCAF"));
2527 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatAIFF"));
2532 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2533 ract->set_active ();
2536 XMLNode* node = Config->extra_xml (X_("TransportControllables"));
2538 set_transport_controllable_state (*node);
2543 ARDOUR_UI::update_transport_clocks (nframes_t pos)
2545 primary_clock.set (pos);
2546 secondary_clock.set (pos);
2548 if (big_clock_window) {
2549 big_clock.set (pos);
2554 ARDOUR_UI::record_state_changed ()
2556 ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::record_state_changed));
2558 if (!session || !big_clock_window) {
2559 /* why bother - the clock isn't visible */
2563 switch (session->record_status()) {
2564 case Session::Recording:
2565 big_clock.set_widget_name ("BigClockRecording");
2568 big_clock.set_widget_name ("BigClockNonRecording");
2574 ARDOUR_UI::set_keybindings_path (string path)
2576 keybindings_path = path;
2580 ARDOUR_UI::save_keybindings ()
2582 if (can_save_keybindings) {
2583 AccelMap::save (keybindings_path);
2588 ARDOUR_UI::first_idle ()
2590 can_save_keybindings = true;
2595 ARDOUR_UI::store_clock_modes ()
2597 XMLNode* node = new XMLNode(X_("ClockModes"));
2599 for (vector<AudioClock*>::iterator x = AudioClock::clocks.begin(); x != AudioClock::clocks.end(); ++x) {
2600 node->add_property ((*x)->name().c_str(), enum_2_string ((*x)->mode()));
2603 session->add_extra_xml (*node);
2604 session->set_dirty ();
2609 ARDOUR_UI::TransportControllable::TransportControllable (std::string name, ARDOUR_UI& u, ToggleType tp)
2610 : Controllable (name), ui (u), type(tp)
2616 ARDOUR_UI::TransportControllable::set_value (float val)
2618 if (type == ShuttleControl) {
2626 fract = -((63.0f - val)/63.0f);
2628 fract = ((val - 63.0f)/63.0f);
2632 ui.set_shuttle_fract (fract);
2637 /* do nothing: these are radio-style actions */
2645 action = X_("Roll");
2648 action = X_("Stop");
2651 action = X_("Goto Start");
2654 action = X_("Goto End");
2657 action = X_("Loop");
2660 action = X_("Play Selection");
2663 action = X_("Record");
2673 Glib::RefPtr<Action> act = ActionManager::get_action ("transport", action);
2681 ARDOUR_UI::TransportControllable::get_value (void) const
2700 case ShuttleControl:
2710 ARDOUR_UI::TransportControllable::set_id (const string& str)