X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=gtk2_ardour%2Fardour_ui.cc;h=cc173c80e333649ddb51240089dfb33784ab2e36;hb=cad92bfa4e0a6c14068e3b42f0b7c3baf18aee8a;hp=1e0b75d3cb2510e76e779d8331c4f6a0358b75f8;hpb=5de741c4ab9970bee830a60efa07e26f219aecef;p=ardour.git diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 1e0b75d3cb..cc173c80e3 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -49,6 +49,7 @@ #include "pbd/file_utils.h" #include "gtkmm2ext/application.h" +#include "gtkmm2ext/bindings.h" #include "gtkmm2ext/gtk_ui.h" #include "gtkmm2ext/utils.h" #include "gtkmm2ext/click_box.h" @@ -77,37 +78,41 @@ #include "ardour/midi_track.h" #include "ardour/filesystem_paths.h" #include "ardour/filename_extensions.h" +#include "ardour/process_thread.h" typedef uint64_t microseconds_t; +#include "about.h" #include "actions.h" +#include "add_route_dialog.h" +#include "ambiguous_file_dialog.h" #include "ardour_ui.h" -#include "public_editor.h" #include "audio_clock.h" +#include "bundle_manager.h" +#include "engine_dialog.h" +#include "gain_meter.h" +#include "global_port_matrix.h" +#include "gui_object.h" +#include "gui_thread.h" #include "keyboard.h" +#include "location_ui.h" +#include "missing_file_dialog.h" +#include "missing_plugin_dialog.h" #include "mixer_ui.h" -#include "prompter.h" #include "opts.h" -#include "add_route_dialog.h" -#include "about.h" -#include "splash.h" -#include "utils.h" -#include "gui_thread.h" -#include "theme_manager.h" -#include "bundle_manager.h" -#include "session_metadata_dialog.h" -#include "gain_meter.h" +#include "processor_box.h" +#include "prompter.h" +#include "public_editor.h" #include "route_time_axis.h" +#include "session_metadata_dialog.h" +#include "shuttle_control.h" +#include "speaker_dialog.h" +#include "splash.h" #include "startup.h" -#include "engine_dialog.h" -#include "processor_box.h" +#include "theme_manager.h" #include "time_axis_view_item.h" +#include "utils.h" #include "window_proxy.h" -#include "global_port_matrix.h" -#include "location_ui.h" -#include "missing_file_dialog.h" -#include "missing_plugin_dialog.h" -#include "ambiguous_file_dialog.h" #include "i18n.h" @@ -128,56 +133,53 @@ bool could_be_a_valid_path (const string& path); ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) - : Gtkmm2ext::UI (PROGRAM_NAME, argcp, argvp), + : Gtkmm2ext::UI (PROGRAM_NAME, argcp, argvp) - primary_clock (X_("primary"), false, X_("TransportClockDisplay"), true, true, false, true), - secondary_clock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, true, false, true), - preroll_clock (X_("preroll"), false, X_("PreRollClock"), true, false, true), - postroll_clock (X_("postroll"), false, X_("PostRollClock"), true, false, true), + , gui_object_state (new GUIObjectState) + , primary_clock (new AudioClock (X_("primary"), false, X_("TransportClockDisplay"), true, true, false, true)) + , secondary_clock (new AudioClock (X_("secondary"), false, X_("SecondaryClockDisplay"), true, true, false, true)) + , preroll_clock (new AudioClock (X_("preroll"), false, X_("PreRollClock"), true, false, true)) + , postroll_clock (new AudioClock (X_("postroll"), false, X_("PostRollClock"), true, false, true)) /* preroll stuff */ - preroll_button (_("pre\nroll")), - postroll_button (_("post\nroll")), + , preroll_button (_("pre\nroll")) + , postroll_button (_("post\nroll")) /* big clock */ - big_clock (X_("bigclock"), false, "BigClockNonRecording", true, true, false, false), + , big_clock (new AudioClock (X_("bigclock"), false, "BigClockNonRecording", true, true, false, false)) /* transport */ - roll_controllable (new TransportControllable ("transport roll", *this, TransportControllable::Roll)), - stop_controllable (new TransportControllable ("transport stop", *this, TransportControllable::Stop)), - goto_start_controllable (new TransportControllable ("transport goto start", *this, TransportControllable::GotoStart)), - goto_end_controllable (new TransportControllable ("transport goto end", *this, TransportControllable::GotoEnd)), - auto_loop_controllable (new TransportControllable ("transport auto loop", *this, TransportControllable::AutoLoop)), - play_selection_controllable (new TransportControllable ("transport play selection", *this, TransportControllable::PlaySelection)), - rec_controllable (new TransportControllable ("transport rec-enable", *this, TransportControllable::RecordEnable)), - shuttle_controllable (new TransportControllable ("shuttle", *this, TransportControllable::ShuttleControl)), - shuttle_controller_binding_proxy (shuttle_controllable), - - roll_button (roll_controllable), - stop_button (stop_controllable), - goto_start_button (goto_start_controllable), - goto_end_button (goto_end_controllable), - auto_loop_button (auto_loop_controllable), - play_selection_button (play_selection_controllable), - rec_button (rec_controllable), - - shuttle_units_button (_("% ")), - - punch_in_button (_("Punch In")), - punch_out_button (_("Punch Out")), - auto_return_button (_("Auto Return")), - auto_play_button (_("Auto Play")), - auto_input_button (_("Auto Input")), - click_button (_("Click")), - time_master_button (_("time\nmaster")), - - auditioning_alert_button (_("AUDITION")), - solo_alert_button (_("SOLO")), - - error_log_button (_("Errors")) + , roll_controllable (new TransportControllable ("transport roll", *this, TransportControllable::Roll)) + , stop_controllable (new TransportControllable ("transport stop", *this, TransportControllable::Stop)) + , goto_start_controllable (new TransportControllable ("transport goto start", *this, TransportControllable::GotoStart)) + , goto_end_controllable (new TransportControllable ("transport goto end", *this, TransportControllable::GotoEnd)) + , auto_loop_controllable (new TransportControllable ("transport auto loop", *this, TransportControllable::AutoLoop)) + , play_selection_controllable (new TransportControllable ("transport play selection", *this, TransportControllable::PlaySelection)) + , rec_controllable (new TransportControllable ("transport rec-enable", *this, TransportControllable::RecordEnable)) + + , roll_button (roll_controllable) + , stop_button (stop_controllable) + , goto_start_button (goto_start_controllable) + , goto_end_button (goto_end_controllable) + , auto_loop_button (auto_loop_controllable) + , play_selection_button (play_selection_controllable) + , rec_button (rec_controllable) + + , auto_return_button (_("Auto Return")) + , auto_play_button (_("Auto Play")) + , auto_input_button (_("Auto Input")) + // , click_button (_("Click")) + , time_master_button (_("time\nmaster")) + + , auditioning_alert_button (_("AUDITION")) + , solo_alert_button (_("SOLO")) + + , error_log_button (_("Errors")) + + , _status_bar_visibility (X_("status-bar")) { using namespace Gtk::Menu_Helpers; @@ -205,6 +207,8 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) ui_config = new UIConfiguration(); theme_manager = new ThemeManager(); + key_editor = 0; + editor = 0; mixer = 0; editor = 0; @@ -218,6 +222,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) _will_create_new_session_automatically = false; add_route_dialog = 0; route_params = 0; + bundle_manager = 0; rc_option_editor = 0; session_option_editor = 0; location_ui = 0; @@ -225,7 +230,6 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) have_configure_timeout = false; have_disk_speed_dialog_displayed = false; session_loaded = false; - last_speed_displayed = -1.0f; ignore_dual_punch = false; original_big_clock_width = -1; original_big_clock_height = -1; @@ -238,19 +242,9 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) auto_loop_button.unset_flags (Gtk::CAN_FOCUS); play_selection_button.unset_flags (Gtk::CAN_FOCUS); rec_button.unset_flags (Gtk::CAN_FOCUS); - + join_play_range_button.unset_flags (Gtk::CAN_FOCUS); last_configure_time= 0; - - shuttle_grabbed = false; - shuttle_fract = 0.0; - shuttle_max_speed = 8.0f; - - shuttle_style_menu = 0; - shuttle_unit_menu = 0; - - // We do not have jack linked in yet so; - - last_shuttle_request = last_peak_grab = 0; // get_microseconds(); + last_peak_grab = 0; ARDOUR::Diskstream::DiskOverrun.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::disk_overrun_handler, this), gui_context()); ARDOUR::Diskstream::DiskUnderrun.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::disk_underrun_handler, this), gui_context()); @@ -268,7 +262,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) ARDOUR::Session::AskAboutSampleRateMismatch.connect_same_thread (forever_connections, boost::bind (&ARDOUR_UI::sr_mismatch_dialog, this, _1, _2)); /* handle requests to quit (coming from JACK session) */ - + ARDOUR::Session::Quit.connect (forever_connections, MISSING_INVALIDATOR, ui_bind (&ARDOUR_UI::finish, this), gui_context ()); /* handle requests to deal with missing files */ @@ -309,15 +303,19 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) keyboard->set_state (*node, Stateful::loading_state_version); } + /* we don't like certain modifiers */ + Bindings::set_ignored_state (GDK_LOCK_MASK|GDK_MOD2_MASK|GDK_MOD3_MASK); + reset_dpi(); TimeAxisViewItem::set_constant_heights (); /* The following must happen after ARDOUR::init() so that Config is set up */ - + location_ui = new ActionWindowProxy (X_("locations"), Config->extra_xml (X_("UI")), X_("ToggleLocations")); big_clock_window = new ActionWindowProxy (X_("bigclock"), Config->extra_xml (X_("UI")), X_("ToggleBigClock")); - + speaker_config_window = new ActionWindowProxy (X_("speakerconf"), Config->extra_xml (X_("UI")), X_("toggle-speaker-config")); + for (ARDOUR::DataType::iterator i = ARDOUR::DataType::begin(); i != ARDOUR::DataType::end(); ++i) { _global_port_matrix[*i] = new ActionWindowProxy ( string_compose ("GlobalPortMatrix-%1", (*i).to_string()), @@ -328,10 +326,15 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) setup_clock (); + SpeakerDialog* s = new SpeakerDialog (); + s->signal_unmap().connect (sigc::bind (sigc::ptr_fun (&ActionManager::uncheck_toggleaction), X_("/Common/toggle-speaker-config"))); + speaker_config_window->set (s); + starting.connect (sigc::mem_fun(*this, &ARDOUR_UI::startup)); stopping.connect (sigc::mem_fun(*this, &ARDOUR_UI::shutdown)); - platform_setup (); + _process_thread = new ProcessThread (); + _process_thread->init (); } /** @return true if a session was chosen and `apply' clicked, otherwise false if `cancel' was clicked */ @@ -342,7 +345,7 @@ ARDOUR_UI::run_startup (bool should_be_new, string load_template) _startup = new ArdourStartup (); XMLNode* audio_setup = Config->extra_xml ("AudioSetup"); - + if (audio_setup && _startup->engine_control()) { _startup->engine_control()->set_state (*audio_setup); } @@ -411,6 +414,12 @@ ARDOUR_UI::post_engine () if (setup_windows ()) { throw failed_constructor (); } + + /* Do this after setup_windows (), as that's when the _status_bar_visibility is created */ + XMLNode* n = Config->extra_xml (X_("UI")); + if (n) { + _status_bar_visibility.set_state (*n); + } check_memory_locking(); @@ -419,10 +428,11 @@ ARDOUR_UI::post_engine () if (ARDOUR_COMMAND_LINE::show_key_actions) { vector names; vector paths; + vector tooltips; vector keys; vector bindings; - ActionManager::get_all_actions (names, paths, keys, bindings); + ActionManager::get_all_actions (names, paths, tooltips, keys, bindings); vector::iterator n; vector::iterator k; @@ -443,11 +453,11 @@ ARDOUR_UI::post_engine () /* set default clock modes */ if (Profile->get_sae()) { - primary_clock.set_mode (AudioClock::BBT); - secondary_clock.set_mode (AudioClock::MinSec); + primary_clock->set_mode (AudioClock::BBT); + secondary_clock->set_mode (AudioClock::MinSec); } else { - primary_clock.set_mode (AudioClock::Timecode); - secondary_clock.set_mode (AudioClock::BBT); + primary_clock->set_mode (AudioClock::Timecode); + secondary_clock->set_mode (AudioClock::BBT); } /* start the time-of-day-clock */ @@ -556,8 +566,9 @@ ARDOUR_UI::set_transport_controllable_state (const XMLNode& node) rec_controllable->set_id (prop->value()); } if ((prop = node.property ("shuttle")) != 0) { - shuttle_controllable->set_id (prop->value()); + shuttle_box->controllable()->set_id (prop->value()); } + } XMLNode& @@ -580,7 +591,7 @@ ARDOUR_UI::get_transport_controllable_state () node->add_property (X_("play_selection"), buf); rec_controllable->id().print (buf, sizeof (buf)); node->add_property (X_("rec"), buf); - shuttle_controllable->id().print (buf, sizeof (buf)); + shuttle_box->controllable()->id().print (buf, sizeof (buf)); node->add_property (X_("shuttle"), buf); return *node; @@ -712,7 +723,12 @@ ARDOUR_UI::startup () for (ARDOUR::DataType::iterator i = ARDOUR::DataType::begin(); i != ARDOUR::DataType::end(); ++i) { add_window_proxy (_global_port_matrix[*i]); } - + + /* We have to do this here since goto_editor_window() ends up calling show_all() on the + * editor window, and we may want stuff to be hidden. + */ + _status_bar_visibility.update (); + BootMessage (string_compose (_("%1 is ready for use"), PROGRAM_NAME)); } @@ -753,15 +769,15 @@ ARDOUR_UI::check_memory_locking () if (ram == 0 || ((double) limits.rlim_cur / ram) < 0.75) { - MessageDialog msg ( - string_compose (_("WARNING: Your system has a limit for maximum amount of locked memory. " - "This might cause %1 to run out of memory before your system " - "runs out of memory. \n\n" - "You can view the memory limit with 'ulimit -l', " - "and it is normally controlled by /etc/security/limits.conf"), - PROGRAM_NAME).c_str()); - + string_compose ( + _("WARNING: Your system has a limit for maximum amount of locked memory. " + "This might cause %1 to run out of memory before your system " + "runs out of memory. \n\n" + "You can view the memory limit with 'ulimit -l', " + "and it is normally controlled by /etc/security/limits.conf"), + PROGRAM_NAME).c_str()); + VBox* vbox = msg.get_vbox(); HBox hbox; CheckButton cb (_("Do not show this window again")); @@ -810,7 +826,11 @@ ARDOUR_UI::finish() } if (_session->dirty()) { - switch (ask_about_saving_session(_("quit"))) { + vector actions; + actions.push_back (_("Don't quit")); + actions.push_back (_("Just quit")); + actions.push_back (_("Save and quit")); + switch (ask_about_saving_session(actions)) { case -1: return; break; @@ -859,7 +879,7 @@ If you still wish to quit, please use the\n\n\ } int -ARDOUR_UI::ask_about_saving_session (const string & what) +ARDOUR_UI::ask_about_saving_session (const vector& actions) { ArdourDialog window (_("Unsaved Session")); Gtk::HBox dhbox; // the hbox for the image and text @@ -868,12 +888,11 @@ ARDOUR_UI::ask_about_saving_session (const string & what) string msg; - msg = string_compose(_("Don't %1"), what); - window.add_button (msg, RESPONSE_REJECT); - msg = string_compose(_("Just %1"), what); - window.add_button (msg, RESPONSE_APPLY); - msg = string_compose(_("Save and %1"), what); - window.add_button (msg, RESPONSE_ACCEPT); + assert (actions.size() >= 3); + + window.add_button (actions[0], RESPONSE_REJECT); + window.add_button (actions[1], RESPONSE_APPLY); + window.add_button (actions[2], RESPONSE_ACCEPT); window.set_default_response (RESPONSE_ACCEPT); @@ -881,15 +900,14 @@ ARDOUR_UI::ask_about_saving_session (const string & what) noquit_button.set_name ("EditorGTKButton"); string prompt; - string type; if (_session->snap_name() == _session->name()) { - type = _("session"); + prompt = string_compose(_("The session \"%1\"\nhas not been saved.\n\nAny changes made this time\nwill be lost unless you save it.\n\nWhat do you want to do?"), + _session->snap_name()); } else { - type = _("snapshot"); + prompt = string_compose(_("The snapshot \"%1\"\nhas not been saved.\n\nAny changes made this time\nwill be lost unless you save it.\n\nWhat do you want to do?"), + _session->snap_name()); } - prompt = string_compose(_("The %1 \"%2\"\nhas not been saved.\n\nAny changes made this time\nwill be lost unless you save it.\n\nWhat do you want to do?"), - type, _session->snap_name()); prompt_label.set_text (prompt); prompt_label.set_name (X_("PrompterLabel")); @@ -941,7 +959,7 @@ ARDOUR_UI::every_second () gint ARDOUR_UI::every_point_one_seconds () { - update_speed_display (); + shuttle_box->update_speed_display (); RapidScreenUpdate(); /* EMIT_SIGNAL */ return TRUE; } @@ -958,7 +976,7 @@ ARDOUR_UI::every_point_zero_one_seconds () void ARDOUR_UI::update_sample_rate (framecnt_t) { - char buf[32]; + char buf[64]; ENSURE_GUI_THREAD (*this, &ARDOUR_UI::update_sample_rate, ignored) @@ -971,40 +989,111 @@ ARDOUR_UI::update_sample_rate (framecnt_t) framecnt_t rate = engine->frame_rate(); if (fmod (rate, 1000.0) != 0.0) { - snprintf (buf, sizeof (buf), _("%.1f kHz / %4.1f ms"), + snprintf (buf, sizeof (buf), _("JACK: %.1f kHz / %4.1f ms"), (float) rate/1000.0f, (engine->frames_per_cycle() / (float) rate) * 1000.0f); } else { - snprintf (buf, sizeof (buf), _("%" PRId64 " kHz / %4.1f ms"), + snprintf (buf, sizeof (buf), _("JACK: %" PRId64 " kHz / %4.1f ms"), rate/1000, (engine->frames_per_cycle() / (float) rate) * 1000.0f); } } - sample_rate_label.set_text (buf); + sample_rate_label.set_markup (buf); +} + +void +ARDOUR_UI::update_format () +{ + if (!_session) { + format_label.set_text (""); + return; + } + + stringstream s; + s << "File: "; + + switch (_session->config.get_native_file_header_format ()) { + case BWF: + s << "BWF"; + break; + case WAVE: + s << "WAV"; + break; + case WAVE64: + s << "WAV64"; + break; + case CAF: + s << "CAF"; + break; + case AIFF: + s << "AIFF"; + break; + case iXML: + s << "iXML"; + break; + case RF64: + s << "RF64"; + break; + } + + s << " "; + + switch (_session->config.get_native_file_data_format ()) { + case FormatFloat: + s << "32-float"; + break; + case FormatInt24: + s << "24-int"; + break; + case FormatInt16: + s << "16-int"; + break; + } + + s << ""; + + format_label.set_markup (s.str ()); } void ARDOUR_UI::update_cpu_load () { - char buf[32]; - snprintf (buf, sizeof (buf), _("DSP: %5.1f%%"), engine->get_cpu_load()); - cpu_load_label.set_text (buf); + char buf[64]; + + /* If this text is changed, the set_size_request_to_display_given_text call in ARDOUR_UI::build_menu_bar + should also be changed. + */ + + float const c = engine->get_cpu_load (); + snprintf (buf, sizeof (buf), _("DSP: %5.1f%%"), c >= 90 ? X_("red") : X_("green"), c); + cpu_load_label.set_markup (buf); } void ARDOUR_UI::update_buffer_load () { - char buf[64]; - uint32_t c, p; + char buf[256]; + + uint32_t const playback = _session ? _session->playback_load () : 100; + uint32_t const capture = _session ? _session->capture_load () : 100; + /* If this text is changed, the set_size_request_to_display_given_text call in ARDOUR_UI::build_menu_bar + should also be changed. + */ + if (_session) { - c = _session->capture_load (); - p = _session->playback_load (); + snprintf ( + buf, sizeof (buf), + _("Buffers: p:%" PRIu32 "%% " + "c:%" PRIu32 "%%"), + playback <= 5 ? X_("red") : X_("green"), + playback, + capture <= 5 ? X_("red") : X_("green"), + capture + ); - snprintf (buf, sizeof (buf), _("Buffers p:%" PRIu32 "%% c:%" PRIu32 "%%"), - _session->playback_load(), _session->capture_load()); - buffer_load_label.set_text (buf); + buffer_load_label.set_markup (buf); } else { buffer_load_label.set_text (""); } @@ -1031,7 +1120,7 @@ ARDOUR_UI::update_disk_space() framecnt_t fr = _session->frame_rate(); if (frames == max_framecnt) { - strcpy (buf, _("Disk: 24hrs+")); + snprintf (buf, sizeof (buf), _("Disk: 24hrs+")); } else { rec_enabled_streams = 0; _session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams); @@ -1050,10 +1139,17 @@ ARDOUR_UI::update_disk_space() frames -= mins * fr * 60; secs = frames / fr; - snprintf (buf, sizeof(buf), _("Disk: %02dh:%02dm:%02ds"), hrs, mins, secs); + bool const low = (hrs == 0 && mins <= 30); + + snprintf ( + buf, sizeof(buf), + _("Disk: %02dh:%02dm:%02ds"), + low ? X_("red") : X_("green"), + hrs, mins, secs + ); } - disk_space_label.set_text (buf); + disk_space_label.set_markup (buf); // An attempt to make the disk space label flash red when space has run out. @@ -1265,9 +1361,10 @@ ARDOUR_UI::check_audioengine () { if (engine) { if (!engine->connected()) { - MessageDialog msg (string_compose (_("%1 is not connected to JACK\n" - "You cannot open or close sessions in this condition"), - PROGRAM_NAME)); + MessageDialog msg (string_compose ( + _("%1 is not connected to JACK\n" + "You cannot open or close sessions in this condition"), + PROGRAM_NAME)); pop_back_splash (); msg.run (); return false; @@ -1330,7 +1427,7 @@ ARDOUR_UI::open_session () void -ARDOUR_UI::session_add_midi_route (bool disk, RouteGroup* route_group, uint32_t how_many) +ARDOUR_UI::session_add_midi_route (bool disk, RouteGroup* route_group, uint32_t how_many, string const & name_template) { list > tracks; @@ -1342,7 +1439,7 @@ ARDOUR_UI::session_add_midi_route (bool disk, RouteGroup* route_group, uint32_t try { if (disk) { - tracks = _session->new_midi_track (ARDOUR::Normal, route_group, how_many); + tracks = _session->new_midi_track (ARDOUR::Normal, route_group, how_many, name_template); if (tracks.size() != how_many) { if (how_many == 1) { @@ -1370,7 +1467,15 @@ restart JACK with more ports."), PROGRAM_NAME)); void -ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t output_channels, ARDOUR::TrackMode mode, RouteGroup* route_group, uint32_t how_many) +ARDOUR_UI::session_add_audio_route ( + bool track, + int32_t input_channels, + int32_t output_channels, + ARDOUR::TrackMode mode, + RouteGroup* route_group, + uint32_t how_many, + string const & name_template + ) { list > tracks; RouteList routes; @@ -1382,7 +1487,7 @@ ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t try { if (track) { - tracks = _session->new_audio_track (input_channels, output_channels, mode, route_group, how_many); + tracks = _session->new_audio_track (input_channels, output_channels, mode, route_group, how_many, name_template); if (tracks.size() != how_many) { if (how_many == 1) { @@ -1395,13 +1500,13 @@ ARDOUR_UI::session_add_audio_route (bool track, int32_t input_channels, int32_t } else { - routes = _session->new_audio_route (input_channels, output_channels, route_group, how_many); + routes = _session->new_audio_route (input_channels, output_channels, route_group, how_many, name_template); if (routes.size() != how_many) { if (how_many == 1) { - error << _("could not create a new audio track") << endmsg; + error << _("could not create a new audio bus") << endmsg; } else { - error << string_compose (_("could not create %1 new audio tracks"), how_many) << endmsg; + error << string_compose (_("could not create %1 new audio busses"), how_many) << endmsg; } } } @@ -1577,7 +1682,7 @@ ARDOUR_UI::transport_record (bool roll) //cerr << "ARDOUR_UI::transport_record () called roll = " << roll << " _session->record_status() = " << _session->record_status() << endl; } -void +void ARDOUR_UI::transport_roll () { if (!_session) { @@ -1626,7 +1731,7 @@ ARDOUR_UI::transport_roll () void ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode) { - + if (!_session) { return; } @@ -1636,7 +1741,6 @@ ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode) return; } -#if 0 if (_session->config.get_external_sync()) { switch (_session->config.get_sync_source()) { case JACK: @@ -1646,7 +1750,6 @@ ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode) return; } } -#endif bool rolling = _session->transport_rolling(); bool affect_transport = true; @@ -1655,7 +1758,7 @@ ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode) /* drop out of loop/range playback but leave transport rolling */ if (_session->get_play_loop()) { if (Config->get_seamless_loop()) { - /* the disk buffers contain copies of the loop - we can't + /* the disk buffers contain copies of the loop - we can't just keep playing, so stop the transport. the user can restart as they wish. */ @@ -1668,8 +1771,8 @@ ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode) } else if (_session->get_play_range ()) { affect_transport = false; _session->request_play_range (0, true); - } - } + } + } if (affect_transport) { if (rolling) { @@ -1678,7 +1781,7 @@ ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode) if (join_play_range_button.get_active()) { _session->request_play_range (&editor->get_selection().time, true); } - + _session->request_transport_speed (1.0f); } } @@ -1690,25 +1793,25 @@ ARDOUR_UI::toggle_session_auto_loop () if (!_session) { return; } - + if (_session->get_play_loop()) { if (_session->transport_rolling()) { - + Location * looploc = _session->locations()->auto_loop_location(); - + if (looploc) { _session->request_locate (looploc->start(), true); _session->request_play_loop (false); } - + } else { _session->request_play_loop (false); } } else { - + Location * looploc = _session->locations()->auto_loop_location(); - + if (looploc) { _session->request_play_loop (true); } @@ -1805,8 +1908,6 @@ ARDOUR_UI::toggle_record_enable (uint32_t rid) void ARDOUR_UI::map_transport_state () { - ENSURE_GUI_THREAD (*this, &ARDOUR_UI::map_transport_state) - if (!_session) { auto_loop_button.set_visual_state (0); play_selection_button.set_visual_state (0); @@ -1815,18 +1916,11 @@ ARDOUR_UI::map_transport_state () return; } - float sp = _session->transport_speed(); + shuttle_box->map_transport_state (); - if (sp == 1.0f) { - shuttle_fract = SHUTTLE_FRACT_SPEED1; /* speed = 1.0, believe it or not */ - shuttle_box.queue_draw (); - } else if (sp == 0.0f) { - shuttle_fract = 0; - shuttle_box.queue_draw (); - update_disk_space (); - } + float sp = _session->transport_speed(); - if (sp != 0.0) { + if (sp != 0.0f) { /* we're rolling */ @@ -1837,13 +1931,13 @@ ARDOUR_UI::map_transport_state () auto_loop_button.set_visual_state (0); } else if (_session->get_play_loop ()) { - + auto_loop_button.set_visual_state (1); play_selection_button.set_visual_state (0); roll_button.set_visual_state (0); } else { - + roll_button.set_visual_state (1); play_selection_button.set_visual_state (0); auto_loop_button.set_visual_state (0); @@ -1863,6 +1957,7 @@ ARDOUR_UI::map_transport_state () roll_button.set_visual_state (0); play_selection_button.set_visual_state (0); auto_loop_button.set_visual_state (0); + update_disk_space (); } } @@ -2073,17 +2168,16 @@ ARDOUR_UI::snapshot_session (bool switch_to_it) prompter.set_name ("Prompter"); prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT); prompter.set_title (_("Take Snapshot")); - prompter.set_title (_("Take Snapshot")); prompter.set_prompt (_("Name of new snapshot")); if (!switch_to_it) { char timebuf[128]; time_t n; struct tm local_time; - + time (&n); localtime_r (&n, &local_time); - strftime (timebuf, sizeof(timebuf), "%FT%T", &local_time); + strftime (timebuf, sizeof(timebuf), "%FT%H.%M.%S", &local_time); prompter.set_initial_text (timebuf); } @@ -2108,6 +2202,12 @@ ARDOUR_UI::snapshot_session (bool switch_to_it) msg.run (); goto again; } + if (snapname.find (':') != string::npos) { + MessageDialog msg (_("To ensure compatibility with various systems\n" + "snapshot names may not contain a ':' character")); + msg.run (); + goto again; + } } vector p; @@ -2138,6 +2238,73 @@ ARDOUR_UI::snapshot_session (bool switch_to_it) } } +/** Ask the user for the name of a new shapshot and then take it. + */ + +void +ARDOUR_UI::rename_session () +{ + if (!_session) { + return; + } + + ArdourPrompter prompter (true); + string name; + + prompter.set_name ("Prompter"); + prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT); + prompter.set_title (_("Rename Session")); + prompter.set_prompt (_("New session name")); + + again: + switch (prompter.run()) { + case RESPONSE_ACCEPT: + { + prompter.get_result (name); + + bool do_rename = (name.length() != 0); + + if (do_rename) { + if (name.find ('/') != string::npos) { + MessageDialog msg (_("To ensure compatibility with various systems\n" + "session names may not contain a '/' character")); + msg.run (); + goto again; + } + if (name.find ('\\') != string::npos) { + MessageDialog msg (_("To ensure compatibility with various systems\n" + "session names may not contain a '\\' character")); + msg.run (); + goto again; + } + + switch (_session->rename (name)) { + case -1: { + MessageDialog msg (_("That name is already in use by another directory/folder. Please try again.")); + msg.set_position (WIN_POS_MOUSE); + msg.run (); + goto again; + break; + } + case 0: + break; + default: { + MessageDialog msg (_("Renaming this session failed.\nThings could be seriously messed up at this point")); + msg.set_position (WIN_POS_MOUSE); + msg.run (); + break; + } + } + } + + break; + } + + default: + break; + } +} + void ARDOUR_UI::save_state (const string & name, bool switch_to_it) { @@ -2149,8 +2316,10 @@ ARDOUR_UI::save_state (const string & name, bool switch_to_it) } } + node->add_child_nocopy (gui_object_state->get_state()); + _session->add_extra_xml (*node); - + save_state_canfail (name, switch_to_it); } @@ -2168,7 +2337,7 @@ ARDOUR_UI::save_state_canfail (string name, bool switch_to_it) return ret; } } - cerr << "SS canfail\n"; + save_ardour_state (); /* XXX cannot fail? yeah, right ... */ return 0; } @@ -2177,7 +2346,7 @@ void ARDOUR_UI::primary_clock_value_changed () { if (_session) { - _session->request_locate (primary_clock.current_time ()); + _session->request_locate (primary_clock->current_time ()); } } @@ -2185,7 +2354,7 @@ void ARDOUR_UI::big_clock_value_changed () { if (_session) { - _session->request_locate (big_clock.current_time ()); + _session->request_locate (big_clock->current_time ()); } } @@ -2193,7 +2362,7 @@ void ARDOUR_UI::secondary_clock_value_changed () { if (_session) { - _session->request_locate (secondary_clock.current_time ()); + _session->request_locate (secondary_clock->current_time ()); } } @@ -2235,8 +2404,8 @@ ARDOUR_UI::save_template () } prompter.set_name (X_("Prompter")); - prompter.set_title (_("Save Mix Template")); - prompter.set_prompt (_("Name for mix template:")); + prompter.set_title (_("Save Template")); + prompter.set_prompt (_("Name for template:")); prompter.set_initial_text(_session->name() + _("-template")); prompter.add_button (Gtk::Stock::SAVE, Gtk::RESPONSE_ACCEPT); @@ -2272,102 +2441,6 @@ ARDOUR_UI::import_metadata () dialog.run (); } -void -ARDOUR_UI::fontconfig_dialog () -{ -#ifdef GTKOSX - /* X11 users will always have fontconfig info around, but new GTK-OSX users - may not and it can take a while to build it. Warn them. - */ - - std::string fontconfig = Glib::build_filename (Glib::get_home_dir(), ".fontconfig"); - - if (!Glib::file_test (fontconfig, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_DIR)) { - MessageDialog msg (*_startup, - string_compose (_("Welcome to %1.\n\n" - "The program will take a bit longer to start up\n" - "while the system fonts are checked.\n\n" - "This will only be done once, and you will\n" - "not see this message again\n"), PROGRAM_NAME), - true, - Gtk::MESSAGE_INFO, - Gtk::BUTTONS_OK); - pop_back_splash (); - msg.show_all (); - msg.present (); - msg.run (); - } -#endif -} - -void -ARDOUR_UI::parse_cmdline_path (const std::string& cmdline_path, std::string& session_name, std::string& session_path, bool& existing_session) -{ - existing_session = false; - - if (Glib::file_test (cmdline_path, Glib::FILE_TEST_IS_DIR)) { - session_path = cmdline_path; - existing_session = true; - } else if (Glib::file_test (cmdline_path, Glib::FILE_TEST_IS_REGULAR)) { - session_path = Glib::path_get_dirname (string (cmdline_path)); - existing_session = true; - } else { - /* it doesn't exist, assume the best */ - session_path = Glib::path_get_dirname (string (cmdline_path)); - } - - session_name = basename_nosuffix (string (cmdline_path)); -} - -int -ARDOUR_UI::load_cmdline_session (const std::string& session_name, const std::string& session_path, bool& existing_session) -{ - /* when this is called, the backend audio system must be running */ - - /* the main idea here is to deal with the fact that a cmdline argument for the session - can be interpreted in different ways - it could be a directory or a file, and before - we load, we need to know both the session directory and the snapshot (statefile) within it - that we are supposed to use. - */ - - if (session_name.length() == 0 || session_path.length() == 0) { - return false; - } - - if (Glib::file_test (session_path, Glib::FILE_TEST_IS_DIR)) { - - std::string predicted_session_file; - - predicted_session_file = session_path; - predicted_session_file += '/'; - predicted_session_file += session_name; - predicted_session_file += ARDOUR::statefile_suffix; - - if (Glib::file_test (predicted_session_file, Glib::FILE_TEST_EXISTS)) { - existing_session = true; - } - - } else if (Glib::file_test (session_path, Glib::FILE_TEST_EXISTS)) { - - if (session_path.find (ARDOUR::statefile_suffix) == session_path.length() - 7) { - /* existing .ardour file */ - existing_session = true; - } - - } else { - existing_session = false; - } - - /* lets just try to load it */ - - if (create_engine ()) { - backend_audio_error (false, _startup); - return -1; - } - - return load_session (session_path, session_name); -} - bool ARDOUR_UI::ask_about_loading_existing_session (const std::string& session_path) { @@ -2424,7 +2497,7 @@ ARDOUR_UI::build_session_from_nsd (const std::string& session_path, const std::s } /// @todo some minor tweaks. - + bus_profile.output_ac = AutoConnectOption (0); if (_startup->connect_outputs ()) { @@ -2505,7 +2578,7 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri int ret = -1; bool likely_new = false; - if (! load_template.empty()) { + if (!load_template.empty()) { should_be_new = true; template_name = load_template; } @@ -2519,14 +2592,17 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri to find the session. */ - if (ARDOUR_COMMAND_LINE::session_name.find (statefile_suffix) != string::npos) { + string::size_type suffix = ARDOUR_COMMAND_LINE::session_name.find (statefile_suffix); + + if (suffix != string::npos) { session_path = Glib::path_get_dirname (ARDOUR_COMMAND_LINE::session_name); + session_name = ARDOUR_COMMAND_LINE::session_name.substr (0, suffix); + session_name = Glib::path_get_basename (session_name); } else { session_path = ARDOUR_COMMAND_LINE::session_name; + session_name = Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name); } - session_name = Glib::path_get_basename (ARDOUR_COMMAND_LINE::session_name); - } else { bool const apply = run_startup (should_be_new, load_template); @@ -2545,6 +2621,12 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri session_name = _startup->session_name (likely_new); + string::size_type suffix = session_name.find (statefile_suffix); + + if (suffix != string::npos) { + session_name = session_name.substr (0, suffix); + } + /* this shouldn't happen, but we catch it just in case it does */ if (session_name.empty()) { @@ -2563,7 +2645,7 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri /* absolute path or cwd-relative path specified for session name: infer session folder from what was given. */ - + session_path = Glib::path_get_dirname (session_name); session_name = Glib::path_get_basename (session_name); @@ -2572,16 +2654,18 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri session_path = _startup->session_folder(); if (session_name.find ('/') != string::npos) { - MessageDialog msg (*_startup, _("To ensure compatibility with various systems\n" - "session names may not contain a '/' character")); + MessageDialog msg (*_startup, + _("To ensure compatibility with various systems\n" + "session names may not contain a '/' character")); msg.run (); ARDOUR_COMMAND_LINE::session_name = ""; // cancel that continue; } - + if (session_name.find ('\\') != string::npos) { - MessageDialog msg (*_startup, _("To ensure compatibility with various systems\n" - "session names may not contain a '\\' character")); + MessageDialog msg (*_startup, + _("To ensure compatibility with various systems\n" + "session names may not contain a '\\' character")); msg.run (); ARDOUR_COMMAND_LINE::session_name = ""; // cancel that continue; @@ -2617,16 +2701,18 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri } if (session_name.find ('/') != std::string::npos) { - MessageDialog msg (*_startup, _("To ensure compatibility with various systems\n" - "session names may not contain a '/' character")); + MessageDialog msg (*_startup, + _("To ensure compatibility with various systems\n" + "session names may not contain a '/' character")); msg.run (); ARDOUR_COMMAND_LINE::session_name = ""; // cancel that continue; } if (session_name.find ('\\') != std::string::npos) { - MessageDialog msg (*_startup, _("To ensure compatibility with various systems\n" - "session names may not contain a '\\' character")); + MessageDialog msg (*_startup, + _("To ensure compatibility with various systems\n" + "session names may not contain a '\\' character")); msg.run (); ARDOUR_COMMAND_LINE::session_name = ""; // cancel that continue; @@ -2642,6 +2728,12 @@ ARDOUR_UI::get_session_parameters (bool quit_on_cancel, bool should_be_new, stri } else { ret = load_session (session_path, session_name, template_name); + + if (ret == -2) { + /* not connected to the AudioEngine, so quit to avoid an infinite loop */ + exit (1); + } + if (!ARDOUR_COMMAND_LINE::immediate_save.empty()) { _session->save_state (ARDOUR_COMMAND_LINE::immediate_save, false); exit (1); @@ -2672,6 +2764,9 @@ ARDOUR_UI::close_session() goto_editor_window (); } +/** @param snap_name Snapshot name (without .ardour suffix). + * @return -2 if the load failed because we are not connected to the AudioEngine. + */ int ARDOUR_UI::load_session (const std::string& path, const std::string& snap_name, std::string mix_template) { @@ -2682,7 +2777,7 @@ ARDOUR_UI::load_session (const std::string& path, const std::string& snap_name, session_loaded = false; if (!check_audioengine()) { - return -1; + return -2; } unload_status = unload_session (); @@ -2694,7 +2789,7 @@ ARDOUR_UI::load_session (const std::string& path, const std::string& snap_name, goto out; } - loading_message (string_compose (_("Please wait while %1loads your session"), PROGRAM_NAME)); + loading_message (string_compose (_("Please wait while %1 loads your session"), PROGRAM_NAME)); try { new_session = new Session (*engine, path, snap_name, 0, mix_template); @@ -2730,7 +2825,9 @@ ARDOUR_UI::load_session (const std::string& path, const std::string& snap_name, catch (...) { - MessageDialog msg (string_compose(_("Session \"%1 (snapshot %2)\" did not load successfully"),path, snap_name), + MessageDialog msg (string_compose( + _("Session \"%1 (snapshot %2)\" did not load successfully"), + path, snap_name), true, Gtk::MESSAGE_INFO, BUTTONS_OK); @@ -2837,8 +2934,11 @@ ARDOUR_UI::build_session (const std::string& path, const std::string& snap_name, } /* Put the playhead at 0 and scroll fully left */ - new_session->instant_xml(X_("Editor"))->add_property (X_("playhead"), X_("0")); - new_session->instant_xml(X_("Editor"))->add_property (X_("left-frame"), X_("0")); + n = new_session->instant_xml (X_("Editor")); + if (n) { + n->add_property (X_("playhead"), X_("0")); + n->add_property (X_("left-frame"), X_("0")); + } set_session (new_session); @@ -2934,10 +3034,11 @@ ARDOUR_UI::display_cleanup_results (ARDOUR::CleanupReport& rep, const gchar* lis if (removed == 0) { MessageDialog msgd (*editor, - _("No audio files were ready for cleanup"), + _("No files were ready for clean-up"), true, Gtk::MESSAGE_INFO, (Gtk::ButtonsType)(Gtk::BUTTONS_OK) ); + msgd.set_title (_("Clean-up")); msgd.set_secondary_text (_("If this seems suprising, \n\ check for any existing snapshots.\n\ These may still include regions that\n\ @@ -2981,11 +3082,11 @@ require some unused files to continue to exist.")); dimage->set_alignment(ALIGN_LEFT, ALIGN_TOP); - const string dead_sound_directory = _session->session_directory().dead_sound_path().to_string(); + const string dead_directory = _session->session_directory().dead_path().to_string(); /* subst: %1 - number of files removed - %2 - location of "dead_sounds" + %2 - location of "dead" %3 - size of files affected %4 - prefix for "bytes" to produce sensible results (e.g. mega, kilo, giga) */ @@ -2993,20 +3094,24 @@ require some unused files to continue to exist.")); const char* bprefix; double space_adjusted = 0; - if (rep.space < 100000.0f) { + if (rep.space < 1000) { + bprefix = X_(""); + space_adjusted = rep.space; + } else if (rep.space < 1000000) { bprefix = X_("kilo"); - } else if (rep.space < 1000000.0f * 1000) { - bprefix = X_("mega"); space_adjusted = truncf((float)rep.space / 1000.0); + } else if (rep.space < 1000000 * 1000) { + bprefix = X_("mega"); + space_adjusted = truncf((float)rep.space / (1000.0 * 1000.0)); } else { bprefix = X_("giga"); - space_adjusted = truncf((float)rep.space / (1000000.0 * 1000)); + space_adjusted = truncf((float)rep.space / (1000.0 * 1000 * 1000.0)); } if (removed > 1) { - txt.set_text (string_compose (plural_msg, removed, _session->path() + "dead_sounds", space_adjusted, bprefix)); + txt.set_text (string_compose (plural_msg, removed, dead_directory, space_adjusted, bprefix)); } else { - txt.set_text (string_compose (singular_msg, removed, _session->path() + "dead_sounds", space_adjusted, bprefix)); + txt.set_text (string_compose (singular_msg, removed, dead_directory, space_adjusted, bprefix)); } dhbox.pack_start (*dimage, true, false, 5); @@ -3055,18 +3160,19 @@ ARDOUR_UI::cleanup () } - MessageDialog checker (_("Are you sure you want to cleanup?"), + MessageDialog checker (_("Are you sure you want to clean-up?"), true, Gtk::MESSAGE_QUESTION, (Gtk::ButtonsType)(Gtk::BUTTONS_NONE)); - checker.set_secondary_text(_("Cleanup is a destructive operation.\n\ -ALL undo/redo information will be lost if you cleanup.\n\ -After cleanup, unused audio files will be moved to a \ -\"dead sounds\" location.")); + checker.set_title (_("Clean-up")); + + checker.set_secondary_text(_("Clean-up is a destructive operation.\n\ +ALL undo/redo information will be lost if you clean-up.\n\ +Clean-up will move all unused files to a \"dead\" location.")); checker.add_button (Stock::CANCEL, RESPONSE_CANCEL); - checker.add_button (_("Clean Up"), RESPONSE_ACCEPT); + checker.add_button (_("Clean-up"), RESPONSE_ACCEPT); checker.set_default_response (RESPONSE_CANCEL); checker.set_name (_("CleanupDialog")); @@ -3100,20 +3206,22 @@ After cleanup, unused audio files will be moved to a \ checker.hide(); display_cleanup_results (rep, - _("cleaned files"), + _("Cleaned Files"), _("\ The following %1 files were not in use and \n\ -have been moved to:\n\ -%2. \n\n\ -Flushing the wastebasket will \n\ -release an additional\n\ +have been moved to:\n\n\ +%2\n\n\ +After a restart of Ardour,\n\n\ +Session -> Clean-up -> Flush Wastebasket\n\n\ +will release an additional\n\ %3 %4bytes of disk space.\n"), _("\ -The following file was not in use and \n \ +The following file was not in use and \n\ has been moved to:\n \ -%2. \n\n\ -Flushing the wastebasket will \n\ -release an additional\n\ +%2\n\n\ +After a restart of Ardour,\n\n\ +Session -> Clean-up -> Flush Wastebasket\n\n\ +will release an additional\n\ %3 %4bytes of disk space.\n" )); @@ -3205,7 +3313,7 @@ ARDOUR_UI::add_route (Gtk::Window* float_window) if (add_route_dialog->type() == ARDOUR::DataType::MIDI) { if (track) { - session_add_midi_track (route_group, count); + session_add_midi_track (route_group, count, name_template); } else { MessageDialog msg (*editor, _("Sorry, MIDI Busses are not supported at this time.")); @@ -3214,9 +3322,9 @@ ARDOUR_UI::add_route (Gtk::Window* float_window) } } else { if (track) { - session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), route_group, count); + session_add_audio_track (input_chan, output_chan, add_route_dialog->mode(), route_group, count, name_template); } else { - session_add_audio_bus (input_chan, output_chan, route_group, count); + session_add_audio_bus (input_chan, output_chan, route_group, count, name_template); } } } @@ -3249,7 +3357,7 @@ ARDOUR_UI::editor_settings () const } else { node = Config->instant_xml(X_("Editor")); } - + if (!node) { if (getenv("ARDOUR_INSTANT_XML_PATH")) { node = Config->instant_xml(getenv("ARDOUR_INSTANT_XML_PATH")); @@ -3273,6 +3381,7 @@ ARDOUR_UI::keyboard_settings () const if (!node) { node = new XMLNode (X_("Keyboard")); } + return node; } @@ -3333,8 +3442,8 @@ ARDOUR_UI::disk_underrun_handler () if (!have_disk_speed_dialog_displayed) { have_disk_speed_dialog_displayed = true; - MessageDialog* msg = new MessageDialog (*editor, - string_compose (_("The disk system on your computer\n\ + MessageDialog* msg = new MessageDialog ( + *editor, string_compose (_("The disk system on your computer\n\ was not able to keep up with %1.\n\ \n\ Specifically, it failed to read data from disk\n\ @@ -3474,19 +3583,19 @@ void ARDOUR_UI::update_transport_clocks (framepos_t pos) { if (Config->get_primary_clock_delta_edit_cursor()) { - primary_clock.set (pos, false, editor->get_preferred_edit_position(), 1); + primary_clock->set (pos, false, editor->get_preferred_edit_position(), 1); } else { - primary_clock.set (pos, 0, true); + primary_clock->set (pos, 0, true); } if (Config->get_secondary_clock_delta_edit_cursor()) { - secondary_clock.set (pos, false, editor->get_preferred_edit_position(), 2); + secondary_clock->set (pos, false, editor->get_preferred_edit_position(), 2); } else { - secondary_clock.set (pos); + secondary_clock->set (pos); } if (big_clock_window->get()) { - big_clock.set (pos); + big_clock->set (pos); } } @@ -3520,9 +3629,9 @@ ARDOUR_UI::record_state_changed () bool const h = _session->have_rec_enabled_track (); if (r == Session::Recording && h) { - big_clock.set_widget_name ("BigClockRecording"); + big_clock->set_widget_name ("BigClockRecording"); } else { - big_clock.set_widget_name ("BigClockNonRecording"); + big_clock->set_widget_name ("BigClockNonRecording"); } } @@ -3547,15 +3656,19 @@ ARDOUR_UI::store_clock_modes () XMLNode* node = new XMLNode(X_("ClockModes")); for (vector::iterator x = AudioClock::clocks.begin(); x != AudioClock::clocks.end(); ++x) { - node->add_property ((*x)->name().c_str(), enum_2_string ((*x)->mode())); + XMLNode* child = new XMLNode (X_("Clock")); + + child->add_property (X_("name"), (*x)->name()); + child->add_property (X_("mode"), enum_2_string ((*x)->mode())); + child->add_property (X_("on"), ((*x)->off() ? X_("no") : X_("yes"))); + + node->add_child_nocopy (*child); } _session->add_extra_xml (*node); _session->set_dirty (); } - - ARDOUR_UI::TransportControllable::TransportControllable (std::string name, ARDOUR_UI& u, ToggleType tp) : Controllable (name), ui (u), type(tp) { @@ -3565,23 +3678,6 @@ ARDOUR_UI::TransportControllable::TransportControllable (std::string name, ARDOU void ARDOUR_UI::TransportControllable::set_value (double val) { - if (type == ShuttleControl) { - double fract; - - if (val == 0.5) { - fract = 0.0; - } else { - if (val < 0.5) { - fract = -((0.5 - val)/0.5); - } else { - fract = ((val - 0.5)/0.5); - } - } - - ui.set_shuttle_fract (fract); - return; - } - if (val < 0.5) { /* do nothing: these are radio-style actions */ return; @@ -3646,8 +3742,6 @@ ARDOUR_UI::TransportControllable::get_value (void) const break; case RecordEnable: break; - case ShuttleControl: - break; default: break; } @@ -3655,12 +3749,6 @@ ARDOUR_UI::TransportControllable::get_value (void) const return val; } -void -ARDOUR_UI::TransportControllable::set_id (const string& str) -{ - _id = str; -} - void ARDOUR_UI::setup_profile () { @@ -3679,16 +3767,16 @@ void ARDOUR_UI::toggle_translations () { using namespace Glib; - + RefPtr act = ActionManager::get_action (X_("Main"), X_("EnableTranslation")); if (act) { RefPtr ract = RefPtr::cast_dynamic (act); if (ract) { - + string i18n_killer = ARDOUR::translation_kill_path(); - + bool already_enabled = !ARDOUR::translations_are_disabled (); - + if (ract->get_active ()) { /* we don't care about errors */ int fd = ::open (i18n_killer.c_str(), O_RDONLY|O_CREAT, 0644); @@ -3697,7 +3785,7 @@ ARDOUR_UI::toggle_translations () /* we don't care about errors */ unlink (i18n_killer.c_str()); } - + if (already_enabled != ract->get_active()) { MessageDialog win (already_enabled ? _("Translations disabled") : _("Translations enabled"), false, @@ -3710,7 +3798,7 @@ ARDOUR_UI::toggle_translations () } } } -} +} /** Add a window proxy to our list, so that its state will be saved. * This call also causes the window to be created and opened if its @@ -3756,7 +3844,7 @@ ARDOUR_UI::missing_file (Session*s, std::string str, DataType type) } int -ARDOUR_UI::ambiguous_file (std::string file, std::string path, std::vector hits) +ARDOUR_UI::ambiguous_file (std::string file, std::string /*path*/, std::vector hits) { AmbiguousFileDialog dialog (file, hits); @@ -3766,3 +3854,17 @@ ARDOUR_UI::ambiguous_file (std::string file, std::string path, std::vectorget_buffers (); +} + +/** Drop our thread-local buffers */ +void +ARDOUR_UI::drop_process_buffers () +{ + _process_thread->drop_buffers (); +}