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.
32 #include <pbd/error.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/selector.h>
41 #include <gtkmm2ext/fastmeter.h>
42 #include <gtkmm2ext/stop_signal.h>
43 #include <gtkmm2ext/popup.h>
45 #include <midi++/port.h>
46 #include <midi++/mmc.h>
48 #include <ardour/ardour.h>
49 #include <ardour/port.h>
50 #include <ardour/audioengine.h>
51 #include <ardour/playlist.h>
52 #include <ardour/utils.h>
53 #include <ardour/diskstream.h>
54 #include <ardour/filesource.h>
55 #include <ardour/recent_sessions.h>
56 #include <ardour/session_diskstream.h>
57 #include <ardour/port.h>
58 #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;
83 SoundFileSelector* ARDOUR_UI::sfdb_window = 0;
85 sigc::signal<void,bool> ARDOUR_UI::Blink;
86 sigc::signal<void> ARDOUR_UI::RapidScreenUpdate;
87 sigc::signal<void> ARDOUR_UI::SuperRapidScreenUpdate;
88 sigc::signal<void,jack_nframes_t> ARDOUR_UI::Clock;
91 static const gchar *h_meter_strip_xpm[] = {
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.`. +++",
284 ". + @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / ( _ : < [ } | 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.`. +++"};
287 static const gchar * v_meter_strip_xpm[] = {
770 static const char* channel_setup_names[] = {
781 vector<string> channel_combo_strings;
783 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
785 : Gtkmm2ext::UI ("ardour", argcp, argvp, rcfile),
787 primary_clock (X_("TransportClockDisplay"), true, false, true),
788 secondary_clock (X_("SecondaryClockDisplay"), true, false, true),
789 preroll_clock (X_("PreRollClock"), true, true),
790 postroll_clock (X_("PostRollClock"), true, true),
794 adjuster_table (3, 3),
798 preroll_button (_("pre\nroll")),
799 postroll_button (_("post\nroll")),
803 big_clock ("BigClockDisplay", true),
807 shuttle_units_button (_("% ")),
808 shuttle_style_button (_("spring")),
810 punch_in_button (_("punch\nin")),
811 punch_out_button (_("punch\nout")),
812 auto_return_button (_("auto\nreturn")),
813 auto_play_button (_("auto\nplay")),
814 auto_input_button (_("auto\ninput")),
815 click_button (_("click")),
816 follow_button (_("follow\nPH")),
817 auditioning_alert_button (_("AUDITIONING")),
818 solo_alert_button (_("SOLO")),
820 session_selector (1, 0),
825 using namespace Gtk::Menu_Helpers;
829 /* actually, its already loaded, but ... */
831 cerr << "Loading UI configuration file " << rcfile << endl;
835 if (theArdourUI == 0) {
842 _session_is_new = false;
843 big_clock_window = 0;
844 session_selector_window = 0;
845 last_key_press_time = 0;
846 connection_editor = 0;
847 add_route_dialog = 0;
853 new_session_window = 0;
854 open_session_selector = 0;
855 have_configure_timeout = false;
856 have_disk_overrun_displayed = false;
857 have_disk_underrun_displayed = false;
858 _will_create_new_session_automatically = false;
859 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_style_actions = ActionGroup::create ();
871 Glib::RefPtr<ActionGroup> shuttle_unit_actions = ActionGroup::create ();
873 shuttle_unit_actions->add (Action::create (_("Percentage")), bind (mem_fun(*this, &ARDOUR_UI::set_shuttle_units), Percentage));
874 shuttle_unit_actions->add (Action::create (_("Semitones")), bind (mem_fun(*this, &ARDOUR_UI::set_shuttle_units), Semitones));
875 shuttle_style_actions->add (Action::create (_("Sprung")), bind (mem_fun(*this, &ARDOUR_UI::set_shuttle_behaviour), Sprung));
876 shuttle_style_actions->add (Action::create (_("Wheel")), bind (mem_fun(*this, &ARDOUR_UI::set_shuttle_behaviour), Wheel));
878 uiManager->insert_action_group (shuttle_style_actions);
879 uiManager->insert_action_group (shuttle_unit_actions);
881 shuttle_style_menu = uiManager.get_widget ('/ShuttleStyle');
882 shuttle_unit_menu = uiManager.get_widget ('/ShuttleUnits');
884 gettimeofday (&last_peak_grab, 0);
885 gettimeofday (&last_shuttle_request, 0);
887 ARDOUR::DiskStream::CannotRecordNoInput.connect (mem_fun(*this, &ARDOUR_UI::cannot_record_no_input));
888 ARDOUR::DiskStream::DeleteSources.connect (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread));
889 ARDOUR::DiskStream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
890 ARDOUR::DiskStream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
892 /* handle pending state with a dialog */
894 ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
896 channel_combo_strings = internationalize (channel_setup_names);
898 /* have to wait for AudioEngine and Configuration before proceeding */
902 ARDOUR_UI::cannot_record_no_input (DiskStream* ds)
904 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::cannot_record_no_input), ds));
906 string msg = compose (_("\
907 You cannot record-enable\n\
909 because it has no input connections.\n\
910 You would be wasting space recording silence."),
913 ArdourMessage message (editor, X_("cannotrecord"), msg);
917 ARDOUR_UI::set_engine (AudioEngine& e)
921 engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
922 engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
923 engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
924 engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
928 keyboard = new Keyboard;
929 install_keybindings ();
931 FastMeter::set_vertical_xpm (v_meter_strip_xpm);
932 FastMeter::set_horizontal_xpm (h_meter_strip_xpm);
934 if (setup_windows ()) {
935 throw failed_constructor ();
938 if (GTK_ARDOUR::show_key_actions) {
939 KeyboardTarget::show_all_actions ();
943 /* start with timecode, metering enabled
946 blink_timeout_tag = -1;
948 /* this being a GUI and all, we want peakfiles */
950 FileSource::set_build_peakfiles (true);
951 FileSource::set_build_missing_peakfiles (true);
953 if (Source::start_peak_thread ()) {
954 throw failed_constructor();
957 /* start the time-of-day-clock */
959 update_wall_clock ();
960 Main::timeout.connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
962 update_disk_space ();
964 update_sample_rate (engine->frame_rate());
966 starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
967 stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
970 ARDOUR_UI::~ARDOUR_UI ()
972 save_ardour_state ();
986 if (add_route_dialog) {
987 delete add_route_dialog;
990 Source::stop_peak_thread ();
994 ARDOUR_UI::configure_timeout ()
999 if (last_configure_time.tv_sec == 0 && last_configure_time.tv_usec == 0) {
1000 /* no configure events yet */
1004 gettimeofday (&now, 0);
1005 timersub (&now, &last_configure_time, &diff);
1007 /* force a gap of 0.5 seconds since the last configure event
1010 if (diff.tv_sec == 0 && diff.tv_usec < 500000) {
1013 have_configure_timeout = false;
1014 save_ardour_state ();
1020 ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
1022 if (have_configure_timeout) {
1023 gettimeofday (&last_configure_time, 0);
1026 t.connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
1027 have_configure_timeout = true;
1034 ARDOUR_UI::save_ardour_state ()
1036 if (!keyboard || !mixer || !editor) {
1040 /* XXX this is all a bit dubious. add_extra_xml() uses
1041 a different lifetime model from add_instant_xml().
1044 XMLNode* node = new XMLNode (keyboard->get_state());
1045 Config->add_extra_xml (*node);
1046 Config->save_state();
1048 XMLNode& enode (static_cast<Stateful*>(editor)->get_state());
1049 XMLNode& mnode (mixer->get_state());
1052 session->add_instant_xml(enode, session->path());
1053 session->add_instant_xml(mnode, session->path());
1055 Config->add_instant_xml(enode, Config->get_user_ardour_path());
1056 Config->add_instant_xml(mnode, Config->get_user_ardour_path());
1061 ARDOUR_UI::startup ()
1063 /* Once the UI is up and running, start the audio engine. Doing
1064 this before the UI is up and running can cause problems
1065 when not running with SCHED_FIFO, because the amount of
1066 CPU and disk work needed to get the UI started can interfere
1067 with the scheduling of the audio thread.
1070 Gtk::Main::idle.connect (mem_fun(*this, &ARDOUR_UI::start_engine));
1076 if (session && session->dirty()) {
1077 switch (ask_about_saving_session(_("quit"))) {
1082 /* use the default name */
1083 if (save_state_canfail ("")) {
1084 /* failed - don't quit */
1085 ArdourMessage (editor, X_("badsave dialog"),
1087 Ardour was unable to save your session.\n\n\
1088 If you still wish to quit, please use the\n\n\
1089 \"Just quit\" option."));
1102 ARDOUR_UI::ask_about_saving_session (string what)
1104 ArdourDialog window ("saving dialog");
1106 Gtk::Label prompt_label;
1107 Gtk::HBox button_packer;
1111 msg = compose(_("Save and %1"), what);
1113 Gtk::Button save_button (msg);
1114 save_button.set_name ("EditorGTKButton");
1116 msg = compose(_("Just %1"), what);
1118 Gtk::Button nosave_button (msg);
1119 nosave_button.set_name ("EditorGTKButton");
1121 msg = compose(_("Don't %1"), what);
1123 Gtk::Button noquit_button (msg);
1124 noquit_button.set_name ("EditorGTKButton");
1129 if (session->snap_name() == session->name()) {
1130 type = _("session");
1132 type = _("snapshot");
1134 prompt = 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?"),
1135 type, session->snap_name());
1137 prompt_label.set_text (prompt);
1138 prompt_label.set_alignment (0.5, 0.5);
1139 prompt_label.set_name (X_("PrompterLabel"));
1141 save_button.signal_clicked().connect (bind(mem_fun(window,&ArdourDialog::stop), 1));
1142 nosave_button.signal_clicked().connect (bind(mem_fun(window,&ArdourDialog::stop), 0));
1143 noquit_button.signal_clicked().connect (bind(mem_fun(window,&ArdourDialog::stop), -1));
1145 button_packer.set_spacing (10);
1146 button_packer.pack_start (save_button);
1147 button_packer.pack_start (nosave_button);
1148 button_packer.pack_start (noquit_button);
1150 packer.set_spacing (10);
1151 packer.set_border_width (10);
1152 packer.pack_start (prompt_label);
1153 packer.pack_start (button_packer);
1155 window.set_name (_("Prompter"));
1156 window.set_title (_("ardour: save session?"));
1157 window.set_position (Gtk::WIN_POS_MOUSE);
1158 window.set_modal (true);
1159 window.add (packer);
1163 window.get_window().set_decorations (GdkWMDecoration (GDK_DECOR_BORDER|GDK_DECOR_RESIZEH));
1164 window.set_keyboard_input (true);
1166 save_the_session = 0;
1168 editor->ensure_float (window);
1172 return window.run_status();
1176 ARDOUR_UI::every_second ()
1179 update_buffer_load ();
1180 update_disk_space ();
1181 // update_disk_rate ();
1186 ARDOUR_UI::every_point_one_seconds ()
1189 struct timeval diff;
1191 /* do not attempt to grab peak power more than once per cycle.
1194 gettimeofday (&now, 0);
1195 timersub (&now, &last_peak_grab, &diff);
1197 if ((diff.tv_usec + (diff.tv_sec * 1000000)) >= engine->usecs_per_cycle()) {
1198 IO::GrabPeakPower(); /* EMIT_SIGNAL */
1199 last_peak_grab = now;
1202 update_speed_display ();
1203 RapidScreenUpdate(); /* EMIT_SIGNAL */
1208 ARDOUR_UI::every_point_zero_one_seconds ()
1210 SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
1215 ARDOUR_UI::update_sample_rate (jack_nframes_t ignored)
1219 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
1221 if (!engine->connected()) {
1223 snprintf (buf, sizeof (buf), _("disconnected"));
1227 jack_nframes_t rate = engine->frame_rate();
1229 if (fmod (rate, 1000.0) != 0.0) {
1230 snprintf (buf, sizeof (buf), _("SR: %.1f kHz / %4.1f msecs"),
1231 (float) rate/1000.0f,
1232 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
1234 snprintf (buf, sizeof (buf), _("SR: %u kHz / %4.1f msecs"),
1236 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
1240 sample_rate_label.set_text (buf);
1244 ARDOUR_UI::update_cpu_load ()
1247 snprintf (buf, sizeof (buf), _("DSP Load: %.1f%%"), engine->get_cpu_load());
1248 cpu_load_label.set_text (buf);
1252 ARDOUR_UI::update_disk_rate ()
1257 snprintf (buf, sizeof (buf), _("Disk r:%5.1f w:%5.1f MB/s"),
1258 session->read_data_rate()/1048576.0f, session->write_data_rate()/1048576.0f);
1259 disk_rate_label.set_text (buf);
1261 disk_rate_label.set_text ("");
1266 ARDOUR_UI::update_buffer_load ()
1271 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"),
1272 session->playback_load(), session->capture_load());
1273 buffer_load_label.set_text (buf);
1275 buffer_load_label.set_text ("");
1280 ARDOUR_UI::count_recenabled_diskstreams (DiskStream& ds)
1282 if (ds.record_enabled()) {
1283 rec_enabled_diskstreams++;
1288 ARDOUR_UI::update_disk_space()
1294 jack_nframes_t frames = session->available_capture_duration();
1297 if (frames == max_frames) {
1298 strcpy (buf, _("space: 24hrs+"));
1303 jack_nframes_t fr = session->frame_rate();
1305 if (session->actively_recording()){
1307 rec_enabled_diskstreams = 0;
1308 session->foreach_diskstream (this, &ARDOUR_UI::count_recenabled_diskstreams);
1310 if (rec_enabled_diskstreams) {
1311 frames /= rec_enabled_diskstreams;
1316 /* hmmm. shall we divide by the route count? or the diskstream count?
1317 or what? for now, do nothing ...
1322 hrs = frames / (fr * 3600);
1323 frames -= hrs * fr * 3600;
1324 mins = frames / (fr * 60);
1325 frames -= mins * fr * 60;
1328 snprintf (buf, sizeof(buf), _("space: %02dh:%02dm:%02ds"), hrs, mins, secs);
1331 disk_space_label.set_text (buf);
1335 ARDOUR_UI::update_wall_clock ()
1342 tm_now = localtime (&now);
1344 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
1345 wall_clock_label.set_text (buf);
1351 ARDOUR_UI::toggle_recording_plugins ()
1353 /* XXX use toggle_some_session_state */
1359 session->set_recording_plugins (!session->get_recording_plugins());
1363 ARDOUR_UI::toggle_auto_play ()
1366 toggle_some_session_state (auto_play_button,
1367 &Session::get_auto_play,
1368 &Session::set_auto_play);
1372 ARDOUR_UI::toggle_auto_return ()
1375 toggle_some_session_state (auto_return_button,
1376 &Session::get_auto_return,
1377 &Session::set_auto_return);
1381 ARDOUR_UI::toggle_click ()
1383 toggle_some_session_state (click_button,
1384 &Session::get_clicking,
1385 &Session::set_clicking);
1389 ARDOUR_UI::follow_changed ()
1397 if (follow_button.get_active() != (x = editor->follow_playhead())) {
1398 follow_button.set_active (x);
1403 ARDOUR_UI::toggle_follow ()
1411 if (editor->follow_playhead() != (x = follow_button.get_active())) {
1412 editor->set_follow_playhead (x);
1417 ARDOUR_UI::toggle_session_auto_loop ()
1420 if (session->get_auto_loop()) {
1421 if (session->transport_rolling()) {
1425 session->request_auto_loop (false);
1429 session->request_auto_loop (true);
1435 ARDOUR_UI::toggle_session_punch_in ()
1438 session->set_punch_in (!session->get_punch_in());
1443 ARDOUR_UI::toggle_punch_out ()
1445 toggle_some_session_state (punch_out_button,
1446 &Session::get_punch_out,
1447 &Session::set_punch_out);
1451 ARDOUR_UI::toggle_punch_in ()
1453 toggle_some_session_state (punch_in_button,
1454 &Session::get_punch_in,
1455 &Session::set_punch_in);
1459 ARDOUR_UI::map_button_state ()
1462 map_some_session_state (auto_return_button,
1463 &Session::get_auto_return);
1464 map_some_session_state (auto_play_button,
1465 &Session::get_auto_play);
1466 map_some_session_state (auto_input_button,
1467 &Session::get_auto_input);
1468 map_some_session_state (punch_in_button,
1469 &Session::get_punch_in);
1470 map_some_session_state (punch_out_button,
1471 &Session::get_punch_out);
1472 map_some_session_state (click_button,
1473 &Session::get_clicking);
1477 ARDOUR_UI::queue_map_control_change (Session::ControlType t)
1479 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::map_control_change), t));
1483 ARDOUR_UI::map_control_change (Session::ControlType t)
1486 case Session::AutoPlay:
1487 map_some_session_state (auto_play_button, &Session::get_auto_play);
1490 case Session::AutoLoop:
1493 case Session::AutoReturn:
1494 map_some_session_state (auto_return_button, &Session::get_auto_return);
1497 case Session::AutoInput:
1498 map_some_session_state (auto_input_button, &Session::get_auto_input);
1501 case Session::PunchOut:
1502 map_some_session_state (punch_in_button, &Session::get_punch_out);
1505 case Session::PunchIn:
1506 map_some_session_state (punch_in_button, &Session::get_punch_in);
1509 case Session::Clicking:
1510 map_some_session_state (click_button, &Session::get_clicking);
1513 case Session::SlaveType:
1514 // map_some_session_state (mtc_slave_button, &Session::get_mtc_slave);
1517 case Session::SendMTC:
1518 // map_some_session_state (send_mtc_button, &Session::get_send_mtc);
1521 case Session::SendMMC:
1522 // map_some_session_state (send_mmc_button, &Session::get_send_mmc);
1525 case Session::MMCControl:
1526 // map_some_session_state (mmc_control_button, &Session::get_mmc_control);
1529 case Session::MidiFeedback:
1530 // map_some_session_state (mmc_control_button, &Session::get_mmc_control);
1532 case Session::MidiControl:
1533 // map_some_session_state (mmc_control_button, &Session::get_mmc_control);
1539 case Session::RecordingPlugins:
1542 case Session::CrossFadesActive:
1545 case Session::EditingMode:
1548 case Session::PlayRange:
1551 case Session::AlignChoice:
1552 /* don't care, this is handled by the options editor */
1554 case Session::SeamlessLoop:
1555 /* don't care, this is handled by the options editor */
1562 ARDOUR_UI::control_methods_adjusted ()
1567 which_method = (int) online_control_button->adjustment.get_value();
1568 switch (which_method) {
1570 allow_mmc_and_local ();
1576 allow_local_only ();
1579 fatal << _("programming error: impossible control method") << endmsg;
1585 ARDOUR_UI::mmc_device_id_adjusted ()
1590 int dev_id = (int) mmc_id_button->adjustment.get_value();
1591 mmc->set_device_id (dev_id);
1597 ARDOUR_UI::map_some_session_state (ToggleButton& button,
1598 bool (Session::*get)() const)
1607 if (button.get_active() != (x = (session->*get)())) {
1608 button.set_active (x);
1613 ARDOUR_UI::toggle_some_session_state (ToggleButton& button,
1614 bool (Session::*get)() const,
1615 void (Session::*set)(bool))
1625 button_state = button.get_active ();
1626 session_state = (session->*get)();
1628 if (button_state != session_state) {
1629 (session->*set) (button_state);
1632 /* check that it worked, and reverse
1633 the button state if it didn't
1636 if ((session->*get)() != button_state) {
1637 button->set_active (!button_state);
1645 ARDOUR_UI::session_menu (GdkEventButton *ev)
1647 session_popup_menu->popup (0, 0, 0, 0);
1652 ARDOUR_UI::redisplay_recent_sessions ()
1654 using namespace Gtkmm2ext;
1655 using namespace Gtk::CTree_Helpers;
1657 vector<string *> *sessions;
1658 vector<string *>::iterator i;
1659 RecentSessionsSorter cmp;
1661 /* ---------------------------------------- */
1662 /* XXX MAKE ME A FUNCTION (no CTree::clear() in gtkmm 1.2) */
1664 gtk_ctree_remove_node (session_selector.gobj(), NULL);
1665 /* ---------------------------------------- */
1669 ARDOUR::read_recent_sessions (rs);
1672 session_selector.thaw();
1675 /* sort them alphabetically */
1676 sort(rs.begin(), rs.end(), cmp);
1677 sessions = new vector<string*>;
1678 for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
1679 sessions->push_back (new string ((*i).second));
1682 session_selector.freeze();
1684 for (i = sessions->begin(); i != sessions->end(); ++i) {
1686 vector<string*>* states;
1687 vector<const gchar*> item;
1688 string fullpath = *(*i);
1690 /* remove any trailing / */
1692 if (fullpath[fullpath.length()-1] == '/') {
1693 fullpath = fullpath.substr (0, fullpath.length()-1);
1696 /* now get available states for this session */
1698 if ((states = Session::possible_states(fullpath)) == 0) {
1699 /* no state file? */
1703 /* OK, try to add entries for this session */
1706 /* add the parent */
1709 string basen = PBD::basename (fullpath);
1710 item.push_back (basen.c_str());
1711 session_selector.rows().push_back (Element (item));
1713 session_selector.rows().back().set_data (new string (fullpath), deferred_delete<string>);
1715 if (states->size() == 1) {
1717 /* only 1 state, show it at the top level */
1719 session_selector.rows().back().set_leaf (true);
1723 session_selector.rows().back().set_leaf (false);
1725 vector<string *>::iterator i2;
1727 /* add the children */
1729 for (i2 = states->begin(); i2 != states->end(); ++i2) {
1731 string statename = *(*i2);
1734 item.push_back (statename.c_str());
1736 session_selector.rows().back().subtree().push_back (Element (item));
1737 session_selector.rows().back().subtree().back().set_data (new string (statename),
1738 deferred_delete<string>);
1739 session_selector.rows().back().subtree().back().set_leaf (true);
1748 session_selector.thaw();
1753 ARDOUR_UI::session_selection (Gtk::CTree_Helpers::Row row, gint column)
1755 using namespace Gtk::CTree_Helpers;
1757 string session_name;
1758 string session_path;
1759 string session_state;
1761 if (!row.is_leaf()) {
1766 string *stp = static_cast<string *> (row.get_data());
1768 if ((*stp)[0] != '/' && (*stp)[0] != '.') {
1770 /* its a state file node, so get the parent for the session information,
1771 and combine with the state file name.
1774 string *spp = static_cast<string *> (row.get_parent().get_data());
1776 session_name = *spp;
1777 session_path = *spp;
1778 session_state = *stp;
1782 /* its a session directory node, so just get the session path,
1783 and use "default" to load the state.
1786 string *spp = static_cast<string *> (row.get_data());
1788 session_name = *spp;
1789 session_path = *spp;
1790 session_state = PBD::basename (*spp);
1793 session_selector_window->hide ();
1794 _session_is_new = false;
1795 load_session (session_path, session_state);
1799 ARDOUR_UI::build_session_selector ()
1801 session_selector_window = new ArdourDialog ("session selector");
1803 Gtk::VBox *vpacker = new Gtk::VBox;
1804 Gtk::ScrolledWindow *scroller = new Gtk::ScrolledWindow;
1805 Gtk::HBox *button_packer = new Gtk::HBox;
1806 Gtk::Button *cancel_button = new Gtk::Button (_("cancel"));
1807 Gtk::Button *rescan_button = new Gtk::Button (_("rescan"));
1809 button_packer->pack_start (*rescan_button);
1810 button_packer->pack_start (*cancel_button);
1812 vpacker->pack_start (*scroller);
1813 vpacker->pack_start (*button_packer, false, false);
1815 scroller->add (session_selector);
1816 scroller->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1818 session_selector_window->add (*vpacker);
1819 session_selector_window->set_name ("SessionSelectorWindow");
1820 session_selector_window->set_size_request (200, 400);
1822 session_selector_window->signal_delete_event().connect (bind (ptr_fun (just_hide_it), static_cast<Gtk::Window*>(session_selector_window)));
1823 cancel_button-.signal_clicked().connect (bind (mem_fun(*this, &ARDOUR_UI::hide_dialog), session_selector_window));
1824 session_selector.tree_select_row.connect (mem_fun(*this, &ARDOUR_UI::session_selection));
1828 ARDOUR_UI::fs_cancel_clicked (Gtk::FileSelection* fs)
1831 fs->get_selection_entry()->set_text("");
1832 allow_focus (false);
1836 ARDOUR_UI::fs_delete_event (GdkEventAny* ev, Gtk::FileSelection* fs)
1838 fs_cancel_clicked (fs);
1843 ARDOUR_UI::open_session ()
1845 /* popup selector window */
1847 if (open_session_selector == 0) {
1848 open_session_selector = new Gtk::FileSelection(_("open session"));
1849 open_session_selector->get_ok_button()-.signal_clicked().connect (mem_fun(*this, &ARDOUR_UI::open_ok_clicked));
1850 open_session_selector->get_cancel_button()-.signal_clicked().connect (bind (mem_fun(*this, &ARDOUR_UI::fs_cancel_clicked), open_session_selector));
1851 open_session_selector->signal_delete_event().connect (bind (mem_fun(*this, &ARDOUR_UI::fs_delete_event), open_session_selector));
1854 open_session_selector->show_all ();
1857 /* wait for selection */
1861 ARDOUR_UI::open_ok_clicked ()
1863 open_session_selector->hide_all();
1864 string session_path = open_session_selector->get_filename();
1868 if (session_path.length() > 0) {
1869 if (Session::find_session (session_path, path, name, isnew) == 0) {
1870 _session_is_new = isnew;
1871 load_session (path, name);
1875 open_session_selector->get_selection_entry()->set_text("");
1877 /* XXX hack hack hack */
1879 GtkCList* clist = (GtkCList*) open_session_selector->gobj()->file_list;
1880 gtk_clist_unselect_all (clist);
1886 ARDOUR_UI::open_recent_session ()
1888 /* popup selector window */
1890 if (session_selector_window == 0) {
1891 build_session_selector ();
1894 redisplay_recent_sessions ();
1895 session_selector_window->show_all ();
1897 /* wait for selection */
1901 ARDOUR_UI::session_add_midi_track ()
1903 cerr << _("Patience is a virtue.\n");
1907 ARDOUR_UI::session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels)
1912 warning << _("You cannot add a track without a session already loaded.") << endmsg;
1918 if ((route = session->new_audio_track (input_channels, output_channels)) == 0) {
1919 error << _("could not create new audio track") << endmsg;
1922 if ((route = session->new_audio_route (input_channels, output_channels)) == 0) {
1923 error << _("could not create new audio bus") << endmsg;
1928 if (need_control_room_outs) {
1934 route->set_stereo_control_outs (control_lr_channels);
1935 route->control_outs()->set_stereo_pan (pans, this);
1937 #endif /* CONTROLOUTS */
1941 ArdourMessage msg (editor, X_("noport dialog"),
1942 _("There are insufficient JACK ports available\n\
1943 to create a new track or bus.\n\
1944 You should save Ardour, exit and\n\
1945 restart JACK with more ports."));
1950 ARDOUR_UI::diskstream_added (DiskStream* ds)
1952 // meter_bridge_dialog_check->set_sensitive (true);
1956 ARDOUR_UI::do_transport_locate (jack_nframes_t new_position)
1958 jack_nframes_t _preroll;
1961 _preroll = session->convert_to_frames_at (new_position, session->preroll);
1963 if (new_position > _preroll) {
1964 new_position -= _preroll;
1969 session->request_locate (new_position);
1974 ARDOUR_UI::transport_goto_start ()
1977 session->request_locate (0);
1980 /* force displayed area in editor to start no matter
1981 what "follow playhead" setting is.
1985 editor->reposition_x_origin (0);
1991 ARDOUR_UI::transport_goto_end ()
1994 jack_nframes_t frame = session->current_end_frame();
1995 session->request_locate (frame);
1997 /* force displayed area in editor to start no matter
1998 what "follow playhead" setting is.
2002 editor->reposition_x_origin (frame);
2008 ARDOUR_UI::mouse_transport_stop (GdkEventButton *ev)
2013 if (session->transport_stopped()) {
2014 session->request_locate (session->last_transport_start());
2016 if (session->get_auto_loop()) {
2017 session->request_auto_loop (false);
2020 Keyboard::ModifierMask mask = Keyboard::ModifierMask (Keyboard::Control|Keyboard::Shift);
2021 session->request_stop (Keyboard::modifier_state_equals (ev->state, mask));
2029 ARDOUR_UI::mouse_transport_roll (GdkEventButton* ev)
2036 ARDOUR_UI::transport_stop ()
2042 if (session->is_auditioning()) {
2043 session->cancel_audition ();
2047 if (session->get_auto_loop()) {
2048 session->request_auto_loop (false);
2051 session->request_stop ();
2055 ARDOUR_UI::transport_stop_and_forget_capture ()
2058 session->request_stop (true);
2063 ARDOUR_UI::remove_last_capture()
2066 editor->remove_last_capture();
2071 ARDOUR_UI::transport_record ()
2074 switch (session->record_status()) {
2075 case Session::Disabled:
2076 if (session->ntracks() == 0) {
2077 string txt = _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu.");
2078 ArdourMessage msg (editor, X_("cannotrecenable"), txt);
2081 session->maybe_enable_record ();
2083 case Session::Recording:
2084 case Session::Enabled:
2085 session->disable_record ();
2091 ARDOUR_UI::transport_roll ()
2099 rolling = session->transport_rolling ();
2101 if (session->get_auto_loop()) {
2102 session->request_auto_loop (false);
2103 auto_loop_button.set_active (false);
2104 roll_button.set_active (true);
2105 } else if (session->get_play_range ()) {
2106 session->request_play_range (false);
2107 play_selection_button.set_active (false);
2108 } else if (rolling) {
2109 session->request_locate (session->last_transport_start(), true);
2112 session->request_transport_speed (1.0f);
2116 ARDOUR_UI::transport_loop()
2119 if (session->get_auto_loop()) {
2120 if (session->transport_rolling()) {
2121 Location * looploc = session->locations()->auto_loop_location();
2123 session->request_locate (looploc->start(), true);
2128 session->request_auto_loop (true);
2134 ARDOUR_UI::transport_play_selection ()
2140 if (!session->get_play_range()) {
2141 session->request_stop ();
2144 editor->play_selection ();
2148 ARDOUR_UI::transport_rewind (int option)
2150 float current_transport_speed;
2153 current_transport_speed = session->transport_speed();
2155 if (current_transport_speed >= 0.0f) {
2158 session->request_transport_speed (-1.0f);
2161 session->request_transport_speed (-4.0f);
2164 session->request_transport_speed (-0.5f);
2169 session->request_transport_speed (current_transport_speed * 1.5f);
2175 ARDOUR_UI::transport_forward (int option)
2177 float current_transport_speed;
2180 current_transport_speed = session->transport_speed();
2182 if (current_transport_speed <= 0.0f) {
2185 session->request_transport_speed (1.0f);
2188 session->request_transport_speed (4.0f);
2191 session->request_transport_speed (0.5f);
2196 session->request_transport_speed (current_transport_speed * 1.5f);
2202 ARDOUR_UI::toggle_monitor_enable (guint32 dstream)
2210 if ((ds = session->diskstream_by_id (dstream)) != 0) {
2211 Port *port = ds->io()->input (0);
2212 port->request_monitor_input (!port->monitoring_input());
2217 ARDOUR_UI::toggle_record_enable (guint32 dstream)
2225 if ((ds = session->diskstream_by_id (dstream)) != 0) {
2226 ds->set_record_enabled (!ds->record_enabled(), this);
2231 ARDOUR_UI::queue_transport_change ()
2233 Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
2237 ARDOUR_UI::map_transport_state ()
2239 float sp = session->transport_speed();
2242 transport_rolling ();
2243 } else if (sp < 0.0f) {
2244 transport_rewinding ();
2245 } else if (sp > 0.0f) {
2246 transport_forwarding ();
2248 transport_stopped ();
2253 ARDOUR_UI::send_all_midi_feedback ()
2256 session->send_all_midi_feedback();
2261 ARDOUR_UI::allow_local_only ()
2267 ARDOUR_UI::allow_mmc_only ()
2273 ARDOUR_UI::allow_mmc_and_local ()
2279 ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg)
2281 snprintf (buf, sizeof(buf), "%s", ((GlobalClickBox *) arg)->strings[
2282 (int) adj.get_value()].c_str());
2286 ARDOUR_UI::engine_stopped ()
2288 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
2290 jack_disconnect_item->set_sensitive (false);
2291 jack_reconnect_item->set_sensitive (true);
2292 jack_bufsize_menu->set_sensitive (false);
2297 ARDOUR_UI::engine_running ()
2299 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
2301 jack_disconnect_item->set_sensitive (true);
2302 jack_reconnect_item->set_sensitive (false);
2303 jack_bufsize_menu->set_sensitive (true);
2307 ARDOUR_UI::engine_halted ()
2309 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
2311 jack_disconnect_item->set_sensitive (false);
2312 jack_reconnect_item->set_sensitive (true);
2313 jack_bufsize_menu->set_sensitive (false);
2315 update_sample_rate (0);
2317 ArdourMessage msg (editor, X_("halted"),
2319 JACK has either been shutdown or it\n\
2320 disconnected Ardour because Ardour\n\
2321 was not fast enough. You can save the\n\
2322 session and/or try to reconnect to JACK ."));
2326 ARDOUR_UI::do_engine_start ()
2332 catch (AudioEngine::PortRegistrationFailure& err) {
2334 error << _("Unable to create all required ports")
2342 error << _("Unable to start the session running")
2352 ARDOUR_UI::start_engine ()
2354 if (do_engine_start () == 0) {
2355 if (session && _session_is_new) {
2356 /* we need to retain initial visual
2357 settings for a new session
2359 session->save_state ("");
2362 /* there is too much going on, in too many threads, for us to
2363 end up with a clean session. So wait 1 second after loading,
2364 and fix it up. its ugly, but until i come across a better
2365 solution, its what we have.
2368 Main::timeout.connect (mem_fun(*this, &ARDOUR_UI::make_session_clean), 1000);
2375 ARDOUR_UI::update_clocks ()
2377 Clock (session->audible_frame()); /* EMIT_SIGNAL */
2381 ARDOUR_UI::start_clocking ()
2383 clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
2387 ARDOUR_UI::stop_clocking ()
2389 clock_signal_connection.disconnect ();
2393 ARDOUR_UI::toggle_clocking ()
2396 if (clock_button.get_active()) {
2405 ARDOUR_UI::_blink (void *arg)
2408 ((ARDOUR_UI *) arg)->blink ();
2415 Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
2419 ARDOUR_UI::start_blinking ()
2421 /* Start the blink signal. Everybody with a blinking widget
2422 uses Blink to drive the widget's state.
2425 if (blink_timeout_tag < 0) {
2427 blink_timeout_tag = gtk_timeout_add (240, _blink, this);
2432 ARDOUR_UI::stop_blinking ()
2434 if (blink_timeout_tag >= 0) {
2435 gtk_timeout_remove (blink_timeout_tag);
2436 blink_timeout_tag = -1;
2442 ARDOUR_UI::add_diskstream_to_menu (DiskStream& dstream)
2444 using namespace Gtk;
2445 using namespace Menu_Helpers;
2447 if (dstream.hidden()) {
2451 MenuList& items = diskstream_menu->items();
2452 items.push_back (MenuElem (dstream.name(), bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), (gint32) dstream.id())));
2456 ARDOUR_UI::diskstream_selected (gint32 id)
2458 selected_dstream = id;
2463 ARDOUR_UI::select_diskstream (GdkEventButton *ev)
2465 using namespace Gtk;
2466 using namespace Menu_Helpers;
2472 diskstream_menu = new Menu();
2473 diskstream_menu->set_name ("ArdourContextMenu");
2474 using namespace Gtk;
2475 using namespace Menu_Helpers;
2477 MenuList& items = diskstream_menu->items();
2478 items.push_back (MenuElem (_("No Stream"), (bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), -1))));
2480 session->foreach_diskstream (this, &ARDOUR_UI::add_diskstream_to_menu);
2483 diskstream_menu->popup (ev->button, ev->time);
2485 diskstream_menu->popup (0, 0);
2488 selected_dstream = -1;
2492 delete diskstream_menu;
2494 return selected_dstream;
2498 ARDOUR_UI::name_io_setup (AudioEngine& engine,
2504 if (io.n_inputs() == 0) {
2509 /* XXX we're not handling multiple ports yet. */
2511 const char **connections = io.input(0)->get_connections();
2513 if (connections == 0 || connections[0] == '\0') {
2516 buf = connections[0];
2523 if (io.n_outputs() == 0) {
2528 /* XXX we're not handling multiple ports yet. */
2530 const char **connections = io.output(0)->get_connections();
2532 if (connections == 0 || connections[0] == '\0') {
2535 buf = connections[0];
2543 ARDOUR_UI::snapshot_session ()
2545 ArdourPrompter prompter (true);
2551 now = now.substr (0, now.length() - 1);
2553 prompter.set_name ("Prompter");
2554 prompter.set_prompt (_("Name for snapshot"));
2555 prompter.set_initial_text (now);
2556 prompter.done.connect (Gtk::Main::quit.slot());
2557 prompter.show_all ();
2561 if (prompter.status == Gtkmm2ext::Prompter::entered) {
2564 prompter.get_result (snapname);
2565 if (snapname.length()){
2566 save_state (snapname);
2572 ARDOUR_UI::save_state (string name)
2574 (void) save_state_canfail (name);
2578 ARDOUR_UI::save_state_canfail (string name)
2583 if (name.length() == 0) {
2584 name = session->snap_name();
2587 if ((ret = session->save_state (name)) != 0) {
2591 save_ardour_state (); /* XXX cannot fail? yeah, right ... */
2596 ARDOUR_UI::restore_state (string name)
2599 if (name.length() == 0) {
2600 name = session->name();
2602 session->restore_state (name);
2607 ARDOUR_UI::allow_focus (bool yn)
2610 keyboard->allow_focus (yn);
2615 ARDOUR_UI::primary_clock_value_changed ()
2618 session->request_locate (primary_clock.current_time ());
2623 ARDOUR_UI::secondary_clock_value_changed ()
2626 session->request_locate (secondary_clock.current_time ());
2631 ARDOUR_UI::rec_enable_button_blink (bool onoff, DiskStream *dstream, Widget *w)
2633 if (session && dstream && dstream->record_enabled()) {
2635 Session::RecordState rs;
2637 rs = session->record_status ();
2640 case Session::Disabled:
2641 case Session::Enabled:
2642 if (w->get_state() != GTK_STATE_SELECTED) {
2643 w->set_state (GTK_STATE_SELECTED);
2647 case Session::Recording:
2648 if (w->get_state() != GTK_STATE_ACTIVE) {
2649 w->set_state (GTK_STATE_ACTIVE);
2655 if (w->get_state() != Gtk::STATE_NORMAL) {
2656 w->set_state (Gtk::STATE_NORMAL);
2662 ARDOUR_UI::transport_rec_enable_blink (bool onoff)
2668 switch (session->record_status()) {
2669 case Session::Enabled:
2671 rec_button.set_state (GTK_STATE_ACTIVE);
2673 rec_button.set_state (Gtk::STATE_NORMAL);
2677 case Session::Recording:
2678 rec_button.set_state (GTK_STATE_ACTIVE);
2682 rec_button.set_active (false);
2683 rec_button.set_state (Gtk::STATE_NORMAL);
2689 ARDOUR_UI::generic_focus_in_event (GdkEventFocus *ev)
2691 ARDOUR_UI::instance()->allow_focus (true);
2696 ARDOUR_UI::generic_focus_out_event (GdkEventFocus *ev)
2698 ARDOUR_UI::instance()->allow_focus (false);
2703 ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
2711 ARDOUR_UI::start_keyboard_prefix ()
2713 keyboard->start_prefix();
2717 ARDOUR_UI::save_template ()
2720 ArdourPrompter prompter (true);
2721 prompter.set_name ("Prompter");
2722 prompter.set_prompt (_("Name for mix template:"));
2723 prompter.set_initial_text(session->name() + _("-template"));
2725 prompter.done.connect(Gtk::Main::quit.slot());
2726 prompter.show_all();
2730 if (prompter.status == Gtkmm2ext::Prompter::entered) {
2733 prompter.get_result (name);
2735 if (name.length()) {
2736 session->save_template (name);
2742 ARDOUR_UI::new_session (bool startup, string predetermined_path)
2744 if (new_session_window == 0){
2745 new_session_window = new NewSessionDialog (*engine, startup, predetermined_path);
2746 editor->ensure_float (*new_session_window);
2749 new_session_window->run ();
2751 /* write favorites either way */
2752 Session::FavoriteDirs favs;
2753 new_session_window->file_selector.get_favorites (favs);
2754 Session::write_favorite_dirs (favs);
2756 if (new_session_window->run_status()) {
2760 string session_path = new_session_window->file_selector.get_path ();
2761 string session_name = PBD::basename (session_path);
2763 // Check that it doesn't already exist.
2764 access(session_path.c_str(), R_OK);
2765 if (errno != ENOENT){
2766 error << compose(_("Session %1 already exists at %2"), session_name, session_path) << endmsg;
2770 _session_is_new = true;
2772 if (session_path[session_path.length()-1] != '/') {
2774 string template_name = new_session_window->get_template_name ();
2776 if (template_name.length()) {
2778 load_session (session_path, session_name, &template_name);
2784 Session::AutoConnectOption iconnect;
2785 Session::AutoConnectOption oconnect;
2787 if (new_session_window->use_control_button.get_active()) {
2788 cchns = (uint32_t) channel_combo_get_channel_count (new_session_window->control_out_channel_combo);
2792 if (new_session_window->use_master_button.get_active()) {
2793 mchns = (uint32_t) channel_combo_get_channel_count (new_session_window->master_out_channel_combo);
2798 if (new_session_window->connect_to_physical_inputs_button.get_active()) {
2799 iconnect = Session::AutoConnectPhysical;
2801 iconnect = Session::AutoConnectOption (0);
2804 if (new_session_window->connect_to_master_button.get_active ()) {
2805 oconnect = Session::AutoConnectMaster;
2806 } else if (new_session_window->connect_to_physical_outputs_button.get_active ()) {
2807 oconnect = Session::AutoConnectPhysical;
2809 oconnect = Session::AutoConnectOption (0);
2812 uint32_t nphysin = (uint32_t) new_session_window->in_count_adjustment.get_value();
2813 uint32_t nphysout = (uint32_t) new_session_window->out_count_adjustment.get_value();
2815 build_session (session_path, session_name, cchns, mchns, iconnect, oconnect, nphysin, nphysout,
2816 engine->frame_rate() * 60 * 5);
2822 ARDOUR_UI::load_session (string path, string snap_name, string* mix_template)
2824 Session *new_session;
2826 session_loaded = false;
2827 x = unload_session ();
2835 /* if it already exists, we must have write access */
2837 if (::access (path.c_str(), F_OK) == 0 && ::access (path.c_str(), W_OK)) {
2838 ArdourMessage msg (editor, X_("noaccess dialog"), _("\
2839 You do not have write access to this session.\n\
2840 This prevents the session from being loaded."));
2845 new_session = new Session (*engine, path, snap_name, mix_template);
2850 error << compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
2854 connect_to_session (new_session);
2856 //if (engine->running()) {
2857 //mixer->show_window();
2859 session_loaded = true;
2864 ARDOUR_UI::make_session_clean ()
2867 session->set_clean ();
2874 ARDOUR_UI::build_session (string path, string snap_name,
2875 uint32_t control_channels,
2876 uint32_t master_channels,
2877 Session::AutoConnectOption input_connect,
2878 Session::AutoConnectOption output_connect,
2881 jack_nframes_t initial_length)
2883 Session *new_session;
2886 session_loaded = false;
2887 x = unload_session ();
2894 _session_is_new = true;
2897 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
2898 control_channels, master_channels, nphysin, nphysout, initial_length);
2903 error << compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
2907 connect_to_session (new_session);
2909 //if (engine->running()) {
2910 //mixer->show_window();
2912 session_loaded = true;
2917 ARDOUR_UI::hide_dialog (ArdourDialog *dialog)
2926 editor->show_window ();
2930 if (session && mixer) {
2931 mixer->show_window ();
2935 about->get_window().raise ();
2940 ARDOUR_UI::show_splash ()
2943 about = new About(this);
2945 about->show_sub (true);
2946 about->get_window().raise ();
2949 about->get_window().set_decorations (GdkWMDecoration (GDK_DECOR_BORDER|GDK_DECOR_RESIZEH));
2951 about->get_window().raise ();
2956 ARDOUR_UI::hide_splash ()
2964 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title, string msg)
2968 removed = rep.paths.size();
2971 ArdourMessage msg (editor, X_("cleanupresults"),
2973 No audio files were ready for cleanup\n\n\
2974 If this seems suprising, check for any existing\n\
2975 snapshots. These may still include regions that\n\
2976 require some unused files to continue to exist."));
2980 ArdourDialog results ("cleanup results");
2982 const gchar* list_titles[] = {
2987 Gtk::CList list (internationalize (list_titles));
2988 Gtk::ScrolledWindow list_scroller;
2990 Gtk::Button ok_button (_("OK"));
2992 const char* rowtext[1];
2994 list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2996 vpacker.set_border_width (10);
2997 vpacker.set_spacing (10);
2999 if (rep.space < 1048576.0f) {
3001 txt.set_text (compose (msg, removed, _("files"), (float) rep.space / 1024.0f, "kilo"));
3003 txt.set_text (compose (msg, removed, _("file"), (float) rep.space / 1024.0f, "kilo"));
3007 txt.set_text (compose (msg, removed, _("files"), (float) rep.space / 1048576.0f, "mega"));
3009 txt.set_text (compose (msg, removed, _("file"), (float) rep.space / 1048576.0f, "mega"));
3013 vpacker.pack_start (txt, false, false);
3015 for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
3016 rowtext[0] = (*i).c_str();
3017 list.rows().push_back (rowtext);
3020 list_scroller.add_with_viewport (list);
3021 list_scroller.set_size_request (-1, 250);
3023 vpacker.pack_start (list_scroller, true, true);
3024 vpacker.pack_start (ok_button, false, false);
3026 ok_button.signal_clicked().connect (Main::quit.slot ());
3027 results.Hiding.connect (Main::quit.slot ());
3029 results.add (vpacker);
3031 results.set_position (Gtk::WIN_POS_MOUSE);
3032 results.set_title (_("ardour: cleanup"));
3033 results.set_modal (true);
3038 ARDOUR_UI::cleanup ()
3041 /* shouldn't happen: menu item is insensitive */
3045 ArdourDialog checker (X_("cleanup confirm dialog"));
3046 Gtk::Label label (_("\
3047 Cleanup is a destructive operation.\n\
3048 ALL undo/redo information will be lost if you cleanup.\n\
3049 Unused audio files will be moved to a \"dead sounds\" location."));
3051 Gtk::Button ok_button (_("Proceed with cleanup"));
3052 Gtk::Button cancel_button (_("Cancel"));
3056 bbox.set_border_width (6);
3057 bbox.set_spacing (12);
3058 bbox.pack_start (ok_button, true, false);
3059 bbox.pack_start (cancel_button, true, false);
3061 vbox.set_border_width (6);
3062 vbox.set_spacing (12);
3063 vbox.pack_start (label, false, false);
3064 vbox.pack_start (bbox, false, false);
3067 checker.set_name (_("CleanupDialog"));
3068 checker.set_title (_("ardour cleanup"));
3069 checker.set_wmclass (_("ardour_cleanup"), "Ardour");
3070 checker.set_position (Gtk::WIN_POS_MOUSE);
3072 checker.get_window().set_decorations (GdkWMDecoration (GDK_DECOR_BORDER|GDK_DECOR_RESIZEH));
3074 ok_button.signal_clicked().connect (bind (mem_fun (checker, &ArdourDialog::stop), 1));
3075 cancel_button.signal_clicked().connect (bind (mem_fun (checker, &ArdourDialog::stop), 0));
3079 if (checker.run_status() != 1) {
3083 Session::cleanup_report rep;
3085 editor->prepare_for_cleanup ();
3087 if (session->cleanup_sources (rep)) {
3091 display_cleanup_results (rep,
3094 The following %1 %2 were not in use.\n\
3095 The next time you flush the wastebasket\n\
3096 it will release an additional %3 %4bytes\n\
3102 ARDOUR_UI::flush_trash ()
3105 /* shouldn't happen: menu item is insensitive */
3109 Session::cleanup_report rep;
3111 if (session->cleanup_trash_sources (rep)) {
3115 display_cleanup_results (rep,
3117 _("The following %1 file%2 were deleted, releasing %3 %4bytes of disk space"));
3121 ARDOUR_UI::add_route ()
3129 if (add_route_dialog == 0) {
3130 add_route_dialog = new AddRouteDialog;
3131 editor->ensure_float (*add_route_dialog);
3134 if (add_route_dialog->is_visible()) {
3135 /* we're already doing this */
3139 add_route_dialog->run ();
3141 if (add_route_dialog->run_status()) {
3145 if ((count = add_route_dialog->count()) <= 0) {
3149 uint32_t input_chan = add_route_dialog->channels ();
3150 uint32_t output_chan;
3151 string name_template = add_route_dialog->name_template ();
3152 bool track = add_route_dialog->track ();
3154 Session::AutoConnectOption oac = session->get_output_auto_connect();
3156 if (oac & Session::AutoConnectMaster) {
3157 output_chan = (session->master_out() ? session->master_out()->n_inputs() : input_chan);
3159 output_chan = input_chan;
3162 /* XXX do something with name template */
3166 session_add_audio_track (input_chan, output_chan);
3168 session_add_audio_bus (input_chan, output_chan);
3172 while (Main::events_pending()) {
3179 ARDOUR_UI::mixer_settings () const
3184 node = session->instant_xml(X_("Mixer"), session->path());
3186 node = Config->instant_xml(X_("Mixer"), Config->get_user_ardour_path());
3190 node = new XMLNode (X_("Mixer"));
3197 ARDOUR_UI::editor_settings () const
3202 node = session->instant_xml(X_("Editor"), session->path());
3204 node = Config->instant_xml(X_("Editor"), Config->get_user_ardour_path());
3208 node = new XMLNode (X_("Editor"));
3214 ARDOUR_UI::keyboard_settings () const
3218 node = Config->extra_xml(X_("Keyboard"));
3221 node = new XMLNode (X_("Keyboard"));
3227 ARDOUR_UI::halt_on_xrun_message ()
3229 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
3231 ArdourMessage msg (editor, X_("haltonxrun"),
3232 _("Recording was stopped because your system could not keep up."));
3236 ARDOUR_UI::delete_sources_in_the_right_thread (list<ARDOUR::Source*>* deletion_list)
3238 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread), deletion_list));
3240 for (list<Source*>::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) {
3244 delete deletion_list;
3248 ARDOUR_UI::disk_overrun_handler ()
3250 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
3252 if (!have_disk_overrun_displayed) {
3253 have_disk_overrun_displayed = true;
3254 ArdourMessage msg (editor, X_("diskrate dialog"), _("\
3255 The disk system on your computer\n\
3256 was not able to keep up with Ardour.\n\
3258 Specifically, it failed to write data to disk\n\
3259 quickly enough to keep up with recording.\n"));
3260 have_disk_overrun_displayed = false;
3265 ARDOUR_UI::disk_underrun_handler ()
3267 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
3269 if (!have_disk_underrun_displayed) {
3270 have_disk_underrun_displayed = true;
3271 ArdourMessage msg (editor, X_("diskrate2 dialog"),
3272 (_("The disk system on your computer\n\
3273 was not able to keep up with Ardour.\n\
3275 Specifically, it failed to read data from disk\n\
3276 quickly enough to keep up with playback.\n")));
3277 have_disk_underrun_displayed = false;
3282 ARDOUR_UI::disk_underrun_message_gone ()
3284 have_disk_underrun_displayed = false;
3288 ARDOUR_UI::disk_overrun_message_gone ()
3290 have_disk_underrun_displayed = false;
3294 ARDOUR_UI::pending_state_dialog ()
3296 ArdourDialog dialog ("pending state dialog");
3297 Button use_button (_("Recover from crash"));
3298 Button cancel_button (_("Ignore crash data"));
3300 This session appears to have been in\n\
3301 middle of recording when ardour or\n\
3302 the computer was shutdown.\n\
3304 Ardour can recover any captured audio for\n\
3305 you, or it can ignore it. Please decide\n\
3306 what you would like to do.\n"));
3310 vpacker.set_border_width (12);
3311 vpacker.set_spacing (7);
3312 vpacker.pack_start (message);
3313 vpacker.pack_start (hpacker);
3315 hpacker.set_spacing (7);
3316 hpacker.pack_start (use_button);
3317 hpacker.pack_start (cancel_button);
3319 use_button.signal_clicked().connect (bind (mem_fun (dialog, &ArdourDialog::stop), 0));
3320 cancel_button.signal_clicked().connect (bind (mem_fun (dialog, &ArdourDialog::stop), 1));
3322 dialog.add (vpacker);
3323 dialog.set_position (GTK_WIN_POS_CENTER);
3326 dialog.get_window().set_decorations (GdkWMDecoration (GDK_DECOR_BORDER|GDK_DECOR_RESIZEH));
3330 if (dialog.run_status () == 0) {
3339 ARDOUR_UI::disconnect_from_jack ()
3342 if( engine->disconnect_from_jack ()) {
3343 ArdourMessage msg (editor, X_("nojack dialog"),
3344 _("Could not disconnect from JACK"));
3347 update_sample_rate (0);
3352 ARDOUR_UI::reconnect_to_jack ()
3355 if (engine->reconnect_to_jack ()) {
3356 ArdourMessage msg (editor, X_("nojack dialog"),
3357 _("Could not reconnect to JACK"));
3360 update_sample_rate (0);
3365 ARDOUR_UI::set_jack_buffer_size (jack_nframes_t nframes)
3367 engine->request_buffer_size (nframes);
3368 update_sample_rate (0);
3372 ARDOUR_UI::cmdline_new_session (string path)
3374 if (path[0] != '/') {
3375 char buf[PATH_MAX+1];
3378 getcwd (buf, sizeof (buf));
3385 new_session (false, path);
3387 _will_create_new_session_automatically = false; /* done it */
3388 return FALSE; /* don't call it again */