2 Copyright (C) 1999-2007 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #define __STDC_FORMAT_MACROS 1
33 #include <sys/resource.h>
35 #include <gtkmm/messagedialog.h>
36 #include <gtkmm/accelmap.h>
38 #include <pbd/error.h>
39 #include <pbd/compose.h>
40 #include <pbd/pathscanner.h>
41 #include <pbd/failed_constructor.h>
42 #include <pbd/enumwriter.h>
43 #include <pbd/stacktrace.h>
44 #include <gtkmm2ext/gtk_ui.h>
45 #include <gtkmm2ext/utils.h>
46 #include <gtkmm2ext/click_box.h>
47 #include <gtkmm2ext/fastmeter.h>
48 #include <gtkmm2ext/stop_signal.h>
49 #include <gtkmm2ext/popup.h>
50 #include <gtkmm2ext/window_title.h>
52 #include <midi++/port.h>
53 #include <midi++/mmc.h>
55 #include <ardour/ardour.h>
56 #include <ardour/profile.h>
57 #include <ardour/session_route.h>
58 #include <ardour/port.h>
59 #include <ardour/audioengine.h>
60 #include <ardour/playlist.h>
61 #include <ardour/utils.h>
62 #include <ardour/audio_diskstream.h>
63 #include <ardour/audiofilesource.h>
64 #include <ardour/recent_sessions.h>
65 #include <ardour/port.h>
66 #include <ardour/audio_track.h>
67 #include <ardour/midi_track.h>
70 #include "ardour_ui.h"
71 #include "public_editor.h"
72 #include "audio_clock.h"
77 #include "add_route_dialog.h"
78 #include "new_session_dialog.h"
81 #include "gui_thread.h"
82 #include "color_manager.h"
86 using namespace ARDOUR;
88 using namespace Gtkmm2ext;
92 ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
94 sigc::signal<void,bool> ARDOUR_UI::Blink;
95 sigc::signal<void> ARDOUR_UI::RapidScreenUpdate;
96 sigc::signal<void> ARDOUR_UI::SuperRapidScreenUpdate;
97 sigc::signal<void,nframes_t, bool, nframes_t> ARDOUR_UI::Clock;
99 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
101 : Gtkmm2ext::UI (X_("Ardour"), argcp, argvp, rcfile),
103 primary_clock (X_("primary"), false, X_("TransportClockDisplay"), true, false, true),
104 secondary_clock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, false, true),
105 preroll_clock (X_("preroll"), false, X_("PreRollClock"), true, true),
106 postroll_clock (X_("postroll"), false, X_("PostRollClock"), true, true),
110 adjuster_table (3, 3),
114 preroll_button (_("pre\nroll")),
115 postroll_button (_("post\nroll")),
119 big_clock (X_("bigclock"), false, "BigClockNonRecording", false, false, true),
123 roll_controllable ("transport roll", *this, TransportControllable::Roll),
124 stop_controllable ("transport stop", *this, TransportControllable::Stop),
125 goto_start_controllable ("transport goto start", *this, TransportControllable::GotoStart),
126 goto_end_controllable ("transport goto end", *this, TransportControllable::GotoEnd),
127 auto_loop_controllable ("transport auto loop", *this, TransportControllable::AutoLoop),
128 play_selection_controllable ("transport play selection", *this, TransportControllable::PlaySelection),
129 rec_controllable ("transport rec-enable", *this, TransportControllable::RecordEnable),
130 shuttle_controllable ("shuttle", *this, TransportControllable::ShuttleControl),
131 shuttle_controller_binding_proxy (shuttle_controllable),
133 roll_button (roll_controllable),
134 stop_button (stop_controllable),
135 goto_start_button (goto_start_controllable),
136 goto_end_button (goto_end_controllable),
137 auto_loop_button (auto_loop_controllable),
138 play_selection_button (play_selection_controllable),
139 rec_button (rec_controllable),
141 shuttle_units_button (_("% ")),
143 punch_in_button (_("Punch In")),
144 punch_out_button (_("Punch Out")),
145 auto_return_button (_("Auto Return")),
146 auto_play_button (_("Auto Play")),
147 auto_input_button (_("Auto Input")),
148 click_button (_("Click")),
149 time_master_button (_("time\nmaster")),
151 auditioning_alert_button (_("AUDITION")),
152 solo_alert_button (_("SOLO")),
155 using namespace Gtk::Menu_Helpers;
161 if (theArdourUI == 0) {
167 color_manager = new ColorManager();
169 std::string color_file = ARDOUR::find_config_file("ardour.colors");
171 color_manager->load (color_file);
176 _session_is_new = false;
177 big_clock_window = 0;
178 session_selector_window = 0;
179 last_key_press_time = 0;
180 connection_editor = 0;
181 add_route_dialog = 0;
185 open_session_selector = 0;
186 have_configure_timeout = false;
187 have_disk_speed_dialog_displayed = false;
188 _will_create_new_session_automatically = false;
189 session_loaded = false;
190 last_speed_displayed = -1.0f;
191 keybindings_path = ARDOUR::find_config_file ("ardour.bindings");
193 can_save_keybindings = false;
195 last_configure_time.tv_sec = 0;
196 last_configure_time.tv_usec = 0;
198 shuttle_grabbed = false;
200 shuttle_max_speed = 8.0f;
202 shuttle_style_menu = 0;
203 shuttle_unit_menu = 0;
205 gettimeofday (&last_peak_grab, 0);
206 gettimeofday (&last_shuttle_request, 0);
208 ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
209 ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
211 /* handle pending state with a dialog */
213 ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
215 /* have to wait for AudioEngine and Configuration before proceeding */
219 ARDOUR_UI::set_engine (AudioEngine& e)
223 engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
224 engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
225 engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
226 engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
228 ActionManager::init ();
229 new_session_dialog = new NewSessionDialog();
233 keyboard = new Keyboard;
235 if (setup_windows ()) {
236 throw failed_constructor ();
239 if (GTK_ARDOUR::show_key_actions) {
240 vector<string> names;
241 vector<string> paths;
243 vector<AccelKey> bindings;
245 ActionManager::get_all_actions (names, paths, keys, bindings);
247 vector<string>::iterator n;
248 vector<string>::iterator k;
249 for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) {
250 cerr << "Action: " << (*n) << " bound to " << (*k) << endl;
256 /* start with timecode, metering enabled
259 blink_timeout_tag = -1;
261 /* the global configuration object is now valid */
265 /* this being a GUI and all, we want peakfiles */
267 AudioFileSource::set_build_peakfiles (true);
268 AudioFileSource::set_build_missing_peakfiles (true);
270 /* set default clock modes */
272 primary_clock.set_mode (AudioClock::SMPTE);
273 secondary_clock.set_mode (AudioClock::BBT);
275 /* start the time-of-day-clock */
277 update_wall_clock ();
278 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
280 update_disk_space ();
282 update_sample_rate (engine->frame_rate());
284 starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
285 stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
288 ARDOUR_UI::~ARDOUR_UI ()
290 save_ardour_state ();
304 if (add_route_dialog) {
305 delete add_route_dialog;
310 ARDOUR_UI::configure_timeout ()
315 if (last_configure_time.tv_sec == 0 && last_configure_time.tv_usec == 0) {
316 /* no configure events yet */
320 gettimeofday (&now, 0);
321 timersub (&now, &last_configure_time, &diff);
323 /* force a gap of 0.5 seconds since the last configure event
326 if (diff.tv_sec == 0 && diff.tv_usec < 500000) {
329 have_configure_timeout = false;
330 save_ardour_state ();
336 ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
338 if (have_configure_timeout) {
339 gettimeofday (&last_configure_time, 0);
341 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
342 have_configure_timeout = true;
349 ARDOUR_UI::set_transport_controllable_state (const XMLNode& node)
351 const XMLProperty* prop;
353 if ((prop = node.property ("roll")) != 0) {
354 roll_controllable.set_id (prop->value());
356 if ((prop = node.property ("stop")) != 0) {
357 stop_controllable.set_id (prop->value());
359 if ((prop = node.property ("goto_start")) != 0) {
360 goto_start_controllable.set_id (prop->value());
362 if ((prop = node.property ("goto_end")) != 0) {
363 goto_end_controllable.set_id (prop->value());
365 if ((prop = node.property ("auto_loop")) != 0) {
366 auto_loop_controllable.set_id (prop->value());
368 if ((prop = node.property ("play_selection")) != 0) {
369 play_selection_controllable.set_id (prop->value());
371 if ((prop = node.property ("rec")) != 0) {
372 rec_controllable.set_id (prop->value());
374 if ((prop = node.property ("shuttle")) != 0) {
375 shuttle_controllable.set_id (prop->value());
380 ARDOUR_UI::get_transport_controllable_state ()
382 XMLNode* node = new XMLNode(X_("TransportControllables"));
385 roll_controllable.id().print (buf, sizeof (buf));
386 node->add_property (X_("roll"), buf);
387 stop_controllable.id().print (buf, sizeof (buf));
388 node->add_property (X_("stop"), buf);
389 goto_start_controllable.id().print (buf, sizeof (buf));
390 node->add_property (X_("goto_start"), buf);
391 goto_end_controllable.id().print (buf, sizeof (buf));
392 node->add_property (X_("goto_end"), buf);
393 auto_loop_controllable.id().print (buf, sizeof (buf));
394 node->add_property (X_("auto_loop"), buf);
395 play_selection_controllable.id().print (buf, sizeof (buf));
396 node->add_property (X_("play_selection"), buf);
397 rec_controllable.id().print (buf, sizeof (buf));
398 node->add_property (X_("rec"), buf);
399 shuttle_controllable.id().print (buf, sizeof (buf));
400 node->add_property (X_("shuttle"), buf);
406 ARDOUR_UI::save_ardour_state ()
408 if (!keyboard || !mixer || !editor) {
412 /* XXX this is all a bit dubious. add_extra_xml() uses
413 a different lifetime model from add_instant_xml().
416 XMLNode* node = new XMLNode (keyboard->get_state());
417 Config->add_extra_xml (*node);
418 Config->add_extra_xml (get_transport_controllable_state());
419 Config->save_state();
421 XMLNode enode(static_cast<Stateful*>(editor)->get_state());
422 XMLNode mnode(mixer->get_state());
425 session->add_instant_xml (enode, session->path());
426 session->add_instant_xml (mnode, session->path());
428 Config->add_instant_xml (enode, get_user_ardour_path());
429 Config->add_instant_xml (mnode, get_user_ardour_path());
436 ARDOUR_UI::autosave_session ()
438 if (!Config->get_periodic_safety_backups())
442 session->maybe_write_autosave();
449 ARDOUR_UI::update_autosave ()
451 ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::update_autosave));
453 if (session->dirty()) {
454 if (_autosave_connection.connected()) {
455 _autosave_connection.disconnect();
458 _autosave_connection = Glib::signal_timeout().connect (mem_fun (*this, &ARDOUR_UI::autosave_session),
459 Config->get_periodic_safety_backup_interval() * 1000);
462 if (_autosave_connection.connected()) {
463 _autosave_connection.disconnect();
469 ARDOUR_UI::startup ()
471 check_memory_locking();
475 ARDOUR_UI::no_memory_warning ()
477 XMLNode node (X_("no-memory-warning"));
478 Config->add_instant_xml (node, get_user_ardour_path());
482 ARDOUR_UI::check_memory_locking ()
485 /* OS X doesn't support mlockall(2), and so testing for memory locking capability there is pointless */
489 XMLNode* memory_warning_node = Config->instant_xml (X_("no-memory-warning"), get_user_ardour_path());
491 if (engine->is_realtime() && memory_warning_node == 0) {
493 struct rlimit limits;
495 long pages, page_size;
497 if ((page_size = sysconf (_SC_PAGESIZE)) < 0 ||(pages = sysconf (_SC_PHYS_PAGES)) < 0) {
500 ram = (int64_t) pages * (int64_t) page_size;
503 if (getrlimit (RLIMIT_MEMLOCK, &limits)) {
507 if (limits.rlim_cur != RLIM_INFINITY) {
509 if (ram == 0 || ((double) limits.rlim_cur / ram) < 0.75) {
512 MessageDialog msg (_("WARNING: Your system has a limit for maximum amount of locked memory. "
513 "This might cause Ardour to run out of memory before your system "
514 "runs out of memory. \n\n"
515 "You can view the memory limit with 'ulimit -l', "
516 "and it is normally controlled by /etc/security/limits.conf"));
518 VBox* vbox = msg.get_vbox();
520 CheckButton cb (_("Do not show this window again"));
522 cb.signal_toggled().connect (mem_fun (*this, &ARDOUR_UI::no_memory_warning));
524 hbox.pack_start (cb, true, false);
525 vbox->pack_start (hbox);
528 editor->ensure_float (msg);
540 if (session && session->dirty()) {
541 switch (ask_about_saving_session(_("quit"))) {
546 /* use the default name */
547 if (save_state_canfail ("")) {
548 /* failed - don't quit */
549 MessageDialog msg (*editor,
551 Ardour was unable to save your session.\n\n\
552 If you still wish to quit, please use the\n\n\
553 \"Just quit\" option."));
564 session->set_deletion_in_progress ();
567 Config->save_state();
572 ARDOUR_UI::ask_about_saving_session (const string & what)
574 ArdourDialog window (_("ardour: save session?"));
575 Gtk::HBox dhbox; // the hbox for the image and text
576 Gtk::Label prompt_label;
577 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_WARNING, Gtk::ICON_SIZE_DIALOG));
581 msg = string_compose(_("Don't %1"), what);
582 window.add_button (msg, RESPONSE_REJECT);
583 msg = string_compose(_("Just %1"), what);
584 window.add_button (msg, RESPONSE_APPLY);
585 msg = string_compose(_("Save and %1"), what);
586 window.add_button (msg, RESPONSE_ACCEPT);
588 window.set_default_response (RESPONSE_ACCEPT);
590 Gtk::Button noquit_button (msg);
591 noquit_button.set_name ("EditorGTKButton");
596 if (session->snap_name() == session->name()) {
599 type = _("snapshot");
601 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?"),
602 type, session->snap_name());
604 prompt_label.set_text (prompt);
605 prompt_label.set_name (X_("PrompterLabel"));
606 prompt_label.set_alignment(ALIGN_LEFT, ALIGN_TOP);
608 dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP)
610 dhbox.set_homogeneous (false);
611 dhbox.pack_start (*dimage, false, false, 5);
612 dhbox.pack_start (prompt_label, true, false, 5);
613 window.get_vbox()->pack_start (dhbox);
615 window.set_name (_("Prompter"));
616 window.set_position (Gtk::WIN_POS_MOUSE);
617 window.set_modal (true);
618 window.set_resizable (false);
621 save_the_session = 0;
623 window.set_keep_above (true);
626 ResponseType r = (ResponseType) window.run();
631 case RESPONSE_ACCEPT: // save and get out of here
633 case RESPONSE_APPLY: // get out of here
643 ARDOUR_UI::every_second ()
646 update_buffer_load ();
647 update_disk_space ();
652 ARDOUR_UI::every_point_one_seconds ()
654 update_speed_display ();
655 RapidScreenUpdate(); /* EMIT_SIGNAL */
660 ARDOUR_UI::every_point_zero_one_seconds ()
662 SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
667 ARDOUR_UI::update_sample_rate (nframes_t ignored)
671 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
673 if (!engine->connected()) {
675 snprintf (buf, sizeof (buf), _("disconnected"));
679 nframes_t rate = engine->frame_rate();
681 if (fmod (rate, 1000.0) != 0.0) {
682 snprintf (buf, sizeof (buf), _("%.1f kHz / %4.1f ms"),
683 (float) rate/1000.0f,
684 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
686 snprintf (buf, sizeof (buf), _("%u kHz / %4.1f ms"),
688 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
692 sample_rate_label.set_text (buf);
696 ARDOUR_UI::update_cpu_load ()
699 snprintf (buf, sizeof (buf), _("DSP: %5.1f%%"), engine->get_cpu_load());
700 cpu_load_label.set_text (buf);
704 ARDOUR_UI::update_buffer_load ()
709 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"),
710 session->playback_load(), session->capture_load());
711 buffer_load_label.set_text (buf);
713 buffer_load_label.set_text ("");
718 ARDOUR_UI::count_recenabled_streams (Route& route)
720 Track* track = dynamic_cast<Track*>(&route);
721 if (track && track->diskstream()->record_enabled()) {
722 rec_enabled_streams += track->n_inputs().get_total();
727 ARDOUR_UI::update_disk_space()
733 nframes_t frames = session->available_capture_duration();
736 if (frames == max_frames) {
737 strcpy (buf, _("Disk: 24hrs+"));
742 nframes_t fr = session->frame_rate();
744 rec_enabled_streams = 0;
745 session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
747 if (rec_enabled_streams) {
748 frames /= rec_enabled_streams;
751 hrs = frames / (fr * 3600);
752 frames -= hrs * fr * 3600;
753 mins = frames / (fr * 60);
754 frames -= mins * fr * 60;
757 snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs);
760 disk_space_label.set_text (buf);
764 ARDOUR_UI::update_wall_clock ()
771 tm_now = localtime (&now);
773 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
774 wall_clock_label.set_text (buf);
780 ARDOUR_UI::session_menu (GdkEventButton *ev)
782 session_popup_menu->popup (0, 0);
787 ARDOUR_UI::redisplay_recent_sessions ()
789 vector<string *> *sessions;
790 vector<string *>::iterator i;
791 RecentSessionsSorter cmp;
793 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
794 recent_session_model->clear ();
797 ARDOUR::read_recent_sessions (rs);
800 recent_session_display.set_model (recent_session_model);
804 /* sort them alphabetically */
805 sort (rs.begin(), rs.end(), cmp);
806 sessions = new vector<string*>;
808 for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
809 sessions->push_back (new string ((*i).second));
812 for (i = sessions->begin(); i != sessions->end(); ++i) {
814 vector<string*>* states;
815 vector<const gchar*> item;
816 string fullpath = *(*i);
818 /* remove any trailing / */
820 if (fullpath[fullpath.length()-1] == '/') {
821 fullpath = fullpath.substr (0, fullpath.length()-1);
824 /* now get available states for this session */
826 if ((states = Session::possible_states (fullpath)) == 0) {
831 TreeModel::Row row = *(recent_session_model->append());
833 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
834 row[recent_session_columns.fullpath] = fullpath;
836 if (states->size() > 1) {
838 /* add the children */
840 for (vector<string*>::iterator i2 = states->begin(); i2 != states->end(); ++i2) {
842 TreeModel::Row child_row = *(recent_session_model->append (row.children()));
844 child_row[recent_session_columns.visible_name] = **i2;
845 child_row[recent_session_columns.fullpath] = fullpath;
854 recent_session_display.set_model (recent_session_model);
859 ARDOUR_UI::build_session_selector ()
861 session_selector_window = new ArdourDialog ("session selector");
863 Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
865 session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
866 session_selector_window->add_button (Stock::OPEN, RESPONSE_ACCEPT);
867 session_selector_window->set_default_response (RESPONSE_ACCEPT);
868 recent_session_model = TreeStore::create (recent_session_columns);
869 recent_session_display.set_model (recent_session_model);
870 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
871 recent_session_display.set_headers_visible (false);
872 recent_session_display.get_selection()->set_mode (SELECTION_SINGLE);
874 recent_session_display.signal_row_activated().connect (mem_fun (*this, &ARDOUR_UI::recent_session_row_activated));
876 scroller->add (recent_session_display);
877 scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
879 session_selector_window->set_name ("SessionSelectorWindow");
880 session_selector_window->set_size_request (200, 400);
881 session_selector_window->get_vbox()->pack_start (*scroller);
882 session_selector_window->show_all_children();
886 ARDOUR_UI::recent_session_row_activated (const TreePath& path, TreeViewColumn* col)
888 session_selector_window->response (RESPONSE_ACCEPT);
892 ARDOUR_UI::open_recent_session ()
894 /* popup selector window */
896 if (session_selector_window == 0) {
897 build_session_selector ();
900 redisplay_recent_sessions ();
902 ResponseType r = (ResponseType) session_selector_window->run ();
904 session_selector_window->hide();
907 case RESPONSE_ACCEPT:
913 Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
915 if (i == recent_session_model->children().end()) {
919 Glib::ustring path = (*i)[recent_session_columns.fullpath];
920 Glib::ustring state = (*i)[recent_session_columns.visible_name];
922 _session_is_new = false;
924 load_session (path, state);
928 ARDOUR_UI::filter_ardour_session_dirs (const FileFilter::Info& info)
932 if (stat (info.filename.c_str(), &statbuf) != 0) {
936 if (!S_ISDIR(statbuf.st_mode)) {
942 string session_file = info.filename;
944 session_file += Glib::path_get_basename (info.filename);
945 session_file += ".ardour";
947 if (stat (session_file.c_str(), &statbuf) != 0) {
951 return S_ISREG (statbuf.st_mode);
955 ARDOUR_UI::check_audioengine ()
958 if (!engine->connected()) {
959 MessageDialog msg (_("Ardour is not connected to JACK\n"
960 "You cannot open or close sessions in this condition"));
971 ARDOUR_UI::open_session ()
973 if (!check_audioengine()) {
978 /* popup selector window */
980 if (open_session_selector == 0) {
982 /* ardour sessions are folders */
984 open_session_selector = new Gtk::FileChooserDialog (_("open session"), FILE_CHOOSER_ACTION_OPEN);
985 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
986 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
988 FileFilter session_filter;
989 session_filter.add_pattern ("*.ardour");
990 session_filter.set_name (_("Ardour sessions"));
991 open_session_selector->add_filter (session_filter);
992 open_session_selector->set_filter (session_filter);
995 int response = open_session_selector->run();
996 open_session_selector->hide ();
999 case RESPONSE_ACCEPT:
1002 open_session_selector->hide();
1006 open_session_selector->hide();
1007 string session_path = open_session_selector->get_filename();
1011 if (session_path.length() > 0) {
1012 if (Session::find_session (session_path, path, name, isnew) == 0) {
1013 _session_is_new = isnew;
1014 load_session (path, name);
1021 ARDOUR_UI::session_add_midi_route (bool disk, uint32_t how_many)
1023 list<boost::shared_ptr<MidiTrack> > tracks;
1026 warning << _("You cannot add a track without a session already loaded.") << endmsg;
1033 tracks = session->new_midi_track (ARDOUR::Normal, how_many);
1035 if (tracks.size() != how_many) {
1036 if (how_many == 1) {
1037 error << _("could not create a new midi track") << endmsg;
1039 error << string_compose (_("could not create %1 new midi tracks"), how_many) << endmsg;
1043 if ((route = session->new_midi_route ()) == 0) {
1044 error << _("could not create new midi bus") << endmsg;
1050 MessageDialog msg (*editor,
1051 _("There are insufficient JACK ports available\n\
1052 to create a new track or bus.\n\
1053 You should save Ardour, exit and\n\
1054 restart JACK with more ports."));
1061 ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, uint32_t how_many)
1063 list<boost::shared_ptr<AudioTrack> > tracks;
1064 Session::RouteList routes;
1067 warning << _("You cannot add a track or bus without a session already loaded.") << endmsg;
1073 tracks = session->new_audio_track (input_channels, output_channels, mode, how_many);
1075 if (tracks.size() != how_many) {
1076 if (how_many == 1) {
1077 error << _("could not create a new audio track") << endmsg;
1079 error << string_compose (_("could only create %1 of %2 new audio %3"),
1080 tracks.size(), how_many, (track ? _("tracks") : _("busses"))) << endmsg;
1086 routes = session->new_audio_route (input_channels, output_channels, how_many);
1088 if (routes.size() != how_many) {
1089 if (how_many == 1) {
1090 error << _("could not create a new audio track") << endmsg;
1092 error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
1098 if (need_control_room_outs) {
1104 route->set_stereo_control_outs (control_lr_channels);
1105 route->control_outs()->set_stereo_pan (pans, this);
1107 #endif /* CONTROLOUTS */
1111 cerr << "About to complain about JACK\n";
1112 MessageDialog msg (*editor,
1113 _("There are insufficient JACK ports available\n\
1114 to create a new track or bus.\n\
1115 You should save Ardour, exit and\n\
1116 restart JACK with more ports."));
1122 ARDOUR_UI::do_transport_locate (nframes_t new_position)
1124 nframes_t _preroll = 0;
1127 // XXX CONFIG_CHANGE FIX - requires AnyTime handling
1128 // _preroll = session->convert_to_frames_at (new_position, Config->get_preroll());
1130 if (new_position > _preroll) {
1131 new_position -= _preroll;
1136 session->request_locate (new_position);
1141 ARDOUR_UI::transport_goto_start ()
1144 session->goto_start();
1147 /* force displayed area in editor to start no matter
1148 what "follow playhead" setting is.
1152 editor->reset_x_origin (session->current_start_frame());
1158 ARDOUR_UI::transport_goto_zero ()
1161 session->request_locate (0);
1164 /* force displayed area in editor to start no matter
1165 what "follow playhead" setting is.
1169 editor->reset_x_origin (0);
1175 ARDOUR_UI::transport_goto_end ()
1178 nframes_t frame = session->current_end_frame();
1179 session->request_locate (frame);
1181 /* force displayed area in editor to start no matter
1182 what "follow playhead" setting is.
1186 editor->reset_x_origin (frame);
1192 ARDOUR_UI::transport_stop ()
1198 if (session->is_auditioning()) {
1199 session->cancel_audition ();
1203 if (session->get_play_loop ()) {
1204 session->request_play_loop (false);
1207 session->request_stop ();
1211 ARDOUR_UI::transport_stop_and_forget_capture ()
1214 session->request_stop (true);
1219 ARDOUR_UI::remove_last_capture()
1222 editor->remove_last_capture();
1227 ARDOUR_UI::transport_record ()
1230 switch (session->record_status()) {
1231 case Session::Disabled:
1232 if (session->ntracks() == 0) {
1233 MessageDialog msg (*editor, _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu."));
1237 session->maybe_enable_record ();
1239 case Session::Recording:
1240 case Session::Enabled:
1241 session->disable_record (true);
1247 ARDOUR_UI::transport_roll ()
1255 rolling = session->transport_rolling ();
1257 if (session->get_play_loop()) {
1258 session->request_play_loop (false);
1259 auto_loop_button.set_visual_state (1);
1260 roll_button.set_visual_state (1);
1261 } else if (session->get_play_range ()) {
1262 session->request_play_range (false);
1263 play_selection_button.set_visual_state (0);
1264 } else if (rolling) {
1265 session->request_locate (session->last_transport_start(), true);
1268 session->request_transport_speed (1.0f);
1272 ARDOUR_UI::transport_loop()
1275 if (session->get_play_loop()) {
1276 if (session->transport_rolling()) {
1277 Location * looploc = session->locations()->auto_loop_location();
1279 session->request_locate (looploc->start(), true);
1284 session->request_play_loop (true);
1290 ARDOUR_UI::transport_play_selection ()
1296 if (!session->get_play_range()) {
1297 session->request_stop ();
1300 editor->play_selection ();
1304 ARDOUR_UI::transport_rewind (int option)
1306 float current_transport_speed;
1309 current_transport_speed = session->transport_speed();
1311 if (current_transport_speed >= 0.0f) {
1314 session->request_transport_speed (-1.0f);
1317 session->request_transport_speed (-4.0f);
1320 session->request_transport_speed (-0.5f);
1325 session->request_transport_speed (current_transport_speed * 1.5f);
1331 ARDOUR_UI::transport_forward (int option)
1333 float current_transport_speed;
1336 current_transport_speed = session->transport_speed();
1338 if (current_transport_speed <= 0.0f) {
1341 session->request_transport_speed (1.0f);
1344 session->request_transport_speed (4.0f);
1347 session->request_transport_speed (0.5f);
1352 session->request_transport_speed (current_transport_speed * 1.5f);
1358 ARDOUR_UI::toggle_record_enable (uint32_t dstream)
1364 boost::shared_ptr<Route> r;
1366 if ((r = session->route_by_remote_id (dstream)) != 0) {
1370 if ((t = dynamic_cast<Track*>(r.get())) != 0) {
1371 t->diskstream()->set_record_enabled (!t->diskstream()->record_enabled());
1380 ARDOUR_UI::queue_transport_change ()
1382 Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
1386 ARDOUR_UI::map_transport_state ()
1388 float sp = session->transport_speed();
1391 transport_rolling ();
1392 } else if (sp < 0.0f) {
1393 transport_rewinding ();
1394 } else if (sp > 0.0f) {
1395 transport_forwarding ();
1397 transport_stopped ();
1402 ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg)
1404 snprintf (buf, sizeof(buf), "%s", ((GlobalClickBox *) arg)->strings[
1405 (int) adj.get_value()].c_str());
1409 ARDOUR_UI::engine_stopped ()
1411 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
1412 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1413 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1417 ARDOUR_UI::engine_running ()
1419 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
1420 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true);
1421 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
1423 Glib::RefPtr<Action> action;
1424 char* action_name = 0;
1426 switch (engine->frames_per_cycle()) {
1428 action_name = X_("JACKLatency32");
1431 action_name = X_("JACKLatency64");
1434 action_name = X_("JACKLatency128");
1437 action_name = X_("JACKLatency512");
1440 action_name = X_("JACKLatency1024");
1443 action_name = X_("JACKLatency2048");
1446 action_name = X_("JACKLatency4096");
1449 action_name = X_("JACKLatency8192");
1452 /* XXX can we do anything useful ? */
1458 action = ActionManager::get_action (X_("JACK"), action_name);
1461 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic (action);
1462 ract->set_active ();
1468 ARDOUR_UI::engine_halted ()
1470 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
1472 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1473 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1475 update_sample_rate (0);
1477 MessageDialog msg (*editor,
1479 JACK has either been shutdown or it\n\
1480 disconnected Ardour because Ardour\n\
1481 was not fast enough. You can save the\n\
1482 session and/or try to reconnect to JACK ."));
1487 ARDOUR_UI::do_engine_start ()
1495 error << _("Unable to start the session running")
1505 ARDOUR_UI::start_engine ()
1507 if (do_engine_start () == 0) {
1508 if (session && _session_is_new) {
1509 /* we need to retain initial visual
1510 settings for a new session
1512 session->save_state ("");
1520 ARDOUR_UI::update_clocks ()
1522 if (!editor || !editor->dragging_playhead()) {
1523 Clock (session->audible_frame(), false, editor->edit_cursor_position(false)); /* EMIT_SIGNAL */
1528 ARDOUR_UI::start_clocking ()
1530 clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
1534 ARDOUR_UI::stop_clocking ()
1536 clock_signal_connection.disconnect ();
1540 ARDOUR_UI::toggle_clocking ()
1543 if (clock_button.get_active()) {
1552 ARDOUR_UI::_blink (void *arg)
1555 ((ARDOUR_UI *) arg)->blink ();
1562 Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
1566 ARDOUR_UI::start_blinking ()
1568 /* Start the blink signal. Everybody with a blinking widget
1569 uses Blink to drive the widget's state.
1572 if (blink_timeout_tag < 0) {
1574 blink_timeout_tag = g_timeout_add (240, _blink, this);
1579 ARDOUR_UI::stop_blinking ()
1581 if (blink_timeout_tag >= 0) {
1582 g_source_remove (blink_timeout_tag);
1583 blink_timeout_tag = -1;
1588 ARDOUR_UI::name_io_setup (AudioEngine& engine,
1594 if (io.n_inputs().get_total() == 0) {
1599 /* XXX we're not handling multiple ports yet. */
1601 const char **connections = io.input(0)->get_connections();
1603 if (connections == 0 || connections[0] == '\0') {
1606 buf = connections[0];
1613 if (io.n_outputs().get_total() == 0) {
1618 /* XXX we're not handling multiple ports yet. */
1620 const char **connections = io.output(0)->get_connections();
1622 if (connections == 0 || connections[0] == '\0') {
1625 buf = connections[0];
1632 /** Ask the user for the name of a new shapshot and then take it.
1635 ARDOUR_UI::snapshot_session ()
1637 ArdourPrompter prompter (true);
1641 struct tm local_time;
1644 localtime_r (&n, &local_time);
1645 strftime (timebuf, sizeof(timebuf), "%FT%T", &local_time);
1647 prompter.set_name ("Prompter");
1648 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1649 prompter.set_prompt (_("Name of New Snapshot"));
1650 prompter.set_initial_text (timebuf);
1652 switch (prompter.run()) {
1653 case RESPONSE_ACCEPT:
1654 prompter.get_result (snapname);
1655 if (snapname.length()){
1656 save_state (snapname);
1666 ARDOUR_UI::save_state (const string & name)
1668 (void) save_state_canfail (name);
1672 ARDOUR_UI::save_state_canfail (string name)
1677 if (name.length() == 0) {
1678 name = session->snap_name();
1681 if ((ret = session->save_state (name)) != 0) {
1685 save_ardour_state (); /* XXX cannot fail? yeah, right ... */
1690 ARDOUR_UI::restore_state (string name)
1693 if (name.length() == 0) {
1694 name = session->name();
1696 session->restore_state (name);
1701 ARDOUR_UI::primary_clock_value_changed ()
1704 session->request_locate (primary_clock.current_time ());
1709 ARDOUR_UI::secondary_clock_value_changed ()
1712 session->request_locate (secondary_clock.current_time ());
1717 ARDOUR_UI::rec_enable_button_blink (bool onoff, AudioDiskstream *dstream, Widget *w)
1719 if (session && dstream && dstream->record_enabled()) {
1721 Session::RecordState rs;
1723 rs = session->record_status ();
1726 case Session::Disabled:
1727 case Session::Enabled:
1728 if (w->get_state() != STATE_SELECTED) {
1729 w->set_state (STATE_SELECTED);
1733 case Session::Recording:
1734 if (w->get_state() != STATE_ACTIVE) {
1735 w->set_state (STATE_ACTIVE);
1741 if (w->get_state() != STATE_NORMAL) {
1742 w->set_state (STATE_NORMAL);
1748 ARDOUR_UI::transport_rec_enable_blink (bool onoff)
1754 switch (session->record_status()) {
1755 case Session::Enabled:
1757 rec_button.set_visual_state (2);
1759 rec_button.set_visual_state (0);
1763 case Session::Recording:
1764 rec_button.set_visual_state (1);
1768 rec_button.set_visual_state (0);
1774 ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
1782 ARDOUR_UI::save_template ()
1785 ArdourPrompter prompter (true);
1788 prompter.set_name (X_("Prompter"));
1789 prompter.set_prompt (_("Name for mix template:"));
1790 prompter.set_initial_text(session->name() + _("-template"));
1791 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1793 switch (prompter.run()) {
1794 case RESPONSE_ACCEPT:
1795 prompter.get_result (name);
1797 if (name.length()) {
1798 session->save_template (name);
1808 ARDOUR_UI::new_session (std::string predetermined_path)
1810 string session_name;
1811 string session_path;
1813 if (!check_audioengine()) {
1817 int response = Gtk::RESPONSE_NONE;
1819 new_session_dialog->set_modal(true);
1820 new_session_dialog->set_name (predetermined_path);
1821 new_session_dialog->reset_recent();
1822 new_session_dialog->show();
1823 new_session_dialog->set_current_page (0);
1826 response = new_session_dialog->run ();
1828 if (!check_audioengine()) {
1829 new_session_dialog->hide ();
1833 _session_is_new = false;
1835 if (response == Gtk::RESPONSE_CANCEL || response == Gtk::RESPONSE_DELETE_EVENT) {
1840 new_session_dialog->hide ();
1843 } else if (response == Gtk::RESPONSE_NONE) {
1845 /* Clear was pressed */
1846 new_session_dialog->reset();
1848 } else if (response == Gtk::RESPONSE_YES) {
1850 /* YES == OPEN, but there's no enum for that */
1852 session_name = new_session_dialog->session_name();
1854 if (session_name.empty()) {
1855 response = Gtk::RESPONSE_NONE;
1859 if (session_name[0] == '/' ||
1860 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1861 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1862 load_session (Glib::path_get_dirname (session_name), session_name);
1864 session_path = new_session_dialog->session_folder();
1865 load_session (session_path, session_name);
1868 } else if (response == Gtk::RESPONSE_OK) {
1870 session_name = new_session_dialog->session_name();
1872 if (new_session_dialog->get_current_page() == 1) {
1874 /* XXX this is a bit of a hack..
1875 i really want the new sesion dialog to return RESPONSE_YES
1876 if we're on page 1 (the load page)
1877 Unfortunately i can't see how atm..
1880 if (session_name.empty()) {
1881 response = Gtk::RESPONSE_NONE;
1885 if (session_name[0] == '/' ||
1886 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1887 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1888 load_session (Glib::path_get_dirname (session_name), session_name);
1890 session_path = new_session_dialog->session_folder();
1891 load_session (session_path, session_name);
1896 if (session_name.empty()) {
1897 response = Gtk::RESPONSE_NONE;
1901 if (session_name[0] == '/' ||
1902 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1903 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1905 session_path = Glib::path_get_dirname (session_name);
1906 session_name = Glib::path_get_basename (session_name);
1910 session_path = new_session_dialog->session_folder();
1914 //XXX This is needed because session constructor wants a
1915 //non-existant path. hopefully this will be fixed at some point.
1917 session_path = Glib::build_filename (session_path, session_name);
1919 if (g_file_test (session_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
1921 Glib::ustring str = string_compose (_("This session\n%1\nalready exists. Do you want to open it?"), session_path);
1923 MessageDialog msg (str,
1925 Gtk::MESSAGE_WARNING,
1926 Gtk::BUTTONS_YES_NO,
1930 msg.set_name (X_("CleanupDialog"));
1931 msg.set_wmclass (X_("existing_session"), "Ardour");
1932 msg.set_position (Gtk::WIN_POS_MOUSE);
1934 switch (msg.run()) {
1936 load_session (session_path, session_name);
1940 response = RESPONSE_NONE;
1941 new_session_dialog->reset ();
1946 _session_is_new = true;
1948 std::string template_name = new_session_dialog->session_template_name();
1950 if (new_session_dialog->use_session_template()) {
1952 load_session (session_path, session_name, &template_name);
1958 AutoConnectOption iconnect;
1959 AutoConnectOption oconnect;
1961 if (new_session_dialog->create_control_bus()) {
1962 cchns = (uint32_t) new_session_dialog->control_channel_count();
1967 if (new_session_dialog->create_master_bus()) {
1968 mchns = (uint32_t) new_session_dialog->master_channel_count();
1973 if (new_session_dialog->connect_inputs()) {
1974 iconnect = AutoConnectPhysical;
1976 iconnect = AutoConnectOption (0);
1979 /// @todo some minor tweaks.
1981 if (new_session_dialog->connect_outs_to_master()) {
1982 oconnect = AutoConnectMaster;
1983 } else if (new_session_dialog->connect_outs_to_physical()) {
1984 oconnect = AutoConnectPhysical;
1986 oconnect = AutoConnectOption (0);
1989 uint32_t nphysin = (uint32_t) new_session_dialog->input_limit_count();
1990 uint32_t nphysout = (uint32_t) new_session_dialog->output_limit_count();
1992 if (build_session (session_path,
2000 engine->frame_rate() * 60 * 5)) {
2002 response = Gtk::RESPONSE_NONE;
2003 new_session_dialog->reset ();
2010 } while (response == Gtk::RESPONSE_NONE);
2014 new_session_dialog->get_window()->set_cursor();
2015 new_session_dialog->hide();
2020 ARDOUR_UI::close_session()
2022 if (!check_audioengine()) {
2031 ARDOUR_UI::load_session (const string & path, const string & snap_name, string* mix_template)
2033 Session *new_session;
2035 session_loaded = false;
2037 if (!check_audioengine()) {
2041 x = unload_session ();
2049 /* if it already exists, we must have write access */
2051 if (::access (path.c_str(), F_OK) == 0 && ::access (path.c_str(), W_OK)) {
2052 MessageDialog msg (*editor, _("You do not have write access to this session.\n"
2053 "This prevents the session from being loaded."));
2059 new_session = new Session (*engine, path, snap_name, mix_template);
2064 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
2068 connect_to_session (new_session);
2070 Config->set_current_owner (ConfigVariableBase::Interface);
2072 session_loaded = true;
2074 goto_editor_window ();
2077 session->set_clean ();
2080 editor->edit_cursor_position (true);
2085 ARDOUR_UI::build_session (const string & path, const string & snap_name,
2086 uint32_t control_channels,
2087 uint32_t master_channels,
2088 AutoConnectOption input_connect,
2089 AutoConnectOption output_connect,
2092 nframes_t initial_length)
2094 Session *new_session;
2097 if (!check_audioengine()) {
2101 session_loaded = false;
2103 x = unload_session ();
2111 _session_is_new = true;
2114 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
2115 control_channels, master_channels, nphysin, nphysout, initial_length);
2120 MessageDialog msg (string_compose(_("Could not create session in \"%1\""), path));
2125 connect_to_session (new_session);
2127 session_loaded = true;
2135 editor->show_window ();
2146 ARDOUR_UI::show_splash ()
2149 about = new About();
2150 about->signal_response().connect(mem_fun (*this, &ARDOUR_UI::about_signal_response) );
2157 ARDOUR_UI::about_signal_response(int response)
2163 ARDOUR_UI::hide_splash ()
2166 about->get_window()->set_cursor ();
2172 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title, const string & msg)
2176 removed = rep.paths.size();
2179 MessageDialog msgd (*editor,
2180 _("No audio files were ready for cleanup"),
2183 (Gtk::ButtonsType)(Gtk::BUTTONS_OK) );
2184 msgd.set_secondary_text (_("If this seems suprising, \n\
2185 check for any existing snapshots.\n\
2186 These may still include regions that\n\
2187 require some unused files to continue to exist."));
2193 ArdourDialog results (_("ardour: cleanup"), true, false);
2195 struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
2196 CleanupResultsModelColumns() {
2200 Gtk::TreeModelColumn<Glib::ustring> visible_name;
2201 Gtk::TreeModelColumn<Glib::ustring> fullpath;
2205 CleanupResultsModelColumns results_columns;
2206 Glib::RefPtr<Gtk::ListStore> results_model;
2207 Gtk::TreeView results_display;
2209 results_model = ListStore::create (results_columns);
2210 results_display.set_model (results_model);
2211 results_display.append_column (list_title, results_columns.visible_name);
2213 results_display.set_name ("CleanupResultsList");
2214 results_display.set_headers_visible (true);
2215 results_display.set_headers_clickable (false);
2216 results_display.set_reorderable (false);
2218 Gtk::ScrolledWindow list_scroller;
2221 Gtk::HBox dhbox; // the hbox for the image and text
2222 Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
2223 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO, Gtk::ICON_SIZE_DIALOG));
2225 dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
2227 if (rep.space < 1048576.0f) {
2229 txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2231 txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2235 txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2237 txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2241 dhbox.pack_start (*dimage, true, false, 5);
2242 dhbox.pack_start (txt, true, false, 5);
2244 for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2245 TreeModel::Row row = *(results_model->append());
2246 row[results_columns.visible_name] = *i;
2247 row[results_columns.fullpath] = *i;
2250 list_scroller.add (results_display);
2251 list_scroller.set_size_request (-1, 150);
2252 list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2254 dvbox.pack_start (dhbox, true, false, 5);
2255 dvbox.pack_start (list_scroller, true, false, 5);
2256 ddhbox.pack_start (dvbox, true, false, 5);
2258 results.get_vbox()->pack_start (ddhbox, true, false, 5);
2259 results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
2260 results.set_default_response (RESPONSE_CLOSE);
2261 results.set_position (Gtk::WIN_POS_MOUSE);
2262 results.show_all_children ();
2263 results.set_resizable (false);
2270 ARDOUR_UI::cleanup ()
2273 /* shouldn't happen: menu item is insensitive */
2278 MessageDialog checker (_("Are you sure you want to cleanup?"),
2280 Gtk::MESSAGE_QUESTION,
2281 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
2283 checker.set_secondary_text(_("Cleanup is a destructive operation.\n\
2284 ALL undo/redo information will be lost if you cleanup.\n\
2285 After cleanup, unused audio files will be moved to a \
2286 \"dead sounds\" location."));
2288 checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2289 checker.add_button (_("Clean Up"), RESPONSE_ACCEPT);
2290 checker.set_default_response (RESPONSE_CANCEL);
2292 checker.set_name (_("CleanupDialog"));
2293 checker.set_wmclass (X_("ardour_cleanup"), "Ardour");
2294 checker.set_position (Gtk::WIN_POS_MOUSE);
2296 switch (checker.run()) {
2297 case RESPONSE_ACCEPT:
2303 Session::cleanup_report rep;
2305 editor->prepare_for_cleanup ();
2307 /* do not allow flush until a session is reloaded */
2309 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
2311 act->set_sensitive (false);
2314 if (session->cleanup_sources (rep)) {
2319 display_cleanup_results (rep,
2322 The following %1 %2 not in use and \n\
2323 have been moved to:\n\
2325 Flushing the wastebasket will \n\
2326 release an additional\n\
2327 %4 %5bytes of disk space.\n"
2335 ARDOUR_UI::flush_trash ()
2338 /* shouldn't happen: menu item is insensitive */
2342 Session::cleanup_report rep;
2344 if (session->cleanup_trash_sources (rep)) {
2348 display_cleanup_results (rep,
2350 _("The following %1 %2 deleted from\n\
2352 releasing %4 %5bytes of disk space"));
2356 ARDOUR_UI::add_route (Gtk::Window* float_window)
2364 if (add_route_dialog == 0) {
2365 add_route_dialog = new AddRouteDialog;
2367 add_route_dialog->set_transient_for (*float_window);
2371 if (add_route_dialog->is_visible()) {
2372 /* we're already doing this */
2376 ResponseType r = (ResponseType) add_route_dialog->run ();
2378 add_route_dialog->hide();
2381 case RESPONSE_ACCEPT:
2388 if ((count = add_route_dialog->count()) <= 0) {
2392 uint32_t input_chan = add_route_dialog->channels ();
2393 uint32_t output_chan;
2394 string name_template = add_route_dialog->name_template ();
2395 bool track = add_route_dialog->track ();
2397 AutoConnectOption oac = Config->get_output_auto_connect();
2399 if (oac & AutoConnectMaster) {
2400 output_chan = (session->master_out() ? session->master_out()->n_inputs().n_audio() : input_chan);
2402 output_chan = input_chan;
2405 /* XXX do something with name template */
2407 if (add_route_dialog->type() == ARDOUR::DataType::MIDI) {
2409 session_add_midi_track(count);
2411 MessageDialog msg (*editor,
2412 _("Sorry, MIDI Busses are not supported at this time."));
2414 //session_add_midi_bus();
2418 session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), count);
2420 session_add_audio_bus (input_chan, output_chan, count);
2426 ARDOUR_UI::mixer_settings () const
2431 node = session->instant_xml(X_("Mixer"), session->path());
2433 node = Config->instant_xml(X_("Mixer"), get_user_ardour_path());
2437 node = new XMLNode (X_("Mixer"));
2444 ARDOUR_UI::editor_settings () const
2449 node = session->instant_xml(X_("Editor"), session->path());
2451 node = Config->instant_xml(X_("Editor"), get_user_ardour_path());
2455 node = new XMLNode (X_("Editor"));
2461 ARDOUR_UI::keyboard_settings () const
2465 node = Config->extra_xml(X_("Keyboard"));
2468 node = new XMLNode (X_("Keyboard"));
2474 ARDOUR_UI::halt_on_xrun_message ()
2476 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
2478 MessageDialog msg (*editor,
2479 _("Recording was stopped because your system could not keep up."));
2484 ARDOUR_UI::disk_overrun_handler ()
2486 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
2488 if (!have_disk_speed_dialog_displayed) {
2489 have_disk_speed_dialog_displayed = true;
2490 MessageDialog* msg = new MessageDialog (*editor, _("\
2491 The disk system on your computer\n\
2492 was not able to keep up with Ardour.\n\
2494 Specifically, it failed to write data to disk\n\
2495 quickly enough to keep up with recording.\n"));
2496 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
2502 ARDOUR_UI::disk_underrun_handler ()
2504 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2506 if (!have_disk_speed_dialog_displayed) {
2507 have_disk_speed_dialog_displayed = true;
2508 MessageDialog* msg = new MessageDialog (*editor,
2509 _("The disk system on your computer\n\
2510 was not able to keep up with Ardour.\n\
2512 Specifically, it failed to read data from disk\n\
2513 quickly enough to keep up with playback.\n"));
2514 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
2520 ARDOUR_UI::disk_speed_dialog_gone (int ignored_response, MessageDialog* msg)
2522 have_disk_speed_dialog_displayed = false;
2527 ARDOUR_UI::pending_state_dialog ()
2529 ArdourDialog dialog ("pending state dialog");
2531 This session appears to have been in\n\
2532 middle of recording when ardour or\n\
2533 the computer was shutdown.\n\
2535 Ardour can recover any captured audio for\n\
2536 you, or it can ignore it. Please decide\n\
2537 what you would like to do.\n"));
2539 dialog.get_vbox()->pack_start (message);
2540 dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
2541 dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
2543 dialog.set_position (WIN_POS_CENTER);
2546 switch (dialog.run ()) {
2547 case RESPONSE_ACCEPT:
2555 ARDOUR_UI::disconnect_from_jack ()
2558 if( engine->disconnect_from_jack ()) {
2559 MessageDialog msg (*editor, _("Could not disconnect from JACK"));
2563 update_sample_rate (0);
2568 ARDOUR_UI::reconnect_to_jack ()
2571 if (engine->reconnect_to_jack ()) {
2572 MessageDialog msg (*editor, _("Could not reconnect to JACK"));
2576 update_sample_rate (0);
2581 ARDOUR_UI::cmdline_new_session (string path)
2583 if (path[0] != '/') {
2584 char buf[PATH_MAX+1];
2587 getcwd (buf, sizeof (buf));
2596 _will_create_new_session_automatically = false; /* done it */
2597 return FALSE; /* don't call it again */
2601 ARDOUR_UI::use_config ()
2603 Glib::RefPtr<Action> act;
2605 switch (Config->get_native_file_data_format ()) {
2607 act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
2610 act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
2615 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2616 ract->set_active ();
2619 switch (Config->get_native_file_header_format ()) {
2621 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
2624 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
2627 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
2630 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
2633 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
2636 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatCAF"));
2639 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatAIFF"));
2644 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2645 ract->set_active ();
2648 XMLNode* node = Config->extra_xml (X_("TransportControllables"));
2650 set_transport_controllable_state (*node);
2655 ARDOUR_UI::update_transport_clocks (nframes_t pos)
2657 if (Config->get_primary_clock_delta_edit_cursor()) {
2658 primary_clock.set (pos, false, editor->edit_cursor_position(false), 'p');
2660 primary_clock.set (pos, 0, true);
2663 if (Config->get_secondary_clock_delta_edit_cursor()) {
2664 secondary_clock.set (pos, false, editor->edit_cursor_position(false), 's');
2666 secondary_clock.set (pos);
2669 if (big_clock_window) {
2670 big_clock.set (pos);
2675 ARDOUR_UI::record_state_changed ()
2677 ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::record_state_changed));
2679 if (!session || !big_clock_window) {
2680 /* why bother - the clock isn't visible */
2684 switch (session->record_status()) {
2685 case Session::Recording:
2686 big_clock.set_widget_name ("BigClockRecording");
2689 big_clock.set_widget_name ("BigClockNonRecording");
2695 ARDOUR_UI::set_keybindings_path (string path)
2697 keybindings_path = path;
2701 ARDOUR_UI::save_keybindings ()
2703 if (can_save_keybindings) {
2704 AccelMap::save (keybindings_path);
2709 ARDOUR_UI::first_idle ()
2712 session->allow_auto_play (true);
2714 can_save_keybindings = true;
2719 ARDOUR_UI::store_clock_modes ()
2721 XMLNode* node = new XMLNode(X_("ClockModes"));
2723 for (vector<AudioClock*>::iterator x = AudioClock::clocks.begin(); x != AudioClock::clocks.end(); ++x) {
2724 node->add_property ((*x)->name().c_str(), enum_2_string ((*x)->mode()));
2727 session->add_extra_xml (*node);
2728 session->set_dirty ();
2733 ARDOUR_UI::TransportControllable::TransportControllable (std::string name, ARDOUR_UI& u, ToggleType tp)
2734 : Controllable (name), ui (u), type(tp)
2740 ARDOUR_UI::TransportControllable::set_value (float val)
2742 if (type == ShuttleControl) {
2749 fract = -((0.5f - val)/0.5f);
2751 fract = ((val - 0.5f)/0.5f);
2755 ui.set_shuttle_fract (fract);
2760 /* do nothing: these are radio-style actions */
2768 action = X_("Roll");
2771 action = X_("Stop");
2774 action = X_("Goto Start");
2777 action = X_("Goto End");
2780 action = X_("Loop");
2783 action = X_("Play Selection");
2786 action = X_("Record");
2796 Glib::RefPtr<Action> act = ActionManager::get_action ("Transport", action);
2804 ARDOUR_UI::TransportControllable::get_value (void) const
2823 case ShuttleControl:
2833 ARDOUR_UI::TransportControllable::set_id (const string& str)
2839 ARDOUR_UI::setup_profile ()
2841 if (gdk_screen_width() < 1200) {
2842 Profile->set_small_screen ();