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/port.h>
57 #include <ardour/audioengine.h>
58 #include <ardour/playlist.h>
59 #include <ardour/utils.h>
60 #include <ardour/audio_diskstream.h>
61 #include <ardour/audiofilesource.h>
62 #include <ardour/recent_sessions.h>
63 #include <ardour/session_route.h>
64 #include <ardour/port.h>
65 #include <ardour/audio_track.h>
66 #include <ardour/midi_track.h>
69 #include "ardour_ui.h"
70 #include "public_editor.h"
71 #include "audio_clock.h"
76 #include "add_route_dialog.h"
77 #include "new_session_dialog.h"
80 #include "gui_thread.h"
81 #include "color_manager.h"
85 using namespace ARDOUR;
87 using namespace Gtkmm2ext;
91 ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
93 sigc::signal<void,bool> ARDOUR_UI::Blink;
94 sigc::signal<void> ARDOUR_UI::RapidScreenUpdate;
95 sigc::signal<void> ARDOUR_UI::MidRapidScreenUpdate;
96 sigc::signal<void> ARDOUR_UI::SuperRapidScreenUpdate;
97 sigc::signal<void,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;
194 Glib::signal_idle().connect (mem_fun (*this, &ARDOUR_UI::first_idle));
196 last_configure_time.tv_sec = 0;
197 last_configure_time.tv_usec = 0;
199 shuttle_grabbed = false;
201 shuttle_max_speed = 8.0f;
203 shuttle_style_menu = 0;
204 shuttle_unit_menu = 0;
206 gettimeofday (&last_peak_grab, 0);
207 gettimeofday (&last_shuttle_request, 0);
209 ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
210 ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
212 /* handle pending state with a dialog */
214 ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
216 /* have to wait for AudioEngine and Configuration before proceeding */
220 ARDOUR_UI::set_engine (AudioEngine& e)
224 engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
225 engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
226 engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
227 engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
229 ActionManager::init ();
230 new_session_dialog = new NewSessionDialog();
234 keyboard = new Keyboard;
236 if (setup_windows ()) {
237 throw failed_constructor ();
240 if (GTK_ARDOUR::show_key_actions) {
241 vector<string> names;
242 vector<string> paths;
244 vector<AccelKey> bindings;
246 ActionManager::get_all_actions (names, paths, keys, bindings);
248 vector<string>::iterator n;
249 vector<string>::iterator k;
250 for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) {
251 cerr << "Action: " << (*n) << " bound to " << (*k) << endl;
257 /* start with timecode, metering enabled
260 blink_timeout_tag = -1;
262 /* the global configuration object is now valid */
266 /* this being a GUI and all, we want peakfiles */
268 AudioFileSource::set_build_peakfiles (true);
269 AudioFileSource::set_build_missing_peakfiles (true);
271 /* set default clock modes */
273 primary_clock.set_mode (AudioClock::SMPTE);
274 secondary_clock.set_mode (AudioClock::BBT);
276 /* start the time-of-day-clock */
278 update_wall_clock ();
279 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
281 update_disk_space ();
283 update_sample_rate (engine->frame_rate());
285 starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
286 stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
289 ARDOUR_UI::~ARDOUR_UI ()
291 save_ardour_state ();
305 if (add_route_dialog) {
306 delete add_route_dialog;
311 ARDOUR_UI::configure_timeout ()
316 if (last_configure_time.tv_sec == 0 && last_configure_time.tv_usec == 0) {
317 /* no configure events yet */
321 gettimeofday (&now, 0);
322 timersub (&now, &last_configure_time, &diff);
324 /* force a gap of 0.5 seconds since the last configure event
327 if (diff.tv_sec == 0 && diff.tv_usec < 500000) {
330 have_configure_timeout = false;
331 save_ardour_state ();
337 ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
339 if (have_configure_timeout) {
340 gettimeofday (&last_configure_time, 0);
342 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
343 have_configure_timeout = true;
350 ARDOUR_UI::set_transport_controllable_state (const XMLNode& node)
352 const XMLProperty* prop;
354 if ((prop = node.property ("roll")) != 0) {
355 roll_controllable.set_id (prop->value());
357 if ((prop = node.property ("stop")) != 0) {
358 stop_controllable.set_id (prop->value());
360 if ((prop = node.property ("goto_start")) != 0) {
361 goto_start_controllable.set_id (prop->value());
363 if ((prop = node.property ("goto_end")) != 0) {
364 goto_end_controllable.set_id (prop->value());
366 if ((prop = node.property ("auto_loop")) != 0) {
367 auto_loop_controllable.set_id (prop->value());
369 if ((prop = node.property ("play_selection")) != 0) {
370 play_selection_controllable.set_id (prop->value());
372 if ((prop = node.property ("rec")) != 0) {
373 rec_controllable.set_id (prop->value());
375 if ((prop = node.property ("shuttle")) != 0) {
376 shuttle_controllable.set_id (prop->value());
381 ARDOUR_UI::get_transport_controllable_state ()
383 XMLNode* node = new XMLNode(X_("TransportControllables"));
386 roll_controllable.id().print (buf, sizeof (buf));
387 node->add_property (X_("roll"), buf);
388 stop_controllable.id().print (buf, sizeof (buf));
389 node->add_property (X_("stop"), buf);
390 goto_start_controllable.id().print (buf, sizeof (buf));
391 node->add_property (X_("goto_start"), buf);
392 goto_end_controllable.id().print (buf, sizeof (buf));
393 node->add_property (X_("goto_end"), buf);
394 auto_loop_controllable.id().print (buf, sizeof (buf));
395 node->add_property (X_("auto_loop"), buf);
396 play_selection_controllable.id().print (buf, sizeof (buf));
397 node->add_property (X_("play_selection"), buf);
398 rec_controllable.id().print (buf, sizeof (buf));
399 node->add_property (X_("rec"), buf);
400 shuttle_controllable.id().print (buf, sizeof (buf));
401 node->add_property (X_("shuttle"), buf);
407 ARDOUR_UI::save_ardour_state ()
409 if (!keyboard || !mixer || !editor) {
413 /* XXX this is all a bit dubious. add_extra_xml() uses
414 a different lifetime model from add_instant_xml().
417 XMLNode* node = new XMLNode (keyboard->get_state());
418 Config->add_extra_xml (*node);
419 Config->add_extra_xml (get_transport_controllable_state());
420 Config->save_state();
422 XMLNode enode(static_cast<Stateful*>(editor)->get_state());
423 XMLNode mnode(mixer->get_state());
426 session->add_instant_xml (enode, session->path());
427 session->add_instant_xml (mnode, session->path());
429 Config->add_instant_xml (enode, get_user_ardour_path());
430 Config->add_instant_xml (mnode, get_user_ardour_path());
437 ARDOUR_UI::startup ()
439 check_memory_locking();
443 ARDOUR_UI::no_memory_warning ()
445 XMLNode node (X_("no-memory-warning"));
446 Config->add_instant_xml (node, get_user_ardour_path());
450 ARDOUR_UI::check_memory_locking ()
453 /* OS X doesn't support mlockall(2), and so testing for memory locking capability there is pointless */
457 XMLNode* memory_warning_node = Config->instant_xml (X_("no-memory-warning"), get_user_ardour_path());
459 if (engine->is_realtime() && memory_warning_node == 0) {
461 struct rlimit limits;
463 long pages, page_size;
465 if ((page_size = sysconf (_SC_PAGESIZE)) < 0 ||(pages = sysconf (_SC_PHYS_PAGES)) < 0) {
468 ram = (int64_t) pages * (int64_t) page_size;
471 if (getrlimit (RLIMIT_MEMLOCK, &limits)) {
475 if (limits.rlim_cur != RLIM_INFINITY) {
477 if (ram == 0 || ((double) limits.rlim_cur / ram) < 0.75) {
480 MessageDialog msg (_("WARNING: Your system has a limit for maximum amount of locked memory. "
481 "This might cause Ardour to run out of memory before your system "
482 "runs out of memory. \n\n"
483 "You can view the memory limit with 'ulimit -l', "
484 "and it is normally controlled by /etc/security/limits.conf"));
486 VBox* vbox = msg.get_vbox();
488 CheckButton cb (_("Do not show this window again"));
490 cb.signal_toggled().connect (mem_fun (*this, &ARDOUR_UI::no_memory_warning));
492 hbox.pack_start (cb, true, false);
493 vbox->pack_start (hbox);
496 editor->ensure_float (msg);
508 if (session && session->dirty()) {
509 switch (ask_about_saving_session(_("quit"))) {
514 /* use the default name */
515 if (save_state_canfail ("")) {
516 /* failed - don't quit */
517 MessageDialog msg (*editor,
519 Ardour was unable to save your session.\n\n\
520 If you still wish to quit, please use the\n\n\
521 \"Just quit\" option."));
532 session->set_deletion_in_progress ();
535 Config->save_state();
540 ARDOUR_UI::ask_about_saving_session (const string & what)
542 ArdourDialog window (_("ardour: save session?"));
543 Gtk::HBox dhbox; // the hbox for the image and text
544 Gtk::Label prompt_label;
545 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_WARNING, Gtk::ICON_SIZE_DIALOG));
549 msg = string_compose(_("Don't %1"), what);
550 window.add_button (msg, RESPONSE_REJECT);
551 msg = string_compose(_("Just %1"), what);
552 window.add_button (msg, RESPONSE_APPLY);
553 msg = string_compose(_("Save and %1"), what);
554 window.add_button (msg, RESPONSE_ACCEPT);
556 window.set_default_response (RESPONSE_ACCEPT);
558 Gtk::Button noquit_button (msg);
559 noquit_button.set_name ("EditorGTKButton");
564 if (session->snap_name() == session->name()) {
567 type = _("snapshot");
569 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?"),
570 type, session->snap_name());
572 prompt_label.set_text (prompt);
573 prompt_label.set_name (X_("PrompterLabel"));
574 prompt_label.set_alignment(ALIGN_LEFT, ALIGN_TOP);
576 dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP)
578 dhbox.set_homogeneous (false);
579 dhbox.pack_start (*dimage, false, false, 5);
580 dhbox.pack_start (prompt_label, true, false, 5);
581 window.get_vbox()->pack_start (dhbox);
583 window.set_name (_("Prompter"));
584 window.set_position (Gtk::WIN_POS_MOUSE);
585 window.set_modal (true);
586 window.set_resizable (false);
589 save_the_session = 0;
591 window.set_keep_above (true);
594 ResponseType r = (ResponseType) window.run();
599 case RESPONSE_ACCEPT: // save and get out of here
601 case RESPONSE_APPLY: // get out of here
611 ARDOUR_UI::every_second ()
614 update_buffer_load ();
615 update_disk_space ();
620 ARDOUR_UI::every_point_one_seconds ()
622 update_speed_display ();
623 RapidScreenUpdate(); /* EMIT_SIGNAL */
628 ARDOUR_UI::every_point_oh_five_seconds ()
630 MidRapidScreenUpdate(); /* EMIT_SIGNAL */
635 ARDOUR_UI::every_point_zero_one_seconds ()
637 SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
642 ARDOUR_UI::update_sample_rate (nframes_t ignored)
646 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
648 if (!engine->connected()) {
650 snprintf (buf, sizeof (buf), _("disconnected"));
654 nframes_t rate = engine->frame_rate();
656 if (fmod (rate, 1000.0) != 0.0) {
657 snprintf (buf, sizeof (buf), _("%.1f kHz / %4.1f msecs"),
658 (float) rate/1000.0f,
659 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
661 snprintf (buf, sizeof (buf), _("%u kHz / %4.1f msecs"),
663 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
667 sample_rate_label.set_text (buf);
671 ARDOUR_UI::update_cpu_load ()
674 snprintf (buf, sizeof (buf), _("DSP: %.1f%%"), engine->get_cpu_load());
675 cpu_load_label.set_text (buf);
679 ARDOUR_UI::update_buffer_load ()
684 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"),
685 session->playback_load(), session->capture_load());
686 buffer_load_label.set_text (buf);
688 buffer_load_label.set_text ("");
693 ARDOUR_UI::count_recenabled_streams (Route& route)
695 Track* track = dynamic_cast<Track*>(&route);
696 if (track && track->diskstream()->record_enabled()) {
697 rec_enabled_streams += track->n_inputs().get_total();
702 ARDOUR_UI::update_disk_space()
708 nframes_t frames = session->available_capture_duration();
711 if (frames == max_frames) {
712 strcpy (buf, _("Disk: 24hrs+"));
717 nframes_t fr = session->frame_rate();
719 rec_enabled_streams = 0;
720 session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
722 if (rec_enabled_streams) {
723 frames /= rec_enabled_streams;
726 hrs = frames / (fr * 3600);
727 frames -= hrs * fr * 3600;
728 mins = frames / (fr * 60);
729 frames -= mins * fr * 60;
732 snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs);
735 disk_space_label.set_text (buf);
739 ARDOUR_UI::update_wall_clock ()
746 tm_now = localtime (&now);
748 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
749 wall_clock_label.set_text (buf);
755 ARDOUR_UI::session_menu (GdkEventButton *ev)
757 session_popup_menu->popup (0, 0);
762 ARDOUR_UI::redisplay_recent_sessions ()
764 vector<string *> *sessions;
765 vector<string *>::iterator i;
766 RecentSessionsSorter cmp;
768 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
769 recent_session_model->clear ();
772 ARDOUR::read_recent_sessions (rs);
775 recent_session_display.set_model (recent_session_model);
779 /* sort them alphabetically */
780 sort (rs.begin(), rs.end(), cmp);
781 sessions = new vector<string*>;
783 for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
784 sessions->push_back (new string ((*i).second));
787 for (i = sessions->begin(); i != sessions->end(); ++i) {
789 vector<string*>* states;
790 vector<const gchar*> item;
791 string fullpath = *(*i);
793 /* remove any trailing / */
795 if (fullpath[fullpath.length()-1] == '/') {
796 fullpath = fullpath.substr (0, fullpath.length()-1);
799 /* now get available states for this session */
801 if ((states = Session::possible_states (fullpath)) == 0) {
806 TreeModel::Row row = *(recent_session_model->append());
808 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
809 row[recent_session_columns.fullpath] = fullpath;
811 if (states->size() > 1) {
813 /* add the children */
815 for (vector<string*>::iterator i2 = states->begin(); i2 != states->end(); ++i2) {
817 TreeModel::Row child_row = *(recent_session_model->append (row.children()));
819 child_row[recent_session_columns.visible_name] = **i2;
820 child_row[recent_session_columns.fullpath] = fullpath;
829 recent_session_display.set_model (recent_session_model);
834 ARDOUR_UI::build_session_selector ()
836 session_selector_window = new ArdourDialog ("session selector");
838 Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
840 session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
841 session_selector_window->add_button (Stock::OPEN, RESPONSE_ACCEPT);
842 session_selector_window->set_default_response (RESPONSE_ACCEPT);
843 recent_session_model = TreeStore::create (recent_session_columns);
844 recent_session_display.set_model (recent_session_model);
845 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
846 recent_session_display.set_headers_visible (false);
847 recent_session_display.get_selection()->set_mode (SELECTION_SINGLE);
849 recent_session_display.signal_row_activated().connect (mem_fun (*this, &ARDOUR_UI::recent_session_row_activated));
851 scroller->add (recent_session_display);
852 scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
854 session_selector_window->set_name ("SessionSelectorWindow");
855 session_selector_window->set_size_request (200, 400);
856 session_selector_window->get_vbox()->pack_start (*scroller);
857 session_selector_window->show_all_children();
861 ARDOUR_UI::recent_session_row_activated (const TreePath& path, TreeViewColumn* col)
863 session_selector_window->response (RESPONSE_ACCEPT);
867 ARDOUR_UI::open_recent_session ()
869 /* popup selector window */
871 if (session_selector_window == 0) {
872 build_session_selector ();
875 redisplay_recent_sessions ();
877 ResponseType r = (ResponseType) session_selector_window->run ();
879 session_selector_window->hide();
882 case RESPONSE_ACCEPT:
888 Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
890 if (i == recent_session_model->children().end()) {
894 Glib::ustring path = (*i)[recent_session_columns.fullpath];
895 Glib::ustring state = (*i)[recent_session_columns.visible_name];
897 _session_is_new = false;
899 load_session (path, state);
903 ARDOUR_UI::filter_ardour_session_dirs (const FileFilter::Info& info)
907 if (stat (info.filename.c_str(), &statbuf) != 0) {
911 if (!S_ISDIR(statbuf.st_mode)) {
917 string session_file = info.filename;
919 session_file += Glib::path_get_basename (info.filename);
920 session_file += ".ardour";
922 if (stat (session_file.c_str(), &statbuf) != 0) {
926 return S_ISREG (statbuf.st_mode);
930 ARDOUR_UI::open_session ()
932 /* popup selector window */
934 if (open_session_selector == 0) {
936 /* ardour sessions are folders */
938 open_session_selector = new Gtk::FileChooserDialog (_("open session"), FILE_CHOOSER_ACTION_OPEN);
939 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
940 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
942 FileFilter session_filter;
943 session_filter.add_pattern ("*.ardour");
944 session_filter.set_name (_("Ardour sessions"));
945 open_session_selector->add_filter (session_filter);
946 open_session_selector->set_filter (session_filter);
949 int response = open_session_selector->run();
950 open_session_selector->hide ();
953 case RESPONSE_ACCEPT:
956 open_session_selector->hide();
960 open_session_selector->hide();
961 string session_path = open_session_selector->get_filename();
965 if (session_path.length() > 0) {
966 if (Session::find_session (session_path, path, name, isnew) == 0) {
967 _session_is_new = isnew;
968 load_session (path, name);
975 ARDOUR_UI::session_add_midi_route (bool disk, uint32_t how_many)
977 list<boost::shared_ptr<MidiTrack> > tracks;
980 warning << _("You cannot add a track without a session already loaded.") << endmsg;
987 tracks = session->new_midi_track (ARDOUR::Normal, how_many);
989 if (tracks.size() != how_many) {
991 error << _("could not create a new midi track") << endmsg;
993 error << string_compose (_("could not create %1 new midi tracks"), how_many) << endmsg;
997 if ((route = session->new_midi_route ()) == 0) {
998 error << _("could not create new midi bus") << endmsg;
1004 MessageDialog msg (*editor,
1005 _("There are insufficient JACK ports available\n\
1006 to create a new track or bus.\n\
1007 You should save Ardour, exit and\n\
1008 restart JACK with more ports."));
1015 ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, uint32_t how_many)
1017 list<boost::shared_ptr<AudioTrack> > tracks;
1018 Session::RouteList routes;
1021 warning << _("You cannot add a track or bus without a session already loaded.") << endmsg;
1027 tracks = session->new_audio_track (input_channels, output_channels, mode, how_many);
1029 if (tracks.size() != how_many) {
1030 if (how_many == 1) {
1031 error << _("could not create a new audio track") << endmsg;
1033 error << string_compose (_("could only create %1 of %2 new audio %3"),
1034 tracks.size(), how_many, (track ? _("tracks") : _("busses"))) << endmsg;
1040 routes = session->new_audio_route (input_channels, output_channels, how_many);
1042 if (routes.size() != how_many) {
1043 if (how_many == 1) {
1044 error << _("could not create a new audio track") << endmsg;
1046 error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
1052 if (need_control_room_outs) {
1058 route->set_stereo_control_outs (control_lr_channels);
1059 route->control_outs()->set_stereo_pan (pans, this);
1061 #endif /* CONTROLOUTS */
1065 cerr << "About to complain about JACK\n";
1066 MessageDialog msg (*editor,
1067 _("There are insufficient JACK ports available\n\
1068 to create a new track or bus.\n\
1069 You should save Ardour, exit and\n\
1070 restart JACK with more ports."));
1076 ARDOUR_UI::do_transport_locate (nframes_t new_position)
1078 nframes_t _preroll = 0;
1081 // XXX CONFIG_CHANGE FIX - requires AnyTime handling
1082 // _preroll = session->convert_to_frames_at (new_position, Config->get_preroll());
1084 if (new_position > _preroll) {
1085 new_position -= _preroll;
1090 session->request_locate (new_position);
1095 ARDOUR_UI::transport_goto_start ()
1098 session->goto_start();
1101 /* force displayed area in editor to start no matter
1102 what "follow playhead" setting is.
1106 editor->reset_x_origin (session->current_start_frame());
1112 ARDOUR_UI::transport_goto_zero ()
1115 session->request_locate (0);
1118 /* force displayed area in editor to start no matter
1119 what "follow playhead" setting is.
1123 editor->reset_x_origin (0);
1129 ARDOUR_UI::transport_goto_end ()
1132 nframes_t frame = session->current_end_frame();
1133 session->request_locate (frame);
1135 /* force displayed area in editor to start no matter
1136 what "follow playhead" setting is.
1140 editor->reset_x_origin (frame);
1146 ARDOUR_UI::transport_stop ()
1152 if (session->is_auditioning()) {
1153 session->cancel_audition ();
1157 if (session->get_play_loop ()) {
1158 session->request_play_loop (false);
1161 session->request_stop ();
1165 ARDOUR_UI::transport_stop_and_forget_capture ()
1168 session->request_stop (true);
1173 ARDOUR_UI::remove_last_capture()
1176 editor->remove_last_capture();
1181 ARDOUR_UI::transport_record ()
1184 switch (session->record_status()) {
1185 case Session::Disabled:
1186 if (session->ntracks() == 0) {
1187 MessageDialog msg (*editor, _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu."));
1191 session->maybe_enable_record ();
1193 case Session::Recording:
1194 case Session::Enabled:
1195 session->disable_record (true);
1201 ARDOUR_UI::transport_roll ()
1209 rolling = session->transport_rolling ();
1211 if (session->get_play_loop()) {
1212 session->request_play_loop (false);
1213 auto_loop_button.set_visual_state (1);
1214 roll_button.set_visual_state (1);
1215 } else if (session->get_play_range ()) {
1216 session->request_play_range (false);
1217 play_selection_button.set_visual_state (0);
1218 } else if (rolling) {
1219 session->request_locate (session->last_transport_start(), true);
1222 session->request_transport_speed (1.0f);
1226 ARDOUR_UI::transport_loop()
1229 if (session->get_play_loop()) {
1230 if (session->transport_rolling()) {
1231 Location * looploc = session->locations()->auto_loop_location();
1233 session->request_locate (looploc->start(), true);
1238 session->request_play_loop (true);
1244 ARDOUR_UI::transport_play_selection ()
1250 if (!session->get_play_range()) {
1251 session->request_stop ();
1254 editor->play_selection ();
1258 ARDOUR_UI::transport_rewind (int option)
1260 float current_transport_speed;
1263 current_transport_speed = session->transport_speed();
1265 if (current_transport_speed >= 0.0f) {
1268 session->request_transport_speed (-1.0f);
1271 session->request_transport_speed (-4.0f);
1274 session->request_transport_speed (-0.5f);
1279 session->request_transport_speed (current_transport_speed * 1.5f);
1285 ARDOUR_UI::transport_forward (int option)
1287 float current_transport_speed;
1290 current_transport_speed = session->transport_speed();
1292 if (current_transport_speed <= 0.0f) {
1295 session->request_transport_speed (1.0f);
1298 session->request_transport_speed (4.0f);
1301 session->request_transport_speed (0.5f);
1306 session->request_transport_speed (current_transport_speed * 1.5f);
1312 ARDOUR_UI::toggle_record_enable (uint32_t dstream)
1318 boost::shared_ptr<Route> r;
1320 if ((r = session->route_by_remote_id (dstream)) != 0) {
1324 if ((t = dynamic_cast<Track*>(r.get())) != 0) {
1325 t->diskstream()->set_record_enabled (!t->diskstream()->record_enabled());
1334 ARDOUR_UI::queue_transport_change ()
1336 Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
1340 ARDOUR_UI::map_transport_state ()
1342 float sp = session->transport_speed();
1345 transport_rolling ();
1346 } else if (sp < 0.0f) {
1347 transport_rewinding ();
1348 } else if (sp > 0.0f) {
1349 transport_forwarding ();
1351 transport_stopped ();
1356 ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg)
1358 snprintf (buf, sizeof(buf), "%s", ((GlobalClickBox *) arg)->strings[
1359 (int) adj.get_value()].c_str());
1363 ARDOUR_UI::engine_stopped ()
1365 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
1366 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1367 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1371 ARDOUR_UI::engine_running ()
1373 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
1374 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true);
1375 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
1377 Glib::RefPtr<Action> action;
1378 char* action_name = 0;
1380 switch (engine->frames_per_cycle()) {
1382 action_name = X_("JACKLatency32");
1385 action_name = X_("JACKLatency64");
1388 action_name = X_("JACKLatency128");
1391 action_name = X_("JACKLatency512");
1394 action_name = X_("JACKLatency1024");
1397 action_name = X_("JACKLatency2048");
1400 action_name = X_("JACKLatency4096");
1403 action_name = X_("JACKLatency8192");
1406 /* XXX can we do anything useful ? */
1412 action = ActionManager::get_action (X_("JACK"), action_name);
1415 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic (action);
1416 ract->set_active ();
1422 ARDOUR_UI::engine_halted ()
1424 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
1426 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1427 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1429 update_sample_rate (0);
1431 MessageDialog msg (*editor,
1433 JACK has either been shutdown or it\n\
1434 disconnected Ardour because Ardour\n\
1435 was not fast enough. You can save the\n\
1436 session and/or try to reconnect to JACK ."));
1441 ARDOUR_UI::do_engine_start ()
1449 error << _("Unable to start the session running")
1459 ARDOUR_UI::start_engine ()
1461 if (do_engine_start () == 0) {
1462 if (session && _session_is_new) {
1463 /* we need to retain initial visual
1464 settings for a new session
1466 session->save_state ("");
1474 ARDOUR_UI::update_clocks ()
1476 if (!editor || !editor->dragging_playhead()) {
1477 Clock (session->audible_frame()); /* EMIT_SIGNAL */
1482 ARDOUR_UI::start_clocking ()
1484 clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
1488 ARDOUR_UI::stop_clocking ()
1490 clock_signal_connection.disconnect ();
1494 ARDOUR_UI::toggle_clocking ()
1497 if (clock_button.get_active()) {
1506 ARDOUR_UI::_blink (void *arg)
1509 ((ARDOUR_UI *) arg)->blink ();
1516 Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
1520 ARDOUR_UI::start_blinking ()
1522 /* Start the blink signal. Everybody with a blinking widget
1523 uses Blink to drive the widget's state.
1526 if (blink_timeout_tag < 0) {
1528 blink_timeout_tag = g_timeout_add (240, _blink, this);
1533 ARDOUR_UI::stop_blinking ()
1535 if (blink_timeout_tag >= 0) {
1536 g_source_remove (blink_timeout_tag);
1537 blink_timeout_tag = -1;
1542 ARDOUR_UI::name_io_setup (AudioEngine& engine,
1548 if (io.n_inputs().get_total() == 0) {
1553 /* XXX we're not handling multiple ports yet. */
1555 const char **connections = io.input(0)->get_connections();
1557 if (connections == 0 || connections[0] == '\0') {
1560 buf = connections[0];
1567 if (io.n_outputs().get_total() == 0) {
1572 /* XXX we're not handling multiple ports yet. */
1574 const char **connections = io.output(0)->get_connections();
1576 if (connections == 0 || connections[0] == '\0') {
1579 buf = connections[0];
1587 ARDOUR_UI::snapshot_session ()
1589 ArdourPrompter prompter (true);
1593 struct tm local_time;
1596 localtime_r (&n, &local_time);
1597 strftime (timebuf, sizeof(timebuf), "%FT%T", &local_time);
1599 prompter.set_name ("Prompter");
1600 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1601 prompter.set_prompt (_("Name of New Snapshot"));
1602 prompter.set_initial_text (timebuf);
1604 switch (prompter.run()) {
1605 case RESPONSE_ACCEPT:
1606 prompter.get_result (snapname);
1607 if (snapname.length()){
1608 save_state (snapname);
1618 ARDOUR_UI::save_state (const string & name)
1620 (void) save_state_canfail (name);
1624 ARDOUR_UI::save_state_canfail (string name)
1629 if (name.length() == 0) {
1630 name = session->snap_name();
1633 if ((ret = session->save_state (name)) != 0) {
1637 save_ardour_state (); /* XXX cannot fail? yeah, right ... */
1642 ARDOUR_UI::restore_state (string name)
1645 if (name.length() == 0) {
1646 name = session->name();
1648 session->restore_state (name);
1653 ARDOUR_UI::primary_clock_value_changed ()
1656 session->request_locate (primary_clock.current_time ());
1661 ARDOUR_UI::secondary_clock_value_changed ()
1664 session->request_locate (secondary_clock.current_time ());
1669 ARDOUR_UI::rec_enable_button_blink (bool onoff, AudioDiskstream *dstream, Widget *w)
1671 if (session && dstream && dstream->record_enabled()) {
1673 Session::RecordState rs;
1675 rs = session->record_status ();
1678 case Session::Disabled:
1679 case Session::Enabled:
1680 if (w->get_state() != STATE_SELECTED) {
1681 w->set_state (STATE_SELECTED);
1685 case Session::Recording:
1686 if (w->get_state() != STATE_ACTIVE) {
1687 w->set_state (STATE_ACTIVE);
1693 if (w->get_state() != STATE_NORMAL) {
1694 w->set_state (STATE_NORMAL);
1700 ARDOUR_UI::transport_rec_enable_blink (bool onoff)
1706 switch (session->record_status()) {
1707 case Session::Enabled:
1709 rec_button.set_visual_state (2);
1711 rec_button.set_visual_state (0);
1715 case Session::Recording:
1716 rec_button.set_visual_state (1);
1720 rec_button.set_visual_state (0);
1726 ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
1734 ARDOUR_UI::save_template ()
1737 ArdourPrompter prompter (true);
1740 prompter.set_name (X_("Prompter"));
1741 prompter.set_prompt (_("Name for mix template:"));
1742 prompter.set_initial_text(session->name() + _("-template"));
1743 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1745 switch (prompter.run()) {
1746 case RESPONSE_ACCEPT:
1747 prompter.get_result (name);
1749 if (name.length()) {
1750 session->save_template (name);
1760 ARDOUR_UI::new_session (std::string predetermined_path)
1762 string session_name;
1763 string session_path;
1765 if (!engine->connected()) {
1766 MessageDialog msg (_("Ardour is not connected to JACK at this time. Creating new sessions is not possible."));
1771 int response = Gtk::RESPONSE_NONE;
1773 new_session_dialog->set_modal(true);
1774 new_session_dialog->set_name (predetermined_path);
1775 new_session_dialog->reset_recent();
1776 new_session_dialog->show();
1779 response = new_session_dialog->run ();
1781 if (!engine->connected()) {
1782 new_session_dialog->hide ();
1783 MessageDialog msg (_("Ardour is not connected to JACK at this time. Creating new sessions is not possible."));
1788 _session_is_new = false;
1790 if (response == Gtk::RESPONSE_CANCEL || response == Gtk::RESPONSE_DELETE_EVENT) {
1795 new_session_dialog->hide ();
1798 } else if (response == Gtk::RESPONSE_NONE) {
1800 /* Clear was pressed */
1801 new_session_dialog->reset();
1803 } else if (response == Gtk::RESPONSE_YES) {
1805 /* YES == OPEN, but there's no enum for that */
1807 session_name = new_session_dialog->session_name();
1809 if (session_name.empty()) {
1810 response = Gtk::RESPONSE_NONE;
1814 if (session_name[0] == '/' ||
1815 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1816 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1817 load_session (Glib::path_get_dirname (session_name), session_name);
1819 session_path = new_session_dialog->session_folder();
1820 load_session (session_path, session_name);
1823 } else if (response == Gtk::RESPONSE_OK) {
1825 session_name = new_session_dialog->session_name();
1827 if (new_session_dialog->get_current_page() == 1) {
1829 /* XXX this is a bit of a hack..
1830 i really want the new sesion dialog to return RESPONSE_YES
1831 if we're on page 1 (the load page)
1832 Unfortunately i can't see how atm..
1835 if (session_name.empty()) {
1836 response = Gtk::RESPONSE_NONE;
1840 if (session_name[0] == '/' ||
1841 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1842 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1843 load_session (Glib::path_get_dirname (session_name), session_name);
1845 session_path = new_session_dialog->session_folder();
1846 load_session (session_path, session_name);
1851 if (session_name.empty()) {
1852 response = Gtk::RESPONSE_NONE;
1856 if (session_name[0] == '/' ||
1857 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1858 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1860 session_path = Glib::path_get_dirname (session_name);
1861 session_name = Glib::path_get_basename (session_name);
1865 session_path = new_session_dialog->session_folder();
1869 //XXX This is needed because session constructor wants a
1870 //non-existant path. hopefully this will be fixed at some point.
1872 session_path = Glib::build_filename (session_path, session_name);
1874 if (g_file_test (session_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
1876 Glib::ustring str = string_compose (_("This session\n%1\nalready exists. Do you want to open it?"), session_path);
1878 MessageDialog msg (str,
1880 Gtk::MESSAGE_WARNING,
1881 Gtk::BUTTONS_YES_NO,
1885 msg.set_name (X_("CleanupDialog"));
1886 msg.set_wmclass (X_("existing_session"), "Ardour");
1887 msg.set_position (Gtk::WIN_POS_MOUSE);
1889 switch (msg.run()) {
1891 load_session (session_path, session_name);
1895 response = RESPONSE_NONE;
1896 new_session_dialog->reset ();
1901 _session_is_new = true;
1903 std::string template_name = new_session_dialog->session_template_name();
1905 if (new_session_dialog->use_session_template()) {
1907 load_session (session_path, session_name, &template_name);
1913 AutoConnectOption iconnect;
1914 AutoConnectOption oconnect;
1916 if (new_session_dialog->create_control_bus()) {
1917 cchns = (uint32_t) new_session_dialog->control_channel_count();
1922 if (new_session_dialog->create_master_bus()) {
1923 mchns = (uint32_t) new_session_dialog->master_channel_count();
1928 if (new_session_dialog->connect_inputs()) {
1929 iconnect = AutoConnectPhysical;
1931 iconnect = AutoConnectOption (0);
1934 /// @todo some minor tweaks.
1936 if (new_session_dialog->connect_outs_to_master()) {
1937 oconnect = AutoConnectMaster;
1938 } else if (new_session_dialog->connect_outs_to_physical()) {
1939 oconnect = AutoConnectPhysical;
1941 oconnect = AutoConnectOption (0);
1944 uint32_t nphysin = (uint32_t) new_session_dialog->input_limit_count();
1945 uint32_t nphysout = (uint32_t) new_session_dialog->output_limit_count();
1947 if (build_session (session_path,
1955 engine->frame_rate() * 60 * 5)) {
1957 response = Gtk::RESPONSE_NONE;
1958 new_session_dialog->reset ();
1965 } while (response == Gtk::RESPONSE_NONE);
1969 new_session_dialog->get_window()->set_cursor();
1970 new_session_dialog->hide();
1975 ARDOUR_UI::close_session()
1982 ARDOUR_UI::load_session (const string & path, const string & snap_name, string* mix_template)
1984 Session *new_session;
1986 session_loaded = false;
1988 x = unload_session ();
1996 /* if it already exists, we must have write access */
1998 if (::access (path.c_str(), F_OK) == 0 && ::access (path.c_str(), W_OK)) {
1999 MessageDialog msg (*editor, _("You do not have write access to this session.\n"
2000 "This prevents the session from being loaded."));
2006 new_session = new Session (*engine, path, snap_name, mix_template);
2011 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
2015 connect_to_session (new_session);
2017 Config->set_current_owner (ConfigVariableBase::Interface);
2019 session_loaded = true;
2021 goto_editor_window ();
2024 session->set_clean ();
2027 editor->edit_cursor_position (true);
2032 ARDOUR_UI::build_session (const string & path, const string & snap_name,
2033 uint32_t control_channels,
2034 uint32_t master_channels,
2035 AutoConnectOption input_connect,
2036 AutoConnectOption output_connect,
2039 nframes_t initial_length)
2041 Session *new_session;
2044 session_loaded = false;
2045 x = unload_session ();
2052 _session_is_new = true;
2055 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
2056 control_channels, master_channels, nphysin, nphysout, initial_length);
2061 MessageDialog msg (string_compose(_("Could not create session in \"%1\""), path));
2066 connect_to_session (new_session);
2068 session_loaded = true;
2076 editor->show_window ();
2087 ARDOUR_UI::show_splash ()
2090 about = new About();
2091 about->signal_response().connect(mem_fun (*this, &ARDOUR_UI::about_signal_response) );
2098 ARDOUR_UI::about_signal_response(int response)
2104 ARDOUR_UI::hide_splash ()
2107 about->get_window()->set_cursor ();
2113 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title, const string & msg)
2117 removed = rep.paths.size();
2120 MessageDialog msgd (*editor,
2121 _("No audio files were ready for cleanup"),
2124 (Gtk::ButtonsType)(Gtk::BUTTONS_OK) );
2125 msgd.set_secondary_text (_("If this seems suprising, \n\
2126 check for any existing snapshots.\n\
2127 These may still include regions that\n\
2128 require some unused files to continue to exist."));
2134 ArdourDialog results (_("ardour: cleanup"), true, false);
2136 struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
2137 CleanupResultsModelColumns() {
2141 Gtk::TreeModelColumn<Glib::ustring> visible_name;
2142 Gtk::TreeModelColumn<Glib::ustring> fullpath;
2146 CleanupResultsModelColumns results_columns;
2147 Glib::RefPtr<Gtk::ListStore> results_model;
2148 Gtk::TreeView results_display;
2150 results_model = ListStore::create (results_columns);
2151 results_display.set_model (results_model);
2152 results_display.append_column (list_title, results_columns.visible_name);
2154 results_display.set_name ("CleanupResultsList");
2155 results_display.set_headers_visible (true);
2156 results_display.set_headers_clickable (false);
2157 results_display.set_reorderable (false);
2159 Gtk::ScrolledWindow list_scroller;
2162 Gtk::HBox dhbox; // the hbox for the image and text
2163 Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
2164 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO, Gtk::ICON_SIZE_DIALOG));
2166 dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
2168 if (rep.space < 1048576.0f) {
2170 txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2172 txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2176 txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2178 txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2182 dhbox.pack_start (*dimage, true, false, 5);
2183 dhbox.pack_start (txt, true, false, 5);
2185 for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2186 TreeModel::Row row = *(results_model->append());
2187 row[results_columns.visible_name] = *i;
2188 row[results_columns.fullpath] = *i;
2191 list_scroller.add (results_display);
2192 list_scroller.set_size_request (-1, 150);
2193 list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2195 dvbox.pack_start (dhbox, true, false, 5);
2196 dvbox.pack_start (list_scroller, true, false, 5);
2197 ddhbox.pack_start (dvbox, true, false, 5);
2199 results.get_vbox()->pack_start (ddhbox, true, false, 5);
2200 results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
2201 results.set_default_response (RESPONSE_CLOSE);
2202 results.set_position (Gtk::WIN_POS_MOUSE);
2203 results.show_all_children ();
2204 results.set_resizable (false);
2211 ARDOUR_UI::cleanup ()
2214 /* shouldn't happen: menu item is insensitive */
2219 MessageDialog checker (_("Are you sure you want to cleanup?"),
2221 Gtk::MESSAGE_QUESTION,
2222 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
2224 checker.set_secondary_text(_("Cleanup is a destructive operation.\n\
2225 ALL undo/redo information will be lost if you cleanup.\n\
2226 After cleanup, unused audio files will be moved to a \
2227 \"dead sounds\" location."));
2229 checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2230 checker.add_button (_("Clean Up"), RESPONSE_ACCEPT);
2231 checker.set_default_response (RESPONSE_CANCEL);
2233 checker.set_name (_("CleanupDialog"));
2234 checker.set_wmclass (X_("ardour_cleanup"), "Ardour");
2235 checker.set_position (Gtk::WIN_POS_MOUSE);
2237 switch (checker.run()) {
2238 case RESPONSE_ACCEPT:
2244 Session::cleanup_report rep;
2246 editor->prepare_for_cleanup ();
2248 /* do not allow flush until a session is reloaded */
2250 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
2252 act->set_sensitive (false);
2255 if (session->cleanup_sources (rep)) {
2260 display_cleanup_results (rep,
2263 The following %1 %2 not in use and \n\
2264 have been moved to:\n\
2266 Flushing the wastebasket will \n\
2267 release an additional\n\
2268 %4 %5bytes of disk space.\n"
2276 ARDOUR_UI::flush_trash ()
2279 /* shouldn't happen: menu item is insensitive */
2283 Session::cleanup_report rep;
2285 if (session->cleanup_trash_sources (rep)) {
2289 display_cleanup_results (rep,
2291 _("The following %1 %2 deleted from\n\
2293 releasing %4 %5bytes of disk space"));
2297 ARDOUR_UI::add_route (Gtk::Window* float_window)
2305 if (add_route_dialog == 0) {
2306 add_route_dialog = new AddRouteDialog;
2308 add_route_dialog->set_transient_for (*float_window);
2312 if (add_route_dialog->is_visible()) {
2313 /* we're already doing this */
2317 ResponseType r = (ResponseType) add_route_dialog->run ();
2319 add_route_dialog->hide();
2322 case RESPONSE_ACCEPT:
2329 if ((count = add_route_dialog->count()) <= 0) {
2333 uint32_t input_chan = add_route_dialog->channels ();
2334 uint32_t output_chan;
2335 string name_template = add_route_dialog->name_template ();
2336 bool track = add_route_dialog->track ();
2338 AutoConnectOption oac = Config->get_output_auto_connect();
2340 if (oac & AutoConnectMaster) {
2341 output_chan = (session->master_out() ? session->master_out()->n_inputs().get(DataType::AUDIO) : input_chan);
2343 output_chan = input_chan;
2346 /* XXX do something with name template */
2348 if (add_route_dialog->type() == ARDOUR::DataType::MIDI) {
2350 session_add_midi_track(count);
2352 MessageDialog msg (*editor,
2353 _("Sorry, MIDI Busses are not supported at this time."));
2355 //session_add_midi_bus();
2359 session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), count);
2361 session_add_audio_bus (input_chan, output_chan, count);
2367 ARDOUR_UI::mixer_settings () const
2372 node = session->instant_xml(X_("Mixer"), session->path());
2374 node = Config->instant_xml(X_("Mixer"), get_user_ardour_path());
2378 node = new XMLNode (X_("Mixer"));
2385 ARDOUR_UI::editor_settings () const
2390 node = session->instant_xml(X_("Editor"), session->path());
2392 node = Config->instant_xml(X_("Editor"), get_user_ardour_path());
2396 node = new XMLNode (X_("Editor"));
2402 ARDOUR_UI::keyboard_settings () const
2406 node = Config->extra_xml(X_("Keyboard"));
2409 node = new XMLNode (X_("Keyboard"));
2415 ARDOUR_UI::halt_on_xrun_message ()
2417 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
2419 MessageDialog msg (*editor,
2420 _("Recording was stopped because your system could not keep up."));
2425 ARDOUR_UI::disk_overrun_handler ()
2427 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
2429 if (!have_disk_speed_dialog_displayed) {
2430 have_disk_speed_dialog_displayed = true;
2431 MessageDialog* msg = new MessageDialog (*editor, X_("diskrate dialog"), _("\
2432 The disk system on your computer\n\
2433 was not able to keep up with Ardour.\n\
2435 Specifically, it failed to write data to disk\n\
2436 quickly enough to keep up with recording.\n"));
2437 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
2443 ARDOUR_UI::disk_underrun_handler ()
2445 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2447 if (!have_disk_speed_dialog_displayed) {
2448 have_disk_speed_dialog_displayed = true;
2449 MessageDialog* msg = new MessageDialog (*editor,
2450 _("The disk system on your computer\n\
2451 was not able to keep up with Ardour.\n\
2453 Specifically, it failed to read data from disk\n\
2454 quickly enough to keep up with playback.\n"));
2455 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
2461 ARDOUR_UI::disk_speed_dialog_gone (int ignored_response, MessageDialog* msg)
2463 have_disk_speed_dialog_displayed = false;
2468 ARDOUR_UI::pending_state_dialog ()
2470 ArdourDialog dialog ("pending state dialog");
2472 This session appears to have been in\n\
2473 middle of recording when ardour or\n\
2474 the computer was shutdown.\n\
2476 Ardour can recover any captured audio for\n\
2477 you, or it can ignore it. Please decide\n\
2478 what you would like to do.\n"));
2480 dialog.get_vbox()->pack_start (message);
2481 dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
2482 dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
2484 dialog.set_position (WIN_POS_CENTER);
2487 switch (dialog.run ()) {
2488 case RESPONSE_ACCEPT:
2496 ARDOUR_UI::disconnect_from_jack ()
2499 if( engine->disconnect_from_jack ()) {
2500 MessageDialog msg (*editor, _("Could not disconnect from JACK"));
2504 update_sample_rate (0);
2509 ARDOUR_UI::reconnect_to_jack ()
2512 if (engine->reconnect_to_jack ()) {
2513 MessageDialog msg (*editor, _("Could not reconnect to JACK"));
2517 update_sample_rate (0);
2522 ARDOUR_UI::cmdline_new_session (string path)
2524 if (path[0] != '/') {
2525 char buf[PATH_MAX+1];
2528 getcwd (buf, sizeof (buf));
2537 _will_create_new_session_automatically = false; /* done it */
2538 return FALSE; /* don't call it again */
2542 ARDOUR_UI::use_config ()
2544 Glib::RefPtr<Action> act;
2546 switch (Config->get_native_file_data_format ()) {
2548 act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
2551 act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
2556 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2557 ract->set_active ();
2560 switch (Config->get_native_file_header_format ()) {
2562 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
2565 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
2568 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
2571 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
2574 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
2577 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatCAF"));
2580 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatAIFF"));
2585 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2586 ract->set_active ();
2589 XMLNode* node = Config->extra_xml (X_("TransportControllables"));
2591 set_transport_controllable_state (*node);
2596 ARDOUR_UI::update_transport_clocks (nframes_t pos)
2598 primary_clock.set (pos);
2599 secondary_clock.set (pos);
2601 if (big_clock_window) {
2602 big_clock.set (pos);
2607 ARDOUR_UI::record_state_changed ()
2609 ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::record_state_changed));
2611 if (!session || !big_clock_window) {
2612 /* why bother - the clock isn't visible */
2616 switch (session->record_status()) {
2617 case Session::Recording:
2618 big_clock.set_widget_name ("BigClockRecording");
2621 big_clock.set_widget_name ("BigClockNonRecording");
2627 ARDOUR_UI::set_keybindings_path (string path)
2629 keybindings_path = path;
2633 ARDOUR_UI::save_keybindings ()
2635 if (can_save_keybindings) {
2636 AccelMap::save (keybindings_path);
2641 ARDOUR_UI::first_idle ()
2643 can_save_keybindings = true;
2648 ARDOUR_UI::store_clock_modes ()
2650 XMLNode* node = new XMLNode(X_("ClockModes"));
2652 for (vector<AudioClock*>::iterator x = AudioClock::clocks.begin(); x != AudioClock::clocks.end(); ++x) {
2653 node->add_property ((*x)->name().c_str(), enum_2_string ((*x)->mode()));
2656 session->add_extra_xml (*node);
2657 session->set_dirty ();
2662 ARDOUR_UI::TransportControllable::TransportControllable (std::string name, ARDOUR_UI& u, ToggleType tp)
2663 : Controllable (name), ui (u), type(tp)
2669 ARDOUR_UI::TransportControllable::set_value (float val)
2671 if (type == ShuttleControl) {
2678 fract = -((0.5f - val)/0.5f);
2680 fract = ((val - 0.5f)/0.5f);
2684 ui.set_shuttle_fract (fract);
2689 /* do nothing: these are radio-style actions */
2697 action = X_("Roll");
2700 action = X_("Stop");
2703 action = X_("Goto Start");
2706 action = X_("Goto End");
2709 action = X_("Loop");
2712 action = X_("Play Selection");
2715 action = X_("Record");
2725 Glib::RefPtr<Action> act = ActionManager::get_action ("Transport", action);
2733 ARDOUR_UI::TransportControllable::get_value (void) const
2752 case ShuttleControl:
2762 ARDOUR_UI::TransportControllable::set_id (const string& str)