2 Copyright (C) 1999-2002 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 #include <pbd/error.h>
32 #include <pbd/compose.h>
33 #include <pbd/basename.h>
34 #include <pbd/pathscanner.h>
35 #include <pbd/failed_constructor.h>
36 #include <gtkmm2ext/gtk_ui.h>
37 #include <gtkmm2ext/pix.h>
38 #include <gtkmm2ext/utils.h>
39 #include <gtkmm2ext/click_box.h>
40 #include <gtkmm2ext/fastmeter.h>
41 #include <gtkmm2ext/stop_signal.h>
42 #include <gtkmm2ext/popup.h>
44 #include <midi++/port.h>
45 #include <midi++/mmc.h>
47 #include <ardour/ardour.h>
48 #include <ardour/port.h>
49 #include <ardour/audioengine.h>
50 #include <ardour/playlist.h>
51 #include <ardour/utils.h>
52 #include <ardour/diskstream.h>
53 #include <ardour/filesource.h>
54 #include <ardour/recent_sessions.h>
55 #include <ardour/session_diskstream.h>
56 #include <ardour/port.h>
57 #include <ardour/audio_track.h>
60 #include "ardour_ui.h"
61 #include "ardour_message.h"
62 #include "public_editor.h"
63 #include "audio_clock.h"
68 #include "keyboard_target.h"
69 #include "add_route_dialog.h"
70 #include "new_session_dialog.h"
73 #include "gui_thread.h"
77 using namespace ARDOUR;
78 using namespace Gtkmm2ext;
82 ARDOUR_UI *ARDOUR_UI::theArdourUI = 0;
84 sigc::signal<void,bool> ARDOUR_UI::Blink;
85 sigc::signal<void> ARDOUR_UI::RapidScreenUpdate;
86 sigc::signal<void> ARDOUR_UI::SuperRapidScreenUpdate;
87 sigc::signal<void,jack_nframes_t> ARDOUR_UI::Clock;
90 static const gchar *h_meter_strip_xpm[] = {
279 ". + @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / ( _ : < [ } | 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ` ...+.@.@.#.$.%.&.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +.+",
280 ". + @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / ( _ : < [ } | 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ` ...+.@.@.#.$.%.&.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +.+",
281 ". + @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / ( _ : < [ } | 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ` ...+.@.@.#.$.%.&.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +++",
282 ". + @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / ( _ : < [ } | 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ` ...+.@.@.#.$.%.&.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +++",
283 ". + @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / ( _ : < [ } | 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ` ...+.@.@.#.$.%.&.*.=.-.;.>.,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.2.3.4.5.6.7.8.9.0.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. +++"};
286 static const gchar * v_meter_strip_xpm[] = {
769 static const char* channel_setup_names[] = {
780 vector<string> channel_combo_strings;
782 ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], string rcfile)
784 : Gtkmm2ext::UI ("ardour", argcp, argvp, rcfile),
786 primary_clock (X_("TransportClockDisplay"), true, false, true),
787 secondary_clock (X_("SecondaryClockDisplay"), true, false, true),
788 preroll_clock (X_("PreRollClock"), true, true),
789 postroll_clock (X_("PostRollClock"), true, true),
793 adjuster_table (3, 3),
797 preroll_button (_("pre\nroll")),
798 postroll_button (_("post\nroll")),
802 big_clock ("BigClockDisplay", true),
806 shuttle_units_button (_("% ")),
807 shuttle_style_button (_("spring")),
809 punch_in_button (_("punch\nin")),
810 punch_out_button (_("punch\nout")),
811 auto_return_button (_("auto\nreturn")),
812 auto_play_button (_("auto\nplay")),
813 auto_input_button (_("auto\ninput")),
814 click_button (_("click")),
815 follow_button (_("follow\nPH")),
816 auditioning_alert_button (_("AUDITIONING")),
817 solo_alert_button (_("SOLO")),
821 using namespace Gtk::Menu_Helpers;
825 /* actually, its already loaded, but ... */
827 cerr << "Loading UI configuration file " << rcfile << endl;
831 if (theArdourUI == 0) {
835 ActionManager::init ();
837 m_new_session_dialog = 0;
838 m_new_session_dialog_ref = NewSessionDialogFactory::create();
839 m_new_session_dialog_ref->get_widget_derived (NewSessionDialogFactory::top_level_widget_name(), m_new_session_dialog);
843 _session_is_new = false;
844 big_clock_window = 0;
845 session_selector_window = 0;
846 last_key_press_time = 0;
847 connection_editor = 0;
848 add_route_dialog = 0;
852 open_session_selector = 0;
853 have_configure_timeout = false;
854 have_disk_overrun_displayed = false;
855 have_disk_underrun_displayed = false;
856 _will_create_new_session_automatically = false;
857 session_loaded = false;
860 last_configure_time.tv_sec = 0;
861 last_configure_time.tv_usec = 0;
863 shuttle_grabbed = false;
866 set_shuttle_units (Percentage);
867 set_shuttle_behaviour (Sprung);
869 Glib::RefPtr<ActionGroup> shuttle_actions = ActionGroup::create ("ShuttleActions");
871 shuttle_actions->add (Action::create (X_("SetShuttleUnitsPercentage"), _("Percentage")), bind (mem_fun(*this, &ARDOUR_UI::set_shuttle_units), Percentage));
872 shuttle_actions->add (Action::create (X_("SetShuttleUnitsSemitones"), _("Semitones")), bind (mem_fun(*this, &ARDOUR_UI::set_shuttle_units), Semitones));
873 shuttle_actions->add (Action::create (X_("SetShuttleActionSprung"), _("Sprung")), bind (mem_fun(*this, &ARDOUR_UI::set_shuttle_behaviour), Sprung));
874 shuttle_actions->add (Action::create (X_("SetShuttleActionWheel"), _("Wheel")), bind (mem_fun(*this, &ARDOUR_UI::set_shuttle_behaviour), Wheel));
876 ActionManager::add_action_group (shuttle_actions);
878 shuttle_style_menu = dynamic_cast<Menu*> (ActionManager::get_widget ("ShuttleStylePopup"));
879 shuttle_unit_menu = dynamic_cast<Menu*> (ActionManager::get_widget ("ShuttleUnitPopup"));
881 gettimeofday (&last_peak_grab, 0);
882 gettimeofday (&last_shuttle_request, 0);
884 ARDOUR::DiskStream::CannotRecordNoInput.connect (mem_fun(*this, &ARDOUR_UI::cannot_record_no_input));
885 ARDOUR::DiskStream::DeleteSources.connect (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread));
886 ARDOUR::DiskStream::DiskOverrun.connect (mem_fun(*this, &ARDOUR_UI::disk_overrun_handler));
887 ARDOUR::DiskStream::DiskUnderrun.connect (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
889 /* handle pending state with a dialog */
891 ARDOUR::Session::AskAboutPendingState.connect (mem_fun(*this, &ARDOUR_UI::pending_state_dialog));
893 channel_combo_strings = internationalize (channel_setup_names);
895 /* have to wait for AudioEngine and Configuration before proceeding */
899 ARDOUR_UI::cannot_record_no_input (DiskStream* ds)
901 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::cannot_record_no_input), ds));
903 string msg = string_compose (_("\
904 You cannot record-enable\n\
906 because it has no input connections.\n\
907 You would be wasting space recording silence."),
910 ArdourMessage message (editor, X_("cannotrecord"), msg);
914 ARDOUR_UI::set_engine (AudioEngine& e)
918 engine->Stopped.connect (mem_fun(*this, &ARDOUR_UI::engine_stopped));
919 engine->Running.connect (mem_fun(*this, &ARDOUR_UI::engine_running));
920 engine->Halted.connect (mem_fun(*this, &ARDOUR_UI::engine_halted));
921 engine->SampleRateChanged.connect (mem_fun(*this, &ARDOUR_UI::update_sample_rate));
925 keyboard = new Keyboard;
926 install_keybindings ();
928 FastMeter::set_vertical_xpm (v_meter_strip_xpm);
929 FastMeter::set_horizontal_xpm (h_meter_strip_xpm);
931 if (setup_windows ()) {
932 throw failed_constructor ();
935 if (GTK_ARDOUR::show_key_actions) {
937 // show_all_actions ();
941 /* start with timecode, metering enabled
944 blink_timeout_tag = -1;
946 /* this being a GUI and all, we want peakfiles */
948 FileSource::set_build_peakfiles (true);
949 FileSource::set_build_missing_peakfiles (true);
951 if (Source::start_peak_thread ()) {
952 throw failed_constructor();
955 /* start the time-of-day-clock */
957 update_wall_clock ();
958 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::update_wall_clock), 60000);
960 update_disk_space ();
962 update_sample_rate (engine->frame_rate());
964 starting.connect (mem_fun(*this, &ARDOUR_UI::startup));
965 stopping.connect (mem_fun(*this, &ARDOUR_UI::shutdown));
968 ARDOUR_UI::~ARDOUR_UI ()
970 save_ardour_state ();
984 if (add_route_dialog) {
985 delete add_route_dialog;
988 Source::stop_peak_thread ();
992 ARDOUR_UI::configure_timeout ()
997 if (last_configure_time.tv_sec == 0 && last_configure_time.tv_usec == 0) {
998 /* no configure events yet */
1002 gettimeofday (&now, 0);
1003 timersub (&now, &last_configure_time, &diff);
1005 /* force a gap of 0.5 seconds since the last configure event
1008 if (diff.tv_sec == 0 && diff.tv_usec < 500000) {
1011 have_configure_timeout = false;
1012 save_ardour_state ();
1018 ARDOUR_UI::configure_handler (GdkEventConfigure* conf)
1020 if (have_configure_timeout) {
1021 gettimeofday (&last_configure_time, 0);
1023 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::configure_timeout), 100);
1024 have_configure_timeout = true;
1031 ARDOUR_UI::save_ardour_state ()
1033 if (!keyboard || !mixer || !editor) {
1037 /* XXX this is all a bit dubious. add_extra_xml() uses
1038 a different lifetime model from add_instant_xml().
1041 XMLNode* node = new XMLNode (keyboard->get_state());
1042 Config->add_extra_xml (*node);
1043 Config->save_state();
1045 XMLNode& enode (static_cast<Stateful*>(editor)->get_state());
1046 XMLNode& mnode (mixer->get_state());
1049 session->add_instant_xml(enode, session->path());
1050 session->add_instant_xml(mnode, session->path());
1052 Config->add_instant_xml(enode, Config->get_user_ardour_path());
1053 Config->add_instant_xml(mnode, Config->get_user_ardour_path());
1058 ARDOUR_UI::startup ()
1060 /* Once the UI is up and running, start the audio engine. Doing
1061 this before the UI is up and running can cause problems
1062 when not running with SCHED_FIFO, because the amount of
1063 CPU and disk work needed to get the UI started can interfere
1064 with the scheduling of the audio thread.
1067 Glib::signal_idle().connect (mem_fun(*this, &ARDOUR_UI::start_engine));
1073 if (session && session->dirty()) {
1074 switch (ask_about_saving_session(_("quit"))) {
1079 /* use the default name */
1080 if (save_state_canfail ("")) {
1081 /* failed - don't quit */
1082 ArdourMessage (editor, X_("badsave dialog"),
1084 Ardour was unable to save your session.\n\n\
1085 If you still wish to quit, please use the\n\n\
1086 \"Just quit\" option."));
1099 ARDOUR_UI::ask_about_saving_session (string what)
1101 ArdourDialog window ("saving dialog");
1103 Gtk::Label prompt_label;
1104 Gtk::HBox button_packer;
1108 msg = string_compose(_("Save and %1"), what);
1110 Gtk::Button save_button (msg);
1111 save_button.set_name ("EditorGTKButton");
1113 msg = string_compose(_("Just %1"), what);
1115 Gtk::Button nosave_button (msg);
1116 nosave_button.set_name ("EditorGTKButton");
1118 msg = string_compose(_("Don't %1"), what);
1120 Gtk::Button noquit_button (msg);
1121 noquit_button.set_name ("EditorGTKButton");
1126 if (session->snap_name() == session->name()) {
1127 type = _("session");
1129 type = _("snapshot");
1131 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?"),
1132 type, session->snap_name());
1134 prompt_label.set_text (prompt);
1135 prompt_label.set_alignment (0.5, 0.5);
1136 prompt_label.set_name (X_("PrompterLabel"));
1138 save_button.signal_clicked().connect (bind(mem_fun(window,&ArdourDialog::stop), 1));
1139 nosave_button.signal_clicked().connect (bind(mem_fun(window,&ArdourDialog::stop), 0));
1140 noquit_button.signal_clicked().connect (bind(mem_fun(window,&ArdourDialog::stop), -1));
1142 button_packer.set_spacing (10);
1143 button_packer.pack_start (save_button);
1144 button_packer.pack_start (nosave_button);
1145 button_packer.pack_start (noquit_button);
1147 packer.set_spacing (10);
1148 packer.set_border_width (10);
1149 packer.pack_start (prompt_label);
1150 packer.pack_start (button_packer);
1152 window.set_name (_("Prompter"));
1153 window.set_title (_("ardour: save session?"));
1154 window.set_position (Gtk::WIN_POS_MOUSE);
1155 window.set_modal (true);
1156 window.add (packer);
1158 window.set_keyboard_input (true);
1160 save_the_session = 0;
1162 editor->ensure_float (window);
1166 return window.run_status();
1170 ARDOUR_UI::every_second ()
1173 update_buffer_load ();
1174 update_disk_space ();
1175 // update_disk_rate ();
1180 ARDOUR_UI::every_point_one_seconds ()
1183 struct timeval diff;
1185 /* do not attempt to grab peak power more than once per cycle.
1188 gettimeofday (&now, 0);
1189 timersub (&now, &last_peak_grab, &diff);
1191 if ((diff.tv_usec + (diff.tv_sec * 1000000)) >= engine->usecs_per_cycle()) {
1192 IO::GrabPeakPower(); /* EMIT_SIGNAL */
1193 last_peak_grab = now;
1196 update_speed_display ();
1197 RapidScreenUpdate(); /* EMIT_SIGNAL */
1202 ARDOUR_UI::every_point_zero_one_seconds ()
1204 SuperRapidScreenUpdate(); /* EMIT_SIGNAL */
1209 ARDOUR_UI::update_sample_rate (jack_nframes_t ignored)
1213 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::update_sample_rate), ignored));
1215 if (!engine->connected()) {
1217 snprintf (buf, sizeof (buf), _("disconnected"));
1221 jack_nframes_t rate = engine->frame_rate();
1223 if (fmod (rate, 1000.0) != 0.0) {
1224 snprintf (buf, sizeof (buf), _("SR: %.1f kHz / %4.1f msecs"),
1225 (float) rate/1000.0f,
1226 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
1228 snprintf (buf, sizeof (buf), _("SR: %u kHz / %4.1f msecs"),
1230 (engine->frames_per_cycle() / (float) rate) * 1000.0f);
1234 sample_rate_label.set_text (buf);
1238 ARDOUR_UI::update_cpu_load ()
1241 snprintf (buf, sizeof (buf), _("DSP Load: %.1f%%"), engine->get_cpu_load());
1242 cpu_load_label.set_text (buf);
1246 ARDOUR_UI::update_disk_rate ()
1251 snprintf (buf, sizeof (buf), _("Disk r:%5.1f w:%5.1f MB/s"),
1252 session->read_data_rate()/1048576.0f, session->write_data_rate()/1048576.0f);
1253 disk_rate_label.set_text (buf);
1255 disk_rate_label.set_text ("");
1260 ARDOUR_UI::update_buffer_load ()
1265 snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"),
1266 session->playback_load(), session->capture_load());
1267 buffer_load_label.set_text (buf);
1269 buffer_load_label.set_text ("");
1274 ARDOUR_UI::count_recenabled_diskstreams (DiskStream& ds)
1276 if (ds.record_enabled()) {
1277 rec_enabled_diskstreams++;
1282 ARDOUR_UI::update_disk_space()
1288 jack_nframes_t frames = session->available_capture_duration();
1291 if (frames == max_frames) {
1292 strcpy (buf, _("space: 24hrs+"));
1297 jack_nframes_t fr = session->frame_rate();
1299 if (session->actively_recording()){
1301 rec_enabled_diskstreams = 0;
1302 session->foreach_diskstream (this, &ARDOUR_UI::count_recenabled_diskstreams);
1304 if (rec_enabled_diskstreams) {
1305 frames /= rec_enabled_diskstreams;
1310 /* hmmm. shall we divide by the route count? or the diskstream count?
1311 or what? for now, do nothing ...
1316 hrs = frames / (fr * 3600);
1317 frames -= hrs * fr * 3600;
1318 mins = frames / (fr * 60);
1319 frames -= mins * fr * 60;
1322 snprintf (buf, sizeof(buf), _("space: %02dh:%02dm:%02ds"), hrs, mins, secs);
1325 disk_space_label.set_text (buf);
1329 ARDOUR_UI::update_wall_clock ()
1336 tm_now = localtime (&now);
1338 sprintf (buf, "%02d:%02d", tm_now->tm_hour, tm_now->tm_min);
1339 wall_clock_label.set_text (buf);
1345 ARDOUR_UI::toggle_recording_plugins ()
1347 /* XXX use toggle_some_session_state */
1353 session->set_recording_plugins (!session->get_recording_plugins());
1357 ARDOUR_UI::toggle_auto_play ()
1360 toggle_some_session_state (auto_play_button,
1361 &Session::get_auto_play,
1362 &Session::set_auto_play);
1366 ARDOUR_UI::toggle_auto_return ()
1369 toggle_some_session_state (auto_return_button,
1370 &Session::get_auto_return,
1371 &Session::set_auto_return);
1375 ARDOUR_UI::toggle_click ()
1377 toggle_some_session_state (click_button,
1378 &Session::get_clicking,
1379 &Session::set_clicking);
1383 ARDOUR_UI::follow_changed ()
1391 if (follow_button.get_active() != (x = editor->follow_playhead())) {
1392 follow_button.set_active (x);
1397 ARDOUR_UI::toggle_follow ()
1405 if (editor->follow_playhead() != (x = follow_button.get_active())) {
1406 editor->set_follow_playhead (x);
1411 ARDOUR_UI::toggle_session_auto_loop ()
1414 if (session->get_auto_loop()) {
1415 if (session->transport_rolling()) {
1419 session->request_auto_loop (false);
1423 session->request_auto_loop (true);
1429 ARDOUR_UI::toggle_session_punch_in ()
1432 session->set_punch_in (!session->get_punch_in());
1437 ARDOUR_UI::toggle_punch_out ()
1439 toggle_some_session_state (punch_out_button,
1440 &Session::get_punch_out,
1441 &Session::set_punch_out);
1445 ARDOUR_UI::toggle_punch_in ()
1447 toggle_some_session_state (punch_in_button,
1448 &Session::get_punch_in,
1449 &Session::set_punch_in);
1453 ARDOUR_UI::map_button_state ()
1456 map_some_session_state (auto_return_button,
1457 &Session::get_auto_return);
1458 map_some_session_state (auto_play_button,
1459 &Session::get_auto_play);
1460 map_some_session_state (auto_input_button,
1461 &Session::get_auto_input);
1462 map_some_session_state (punch_in_button,
1463 &Session::get_punch_in);
1464 map_some_session_state (punch_out_button,
1465 &Session::get_punch_out);
1466 map_some_session_state (click_button,
1467 &Session::get_clicking);
1471 ARDOUR_UI::queue_map_control_change (Session::ControlType t)
1473 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::map_control_change), t));
1477 ARDOUR_UI::map_control_change (Session::ControlType t)
1480 case Session::AutoPlay:
1481 map_some_session_state (auto_play_button, &Session::get_auto_play);
1484 case Session::AutoLoop:
1487 case Session::AutoReturn:
1488 map_some_session_state (auto_return_button, &Session::get_auto_return);
1491 case Session::AutoInput:
1492 map_some_session_state (auto_input_button, &Session::get_auto_input);
1495 case Session::PunchOut:
1496 map_some_session_state (punch_in_button, &Session::get_punch_out);
1499 case Session::PunchIn:
1500 map_some_session_state (punch_in_button, &Session::get_punch_in);
1503 case Session::Clicking:
1504 map_some_session_state (click_button, &Session::get_clicking);
1507 case Session::SlaveType:
1508 // map_some_session_state (mtc_slave_button, &Session::get_mtc_slave);
1511 case Session::SendMTC:
1512 // map_some_session_state (send_mtc_button, &Session::get_send_mtc);
1515 case Session::SendMMC:
1516 // map_some_session_state (send_mmc_button, &Session::get_send_mmc);
1519 case Session::MMCControl:
1520 // map_some_session_state (mmc_control_button, &Session::get_mmc_control);
1523 case Session::MidiFeedback:
1524 // map_some_session_state (mmc_control_button, &Session::get_mmc_control);
1526 case Session::MidiControl:
1527 // map_some_session_state (mmc_control_button, &Session::get_mmc_control);
1533 case Session::RecordingPlugins:
1536 case Session::CrossFadesActive:
1539 case Session::EditingMode:
1542 case Session::PlayRange:
1545 case Session::AlignChoice:
1546 /* don't care, this is handled by the options editor */
1548 case Session::SeamlessLoop:
1549 /* don't care, this is handled by the options editor */
1556 ARDOUR_UI::control_methods_adjusted ()
1561 which_method = (int) online_control_button->adjustment.get_value();
1562 switch (which_method) {
1564 allow_mmc_and_local ();
1570 allow_local_only ();
1573 fatal << _("programming error: impossible control method") << endmsg;
1579 ARDOUR_UI::mmc_device_id_adjusted ()
1584 int dev_id = (int) mmc_id_button->adjustment.get_value();
1585 mmc->set_device_id (dev_id);
1591 ARDOUR_UI::map_some_session_state (ToggleButton& button,
1592 bool (Session::*get)() const)
1601 if (button.get_active() != (x = (session->*get)())) {
1602 button.set_active (x);
1607 ARDOUR_UI::toggle_some_session_state (ToggleButton& button,
1608 bool (Session::*get)() const,
1609 void (Session::*set)(bool))
1619 button_state = button.get_active ();
1620 session_state = (session->*get)();
1622 if (button_state != session_state) {
1623 (session->*set) (button_state);
1626 /* check that it worked, and reverse
1627 the button state if it didn't
1630 if ((session->*get)() != button_state) {
1631 button->set_active (!button_state);
1639 ARDOUR_UI::session_menu (GdkEventButton *ev)
1641 session_popup_menu->popup (0, 0);
1646 ARDOUR_UI::redisplay_recent_sessions ()
1648 vector<string *> *sessions;
1649 vector<string *>::iterator i;
1650 RecentSessionsSorter cmp;
1652 recent_session_display.set_model (Glib::RefPtr<TreeModel>(0));
1653 recent_session_model->clear ();
1656 ARDOUR::read_recent_sessions (rs);
1659 recent_session_display.set_model (recent_session_model);
1663 /* sort them alphabetically */
1664 sort (rs.begin(), rs.end(), cmp);
1665 sessions = new vector<string*>;
1667 for (RecentSessions::iterator i = rs.begin(); i != rs.end(); ++i) {
1668 sessions->push_back (new string ((*i).second));
1671 for (i = sessions->begin(); i != sessions->end(); ++i) {
1673 vector<string*>* states;
1674 vector<const gchar*> item;
1675 string fullpath = *(*i);
1677 /* remove any trailing / */
1679 if (fullpath[fullpath.length()-1] == '/') {
1680 fullpath = fullpath.substr (0, fullpath.length()-1);
1683 /* now get available states for this session */
1685 if ((states = Session::possible_states (fullpath)) == 0) {
1686 /* no state file? */
1690 TreeModel::Row row = *(recent_session_model->append());
1692 row[recent_session_columns.visible_name] = PBD::basename (fullpath);
1693 row[recent_session_columns.fullpath] = fullpath;
1695 if (states->size() > 1) {
1697 /* add the children */
1699 for (vector<string*>::iterator i2 = states->begin(); i2 != states->end(); ++i2) {
1701 TreeModel::Row child_row = *(recent_session_model->append (row.children()));
1703 child_row[recent_session_columns.visible_name] = **i2;
1704 child_row[recent_session_columns.fullpath] = fullpath;
1713 recent_session_display.set_model (recent_session_model);
1718 ARDOUR_UI::build_session_selector ()
1720 session_selector_window = new ArdourDialog ("session selector");
1722 Gtk::VBox *vpacker = manage (new Gtk::VBox);
1723 Gtk::ScrolledWindow *scroller = manage (new Gtk::ScrolledWindow);
1724 Gtk::HBox *button_packer = manage (new Gtk::HBox);
1725 Gtk::Button *cancel_button = manage (new Gtk::Button (_("cancel")));
1726 Gtk::Button *rescan_button = manage (new Gtk::Button (_("rescan")));
1728 button_packer->pack_start (*rescan_button);
1729 button_packer->pack_start (*cancel_button);
1731 vpacker->pack_start (*scroller);
1732 vpacker->pack_start (*button_packer, false, false);
1734 recent_session_model = TreeStore::create (recent_session_columns);
1735 recent_session_display.set_model (recent_session_model);
1736 recent_session_display.append_column (_("Recent Sessions"), recent_session_columns.visible_name);
1737 recent_session_display.set_headers_visible (false);
1739 scroller->add (recent_session_display);
1740 scroller->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
1742 session_selector_window->add (*vpacker);
1743 session_selector_window->set_name ("SessionSelectorWindow");
1744 session_selector_window->set_size_request (200, 400);
1748 ARDOUR_UI::open_recent_session ()
1750 /* popup selector window */
1752 if (session_selector_window == 0) {
1753 build_session_selector ();
1756 redisplay_recent_sessions ();
1758 session_selector_window->run ();
1761 switch (session_selector_window->run_status()) {
1769 Gtk::TreeModel::iterator i = recent_session_display.get_selection()->get_selected();
1771 if (i == recent_session_model->children().end()) {
1775 Glib::ustring path = (*i)[recent_session_columns.fullpath];
1776 Glib::ustring state = (*i)[recent_session_columns.visible_name];
1778 session_selector_window->response (RESPONSE_ACCEPT);
1779 _session_is_new = false;
1781 load_session (path, state);
1786 ARDOUR_UI::filter_ardour_session_dirs (const FileFilter::Info& info)
1788 struct stat statbuf;
1790 if (stat (info.filename.c_str(), &statbuf) != 0) {
1794 if (!S_ISDIR(statbuf.st_mode)) {
1798 string session_file = info.filename;
1799 session_file += '/';
1800 session_file += PBD::basename (info.filename);
1801 session_file += ".ardour";
1803 if (stat (session_file.c_str(), &statbuf) != 0) {
1807 return S_ISREG (statbuf.st_mode);
1811 ARDOUR_UI::open_session ()
1813 /* popup selector window */
1815 if (open_session_selector == 0) {
1816 open_session_selector = new Gtk::FileChooserDialog (_("open session"), FILE_CHOOSER_ACTION_OPEN);
1817 open_session_selector->add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1818 open_session_selector->add_button (Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
1820 FileFilter filter_ardour;
1821 filter_ardour.set_name (_("Ardour sessions"));
1822 filter_ardour.add_custom (FILE_FILTER_FILENAME, mem_fun (*this, &ARDOUR_UI::filter_ardour_session_dirs));
1824 open_session_selector->add_filter (filter_ardour);
1827 switch (open_session_selector->run ()) {
1834 string session_path = open_session_selector->get_filename();
1838 if (session_path.length() > 0) {
1839 if (Session::find_session (session_path, path, name, isnew) == 0) {
1840 _session_is_new = isnew;
1841 load_session (path, name);
1848 ARDOUR_UI::session_add_midi_track ()
1850 cerr << _("Patience is a virtue.\n");
1854 ARDOUR_UI::session_add_audio_route (bool disk, int32_t input_channels, int32_t output_channels)
1859 warning << _("You cannot add a track without a session already loaded.") << endmsg;
1865 if ((route = session->new_audio_track (input_channels, output_channels)) == 0) {
1866 error << _("could not create new audio track") << endmsg;
1869 if ((route = session->new_audio_route (input_channels, output_channels)) == 0) {
1870 error << _("could not create new audio bus") << endmsg;
1875 if (need_control_room_outs) {
1881 route->set_stereo_control_outs (control_lr_channels);
1882 route->control_outs()->set_stereo_pan (pans, this);
1884 #endif /* CONTROLOUTS */
1888 ArdourMessage msg (editor, X_("noport dialog"),
1889 _("There are insufficient JACK ports available\n\
1890 to create a new track or bus.\n\
1891 You should save Ardour, exit and\n\
1892 restart JACK with more ports."));
1897 ARDOUR_UI::diskstream_added (DiskStream* ds)
1902 ARDOUR_UI::do_transport_locate (jack_nframes_t new_position)
1904 jack_nframes_t _preroll;
1907 _preroll = session->convert_to_frames_at (new_position, session->preroll);
1909 if (new_position > _preroll) {
1910 new_position -= _preroll;
1915 session->request_locate (new_position);
1920 ARDOUR_UI::transport_goto_start ()
1923 session->request_locate (0);
1926 /* force displayed area in editor to start no matter
1927 what "follow playhead" setting is.
1931 editor->reposition_x_origin (0);
1937 ARDOUR_UI::transport_goto_end ()
1940 jack_nframes_t frame = session->current_end_frame();
1941 session->request_locate (frame);
1943 /* force displayed area in editor to start no matter
1944 what "follow playhead" setting is.
1948 editor->reposition_x_origin (frame);
1954 ARDOUR_UI::mouse_transport_stop (GdkEventButton *ev)
1959 if (session->transport_stopped()) {
1960 session->request_locate (session->last_transport_start());
1962 if (session->get_auto_loop()) {
1963 session->request_auto_loop (false);
1966 Keyboard::ModifierMask mask = Keyboard::ModifierMask (Keyboard::Control|Keyboard::Shift);
1967 session->request_stop (Keyboard::modifier_state_equals (ev->state, mask));
1975 ARDOUR_UI::mouse_transport_roll (GdkEventButton* ev)
1982 ARDOUR_UI::transport_stop ()
1988 if (session->is_auditioning()) {
1989 session->cancel_audition ();
1993 if (session->get_auto_loop()) {
1994 session->request_auto_loop (false);
1997 session->request_stop ();
2001 ARDOUR_UI::transport_stop_and_forget_capture ()
2004 session->request_stop (true);
2009 ARDOUR_UI::remove_last_capture()
2012 editor->remove_last_capture();
2017 ARDOUR_UI::transport_record ()
2020 switch (session->record_status()) {
2021 case Session::Disabled:
2022 if (session->ntracks() == 0) {
2023 string txt = _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu.");
2024 ArdourMessage msg (editor, X_("cannotrecenable"), txt);
2027 session->maybe_enable_record ();
2029 case Session::Recording:
2030 case Session::Enabled:
2031 session->disable_record ();
2037 ARDOUR_UI::transport_roll ()
2045 rolling = session->transport_rolling ();
2047 if (session->get_auto_loop()) {
2048 session->request_auto_loop (false);
2049 auto_loop_button.set_active (false);
2050 roll_button.set_active (true);
2051 } else if (session->get_play_range ()) {
2052 session->request_play_range (false);
2053 play_selection_button.set_active (false);
2054 } else if (rolling) {
2055 session->request_locate (session->last_transport_start(), true);
2058 session->request_transport_speed (1.0f);
2062 ARDOUR_UI::transport_loop()
2065 if (session->get_auto_loop()) {
2066 if (session->transport_rolling()) {
2067 Location * looploc = session->locations()->auto_loop_location();
2069 session->request_locate (looploc->start(), true);
2074 session->request_auto_loop (true);
2080 ARDOUR_UI::transport_play_selection ()
2086 if (!session->get_play_range()) {
2087 session->request_stop ();
2090 editor->play_selection ();
2094 ARDOUR_UI::transport_rewind (int option)
2096 float current_transport_speed;
2099 current_transport_speed = session->transport_speed();
2101 if (current_transport_speed >= 0.0f) {
2104 session->request_transport_speed (-1.0f);
2107 session->request_transport_speed (-4.0f);
2110 session->request_transport_speed (-0.5f);
2115 session->request_transport_speed (current_transport_speed * 1.5f);
2121 ARDOUR_UI::transport_forward (int option)
2123 float current_transport_speed;
2126 current_transport_speed = session->transport_speed();
2128 if (current_transport_speed <= 0.0f) {
2131 session->request_transport_speed (1.0f);
2134 session->request_transport_speed (4.0f);
2137 session->request_transport_speed (0.5f);
2142 session->request_transport_speed (current_transport_speed * 1.5f);
2148 ARDOUR_UI::toggle_monitor_enable (guint32 dstream)
2156 if ((ds = session->diskstream_by_id (dstream)) != 0) {
2157 Port *port = ds->io()->input (0);
2158 port->request_monitor_input (!port->monitoring_input());
2163 ARDOUR_UI::toggle_record_enable (guint32 dstream)
2171 if ((ds = session->diskstream_by_id (dstream)) != 0) {
2172 ds->set_record_enabled (!ds->record_enabled(), this);
2177 ARDOUR_UI::queue_transport_change ()
2179 Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &ARDOUR_UI::map_transport_state));
2183 ARDOUR_UI::map_transport_state ()
2185 float sp = session->transport_speed();
2188 transport_rolling ();
2189 } else if (sp < 0.0f) {
2190 transport_rewinding ();
2191 } else if (sp > 0.0f) {
2192 transport_forwarding ();
2194 transport_stopped ();
2199 ARDOUR_UI::send_all_midi_feedback ()
2202 session->send_all_midi_feedback();
2207 ARDOUR_UI::allow_local_only ()
2213 ARDOUR_UI::allow_mmc_only ()
2219 ARDOUR_UI::allow_mmc_and_local ()
2225 ARDOUR_UI::GlobalClickBox::printer (char buf[32], Adjustment &adj, void *arg)
2227 snprintf (buf, sizeof(buf), "%s", ((GlobalClickBox *) arg)->strings[
2228 (int) adj.get_value()].c_str());
2232 ARDOUR_UI::engine_stopped ()
2234 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_stopped));
2236 jack_disconnect_item->set_sensitive (false);
2237 jack_reconnect_item->set_sensitive (true);
2238 jack_bufsize_menu->set_sensitive (false);
2243 ARDOUR_UI::engine_running ()
2245 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_running));
2247 jack_disconnect_item->set_sensitive (true);
2248 jack_reconnect_item->set_sensitive (false);
2249 jack_bufsize_menu->set_sensitive (true);
2253 ARDOUR_UI::engine_halted ()
2255 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::engine_halted));
2257 jack_disconnect_item->set_sensitive (false);
2258 jack_reconnect_item->set_sensitive (true);
2259 jack_bufsize_menu->set_sensitive (false);
2261 update_sample_rate (0);
2263 ArdourMessage msg (editor, X_("halted"),
2265 JACK has either been shutdown or it\n\
2266 disconnected Ardour because Ardour\n\
2267 was not fast enough. You can save the\n\
2268 session and/or try to reconnect to JACK ."));
2272 ARDOUR_UI::do_engine_start ()
2278 catch (AudioEngine::PortRegistrationFailure& err) {
2280 error << _("Unable to create all required ports")
2288 error << _("Unable to start the session running")
2298 ARDOUR_UI::start_engine ()
2300 if (do_engine_start () == 0) {
2301 if (session && _session_is_new) {
2302 /* we need to retain initial visual
2303 settings for a new session
2305 session->save_state ("");
2308 /* there is too much going on, in too many threads, for us to
2309 end up with a clean session. So wait 1 second after loading,
2310 and fix it up. its ugly, but until i come across a better
2311 solution, its what we have.
2314 Glib::signal_timeout().connect (mem_fun(*this, &ARDOUR_UI::make_session_clean), 1000);
2321 ARDOUR_UI::update_clocks ()
2323 Clock (session->audible_frame()); /* EMIT_SIGNAL */
2327 ARDOUR_UI::start_clocking ()
2329 clock_signal_connection = RapidScreenUpdate.connect (mem_fun(*this, &ARDOUR_UI::update_clocks));
2333 ARDOUR_UI::stop_clocking ()
2335 clock_signal_connection.disconnect ();
2339 ARDOUR_UI::toggle_clocking ()
2342 if (clock_button.get_active()) {
2351 ARDOUR_UI::_blink (void *arg)
2354 ((ARDOUR_UI *) arg)->blink ();
2361 Blink (blink_on = !blink_on); /* EMIT_SIGNAL */
2365 ARDOUR_UI::start_blinking ()
2367 /* Start the blink signal. Everybody with a blinking widget
2368 uses Blink to drive the widget's state.
2371 if (blink_timeout_tag < 0) {
2373 blink_timeout_tag = gtk_timeout_add (240, _blink, this);
2378 ARDOUR_UI::stop_blinking ()
2380 if (blink_timeout_tag >= 0) {
2381 gtk_timeout_remove (blink_timeout_tag);
2382 blink_timeout_tag = -1;
2388 ARDOUR_UI::add_diskstream_to_menu (DiskStream& dstream)
2390 using namespace Gtk;
2391 using namespace Menu_Helpers;
2393 if (dstream.hidden()) {
2397 MenuList& items = diskstream_menu->items();
2398 items.push_back (MenuElem (dstream.name(), bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), (gint32) dstream.id())));
2402 ARDOUR_UI::diskstream_selected (gint32 id)
2404 selected_dstream = id;
2409 ARDOUR_UI::select_diskstream (GdkEventButton *ev)
2411 using namespace Gtk;
2412 using namespace Menu_Helpers;
2418 diskstream_menu = new Menu();
2419 diskstream_menu->set_name ("ArdourContextMenu");
2420 using namespace Gtk;
2421 using namespace Menu_Helpers;
2423 MenuList& items = diskstream_menu->items();
2424 items.push_back (MenuElem (_("No Stream"), (bind (mem_fun(*this, &ARDOUR_UI::diskstream_selected), -1))));
2426 session->foreach_diskstream (this, &ARDOUR_UI::add_diskstream_to_menu);
2429 diskstream_menu->popup (ev->button, ev->time);
2431 diskstream_menu->popup (0, 0);
2434 selected_dstream = -1;
2438 delete diskstream_menu;
2440 return selected_dstream;
2444 ARDOUR_UI::name_io_setup (AudioEngine& engine,
2450 if (io.n_inputs() == 0) {
2455 /* XXX we're not handling multiple ports yet. */
2457 const char **connections = io.input(0)->get_connections();
2459 if (connections == 0 || connections[0] == '\0') {
2462 buf = connections[0];
2469 if (io.n_outputs() == 0) {
2474 /* XXX we're not handling multiple ports yet. */
2476 const char **connections = io.output(0)->get_connections();
2478 if (connections == 0 || connections[0] == '\0') {
2481 buf = connections[0];
2489 ARDOUR_UI::snapshot_session ()
2491 ArdourPrompter prompter (true);
2498 now = now.substr (0, now.length() - 1);
2500 prompter.set_name ("Prompter");
2501 prompter.set_prompt (_("Name for snapshot"));
2502 prompter.set_initial_text (now);
2504 switch (prompter.run()) {
2505 case RESPONSE_ACCEPT:
2506 prompter.get_result (snapname);
2507 if (snapname.length()){
2508 save_state (snapname);
2518 ARDOUR_UI::save_state (string name)
2520 (void) save_state_canfail (name);
2524 ARDOUR_UI::save_state_canfail (string name)
2529 if (name.length() == 0) {
2530 name = session->snap_name();
2533 if ((ret = session->save_state (name)) != 0) {
2537 save_ardour_state (); /* XXX cannot fail? yeah, right ... */
2542 ARDOUR_UI::restore_state (string name)
2545 if (name.length() == 0) {
2546 name = session->name();
2548 session->restore_state (name);
2553 ARDOUR_UI::primary_clock_value_changed ()
2556 session->request_locate (primary_clock.current_time ());
2561 ARDOUR_UI::secondary_clock_value_changed ()
2564 session->request_locate (secondary_clock.current_time ());
2569 ARDOUR_UI::rec_enable_button_blink (bool onoff, DiskStream *dstream, Widget *w)
2571 if (session && dstream && dstream->record_enabled()) {
2573 Session::RecordState rs;
2575 rs = session->record_status ();
2578 case Session::Disabled:
2579 case Session::Enabled:
2580 if (w->get_state() != STATE_SELECTED) {
2581 w->set_state (STATE_SELECTED);
2585 case Session::Recording:
2586 if (w->get_state() != STATE_ACTIVE) {
2587 w->set_state (STATE_ACTIVE);
2593 if (w->get_state() != STATE_NORMAL) {
2594 w->set_state (STATE_NORMAL);
2600 ARDOUR_UI::transport_rec_enable_blink (bool onoff)
2606 switch (session->record_status()) {
2607 case Session::Enabled:
2609 rec_button.set_state (STATE_ACTIVE);
2611 rec_button.set_state (STATE_NORMAL);
2615 case Session::Recording:
2616 rec_button.set_state (STATE_ACTIVE);
2620 rec_button.set_active (false);
2621 rec_button.set_state (STATE_NORMAL);
2627 ARDOUR_UI::hide_and_quit (GdkEventAny *ev, ArdourDialog *window)
2635 ARDOUR_UI::start_keyboard_prefix ()
2637 keyboard->start_prefix();
2641 ARDOUR_UI::save_template ()
2644 ArdourPrompter prompter (true);
2647 prompter.set_name (X_("Prompter"));
2648 prompter.set_prompt (_("Name for mix template:"));
2649 prompter.set_initial_text(session->name() + _("-template"));
2651 switch (prompter.run()) {
2652 case RESPONSE_ACCEPT:
2653 prompter.get_result (name);
2655 if (name.length()) {
2656 session->save_template (name);
2666 ARDOUR_UI::new_session (bool startup, std::string predetermined_path)
2668 m_new_session_dialog->show_all();
2669 m_new_session_dialog->set_transient_for(*editor);
2670 m_new_session_dialog->set_name(predetermined_path);
2672 int response = Gtk::RESPONSE_CANCEL;
2675 response = m_new_session_dialog->run ();
2677 if(response == Gtk::RESPONSE_OK) {
2679 _session_is_new = true;
2681 std::string session_name = m_new_session_dialog->session_name();
2682 std::string session_path = m_new_session_dialog->session_folder();
2683 std::string template_name = m_new_session_dialog->session_template_name();
2685 if (m_new_session_dialog->use_session_template()) {
2687 load_session (session_path, session_name, &template_name);
2693 Session::AutoConnectOption iconnect;
2694 Session::AutoConnectOption oconnect;
2696 if (m_new_session_dialog->create_control_track()) {
2697 cchns = (uint32_t) m_new_session_dialog->control_channel_count();
2702 if (m_new_session_dialog->create_master_track()) {
2703 mchns = (uint32_t) m_new_session_dialog->master_channel_count();
2708 if (m_new_session_dialog->connect_inputs()) {
2709 iconnect = Session::AutoConnectPhysical;
2711 iconnect = Session::AutoConnectOption (0);
2714 /// @todo some minor tweaks.
2716 if (m_new_session_dialog->connect_outs_to_master()) {
2717 oconnect = Session::AutoConnectMaster;
2718 } else if (m_new_session_dialog->connect_outs_to_physical()) {
2719 oconnect = Session::AutoConnectPhysical;
2721 oconnect = Session::AutoConnectOption (0);
2724 uint32_t nphysin = (uint32_t) m_new_session_dialog->input_limit_count();
2725 uint32_t nphysout = (uint32_t) m_new_session_dialog->output_limit_count();
2727 build_session (session_path,
2735 engine->frame_rate() * 60 * 5);
2739 } while(response == Gtk::RESPONSE_HELP);
2740 m_new_session_dialog->hide_all();
2744 ARDOUR_UI::load_session (string path, string snap_name, string* mix_template)
2746 Session *new_session;
2748 session_loaded = false;
2749 x = unload_session ();
2757 /* if it already exists, we must have write access */
2759 if (::access (path.c_str(), F_OK) == 0 && ::access (path.c_str(), W_OK)) {
2760 ArdourMessage msg (editor, X_("noaccess dialog"), _("\
2761 You do not have write access to this session.\n\
2762 This prevents the session from being loaded."));
2767 new_session = new Session (*engine, path, snap_name, mix_template);
2772 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
2776 connect_to_session (new_session);
2778 //if (engine->running()) {
2779 //mixer->show_window();
2781 session_loaded = true;
2786 ARDOUR_UI::make_session_clean ()
2789 session->set_clean ();
2796 ARDOUR_UI::build_session (string path, string snap_name,
2797 uint32_t control_channels,
2798 uint32_t master_channels,
2799 Session::AutoConnectOption input_connect,
2800 Session::AutoConnectOption output_connect,
2803 jack_nframes_t initial_length)
2805 Session *new_session;
2808 session_loaded = false;
2809 x = unload_session ();
2816 _session_is_new = true;
2819 new_session = new Session (*engine, path, snap_name, input_connect, output_connect,
2820 control_channels, master_channels, nphysin, nphysout, initial_length);
2825 error << string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"), path, snap_name) << endmsg;
2829 connect_to_session (new_session);
2831 //if (engine->running()) {
2832 //mixer->show_window();
2834 session_loaded = true;
2842 editor->show_window ();
2846 if (session && mixer) {
2847 mixer->show_window ();
2856 ARDOUR_UI::show_splash ()
2859 about = new About();
2865 ARDOUR_UI::hide_splash ()
2873 ARDOUR_UI::display_cleanup_results (Session::cleanup_report& rep, const gchar* list_title, string msg)
2877 removed = rep.paths.size();
2880 ArdourMessage msg (editor, X_("cleanupresults"),
2882 No audio files were ready for cleanup\n\n\
2883 If this seems suprising, check for any existing\n\
2884 snapshots. These may still include regions that\n\
2885 require some unused files to continue to exist."));
2889 ArdourDialog results ("cleanup results");
2891 struct CleanupResultsModelColumns : public Gtk::TreeModel::ColumnRecord {
2892 CleanupResultsModelColumns() {
2896 Gtk::TreeModelColumn<Glib::ustring> visible_name;
2897 Gtk::TreeModelColumn<Glib::ustring> fullpath;
2901 Glib::RefPtr<Gtk::ListStore> results_model;
2902 CleanupResultsModelColumns results_columns;
2903 Gtk::TreeView results_display;
2905 results_model = ListStore::create (results_columns);
2906 results_display.set_model (results_model);
2907 results_display.append_column (list_title, results_columns.visible_name);
2908 results_display.set_headers_visible (true);
2910 Gtk::ScrolledWindow list_scroller;
2912 Gtk::Button ok_button (_("OK"));
2915 vpacker.set_border_width (10);
2916 vpacker.set_spacing (10);
2918 if (rep.space < 1048576.0f) {
2920 txt.set_text (string_compose (msg, removed, _("files"), (float) rep.space / 1024.0f, "kilo"));
2922 txt.set_text (string_compose (msg, removed, _("file"), (float) rep.space / 1024.0f, "kilo"));
2926 txt.set_text (string_compose (msg, removed, _("files"), (float) rep.space / 1048576.0f, "mega"));
2928 txt.set_text (string_compose (msg, removed, _("file"), (float) rep.space / 1048576.0f, "mega"));
2932 vpacker.pack_start (txt, false, false);
2934 for (vector<string>::iterator i = rep.paths.begin(); i != rep.paths.end(); ++i) {
2935 TreeModel::Row row = *(results_model->append());
2936 row[results_columns.visible_name] = *i;
2937 row[results_columns.fullpath] = *i;
2940 list_scroller.add (results_display);
2941 list_scroller.set_size_request (-1, 250);
2942 list_scroller.set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC);
2944 vpacker.pack_start (list_scroller, true, true);
2945 vpacker.pack_start (ok_button, false, false);
2947 results.add (vpacker);
2949 results.set_position (Gtk::WIN_POS_MOUSE);
2950 results.set_title (_("ardour: cleanup"));
2951 results.set_modal (true);
2957 ARDOUR_UI::cleanup ()
2960 /* shouldn't happen: menu item is insensitive */
2964 ArdourDialog checker (X_("cleanup confirm dialog"));
2965 Gtk::Label label (_("\
2966 Cleanup is a destructive operation.\n\
2967 ALL undo/redo information will be lost if you cleanup.\n\
2968 Unused audio files will be moved to a \"dead sounds\" location."));
2970 Gtk::Button ok_button (_("Proceed with cleanup"));
2971 Gtk::Button cancel_button (_("Cancel"));
2975 bbox.set_border_width (6);
2976 bbox.set_spacing (12);
2977 bbox.pack_start (ok_button, true, false);
2978 bbox.pack_start (cancel_button, true, false);
2980 vbox.set_border_width (6);
2981 vbox.set_spacing (12);
2982 vbox.pack_start (label, false, false);
2983 vbox.pack_start (bbox, false, false);
2986 checker.set_name (_("CleanupDialog"));
2987 checker.set_title (_("ardour cleanup"));
2988 checker.set_wmclass (_("ardour_cleanup"), "Ardour");
2989 checker.set_position (Gtk::WIN_POS_MOUSE);
2991 ok_button.signal_clicked().connect (bind (mem_fun (checker, &ArdourDialog::stop), 1));
2992 cancel_button.signal_clicked().connect (bind (mem_fun (checker, &ArdourDialog::stop), 0));
2996 switch (checker.run_status()) {
3003 Session::cleanup_report rep;
3005 editor->prepare_for_cleanup ();
3007 if (session->cleanup_sources (rep)) {
3011 display_cleanup_results (rep,
3014 The following %1 %2 were not in use.\n\
3015 The next time you flush the wastebasket\n\
3016 it will release an additional %3 %4bytes\n\
3022 ARDOUR_UI::flush_trash ()
3025 /* shouldn't happen: menu item is insensitive */
3029 Session::cleanup_report rep;
3031 if (session->cleanup_trash_sources (rep)) {
3035 display_cleanup_results (rep,
3037 _("The following %1 file%2 were deleted, releasing %3 %4bytes of disk space"));
3041 ARDOUR_UI::add_route ()
3049 if (add_route_dialog == 0) {
3050 add_route_dialog = new AddRouteDialog;
3051 editor->ensure_float (*add_route_dialog);
3054 if (add_route_dialog->is_visible()) {
3055 /* we're already doing this */
3059 add_route_dialog->run ();
3061 if (add_route_dialog->run_status()) {
3065 if ((count = add_route_dialog->count()) <= 0) {
3069 uint32_t input_chan = add_route_dialog->channels ();
3070 uint32_t output_chan;
3071 string name_template = add_route_dialog->name_template ();
3072 bool track = add_route_dialog->track ();
3074 Session::AutoConnectOption oac = session->get_output_auto_connect();
3076 if (oac & Session::AutoConnectMaster) {
3077 output_chan = (session->master_out() ? session->master_out()->n_inputs() : input_chan);
3079 output_chan = input_chan;
3082 /* XXX do something with name template */
3086 session_add_audio_track (input_chan, output_chan);
3088 session_add_audio_bus (input_chan, output_chan);
3092 while (Main::events_pending()) {
3099 ARDOUR_UI::mixer_settings () const
3104 node = session->instant_xml(X_("Mixer"), session->path());
3106 node = Config->instant_xml(X_("Mixer"), Config->get_user_ardour_path());
3110 node = new XMLNode (X_("Mixer"));
3117 ARDOUR_UI::editor_settings () const
3122 node = session->instant_xml(X_("Editor"), session->path());
3124 node = Config->instant_xml(X_("Editor"), Config->get_user_ardour_path());
3128 node = new XMLNode (X_("Editor"));
3134 ARDOUR_UI::keyboard_settings () const
3138 node = Config->extra_xml(X_("Keyboard"));
3141 node = new XMLNode (X_("Keyboard"));
3147 ARDOUR_UI::halt_on_xrun_message ()
3149 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::halt_on_xrun_message));
3151 ArdourMessage msg (editor, X_("haltonxrun"),
3152 _("Recording was stopped because your system could not keep up."));
3156 ARDOUR_UI::delete_sources_in_the_right_thread (list<ARDOUR::Source*>* deletion_list)
3158 ENSURE_GUI_THREAD (bind (mem_fun(*this, &ARDOUR_UI::delete_sources_in_the_right_thread), deletion_list));
3160 for (list<Source*>::iterator i = deletion_list->begin(); i != deletion_list->end(); ++i) {
3164 delete deletion_list;
3168 ARDOUR_UI::disk_overrun_handler ()
3170 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
3172 if (!have_disk_overrun_displayed) {
3173 have_disk_overrun_displayed = true;
3174 ArdourMessage msg (editor, X_("diskrate dialog"), _("\
3175 The disk system on your computer\n\
3176 was not able to keep up with Ardour.\n\
3178 Specifically, it failed to write data to disk\n\
3179 quickly enough to keep up with recording.\n"));
3180 have_disk_overrun_displayed = false;
3185 ARDOUR_UI::disk_underrun_handler ()
3187 ENSURE_GUI_THREAD (mem_fun(*this, &ARDOUR_UI::disk_underrun_handler));
3189 if (!have_disk_underrun_displayed) {
3190 have_disk_underrun_displayed = true;
3191 ArdourMessage msg (editor, X_("diskrate2 dialog"),
3192 (_("The disk system on your computer\n\
3193 was not able to keep up with Ardour.\n\
3195 Specifically, it failed to read data from disk\n\
3196 quickly enough to keep up with playback.\n")));
3197 have_disk_underrun_displayed = false;
3202 ARDOUR_UI::disk_underrun_message_gone ()
3204 have_disk_underrun_displayed = false;
3208 ARDOUR_UI::disk_overrun_message_gone ()
3210 have_disk_underrun_displayed = false;
3214 ARDOUR_UI::pending_state_dialog ()
3216 ArdourDialog dialog ("pending state dialog");
3217 Button use_button (_("Recover from crash"));
3218 Button cancel_button (_("Ignore crash data"));
3220 This session appears to have been in\n\
3221 middle of recording when ardour or\n\
3222 the computer was shutdown.\n\
3224 Ardour can recover any captured audio for\n\
3225 you, or it can ignore it. Please decide\n\
3226 what you would like to do.\n"));
3230 vpacker.set_border_width (12);
3231 vpacker.set_spacing (7);
3232 vpacker.pack_start (message);
3233 vpacker.pack_start (hpacker);
3235 hpacker.set_spacing (7);
3236 hpacker.pack_start (use_button);
3237 hpacker.pack_start (cancel_button);
3239 use_button.signal_clicked().connect (bind (mem_fun (dialog, &ArdourDialog::stop), 0));
3240 cancel_button.signal_clicked().connect (bind (mem_fun (dialog, &ArdourDialog::stop), 1));
3242 dialog.add (vpacker);
3243 dialog.set_position (WIN_POS_CENTER);
3248 if (dialog.run_status () != 0) {
3257 ARDOUR_UI::disconnect_from_jack ()
3260 if( engine->disconnect_from_jack ()) {
3261 ArdourMessage msg (editor, X_("nojack dialog"),
3262 _("Could not disconnect from JACK"));
3265 update_sample_rate (0);
3270 ARDOUR_UI::reconnect_to_jack ()
3273 if (engine->reconnect_to_jack ()) {
3274 ArdourMessage msg (editor, X_("nojack dialog"),
3275 _("Could not reconnect to JACK"));
3278 update_sample_rate (0);
3283 ARDOUR_UI::set_jack_buffer_size (jack_nframes_t nframes)
3285 engine->request_buffer_size (nframes);
3286 update_sample_rate (0);
3290 ARDOUR_UI::cmdline_new_session (string path)
3292 if (path[0] != '/') {
3293 char buf[PATH_MAX+1];
3296 getcwd (buf, sizeof (buf));
3303 new_session (false, path);
3305 _will_create_new_session_automatically = false; /* done it */
3306 return FALSE; /* don't call it again */