2 Copyright (C) 1999-2007 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #define __STDC_FORMAT_MACROS 1
33 #include <sys/resource.h>
35 #include <gtkmm/messagedialog.h>
36 #include <gtkmm/accelmap.h>
38 #include <pbd/error.h>
39 #include <pbd/compose.h>
40 #include <pbd/pathscanner.h>
41 #include <pbd/failed_constructor.h>
42 #include <pbd/enumwriter.h>
43 #include <pbd/stacktrace.h>
44 #include <gtkmm2ext/gtk_ui.h>
45 #include <gtkmm2ext/utils.h>
46 #include <gtkmm2ext/click_box.h>
47 #include <gtkmm2ext/fastmeter.h>
48 #include <gtkmm2ext/stop_signal.h>
49 #include <gtkmm2ext/popup.h>
50 #include <gtkmm2ext/window_title.h>
52 #include <midi++/port.h>
53 #include <midi++/mmc.h>
55 #include <ardour/ardour.h>
56 #include <ardour/profile.h>
57 #include <ardour/session_route.h>
58 #include <ardour/port.h>
59 #include <ardour/audioengine.h>
60 #include <ardour/playlist.h>
61 #include <ardour/utils.h>
62 #include <ardour/audio_diskstream.h>
63 #include <ardour/audiofilesource.h>
64 #include <ardour/recent_sessions.h>
65 #include <ardour/port.h>
66 #include <ardour/audio_track.h>
67 #include <ardour/midi_track.h>
70 #include "ardour_ui.h"
71 #include "public_editor.h"
72 #include "audio_clock.h"
77 #include "add_route_dialog.h"
78 #include "new_session_dialog.h"
81 #include "gui_thread.h"
82 #include "color_manager.h"
86 using namespace ARDOUR;
88 using namespace Gtkmm2ext;
92 ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
94 sigc::signal<void,bool> ARDOUR_UI::Blink;
95 sigc::signal<void> ARDOUR_UI::RapidScreenUpdate;
96 sigc::signal<void> ARDOUR_UI::SuperRapidScreenUpdate;
97 sigc::signal<void,nframes_t> ARDOUR_UI::Clock;
99 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
101 : Gtkmm2ext::UI (X_("Ardour"), argcp, argvp, rcfile),
103 primary_clock (X_("primary"), false, X_("TransportClockDisplay"), true, false, true),
104 secondary_clock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, false, true),
105 preroll_clock (X_("preroll"), false, X_("PreRollClock"), true, true),
106 postroll_clock (X_("postroll"), false, X_("PostRollClock"), true, true),
110 adjuster_table (3, 3),
114 preroll_button (_("pre\nroll")),
115 postroll_button (_("post\nroll")),
119 big_clock (X_("bigclock"), false, "BigClockNonRecording", false, false, true),
123 roll_controllable ("transport roll", *this, TransportControllable::Roll),
124 stop_controllable ("transport stop", *this, TransportControllable::Stop),
125 goto_start_controllable ("transport goto start", *this, TransportControllable::GotoStart),
126 goto_end_controllable ("transport goto end", *this, TransportControllable::GotoEnd),
127 auto_loop_controllable ("transport auto loop", *this, TransportControllable::AutoLoop),
128 play_selection_controllable ("transport play selection", *this, TransportControllable::PlaySelection),
129 rec_controllable ("transport rec-enable", *this, TransportControllable::RecordEnable),
130 shuttle_controllable ("shuttle", *this, TransportControllable::ShuttleControl),
131 shuttle_controller_binding_proxy (shuttle_controllable),
133 roll_button (roll_controllable),
134 stop_button (stop_controllable),
135 goto_start_button (goto_start_controllable),
136 goto_end_button (goto_end_controllable),
137 auto_loop_button (auto_loop_controllable),
138 play_selection_button (play_selection_controllable),
139 rec_button (rec_controllable),
141 shuttle_units_button (_("% ")),
143 punch_in_button (_("Punch In")),
144 punch_out_button (_("Punch Out")),
145 auto_return_button (_("Auto Return")),
146 auto_play_button (_("Auto Play")),
147 auto_input_button (_("Auto Input")),
148 click_button (_("Click")),
149 time_master_button (_("time\nmaster")),
151 auditioning_alert_button (_("AUDITION")),
152 solo_alert_button (_("SOLO")),
155 using namespace Gtk::Menu_Helpers;
161 if (theArdourUI == 0) {
167 color_manager = new ColorManager();
169 std::string color_file = ARDOUR::find_config_file("ardour.colors");
171 color_manager->load (color_file);
176 _session_is_new = false;
177 big_clock_window = 0;
178 session_selector_window = 0;
179 last_key_press_time = 0;
180 connection_editor = 0;
181 add_route_dialog = 0;
185 open_session_selector = 0;
186 have_configure_timeout = false;
187 have_disk_speed_dialog_displayed = false;
188 _will_create_new_session_automatically = false;
189 session_loaded = false;
190 last_speed_displayed = -1.0f;
191 keybindings_path = ARDOUR::find_config_file ("ardour.bindings");
193 can_save_keybindings = false;
195 last_configure_time.tv_sec = 0;
196 last_configure_time.tv_usec = 0;
198 shuttle_grabbed = false;
200 shuttle_max_speed = 8.0f;
202 shuttle_style_menu = 0;
203 shuttle_unit_menu = 0;
205 gettimeofday (&last_peak_grab, 0);
206 gettimeofday (&last_shuttle_request, 0);
208 ARDOUR::Diskstream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
209 ARDOUR::Diskstream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
211 /* handle pending state with a dialog */
213 ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
215 /* have to wait for AudioEngine and Configuration before proceeding */
219 ARDOUR_UI::set_engine (AudioEngine& e)
223 engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
224 engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
225 engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
226 engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
228 ActionManager::init ();
229 new_session_dialog = new NewSessionDialog();
233 keyboard = new Keyboard;
235 if (setup_windows ()) {
236 throw failed_constructor ();
239 if (GTK_ARDOUR::show_key_actions) {
240 vector<string> names;
241 vector<string> paths;
243 vector<AccelKey> bindings;
245 ActionManager::get_all_actions (names, paths, keys, bindings);
247 vector<string>::iterator n;
248 vector<string>::iterator k;
249 for (n = names.begin(), k = keys.begin(); n != names.end(); ++n, ++k) {
250 cerr << "Action: " << (*n) << " bound to " << (*k) << endl;
256 /* start with timecode, metering enabled
259 blink_timeout_tag = -1;
261 /* the global configuration object is now valid */
265 /* this being a GUI and all, we want peakfiles */
267 AudioFileSource::set_build_peakfiles (true);
268 AudioFileSource::set_build_missing_peakfiles (true);
270 /* set default clock modes */
272 primary_clock.set_mode (AudioClock::SMPTE);
273 secondary_clock.set_mode (AudioClock::BBT);
275 /* start the time-of-day-clock */
277 update_wall_clock ();
278 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
280 update_disk_space ();
282 update_sample_rate (engine->frame_rate());
284 starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
285 stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
288 ARDOUR_UI::~ARDOUR_UI ()
290 save_ardour_state ();
304 if (add_route_dialog) {
305 delete add_route_dialog;
310 ARDOUR_UI::configure_timeout ()
315 if (last_configure_time.tv_sec == 0 && last_configure_time.tv_usec == 0) {
316 /* no configure events yet */
320 gettimeofday (&now, 0);
321 timersub (&now, &last_configure_time, &diff);
323 /* force a gap of 0.5 seconds since the last configure event
326 if (diff.tv_sec == 0 && diff.tv_usec < 500000) {
329 have_configure_timeout = false;
330 save_ardour_state ();
336 ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
338 if (have_configure_timeout) {
339 gettimeofday (&last_configure_time, 0);
341 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
342 have_configure_timeout = true;
349 ARDOUR_UI::set_transport_controllable_state (const XMLNode& node)
351 const XMLProperty* prop;
353 if ((prop = node.property ("roll")) != 0) {
354 roll_controllable.set_id (prop->value());
356 if ((prop = node.property ("stop")) != 0) {
357 stop_controllable.set_id (prop->value());
359 if ((prop = node.property ("goto_start")) != 0) {
360 goto_start_controllable.set_id (prop->value());
362 if ((prop = node.property ("goto_end")) != 0) {
363 goto_end_controllable.set_id (prop->value());
365 if ((prop = node.property ("auto_loop")) != 0) {
366 auto_loop_controllable.set_id (prop->value());
368 if ((prop = node.property ("play_selection")) != 0) {
369 play_selection_controllable.set_id (prop->value());
371 if ((prop = node.property ("rec")) != 0) {
372 rec_controllable.set_id (prop->value());
374 if ((prop = node.property ("shuttle")) != 0) {
375 shuttle_controllable.set_id (prop->value());
380 ARDOUR_UI::get_transport_controllable_state ()
382 XMLNode* node = new XMLNode(X_("TransportControllables"));
385 roll_controllable.id().print (buf, sizeof (buf));
386 node->add_property (X_("roll"), buf);
387 stop_controllable.id().print (buf, sizeof (buf));
388 node->add_property (X_("stop"), buf);
389 goto_start_controllable.id().print (buf, sizeof (buf));
390 node->add_property (X_("goto_start"), buf);
391 goto_end_controllable.id().print (buf, sizeof (buf));
392 node->add_property (X_("goto_end"), buf);
393 auto_loop_controllable.id().print (buf, sizeof (buf));
394 node->add_property (X_("auto_loop"), buf);
395 play_selection_controllable.id().print (buf, sizeof (buf));
396 node->add_property (X_("play_selection"), buf);
397 rec_controllable.id().print (buf, sizeof (buf));
398 node->add_property (X_("rec"), buf);
399 shuttle_controllable.id().print (buf, sizeof (buf));
400 node->add_property (X_("shuttle"), buf);
406 ARDOUR_UI::save_ardour_state ()
408 if (!keyboard || !mixer || !editor) {
412 /* XXX this is all a bit dubious. add_extra_xml() uses
413 a different lifetime model from add_instant_xml().
416 XMLNode* node = new XMLNode (keyboard->get_state());
417 Config->add_extra_xml (*node);
418 Config->add_extra_xml (get_transport_controllable_state());
419 Config->save_state();
421 XMLNode enode(static_cast<Stateful*>(editor)->get_state());
422 XMLNode mnode(mixer->get_state());
425 session->add_instant_xml (enode, session->path());
426 session->add_instant_xml (mnode, session->path());
428 Config->add_instant_xml (enode, get_user_ardour_path());
429 Config->add_instant_xml (mnode, get_user_ardour_path());
436 ARDOUR_UI::startup ()
438 check_memory_locking();
442 ARDOUR_UI::no_memory_warning ()
444 XMLNode node (X_("no-memory-warning"));
445 Config->add_instant_xml (node, get_user_ardour_path());
449 ARDOUR_UI::check_memory_locking ()
452 /* OS X doesn't support mlockall(2), and so testing for memory locking capability there is pointless */
456 XMLNode* memory_warning_node = Config->instant_xml (X_("no-memory-warning"), get_user_ardour_path());
458 if (engine->is_realtime() && memory_warning_node == 0) {
460 struct rlimit limits;
462 long pages, page_size;
464 if ((page_size = sysconf (_SC_PAGESIZE)) < 0 ||(pages = sysconf (_SC_PHYS_PAGES)) < 0) {
467 ram = (int64_t) pages * (int64_t) page_size;
470 if (getrlimit (RLIMIT_MEMLOCK, &limits)) {
474 if (limits.rlim_cur != RLIM_INFINITY) {
476 if (ram == 0 || ((double) limits.rlim_cur / ram) < 0.75) {
479 MessageDialog msg (_("WARNING: Your system has a limit for maximum amount of locked memory. "
480 "This might cause Ardour to run out of memory before your system "
481 "runs out of memory. \n\n"
482 "You can view the memory limit with 'ulimit -l', "
483 "and it is normally controlled by /etc/security/limits.conf"));
485 VBox* vbox = msg.get_vbox();
487 CheckButton cb (_("Do not show this window again"));
489 cb.signal_toggled().connect (mem_fun (*this, &ARDOUR_UI::no_memory_warning));
491 hbox.pack_start (cb, true, false);
492 vbox->pack_start (hbox);
495 editor->ensure_float (msg);
507 if (session && session->dirty()) {
508 switch (ask_about_saving_session(_("quit"))) {
513 /* use the default name */
514 if (save_state_canfail ("")) {
515 /* failed - don't quit */
516 MessageDialog msg (*editor,
518 Ardour was unable to save your session.\n\n\
519 If you still wish to quit, please use the\n\n\
520 \"Just quit\" option."));
531 session->set_deletion_in_progress ();
534 Config->save_state();
539 ARDOUR_UI::ask_about_saving_session (const string & what)
541 ArdourDialog window (_("ardour: save session?"));
542 Gtk::HBox dhbox; // the hbox for the image and text
543 Gtk::Label prompt_label;
544 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_WARNING, Gtk::ICON_SIZE_DIALOG));
548 msg = string_compose(_("Don't %1"), what);
549 window.add_button (msg, RESPONSE_REJECT);
550 msg = string_compose(_("Just %1"), what);
551 window.add_button (msg, RESPONSE_APPLY);
552 msg = string_compose(_("Save and %1"), what);
553 window.add_button (msg, RESPONSE_ACCEPT);
555 window.set_default_response (RESPONSE_ACCEPT);
557 Gtk::Button noquit_button (msg);
558 noquit_button.set_name ("EditorGTKButton");
563 if (session->snap_name() == session->name()) {
566 type = _("snapshot");
568 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?"),
569 type, session->snap_name());
571 prompt_label.set_text (prompt);
572 prompt_label.set_name (X_("PrompterLabel"));
573 prompt_label.set_alignment(ALIGN_LEFT, ALIGN_TOP);
575 dimage->set_alignment(ALIGN_CENTER, ALIGN_TOP)
577 dhbox.set_homogeneous (false);
578 dhbox.pack_start (*dimage, false, false, 5);
579 dhbox.pack_start (prompt_label, true, false, 5);
580 window.get_vbox()->pack_start (dhbox);
582 window.set_name (_("Prompter"));
583 window.set_position (Gtk::WIN_POS_MOUSE);
584 window.set_modal (true);
585 window.set_resizable (false);
588 save_the_session = 0;
590 window.set_keep_above (true);
593 ResponseType r = (ResponseType) window.run();
598 case RESPONSE_ACCEPT: // save and get out of here
600 case RESPONSE_APPLY: // get out of here
610 ARDOUR_UI::every_second ()
613 update_buffer_load ();
614 update_disk_space ();
619 ARDOUR_UI::every_point_one_seconds ()
621 update_speed_display ();
622 RapidScreenUpdate(); /* EMIT_SIGNAL */
627 ARDOUR_UI::every_point_zero_one_seconds ()
629 SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
634 ARDOUR_UI::update_sample_rate (nframes_t ignored)
638 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
640 if (!engine->connected()) {
642 snprintf (buf, sizeof (buf), _("disconnected"));
646 nframes_t rate = engine->frame_rate();
648 if (fmod (rate, 1000.0) != 0.0) {
649 snprintf (buf, sizeof (buf), _("%.1f kHz / %4.1f ms"),
650 (float) rate/1000.0f,
651 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
653 snprintf (buf, sizeof (buf), _("%u kHz / %4.1f ms"),
655 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
659 sample_rate_label.set_text (buf);
663 ARDOUR_UI::update_cpu_load ()
666 snprintf (buf, sizeof (buf), _("DSP: %5.1f%%"), engine->get_cpu_load());
667 cpu_load_label.set_text (buf);
671 ARDOUR_UI::update_buffer_load ()
676 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"),
677 session->playback_load(), session->capture_load());
678 buffer_load_label.set_text (buf);
680 buffer_load_label.set_text ("");
685 ARDOUR_UI::count_recenabled_streams (Route& route)
687 Track* track = dynamic_cast<Track*>(&route);
688 if (track && track->diskstream()->record_enabled()) {
689 rec_enabled_streams += track->n_inputs().get_total();
694 ARDOUR_UI::update_disk_space()
700 nframes_t frames = session->available_capture_duration();
703 if (frames == max_frames) {
704 strcpy (buf, _("Disk: 24hrs+"));
709 nframes_t fr = session->frame_rate();
711 rec_enabled_streams = 0;
712 session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams);
714 if (rec_enabled_streams) {
715 frames /= rec_enabled_streams;
718 hrs = frames / (fr * 3600);
719 frames -= hrs * fr * 3600;
720 mins = frames / (fr * 60);
721 frames -= mins * fr * 60;
724 snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs);
727 disk_space_label.set_text (buf);
731 ARDOUR_UI::update_wall_clock ()
738 tm_now = localtime (&now);
740 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
741 wall_clock_label.set_text (buf);
747 ARDOUR_UI::session_menu (GdkEventButton *ev)
749 session_popup_menu->popup (0, 0);
754 ARDOUR_UI::redisplay_recent_sessions ()
756 vector<string *> *sessions;
757 vector<string *>::iterator i;
758 RecentSessionsSorter cmp;
760 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
761 recent_session_model->clear ();
764 ARDOUR::read_recent_sessions (rs);
767 recent_session_display.set_model (recent_session_model);
771 /* sort them alphabetically */
772 sort (rs.begin(), rs.end(), cmp);
773 sessions = new vector<string*>;
775 for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
776 sessions->push_back (new string ((*i).second));
779 for (i = sessions->begin(); i != sessions->end(); ++i) {
781 vector<string*>* states;
782 vector<const gchar*> item;
783 string fullpath = *(*i);
785 /* remove any trailing / */
787 if (fullpath[fullpath.length()-1] == '/') {
788 fullpath = fullpath.substr (0, fullpath.length()-1);
791 /* now get available states for this session */
793 if ((states = Session::possible_states (fullpath)) == 0) {
798 TreeModel::Row row = *(recent_session_model->append());
800 row[recent_session_columns.visible_name] = Glib::path_get_basename (fullpath);
801 row[recent_session_columns.fullpath] = fullpath;
803 if (states->size() > 1) {
805 /* add the children */
807 for (vector<string*>::iterator i2 = states->begin(); i2 != states->end(); ++i2) {
809 TreeModel::Row child_row = *(recent_session_model->append (row.children()));
811 child_row[recent_session_columns.visible_name] = **i2;
812 child_row[recent_session_columns.fullpath] = fullpath;
821 recent_session_display.set_model (recent_session_model);
826 ARDOUR_UI::build_session_selector ()
828 session_selector_window = new ArdourDialog ("session selector");
830 Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
832 session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
833 session_selector_window->add_button (Stock::OPEN, RESPONSE_ACCEPT);
834 session_selector_window->set_default_response (RESPONSE_ACCEPT);
835 recent_session_model = TreeStore::create (recent_session_columns);
836 recent_session_display.set_model (recent_session_model);
837 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
838 recent_session_display.set_headers_visible (false);
839 recent_session_display.get_selection()->set_mode (SELECTION_SINGLE);
841 recent_session_display.signal_row_activated().connect (mem_fun (*this, &ARDOUR_UI::recent_session_row_activated));
843 scroller->add (recent_session_display);
844 scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
846 session_selector_window->set_name ("SessionSelectorWindow");
847 session_selector_window->set_size_request (200, 400);
848 session_selector_window->get_vbox()->pack_start (*scroller);
849 session_selector_window->show_all_children();
853 ARDOUR_UI::recent_session_row_activated (const TreePath& path, TreeViewColumn* col)
855 session_selector_window->response (RESPONSE_ACCEPT);
859 ARDOUR_UI::open_recent_session ()
861 /* popup selector window */
863 if (session_selector_window == 0) {
864 build_session_selector ();
867 redisplay_recent_sessions ();
869 ResponseType r = (ResponseType) session_selector_window->run ();
871 session_selector_window->hide();
874 case RESPONSE_ACCEPT:
880 Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
882 if (i == recent_session_model->children().end()) {
886 Glib::ustring path = (*i)[recent_session_columns.fullpath];
887 Glib::ustring state = (*i)[recent_session_columns.visible_name];
889 _session_is_new = false;
891 load_session (path, state);
895 ARDOUR_UI::filter_ardour_session_dirs (const FileFilter::Info& info)
899 if (stat (info.filename.c_str(), &statbuf) != 0) {
903 if (!S_ISDIR(statbuf.st_mode)) {
909 string session_file = info.filename;
911 session_file += Glib::path_get_basename (info.filename);
912 session_file += ".ardour";
914 if (stat (session_file.c_str(), &statbuf) != 0) {
918 return S_ISREG (statbuf.st_mode);
922 ARDOUR_UI::open_session ()
924 /* popup selector window */
926 if (open_session_selector == 0) {
928 /* ardour sessions are folders */
930 open_session_selector = new Gtk::FileChooserDialog (_("open session"), FILE_CHOOSER_ACTION_OPEN);
931 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
932 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_ACCEPT);
934 FileFilter session_filter;
935 session_filter.add_pattern ("*.ardour");
936 session_filter.set_name (_("Ardour sessions"));
937 open_session_selector->add_filter (session_filter);
938 open_session_selector->set_filter (session_filter);
941 int response = open_session_selector->run();
942 open_session_selector->hide ();
945 case RESPONSE_ACCEPT:
948 open_session_selector->hide();
952 open_session_selector->hide();
953 string session_path = open_session_selector->get_filename();
957 if (session_path.length() > 0) {
958 if (Session::find_session (session_path, path, name, isnew) == 0) {
959 _session_is_new = isnew;
960 load_session (path, name);
967 ARDOUR_UI::session_add_midi_route (bool disk, uint32_t how_many)
969 list<boost::shared_ptr<MidiTrack> > tracks;
972 warning << _("You cannot add a track without a session already loaded.") << endmsg;
979 tracks = session->new_midi_track (ARDOUR::Normal, how_many);
981 if (tracks.size() != how_many) {
983 error << _("could not create a new midi track") << endmsg;
985 error << string_compose (_("could not create %1 new midi tracks"), how_many) << endmsg;
989 if ((route = session->new_midi_route ()) == 0) {
990 error << _("could not create new midi bus") << endmsg;
996 MessageDialog msg (*editor,
997 _("There are insufficient JACK ports available\n\
998 to create a new track or bus.\n\
999 You should save Ardour, exit and\n\
1000 restart JACK with more ports."));
1007 ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, uint32_t how_many)
1009 list<boost::shared_ptr<AudioTrack> > tracks;
1010 Session::RouteList routes;
1013 warning << _("You cannot add a track or bus without a session already loaded.") << endmsg;
1019 tracks = session->new_audio_track (input_channels, output_channels, mode, how_many);
1021 if (tracks.size() != how_many) {
1022 if (how_many == 1) {
1023 error << _("could not create a new audio track") << endmsg;
1025 error << string_compose (_("could only create %1 of %2 new audio %3"),
1026 tracks.size(), how_many, (track ? _("tracks") : _("busses"))) << endmsg;
1032 routes = session->new_audio_route (input_channels, output_channels, how_many);
1034 if (routes.size() != how_many) {
1035 if (how_many == 1) {
1036 error << _("could not create a new audio track") << endmsg;
1038 error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg;
1044 if (need_control_room_outs) {
1050 route->set_stereo_control_outs (control_lr_channels);
1051 route->control_outs()->set_stereo_pan (pans, this);
1053 #endif /* CONTROLOUTS */
1057 cerr << "About to complain about JACK\n";
1058 MessageDialog msg (*editor,
1059 _("There are insufficient JACK ports available\n\
1060 to create a new track or bus.\n\
1061 You should save Ardour, exit and\n\
1062 restart JACK with more ports."));
1068 ARDOUR_UI::do_transport_locate (nframes_t new_position)
1070 nframes_t _preroll = 0;
1073 // XXX CONFIG_CHANGE FIX - requires AnyTime handling
1074 // _preroll = session->convert_to_frames_at (new_position, Config->get_preroll());
1076 if (new_position > _preroll) {
1077 new_position -= _preroll;
1082 session->request_locate (new_position);
1087 ARDOUR_UI::transport_goto_start ()
1090 session->goto_start();
1093 /* force displayed area in editor to start no matter
1094 what "follow playhead" setting is.
1098 editor->reset_x_origin (session->current_start_frame());
1104 ARDOUR_UI::transport_goto_zero ()
1107 session->request_locate (0);
1110 /* force displayed area in editor to start no matter
1111 what "follow playhead" setting is.
1115 editor->reset_x_origin (0);
1121 ARDOUR_UI::transport_goto_end ()
1124 nframes_t frame = session->current_end_frame();
1125 session->request_locate (frame);
1127 /* force displayed area in editor to start no matter
1128 what "follow playhead" setting is.
1132 editor->reset_x_origin (frame);
1138 ARDOUR_UI::transport_stop ()
1144 if (session->is_auditioning()) {
1145 session->cancel_audition ();
1149 if (session->get_play_loop ()) {
1150 session->request_play_loop (false);
1153 session->request_stop ();
1157 ARDOUR_UI::transport_stop_and_forget_capture ()
1160 session->request_stop (true);
1165 ARDOUR_UI::remove_last_capture()
1168 editor->remove_last_capture();
1173 ARDOUR_UI::transport_record ()
1176 switch (session->record_status()) {
1177 case Session::Disabled:
1178 if (session->ntracks() == 0) {
1179 MessageDialog msg (*editor, _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu."));
1183 session->maybe_enable_record ();
1185 case Session::Recording:
1186 case Session::Enabled:
1187 session->disable_record (true);
1193 ARDOUR_UI::transport_roll ()
1201 rolling = session->transport_rolling ();
1203 if (session->get_play_loop()) {
1204 session->request_play_loop (false);
1205 auto_loop_button.set_visual_state (1);
1206 roll_button.set_visual_state (1);
1207 } else if (session->get_play_range ()) {
1208 session->request_play_range (false);
1209 play_selection_button.set_visual_state (0);
1210 } else if (rolling) {
1211 session->request_locate (session->last_transport_start(), true);
1214 session->request_transport_speed (1.0f);
1218 ARDOUR_UI::transport_loop()
1221 if (session->get_play_loop()) {
1222 if (session->transport_rolling()) {
1223 Location * looploc = session->locations()->auto_loop_location();
1225 session->request_locate (looploc->start(), true);
1230 session->request_play_loop (true);
1236 ARDOUR_UI::transport_play_selection ()
1242 if (!session->get_play_range()) {
1243 session->request_stop ();
1246 editor->play_selection ();
1250 ARDOUR_UI::transport_rewind (int option)
1252 float current_transport_speed;
1255 current_transport_speed = session->transport_speed();
1257 if (current_transport_speed >= 0.0f) {
1260 session->request_transport_speed (-1.0f);
1263 session->request_transport_speed (-4.0f);
1266 session->request_transport_speed (-0.5f);
1271 session->request_transport_speed (current_transport_speed * 1.5f);
1277 ARDOUR_UI::transport_forward (int option)
1279 float current_transport_speed;
1282 current_transport_speed = session->transport_speed();
1284 if (current_transport_speed <= 0.0f) {
1287 session->request_transport_speed (1.0f);
1290 session->request_transport_speed (4.0f);
1293 session->request_transport_speed (0.5f);
1298 session->request_transport_speed (current_transport_speed * 1.5f);
1304 ARDOUR_UI::toggle_record_enable (uint32_t dstream)
1310 boost::shared_ptr<Route> r;
1312 if ((r = session->route_by_remote_id (dstream)) != 0) {
1316 if ((t = dynamic_cast<Track*>(r.get())) != 0) {
1317 t->diskstream()->set_record_enabled (!t->diskstream()->record_enabled());
1326 ARDOUR_UI::queue_transport_change ()
1328 Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
1332 ARDOUR_UI::map_transport_state ()
1334 float sp = session->transport_speed();
1337 transport_rolling ();
1338 } else if (sp < 0.0f) {
1339 transport_rewinding ();
1340 } else if (sp > 0.0f) {
1341 transport_forwarding ();
1343 transport_stopped ();
1348 ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg)
1350 snprintf (buf, sizeof(buf), "%s", ((GlobalClickBox *) arg)->strings[
1351 (int) adj.get_value()].c_str());
1355 ARDOUR_UI::engine_stopped ()
1357 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
1358 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1359 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1363 ARDOUR_UI::engine_running ()
1365 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
1366 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, true);
1367 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, false);
1369 Glib::RefPtr<Action> action;
1370 char* action_name = 0;
1372 switch (engine->frames_per_cycle()) {
1374 action_name = X_("JACKLatency32");
1377 action_name = X_("JACKLatency64");
1380 action_name = X_("JACKLatency128");
1383 action_name = X_("JACKLatency512");
1386 action_name = X_("JACKLatency1024");
1389 action_name = X_("JACKLatency2048");
1392 action_name = X_("JACKLatency4096");
1395 action_name = X_("JACKLatency8192");
1398 /* XXX can we do anything useful ? */
1404 action = ActionManager::get_action (X_("JACK"), action_name);
1407 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic (action);
1408 ract->set_active ();
1414 ARDOUR_UI::engine_halted ()
1416 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
1418 ActionManager::set_sensitive (ActionManager::jack_sensitive_actions, false);
1419 ActionManager::set_sensitive (ActionManager::jack_opposite_sensitive_actions, true);
1421 update_sample_rate (0);
1423 MessageDialog msg (*editor,
1425 JACK has either been shutdown or it\n\
1426 disconnected Ardour because Ardour\n\
1427 was not fast enough. You can save the\n\
1428 session and/or try to reconnect to JACK ."));
1433 ARDOUR_UI::do_engine_start ()
1441 error << _("Unable to start the session running")
1451 ARDOUR_UI::start_engine ()
1453 if (do_engine_start () == 0) {
1454 if (session && _session_is_new) {
1455 /* we need to retain initial visual
1456 settings for a new session
1458 session->save_state ("");
1466 ARDOUR_UI::update_clocks ()
1468 if (!editor || !editor->dragging_playhead()) {
1469 Clock (session->audible_frame()); /* EMIT_SIGNAL */
1474 ARDOUR_UI::start_clocking ()
1476 clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
1480 ARDOUR_UI::stop_clocking ()
1482 clock_signal_connection.disconnect ();
1486 ARDOUR_UI::toggle_clocking ()
1489 if (clock_button.get_active()) {
1498 ARDOUR_UI::_blink (void *arg)
1501 ((ARDOUR_UI *) arg)->blink ();
1508 Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
1512 ARDOUR_UI::start_blinking ()
1514 /* Start the blink signal. Everybody with a blinking widget
1515 uses Blink to drive the widget's state.
1518 if (blink_timeout_tag < 0) {
1520 blink_timeout_tag = g_timeout_add (240, _blink, this);
1525 ARDOUR_UI::stop_blinking ()
1527 if (blink_timeout_tag >= 0) {
1528 g_source_remove (blink_timeout_tag);
1529 blink_timeout_tag = -1;
1534 ARDOUR_UI::name_io_setup (AudioEngine& engine,
1540 if (io.n_inputs().get_total() == 0) {
1545 /* XXX we're not handling multiple ports yet. */
1547 const char **connections = io.input(0)->get_connections();
1549 if (connections == 0 || connections[0] == '\0') {
1552 buf = connections[0];
1559 if (io.n_outputs().get_total() == 0) {
1564 /* XXX we're not handling multiple ports yet. */
1566 const char **connections = io.output(0)->get_connections();
1568 if (connections == 0 || connections[0] == '\0') {
1571 buf = connections[0];
1578 /** Ask the user for the name of a new shapshot and then take it.
1581 ARDOUR_UI::snapshot_session ()
1583 ArdourPrompter prompter (true);
1587 struct tm local_time;
1590 localtime_r (&n, &local_time);
1591 strftime (timebuf, sizeof(timebuf), "%FT%T", &local_time);
1593 prompter.set_name ("Prompter");
1594 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1595 prompter.set_prompt (_("Name of New Snapshot"));
1596 prompter.set_initial_text (timebuf);
1598 switch (prompter.run()) {
1599 case RESPONSE_ACCEPT:
1600 prompter.get_result (snapname);
1601 if (snapname.length()){
1602 save_state (snapname);
1612 ARDOUR_UI::save_state (const string & name)
1614 (void) save_state_canfail (name);
1618 ARDOUR_UI::save_state_canfail (string name)
1623 if (name.length() == 0) {
1624 name = session->snap_name();
1627 if ((ret = session->save_state (name)) != 0) {
1631 save_ardour_state (); /* XXX cannot fail? yeah, right ... */
1636 ARDOUR_UI::restore_state (string name)
1639 if (name.length() == 0) {
1640 name = session->name();
1642 session->restore_state (name);
1647 ARDOUR_UI::primary_clock_value_changed ()
1650 session->request_locate (primary_clock.current_time ());
1655 ARDOUR_UI::secondary_clock_value_changed ()
1658 session->request_locate (secondary_clock.current_time ());
1663 ARDOUR_UI::rec_enable_button_blink (bool onoff, AudioDiskstream *dstream, Widget *w)
1665 if (session && dstream && dstream->record_enabled()) {
1667 Session::RecordState rs;
1669 rs = session->record_status ();
1672 case Session::Disabled:
1673 case Session::Enabled:
1674 if (w->get_state() != STATE_SELECTED) {
1675 w->set_state (STATE_SELECTED);
1679 case Session::Recording:
1680 if (w->get_state() != STATE_ACTIVE) {
1681 w->set_state (STATE_ACTIVE);
1687 if (w->get_state() != STATE_NORMAL) {
1688 w->set_state (STATE_NORMAL);
1694 ARDOUR_UI::transport_rec_enable_blink (bool onoff)
1700 switch (session->record_status()) {
1701 case Session::Enabled:
1703 rec_button.set_visual_state (2);
1705 rec_button.set_visual_state (0);
1709 case Session::Recording:
1710 rec_button.set_visual_state (1);
1714 rec_button.set_visual_state (0);
1720 ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
1728 ARDOUR_UI::save_template ()
1731 ArdourPrompter prompter (true);
1734 prompter.set_name (X_("Prompter"));
1735 prompter.set_prompt (_("Name for mix template:"));
1736 prompter.set_initial_text(session->name() + _("-template"));
1737 prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT);
1739 switch (prompter.run()) {
1740 case RESPONSE_ACCEPT:
1741 prompter.get_result (name);
1743 if (name.length()) {
1744 session->save_template (name);
1754 ARDOUR_UI::new_session (std::string predetermined_path)
1756 string session_name;
1757 string session_path;
1759 if (!engine->connected()) {
1760 MessageDialog msg (_("Ardour is not connected to JACK at this time. Creating new sessions is not possible."));
1765 int response = Gtk::RESPONSE_NONE;
1767 new_session_dialog->set_modal(true);
1768 new_session_dialog->set_name (predetermined_path);
1769 new_session_dialog->reset_recent();
1770 new_session_dialog->show();
1773 response = new_session_dialog->run ();
1775 if (!engine->connected()) {
1776 new_session_dialog->hide ();
1777 MessageDialog msg (_("Ardour is not connected to JACK at this time. Creating new sessions is not possible."));
1782 _session_is_new = false;
1784 if (response == Gtk::RESPONSE_CANCEL || response == Gtk::RESPONSE_DELETE_EVENT) {
1789 new_session_dialog->hide ();
1792 } else if (response == Gtk::RESPONSE_NONE) {
1794 /* Clear was pressed */
1795 new_session_dialog->reset();
1797 } else if (response == Gtk::RESPONSE_YES) {
1799 /* YES == OPEN, but there's no enum for that */
1801 session_name = new_session_dialog->session_name();
1803 if (session_name.empty()) {
1804 response = Gtk::RESPONSE_NONE;
1808 if (session_name[0] == '/' ||
1809 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1810 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1811 load_session (Glib::path_get_dirname (session_name), session_name);
1813 session_path = new_session_dialog->session_folder();
1814 load_session (session_path, session_name);
1817 } else if (response == Gtk::RESPONSE_OK) {
1819 session_name = new_session_dialog->session_name();
1821 if (new_session_dialog->get_current_page() == 1) {
1823 /* XXX this is a bit of a hack..
1824 i really want the new sesion dialog to return RESPONSE_YES
1825 if we're on page 1 (the load page)
1826 Unfortunately i can't see how atm..
1829 if (session_name.empty()) {
1830 response = Gtk::RESPONSE_NONE;
1834 if (session_name[0] == '/' ||
1835 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1836 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1837 load_session (Glib::path_get_dirname (session_name), session_name);
1839 session_path = new_session_dialog->session_folder();
1840 load_session (session_path, session_name);
1845 if (session_name.empty()) {
1846 response = Gtk::RESPONSE_NONE;
1850 if (session_name[0] == '/' ||
1851 (session_name.length() > 2 && session_name[0] == '.' && session_name[1] == '/') ||
1852 (session_name.length() > 3 && session_name[0] == '.' && session_name[1] == '.' && session_name[2] == '/')) {
1854 session_path = Glib::path_get_dirname (session_name);
1855 session_name = Glib::path_get_basename (session_name);
1859 session_path = new_session_dialog->session_folder();
1863 //XXX This is needed because session constructor wants a
1864 //non-existant path. hopefully this will be fixed at some point.
1866 session_path = Glib::build_filename (session_path, session_name);
1868 if (g_file_test (session_path.c_str(), GFileTest (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
1870 Glib::ustring str = string_compose (_("This session\n%1\nalready exists. Do you want to open it?"), session_path);
1872 MessageDialog msg (str,
1874 Gtk::MESSAGE_WARNING,
1875 Gtk::BUTTONS_YES_NO,
1879 msg.set_name (X_("CleanupDialog"));
1880 msg.set_wmclass (X_("existing_session"), "Ardour");
1881 msg.set_position (Gtk::WIN_POS_MOUSE);
1883 switch (msg.run()) {
1885 load_session (session_path, session_name);
1889 response = RESPONSE_NONE;
1890 new_session_dialog->reset ();
1895 _session_is_new = true;
1897 std::string template_name = new_session_dialog->session_template_name();
1899 if (new_session_dialog->use_session_template()) {
1901 load_session (session_path, session_name, &template_name);
1907 AutoConnectOption iconnect;
1908 AutoConnectOption oconnect;
1910 if (new_session_dialog->create_control_bus()) {
1911 cchns = (uint32_t) new_session_dialog->control_channel_count();
1916 if (new_session_dialog->create_master_bus()) {
1917 mchns = (uint32_t) new_session_dialog->master_channel_count();
1922 if (new_session_dialog->connect_inputs()) {
1923 iconnect = AutoConnectPhysical;
1925 iconnect = AutoConnectOption (0);
1928 /// @todo some minor tweaks.
1930 if (new_session_dialog->connect_outs_to_master()) {
1931 oconnect = AutoConnectMaster;
1932 } else if (new_session_dialog->connect_outs_to_physical()) {
1933 oconnect = AutoConnectPhysical;
1935 oconnect = AutoConnectOption (0);
1938 uint32_t nphysin = (uint32_t) new_session_dialog->input_limit_count();
1939 uint32_t nphysout = (uint32_t) new_session_dialog->output_limit_count();
1941 if (build_session (session_path,
1949 engine->frame_rate() * 60 * 5)) {
1951 response = Gtk::RESPONSE_NONE;
1952 new_session_dialog->reset ();
1959 } while (response == Gtk::RESPONSE_NONE);
1963 new_session_dialog->get_window()->set_cursor();
1964 new_session_dialog->hide();
1969 ARDOUR_UI::close_session()
1976 ARDOUR_UI::load_session (const string & path, const string & snap_name, string* mix_template)
1978 Session *new_session;
1980 session_loaded = false;
1982 x = unload_session ();
1990 /* if it already exists, we must have write access */
1992 if (::access (path.c_str(), F_OK) == 0 && ::access (path.c_str(), W_OK)) {
1993 MessageDialog msg (*editor, _("You do not have write access to this session.\n"
1994 "This prevents the session from being loaded."));
2000 new_session = new Session (*engine, path, snap_name, mix_template);
2005 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
2009 connect_to_session (new_session);
2011 Config->set_current_owner (ConfigVariableBase::Interface);
2013 session_loaded = true;
2015 goto_editor_window ();
2018 session->set_clean ();
2021 editor->edit_cursor_position (true);
2026 ARDOUR_UI::build_session (const string & path, const string & snap_name,
2027 uint32_t control_channels,
2028 uint32_t master_channels,
2029 AutoConnectOption input_connect,
2030 AutoConnectOption output_connect,
2033 nframes_t initial_length)
2035 Session *new_session;
2038 session_loaded = false;
2039 x = unload_session ();
2046 _session_is_new = true;
2049 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
2050 control_channels, master_channels, nphysin, nphysout, initial_length);
2055 MessageDialog msg (string_compose(_("Could not create session in \"%1\""), path));
2060 connect_to_session (new_session);
2062 session_loaded = true;
2070 editor->show_window ();
2081 ARDOUR_UI::show_splash ()
2084 about = new About();
2085 about->signal_response().connect(mem_fun (*this, &ARDOUR_UI::about_signal_response) );
2092 ARDOUR_UI::about_signal_response(int response)
2098 ARDOUR_UI::hide_splash ()
2101 about->get_window()->set_cursor ();
2107 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title, const string & msg)
2111 removed = rep.paths.size();
2114 MessageDialog msgd (*editor,
2115 _("No audio files were ready for cleanup"),
2118 (Gtk::ButtonsType)(Gtk::BUTTONS_OK) );
2119 msgd.set_secondary_text (_("If this seems suprising, \n\
2120 check for any existing snapshots.\n\
2121 These may still include regions that\n\
2122 require some unused files to continue to exist."));
2128 ArdourDialog results (_("ardour: cleanup"), true, false);
2130 struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
2131 CleanupResultsModelColumns() {
2135 Gtk::TreeModelColumn<Glib::ustring> visible_name;
2136 Gtk::TreeModelColumn<Glib::ustring> fullpath;
2140 CleanupResultsModelColumns results_columns;
2141 Glib::RefPtr<Gtk::ListStore> results_model;
2142 Gtk::TreeView results_display;
2144 results_model = ListStore::create (results_columns);
2145 results_display.set_model (results_model);
2146 results_display.append_column (list_title, results_columns.visible_name);
2148 results_display.set_name ("CleanupResultsList");
2149 results_display.set_headers_visible (true);
2150 results_display.set_headers_clickable (false);
2151 results_display.set_reorderable (false);
2153 Gtk::ScrolledWindow list_scroller;
2156 Gtk::HBox dhbox; // the hbox for the image and text
2157 Gtk::HBox ddhbox; // the hbox we eventually pack into the dialog's vbox
2158 Gtk::Image* dimage = manage (new Gtk::Image(Stock::DIALOG_INFO, Gtk::ICON_SIZE_DIALOG));
2160 dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP);
2162 if (rep.space < 1048576.0f) {
2164 txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2166 txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1024.0f, "kilo"));
2170 txt.set_text (string_compose (msg, removed, _("files were"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2172 txt.set_text (string_compose (msg, removed, _("file was"), session->path() + "dead_sounds", (float) rep.space / 1048576.0f, "mega"));
2176 dhbox.pack_start (*dimage, true, false, 5);
2177 dhbox.pack_start (txt, true, false, 5);
2179 for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2180 TreeModel::Row row = *(results_model->append());
2181 row[results_columns.visible_name] = *i;
2182 row[results_columns.fullpath] = *i;
2185 list_scroller.add (results_display);
2186 list_scroller.set_size_request (-1, 150);
2187 list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2189 dvbox.pack_start (dhbox, true, false, 5);
2190 dvbox.pack_start (list_scroller, true, false, 5);
2191 ddhbox.pack_start (dvbox, true, false, 5);
2193 results.get_vbox()->pack_start (ddhbox, true, false, 5);
2194 results.add_button (Stock::CLOSE, RESPONSE_CLOSE);
2195 results.set_default_response (RESPONSE_CLOSE);
2196 results.set_position (Gtk::WIN_POS_MOUSE);
2197 results.show_all_children ();
2198 results.set_resizable (false);
2205 ARDOUR_UI::cleanup ()
2208 /* shouldn't happen: menu item is insensitive */
2213 MessageDialog checker (_("Are you sure you want to cleanup?"),
2215 Gtk::MESSAGE_QUESTION,
2216 (Gtk::ButtonsType)(Gtk::BUTTONS_NONE));
2218 checker.set_secondary_text(_("Cleanup is a destructive operation.\n\
2219 ALL undo/redo information will be lost if you cleanup.\n\
2220 After cleanup, unused audio files will be moved to a \
2221 \"dead sounds\" location."));
2223 checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2224 checker.add_button (_("Clean Up"), RESPONSE_ACCEPT);
2225 checker.set_default_response (RESPONSE_CANCEL);
2227 checker.set_name (_("CleanupDialog"));
2228 checker.set_wmclass (X_("ardour_cleanup"), "Ardour");
2229 checker.set_position (Gtk::WIN_POS_MOUSE);
2231 switch (checker.run()) {
2232 case RESPONSE_ACCEPT:
2238 Session::cleanup_report rep;
2240 editor->prepare_for_cleanup ();
2242 /* do not allow flush until a session is reloaded */
2244 Glib::RefPtr<Action> act = ActionManager::get_action (X_("Main"), X_("FlushWastebasket"));
2246 act->set_sensitive (false);
2249 if (session->cleanup_sources (rep)) {
2254 display_cleanup_results (rep,
2257 The following %1 %2 not in use and \n\
2258 have been moved to:\n\
2260 Flushing the wastebasket will \n\
2261 release an additional\n\
2262 %4 %5bytes of disk space.\n"
2270 ARDOUR_UI::flush_trash ()
2273 /* shouldn't happen: menu item is insensitive */
2277 Session::cleanup_report rep;
2279 if (session->cleanup_trash_sources (rep)) {
2283 display_cleanup_results (rep,
2285 _("The following %1 %2 deleted from\n\
2287 releasing %4 %5bytes of disk space"));
2291 ARDOUR_UI::add_route (Gtk::Window* float_window)
2299 if (add_route_dialog == 0) {
2300 add_route_dialog = new AddRouteDialog;
2302 add_route_dialog->set_transient_for (*float_window);
2306 if (add_route_dialog->is_visible()) {
2307 /* we're already doing this */
2311 ResponseType r = (ResponseType) add_route_dialog->run ();
2313 add_route_dialog->hide();
2316 case RESPONSE_ACCEPT:
2323 if ((count = add_route_dialog->count()) <= 0) {
2327 uint32_t input_chan = add_route_dialog->channels ();
2328 uint32_t output_chan;
2329 string name_template = add_route_dialog->name_template ();
2330 bool track = add_route_dialog->track ();
2332 AutoConnectOption oac = Config->get_output_auto_connect();
2334 if (oac & AutoConnectMaster) {
2335 output_chan = (session->master_out() ? session->master_out()->n_inputs().get(DataType::AUDIO) : input_chan);
2337 output_chan = input_chan;
2340 /* XXX do something with name template */
2342 if (add_route_dialog->type() == ARDOUR::DataType::MIDI) {
2344 session_add_midi_track(count);
2346 MessageDialog msg (*editor,
2347 _("Sorry, MIDI Busses are not supported at this time."));
2349 //session_add_midi_bus();
2353 session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), count);
2355 session_add_audio_bus (input_chan, output_chan, count);
2361 ARDOUR_UI::mixer_settings () const
2366 node = session->instant_xml(X_("Mixer"), session->path());
2368 node = Config->instant_xml(X_("Mixer"), get_user_ardour_path());
2372 node = new XMLNode (X_("Mixer"));
2379 ARDOUR_UI::editor_settings () const
2384 node = session->instant_xml(X_("Editor"), session->path());
2386 node = Config->instant_xml(X_("Editor"), get_user_ardour_path());
2390 node = new XMLNode (X_("Editor"));
2396 ARDOUR_UI::keyboard_settings () const
2400 node = Config->extra_xml(X_("Keyboard"));
2403 node = new XMLNode (X_("Keyboard"));
2409 ARDOUR_UI::halt_on_xrun_message ()
2411 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
2413 MessageDialog msg (*editor,
2414 _("Recording was stopped because your system could not keep up."));
2419 ARDOUR_UI::disk_overrun_handler ()
2421 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
2423 if (!have_disk_speed_dialog_displayed) {
2424 have_disk_speed_dialog_displayed = true;
2425 MessageDialog* msg = new MessageDialog (*editor, _("\
2426 The disk system on your computer\n\
2427 was not able to keep up with Ardour.\n\
2429 Specifically, it failed to write data to disk\n\
2430 quickly enough to keep up with recording.\n"));
2431 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
2437 ARDOUR_UI::disk_underrun_handler ()
2439 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
2441 if (!have_disk_speed_dialog_displayed) {
2442 have_disk_speed_dialog_displayed = true;
2443 MessageDialog* msg = new MessageDialog (*editor,
2444 _("The disk system on your computer\n\
2445 was not able to keep up with Ardour.\n\
2447 Specifically, it failed to read data from disk\n\
2448 quickly enough to keep up with playback.\n"));
2449 msg->signal_response().connect (bind (mem_fun (*this, &ARDOUR_UI::disk_speed_dialog_gone), msg));
2455 ARDOUR_UI::disk_speed_dialog_gone (int ignored_response, MessageDialog* msg)
2457 have_disk_speed_dialog_displayed = false;
2462 ARDOUR_UI::pending_state_dialog ()
2464 ArdourDialog dialog ("pending state dialog");
2466 This session appears to have been in\n\
2467 middle of recording when ardour or\n\
2468 the computer was shutdown.\n\
2470 Ardour can recover any captured audio for\n\
2471 you, or it can ignore it. Please decide\n\
2472 what you would like to do.\n"));
2474 dialog.get_vbox()->pack_start (message);
2475 dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
2476 dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
2478 dialog.set_position (WIN_POS_CENTER);
2481 switch (dialog.run ()) {
2482 case RESPONSE_ACCEPT:
2490 ARDOUR_UI::disconnect_from_jack ()
2493 if( engine->disconnect_from_jack ()) {
2494 MessageDialog msg (*editor, _("Could not disconnect from JACK"));
2498 update_sample_rate (0);
2503 ARDOUR_UI::reconnect_to_jack ()
2506 if (engine->reconnect_to_jack ()) {
2507 MessageDialog msg (*editor, _("Could not reconnect to JACK"));
2511 update_sample_rate (0);
2516 ARDOUR_UI::cmdline_new_session (string path)
2518 if (path[0] != '/') {
2519 char buf[PATH_MAX+1];
2522 getcwd (buf, sizeof (buf));
2531 _will_create_new_session_automatically = false; /* done it */
2532 return FALSE; /* don't call it again */
2536 ARDOUR_UI::use_config ()
2538 Glib::RefPtr<Action> act;
2540 switch (Config->get_native_file_data_format ()) {
2542 act = ActionManager::get_action (X_("options"), X_("FileDataFormatFloat"));
2545 act = ActionManager::get_action (X_("options"), X_("FileDataFormat24bit"));
2550 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2551 ract->set_active ();
2554 switch (Config->get_native_file_header_format ()) {
2556 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatBWF"));
2559 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE"));
2562 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatWAVE64"));
2565 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatiXML"));
2568 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatRF64"));
2571 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatCAF"));
2574 act = ActionManager::get_action (X_("options"), X_("FileHeaderFormatAIFF"));
2579 Glib::RefPtr<RadioAction> ract = Glib::RefPtr<RadioAction>::cast_dynamic(act);
2580 ract->set_active ();
2583 XMLNode* node = Config->extra_xml (X_("TransportControllables"));
2585 set_transport_controllable_state (*node);
2590 ARDOUR_UI::update_transport_clocks (nframes_t pos)
2592 primary_clock.set (pos);
2593 secondary_clock.set (pos);
2595 if (big_clock_window) {
2596 big_clock.set (pos);
2601 ARDOUR_UI::record_state_changed ()
2603 ENSURE_GUI_THREAD (mem_fun (*this, &ARDOUR_UI::record_state_changed));
2605 if (!session || !big_clock_window) {
2606 /* why bother - the clock isn't visible */
2610 switch (session->record_status()) {
2611 case Session::Recording:
2612 big_clock.set_widget_name ("BigClockRecording");
2615 big_clock.set_widget_name ("BigClockNonRecording");
2621 ARDOUR_UI::set_keybindings_path (string path)
2623 keybindings_path = path;
2627 ARDOUR_UI::save_keybindings ()
2629 if (can_save_keybindings) {
2630 AccelMap::save (keybindings_path);
2635 ARDOUR_UI::first_idle ()
2638 session->allow_auto_play (true);
2640 can_save_keybindings = true;
2645 ARDOUR_UI::store_clock_modes ()
2647 XMLNode* node = new XMLNode(X_("ClockModes"));
2649 for (vector<AudioClock*>::iterator x = AudioClock::clocks.begin(); x != AudioClock::clocks.end(); ++x) {
2650 node->add_property ((*x)->name().c_str(), enum_2_string ((*x)->mode()));
2653 session->add_extra_xml (*node);
2654 session->set_dirty ();
2659 ARDOUR_UI::TransportControllable::TransportControllable (std::string name, ARDOUR_UI& u, ToggleType tp)
2660 : Controllable (name), ui (u), type(tp)
2666 ARDOUR_UI::TransportControllable::set_value (float val)
2668 if (type == ShuttleControl) {
2675 fract = -((0.5f - val)/0.5f);
2677 fract = ((val - 0.5f)/0.5f);
2681 ui.set_shuttle_fract (fract);
2686 /* do nothing: these are radio-style actions */
2694 action = X_("Roll");
2697 action = X_("Stop");
2700 action = X_("Goto Start");
2703 action = X_("Goto End");
2706 action = X_("Loop");
2709 action = X_("Play Selection");
2712 action = X_("Record");
2722 Glib::RefPtr<Action> act = ActionManager::get_action ("Transport", action);
2730 ARDOUR_UI::TransportControllable::get_value (void) const
2749 case ShuttleControl:
2759 ARDOUR_UI::TransportControllable::set_id (const string& str)
2765 ARDOUR_UI::setup_profile ()
2767 if (gdk_screen_width() < 1200) {
2768 Profile->set_small_screen ();