2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 #include <pbd/error.h>
32 #include <pbd/compose.h>
33 #include <pbd/basename.h>
34 #include <pbd/pathscanner.h>
35 #include <pbd/failed_constructor.h>
36 #include <gtkmm2ext/gtk_ui.h>
37 #include <gtkmm2ext/pix.h>
38 #include <gtkmm2ext/utils.h>
39 #include <gtkmm2ext/click_box.h>
40 #include <gtkmm2ext/fastmeter.h>
41 #include <gtkmm2ext/stop_signal.h>
42 #include <gtkmm2ext/popup.h>
44 #include <midi++/port.h>
45 #include <midi++/mmc.h>
47 #include <ardour/ardour.h>
48 #include <ardour/port.h>
49 #include <ardour/audioengine.h>
50 #include <ardour/playlist.h>
51 #include <ardour/utils.h>
52 #include <ardour/diskstream.h>
53 #include <ardour/filesource.h>
54 #include <ardour/recent_sessions.h>
55 #include <ardour/session_diskstream.h>
56 #include <ardour/port.h>
57 #include <ardour/audio_track.h>
60 #include "ardour_ui.h"
61 #include "ardour_message.h"
62 #include "public_editor.h"
63 #include "audio_clock.h"
68 #include "keyboard_target.h"
69 #include "add_route_dialog.h"
70 #include "new_session_dialog.h"
73 #include "gui_thread.h"
77 using namespace ARDOUR;
78 using namespace Gtkmm2ext;
82 ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
84 sigc::signal<void,bool> ARDOUR_UI::Blink;
85 sigc::signal<void> ARDOUR_UI::RapidScreenUpdate;
86 sigc::signal<void> ARDOUR_UI::SuperRapidScreenUpdate;
87 sigc::signal<void,jack_nframes_t> ARDOUR_UI::Clock;
90 static const gchar *h_meter_strip_xpm[] = {
279 ". + @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / ( _ : < [ } | 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ` ...+.@.@.#.$.%.&.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +.+",
280 ". + @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / ( _ : < [ } | 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ` ...+.@.@.#.$.%.&.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +.+",
281 ". + @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / ( _ : < [ } | 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ` ...+.@.@.#.$.%.&.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +++",
282 ". + @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / ( _ : < [ } | 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ` ...+.@.@.#.$.%.&.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +++",
283 ". + @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / ( _ : < [ } | 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ` ...+.@.@.#.$.%.&.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +++"};
286 static const gchar * v_meter_strip_xpm[] = {
769 static const char* channel_setup_names[] = {
780 vector<string> channel_combo_strings;
782 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
784 : Gtkmm2ext::UI ("ardour", argcp, argvp, rcfile),
786 primary_clock (X_("TransportClockDisplay"), true, false, true),
787 secondary_clock (X_("SecondaryClockDisplay"), true, false, true),
788 preroll_clock (X_("PreRollClock"), true, true),
789 postroll_clock (X_("PostRollClock"), true, true),
793 adjuster_table (3, 3),
797 preroll_button (_("pre\nroll")),
798 postroll_button (_("post\nroll")),
802 big_clock ("BigClockDisplay", true),
806 shuttle_units_button (_("% ")),
807 shuttle_style_button (_("spring")),
809 punch_in_button (_("punch\nin")),
810 punch_out_button (_("punch\nout")),
811 auto_return_button (_("auto\nreturn")),
812 auto_play_button (_("auto\nplay")),
813 auto_input_button (_("auto\ninput")),
814 click_button (_("click")),
815 follow_button (_("follow\nPH")),
816 auditioning_alert_button (_("AUDITIONING")),
817 solo_alert_button (_("SOLO")),
821 using namespace Gtk::Menu_Helpers;
825 /* actually, its already loaded, but ... */
827 cerr << "Loading UI configuration file " << rcfile << endl;
831 if (theArdourUI == 0) {
835 ActionManager::init ();
837 m_new_session_dialog = 0;
838 m_new_session_dialog_ref = NewSessionDialogFactory::create();
839 m_new_session_dialog_ref->get_widget_derived (NewSessionDialogFactory::top_level_widget_name(), m_new_session_dialog);
843 _session_is_new = false;
844 big_clock_window = 0;
845 session_selector_window = 0;
846 last_key_press_time = 0;
847 connection_editor = 0;
848 add_route_dialog = 0;
852 open_session_selector = 0;
853 have_configure_timeout = false;
854 have_disk_overrun_displayed = false;
855 have_disk_underrun_displayed = false;
856 _will_create_new_session_automatically = false;
857 session_loaded = false;
860 last_configure_time.tv_sec = 0;
861 last_configure_time.tv_usec = 0;
863 shuttle_grabbed = false;
866 set_shuttle_units (Percentage);
867 set_shuttle_behaviour (Sprung);
869 Glib::RefPtr<ActionGroup> shuttle_actions = ActionGroup::create ("ShuttleActions");
871 shuttle_actions->add (Action::create (X_("SetShuttleUnitsPercentage"), _("Percentage")), bind (mem_fun(*this, &ARDOUR_UI::set_shuttle_units), Percentage));
872 shuttle_actions->add (Action::create (X_("SetShuttleUnitsSemitones"), _("Semitones")), bind (mem_fun(*this, &ARDOUR_UI::set_shuttle_units), Semitones));
873 shuttle_actions->add (Action::create (X_("SetShuttleActionSprung"), _("Sprung")), bind (mem_fun(*this, &ARDOUR_UI::set_shuttle_behaviour), Sprung));
874 shuttle_actions->add (Action::create (X_("SetShuttleActionWheel"), _("Wheel")), bind (mem_fun(*this, &ARDOUR_UI::set_shuttle_behaviour), Wheel));
876 ActionManager::add_action_group (shuttle_actions);
878 shuttle_style_menu = dynamic_cast<Menu*> (ActionManager::get_widget ("ShuttleStylePopup"));
879 shuttle_unit_menu = dynamic_cast<Menu*> (ActionManager::get_widget ("ShuttleUnitPopup"));
881 gettimeofday (&last_peak_grab, 0);
882 gettimeofday (&last_shuttle_request, 0);
884 ARDOUR::DiskStream::CannotRecordNoInput.connect (mem_fun(*this, &ARDOUR_UI::cannot_record_no_input));
885 ARDOUR::DiskStream::DeleteSources.connect (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread));
886 ARDOUR::DiskStream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
887 ARDOUR::DiskStream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
889 /* handle pending state with a dialog */
891 ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
893 channel_combo_strings = internationalize (channel_setup_names);
895 /* have to wait for AudioEngine and Configuration before proceeding */
899 ARDOUR_UI::cannot_record_no_input (DiskStream* ds)
901 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::cannot_record_no_input), ds));
903 string msg = string_compose (_("\
904 You cannot record-enable\n\
906 because it has no input connections.\n\
907 You would be wasting space recording silence."),
910 ArdourMessage message (editor, X_("cannotrecord"), msg);
914 ARDOUR_UI::set_engine (AudioEngine& e)
918 engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
919 engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
920 engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
921 engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
925 keyboard = new Keyboard;
926 install_keybindings ();
928 FastMeter::set_vertical_xpm (v_meter_strip_xpm);
929 FastMeter::set_horizontal_xpm (h_meter_strip_xpm);
931 if (setup_windows ()) {
932 throw failed_constructor ();
935 if (GTK_ARDOUR::show_key_actions) {
937 // show_all_actions ();
941 /* start with timecode, metering enabled
944 blink_timeout_tag = -1;
946 /* this being a GUI and all, we want peakfiles */
948 FileSource::set_build_peakfiles (true);
949 FileSource::set_build_missing_peakfiles (true);
951 if (Source::start_peak_thread ()) {
952 throw failed_constructor();
955 /* start the time-of-day-clock */
957 update_wall_clock ();
958 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
960 update_disk_space ();
962 update_sample_rate (engine->frame_rate());
964 starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
965 stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
968 ARDOUR_UI::~ARDOUR_UI ()
970 save_ardour_state ();
984 if (add_route_dialog) {
985 delete add_route_dialog;
988 Source::stop_peak_thread ();
992 ARDOUR_UI::configure_timeout ()
997 if (last_configure_time.tv_sec == 0 && last_configure_time.tv_usec == 0) {
998 /* no configure events yet */
1002 gettimeofday (&now, 0);
1003 timersub (&now, &last_configure_time, &diff);
1005 /* force a gap of 0.5 seconds since the last configure event
1008 if (diff.tv_sec == 0 && diff.tv_usec < 500000) {
1011 have_configure_timeout = false;
1012 save_ardour_state ();
1018 ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
1020 if (have_configure_timeout) {
1021 gettimeofday (&last_configure_time, 0);
1023 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
1024 have_configure_timeout = true;
1031 ARDOUR_UI::save_ardour_state ()
1033 if (!keyboard || !mixer || !editor) {
1037 /* XXX this is all a bit dubious. add_extra_xml() uses
1038 a different lifetime model from add_instant_xml().
1041 XMLNode* node = new XMLNode (keyboard->get_state());
1042 Config->add_extra_xml (*node);
1043 Config->save_state();
1045 XMLNode& enode (static_cast<Stateful*>(editor)->get_state());
1046 XMLNode& mnode (mixer->get_state());
1049 session->add_instant_xml(enode, session->path());
1050 session->add_instant_xml(mnode, session->path());
1052 Config->add_instant_xml(enode, Config->get_user_ardour_path());
1053 Config->add_instant_xml(mnode, Config->get_user_ardour_path());
1058 ARDOUR_UI::startup ()
1060 /* Once the UI is up and running, start the audio engine. Doing
1061 this before the UI is up and running can cause problems
1062 when not running with SCHED_FIFO, because the amount of
1063 CPU and disk work needed to get the UI started can interfere
1064 with the scheduling of the audio thread.
1067 Glib::signal_idle().connect (mem_fun(*this, &ARDOUR_UI::start_engine));
1073 if (session && session->dirty()) {
1074 switch (ask_about_saving_session(_("quit"))) {
1079 /* use the default name */
1080 if (save_state_canfail ("")) {
1081 /* failed - don't quit */
1082 ArdourMessage (editor, X_("badsave dialog"),
1084 Ardour was unable to save your session.\n\n\
1085 If you still wish to quit, please use the\n\n\
1086 \"Just quit\" option."));
1099 ARDOUR_UI::ask_about_saving_session (string what)
1101 ArdourDialog window (_("ardour: save session?"));
1102 Gtk::Label prompt_label;
1105 msg = string_compose(_("Save and %1"), what);
1106 window.add_button (msg, RESPONSE_ACCEPT);
1107 msg = string_compose(_("Just %1"), what);
1108 window.add_button (msg, RESPONSE_REJECT);
1109 msg = string_compose(_("Don't %1"), what);
1110 window.add_button (msg, RESPONSE_REJECT);
1112 Gtk::Button noquit_button (msg);
1113 noquit_button.set_name ("EditorGTKButton");
1118 if (session->snap_name() == session->name()) {
1119 type = _("session");
1121 type = _("snapshot");
1123 prompt = string_compose(_("The %1\n\"%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?"),
1124 type, session->snap_name());
1126 prompt_label.set_text (prompt);
1127 prompt_label.set_alignment (0.5, 0.5);
1128 prompt_label.set_name (X_("PrompterLabel"));
1130 window.get_vbox()->pack_start (prompt_label);
1132 window.set_name (_("Prompter"));
1133 window.set_position (Gtk::WIN_POS_MOUSE);
1134 window.set_modal (true);
1137 save_the_session = 0;
1139 editor->ensure_float (window);
1141 ResponseType r = (ResponseType) window.run();
1146 case RESPONSE_ACCEPT:
1156 ARDOUR_UI::every_second ()
1159 update_buffer_load ();
1160 update_disk_space ();
1161 // update_disk_rate ();
1166 ARDOUR_UI::every_point_one_seconds ()
1169 struct timeval diff;
1171 /* do not attempt to grab peak power more than once per cycle.
1174 gettimeofday (&now, 0);
1175 timersub (&now, &last_peak_grab, &diff);
1177 if ((diff.tv_usec + (diff.tv_sec * 1000000)) >= engine->usecs_per_cycle()) {
1178 IO::GrabPeakPower(); /* EMIT_SIGNAL */
1179 last_peak_grab = now;
1182 update_speed_display ();
1183 RapidScreenUpdate(); /* EMIT_SIGNAL */
1188 ARDOUR_UI::every_point_zero_one_seconds ()
1190 SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
1195 ARDOUR_UI::update_sample_rate (jack_nframes_t ignored)
1199 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
1201 if (!engine->connected()) {
1203 snprintf (buf, sizeof (buf), _("disconnected"));
1207 jack_nframes_t rate = engine->frame_rate();
1209 if (fmod (rate, 1000.0) != 0.0) {
1210 snprintf (buf, sizeof (buf), _("SR: %.1f kHz / %4.1f msecs"),
1211 (float) rate/1000.0f,
1212 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
1214 snprintf (buf, sizeof (buf), _("SR: %u kHz / %4.1f msecs"),
1216 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
1220 sample_rate_label.set_text (buf);
1224 ARDOUR_UI::update_cpu_load ()
1227 snprintf (buf, sizeof (buf), _("DSP Load: %.1f%%"), engine->get_cpu_load());
1228 cpu_load_label.set_text (buf);
1232 ARDOUR_UI::update_disk_rate ()
1237 snprintf (buf, sizeof (buf), _("Disk r:%5.1f w:%5.1f MB/s"),
1238 session->read_data_rate()/1048576.0f, session->write_data_rate()/1048576.0f);
1239 disk_rate_label.set_text (buf);
1241 disk_rate_label.set_text ("");
1246 ARDOUR_UI::update_buffer_load ()
1251 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"),
1252 session->playback_load(), session->capture_load());
1253 buffer_load_label.set_text (buf);
1255 buffer_load_label.set_text ("");
1260 ARDOUR_UI::count_recenabled_diskstreams (DiskStream& ds)
1262 if (ds.record_enabled()) {
1263 rec_enabled_diskstreams++;
1268 ARDOUR_UI::update_disk_space()
1274 jack_nframes_t frames = session->available_capture_duration();
1277 if (frames == max_frames) {
1278 strcpy (buf, _("space: 24hrs+"));
1283 jack_nframes_t fr = session->frame_rate();
1285 if (session->actively_recording()){
1287 rec_enabled_diskstreams = 0;
1288 session->foreach_diskstream (this, &ARDOUR_UI::count_recenabled_diskstreams);
1290 if (rec_enabled_diskstreams) {
1291 frames /= rec_enabled_diskstreams;
1296 /* hmmm. shall we divide by the route count? or the diskstream count?
1297 or what? for now, do nothing ...
1302 hrs = frames / (fr * 3600);
1303 frames -= hrs * fr * 3600;
1304 mins = frames / (fr * 60);
1305 frames -= mins * fr * 60;
1308 snprintf (buf, sizeof(buf), _("space: %02dh:%02dm:%02ds"), hrs, mins, secs);
1311 disk_space_label.set_text (buf);
1315 ARDOUR_UI::update_wall_clock ()
1322 tm_now = localtime (&now);
1324 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
1325 wall_clock_label.set_text (buf);
1331 ARDOUR_UI::toggle_recording_plugins ()
1333 /* XXX use toggle_some_session_state */
1339 session->set_recording_plugins (!session->get_recording_plugins());
1343 ARDOUR_UI::toggle_auto_play ()
1346 toggle_some_session_state (auto_play_button,
1347 &Session::get_auto_play,
1348 &Session::set_auto_play);
1352 ARDOUR_UI::toggle_auto_return ()
1355 toggle_some_session_state (auto_return_button,
1356 &Session::get_auto_return,
1357 &Session::set_auto_return);
1361 ARDOUR_UI::toggle_click ()
1363 toggle_some_session_state (click_button,
1364 &Session::get_clicking,
1365 &Session::set_clicking);
1369 ARDOUR_UI::follow_changed ()
1377 if (follow_button.get_active() != (x = editor->follow_playhead())) {
1378 follow_button.set_active (x);
1383 ARDOUR_UI::toggle_follow ()
1391 if (editor->follow_playhead() != (x = follow_button.get_active())) {
1392 editor->set_follow_playhead (x);
1397 ARDOUR_UI::toggle_session_auto_loop ()
1400 if (session->get_auto_loop()) {
1401 if (session->transport_rolling()) {
1405 session->request_auto_loop (false);
1409 session->request_auto_loop (true);
1415 ARDOUR_UI::toggle_session_punch_in ()
1418 session->set_punch_in (!session->get_punch_in());
1423 ARDOUR_UI::toggle_punch_out ()
1425 toggle_some_session_state (punch_out_button,
1426 &Session::get_punch_out,
1427 &Session::set_punch_out);
1431 ARDOUR_UI::toggle_punch_in ()
1433 toggle_some_session_state (punch_in_button,
1434 &Session::get_punch_in,
1435 &Session::set_punch_in);
1439 ARDOUR_UI::map_button_state ()
1442 map_some_session_state (auto_return_button,
1443 &Session::get_auto_return);
1444 map_some_session_state (auto_play_button,
1445 &Session::get_auto_play);
1446 map_some_session_state (auto_input_button,
1447 &Session::get_auto_input);
1448 map_some_session_state (punch_in_button,
1449 &Session::get_punch_in);
1450 map_some_session_state (punch_out_button,
1451 &Session::get_punch_out);
1452 map_some_session_state (click_button,
1453 &Session::get_clicking);
1457 ARDOUR_UI::queue_map_control_change (Session::ControlType t)
1459 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::map_control_change), t));
1463 ARDOUR_UI::map_control_change (Session::ControlType t)
1466 case Session::AutoPlay:
1467 map_some_session_state (auto_play_button, &Session::get_auto_play);
1470 case Session::AutoLoop:
1473 case Session::AutoReturn:
1474 map_some_session_state (auto_return_button, &Session::get_auto_return);
1477 case Session::AutoInput:
1478 map_some_session_state (auto_input_button, &Session::get_auto_input);
1481 case Session::PunchOut:
1482 map_some_session_state (punch_in_button, &Session::get_punch_out);
1485 case Session::PunchIn:
1486 map_some_session_state (punch_in_button, &Session::get_punch_in);
1489 case Session::Clicking:
1490 map_some_session_state (click_button, &Session::get_clicking);
1493 case Session::SlaveType:
1494 // map_some_session_state (mtc_slave_button, &Session::get_mtc_slave);
1497 case Session::SendMTC:
1498 // map_some_session_state (send_mtc_button, &Session::get_send_mtc);
1501 case Session::SendMMC:
1502 // map_some_session_state (send_mmc_button, &Session::get_send_mmc);
1505 case Session::MMCControl:
1506 // map_some_session_state (mmc_control_button, &Session::get_mmc_control);
1509 case Session::MidiFeedback:
1510 // map_some_session_state (mmc_control_button, &Session::get_mmc_control);
1512 case Session::MidiControl:
1513 // map_some_session_state (mmc_control_button, &Session::get_mmc_control);
1519 case Session::RecordingPlugins:
1522 case Session::CrossFadesActive:
1525 case Session::EditingMode:
1528 case Session::PlayRange:
1531 case Session::AlignChoice:
1532 /* don't care, this is handled by the options editor */
1534 case Session::SeamlessLoop:
1535 /* don't care, this is handled by the options editor */
1542 ARDOUR_UI::control_methods_adjusted ()
1547 which_method = (int) online_control_button->adjustment.get_value();
1548 switch (which_method) {
1550 allow_mmc_and_local ();
1556 allow_local_only ();
1559 fatal << _("programming error: impossible control method") << endmsg;
1565 ARDOUR_UI::mmc_device_id_adjusted ()
1570 int dev_id = (int) mmc_id_button->adjustment.get_value();
1571 mmc->set_device_id (dev_id);
1577 ARDOUR_UI::map_some_session_state (ToggleButton& button,
1578 bool (Session::*get)() const)
1587 if (button.get_active() != (x = (session->*get)())) {
1588 button.set_active (x);
1593 ARDOUR_UI::toggle_some_session_state (ToggleButton& button,
1594 bool (Session::*get)() const,
1595 void (Session::*set)(bool))
1605 button_state = button.get_active ();
1606 session_state = (session->*get)();
1608 if (button_state != session_state) {
1609 (session->*set) (button_state);
1612 /* check that it worked, and reverse
1613 the button state if it didn't
1616 if ((session->*get)() != button_state) {
1617 button->set_active (!button_state);
1625 ARDOUR_UI::session_menu (GdkEventButton *ev)
1627 session_popup_menu->popup (0, 0);
1632 ARDOUR_UI::redisplay_recent_sessions ()
1634 vector<string *> *sessions;
1635 vector<string *>::iterator i;
1636 RecentSessionsSorter cmp;
1638 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
1639 recent_session_model->clear ();
1642 ARDOUR::read_recent_sessions (rs);
1645 recent_session_display.set_model (recent_session_model);
1649 /* sort them alphabetically */
1650 sort (rs.begin(), rs.end(), cmp);
1651 sessions = new vector<string*>;
1653 for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
1654 sessions->push_back (new string ((*i).second));
1657 for (i = sessions->begin(); i != sessions->end(); ++i) {
1659 vector<string*>* states;
1660 vector<const gchar*> item;
1661 string fullpath = *(*i);
1663 /* remove any trailing / */
1665 if (fullpath[fullpath.length()-1] == '/') {
1666 fullpath = fullpath.substr (0, fullpath.length()-1);
1669 /* now get available states for this session */
1671 if ((states = Session::possible_states (fullpath)) == 0) {
1672 /* no state file? */
1676 TreeModel::Row row = *(recent_session_model->append());
1678 row[recent_session_columns.visible_name] = PBD::basename (fullpath);
1679 row[recent_session_columns.fullpath] = fullpath;
1681 if (states->size() > 1) {
1683 /* add the children */
1685 for (vector<string*>::iterator i2 = states->begin(); i2 != states->end(); ++i2) {
1687 TreeModel::Row child_row = *(recent_session_model->append (row.children()));
1689 child_row[recent_session_columns.visible_name] = **i2;
1690 child_row[recent_session_columns.fullpath] = fullpath;
1699 recent_session_display.set_model (recent_session_model);
1704 ARDOUR_UI::build_session_selector ()
1706 session_selector_window = new ArdourDialog ("session selector");
1708 Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
1710 session_selector_window->add_button (Stock::OK, RESPONSE_ACCEPT);
1711 session_selector_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
1713 recent_session_model = TreeStore::create (recent_session_columns);
1714 recent_session_display.set_model (recent_session_model);
1715 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1716 recent_session_display.set_headers_visible (false);
1718 scroller->add (recent_session_display);
1719 scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1721 session_selector_window->set_name ("SessionSelectorWindow");
1722 session_selector_window->set_size_request (200, 400);
1723 session_selector_window->get_vbox()->pack_start (*scroller);
1727 ARDOUR_UI::open_recent_session ()
1729 /* popup selector window */
1731 if (session_selector_window == 0) {
1732 build_session_selector ();
1735 redisplay_recent_sessions ();
1737 ResponseType r = (ResponseType) session_selector_window->run ();
1739 session_selector_window->hide();
1742 case RESPONSE_ACCEPT:
1748 Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
1750 if (i == recent_session_model->children().end()) {
1754 Glib::ustring path = (*i)[recent_session_columns.fullpath];
1755 Glib::ustring state = (*i)[recent_session_columns.visible_name];
1757 _session_is_new = false;
1759 load_session (path, state);
1763 ARDOUR_UI::filter_ardour_session_dirs (const FileFilter::Info& info)
1765 struct stat statbuf;
1767 if (stat (info.filename.c_str(), &statbuf) != 0) {
1771 if (!S_ISDIR(statbuf.st_mode)) {
1775 string session_file = info.filename;
1776 session_file += '/';
1777 session_file += PBD::basename (info.filename);
1778 session_file += ".ardour";
1780 if (stat (session_file.c_str(), &statbuf) != 0) {
1784 return S_ISREG (statbuf.st_mode);
1788 ARDOUR_UI::open_session ()
1790 /* popup selector window */
1792 if (open_session_selector == 0) {
1793 open_session_selector = new Gtk::FileChooserDialog (_("open session"), FILE_CHOOSER_ACTION_OPEN);
1794 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1795 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
1797 FileFilter filter_ardour;
1798 filter_ardour.set_name (_("Ardour sessions"));
1799 filter_ardour.add_custom (FILE_FILTER_FILENAME, mem_fun (*this, &ARDOUR_UI::filter_ardour_session_dirs));
1801 open_session_selector->add_filter (filter_ardour);
1804 switch (open_session_selector->run ()) {
1811 string session_path = open_session_selector->get_filename();
1815 if (session_path.length() > 0) {
1816 if (Session::find_session (session_path, path, name, isnew) == 0) {
1817 _session_is_new = isnew;
1818 load_session (path, name);
1825 ARDOUR_UI::session_add_midi_track ()
1827 cerr << _("Patience is a virtue.\n");
1831 ARDOUR_UI::session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels)
1836 warning << _("You cannot add a track without a session already loaded.") << endmsg;
1842 if ((route = session->new_audio_track (input_channels, output_channels)) == 0) {
1843 error << _("could not create new audio track") << endmsg;
1846 if ((route = session->new_audio_route (input_channels, output_channels)) == 0) {
1847 error << _("could not create new audio bus") << endmsg;
1852 if (need_control_room_outs) {
1858 route->set_stereo_control_outs (control_lr_channels);
1859 route->control_outs()->set_stereo_pan (pans, this);
1861 #endif /* CONTROLOUTS */
1865 ArdourMessage msg (editor, X_("noport dialog"),
1866 _("There are insufficient JACK ports available\n\
1867 to create a new track or bus.\n\
1868 You should save Ardour, exit and\n\
1869 restart JACK with more ports."));
1874 ARDOUR_UI::diskstream_added (DiskStream* ds)
1879 ARDOUR_UI::do_transport_locate (jack_nframes_t new_position)
1881 jack_nframes_t _preroll;
1884 _preroll = session->convert_to_frames_at (new_position, session->preroll);
1886 if (new_position > _preroll) {
1887 new_position -= _preroll;
1892 session->request_locate (new_position);
1897 ARDOUR_UI::transport_goto_start ()
1900 session->request_locate (0);
1903 /* force displayed area in editor to start no matter
1904 what "follow playhead" setting is.
1908 editor->reposition_x_origin (0);
1914 ARDOUR_UI::transport_goto_end ()
1917 jack_nframes_t frame = session->current_end_frame();
1918 session->request_locate (frame);
1920 /* force displayed area in editor to start no matter
1921 what "follow playhead" setting is.
1925 editor->reposition_x_origin (frame);
1931 ARDOUR_UI::mouse_transport_stop (GdkEventButton *ev)
1936 if (session->transport_stopped()) {
1937 session->request_locate (session->last_transport_start());
1939 if (session->get_auto_loop()) {
1940 session->request_auto_loop (false);
1943 Keyboard::ModifierMask mask = Keyboard::ModifierMask (Keyboard::Control|Keyboard::Shift);
1944 session->request_stop (Keyboard::modifier_state_equals (ev->state, mask));
1952 ARDOUR_UI::mouse_transport_roll (GdkEventButton* ev)
1959 ARDOUR_UI::transport_stop ()
1965 if (session->is_auditioning()) {
1966 session->cancel_audition ();
1970 if (session->get_auto_loop()) {
1971 session->request_auto_loop (false);
1974 session->request_stop ();
1978 ARDOUR_UI::transport_stop_and_forget_capture ()
1981 session->request_stop (true);
1986 ARDOUR_UI::remove_last_capture()
1989 editor->remove_last_capture();
1994 ARDOUR_UI::transport_record ()
1997 switch (session->record_status()) {
1998 case Session::Disabled:
1999 if (session->ntracks() == 0) {
2000 string txt = _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu.");
2001 ArdourMessage msg (editor, X_("cannotrecenable"), txt);
2004 session->maybe_enable_record ();
2006 case Session::Recording:
2007 case Session::Enabled:
2008 session->disable_record ();
2014 ARDOUR_UI::transport_roll ()
2022 rolling = session->transport_rolling ();
2024 if (session->get_auto_loop()) {
2025 session->request_auto_loop (false);
2026 auto_loop_button.set_active (false);
2027 roll_button.set_active (true);
2028 } else if (session->get_play_range ()) {
2029 session->request_play_range (false);
2030 play_selection_button.set_active (false);
2031 } else if (rolling) {
2032 session->request_locate (session->last_transport_start(), true);
2035 session->request_transport_speed (1.0f);
2039 ARDOUR_UI::transport_loop()
2042 if (session->get_auto_loop()) {
2043 if (session->transport_rolling()) {
2044 Location * looploc = session->locations()->auto_loop_location();
2046 session->request_locate (looploc->start(), true);
2051 session->request_auto_loop (true);
2057 ARDOUR_UI::transport_play_selection ()
2063 if (!session->get_play_range()) {
2064 session->request_stop ();
2067 editor->play_selection ();
2071 ARDOUR_UI::transport_rewind (int option)
2073 float current_transport_speed;
2076 current_transport_speed = session->transport_speed();
2078 if (current_transport_speed >= 0.0f) {
2081 session->request_transport_speed (-1.0f);
2084 session->request_transport_speed (-4.0f);
2087 session->request_transport_speed (-0.5f);
2092 session->request_transport_speed (current_transport_speed * 1.5f);
2098 ARDOUR_UI::transport_forward (int option)
2100 float current_transport_speed;
2103 current_transport_speed = session->transport_speed();
2105 if (current_transport_speed <= 0.0f) {
2108 session->request_transport_speed (1.0f);
2111 session->request_transport_speed (4.0f);
2114 session->request_transport_speed (0.5f);
2119 session->request_transport_speed (current_transport_speed * 1.5f);
2125 ARDOUR_UI::toggle_monitor_enable (guint32 dstream)
2133 if ((ds = session->diskstream_by_id (dstream)) != 0) {
2134 Port *port = ds->io()->input (0);
2135 port->request_monitor_input (!port->monitoring_input());
2140 ARDOUR_UI::toggle_record_enable (guint32 dstream)
2148 if ((ds = session->diskstream_by_id (dstream)) != 0) {
2149 ds->set_record_enabled (!ds->record_enabled(), this);
2154 ARDOUR_UI::queue_transport_change ()
2156 Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
2160 ARDOUR_UI::map_transport_state ()
2162 float sp = session->transport_speed();
2165 transport_rolling ();
2166 } else if (sp < 0.0f) {
2167 transport_rewinding ();
2168 } else if (sp > 0.0f) {
2169 transport_forwarding ();
2171 transport_stopped ();
2176 ARDOUR_UI::send_all_midi_feedback ()
2179 session->send_all_midi_feedback();
2184 ARDOUR_UI::allow_local_only ()
2190 ARDOUR_UI::allow_mmc_only ()
2196 ARDOUR_UI::allow_mmc_and_local ()
2202 ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg)
2204 snprintf (buf, sizeof(buf), "%s", ((GlobalClickBox *) arg)->strings[
2205 (int) adj.get_value()].c_str());
2209 ARDOUR_UI::engine_stopped ()
2211 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
2213 jack_disconnect_item->set_sensitive (false);
2214 jack_reconnect_item->set_sensitive (true);
2215 jack_bufsize_menu->set_sensitive (false);
2220 ARDOUR_UI::engine_running ()
2222 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
2224 jack_disconnect_item->set_sensitive (true);
2225 jack_reconnect_item->set_sensitive (false);
2226 jack_bufsize_menu->set_sensitive (true);
2230 ARDOUR_UI::engine_halted ()
2232 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
2234 jack_disconnect_item->set_sensitive (false);
2235 jack_reconnect_item->set_sensitive (true);
2236 jack_bufsize_menu->set_sensitive (false);
2238 update_sample_rate (0);
2240 ArdourMessage msg (editor, X_("halted"),
2242 JACK has either been shutdown or it\n\
2243 disconnected Ardour because Ardour\n\
2244 was not fast enough. You can save the\n\
2245 session and/or try to reconnect to JACK ."));
2249 ARDOUR_UI::do_engine_start ()
2255 catch (AudioEngine::PortRegistrationFailure& err) {
2257 error << _("Unable to create all required ports")
2265 error << _("Unable to start the session running")
2275 ARDOUR_UI::start_engine ()
2277 if (do_engine_start () == 0) {
2278 if (session && _session_is_new) {
2279 /* we need to retain initial visual
2280 settings for a new session
2282 session->save_state ("");
2285 /* there is too much going on, in too many threads, for us to
2286 end up with a clean session. So wait 1 second after loading,
2287 and fix it up. its ugly, but until i come across a better
2288 solution, its what we have.
2291 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::make_session_clean), 1000);
2298 ARDOUR_UI::update_clocks ()
2300 Clock (session->audible_frame()); /* EMIT_SIGNAL */
2304 ARDOUR_UI::start_clocking ()
2306 clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
2310 ARDOUR_UI::stop_clocking ()
2312 clock_signal_connection.disconnect ();
2316 ARDOUR_UI::toggle_clocking ()
2319 if (clock_button.get_active()) {
2328 ARDOUR_UI::_blink (void *arg)
2331 ((ARDOUR_UI *) arg)->blink ();
2338 Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
2342 ARDOUR_UI::start_blinking ()
2344 /* Start the blink signal. Everybody with a blinking widget
2345 uses Blink to drive the widget's state.
2348 if (blink_timeout_tag < 0) {
2350 blink_timeout_tag = gtk_timeout_add (240, _blink, this);
2355 ARDOUR_UI::stop_blinking ()
2357 if (blink_timeout_tag >= 0) {
2358 gtk_timeout_remove (blink_timeout_tag);
2359 blink_timeout_tag = -1;
2365 ARDOUR_UI::add_diskstream_to_menu (DiskStream& dstream)
2367 using namespace Gtk;
2368 using namespace Menu_Helpers;
2370 if (dstream.hidden()) {
2374 MenuList& items = diskstream_menu->items();
2375 items.push_back (MenuElem (dstream.name(), bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), (gint32) dstream.id())));
2379 ARDOUR_UI::diskstream_selected (gint32 id)
2381 selected_dstream = id;
2386 ARDOUR_UI::select_diskstream (GdkEventButton *ev)
2388 using namespace Gtk;
2389 using namespace Menu_Helpers;
2395 diskstream_menu = new Menu();
2396 diskstream_menu->set_name ("ArdourContextMenu");
2397 using namespace Gtk;
2398 using namespace Menu_Helpers;
2400 MenuList& items = diskstream_menu->items();
2401 items.push_back (MenuElem (_("No Stream"), (bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), -1))));
2403 session->foreach_diskstream (this, &ARDOUR_UI::add_diskstream_to_menu);
2406 diskstream_menu->popup (ev->button, ev->time);
2408 diskstream_menu->popup (0, 0);
2411 selected_dstream = -1;
2415 delete diskstream_menu;
2417 return selected_dstream;
2421 ARDOUR_UI::name_io_setup (AudioEngine& engine,
2427 if (io.n_inputs() == 0) {
2432 /* XXX we're not handling multiple ports yet. */
2434 const char **connections = io.input(0)->get_connections();
2436 if (connections == 0 || connections[0] == '\0') {
2439 buf = connections[0];
2446 if (io.n_outputs() == 0) {
2451 /* XXX we're not handling multiple ports yet. */
2453 const char **connections = io.output(0)->get_connections();
2455 if (connections == 0 || connections[0] == '\0') {
2458 buf = connections[0];
2466 ARDOUR_UI::snapshot_session ()
2468 ArdourPrompter prompter (true);
2475 now = now.substr (0, now.length() - 1);
2477 prompter.set_name ("Prompter");
2478 prompter.set_prompt (_("Name for snapshot"));
2479 prompter.set_initial_text (now);
2481 switch (prompter.run()) {
2482 case RESPONSE_ACCEPT:
2483 prompter.get_result (snapname);
2484 if (snapname.length()){
2485 save_state (snapname);
2495 ARDOUR_UI::save_state (string name)
2497 (void) save_state_canfail (name);
2501 ARDOUR_UI::save_state_canfail (string name)
2506 if (name.length() == 0) {
2507 name = session->snap_name();
2510 if ((ret = session->save_state (name)) != 0) {
2514 save_ardour_state (); /* XXX cannot fail? yeah, right ... */
2519 ARDOUR_UI::restore_state (string name)
2522 if (name.length() == 0) {
2523 name = session->name();
2525 session->restore_state (name);
2530 ARDOUR_UI::primary_clock_value_changed ()
2533 session->request_locate (primary_clock.current_time ());
2538 ARDOUR_UI::secondary_clock_value_changed ()
2541 session->request_locate (secondary_clock.current_time ());
2546 ARDOUR_UI::rec_enable_button_blink (bool onoff, DiskStream *dstream, Widget *w)
2548 if (session && dstream && dstream->record_enabled()) {
2550 Session::RecordState rs;
2552 rs = session->record_status ();
2555 case Session::Disabled:
2556 case Session::Enabled:
2557 if (w->get_state() != STATE_SELECTED) {
2558 w->set_state (STATE_SELECTED);
2562 case Session::Recording:
2563 if (w->get_state() != STATE_ACTIVE) {
2564 w->set_state (STATE_ACTIVE);
2570 if (w->get_state() != STATE_NORMAL) {
2571 w->set_state (STATE_NORMAL);
2577 ARDOUR_UI::transport_rec_enable_blink (bool onoff)
2583 switch (session->record_status()) {
2584 case Session::Enabled:
2586 rec_button.set_state (STATE_ACTIVE);
2588 rec_button.set_state (STATE_NORMAL);
2592 case Session::Recording:
2593 rec_button.set_state (STATE_ACTIVE);
2597 rec_button.set_active (false);
2598 rec_button.set_state (STATE_NORMAL);
2604 ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
2612 ARDOUR_UI::start_keyboard_prefix ()
2614 keyboard->start_prefix();
2618 ARDOUR_UI::save_template ()
2621 ArdourPrompter prompter (true);
2624 prompter.set_name (X_("Prompter"));
2625 prompter.set_prompt (_("Name for mix template:"));
2626 prompter.set_initial_text(session->name() + _("-template"));
2628 switch (prompter.run()) {
2629 case RESPONSE_ACCEPT:
2630 prompter.get_result (name);
2632 if (name.length()) {
2633 session->save_template (name);
2643 ARDOUR_UI::new_session (bool startup, std::string predetermined_path)
2645 m_new_session_dialog->show_all();
2646 m_new_session_dialog->set_transient_for(*editor);
2647 m_new_session_dialog->set_name(predetermined_path);
2649 int response = Gtk::RESPONSE_CANCEL;
2652 response = m_new_session_dialog->run ();
2654 if(response == Gtk::RESPONSE_OK) {
2656 _session_is_new = true;
2658 std::string session_name = m_new_session_dialog->session_name();
2659 std::string session_path = m_new_session_dialog->session_folder();
2660 std::string template_name = m_new_session_dialog->session_template_name();
2662 if (m_new_session_dialog->use_session_template()) {
2664 load_session (session_path, session_name, &template_name);
2670 Session::AutoConnectOption iconnect;
2671 Session::AutoConnectOption oconnect;
2673 if (m_new_session_dialog->create_control_bus()) {
2674 cchns = (uint32_t) m_new_session_dialog->control_channel_count();
2679 if (m_new_session_dialog->create_master_bus()) {
2680 mchns = (uint32_t) m_new_session_dialog->master_channel_count();
2685 if (m_new_session_dialog->connect_inputs()) {
2686 iconnect = Session::AutoConnectPhysical;
2688 iconnect = Session::AutoConnectOption (0);
2691 /// @todo some minor tweaks.
2693 if (m_new_session_dialog->connect_outs_to_master()) {
2694 oconnect = Session::AutoConnectMaster;
2695 } else if (m_new_session_dialog->connect_outs_to_physical()) {
2696 oconnect = Session::AutoConnectPhysical;
2698 oconnect = Session::AutoConnectOption (0);
2701 uint32_t nphysin = (uint32_t) m_new_session_dialog->input_limit_count();
2702 uint32_t nphysout = (uint32_t) m_new_session_dialog->output_limit_count();
2704 build_session (session_path,
2712 engine->frame_rate() * 60 * 5);
2716 } while(response == Gtk::RESPONSE_HELP);
2717 m_new_session_dialog->hide_all();
2721 ARDOUR_UI::load_session (string path, string snap_name, string* mix_template)
2723 Session *new_session;
2725 session_loaded = false;
2726 x = unload_session ();
2734 /* if it already exists, we must have write access */
2736 if (::access (path.c_str(), F_OK) == 0 && ::access (path.c_str(), W_OK)) {
2737 ArdourMessage msg (editor, X_("noaccess dialog"), _("\
2738 You do not have write access to this session.\n\
2739 This prevents the session from being loaded."));
2744 new_session = new Session (*engine, path, snap_name, mix_template);
2749 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
2753 connect_to_session (new_session);
2755 //if (engine->running()) {
2756 //mixer->show_window();
2758 session_loaded = true;
2763 ARDOUR_UI::make_session_clean ()
2766 session->set_clean ();
2773 ARDOUR_UI::build_session (string path, string snap_name,
2774 uint32_t control_channels,
2775 uint32_t master_channels,
2776 Session::AutoConnectOption input_connect,
2777 Session::AutoConnectOption output_connect,
2780 jack_nframes_t initial_length)
2782 Session *new_session;
2785 session_loaded = false;
2786 x = unload_session ();
2793 _session_is_new = true;
2796 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
2797 control_channels, master_channels, nphysin, nphysout, initial_length);
2802 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
2806 connect_to_session (new_session);
2808 //if (engine->running()) {
2809 //mixer->show_window();
2811 session_loaded = true;
2819 editor->show_window ();
2823 if (session && mixer) {
2824 mixer->show_window ();
2833 ARDOUR_UI::show_splash ()
2836 about = new About();
2842 ARDOUR_UI::hide_splash ()
2850 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title, string msg)
2854 removed = rep.paths.size();
2857 ArdourMessage msg (editor, X_("cleanupresults"),
2859 No audio files were ready for cleanup\n\n\
2860 If this seems suprising, check for any existing\n\
2861 snapshots. These may still include regions that\n\
2862 require some unused files to continue to exist."));
2866 ArdourDialog results (_("ardour: cleanup"), true);
2868 struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
2869 CleanupResultsModelColumns() {
2873 Gtk::TreeModelColumn<Glib::ustring> visible_name;
2874 Gtk::TreeModelColumn<Glib::ustring> fullpath;
2878 Glib::RefPtr<Gtk::ListStore> results_model;
2879 CleanupResultsModelColumns results_columns;
2880 Gtk::TreeView results_display;
2882 results_model = ListStore::create (results_columns);
2883 results_display.set_model (results_model);
2884 results_display.append_column (list_title, results_columns.visible_name);
2885 results_display.set_headers_visible (true);
2887 Gtk::ScrolledWindow list_scroller;
2890 if (rep.space < 1048576.0f) {
2892 txt.set_text (string_compose (msg, removed, _("files"), (float) rep.space / 1024.0f, "kilo"));
2894 txt.set_text (string_compose (msg, removed, _("file"), (float) rep.space / 1024.0f, "kilo"));
2898 txt.set_text (string_compose (msg, removed, _("files"), (float) rep.space / 1048576.0f, "mega"));
2900 txt.set_text (string_compose (msg, removed, _("file"), (float) rep.space / 1048576.0f, "mega"));
2904 results.get_vbox()->pack_start (txt, false, false);
2906 for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2907 TreeModel::Row row = *(results_model->append());
2908 row[results_columns.visible_name] = *i;
2909 row[results_columns.fullpath] = *i;
2912 list_scroller.add (results_display);
2913 list_scroller.set_size_request (-1, 250);
2914 list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2916 results.get_vbox()->pack_start (list_scroller, true, true);
2917 results.add_button (Stock::OK, RESPONSE_ACCEPT);
2918 results.set_position (Gtk::WIN_POS_MOUSE);
2924 ARDOUR_UI::cleanup ()
2927 /* shouldn't happen: menu item is insensitive */
2931 ArdourDialog checker (_("ardour cleanup"));
2932 Gtk::Label label (_("\
2933 Cleanup is a destructive operation.\n\
2934 ALL undo/redo information will be lost if you cleanup.\n\
2935 Unused audio files will be moved to a \"dead sounds\" location."));
2937 checker.get_vbox()->pack_start (label, false, false);
2938 checker.add_button (Stock::OK, RESPONSE_ACCEPT);
2939 checker.add_button (Stock::CANCEL, RESPONSE_CANCEL);
2941 checker.set_name (_("CleanupDialog"));
2942 checker.set_wmclass (_("ardour_cleanup"), "Ardour");
2943 checker.set_position (Gtk::WIN_POS_MOUSE);
2945 switch (checker.run()) {
2946 case RESPONSE_ACCEPT:
2952 Session::cleanup_report rep;
2954 editor->prepare_for_cleanup ();
2956 if (session->cleanup_sources (rep)) {
2960 display_cleanup_results (rep,
2963 The following %1 %2 were not in use.\n\
2964 The next time you flush the wastebasket\n\
2965 it will release an additional %3 %4bytes\n\
2971 ARDOUR_UI::flush_trash ()
2974 /* shouldn't happen: menu item is insensitive */
2978 Session::cleanup_report rep;
2980 if (session->cleanup_trash_sources (rep)) {
2984 display_cleanup_results (rep,
2986 _("The following %1 file%2 were deleted, releasing %3 %4bytes of disk space"));
2990 ARDOUR_UI::add_route ()
2998 if (add_route_dialog == 0) {
2999 add_route_dialog = new AddRouteDialog;
3000 editor->ensure_float (*add_route_dialog);
3003 if (add_route_dialog->is_visible()) {
3004 /* we're already doing this */
3008 ResponseType r = (ResponseType) add_route_dialog->run ();
3010 add_route_dialog->hide();
3013 case RESPONSE_ACCEPT:
3020 if ((count = add_route_dialog->count()) <= 0) {
3024 uint32_t input_chan = add_route_dialog->channels ();
3025 uint32_t output_chan;
3026 string name_template = add_route_dialog->name_template ();
3027 bool track = add_route_dialog->track ();
3029 Session::AutoConnectOption oac = session->get_output_auto_connect();
3031 if (oac & Session::AutoConnectMaster) {
3032 output_chan = (session->master_out() ? session->master_out()->n_inputs() : input_chan);
3034 output_chan = input_chan;
3037 /* XXX do something with name template */
3041 session_add_audio_track (input_chan, output_chan);
3043 session_add_audio_bus (input_chan, output_chan);
3047 while (Main::events_pending()) {
3054 ARDOUR_UI::mixer_settings () const
3059 node = session->instant_xml(X_("Mixer"), session->path());
3061 node = Config->instant_xml(X_("Mixer"), Config->get_user_ardour_path());
3065 node = new XMLNode (X_("Mixer"));
3072 ARDOUR_UI::editor_settings () const
3077 node = session->instant_xml(X_("Editor"), session->path());
3079 node = Config->instant_xml(X_("Editor"), Config->get_user_ardour_path());
3083 node = new XMLNode (X_("Editor"));
3089 ARDOUR_UI::keyboard_settings () const
3093 node = Config->extra_xml(X_("Keyboard"));
3096 node = new XMLNode (X_("Keyboard"));
3102 ARDOUR_UI::halt_on_xrun_message ()
3104 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
3106 ArdourMessage msg (editor, X_("haltonxrun"),
3107 _("Recording was stopped because your system could not keep up."));
3111 ARDOUR_UI::delete_sources_in_the_right_thread (list<ARDOUR::Source*>* deletion_list)
3113 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread), deletion_list));
3115 for (list<Source*>::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) {
3119 delete deletion_list;
3123 ARDOUR_UI::disk_overrun_handler ()
3125 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
3127 if (!have_disk_overrun_displayed) {
3128 have_disk_overrun_displayed = true;
3129 ArdourMessage msg (editor, X_("diskrate dialog"), _("\
3130 The disk system on your computer\n\
3131 was not able to keep up with Ardour.\n\
3133 Specifically, it failed to write data to disk\n\
3134 quickly enough to keep up with recording.\n"));
3135 have_disk_overrun_displayed = false;
3140 ARDOUR_UI::disk_underrun_handler ()
3142 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
3144 if (!have_disk_underrun_displayed) {
3145 have_disk_underrun_displayed = true;
3146 ArdourMessage msg (editor, X_("diskrate2 dialog"),
3147 (_("The disk system on your computer\n\
3148 was not able to keep up with Ardour.\n\
3150 Specifically, it failed to read data from disk\n\
3151 quickly enough to keep up with playback.\n")));
3152 have_disk_underrun_displayed = false;
3157 ARDOUR_UI::disk_underrun_message_gone ()
3159 have_disk_underrun_displayed = false;
3163 ARDOUR_UI::disk_overrun_message_gone ()
3165 have_disk_underrun_displayed = false;
3169 ARDOUR_UI::pending_state_dialog ()
3171 ArdourDialog dialog ("pending state dialog");
3173 This session appears to have been in\n\
3174 middle of recording when ardour or\n\
3175 the computer was shutdown.\n\
3177 Ardour can recover any captured audio for\n\
3178 you, or it can ignore it. Please decide\n\
3179 what you would like to do.\n"));
3181 dialog.get_vbox()->pack_start (message);
3182 dialog.add_button (_("Recover from crash"), RESPONSE_ACCEPT);
3183 dialog.add_button (_("Ignore crash data"), RESPONSE_REJECT);
3185 dialog.set_position (WIN_POS_CENTER);
3188 switch (dialog.run ()) {
3189 case RESPONSE_ACCEPT:
3200 ARDOUR_UI::disconnect_from_jack ()
3203 if( engine->disconnect_from_jack ()) {
3204 ArdourMessage msg (editor, X_("nojack dialog"),
3205 _("Could not disconnect from JACK"));
3208 update_sample_rate (0);
3213 ARDOUR_UI::reconnect_to_jack ()
3216 if (engine->reconnect_to_jack ()) {
3217 ArdourMessage msg (editor, X_("nojack dialog"),
3218 _("Could not reconnect to JACK"));
3221 update_sample_rate (0);
3226 ARDOUR_UI::set_jack_buffer_size (jack_nframes_t nframes)
3228 engine->request_buffer_size (nframes);
3229 update_sample_rate (0);
3233 ARDOUR_UI::cmdline_new_session (string path)
3235 if (path[0] != '/') {
3236 char buf[PATH_MAX+1];
3239 getcwd (buf, sizeof (buf));
3246 new_session (false, path);
3248 _will_create_new_session_automatically = false; /* done it */
3249 return FALSE; /* don't call it again */