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;
853 open_session_selector = 0;
854 have_configure_timeout = false;
855 have_disk_overrun_displayed = false;
856 have_disk_underrun_displayed = false;
857 _will_create_new_session_automatically = false;
858 session_loaded = false;
861 last_configure_time.tv_sec = 0;
862 last_configure_time.tv_usec = 0;
864 shuttle_grabbed = false;
867 set_shuttle_units (Percentage);
868 set_shuttle_behaviour (Sprung);
870 Glib::RefPtr<ActionGroup> shuttle_actions = ActionGroup::create ("ShuttleActions");
872 shuttle_actions->add (Action::create (X_("SetShuttleUnitsPercentage"), _("Percentage")), bind (mem_fun(*this, &ARDOUR_UI::set_shuttle_units), Percentage));
873 shuttle_actions->add (Action::create (X_("SetShuttleUnitsSemitones"), _("Semitones")), bind (mem_fun(*this, &ARDOUR_UI::set_shuttle_units), Semitones));
874 shuttle_actions->add (Action::create (X_("SetShuttleActionSprung"), _("Sprung")), bind (mem_fun(*this, &ARDOUR_UI::set_shuttle_behaviour), Sprung));
875 shuttle_actions->add (Action::create (X_("SetShuttleActionWheel"), _("Wheel")), bind (mem_fun(*this, &ARDOUR_UI::set_shuttle_behaviour), Wheel));
877 ActionManager::add_action_group (shuttle_actions);
879 shuttle_style_menu = dynamic_cast<Menu*> (ActionManager::get_widget ("ShuttleStylePopup"));
880 shuttle_unit_menu = dynamic_cast<Menu*> (ActionManager::get_widget ("ShuttleUnitPopup"));
882 gettimeofday (&last_peak_grab, 0);
883 gettimeofday (&last_shuttle_request, 0);
885 ARDOUR::DiskStream::CannotRecordNoInput.connect (mem_fun(*this, &ARDOUR_UI::cannot_record_no_input));
886 ARDOUR::DiskStream::DeleteSources.connect (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread));
887 ARDOUR::DiskStream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
888 ARDOUR::DiskStream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
890 /* handle pending state with a dialog */
892 ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
894 channel_combo_strings = internationalize (channel_setup_names);
896 /* have to wait for AudioEngine and Configuration before proceeding */
900 ARDOUR_UI::cannot_record_no_input (DiskStream* ds)
902 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::cannot_record_no_input), ds));
904 string msg = string_compose (_("\
905 You cannot record-enable\n\
907 because it has no input connections.\n\
908 You would be wasting space recording silence."),
911 ArdourMessage message (editor, X_("cannotrecord"), msg);
915 ARDOUR_UI::set_engine (AudioEngine& e)
919 engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
920 engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
921 engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
922 engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
926 keyboard = new Keyboard;
927 install_keybindings ();
929 FastMeter::set_vertical_xpm (v_meter_strip_xpm);
930 FastMeter::set_horizontal_xpm (h_meter_strip_xpm);
932 if (setup_windows ()) {
933 throw failed_constructor ();
936 if (GTK_ARDOUR::show_key_actions) {
938 // show_all_actions ();
942 /* start with timecode, metering enabled
945 blink_timeout_tag = -1;
947 /* this being a GUI and all, we want peakfiles */
949 FileSource::set_build_peakfiles (true);
950 FileSource::set_build_missing_peakfiles (true);
952 if (Source::start_peak_thread ()) {
953 throw failed_constructor();
956 /* start the time-of-day-clock */
958 update_wall_clock ();
959 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
961 update_disk_space ();
963 update_sample_rate (engine->frame_rate());
965 starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
966 stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
969 ARDOUR_UI::~ARDOUR_UI ()
971 save_ardour_state ();
985 if (add_route_dialog) {
986 delete add_route_dialog;
989 Source::stop_peak_thread ();
993 ARDOUR_UI::configure_timeout ()
998 if (last_configure_time.tv_sec == 0 && last_configure_time.tv_usec == 0) {
999 /* no configure events yet */
1003 gettimeofday (&now, 0);
1004 timersub (&now, &last_configure_time, &diff);
1006 /* force a gap of 0.5 seconds since the last configure event
1009 if (diff.tv_sec == 0 && diff.tv_usec < 500000) {
1012 have_configure_timeout = false;
1013 save_ardour_state ();
1019 ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
1021 if (have_configure_timeout) {
1022 gettimeofday (&last_configure_time, 0);
1024 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
1025 have_configure_timeout = true;
1032 ARDOUR_UI::save_ardour_state ()
1034 if (!keyboard || !mixer || !editor) {
1038 /* XXX this is all a bit dubious. add_extra_xml() uses
1039 a different lifetime model from add_instant_xml().
1042 XMLNode* node = new XMLNode (keyboard->get_state());
1043 Config->add_extra_xml (*node);
1044 Config->save_state();
1046 XMLNode& enode (static_cast<Stateful*>(editor)->get_state());
1047 XMLNode& mnode (mixer->get_state());
1050 session->add_instant_xml(enode, session->path());
1051 session->add_instant_xml(mnode, session->path());
1053 Config->add_instant_xml(enode, Config->get_user_ardour_path());
1054 Config->add_instant_xml(mnode, Config->get_user_ardour_path());
1059 ARDOUR_UI::startup ()
1061 /* Once the UI is up and running, start the audio engine. Doing
1062 this before the UI is up and running can cause problems
1063 when not running with SCHED_FIFO, because the amount of
1064 CPU and disk work needed to get the UI started can interfere
1065 with the scheduling of the audio thread.
1068 Glib::signal_idle().connect (mem_fun(*this, &ARDOUR_UI::start_engine));
1074 if (session && session->dirty()) {
1075 switch (ask_about_saving_session(_("quit"))) {
1080 /* use the default name */
1081 if (save_state_canfail ("")) {
1082 /* failed - don't quit */
1083 ArdourMessage (editor, X_("badsave dialog"),
1085 Ardour was unable to save your session.\n\n\
1086 If you still wish to quit, please use the\n\n\
1087 \"Just quit\" option."));
1100 ARDOUR_UI::ask_about_saving_session (string what)
1102 ArdourDialog window ("saving dialog");
1104 Gtk::Label prompt_label;
1105 Gtk::HBox button_packer;
1109 msg = string_compose(_("Save and %1"), what);
1111 Gtk::Button save_button (msg);
1112 save_button.set_name ("EditorGTKButton");
1114 msg = string_compose(_("Just %1"), what);
1116 Gtk::Button nosave_button (msg);
1117 nosave_button.set_name ("EditorGTKButton");
1119 msg = string_compose(_("Don't %1"), what);
1121 Gtk::Button noquit_button (msg);
1122 noquit_button.set_name ("EditorGTKButton");
1127 if (session->snap_name() == session->name()) {
1128 type = _("session");
1130 type = _("snapshot");
1132 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?"),
1133 type, session->snap_name());
1135 prompt_label.set_text (prompt);
1136 prompt_label.set_alignment (0.5, 0.5);
1137 prompt_label.set_name (X_("PrompterLabel"));
1139 save_button.signal_clicked().connect (bind(mem_fun(window,&ArdourDialog::stop), 1));
1140 nosave_button.signal_clicked().connect (bind(mem_fun(window,&ArdourDialog::stop), 0));
1141 noquit_button.signal_clicked().connect (bind(mem_fun(window,&ArdourDialog::stop), -1));
1143 button_packer.set_spacing (10);
1144 button_packer.pack_start (save_button);
1145 button_packer.pack_start (nosave_button);
1146 button_packer.pack_start (noquit_button);
1148 packer.set_spacing (10);
1149 packer.set_border_width (10);
1150 packer.pack_start (prompt_label);
1151 packer.pack_start (button_packer);
1153 window.set_name (_("Prompter"));
1154 window.set_title (_("ardour: save session?"));
1155 window.set_position (Gtk::WIN_POS_MOUSE);
1156 window.set_modal (true);
1157 window.add (packer);
1159 window.set_keyboard_input (true);
1161 save_the_session = 0;
1163 editor->ensure_float (window);
1167 return window.run_status();
1171 ARDOUR_UI::every_second ()
1174 update_buffer_load ();
1175 update_disk_space ();
1176 // update_disk_rate ();
1181 ARDOUR_UI::every_point_one_seconds ()
1184 struct timeval diff;
1186 /* do not attempt to grab peak power more than once per cycle.
1189 gettimeofday (&now, 0);
1190 timersub (&now, &last_peak_grab, &diff);
1192 if ((diff.tv_usec + (diff.tv_sec * 1000000)) >= engine->usecs_per_cycle()) {
1193 IO::GrabPeakPower(); /* EMIT_SIGNAL */
1194 last_peak_grab = now;
1197 update_speed_display ();
1198 RapidScreenUpdate(); /* EMIT_SIGNAL */
1203 ARDOUR_UI::every_point_zero_one_seconds ()
1205 SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
1210 ARDOUR_UI::update_sample_rate (jack_nframes_t ignored)
1214 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
1216 if (!engine->connected()) {
1218 snprintf (buf, sizeof (buf), _("disconnected"));
1222 jack_nframes_t rate = engine->frame_rate();
1224 if (fmod (rate, 1000.0) != 0.0) {
1225 snprintf (buf, sizeof (buf), _("SR: %.1f kHz / %4.1f msecs"),
1226 (float) rate/1000.0f,
1227 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
1229 snprintf (buf, sizeof (buf), _("SR: %u kHz / %4.1f msecs"),
1231 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
1235 sample_rate_label.set_text (buf);
1239 ARDOUR_UI::update_cpu_load ()
1242 snprintf (buf, sizeof (buf), _("DSP Load: %.1f%%"), engine->get_cpu_load());
1243 cpu_load_label.set_text (buf);
1247 ARDOUR_UI::update_disk_rate ()
1252 snprintf (buf, sizeof (buf), _("Disk r:%5.1f w:%5.1f MB/s"),
1253 session->read_data_rate()/1048576.0f, session->write_data_rate()/1048576.0f);
1254 disk_rate_label.set_text (buf);
1256 disk_rate_label.set_text ("");
1261 ARDOUR_UI::update_buffer_load ()
1266 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"),
1267 session->playback_load(), session->capture_load());
1268 buffer_load_label.set_text (buf);
1270 buffer_load_label.set_text ("");
1275 ARDOUR_UI::count_recenabled_diskstreams (DiskStream& ds)
1277 if (ds.record_enabled()) {
1278 rec_enabled_diskstreams++;
1283 ARDOUR_UI::update_disk_space()
1289 jack_nframes_t frames = session->available_capture_duration();
1292 if (frames == max_frames) {
1293 strcpy (buf, _("space: 24hrs+"));
1298 jack_nframes_t fr = session->frame_rate();
1300 if (session->actively_recording()){
1302 rec_enabled_diskstreams = 0;
1303 session->foreach_diskstream (this, &ARDOUR_UI::count_recenabled_diskstreams);
1305 if (rec_enabled_diskstreams) {
1306 frames /= rec_enabled_diskstreams;
1311 /* hmmm. shall we divide by the route count? or the diskstream count?
1312 or what? for now, do nothing ...
1317 hrs = frames / (fr * 3600);
1318 frames -= hrs * fr * 3600;
1319 mins = frames / (fr * 60);
1320 frames -= mins * fr * 60;
1323 snprintf (buf, sizeof(buf), _("space: %02dh:%02dm:%02ds"), hrs, mins, secs);
1326 disk_space_label.set_text (buf);
1330 ARDOUR_UI::update_wall_clock ()
1337 tm_now = localtime (&now);
1339 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
1340 wall_clock_label.set_text (buf);
1346 ARDOUR_UI::toggle_recording_plugins ()
1348 /* XXX use toggle_some_session_state */
1354 session->set_recording_plugins (!session->get_recording_plugins());
1358 ARDOUR_UI::toggle_auto_play ()
1361 toggle_some_session_state (auto_play_button,
1362 &Session::get_auto_play,
1363 &Session::set_auto_play);
1367 ARDOUR_UI::toggle_auto_return ()
1370 toggle_some_session_state (auto_return_button,
1371 &Session::get_auto_return,
1372 &Session::set_auto_return);
1376 ARDOUR_UI::toggle_click ()
1378 toggle_some_session_state (click_button,
1379 &Session::get_clicking,
1380 &Session::set_clicking);
1384 ARDOUR_UI::follow_changed ()
1392 if (follow_button.get_active() != (x = editor->follow_playhead())) {
1393 follow_button.set_active (x);
1398 ARDOUR_UI::toggle_follow ()
1406 if (editor->follow_playhead() != (x = follow_button.get_active())) {
1407 editor->set_follow_playhead (x);
1412 ARDOUR_UI::toggle_session_auto_loop ()
1415 if (session->get_auto_loop()) {
1416 if (session->transport_rolling()) {
1420 session->request_auto_loop (false);
1424 session->request_auto_loop (true);
1430 ARDOUR_UI::toggle_session_punch_in ()
1433 session->set_punch_in (!session->get_punch_in());
1438 ARDOUR_UI::toggle_punch_out ()
1440 toggle_some_session_state (punch_out_button,
1441 &Session::get_punch_out,
1442 &Session::set_punch_out);
1446 ARDOUR_UI::toggle_punch_in ()
1448 toggle_some_session_state (punch_in_button,
1449 &Session::get_punch_in,
1450 &Session::set_punch_in);
1454 ARDOUR_UI::map_button_state ()
1457 map_some_session_state (auto_return_button,
1458 &Session::get_auto_return);
1459 map_some_session_state (auto_play_button,
1460 &Session::get_auto_play);
1461 map_some_session_state (auto_input_button,
1462 &Session::get_auto_input);
1463 map_some_session_state (punch_in_button,
1464 &Session::get_punch_in);
1465 map_some_session_state (punch_out_button,
1466 &Session::get_punch_out);
1467 map_some_session_state (click_button,
1468 &Session::get_clicking);
1472 ARDOUR_UI::queue_map_control_change (Session::ControlType t)
1474 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::map_control_change), t));
1478 ARDOUR_UI::map_control_change (Session::ControlType t)
1481 case Session::AutoPlay:
1482 map_some_session_state (auto_play_button, &Session::get_auto_play);
1485 case Session::AutoLoop:
1488 case Session::AutoReturn:
1489 map_some_session_state (auto_return_button, &Session::get_auto_return);
1492 case Session::AutoInput:
1493 map_some_session_state (auto_input_button, &Session::get_auto_input);
1496 case Session::PunchOut:
1497 map_some_session_state (punch_in_button, &Session::get_punch_out);
1500 case Session::PunchIn:
1501 map_some_session_state (punch_in_button, &Session::get_punch_in);
1504 case Session::Clicking:
1505 map_some_session_state (click_button, &Session::get_clicking);
1508 case Session::SlaveType:
1509 // map_some_session_state (mtc_slave_button, &Session::get_mtc_slave);
1512 case Session::SendMTC:
1513 // map_some_session_state (send_mtc_button, &Session::get_send_mtc);
1516 case Session::SendMMC:
1517 // map_some_session_state (send_mmc_button, &Session::get_send_mmc);
1520 case Session::MMCControl:
1521 // map_some_session_state (mmc_control_button, &Session::get_mmc_control);
1524 case Session::MidiFeedback:
1525 // map_some_session_state (mmc_control_button, &Session::get_mmc_control);
1527 case Session::MidiControl:
1528 // map_some_session_state (mmc_control_button, &Session::get_mmc_control);
1534 case Session::RecordingPlugins:
1537 case Session::CrossFadesActive:
1540 case Session::EditingMode:
1543 case Session::PlayRange:
1546 case Session::AlignChoice:
1547 /* don't care, this is handled by the options editor */
1549 case Session::SeamlessLoop:
1550 /* don't care, this is handled by the options editor */
1557 ARDOUR_UI::control_methods_adjusted ()
1562 which_method = (int) online_control_button->adjustment.get_value();
1563 switch (which_method) {
1565 allow_mmc_and_local ();
1571 allow_local_only ();
1574 fatal << _("programming error: impossible control method") << endmsg;
1580 ARDOUR_UI::mmc_device_id_adjusted ()
1585 int dev_id = (int) mmc_id_button->adjustment.get_value();
1586 mmc->set_device_id (dev_id);
1592 ARDOUR_UI::map_some_session_state (ToggleButton& button,
1593 bool (Session::*get)() const)
1602 if (button.get_active() != (x = (session->*get)())) {
1603 button.set_active (x);
1608 ARDOUR_UI::toggle_some_session_state (ToggleButton& button,
1609 bool (Session::*get)() const,
1610 void (Session::*set)(bool))
1620 button_state = button.get_active ();
1621 session_state = (session->*get)();
1623 if (button_state != session_state) {
1624 (session->*set) (button_state);
1627 /* check that it worked, and reverse
1628 the button state if it didn't
1631 if ((session->*get)() != button_state) {
1632 button->set_active (!button_state);
1640 ARDOUR_UI::session_menu (GdkEventButton *ev)
1642 session_popup_menu->popup (0, 0);
1647 ARDOUR_UI::redisplay_recent_sessions ()
1649 vector<string *> *sessions;
1650 vector<string *>::iterator i;
1651 RecentSessionsSorter cmp;
1653 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
1654 recent_session_model->clear ();
1657 ARDOUR::read_recent_sessions (rs);
1660 recent_session_display.set_model (recent_session_model);
1664 /* sort them alphabetically */
1665 sort (rs.begin(), rs.end(), cmp);
1666 sessions = new vector<string*>;
1668 for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
1669 sessions->push_back (new string ((*i).second));
1672 for (i = sessions->begin(); i != sessions->end(); ++i) {
1674 vector<string*>* states;
1675 vector<const gchar*> item;
1676 string fullpath = *(*i);
1678 /* remove any trailing / */
1680 if (fullpath[fullpath.length()-1] == '/') {
1681 fullpath = fullpath.substr (0, fullpath.length()-1);
1684 /* now get available states for this session */
1686 if ((states = Session::possible_states (fullpath)) == 0) {
1687 /* no state file? */
1691 TreeModel::Row row = *(recent_session_model->append());
1693 row[recent_session_columns.visible_name] = PBD::basename (fullpath);
1694 row[recent_session_columns.fullpath] = fullpath;
1696 if (states->size() > 1) {
1698 /* add the children */
1700 for (vector<string*>::iterator i2 = states->begin(); i2 != states->end(); ++i2) {
1702 TreeModel::Row child_row = *(recent_session_model->append (row.children()));
1704 child_row[recent_session_columns.visible_name] = **i2;
1705 child_row[recent_session_columns.fullpath] = fullpath;
1714 recent_session_display.set_model (recent_session_model);
1719 ARDOUR_UI::build_session_selector ()
1721 session_selector_window = new ArdourDialog ("session selector");
1723 Gtk::VBox *vpacker = manage (new Gtk::VBox);
1724 Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
1725 Gtk::HBox *button_packer = manage (new Gtk::HBox);
1726 Gtk::Button *cancel_button = manage (new Gtk::Button (_("cancel")));
1727 Gtk::Button *rescan_button = manage (new Gtk::Button (_("rescan")));
1729 button_packer->pack_start (*rescan_button);
1730 button_packer->pack_start (*cancel_button);
1732 vpacker->pack_start (*scroller);
1733 vpacker->pack_start (*button_packer, false, false);
1735 recent_session_model = TreeStore::create (recent_session_columns);
1736 recent_session_display.set_model (recent_session_model);
1737 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1738 recent_session_display.set_headers_visible (false);
1740 scroller->add (recent_session_display);
1741 scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1743 session_selector_window->add (*vpacker);
1744 session_selector_window->set_name ("SessionSelectorWindow");
1745 session_selector_window->set_size_request (200, 400);
1749 ARDOUR_UI::open_recent_session ()
1751 /* popup selector window */
1753 if (session_selector_window == 0) {
1754 build_session_selector ();
1757 redisplay_recent_sessions ();
1759 session_selector_window->run ();
1762 switch (session_selector_window->run_status()) {
1770 Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
1772 if (i == recent_session_model->children().end()) {
1776 Glib::ustring path = (*i)[recent_session_columns.fullpath];
1777 Glib::ustring state = (*i)[recent_session_columns.visible_name];
1779 session_selector_window->response (RESPONSE_ACCEPT);
1780 _session_is_new = false;
1782 load_session (path, state);
1787 ARDOUR_UI::filter_ardour_session_dirs (const FileFilter::Info& info)
1789 struct stat statbuf;
1791 if (stat (info.filename.c_str(), &statbuf) != 0) {
1795 if (!S_ISDIR(statbuf.st_mode)) {
1799 string session_file = info.filename;
1800 session_file += '/';
1801 session_file += PBD::basename (info.filename);
1802 session_file += ".ardour";
1804 if (stat (session_file.c_str(), &statbuf) != 0) {
1808 return S_ISREG (statbuf.st_mode);
1812 ARDOUR_UI::open_session ()
1814 /* popup selector window */
1816 if (open_session_selector == 0) {
1817 open_session_selector = new Gtk::FileChooserDialog (_("open session"), FILE_CHOOSER_ACTION_OPEN);
1818 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1819 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
1821 FileFilter filter_ardour;
1822 filter_ardour.set_name (_("Ardour sessions"));
1823 filter_ardour.add_custom (FILE_FILTER_FILENAME, mem_fun (*this, &ARDOUR_UI::filter_ardour_session_dirs));
1825 open_session_selector->add_filter (filter_ardour);
1828 switch (open_session_selector->run ()) {
1835 string session_path = open_session_selector->get_filename();
1839 if (session_path.length() > 0) {
1840 if (Session::find_session (session_path, path, name, isnew) == 0) {
1841 _session_is_new = isnew;
1842 load_session (path, name);
1849 ARDOUR_UI::session_add_midi_track ()
1851 cerr << _("Patience is a virtue.\n");
1855 ARDOUR_UI::session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels)
1860 warning << _("You cannot add a track without a session already loaded.") << endmsg;
1866 if ((route = session->new_audio_track (input_channels, output_channels)) == 0) {
1867 error << _("could not create new audio track") << endmsg;
1870 if ((route = session->new_audio_route (input_channels, output_channels)) == 0) {
1871 error << _("could not create new audio bus") << endmsg;
1876 if (need_control_room_outs) {
1882 route->set_stereo_control_outs (control_lr_channels);
1883 route->control_outs()->set_stereo_pan (pans, this);
1885 #endif /* CONTROLOUTS */
1889 ArdourMessage msg (editor, X_("noport dialog"),
1890 _("There are insufficient JACK ports available\n\
1891 to create a new track or bus.\n\
1892 You should save Ardour, exit and\n\
1893 restart JACK with more ports."));
1898 ARDOUR_UI::diskstream_added (DiskStream* ds)
1900 // meter_bridge_dialog_check->set_sensitive (true);
1904 ARDOUR_UI::do_transport_locate (jack_nframes_t new_position)
1906 jack_nframes_t _preroll;
1909 _preroll = session->convert_to_frames_at (new_position, session->preroll);
1911 if (new_position > _preroll) {
1912 new_position -= _preroll;
1917 session->request_locate (new_position);
1922 ARDOUR_UI::transport_goto_start ()
1925 session->request_locate (0);
1928 /* force displayed area in editor to start no matter
1929 what "follow playhead" setting is.
1933 editor->reposition_x_origin (0);
1939 ARDOUR_UI::transport_goto_end ()
1942 jack_nframes_t frame = session->current_end_frame();
1943 session->request_locate (frame);
1945 /* force displayed area in editor to start no matter
1946 what "follow playhead" setting is.
1950 editor->reposition_x_origin (frame);
1956 ARDOUR_UI::mouse_transport_stop (GdkEventButton *ev)
1961 if (session->transport_stopped()) {
1962 session->request_locate (session->last_transport_start());
1964 if (session->get_auto_loop()) {
1965 session->request_auto_loop (false);
1968 Keyboard::ModifierMask mask = Keyboard::ModifierMask (Keyboard::Control|Keyboard::Shift);
1969 session->request_stop (Keyboard::modifier_state_equals (ev->state, mask));
1977 ARDOUR_UI::mouse_transport_roll (GdkEventButton* ev)
1984 ARDOUR_UI::transport_stop ()
1990 if (session->is_auditioning()) {
1991 session->cancel_audition ();
1995 if (session->get_auto_loop()) {
1996 session->request_auto_loop (false);
1999 session->request_stop ();
2003 ARDOUR_UI::transport_stop_and_forget_capture ()
2006 session->request_stop (true);
2011 ARDOUR_UI::remove_last_capture()
2014 editor->remove_last_capture();
2019 ARDOUR_UI::transport_record ()
2022 switch (session->record_status()) {
2023 case Session::Disabled:
2024 if (session->ntracks() == 0) {
2025 string txt = _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu.");
2026 ArdourMessage msg (editor, X_("cannotrecenable"), txt);
2029 session->maybe_enable_record ();
2031 case Session::Recording:
2032 case Session::Enabled:
2033 session->disable_record ();
2039 ARDOUR_UI::transport_roll ()
2047 rolling = session->transport_rolling ();
2049 if (session->get_auto_loop()) {
2050 session->request_auto_loop (false);
2051 auto_loop_button.set_active (false);
2052 roll_button.set_active (true);
2053 } else if (session->get_play_range ()) {
2054 session->request_play_range (false);
2055 play_selection_button.set_active (false);
2056 } else if (rolling) {
2057 session->request_locate (session->last_transport_start(), true);
2060 session->request_transport_speed (1.0f);
2064 ARDOUR_UI::transport_loop()
2067 if (session->get_auto_loop()) {
2068 if (session->transport_rolling()) {
2069 Location * looploc = session->locations()->auto_loop_location();
2071 session->request_locate (looploc->start(), true);
2076 session->request_auto_loop (true);
2082 ARDOUR_UI::transport_play_selection ()
2088 if (!session->get_play_range()) {
2089 session->request_stop ();
2092 editor->play_selection ();
2096 ARDOUR_UI::transport_rewind (int option)
2098 float current_transport_speed;
2101 current_transport_speed = session->transport_speed();
2103 if (current_transport_speed >= 0.0f) {
2106 session->request_transport_speed (-1.0f);
2109 session->request_transport_speed (-4.0f);
2112 session->request_transport_speed (-0.5f);
2117 session->request_transport_speed (current_transport_speed * 1.5f);
2123 ARDOUR_UI::transport_forward (int option)
2125 float current_transport_speed;
2128 current_transport_speed = session->transport_speed();
2130 if (current_transport_speed <= 0.0f) {
2133 session->request_transport_speed (1.0f);
2136 session->request_transport_speed (4.0f);
2139 session->request_transport_speed (0.5f);
2144 session->request_transport_speed (current_transport_speed * 1.5f);
2150 ARDOUR_UI::toggle_monitor_enable (guint32 dstream)
2158 if ((ds = session->diskstream_by_id (dstream)) != 0) {
2159 Port *port = ds->io()->input (0);
2160 port->request_monitor_input (!port->monitoring_input());
2165 ARDOUR_UI::toggle_record_enable (guint32 dstream)
2173 if ((ds = session->diskstream_by_id (dstream)) != 0) {
2174 ds->set_record_enabled (!ds->record_enabled(), this);
2179 ARDOUR_UI::queue_transport_change ()
2181 Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
2185 ARDOUR_UI::map_transport_state ()
2187 float sp = session->transport_speed();
2190 transport_rolling ();
2191 } else if (sp < 0.0f) {
2192 transport_rewinding ();
2193 } else if (sp > 0.0f) {
2194 transport_forwarding ();
2196 transport_stopped ();
2201 ARDOUR_UI::send_all_midi_feedback ()
2204 session->send_all_midi_feedback();
2209 ARDOUR_UI::allow_local_only ()
2215 ARDOUR_UI::allow_mmc_only ()
2221 ARDOUR_UI::allow_mmc_and_local ()
2227 ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg)
2229 snprintf (buf, sizeof(buf), "%s", ((GlobalClickBox *) arg)->strings[
2230 (int) adj.get_value()].c_str());
2234 ARDOUR_UI::engine_stopped ()
2236 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
2238 jack_disconnect_item->set_sensitive (false);
2239 jack_reconnect_item->set_sensitive (true);
2240 jack_bufsize_menu->set_sensitive (false);
2245 ARDOUR_UI::engine_running ()
2247 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
2249 jack_disconnect_item->set_sensitive (true);
2250 jack_reconnect_item->set_sensitive (false);
2251 jack_bufsize_menu->set_sensitive (true);
2255 ARDOUR_UI::engine_halted ()
2257 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
2259 jack_disconnect_item->set_sensitive (false);
2260 jack_reconnect_item->set_sensitive (true);
2261 jack_bufsize_menu->set_sensitive (false);
2263 update_sample_rate (0);
2265 ArdourMessage msg (editor, X_("halted"),
2267 JACK has either been shutdown or it\n\
2268 disconnected Ardour because Ardour\n\
2269 was not fast enough. You can save the\n\
2270 session and/or try to reconnect to JACK ."));
2274 ARDOUR_UI::do_engine_start ()
2280 catch (AudioEngine::PortRegistrationFailure& err) {
2282 error << _("Unable to create all required ports")
2290 error << _("Unable to start the session running")
2300 ARDOUR_UI::start_engine ()
2302 if (do_engine_start () == 0) {
2303 if (session && _session_is_new) {
2304 /* we need to retain initial visual
2305 settings for a new session
2307 session->save_state ("");
2310 /* there is too much going on, in too many threads, for us to
2311 end up with a clean session. So wait 1 second after loading,
2312 and fix it up. its ugly, but until i come across a better
2313 solution, its what we have.
2316 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::make_session_clean), 1000);
2323 ARDOUR_UI::update_clocks ()
2325 Clock (session->audible_frame()); /* EMIT_SIGNAL */
2329 ARDOUR_UI::start_clocking ()
2331 clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
2335 ARDOUR_UI::stop_clocking ()
2337 clock_signal_connection.disconnect ();
2341 ARDOUR_UI::toggle_clocking ()
2344 if (clock_button.get_active()) {
2353 ARDOUR_UI::_blink (void *arg)
2356 ((ARDOUR_UI *) arg)->blink ();
2363 Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
2367 ARDOUR_UI::start_blinking ()
2369 /* Start the blink signal. Everybody with a blinking widget
2370 uses Blink to drive the widget's state.
2373 if (blink_timeout_tag < 0) {
2375 blink_timeout_tag = gtk_timeout_add (240, _blink, this);
2380 ARDOUR_UI::stop_blinking ()
2382 if (blink_timeout_tag >= 0) {
2383 gtk_timeout_remove (blink_timeout_tag);
2384 blink_timeout_tag = -1;
2390 ARDOUR_UI::add_diskstream_to_menu (DiskStream& dstream)
2392 using namespace Gtk;
2393 using namespace Menu_Helpers;
2395 if (dstream.hidden()) {
2399 MenuList& items = diskstream_menu->items();
2400 items.push_back (MenuElem (dstream.name(), bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), (gint32) dstream.id())));
2404 ARDOUR_UI::diskstream_selected (gint32 id)
2406 selected_dstream = id;
2411 ARDOUR_UI::select_diskstream (GdkEventButton *ev)
2413 using namespace Gtk;
2414 using namespace Menu_Helpers;
2420 diskstream_menu = new Menu();
2421 diskstream_menu->set_name ("ArdourContextMenu");
2422 using namespace Gtk;
2423 using namespace Menu_Helpers;
2425 MenuList& items = diskstream_menu->items();
2426 items.push_back (MenuElem (_("No Stream"), (bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), -1))));
2428 session->foreach_diskstream (this, &ARDOUR_UI::add_diskstream_to_menu);
2431 diskstream_menu->popup (ev->button, ev->time);
2433 diskstream_menu->popup (0, 0);
2436 selected_dstream = -1;
2440 delete diskstream_menu;
2442 return selected_dstream;
2446 ARDOUR_UI::name_io_setup (AudioEngine& engine,
2452 if (io.n_inputs() == 0) {
2457 /* XXX we're not handling multiple ports yet. */
2459 const char **connections = io.input(0)->get_connections();
2461 if (connections == 0 || connections[0] == '\0') {
2464 buf = connections[0];
2471 if (io.n_outputs() == 0) {
2476 /* XXX we're not handling multiple ports yet. */
2478 const char **connections = io.output(0)->get_connections();
2480 if (connections == 0 || connections[0] == '\0') {
2483 buf = connections[0];
2491 ARDOUR_UI::snapshot_session ()
2493 ArdourPrompter prompter (true);
2500 now = now.substr (0, now.length() - 1);
2502 prompter.set_name ("Prompter");
2503 prompter.set_prompt (_("Name for snapshot"));
2504 prompter.set_initial_text (now);
2506 switch (prompter.run()) {
2507 case RESPONSE_ACCEPT:
2508 prompter.get_result (snapname);
2509 if (snapname.length()){
2510 save_state (snapname);
2520 ARDOUR_UI::save_state (string name)
2522 (void) save_state_canfail (name);
2526 ARDOUR_UI::save_state_canfail (string name)
2531 if (name.length() == 0) {
2532 name = session->snap_name();
2535 if ((ret = session->save_state (name)) != 0) {
2539 save_ardour_state (); /* XXX cannot fail? yeah, right ... */
2544 ARDOUR_UI::restore_state (string name)
2547 if (name.length() == 0) {
2548 name = session->name();
2550 session->restore_state (name);
2555 ARDOUR_UI::primary_clock_value_changed ()
2558 session->request_locate (primary_clock.current_time ());
2563 ARDOUR_UI::secondary_clock_value_changed ()
2566 session->request_locate (secondary_clock.current_time ());
2571 ARDOUR_UI::rec_enable_button_blink (bool onoff, DiskStream *dstream, Widget *w)
2573 if (session && dstream && dstream->record_enabled()) {
2575 Session::RecordState rs;
2577 rs = session->record_status ();
2580 case Session::Disabled:
2581 case Session::Enabled:
2582 if (w->get_state() != STATE_SELECTED) {
2583 w->set_state (STATE_SELECTED);
2587 case Session::Recording:
2588 if (w->get_state() != STATE_ACTIVE) {
2589 w->set_state (STATE_ACTIVE);
2595 if (w->get_state() != STATE_NORMAL) {
2596 w->set_state (STATE_NORMAL);
2602 ARDOUR_UI::transport_rec_enable_blink (bool onoff)
2608 switch (session->record_status()) {
2609 case Session::Enabled:
2611 rec_button.set_state (STATE_ACTIVE);
2613 rec_button.set_state (STATE_NORMAL);
2617 case Session::Recording:
2618 rec_button.set_state (STATE_ACTIVE);
2622 rec_button.set_active (false);
2623 rec_button.set_state (STATE_NORMAL);
2629 ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
2637 ARDOUR_UI::start_keyboard_prefix ()
2639 keyboard->start_prefix();
2643 ARDOUR_UI::save_template ()
2646 ArdourPrompter prompter (true);
2649 prompter.set_name (X_("Prompter"));
2650 prompter.set_prompt (_("Name for mix template:"));
2651 prompter.set_initial_text(session->name() + _("-template"));
2653 switch (prompter.run()) {
2654 case RESPONSE_ACCEPT:
2655 prompter.get_result (name);
2657 if (name.length()) {
2658 session->save_template (name);
2668 ARDOUR_UI::new_session (bool startup, std::string predetermined_path)
2670 m_new_session_dialog->show_all();
2671 m_new_session_dialog->set_transient_for(*editor);
2672 m_new_session_dialog->set_name(predetermined_path);
2674 int response = Gtk::RESPONSE_CANCEL;
2677 response = m_new_session_dialog->run ();
2679 if(response == Gtk::RESPONSE_OK) {
2681 _session_is_new = true;
2683 std::string session_name = m_new_session_dialog->session_name();
2684 std::string session_path = m_new_session_dialog->session_folder();
2685 std::string template_name = m_new_session_dialog->session_template_name();
2687 if (m_new_session_dialog->use_session_template()) {
2689 load_session (session_path, session_name, &template_name);
2695 Session::AutoConnectOption iconnect;
2696 Session::AutoConnectOption oconnect;
2698 if (m_new_session_dialog->create_control_track()) {
2699 cchns = (uint32_t) m_new_session_dialog->control_channel_count();
2704 if (m_new_session_dialog->create_master_track()) {
2705 mchns = (uint32_t) m_new_session_dialog->master_channel_count();
2710 if (m_new_session_dialog->connect_inputs()) {
2711 iconnect = Session::AutoConnectPhysical;
2713 iconnect = Session::AutoConnectOption (0);
2716 /// @todo some minor tweaks.
2718 if (m_new_session_dialog->connect_outs_to_master()) {
2719 oconnect = Session::AutoConnectMaster;
2720 } else if (m_new_session_dialog->connect_outs_to_physical()) {
2721 oconnect = Session::AutoConnectPhysical;
2723 oconnect = Session::AutoConnectOption (0);
2726 uint32_t nphysin = (uint32_t) m_new_session_dialog->input_limit_count();
2727 uint32_t nphysout = (uint32_t) m_new_session_dialog->output_limit_count();
2729 build_session (session_path,
2737 engine->frame_rate() * 60 * 5);
2741 } while(response == Gtk::RESPONSE_HELP);
2742 m_new_session_dialog->hide_all();
2746 ARDOUR_UI::load_session (string path, string snap_name, string* mix_template)
2748 Session *new_session;
2750 session_loaded = false;
2751 x = unload_session ();
2759 /* if it already exists, we must have write access */
2761 if (::access (path.c_str(), F_OK) == 0 && ::access (path.c_str(), W_OK)) {
2762 ArdourMessage msg (editor, X_("noaccess dialog"), _("\
2763 You do not have write access to this session.\n\
2764 This prevents the session from being loaded."));
2769 new_session = new Session (*engine, path, snap_name, mix_template);
2774 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
2778 connect_to_session (new_session);
2780 //if (engine->running()) {
2781 //mixer->show_window();
2783 session_loaded = true;
2788 ARDOUR_UI::make_session_clean ()
2791 session->set_clean ();
2798 ARDOUR_UI::build_session (string path, string snap_name,
2799 uint32_t control_channels,
2800 uint32_t master_channels,
2801 Session::AutoConnectOption input_connect,
2802 Session::AutoConnectOption output_connect,
2805 jack_nframes_t initial_length)
2807 Session *new_session;
2810 session_loaded = false;
2811 x = unload_session ();
2818 _session_is_new = true;
2821 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
2822 control_channels, master_channels, nphysin, nphysout, initial_length);
2827 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
2831 connect_to_session (new_session);
2833 //if (engine->running()) {
2834 //mixer->show_window();
2836 session_loaded = true;
2844 editor->show_window ();
2848 if (session && mixer) {
2849 mixer->show_window ();
2858 ARDOUR_UI::show_splash ()
2861 about = new About();
2867 ARDOUR_UI::hide_splash ()
2875 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title, string msg)
2879 removed = rep.paths.size();
2882 ArdourMessage msg (editor, X_("cleanupresults"),
2884 No audio files were ready for cleanup\n\n\
2885 If this seems suprising, check for any existing\n\
2886 snapshots. These may still include regions that\n\
2887 require some unused files to continue to exist."));
2891 ArdourDialog results ("cleanup results");
2893 struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
2894 CleanupResultsModelColumns() {
2898 Gtk::TreeModelColumn<Glib::ustring> visible_name;
2899 Gtk::TreeModelColumn<Glib::ustring> fullpath;
2903 Glib::RefPtr<Gtk::ListStore> results_model;
2904 CleanupResultsModelColumns results_columns;
2905 Gtk::TreeView results_display;
2907 results_model = ListStore::create (results_columns);
2908 results_display.set_model (results_model);
2909 results_display.append_column (list_title, results_columns.visible_name);
2910 results_display.set_headers_visible (true);
2912 Gtk::ScrolledWindow list_scroller;
2914 Gtk::Button ok_button (_("OK"));
2917 vpacker.set_border_width (10);
2918 vpacker.set_spacing (10);
2920 if (rep.space < 1048576.0f) {
2922 txt.set_text (string_compose (msg, removed, _("files"), (float) rep.space / 1024.0f, "kilo"));
2924 txt.set_text (string_compose (msg, removed, _("file"), (float) rep.space / 1024.0f, "kilo"));
2928 txt.set_text (string_compose (msg, removed, _("files"), (float) rep.space / 1048576.0f, "mega"));
2930 txt.set_text (string_compose (msg, removed, _("file"), (float) rep.space / 1048576.0f, "mega"));
2934 vpacker.pack_start (txt, false, false);
2936 for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2937 TreeModel::Row row = *(results_model->append());
2938 row[results_columns.visible_name] = *i;
2939 row[results_columns.fullpath] = *i;
2942 list_scroller.add (results_display);
2943 list_scroller.set_size_request (-1, 250);
2944 list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2946 vpacker.pack_start (list_scroller, true, true);
2947 vpacker.pack_start (ok_button, false, false);
2949 results.add (vpacker);
2951 results.set_position (Gtk::WIN_POS_MOUSE);
2952 results.set_title (_("ardour: cleanup"));
2953 results.set_modal (true);
2959 ARDOUR_UI::cleanup ()
2962 /* shouldn't happen: menu item is insensitive */
2966 ArdourDialog checker (X_("cleanup confirm dialog"));
2967 Gtk::Label label (_("\
2968 Cleanup is a destructive operation.\n\
2969 ALL undo/redo information will be lost if you cleanup.\n\
2970 Unused audio files will be moved to a \"dead sounds\" location."));
2972 Gtk::Button ok_button (_("Proceed with cleanup"));
2973 Gtk::Button cancel_button (_("Cancel"));
2977 bbox.set_border_width (6);
2978 bbox.set_spacing (12);
2979 bbox.pack_start (ok_button, true, false);
2980 bbox.pack_start (cancel_button, true, false);
2982 vbox.set_border_width (6);
2983 vbox.set_spacing (12);
2984 vbox.pack_start (label, false, false);
2985 vbox.pack_start (bbox, false, false);
2988 checker.set_name (_("CleanupDialog"));
2989 checker.set_title (_("ardour cleanup"));
2990 checker.set_wmclass (_("ardour_cleanup"), "Ardour");
2991 checker.set_position (Gtk::WIN_POS_MOUSE);
2993 ok_button.signal_clicked().connect (bind (mem_fun (checker, &ArdourDialog::stop), 1));
2994 cancel_button.signal_clicked().connect (bind (mem_fun (checker, &ArdourDialog::stop), 0));
2998 switch (checker.run_status()) {
3005 Session::cleanup_report rep;
3007 editor->prepare_for_cleanup ();
3009 if (session->cleanup_sources (rep)) {
3013 display_cleanup_results (rep,
3016 The following %1 %2 were not in use.\n\
3017 The next time you flush the wastebasket\n\
3018 it will release an additional %3 %4bytes\n\
3024 ARDOUR_UI::flush_trash ()
3027 /* shouldn't happen: menu item is insensitive */
3031 Session::cleanup_report rep;
3033 if (session->cleanup_trash_sources (rep)) {
3037 display_cleanup_results (rep,
3039 _("The following %1 file%2 were deleted, releasing %3 %4bytes of disk space"));
3043 ARDOUR_UI::add_route ()
3051 if (add_route_dialog == 0) {
3052 add_route_dialog = new AddRouteDialog;
3053 editor->ensure_float (*add_route_dialog);
3056 if (add_route_dialog->is_visible()) {
3057 /* we're already doing this */
3061 add_route_dialog->run ();
3063 if (add_route_dialog->run_status()) {
3067 if ((count = add_route_dialog->count()) <= 0) {
3071 uint32_t input_chan = add_route_dialog->channels ();
3072 uint32_t output_chan;
3073 string name_template = add_route_dialog->name_template ();
3074 bool track = add_route_dialog->track ();
3076 Session::AutoConnectOption oac = session->get_output_auto_connect();
3078 if (oac & Session::AutoConnectMaster) {
3079 output_chan = (session->master_out() ? session->master_out()->n_inputs() : input_chan);
3081 output_chan = input_chan;
3084 /* XXX do something with name template */
3088 session_add_audio_track (input_chan, output_chan);
3090 session_add_audio_bus (input_chan, output_chan);
3094 while (Main::events_pending()) {
3101 ARDOUR_UI::mixer_settings () const
3106 node = session->instant_xml(X_("Mixer"), session->path());
3108 node = Config->instant_xml(X_("Mixer"), Config->get_user_ardour_path());
3112 node = new XMLNode (X_("Mixer"));
3119 ARDOUR_UI::editor_settings () const
3124 node = session->instant_xml(X_("Editor"), session->path());
3126 node = Config->instant_xml(X_("Editor"), Config->get_user_ardour_path());
3130 node = new XMLNode (X_("Editor"));
3136 ARDOUR_UI::keyboard_settings () const
3140 node = Config->extra_xml(X_("Keyboard"));
3143 node = new XMLNode (X_("Keyboard"));
3149 ARDOUR_UI::halt_on_xrun_message ()
3151 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
3153 ArdourMessage msg (editor, X_("haltonxrun"),
3154 _("Recording was stopped because your system could not keep up."));
3158 ARDOUR_UI::delete_sources_in_the_right_thread (list<ARDOUR::Source*>* deletion_list)
3160 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread), deletion_list));
3162 for (list<Source*>::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) {
3166 delete deletion_list;
3170 ARDOUR_UI::disk_overrun_handler ()
3172 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
3174 if (!have_disk_overrun_displayed) {
3175 have_disk_overrun_displayed = true;
3176 ArdourMessage msg (editor, X_("diskrate dialog"), _("\
3177 The disk system on your computer\n\
3178 was not able to keep up with Ardour.\n\
3180 Specifically, it failed to write data to disk\n\
3181 quickly enough to keep up with recording.\n"));
3182 have_disk_overrun_displayed = false;
3187 ARDOUR_UI::disk_underrun_handler ()
3189 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
3191 if (!have_disk_underrun_displayed) {
3192 have_disk_underrun_displayed = true;
3193 ArdourMessage msg (editor, X_("diskrate2 dialog"),
3194 (_("The disk system on your computer\n\
3195 was not able to keep up with Ardour.\n\
3197 Specifically, it failed to read data from disk\n\
3198 quickly enough to keep up with playback.\n")));
3199 have_disk_underrun_displayed = false;
3204 ARDOUR_UI::disk_underrun_message_gone ()
3206 have_disk_underrun_displayed = false;
3210 ARDOUR_UI::disk_overrun_message_gone ()
3212 have_disk_underrun_displayed = false;
3216 ARDOUR_UI::pending_state_dialog ()
3218 ArdourDialog dialog ("pending state dialog");
3219 Button use_button (_("Recover from crash"));
3220 Button cancel_button (_("Ignore crash data"));
3222 This session appears to have been in\n\
3223 middle of recording when ardour or\n\
3224 the computer was shutdown.\n\
3226 Ardour can recover any captured audio for\n\
3227 you, or it can ignore it. Please decide\n\
3228 what you would like to do.\n"));
3232 vpacker.set_border_width (12);
3233 vpacker.set_spacing (7);
3234 vpacker.pack_start (message);
3235 vpacker.pack_start (hpacker);
3237 hpacker.set_spacing (7);
3238 hpacker.pack_start (use_button);
3239 hpacker.pack_start (cancel_button);
3241 use_button.signal_clicked().connect (bind (mem_fun (dialog, &ArdourDialog::stop), 0));
3242 cancel_button.signal_clicked().connect (bind (mem_fun (dialog, &ArdourDialog::stop), 1));
3244 dialog.add (vpacker);
3245 dialog.set_position (WIN_POS_CENTER);
3250 if (dialog.run_status () != 0) {
3259 ARDOUR_UI::disconnect_from_jack ()
3262 if( engine->disconnect_from_jack ()) {
3263 ArdourMessage msg (editor, X_("nojack dialog"),
3264 _("Could not disconnect from JACK"));
3267 update_sample_rate (0);
3272 ARDOUR_UI::reconnect_to_jack ()
3275 if (engine->reconnect_to_jack ()) {
3276 ArdourMessage msg (editor, X_("nojack dialog"),
3277 _("Could not reconnect to JACK"));
3280 update_sample_rate (0);
3285 ARDOUR_UI::set_jack_buffer_size (jack_nframes_t nframes)
3287 engine->request_buffer_size (nframes);
3288 update_sample_rate (0);
3292 ARDOUR_UI::cmdline_new_session (string path)
3294 if (path[0] != '/') {
3295 char buf[PATH_MAX+1];
3298 getcwd (buf, sizeof (buf));
3305 new_session (false, path);
3307 _will_create_new_session_automatically = false; /* done it */
3308 return FALSE; /* don't call it again */