2 Copyright (C) 1999-2007 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #define __STDC_FORMAT_MACROS 1
33 #include <sys/resource.h>
35 #include <gtkmm/messagedialog.h>
36 #include <gtkmm/accelmap.h>
38 #include <pbd/error.h>
39 #include <pbd/compose.h>
40 #include <pbd/failed_constructor.h>
41 #include <pbd/enumwriter.h>
42 #include <pbd/memento_command.h>
43 #include <pbd/file_utils.h>
45 #include <gtkmm2ext/gtk_ui.h>
46 #include <gtkmm2ext/utils.h>
47 #include <gtkmm2ext/click_box.h>
48 #include <gtkmm2ext/fastmeter.h>
49 #include <gtkmm2ext/stop_signal.h>
50 #include <gtkmm2ext/popup.h>
51 #include <gtkmm2ext/window_title.h>
53 #include <midi++/port.h>
54 #include <midi++/mmc.h>
56 #include <ardour/ardour.h>
57 #include <ardour/profile.h>
58 #include <ardour/session_directory.h>
59 #include <ardour/session_route.h>
60 #include <ardour/session_utils.h>
61 #include <ardour/port.h>
62 #include <ardour/audioengine.h>
63 #include <ardour/playlist.h>
64 #include <ardour/utils.h>
65 #include <ardour/audio_diskstream.h>
66 #include <ardour/audiofilesource.h>
67 #include <ardour/recent_sessions.h>
68 #include <ardour/port.h>
69 #include <ardour/audio_track.h>
70 #include <ardour/midi_track.h>
71 #include <ardour/filesystem_paths.h>
74 #include "ardour_ui.h"
75 #include "public_editor.h"
76 #include "audio_clock.h"
81 #include "add_route_dialog.h"
82 #include "new_session_dialog.h"
85 #include "gui_thread.h"
86 #include "theme_manager.h"
90 using namespace ARDOUR;
92 using namespace Gtkmm2ext;
96 ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
98 sigc::signal<void,bool> ARDOUR_UI::Blink;
99 sigc::signal<void> ARDOUR_UI::RapidScreenUpdate;
100 sigc::signal<void> ARDOUR_UI::SuperRapidScreenUpdate;
101 sigc::signal<void,nframes_t, bool, nframes_t> ARDOUR_UI::Clock;
103 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[])
105 : Gtkmm2ext::UI (X_("Ardour"), argcp, argvp),
107 primary_clock (X_("primary"), false, X_("TransportClockDisplay"), true, false, true),
108 secondary_clock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, false, true),
109 preroll_clock (X_("preroll"), false, X_("PreRollClock"), true, true),
110 postroll_clock (X_("postroll"), false, X_("PostRollClock"), true, true),
114 adjuster_table (3, 3),
118 preroll_button (_("pre\nroll")),
119 postroll_button (_("post\nroll")),
123 big_clock (X_("bigclock"), false, "BigClockNonRecording", false, false, true),
127 roll_controllable ("transport roll", *this, TransportControllable::Roll),
128 stop_controllable ("transport stop", *this, TransportControllable::Stop),
129 goto_start_controllable ("transport goto start", *this, TransportControllable::GotoStart),
130 goto_end_controllable ("transport goto end", *this, TransportControllable::GotoEnd),
131 auto_loop_controllable ("transport auto loop", *this, TransportControllable::AutoLoop),
132 play_selection_controllable ("transport play selection", *this, TransportControllable::PlaySelection),
133 rec_controllable ("transport rec-enable", *this, TransportControllable::RecordEnable),
134 shuttle_controllable ("shuttle", *this, TransportControllable::ShuttleControl),
135 shuttle_controller_binding_proxy (shuttle_controllable),
137 roll_button (roll_controllable),
138 stop_button (stop_controllable),
139 goto_start_button (goto_start_controllable),
140 goto_end_button (goto_end_controllable),
141 auto_loop_button (auto_loop_controllable),
142 play_selection_button (play_selection_controllable),
143 rec_button (rec_controllable),
145 shuttle_units_button (_("% ")),
147 punch_in_button (_("Punch In")),
148 punch_out_button (_("Punch Out")),
149 auto_return_button (_("Auto Return")),
150 auto_play_button (_("Auto Play")),
151 auto_input_button (_("Auto Input")),
152 click_button (_("Click")),
153 time_master_button (_("time\nmaster")),
155 auditioning_alert_button (_("AUDITION")),
156 solo_alert_button (_("SOLO")),
159 using namespace Gtk::Menu_Helpers;
165 if (theArdourUI == 0) {
171 theme_manager = new ThemeManager();
173 //std::string color_file = ARDOUR::find_config_file("ardour.colors");
175 //theme_manager->load (color_file);
180 _session_is_new = false;
181 big_clock_window = 0;
182 session_selector_window = 0;
183 last_key_press_time = 0;
184 connection_editor = 0;
185 add_route_dialog = 0;
189 open_session_selector = 0;
190 have_configure_timeout = false;
191 have_disk_speed_dialog_displayed = false;
192 session_loaded = false;
193 last_speed_displayed = -1.0f;
196 sys::path key_bindings_file;
198 find_file_in_search_path (ardour_search_path() + system_config_search_path(),
199 "ardour.bindings", key_bindings_file);
201 keybindings_path = key_bindings_file.to_string();
203 can_save_keybindings = false;
205 last_configure_time.tv_sec = 0;
206 last_configure_time.tv_usec = 0;
208 shuttle_grabbed = false;
210 shuttle_max_speed = 8.0f;
212 shuttle_style_menu = 0;
213 shuttle_unit_menu = 0;
215 gettimeofday (&last_peak_grab, 0);
216 gettimeofday (&last_shuttle_request, 0);
218 ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
219 ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
221 /* handle pending state with a dialog */
223 ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
225 /* have to wait for AudioEngine and Configuration before proceeding */
229 ARDOUR_UI::set_engine (AudioEngine& e)
233 engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
234 engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
235 engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
236 engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
238 ActionManager::init ();
239 new_session_dialog = new NewSessionDialog();
243 keyboard = new Keyboard;
245 if (setup_windows ()) {
246 throw failed_constructor ();
249 if (GTK_ARDOUR::show_key_actions) {
250 vector<string> names;
251 vector<string> paths;
253 vector<AccelKey> bindings;
255 ActionManager::get_all_actions (names, paths, keys, bindings);
257 vector<string>::iterator n;
258 vector<string>::iterator k;
259 for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) {
260 cerr << "Action: " << (*n) << " bound to " << (*k) << endl;
266 /* start with timecode, metering enabled
269 blink_timeout_tag = -1;
271 /* the global configuration object is now valid */
275 /* this being a GUI and all, we want peakfiles */
277 AudioFileSource::set_build_peakfiles (true);
278 AudioFileSource::set_build_missing_peakfiles (true);
280 /* set default clock modes */
282 primary_clock.set_mode (AudioClock::SMPTE);
283 secondary_clock.set_mode (AudioClock::BBT);
285 /* start the time-of-day-clock */
287 update_wall_clock ();
288 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
290 update_disk_space ();
292 update_sample_rate (engine->frame_rate());
294 starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
295 stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
298 ARDOUR_UI::~ARDOUR_UI ()
300 save_ardour_state ();
314 if (add_route_dialog) {
315 delete add_route_dialog;
320 ARDOUR_UI::configure_timeout ()
325 if (last_configure_time.tv_sec == 0 && last_configure_time.tv_usec == 0) {
326 /* no configure events yet */
330 gettimeofday (&now, 0);
331 timersub (&now, &last_configure_time, &diff);
333 /* force a gap of 0.5 seconds since the last configure event
336 if (diff.tv_sec == 0 && diff.tv_usec < 500000) {
339 have_configure_timeout = false;
340 save_ardour_state ();
346 ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
348 if (have_configure_timeout) {
349 gettimeofday (&last_configure_time, 0);
351 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
352 have_configure_timeout = true;
359 ARDOUR_UI::set_transport_controllable_state (const XMLNode& node)
361 const XMLProperty* prop;
363 if ((prop = node.property ("roll")) != 0) {
364 roll_controllable.set_id (prop->value());
366 if ((prop = node.property ("stop")) != 0) {
367 stop_controllable.set_id (prop->value());
369 if ((prop = node.property ("goto_start")) != 0) {
370 goto_start_controllable.set_id (prop->value());
372 if ((prop = node.property ("goto_end")) != 0) {
373 goto_end_controllable.set_id (prop->value());
375 if ((prop = node.property ("auto_loop")) != 0) {
376 auto_loop_controllable.set_id (prop->value());
378 if ((prop = node.property ("play_selection")) != 0) {
379 play_selection_controllable.set_id (prop->value());
381 if ((prop = node.property ("rec")) != 0) {
382 rec_controllable.set_id (prop->value());
384 if ((prop = node.property ("shuttle")) != 0) {
385 shuttle_controllable.set_id (prop->value());
390 ARDOUR_UI::get_transport_controllable_state ()
392 XMLNode* node = new XMLNode(X_("TransportControllables"));
395 roll_controllable.id().print (buf, sizeof (buf));
396 node->add_property (X_("roll"), buf);
397 stop_controllable.id().print (buf, sizeof (buf));
398 node->add_property (X_("stop"), buf);
399 goto_start_controllable.id().print (buf, sizeof (buf));
400 node->add_property (X_("goto_start"), buf);
401 goto_end_controllable.id().print (buf, sizeof (buf));
402 node->add_property (X_("goto_end"), buf);
403 auto_loop_controllable.id().print (buf, sizeof (buf));
404 node->add_property (X_("auto_loop"), buf);
405 play_selection_controllable.id().print (buf, sizeof (buf));
406 node->add_property (X_("play_selection"), buf);
407 rec_controllable.id().print (buf, sizeof (buf));
408 node->add_property (X_("rec"), buf);
409 shuttle_controllable.id().print (buf, sizeof (buf));
410 node->add_property (X_("shuttle"), buf);
416 ARDOUR_UI::save_ardour_state ()
418 if (!keyboard || !mixer || !editor) {
422 /* XXX this is all a bit dubious. add_extra_xml() uses
423 a different lifetime model from add_instant_xml().
426 XMLNode* node = new XMLNode (keyboard->get_state());
427 Config->add_extra_xml (*node);
428 Config->add_extra_xml (get_transport_controllable_state());
429 Config->save_state();
431 XMLNode enode(static_cast<Stateful*>(editor)->get_state());
432 XMLNode mnode(mixer->get_state());
435 session->add_instant_xml (enode);
436 session->add_instant_xml (mnode);
438 Config->add_instant_xml (enode);
439 Config->add_instant_xml (mnode);
446 ARDOUR_UI::autosave_session ()
448 if (!Config->get_periodic_safety_backups())
452 session->maybe_write_autosave();
459 ARDOUR_UI::update_autosave ()
461 ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::update_autosave));
463 if (session->dirty()) {
464 if (_autosave_connection.connected()) {
465 _autosave_connection.disconnect();
468 _autosave_connection = Glib::signal_timeout().connect (mem_fun (*this, &ARDOUR_UI::autosave_session),
469 Config->get_periodic_safety_backup_interval() * 1000);
472 if (_autosave_connection.connected()) {
473 _autosave_connection.disconnect();
479 ARDOUR_UI::startup ()
481 check_memory_locking();
485 ARDOUR_UI::no_memory_warning ()
487 XMLNode node (X_("no-memory-warning"));
488 Config->add_instant_xml (node);
492 ARDOUR_UI::check_memory_locking ()
495 /* OS X doesn't support mlockall(2), and so testing for memory locking capability there is pointless */
499 XMLNode* memory_warning_node = Config->instant_xml (X_("no-memory-warning"));
501 if (engine->is_realtime() && memory_warning_node == 0) {
503 struct rlimit limits;
505 long pages, page_size;
507 if ((page_size = sysconf (_SC_PAGESIZE)) < 0 ||(pages = sysconf (_SC_PHYS_PAGES)) < 0) {
510 ram = (int64_t) pages * (int64_t) page_size;
513 if (getrlimit (RLIMIT_MEMLOCK, &limits)) {
517 if (limits.rlim_cur != RLIM_INFINITY) {
519 if (ram == 0 || ((double) limits.rlim_cur / ram) < 0.75) {
522 MessageDialog msg (_("WARNING: Your system has a limit for maximum amount of locked memory. "
523 "This might cause Ardour to run out of memory before your system "
524 "runs out of memory. \n\n"
525 "You can view the memory limit with 'ulimit -l', "
526 "and it is normally controlled by /etc/security/limits.conf"));
528 VBox* vbox = msg.get_vbox();
530 CheckButton cb (_("Do not show this window again"));
532 cb.signal_toggled().connect (mem_fun (*this, &ARDOUR_UI::no_memory_warning));
534 hbox.pack_start (cb, true, false);
535 vbox->pack_start (hbox);
538 editor->ensure_float (msg);
550 if (session && session->dirty()) {
551 switch (ask_about_saving_session(_("quit"))) {
556 /* use the default name */
557 if (save_state_canfail ("")) {
558 /* failed - don't quit */
559 MessageDialog msg (*editor,
561 Ardour was unable to save your session.\n\n\
562 If you still wish to quit, please use the\n\n\
563 \"Just quit\" option."));
574 session->set_deletion_in_progress ();
577 Config->save_state();
582 ARDOUR_UI::ask_about_saving_session (const string & what)
584 ArdourDialog window (_("ardour: save session?"));
585 Gtk::HBox dhbox; // the hbox for the image and text
586 Gtk::Label prompt_label;
587 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_WARNING, Gtk::ICON_SIZE_DIALOG));
591 msg = string_compose(_("Don't %1"), what);
592 window.add_button (msg, RESPONSE_REJECT);
593 msg = string_compose(_("Just %1"), what);
594 window.add_button (msg, RESPONSE_APPLY);
595 msg = string_compose(_("Save and %1"), what);
596 window.add_button (msg, RESPONSE_ACCEPT);
598 window.set_default_response (RESPONSE_ACCEPT);
600 Gtk::Button noquit_button (msg);
601 noquit_button.set_name ("EditorGTKButton");
606 if (session->snap_name() == session->name()) {
609 type = _("snapshot");
611 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?"),
612 type, session->snap_name());
614 prompt_label.set_text (prompt);
615 prompt_label.set_name (X_("PrompterLabel"));
616 prompt_label.set_alignment(ALIGN_LEFT, ALIGN_TOP);
618 dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP)
620 dhbox.set_homogeneous (false);
621 dhbox.pack_start (*dimage, false, false, 5);
622 dhbox.pack_start (prompt_label, true, false, 5);
623 window.get_vbox()->pack_start (dhbox);
625 window.set_name (_("Prompter"));
626 window.set_position (Gtk::WIN_POS_MOUSE);
627 window.set_modal (true);
628 window.set_resizable (false);
631 save_the_session = 0;
633 window.set_keep_above (true);
636 ResponseType r = (ResponseType) window.run();
641 case RESPONSE_ACCEPT: // save and get out of here
643 case RESPONSE_APPLY: // get out of here
653 ARDOUR_UI::every_second ()
656 update_buffer_load ();
657 update_disk_space ();
662 ARDOUR_UI::every_point_one_seconds ()
664 update_speed_display ();
665 RapidScreenUpdate(); /* EMIT_SIGNAL */
670 ARDOUR_UI::every_point_zero_one_seconds ()
672 SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
677 ARDOUR_UI::update_sample_rate (nframes_t ignored)
681 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
683 if (!engine->connected()) {
685 snprintf (buf, sizeof (buf), _("disconnected"));
689 nframes_t rate = engine->frame_rate();
691 if (fmod (rate, 1000.0) != 0.0) {
692 snprintf (buf, sizeof (buf), _("%.1f kHz / %4.1f ms"),
693 (float) rate/1000.0f,
694 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
696 snprintf (buf, sizeof (buf), _("%u kHz / %4.1f ms"),
698 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
702 sample_rate_label.set_text (buf);
706 ARDOUR_UI::update_cpu_load ()
709 snprintf (buf, sizeof (buf), _("DSP: %5.1f%%"), engine->get_cpu_load());
710 cpu_load_label.set_text (buf);
714 ARDOUR_UI::update_buffer_load ()
719 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"),
720 session->playback_load(), session->capture_load());
721 buffer_load_label.set_text (buf);
723 buffer_load_label.set_text ("");
728 ARDOUR_UI::count_recenabled_streams (Route& route)
730 Track* track = dynamic_cast<Track*>(&route);
731 if (track && track->diskstream()->record_enabled()) {
732 rec_enabled_streams += track->n_inputs().n_total();
737 ARDOUR_UI::update_disk_space()
743 nframes_t frames = session->available_capture_duration();
746 if (frames == max_frames) {
747 strcpy (buf, _("Disk: 24hrs+"));
752 nframes_t fr = session->frame_rate();
754 rec_enabled_streams = 0;
755 session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
757 if (rec_enabled_streams) {
758 frames /= rec_enabled_streams;
761 hrs = frames / (fr * 3600);
762 frames -= hrs * fr * 3600;
763 mins = frames / (fr * 60);
764 frames -= mins * fr * 60;
767 snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs);
770 disk_space_label.set_text (buf);
774 ARDOUR_UI::update_wall_clock ()
781 tm_now = localtime (&now);
783 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
784 wall_clock_label.set_text (buf);
790 ARDOUR_UI::session_menu (GdkEventButton *ev)
792 session_popup_menu->popup (0, 0);
797 ARDOUR_UI::redisplay_recent_sessions ()
799 vector<string *> *sessions;
800 vector<string *>::iterator i;
801 RecentSessionsSorter cmp;
803 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
804 recent_session_model->clear ();
807 ARDOUR::read_recent_sessions (rs);
810 recent_session_display.set_model (recent_session_model);
814 /* sort them alphabetically */
815 sort (rs.begin(), rs.end(), cmp);
816 sessions = new vector<string*>;
818 for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
819 sessions->push_back (new string ((*i).second));
822 for (i = sessions->begin(); i != sessions->end(); ++i) {
824 vector<string*>* states;
825 vector<const gchar*> item;
826 string fullpath = *(*i);
828 /* remove any trailing / */
830 if (fullpath[fullpath.length()-1] == '/') {
831 fullpath = fullpath.substr (0, fullpath.length()-1);
834 /* now get available states for this session */
836 if ((states = Session::possible_states (fullpath)) == 0) {
841 TreeModel::Row row = *(recent_session_model->append());
843 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
844 row[recent_session_columns.fullpath] = fullpath;
846 if (states->size() > 1) {
848 /* add the children */
850 for (vector<string*>::iterator i2 = states->begin(); i2 != states->end(); ++i2) {
852 TreeModel::Row child_row = *(recent_session_model->append (row.children()));
854 child_row[recent_session_columns.visible_name] = **i2;
855 child_row[recent_session_columns.fullpath] = fullpath;
864 recent_session_display.set_model (recent_session_model);
869 ARDOUR_UI::build_session_selector ()
871 session_selector_window = new ArdourDialog ("session selector");
873 Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
875 session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
876 session_selector_window->add_button (Stock::OPEN, RESPONSE_ACCEPT);
877 session_selector_window->set_default_response (RESPONSE_ACCEPT);
878 recent_session_model = TreeStore::create (recent_session_columns);
879 recent_session_display.set_model (recent_session_model);
880 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
881 recent_session_display.set_headers_visible (false);
882 recent_session_display.get_selection()->set_mode (SELECTION_SINGLE);
884 recent_session_display.signal_row_activated().connect (mem_fun (*this, &ARDOUR_UI::recent_session_row_activated));
886 scroller->add (recent_session_display);
887 scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
889 session_selector_window->set_name ("SessionSelectorWindow");
890 session_selector_window->set_size_request (200, 400);
891 session_selector_window->get_vbox()->pack_start (*scroller);
892 session_selector_window->show_all_children();
896 ARDOUR_UI::recent_session_row_activated (const TreePath& path, TreeViewColumn* col)
898 session_selector_window->response (RESPONSE_ACCEPT);
902 ARDOUR_UI::open_recent_session ()
904 /* popup selector window */
906 if (session_selector_window == 0) {
907 build_session_selector ();
910 redisplay_recent_sessions ();
912 ResponseType r = (ResponseType) session_selector_window->run ();
914 session_selector_window->hide();
917 case RESPONSE_ACCEPT:
923 Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
925 if (i == recent_session_model->children().end()) {
929 Glib::ustring path = (*i)[recent_session_columns.fullpath];
930 Glib::ustring state = (*i)[recent_session_columns.visible_name];
932 _session_is_new = false;
934 load_session (path, state);
938 ARDOUR_UI::filter_ardour_session_dirs (const FileFilter::Info& info)
942 if (stat (info.filename.c_str(), &statbuf) != 0) {
946 if (!S_ISDIR(statbuf.st_mode)) {
952 string session_file = info.filename;
954 session_file += Glib::path_get_basename (info.filename);
955 session_file += ".ardour";
957 if (stat (session_file.c_str(), &statbuf) != 0) {
961 return S_ISREG (statbuf.st_mode);
965 ARDOUR_UI::check_audioengine ()
968 if (!engine->connected()) {
969 MessageDialog msg (_("Ardour is not connected to JACK\n"
970 "You cannot open or close sessions in this condition"));
981 ARDOUR_UI::open_session ()
983 if (!check_audioengine()) {
988 /* popup selector window */
990 if (open_session_selector == 0) {
992 /* ardour sessions are folders */
994 open_session_selector = new Gtk::FileChooserDialog (_("open session"), FILE_CHOOSER_ACTION_OPEN);
995 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
996 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
998 FileFilter session_filter;
999 session_filter.add_pattern ("*.ardour");
1000 session_filter.set_name (_("Ardour sessions"));
1001 open_session_selector->add_filter (session_filter);
1002 open_session_selector->set_filter (session_filter);
1005 int response = open_session_selector->run();
1006 open_session_selector->hide ();
1009 case RESPONSE_ACCEPT:
1012 open_session_selector->hide();
1016 open_session_selector->hide();
1017 string session_path = open_session_selector->get_filename();
1021 if (session_path.length() > 0) {
1022 if (ARDOUR::find_session (session_path, path, name, isnew) == 0) {
1023 _session_is_new = isnew;
1024 load_session (path, name);
1031 ARDOUR_UI::session_add_midi_route (bool disk, uint32_t how_many)
1033 list<boost::shared_ptr<MidiTrack> > tracks;
1036 warning << _("You cannot add a track without a session already loaded.") << endmsg;
1043 tracks = session->new_midi_track (ARDOUR::Normal, how_many);
1045 if (tracks.size() != how_many) {
1046 if (how_many == 1) {
1047 error << _("could not create a new midi track") << endmsg;
1049 error << string_compose (_("could not create %1 new midi tracks"), how_many) << endmsg;
1053 if ((route = session->new_midi_route ()) == 0) {
1054 error << _("could not create new midi bus") << endmsg;
1060 MessageDialog msg (*editor,
1061 _("There are insufficient JACK ports available\n\
1062 to create a new track or bus.\n\
1063 You should save Ardour, exit and\n\
1064 restart JACK with more ports."));
1071 ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, uint32_t how_many)
1073 list<boost::shared_ptr<AudioTrack> > tracks;
1074 Session::RouteList routes;
1077 warning << _("You cannot add a track or bus without a session already loaded.") << endmsg;
1083 tracks = session->new_audio_track (input_channels, output_channels, mode, how_many);
1085 if (tracks.size() != how_many) {
1086 if (how_many == 1) {
1087 error << _("could not create a new audio track") << endmsg;
1089 error << string_compose (_("could only create %1 of %2 new audio %3"),
1090 tracks.size(), how_many, (track ? _("tracks") : _("busses"))) << endmsg;
1096 routes = session->new_audio_route (input_channels, output_channels, how_many);
1098 if (routes.size() != how_many) {
1099 if (how_many == 1) {
1100 error << _("could not create a new audio track") << endmsg;
1102 error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
1108 if (need_control_room_outs) {
1114 route->set_stereo_control_outs (control_lr_channels);
1115 route->control_outs()->set_stereo_pan (pans, this);
1117 #endif /* CONTROLOUTS */
1121 cerr << "About to complain about JACK\n";
1122 MessageDialog msg (*editor,
1123 _("There are insufficient JACK ports available\n\
1124 to create a new track or bus.\n\
1125 You should save Ardour, exit and\n\
1126 restart JACK with more ports."));
1132 ARDOUR_UI::do_transport_locate (nframes_t new_position)
1134 nframes_t _preroll = 0;
1137 // XXX CONFIG_CHANGE FIX - requires AnyTime handling
1138 // _preroll = session->convert_to_frames_at (new_position, Config->get_preroll());
1140 if (new_position > _preroll) {
1141 new_position -= _preroll;
1146 session->request_locate (new_position);
1151 ARDOUR_UI::transport_goto_start ()
1154 session->goto_start();
1157 /* force displayed area in editor to start no matter
1158 what "follow playhead" setting is.
1162 editor->reset_x_origin (session->current_start_frame());
1168 ARDOUR_UI::transport_goto_zero ()
1171 session->request_locate (0);
1174 /* force displayed area in editor to start no matter
1175 what "follow playhead" setting is.
1179 editor->reset_x_origin (0);
1185 ARDOUR_UI::transport_goto_end ()
1188 nframes_t frame = session->current_end_frame();
1189 session->request_locate (frame);
1191 /* force displayed area in editor to start no matter
1192 what "follow playhead" setting is.
1196 editor->reset_x_origin (frame);
1202 ARDOUR_UI::transport_stop ()
1208 if (session->is_auditioning()) {
1209 session->cancel_audition ();
1213 if (session->get_play_loop ()) {
1214 session->request_play_loop (false);
1217 session->request_stop ();
1221 ARDOUR_UI::transport_stop_and_forget_capture ()
1224 session->request_stop (true);
1229 ARDOUR_UI::remove_last_capture()
1232 editor->remove_last_capture();
1237 ARDOUR_UI::transport_record ()
1240 switch (session->record_status()) {
1241 case Session::Disabled:
1242 if (session->ntracks() == 0) {
1243 MessageDialog msg (*editor, _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu."));
1247 session->maybe_enable_record ();
1249 case Session::Recording:
1250 case Session::Enabled:
1251 session->disable_record (false, true);
1257 ARDOUR_UI::transport_roll ()
1265 rolling = session->transport_rolling ();
1267 if (session->get_play_loop()) {
1268 session->request_play_loop (false);
1269 auto_loop_button.set_visual_state (1);
1270 roll_button.set_visual_state (1);
1271 } else if (session->get_play_range ()) {
1272 session->request_play_range (false);
1273 play_selection_button.set_visual_state (0);
1274 } else if (rolling) {
1275 session->request_locate (session->last_transport_start(), true);
1278 session->request_transport_speed (1.0f);
1282 ARDOUR_UI::transport_loop()
1285 if (session->get_play_loop()) {
1286 if (session->transport_rolling()) {
1287 Location * looploc = session->locations()->auto_loop_location();
1289 session->request_locate (looploc->start(), true);
1294 session->request_play_loop (true);
1300 ARDOUR_UI::transport_play_selection ()
1306 if (!session->get_play_range()) {
1307 session->request_stop ();
1310 editor->play_selection ();
1314 ARDOUR_UI::transport_rewind (int option)
1316 float current_transport_speed;
1319 current_transport_speed = session->transport_speed();
1321 if (current_transport_speed >= 0.0f) {
1324 session->request_transport_speed (-1.0f);
1327 session->request_transport_speed (-4.0f);
1330 session->request_transport_speed (-0.5f);
1335 session->request_transport_speed (current_transport_speed * 1.5f);
1341 ARDOUR_UI::transport_forward (int option)
1343 float current_transport_speed;
1346 current_transport_speed = session->transport_speed();
1348 if (current_transport_speed <= 0.0f) {
1351 session->request_transport_speed (1.0f);
1354 session->request_transport_speed (4.0f);
1357 session->request_transport_speed (0.5f);
1362 session->request_transport_speed (current_transport_speed * 1.5f);
1368 ARDOUR_UI::toggle_record_enable (uint32_t dstream)
1374 boost::shared_ptr<Route> r;
1376 if ((r = session->route_by_remote_id (dstream)) != 0) {
1380 if ((t = dynamic_cast<Track*>(r.get())) != 0) {
1381 t->diskstream()->set_record_enabled (!t->diskstream()->record_enabled());
1390 ARDOUR_UI::queue_transport_change ()
1392 Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
1396 ARDOUR_UI::map_transport_state ()
1398 float sp = session->transport_speed();
1401 transport_rolling ();
1402 } else if (sp < 0.0f) {
1403 transport_rewinding ();
1404 } else if (sp > 0.0f) {
1405 transport_forwarding ();
1407 transport_stopped ();
1412 ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg)
1414 snprintf (buf, sizeof(buf), "%s", ((GlobalClickBox *) arg)->strings[
1415 (int) adj.get_value()].c_str());
1419 ARDOUR_UI::engine_stopped ()
1421 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
1422 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1423 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1427 ARDOUR_UI::engine_running ()
1429 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
1430 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true);
1431 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
1433 Glib::RefPtr<Action> action;
1434 char* action_name = 0;
1436 switch (engine->frames_per_cycle()) {
1438 action_name = X_("JACKLatency32");
1441 action_name = X_("JACKLatency64");
1444 action_name = X_("JACKLatency128");
1447 action_name = X_("JACKLatency512");
1450 action_name = X_("JACKLatency1024");
1453 action_name = X_("JACKLatency2048");
1456 action_name = X_("JACKLatency4096");
1459 action_name = X_("JACKLatency8192");
1462 /* XXX can we do anything useful ? */
1468 action = ActionManager::get_action (X_("JACK"), action_name);
1471 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic (action);
1472 ract->set_active ();
1478 ARDOUR_UI::engine_halted ()
1480 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
1482 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1483 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1485 update_sample_rate (0);
1487 MessageDialog msg (*editor,
1489 JACK has either been shutdown or it\n\
1490 disconnected Ardour because Ardour\n\
1491 was not fast enough. You can save the\n\
1492 session and/or try to reconnect to JACK ."));
1497 ARDOUR_UI::do_engine_start ()
1505 error << _("Unable to start the session running")
1515 ARDOUR_UI::setup_theme ()
1520 if ((env = getenv ("ARDOUR2_UI_RC")) != 0 && strlen (env)) {
1523 rcfile = Config->get_ui_rc_file();
1526 rcfile = find_config_file (rcfile);
1528 if (rcfile.empty()) {
1529 warning << _("Without a UI style file, ardour will look strange.\n Please set ARDOUR2_UI_RC to point to a valid UI style file") << endmsg;
1531 cerr << "Loading ui configuration file " << rcfile << endl;
1534 load_rcfile(rcfile);
1536 theme_manager->setup_theme();
1540 ARDOUR_UI::start_engine ()
1542 if (do_engine_start () == 0) {
1543 if (session && _session_is_new) {
1544 /* we need to retain initial visual
1545 settings for a new session
1547 session->save_state ("");
1555 ARDOUR_UI::update_clocks ()
1557 if (!editor || !editor->dragging_playhead()) {
1558 Clock (session->audible_frame(), false, editor->edit_cursor_position(false)); /* EMIT_SIGNAL */
1563 ARDOUR_UI::start_clocking ()
1565 clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
1569 ARDOUR_UI::stop_clocking ()
1571 clock_signal_connection.disconnect ();
1575 ARDOUR_UI::toggle_clocking ()
1578 if (clock_button.get_active()) {
1587 ARDOUR_UI::_blink (void *arg)
1590 ((ARDOUR_UI *) arg)->blink ();
1597 Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
1601 ARDOUR_UI::start_blinking ()
1603 /* Start the blink signal. Everybody with a blinking widget
1604 uses Blink to drive the widget's state.
1607 if (blink_timeout_tag < 0) {
1609 blink_timeout_tag = g_timeout_add (240, _blink, this);
1614 ARDOUR_UI::stop_blinking ()
1616 if (blink_timeout_tag >= 0) {
1617 g_source_remove (blink_timeout_tag);
1618 blink_timeout_tag = -1;
1623 ARDOUR_UI::name_io_setup (AudioEngine& engine,
1629 if (io.n_inputs().n_total() == 0) {
1634 /* XXX we're not handling multiple ports yet. */
1636 const char **connections = io.input(0)->get_connections();
1638 if (connections == 0 || connections[0] == '\0') {
1641 buf = connections[0];
1648 if (io.n_outputs().n_total() == 0) {
1653 /* XXX we're not handling multiple ports yet. */
1655 const char **connections = io.output(0)->get_connections();
1657 if (connections == 0 || connections[0] == '\0') {
1660 buf = connections[0];
1667 /** Ask the user for the name of a new shapshot and then take it.
1670 ARDOUR_UI::snapshot_session ()
1672 ArdourPrompter prompter (true);
1676 struct tm local_time;
1679 localtime_r (&n, &local_time);
1680 strftime (timebuf, sizeof(timebuf), "%FT%T", &local_time);
1682 prompter.set_name ("Prompter");
1683 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1684 prompter.set_prompt (_("Name of New Snapshot"));
1685 prompter.set_initial_text (timebuf);
1687 switch (prompter.run()) {
1688 case RESPONSE_ACCEPT:
1689 prompter.get_result (snapname);
1690 if (snapname.length()){
1691 save_state (snapname);
1701 ARDOUR_UI::save_state (const string & name)
1703 (void) save_state_canfail (name);
1707 ARDOUR_UI::save_state_canfail (string name)
1712 if (name.length() == 0) {
1713 name = session->snap_name();
1716 if ((ret = session->save_state (name)) != 0) {
1720 save_ardour_state (); /* XXX cannot fail? yeah, right ... */
1725 ARDOUR_UI::restore_state (string name)
1728 if (name.length() == 0) {
1729 name = session->name();
1731 session->restore_state (name);
1736 ARDOUR_UI::primary_clock_value_changed ()
1739 session->request_locate (primary_clock.current_time ());
1744 ARDOUR_UI::secondary_clock_value_changed ()
1747 session->request_locate (secondary_clock.current_time ());
1752 ARDOUR_UI::rec_enable_button_blink (bool onoff, AudioDiskstream *dstream, Widget *w)
1754 if (session && dstream && dstream->record_enabled()) {
1756 Session::RecordState rs;
1758 rs = session->record_status ();
1761 case Session::Disabled:
1762 case Session::Enabled:
1763 if (w->get_state() != STATE_SELECTED) {
1764 w->set_state (STATE_SELECTED);
1768 case Session::Recording:
1769 if (w->get_state() != STATE_ACTIVE) {
1770 w->set_state (STATE_ACTIVE);
1776 if (w->get_state() != STATE_NORMAL) {
1777 w->set_state (STATE_NORMAL);
1783 ARDOUR_UI::transport_rec_enable_blink (bool onoff)
1789 switch (session->record_status()) {
1790 case Session::Enabled:
1792 rec_button.set_visual_state (2);
1794 rec_button.set_visual_state (0);
1798 case Session::Recording:
1799 rec_button.set_visual_state (1);
1803 rec_button.set_visual_state (0);
1809 ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
1817 ARDOUR_UI::save_template ()
1820 ArdourPrompter prompter (true);
1823 prompter.set_name (X_("Prompter"));
1824 prompter.set_prompt (_("Name for mix template:"));
1825 prompter.set_initial_text(session->name() + _("-template"));
1826 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1828 switch (prompter.run()) {
1829 case RESPONSE_ACCEPT:
1830 prompter.get_result (name);
1832 if (name.length()) {
1833 session->save_template (name);
1843 ARDOUR_UI::new_session (std::string predetermined_path)
1845 string session_name;
1846 string session_path;
1848 if (!check_audioengine()) {
1852 int response = Gtk::RESPONSE_NONE;
1854 new_session_dialog->set_modal(true);
1855 new_session_dialog->set_name (predetermined_path);
1856 new_session_dialog->reset_recent();
1857 new_session_dialog->show();
1858 new_session_dialog->set_current_page (0);
1861 response = new_session_dialog->run ();
1863 if (!check_audioengine()) {
1864 new_session_dialog->hide ();
1868 _session_is_new = false;
1870 if (response == Gtk::RESPONSE_CANCEL || response == Gtk::RESPONSE_DELETE_EVENT) {
1875 new_session_dialog->hide ();
1878 } else if (response == Gtk::RESPONSE_NONE) {
1880 /* Clear was pressed */
1881 new_session_dialog->reset();
1883 } else if (response == Gtk::RESPONSE_YES) {
1885 /* YES == OPEN, but there's no enum for that */
1887 session_name = new_session_dialog->session_name();
1889 if (session_name.empty()) {
1890 response = Gtk::RESPONSE_NONE;
1894 if (session_name[0] == '/' ||
1895 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1896 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1897 load_session (Glib::path_get_dirname (session_name), session_name);
1899 session_path = new_session_dialog->session_folder();
1900 load_session (session_path, session_name);
1903 } else if (response == Gtk::RESPONSE_OK) {
1905 session_name = new_session_dialog->session_name();
1907 if (!new_session_dialog->on_new_session_page ()) {
1909 /* XXX this is a bit of a hack..
1910 i really want the new sesion dialog to return RESPONSE_YES
1911 if we're on page 1 (the load page)
1912 Unfortunately i can't see how atm..
1915 if (session_name.empty()) {
1916 response = Gtk::RESPONSE_NONE;
1920 if (session_name[0] == '/' ||
1921 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1922 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1923 load_session (Glib::path_get_dirname (session_name), session_name);
1925 session_path = new_session_dialog->session_folder();
1926 load_session (session_path, session_name);
1931 if (session_name.empty()) {
1932 response = Gtk::RESPONSE_NONE;
1936 if (session_name[0] == '/' ||
1937 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1938 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1940 session_path = Glib::path_get_dirname (session_name);
1941 session_name = Glib::path_get_basename (session_name);
1945 session_path = new_session_dialog->session_folder();
1949 //XXX This is needed because session constructor wants a
1950 //non-existant path. hopefully this will be fixed at some point.
1952 session_path = Glib::build_filename (session_path, session_name);
1954 if (g_file_test (session_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
1956 Glib::ustring str = string_compose (_("This session\n%1\nalready exists. Do you want to open it?"), session_path);
1958 MessageDialog msg (str,
1960 Gtk::MESSAGE_WARNING,
1961 Gtk::BUTTONS_YES_NO,
1965 msg.set_name (X_("CleanupDialog"));
1966 msg.set_wmclass (X_("existing_session"), "Ardour");
1967 msg.set_position (Gtk::WIN_POS_MOUSE);
1969 switch (msg.run()) {
1971 load_session (session_path, session_name);
1975 response = RESPONSE_NONE;
1976 new_session_dialog->reset ();
1981 _session_is_new = true;
1983 std::string template_name = new_session_dialog->session_template_name();
1985 if (new_session_dialog->use_session_template()) {
1987 load_session (session_path, session_name, &template_name);
1993 AutoConnectOption iconnect;
1994 AutoConnectOption oconnect;
1996 if (new_session_dialog->create_control_bus()) {
1997 cchns = (uint32_t) new_session_dialog->control_channel_count();
2002 if (new_session_dialog->create_master_bus()) {
2003 mchns = (uint32_t) new_session_dialog->master_channel_count();
2008 if (new_session_dialog->connect_inputs()) {
2009 iconnect = AutoConnectPhysical;
2011 iconnect = AutoConnectOption (0);
2014 /// @todo some minor tweaks.
2016 if (new_session_dialog->connect_outs_to_master()) {
2017 oconnect = AutoConnectMaster;
2018 } else if (new_session_dialog->connect_outs_to_physical()) {
2019 oconnect = AutoConnectPhysical;
2021 oconnect = AutoConnectOption (0);
2024 uint32_t nphysin = (uint32_t) new_session_dialog->input_limit_count();
2025 uint32_t nphysout = (uint32_t) new_session_dialog->output_limit_count();
2027 if (!build_session (session_path,
2035 engine->frame_rate() * 60 * 5)) {
2037 response = Gtk::RESPONSE_NONE;
2038 new_session_dialog->reset ();
2045 } while (response == Gtk::RESPONSE_NONE);
2049 new_session_dialog->get_window()->set_cursor();
2050 new_session_dialog->hide();
2055 ARDOUR_UI::close_session()
2057 if (!check_audioengine()) {
2066 ARDOUR_UI::load_session (const string & path, const string & snap_name, string* mix_template)
2068 Session *new_session;
2069 session_loaded = false;
2071 if (!check_audioengine()) {
2075 if(!unload_session ()) return -1;
2077 /* if it already exists, we must have write access */
2079 if (::access (path.c_str(), F_OK) == 0 && ::access (path.c_str(), W_OK)) {
2080 MessageDialog msg (*editor, _("You do not have write access to this session.\n"
2081 "This prevents the session from being loaded."));
2087 new_session = new Session (*engine, path, snap_name, mix_template);
2092 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
2096 connect_to_session (new_session);
2098 Config->set_current_owner (ConfigVariableBase::Interface);
2100 session_loaded = true;
2102 goto_editor_window ();
2105 session->set_clean ();
2108 editor->edit_cursor_position (true);
2113 ARDOUR_UI::build_session (const string & path, const string & snap_name,
2114 uint32_t control_channels,
2115 uint32_t master_channels,
2116 AutoConnectOption input_connect,
2117 AutoConnectOption output_connect,
2120 nframes_t initial_length)
2122 Session *new_session;
2124 if (!check_audioengine()) {
2128 session_loaded = false;
2130 if (!unload_session ()) return false;
2132 _session_is_new = true;
2135 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
2136 control_channels, master_channels, nphysin, nphysout, initial_length);
2141 MessageDialog msg (string_compose(_("Could not create session in \"%1\""), path));
2146 connect_to_session (new_session);
2148 session_loaded = true;
2156 editor->show_window ();
2167 ARDOUR_UI::show_splash ()
2170 about = new About();
2171 about->signal_response().connect(mem_fun (*this, &ARDOUR_UI::about_signal_response) );
2178 ARDOUR_UI::about_signal_response(int response)
2184 ARDOUR_UI::hide_splash ()
2187 about->get_window()->set_cursor ();
2193 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title, const string & msg)
2197 removed = rep.paths.size();
2200 MessageDialog msgd (*editor,
2201 _("No audio files were ready for cleanup"),
2204 (Gtk::ButtonsType)(Gtk::BUTTONS_OK) );
2205 msgd.set_secondary_text (_("If this seems suprising, \n\
2206 check for any existing snapshots.\n\
2207 These may still include regions that\n\
2208 require some unused files to continue to exist."));
2214 ArdourDialog results (_("ardour: cleanup"), true, false);
2216 struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
2217 CleanupResultsModelColumns() {
2221 Gtk::TreeModelColumn<Glib::ustring> visible_name;
2222 Gtk::TreeModelColumn<Glib::ustring> fullpath;
2226 CleanupResultsModelColumns results_columns;
2227 Glib::RefPtr<Gtk::ListStore> results_model;
2228 Gtk::TreeView results_display;
2230 results_model = ListStore::create (results_columns);
2231 results_display.set_model (results_model);
2232 results_display.append_column (list_title, results_columns.visible_name);
2234 results_display.set_name ("CleanupResultsList");
2235 results_display.set_headers_visible (true);
2236 results_display.set_headers_clickable (false);
2237 results_display.set_reorderable (false);
2239 Gtk::ScrolledWindow list_scroller;
2242 Gtk::HBox dhbox; // the hbox for the image and text
2243 Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
2244 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO, Gtk::ICON_SIZE_DIALOG));
2246 dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
2248 const string dead_sound_directory = session->session_directory().dead_sound_path().to_string();
2250 if (rep.space < 1048576.0f) {
2252 txt.set_text (string_compose (msg, removed, _("files were"), dead_sound_directory, (float) rep.space / 1024.0f, "kilo"));
2254 txt.set_text (string_compose (msg, removed, _("file was"), dead_sound_directory, (float) rep.space / 1024.0f, "kilo"));
2258 txt.set_text (string_compose (msg, removed, _("files were"), dead_sound_directory, (float) rep.space / 1048576.0f, "mega"));
2260 txt.set_text (string_compose (msg, removed, _("file was"), dead_sound_directory, (float) rep.space / 1048576.0f, "mega"));
2264 dhbox.pack_start (*dimage, true, false, 5);
2265 dhbox.pack_start (txt, true, false, 5);
2267 for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2268 TreeModel::Row row = *(results_model->append());
2269 row[results_columns.visible_name] = *i;
2270 row[results_columns.fullpath] = *i;
2273 list_scroller.add (results_display);
2274 list_scroller.set_size_request (-1, 150);
2275 list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2277 dvbox.pack_start (dhbox, true, false, 5);
2278 dvbox.pack_start (list_scroller, true, false, 5);
2279 ddhbox.pack_start (dvbox, true, false, 5);
2281 results.get_vbox()->pack_start (ddhbox, true, false, 5);
2282 results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
2283 results.set_default_response (RESPONSE_CLOSE);
2284 results.set_position (Gtk::WIN_POS_MOUSE);
2285 results.show_all_children ();
2286 results.set_resizable (false);
2293 ARDOUR_UI::cleanup ()
2296 /* shouldn't happen: menu item is insensitive */
2301 MessageDialog checker (_("Are you sure you want to cleanup?"),
2303 Gtk::MESSAGE_QUESTION,
2304 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
2306 checker.set_secondary_text(_("Cleanup is a destructive operation.\n\
2307 ALL undo/redo information will be lost if you cleanup.\n\
2308 After cleanup, unused audio files will be moved to a \
2309 \"dead sounds\" location."));
2311 checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2312 checker.add_button (_("Clean Up"), RESPONSE_ACCEPT);
2313 checker.set_default_response (RESPONSE_CANCEL);
2315 checker.set_name (_("CleanupDialog"));
2316 checker.set_wmclass (X_("ardour_cleanup"), "Ardour");
2317 checker.set_position (Gtk::WIN_POS_MOUSE);
2319 switch (checker.run()) {
2320 case RESPONSE_ACCEPT:
2326 Session::cleanup_report rep;
2328 editor->prepare_for_cleanup ();
2330 /* do not allow flush until a session is reloaded */
2332 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
2334 act->set_sensitive (false);
2337 if (session->cleanup_sources (rep)) {
2342 display_cleanup_results (rep,
2345 The following %1 %2 not in use and \n\
2346 have been moved to:\n\
2348 Flushing the wastebasket will \n\
2349 release an additional\n\
2350 %4 %5bytes of disk space.\n"
2358 ARDOUR_UI::flush_trash ()
2361 /* shouldn't happen: menu item is insensitive */
2365 Session::cleanup_report rep;
2367 if (session->cleanup_trash_sources (rep)) {
2371 display_cleanup_results (rep,
2373 _("The following %1 %2 deleted from\n\
2375 releasing %4 %5bytes of disk space"));
2379 ARDOUR_UI::add_route (Gtk::Window* float_window)
2387 if (add_route_dialog == 0) {
2388 add_route_dialog = new AddRouteDialog;
2390 add_route_dialog->set_transient_for (*float_window);
2394 if (add_route_dialog->is_visible()) {
2395 /* we're already doing this */
2399 ResponseType r = (ResponseType) add_route_dialog->run ();
2401 add_route_dialog->hide();
2404 case RESPONSE_ACCEPT:
2411 if ((count = add_route_dialog->count()) <= 0) {
2415 uint32_t input_chan = add_route_dialog->channels ();
2416 uint32_t output_chan;
2417 string name_template = add_route_dialog->name_template ();
2418 bool track = add_route_dialog->track ();
2420 AutoConnectOption oac = Config->get_output_auto_connect();
2422 if (oac & AutoConnectMaster) {
2423 output_chan = (session->master_out() ? session->master_out()->n_inputs().n_audio() : input_chan);
2425 output_chan = input_chan;
2428 /* XXX do something with name template */
2430 if (add_route_dialog->type() == ARDOUR::DataType::MIDI) {
2432 session_add_midi_track(count);
2434 MessageDialog msg (*editor,
2435 _("Sorry, MIDI Busses are not supported at this time."));
2437 //session_add_midi_bus();
2441 session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), count);
2443 session_add_audio_bus (input_chan, output_chan, count);
2449 ARDOUR_UI::mixer_settings () const
2454 node = session->instant_xml(X_("Mixer"));
2456 node = Config->instant_xml(X_("Mixer"));
2460 node = new XMLNode (X_("Mixer"));
2467 ARDOUR_UI::editor_settings () const
2472 node = session->instant_xml(X_("Editor"));
2474 node = Config->instant_xml(X_("Editor"));
2478 node = new XMLNode (X_("Editor"));
2484 ARDOUR_UI::keyboard_settings () const
2488 node = Config->extra_xml(X_("Keyboard"));
2491 node = new XMLNode (X_("Keyboard"));
2497 ARDOUR_UI::halt_on_xrun_message ()
2499 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
2501 MessageDialog msg (*editor,
2502 _("Recording was stopped because your system could not keep up."));
2507 ARDOUR_UI::disk_overrun_handler ()
2509 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
2511 if (!have_disk_speed_dialog_displayed) {
2512 have_disk_speed_dialog_displayed = true;
2513 MessageDialog* msg = new MessageDialog (*editor, _("\
2514 The disk system on your computer\n\
2515 was not able to keep up with Ardour.\n\
2517 Specifically, it failed to write data to disk\n\
2518 quickly enough to keep up with recording.\n"));
2519 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
2525 ARDOUR_UI::disk_underrun_handler ()
2527 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2529 if (!have_disk_speed_dialog_displayed) {
2530 have_disk_speed_dialog_displayed = true;
2531 MessageDialog* msg = new MessageDialog (*editor,
2532 _("The disk system on your computer\n\
2533 was not able to keep up with Ardour.\n\
2535 Specifically, it failed to read data from disk\n\
2536 quickly enough to keep up with playback.\n"));
2537 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
2543 ARDOUR_UI::disk_speed_dialog_gone (int ignored_response, MessageDialog* msg)
2545 have_disk_speed_dialog_displayed = false;
2550 ARDOUR_UI::pending_state_dialog ()
2552 ArdourDialog dialog ("pending state dialog");
2554 This session appears to have been in\n\
2555 middle of recording when ardour or\n\
2556 the computer was shutdown.\n\
2558 Ardour can recover any captured audio for\n\
2559 you, or it can ignore it. Please decide\n\
2560 what you would like to do.\n"));
2562 dialog.get_vbox()->pack_start (message);
2563 dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
2564 dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
2566 dialog.set_position (WIN_POS_CENTER);
2569 switch (dialog.run ()) {
2570 case RESPONSE_ACCEPT:
2578 ARDOUR_UI::disconnect_from_jack ()
2581 if( engine->disconnect_from_jack ()) {
2582 MessageDialog msg (*editor, _("Could not disconnect from JACK"));
2586 update_sample_rate (0);
2591 ARDOUR_UI::reconnect_to_jack ()
2594 if (engine->reconnect_to_jack ()) {
2595 MessageDialog msg (*editor, _("Could not reconnect to JACK"));
2599 update_sample_rate (0);
2604 ARDOUR_UI::cmdline_new_session (string path)
2606 if (path[0] != '/') {
2607 char buf[PATH_MAX+1];
2610 getcwd (buf, sizeof (buf));
2619 return FALSE; /* don't call it again */
2623 ARDOUR_UI::use_config ()
2625 Glib::RefPtr<Action> act;
2627 switch (Config->get_native_file_data_format ()) {
2629 act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
2632 act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
2637 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2638 ract->set_active ();
2641 switch (Config->get_native_file_header_format ()) {
2643 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
2646 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
2649 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
2652 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
2655 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
2658 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatCAF"));
2661 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatAIFF"));
2666 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2667 ract->set_active ();
2670 XMLNode* node = Config->extra_xml (X_("TransportControllables"));
2672 set_transport_controllable_state (*node);
2677 ARDOUR_UI::update_transport_clocks (nframes_t pos)
2679 if (Config->get_primary_clock_delta_edit_cursor()) {
2680 primary_clock.set (pos, false, editor->edit_cursor_position(false), 'p');
2682 primary_clock.set (pos, 0, true);
2685 if (Config->get_secondary_clock_delta_edit_cursor()) {
2686 secondary_clock.set (pos, false, editor->edit_cursor_position(false), 's');
2688 secondary_clock.set (pos);
2691 if (big_clock_window) {
2692 big_clock.set (pos);
2697 ARDOUR_UI::record_state_changed ()
2699 ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::record_state_changed));
2701 if (!session || !big_clock_window) {
2702 /* why bother - the clock isn't visible */
2706 switch (session->record_status()) {
2707 case Session::Recording:
2708 big_clock.set_widget_name ("BigClockRecording");
2711 big_clock.set_widget_name ("BigClockNonRecording");
2717 ARDOUR_UI::set_keybindings_path (string path)
2719 keybindings_path = path;
2723 ARDOUR_UI::save_keybindings ()
2725 if (can_save_keybindings) {
2726 AccelMap::save (keybindings_path);
2731 ARDOUR_UI::first_idle ()
2734 session->allow_auto_play (true);
2736 can_save_keybindings = true;
2741 ARDOUR_UI::store_clock_modes ()
2743 XMLNode* node = new XMLNode(X_("ClockModes"));
2745 for (vector<AudioClock*>::iterator x = AudioClock::clocks.begin(); x != AudioClock::clocks.end(); ++x) {
2746 node->add_property ((*x)->name().c_str(), enum_2_string ((*x)->mode()));
2749 session->add_extra_xml (*node);
2750 session->set_dirty ();
2755 ARDOUR_UI::TransportControllable::TransportControllable (std::string name, ARDOUR_UI& u, ToggleType tp)
2756 : Controllable (name), ui (u), type(tp)
2762 ARDOUR_UI::TransportControllable::set_value (float val)
2764 if (type == ShuttleControl) {
2771 fract = -((0.5f - val)/0.5f);
2773 fract = ((val - 0.5f)/0.5f);
2777 ui.set_shuttle_fract (fract);
2782 /* do nothing: these are radio-style actions */
2790 action = X_("Roll");
2793 action = X_("Stop");
2796 action = X_("Goto Start");
2799 action = X_("Goto End");
2802 action = X_("Loop");
2805 action = X_("Play Selection");
2808 action = X_("Record");
2818 Glib::RefPtr<Action> act = ActionManager::get_action ("Transport", action);
2826 ARDOUR_UI::TransportControllable::get_value (void) const
2845 case ShuttleControl:
2855 ARDOUR_UI::TransportControllable::set_id (const string& str)
2861 ARDOUR_UI::setup_profile ()
2863 if (gdk_screen_width() < 1200) {
2864 Profile->set_small_screen ();
2869 ARDOUR_UI::disable_all_plugins ()
2875 // session->begin_reversible_command (_("Disable all plugins"));
2877 boost::shared_ptr<Session::RouteList> routes = session->get_routes ();
2879 for (Session::RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
2880 // XMLNode& before = (*i)->get_redirect_state ();
2881 // session->add_command (new MementoCommand<Route>(**i, &before, 0));
2882 (*i)->disable_plugins ();
2883 // XMLNode& after = (*i)->get_redirect_state ();
2884 // session->add_command (new MementoCommand<Route>(**i, 0, &after));
2888 // session->commit_reversible_command ();
2892 ARDOUR_UI::ab_all_plugins ()
2898 boost::shared_ptr<Session::RouteList> routes = session->get_routes ();
2900 for (Session::RouteList::iterator i = routes->begin(); i != routes->end(); ++i) {
2901 (*i)->ab_plugins (ab_direction);
2904 ab_direction = !ab_direction;