X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fardour_ui.cc;h=dce3fbfac88d66b355f41bd3448c70106c945539;hb=cd3c72bffe950bdaad46b4d4162e1904e0ca58c0;hp=95a97d2829fe6d8dc8a516bbd36ab53762a4b766;hpb=f85c320759e0fb8d95ea29982d6e3d94646b5de4;p=ardour.git diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 95a97d2829..dce3fbfac8 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -79,6 +79,7 @@ #include "widgets/fastmeter.h" #include "widgets/prompter.h" +#include "widgets/tooltips.h" #include "ardour/ardour.h" #include "ardour/audio_backend.h" @@ -86,10 +87,12 @@ #include "ardour/audioengine.h" #include "ardour/audiofilesource.h" #include "ardour/automation_watch.h" -#include "ardour/diskstream.h" +#include "ardour/disk_reader.h" +#include "ardour/disk_writer.h" #include "ardour/filename_extensions.h" #include "ardour/filesystem_paths.h" #include "ardour/ltc_file_reader.h" +#include "ardour/monitor_control.h" #include "ardour/midi_track.h" #include "ardour/port.h" #include "ardour/plugin_manager.h" @@ -103,7 +106,8 @@ #include "ardour/session_state_utils.h" #include "ardour/session_utils.h" #include "ardour/source_factory.h" -#include "ardour/slave.h" +#include "ardour/transport_master.h" +#include "ardour/transport_master_manager.h" #include "ardour/system_exec.h" #include "ardour/track.h" #include "ardour/vca_manager.h" @@ -123,7 +127,7 @@ #undef check #endif -#include "timecode/time.h" +#include "temporal/time.h" typedef uint64_t microseconds_t; @@ -137,6 +141,7 @@ typedef uint64_t microseconds_t; #include "audio_clock.h" #include "audio_region_view.h" #include "big_clock_window.h" +#include "big_transport_window.h" #include "bundle_manager.h" #include "duplicate_routes_dialog.h" #include "debug.h" @@ -163,12 +168,14 @@ typedef uint64_t microseconds_t; #include "nsm.h" #include "opts.h" #include "pingback.h" +#include "plugin_dspload_window.h" #include "processor_box.h" #include "public_editor.h" #include "rc_option_editor.h" #include "route_time_axis.h" #include "route_params_ui.h" #include "save_as_dialog.h" +#include "save_template_dialog.h" #include "script_selector.h" #include "session_archive_dialog.h" #include "session_dialog.h" @@ -181,6 +188,7 @@ typedef uint64_t microseconds_t; #include "time_axis_view_item.h" #include "time_info_box.h" #include "timers.h" +#include "transport_masters_dialog.h" #include "utils.h" #include "utils_videotl.h" #include "video_server_dialog.h" @@ -200,7 +208,7 @@ using namespace Editing; ARDOUR_UI *ARDOUR_UI::theArdourUI = 0; -sigc::signal ARDOUR_UI::Clock; +sigc::signal ARDOUR_UI::Clock; sigc::signal ARDOUR_UI::CloseAllDialogs; static bool @@ -265,14 +273,12 @@ libxml_structured_error_func (void* /* parsing_context*/, ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) : Gtkmm2ext::UI (PROGRAM_NAME, X_("gui"), argcp, argvp) - , session_loaded (false) , session_load_in_progress (false) , gui_object_state (new GUIObjectState) , primary_clock (new MainClock (X_("primary"), X_("transport"), true )) , secondary_clock (new MainClock (X_("secondary"), X_("secondary"), false)) , big_clock (new AudioClock (X_("bigclock"), false, "big", true, true, false, false)) , video_timeline(0) - , global_actions (X_("global")) , ignore_dual_punch (false) , main_window_visibility (0) , editor (0) @@ -281,15 +287,7 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) , _was_dirty (false) , _mixer_on_top (false) , _initial_verbose_plugin_scan (false) - , first_time_engine_run (true) , secondary_clock_spacer (0) - , 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)) , auto_input_button (ArdourButton::led_default_elements) , time_info_box (0) , auto_return_button (ArdourButton::led_default_elements) @@ -317,10 +315,13 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) , export_video_dialog (X_("video-export"), _("Video Export Dialog")) , lua_script_window (X_("script-manager"), _("Script Manager")) , idleometer (X_("idle-o-meter"), _("Idle'o'Meter")) + , plugin_dsp_load_window (X_("plugin-dsp-load"), _("Plugin DSP Load")) + , transport_masters_window (X_("transport-masters"), _("Transport Masters")) , session_option_editor (X_("session-options-editor"), _("Properties"), boost::bind (&ARDOUR_UI::create_session_option_editor, this)) , add_video_dialog (X_("add-video"), _("Add Video"), boost::bind (&ARDOUR_UI::create_add_video_dialog, this)) , bundle_manager (X_("bundle-manager"), _("Bundle Manager"), boost::bind (&ARDOUR_UI::create_bundle_manager, this)) , big_clock_window (X_("big-clock"), _("Big Clock"), boost::bind (&ARDOUR_UI::create_big_clock_window, this)) + , big_transport_window (X_("big-transport"), _("Transport Controls"), boost::bind (&ARDOUR_UI::create_big_transport_window, this)) , audio_port_matrix (X_("audio-connection-manager"), _("Audio Connections"), boost::bind (&ARDOUR_UI::create_global_port_matrix, this, ARDOUR::DataType::AUDIO)) , midi_port_matrix (X_("midi-connection-manager"), _("MIDI Connections"), boost::bind (&ARDOUR_UI::create_global_port_matrix, this, ARDOUR::DataType::MIDI)) , key_editor (X_("key-editor"), _("Keyboard Shortcuts"), boost::bind (&ARDOUR_UI::create_key_editor, this)) @@ -374,29 +375,40 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) xmlSetGenericErrorFunc (this, libxml_generic_error_func); xmlSetStructuredErrorFunc (this, libxml_structured_error_func); + /* Set this up early */ + + ActionManager::init (); + + /* we like keyboards */ + + keyboard = new ArdourKeyboard(*this); + + XMLNode* node = ARDOUR_UI::instance()->keyboard_settings(); + if (node) { + keyboard->set_state (*node, Stateful::loading_state_version); + } + + /* actions do not need to be defined when we load keybindings. They + * will be lazily discovered. But bindings do need to exist when we + * create windows/tabs with their own binding sets. + */ + + keyboard->setup_keybindings (); + + if ((global_bindings = Bindings::get_bindings (X_("Global"))) == 0) { + error << _("Global keybindings are missing") << endmsg; + } + + install_actions (); + UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &ARDOUR_UI::parameter_changed)); boost::function pc (boost::bind (&ARDOUR_UI::parameter_changed, this, _1)); UIConfiguration::instance().map_parameters (pc); - roll_button.set_controllable (roll_controllable); - stop_button.set_controllable (stop_controllable); - goto_start_button.set_controllable (goto_start_controllable); - goto_end_button.set_controllable (goto_end_controllable); - auto_loop_button.set_controllable (auto_loop_controllable); - play_selection_button.set_controllable (play_selection_controllable); - rec_button.set_controllable (rec_controllable); - - roll_button.set_name ("transport button"); - stop_button.set_name ("transport button"); - goto_start_button.set_name ("transport button"); - goto_end_button.set_name ("transport button"); - auto_loop_button.set_name ("transport button"); - play_selection_button.set_name ("transport button"); - rec_button.set_name ("transport recenable button"); - midi_panic_button.set_name ("transport button"); - - 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()); + transport_ctrl.setup (this); + + ARDOUR::DiskWriter::Overrun.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::disk_overrun_handler, this), gui_context()); + ARDOUR::DiskReader::Underrun.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::disk_underrun_handler, this), gui_context()); ARDOUR::Session::VersionMismatch.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::session_format_mismatch, this, _1, _2), gui_context()); @@ -452,23 +464,10 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) SessionEvent::create_per_thread_pool ("GUI", 4096); - /* we like keyboards */ - - keyboard = new ArdourKeyboard(*this); - - XMLNode* node = ARDOUR_UI::instance()->keyboard_settings(); - if (node) { - keyboard->set_state (*node, Stateful::loading_state_version); - } - UIConfiguration::instance().reset_dpi (); TimeAxisViewItem::set_constant_heights (); - /* Set this up so that our window proxies can register actions */ - - ActionManager::init (); - /* The following must happen after ARDOUR::init() so that Config is set up */ const XMLNode* ui_xml = Config->extra_xml (X_("UI")); @@ -484,11 +483,14 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) bundle_manager.set_state (*ui_xml, 0); location_ui.set_state (*ui_xml, 0); big_clock_window.set_state (*ui_xml, 0); + big_transport_window.set_state (*ui_xml, 0); audio_port_matrix.set_state (*ui_xml, 0); midi_port_matrix.set_state (*ui_xml, 0); export_video_dialog.set_state (*ui_xml, 0); lua_script_window.set_state (*ui_xml, 0); idleometer.set_state (*ui_xml, 0); + plugin_dsp_load_window.set_state (*ui_xml, 0); + transport_masters_window.set_state (*ui_xml, 0); } /* Separate windows */ @@ -506,9 +508,12 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir) WM::Manager::instance().register_window (&bundle_manager); WM::Manager::instance().register_window (&location_ui); WM::Manager::instance().register_window (&big_clock_window); + WM::Manager::instance().register_window (&big_transport_window); WM::Manager::instance().register_window (&audio_port_matrix); WM::Manager::instance().register_window (&midi_port_matrix); WM::Manager::instance().register_window (&idleometer); + WM::Manager::instance().register_window (&plugin_dsp_load_window); + WM::Manager::instance().register_window (&transport_masters_window); /* do not retain position for add route dialog */ add_route_dialog.set_state_mask (WindowProxy::Size); @@ -541,11 +546,12 @@ release software. So, a few guidelines:\n\ though it may be so, depending on your workflow.\n\ 2) Please wait for a helpful writeup of new features.\n\ 3) Please do NOT use the forums at ardour.org to report issues.\n\ -4) Please DO use the bugtracker at http://tracker.ardour.org/ to report issues\n\ - making sure to note the product version number as 5.0-pre.\n\ -5) Please DO use the ardour-users mailing list to discuss ideas and pass on comments.\n\ -6) Please DO join us on IRC for real time discussions about %1 %2. You\n\ +4) Please do NOT file bugs for this alpha-development versions at this point in time.\n\ + There is no bug triaging before the initial development concludes and\n\ + reporting issue for incomplete, ongoing work-in-progress is mostly useless.\n\ +5) Please DO join us on IRC for real time discussions about %1 %2. You\n\ can get there directly from within the program via the Help->Chat menu option.\n\ +6) Please DO submit patches for issues after discussing them on IRC.\n\ \n\ Full information on all the above can be found on the support page at\n\ \n\ @@ -571,7 +577,7 @@ ARDOUR_UI::create_global_port_matrix (ARDOUR::DataType type) void ARDOUR_UI::attach_to_engine () { - AudioEngine::instance()->Running.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::engine_running, this), gui_context()); + AudioEngine::instance()->Running.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::engine_running, this, _1), gui_context()); ARDOUR::Port::set_connecting_blocked (ARDOUR_COMMAND_LINE::no_connect_ports); } @@ -586,12 +592,10 @@ ARDOUR_UI::engine_stopped () } void -ARDOUR_UI::engine_running () +ARDOUR_UI::engine_running (uint32_t cnt) { - ENSURE_GUI_THREAD (*this, &ARDOUR_UI::engine_running) - if (first_time_engine_run) { + if (cnt == 0) { post_engine(); - first_time_engine_run = false; } if (_session) { @@ -599,7 +603,6 @@ ARDOUR_UI::engine_running () } update_disk_space (); update_cpu_load (); - update_xrun_count (); update_sample_rate (AudioEngine::instance()->sample_rate()); update_timecode_format (); update_peak_thread_work (); @@ -664,8 +667,6 @@ ARDOUR_UI::post_engine () } #endif - ARDOUR::init_post_engine (); - /* connect to important signals */ AudioEngine::instance()->Stopped.connect (forever_connections, MISSING_INVALIDATOR, boost::bind (&ARDOUR_UI::engine_stopped, this), gui_context()); @@ -678,6 +679,8 @@ ARDOUR_UI::post_engine () throw failed_constructor (); } + transport_ctrl.map_actions (); + /* Do this after setup_windows (), as that's when the _status_bar_visibility is created */ XMLNode* n = Config->extra_xml (X_("UI")); if (n) { @@ -762,13 +765,13 @@ ARDOUR_UI::post_engine () output << " Action NameMenu Name" << endl; output << " \n " << endl; - Gtkmm2ext::ActionMap::get_all_actions (paths, labels, tooltips, keys, actions); + ActionManager::get_all_actions (paths, labels, tooltips, keys, actions); vector::iterator p; vector::iterator l; for (p = paths.begin(), l = labels.begin(); p != paths.end(); ++p, ++l) { - output << " " << (*p).substr (9, string::npos); + output << " " << (*p).substr (10, string::npos); output << "" << *l << "" << endl; } output << " \n " << endl; @@ -780,7 +783,7 @@ ARDOUR_UI::post_engine () GError *err = NULL; gint fd; - if ((fd = g_file_open_tmp ("akprintXXXXXX.html", &file_name, &err)) < 0) { + if ((fd = g_file_open_tmp ("list-of-menu-actionsXXXXXX.html", &file_name, &err)) < 0) { if (err) { error << string_compose (_("Could not open temporary file to print bindings (%1)"), err->message) << endmsg; g_error_free (err); @@ -1105,7 +1108,7 @@ ARDOUR_UI::starting () * The wrapper startup script should set the environment variable 'ARDOUR_SELF' */ const char *process_name = g_getenv ("ARDOUR_SELF"); - nsm->announce (PROGRAM_NAME, ":dirty:", process_name ? process_name : "ardour4"); + nsm->announce (PROGRAM_NAME, ":dirty:", process_name ? process_name : "ardour6"); unsigned int i = 0; // wait for announce reply from nsm server @@ -1188,15 +1191,13 @@ ARDOUR_UI::starting () Searchpath ds (ARDOUR::ardour_data_search_path()); ds.add_subdirectory_to_paths ("sessions"); vector demos; - find_files_matching_pattern (demos, ds, "*.tar.xz"); + find_files_matching_pattern (demos, ds, ARDOUR::session_archive_suffix); ARDOUR::RecentSessions rs; ARDOUR::read_recent_sessions (rs); for (vector::iterator i = demos.begin(); i != demos.end (); ++i) { - /* "demo-session" must be inside "demo-session.tar.xz" - * strip ".tar.xz" - */ + /* "demo-session" must be inside "demo-session." */ std::string name = basename_nosuffix (basename_nosuffix (*i)); std::string path = Glib::build_filename (dspd, name); /* skip if session-dir already exists */ @@ -1524,8 +1525,6 @@ void ARDOUR_UI::every_second () { update_cpu_load (); - update_xrun_count (); - update_buffer_load (); update_disk_space (); update_timecode_format (); update_peak_thread_work (); @@ -1547,8 +1546,7 @@ ARDOUR_UI::every_second () void ARDOUR_UI::every_point_one_seconds () { - // TODO get rid of this.. - // ShuttleControl is updated directly via TransportStateChange signal + if (editor) editor->build_region_boundary_cache(); } void @@ -1579,7 +1577,7 @@ ARDOUR_UI::set_fps_timeout_connection () * signals to the GUI Thread.. */ interval = floor(500. /* update twice per FPS, since Glib::signal_timeout is very irregular */ - * _session->frame_rate() / _session->nominal_frame_rate() + * _session->sample_rate() / _session->nominal_sample_rate() / _session->timecode_frames_per_second() ); #ifdef PLATFORM_WINDOWS @@ -1599,19 +1597,19 @@ ARDOUR_UI::set_fps_timeout_connection () } void -ARDOUR_UI::update_sample_rate (framecnt_t) +ARDOUR_UI::update_sample_rate (samplecnt_t) { char buf[64]; ENSURE_GUI_THREAD (*this, &ARDOUR_UI::update_sample_rate, ignored) - if (!AudioEngine::instance()->connected()) { + if (!AudioEngine::instance()->running()) { snprintf (buf, sizeof (buf), "%s", _("Audio: none")); } else { - framecnt_t rate = AudioEngine::instance()->sample_rate(); + samplecnt_t rate = AudioEngine::instance()->sample_rate(); if (rate == 0) { /* no sample rate available */ @@ -1671,6 +1669,9 @@ ARDOUR_UI::update_format () case MBWF: s << _("MBWF"); break; + case FLAC: + s << _("FLAC"); + break; } s << " "; @@ -1693,40 +1694,33 @@ ARDOUR_UI::update_format () } void -ARDOUR_UI::update_xrun_count () +ARDOUR_UI::update_cpu_load () { - char buf[64]; + const unsigned int x = _session ? _session->get_xrun_count () : 0; + double const c = AudioEngine::instance()->get_dsp_load (); - /* If this text is changed, the set_size_request_to_display_given_text call in ARDOUR_UI::resize_text_widgets - should also be changed. - */ + const char* const bg = c > 90 ? " background=\"red\"" : ""; - if (_session) { - const unsigned int x = _session->get_xrun_count (); - if (x > 9999) { - snprintf (buf, sizeof (buf), _("X: >10K"), X_("red")); - } else { - snprintf (buf, sizeof (buf), _("X: %u"), x > 0 ? X_("red") : X_("green"), x); - } + char buf[64]; + if (x > 9999) { + snprintf (buf, sizeof (buf), "DSP: %.0f%% (>10k)", bg, c); + } else if (x > 0) { + snprintf (buf, sizeof (buf), "DSP: %.0f%% (%d)", bg, c, x); } else { - snprintf (buf, sizeof (buf), _("X: ?"), X_("yellow")); + snprintf (buf, sizeof (buf), "DSP: %.0f%%", bg, c); } - xrun_label.set_markup (buf); - set_tip (xrun_label, _("Audio dropouts. Shift+click to reset")); -} -void -ARDOUR_UI::update_cpu_load () -{ - char buf[64]; + dsp_load_label.set_markup (buf); - /* If this text is changed, the set_size_request_to_display_given_text call in ARDOUR_UI::resize_text_widgets - should also be changed. - */ + if (x > 9999) { + snprintf (buf, sizeof (buf), _("DSP: %.1f%% X: >10k\n%s"), c, _("Shift+Click to clear xruns.")); + } else if (x > 0) { + snprintf (buf, sizeof (buf), _("DSP: %.1f%% X: %u\n%s"), c, x, _("Shift+Click to clear xruns.")); + } else { + snprintf (buf, sizeof (buf), _("DSP: %.1f%%"), c); + } - double const c = AudioEngine::instance()->get_dsp_load (); - snprintf (buf, sizeof (buf), _("DSP: %5.1f%%"), c >= 90 ? X_("red") : X_("green"), c); - cpu_load_label.set_markup (buf); + ArdourWidgets::set_tooltip (dsp_load_label, buf); } void @@ -1743,100 +1737,81 @@ ARDOUR_UI::update_peak_thread_work () } void -ARDOUR_UI::update_buffer_load () +ARDOUR_UI::count_recenabled_streams (Route& route) { - 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::resize_text_widgets - should also be changed. - */ - - if (_session) { - snprintf ( - buf, sizeof (buf), - _("Buffers: p:%" PRIu32 "%% " - "c:%" PRIu32 "%%"), - playback <= 5 ? X_("red") : X_("green"), - playback, - capture <= 5 ? X_("red") : X_("green"), - capture - ); - - buffer_load_label.set_markup (buf); - } else { - buffer_load_label.set_text (""); + Track* track = dynamic_cast(&route); + if (track && track->rec_enable_control()->get_value()) { + rec_enabled_streams += track->n_inputs().n_total(); } } void -ARDOUR_UI::count_recenabled_streams (Route& route) +ARDOUR_UI::format_disk_space_label (float remain_sec) { - Track* track = dynamic_cast(&route); - if (track && track->rec_enable_control()->get_value()) { - rec_enabled_streams += track->n_inputs().n_total(); + if (remain_sec < 0) { + disk_space_label.set_text (_("N/A")); + ArdourWidgets::set_tooltip (disk_space_label, _("Unknown")); + return; } + + char buf[64]; + + int sec = floor (remain_sec); + int hrs = sec / 3600; + int mins = (sec / 60) % 60; + int secs = sec % 60; + snprintf (buf, sizeof(buf), _("%02dh:%02dm:%02ds"), hrs, mins, secs); + ArdourWidgets::set_tooltip (disk_space_label, buf); + + if (remain_sec > 86400) { + disk_space_label.set_text (_("Rec: >24h")); + return; + } else if (remain_sec > 32400 /* 9 hours */) { + snprintf (buf, sizeof (buf), "Rec: %.0fh", remain_sec / 3600.f); + } else if (remain_sec > 5940 /* 99 mins */) { + snprintf (buf, sizeof (buf), "Rec: %.1fh", remain_sec / 3600.f); + } else { + snprintf (buf, sizeof (buf), "Rec: %.0fm", remain_sec / 60.f); + } + disk_space_label.set_text (buf); + } void ARDOUR_UI::update_disk_space() { if (_session == 0) { + format_disk_space_label (-1); return; } - boost::optional opt_frames = _session->available_capture_duration(); - char buf[64]; - framecnt_t fr = _session->frame_rate(); + boost::optional opt_samples = _session->available_capture_duration(); + samplecnt_t fr = _session->sample_rate(); if (fr == 0) { /* skip update - no SR available */ + format_disk_space_label (-1); return; } - if (!opt_frames) { + if (!opt_samples) { /* Available space is unknown */ - snprintf (buf, sizeof (buf), "%s", _("Disk: Unknown")); - } else if (opt_frames.get_value_or (0) == max_framecnt) { - snprintf (buf, sizeof (buf), "%s", _("Disk: 24hrs+")); + format_disk_space_label (-1); + } else if (opt_samples.get_value_or (0) == max_samplecnt) { + format_disk_space_label (max_samplecnt); } else { rec_enabled_streams = 0; _session->foreach_route (this, &ARDOUR_UI::count_recenabled_streams, false); - framecnt_t frames = opt_frames.get_value_or (0); + samplecnt_t samples = opt_samples.get_value_or (0); if (rec_enabled_streams) { - frames /= rec_enabled_streams; + samples /= rec_enabled_streams; } - int hrs; - int mins; - int secs; - - hrs = frames / (fr * 3600); - - if (hrs > 24) { - snprintf (buf, sizeof (buf), "%s", _("Disk: >24 hrs")); - } else { - frames -= hrs * fr * 3600; - mins = frames / (fr * 60); - frames -= mins * fr * 60; - secs = frames / fr; - - bool const low = (hrs == 0 && mins <= 30); - - snprintf ( - buf, sizeof(buf), - _("Disk: %02dh:%02dm:%02ds"), - low ? X_("red") : X_("green"), - hrs, mins, secs - ); - } + format_disk_space_label (samples / (float)fr); } - disk_space_label.set_markup (buf); } void @@ -1846,11 +1821,11 @@ ARDOUR_UI::update_timecode_format () if (_session) { bool matching; - TimecodeSlave* tcslave; - SyncSource sync_src = Config->get_sync_source(); + boost::shared_ptr tcmaster; + boost::shared_ptr tm = TransportMasterManager::instance().current(); - if ((sync_src == LTC || sync_src == MTC) && (tcslave = dynamic_cast(_session->slave())) != 0) { - matching = (tcslave->apparent_timecode_format() == _session->config.get_timecode_format()); + if ((tm->type() == LTC || tm->type() == MTC) && (tcmaster = boost::dynamic_pointer_cast(tm)) != 0) { + matching = (tcmaster->apparent_timecode_format() == _session->config.get_timecode_format()); } else { matching = true; } @@ -1931,7 +1906,7 @@ ARDOUR_UI::open_recent_session () bool ARDOUR_UI::check_audioengine (Gtk::Window& parent) { - if (!AudioEngine::instance()->connected()) { + if (!AudioEngine::instance()->running()) { MessageDialog msg (parent, string_compose ( _("%1 is not connected to any audio backend.\n" "You cannot open or close sessions in this condition"), @@ -1969,7 +1944,7 @@ ARDOUR_UI::open_session () string default_session_folder = Config->get_default_session_parent_dir(); open_session_selector.add_shortcut_folder (default_session_folder); } - catch (Glib::Error & e) { + catch (Glib::Error const& e) { std::cerr << "open_session_selector.add_shortcut_folder() threw Glib::Error " << e.what() << std::endl; } @@ -1979,7 +1954,7 @@ ARDOUR_UI::open_session () open_session_selector.add_filter (session_filter); FileFilter archive_filter; - archive_filter.add_pattern (X_("*.tar.xz")); + archive_filter.add_pattern (string_compose(X_("*%1"), ARDOUR::session_archive_suffix)); archive_filter.set_name (_("Session Archives")); open_session_selector.add_filter (archive_filter); @@ -2155,6 +2130,32 @@ ARDOUR_UI::session_add_audio_route ( } } +void +ARDOUR_UI::session_add_foldback_bus (uint32_t how_many, string const & name_template) +{ + RouteList routes; + + assert (_session); + + try { + routes = _session->new_audio_route (2, 2, 0, how_many, name_template, PresentationInfo::FoldbackBus, -1); + + if (routes.size() != how_many) { + error << string_compose (P_("could not create %1 new foldback bus", "could not create %1 new foldback busses", how_many), how_many) + << endmsg; + } + } + + catch (...) { + display_insufficient_ports_message (); + return; + } + + for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) { + (*i)->set_strict_io (true); + } +} + void ARDOUR_UI::display_insufficient_ports_message () { @@ -2178,7 +2179,7 @@ ARDOUR_UI::transport_goto_start () */ if (editor) { - editor->center_screen (_session->current_start_frame ()); + editor->center_screen (_session->current_start_sample ()); } } } @@ -2206,30 +2207,30 @@ ARDOUR_UI::transport_goto_wallclock () time_t now; struct tm tmnow; - framepos_t frames; + samplepos_t samples; time (&now); localtime_r (&now, &tmnow); - framecnt_t frame_rate = _session->frame_rate(); + samplecnt_t sample_rate = _session->sample_rate(); - if (frame_rate == 0) { + if (sample_rate == 0) { /* no frame rate available */ return; } - frames = tmnow.tm_hour * (60 * 60 * frame_rate); - frames += tmnow.tm_min * (60 * frame_rate); - frames += tmnow.tm_sec * frame_rate; + samples = tmnow.tm_hour * (60 * 60 * sample_rate); + samples += tmnow.tm_min * (60 * sample_rate); + samples += tmnow.tm_sec * sample_rate; - _session->request_locate (frames, _session->transport_rolling ()); + _session->request_locate (samples, _session->transport_rolling ()); /* force displayed area in editor to start no matter what "follow playhead" setting is. */ if (editor) { - editor->center_screen (frames); + editor->center_screen (samples); } } } @@ -2238,15 +2239,15 @@ void ARDOUR_UI::transport_goto_end () { if (_session) { - framepos_t const frame = _session->current_end_frame(); - _session->request_locate (frame); + samplepos_t const sample = _session->current_end_sample(); + _session->request_locate (sample); /* force displayed area in editor to start no matter what "follow playhead" setting is. */ if (editor) { - editor->center_screen (frame); + editor->center_screen (sample); } } } @@ -2340,9 +2341,8 @@ ARDOUR_UI::transport_roll () return; } -#if 0 if (_session->config.get_external_sync()) { - switch (Config->get_sync_source()) { + switch (TransportMasterManager::instance().current()->type()) { case Engine: break; default: @@ -2350,7 +2350,6 @@ ARDOUR_UI::transport_roll () return; } } -#endif bool rolling = _session->transport_rolling(); @@ -2404,7 +2403,7 @@ ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode) } if (_session->config.get_external_sync()) { - switch (Config->get_sync_source()) { + switch (TransportMasterManager::instance().current()->type()) { case Engine: break; default: @@ -2459,9 +2458,9 @@ ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode) * want to do this. */ - if (UIConfiguration::instance().get_follow_edits() && ( editor->get_selection().time.front().start == _session->transport_frame() ) ) { //if playhead is exactly at the start of a range, we can assume it was placed there by follow_edits + if (UIConfiguration::instance().get_follow_edits() && ( editor->get_selection().time.front().start == _session->transport_sample() ) ) { //if playhead is exactly at the start of a range, we can assume it was placed there by follow_edits _session->request_play_range (&editor->get_selection().time, true); - _session->set_requested_return_frame( editor->get_selection().time.front().start ); //force an auto-return here + _session->set_requested_return_sample( editor->get_selection().time.front().start ); //force an auto-return here } _session->request_transport_speed (1.0f); } @@ -2620,10 +2619,6 @@ void ARDOUR_UI::map_transport_state () { if (!_session) { - auto_loop_button.unset_active_state (); - play_selection_button.unset_active_state (); - roll_button.unset_active_state (); - stop_button.set_active_state (Gtkmm2ext::ExplicitActive); layered_button.set_sensitive (false); return; } @@ -2633,52 +2628,9 @@ ARDOUR_UI::map_transport_state () float sp = _session->transport_speed(); if (sp != 0.0f) { - - /* we're rolling */ - - if (_session->get_play_range()) { - - play_selection_button.set_active_state (Gtkmm2ext::ExplicitActive); - roll_button.unset_active_state (); - auto_loop_button.unset_active_state (); - - } else if (_session->get_play_loop ()) { - - auto_loop_button.set_active (true); - play_selection_button.set_active (false); - if (Config->get_loop_is_mode()) { - roll_button.set_active (true); - } else { - roll_button.set_active (false); - } - - } else { - - roll_button.set_active (true); - play_selection_button.set_active (false); - auto_loop_button.set_active (false); - } - - if (UIConfiguration::instance().get_follow_edits() && !_session->config.get_external_sync()) { - /* light up both roll and play-selection if they are joined */ - roll_button.set_active (true); - play_selection_button.set_active (true); - } layered_button.set_sensitive (!_session->actively_recording ()); - - stop_button.set_active (false); - } else { - layered_button.set_sensitive (true); - stop_button.set_active (true); - roll_button.set_active (false); - play_selection_button.set_active (false); - if (Config->get_loop_is_mode ()) { - auto_loop_button.set_active (_session->get_play_loop()); - } else { - auto_loop_button.set_active (false); - } update_disk_space (); } } @@ -2686,7 +2638,6 @@ ARDOUR_UI::map_transport_state () void ARDOUR_UI::blink_handler (bool blink_on) { - transport_rec_enable_blink (blink_on); sync_blink (blink_on); if (!UIConfiguration::instance().get_blink_alert_indicators()) { @@ -2704,7 +2655,7 @@ ARDOUR_UI::update_clocks () if (!_session) return; if (editor && !editor->dragging_playhead()) { - Clock (_session->audible_frame(), false, editor->get_preferred_edit_position (EDIT_IGNORE_PHEAD)); /* EMIT_SIGNAL */ + Clock (_session->audible_sample()); /* EMIT_SIGNAL */ } } @@ -2764,13 +2715,13 @@ ARDOUR_UI::save_session_as () MessageDialog msg (_main_window, string_compose (_("\ %1 was unable to save your session.\n\n\ -If you still wish to proceeed, please use the\n\n\ +If you still wish to proceed, please use the\n\n\ \"Don't save now\" option."), PROGRAM_NAME)); pop_back_splash(msg); msg.run (); return; } - // no break + /* fall through */ case 0: _session->remove_pending_capture_state (); break; @@ -2875,7 +2826,7 @@ ARDOUR_UI::archive_session () return; } - if (_session->archive_session (sad.target_folder(), sad.name(), sad.encode_option (), sad.only_used_sources (), &sad)) { + if (_session->archive_session (sad.target_folder(), sad.name(), sad.encode_option (), sad.compression_level (), sad.only_used_sources (), &sad)) { MessageDialog msg (_("Session Archiving failed.")); msg.run (); } @@ -2960,13 +2911,13 @@ ARDOUR_UI::snapshot_session (bool switch_to_it) MessageDialog msg (_main_window, string_compose (_("\ %1 was unable to save your session.\n\n\ -If you still wish to proceeed, please use the\n\n\ +If you still wish to proceed, please use the\n\n\ \"Don't save now\" option."), PROGRAM_NAME)); pop_back_splash(msg); msg.run (); return; } - // no break + /* fall through */ case 0: _session->remove_pending_capture_state (); break; @@ -3130,88 +3081,43 @@ ARDOUR_UI::secondary_clock_value_changed () _session->request_locate (secondary_clock->current_time ()); } } - void -ARDOUR_UI::transport_rec_enable_blink (bool onoff) +ARDOUR_UI::save_template_dialog_response (int response, SaveTemplateDialog* d) { - if (_session == 0) { - return; - } - - if (_session->step_editing()) { - return; - } + if (response == RESPONSE_ACCEPT) { + const string name = d->get_template_name (); + const string desc = d->get_description (); - Session::RecordState const r = _session->record_status (); - bool const h = _session->have_rec_enabled_track (); - - if (r == Session::Enabled || (r == Session::Recording && !h)) { - if (onoff) { - rec_button.set_active_state (Gtkmm2ext::ExplicitActive); - } else { - rec_button.set_active_state (Gtkmm2ext::Off); - } - } else if (r == Session::Recording && h) { - rec_button.set_active_state (Gtkmm2ext::ExplicitActive); - } else { - rec_button.unset_active_state (); - } -} - -bool -ARDOUR_UI::process_save_template_prompter (Prompter& prompter) -{ - string name; - - prompter.get_result (name); - - if (name.length()) { - int failed = _session->save_template (name); + int failed = _session->save_template (name, desc); if (failed == -2) { /* file already exists. */ - bool overwrite = overwrite_file_dialog (prompter, + bool overwrite = overwrite_file_dialog (*d, _("Confirm Template Overwrite"), _("A template already exists with that name. Do you want to overwrite it?")); if (overwrite) { - _session->save_template (name, true); + _session->save_template (name, desc, true); } else { - return false; + d->show (); + return; } } } - - return true; + delete d; } void ARDOUR_UI::save_template () { - Prompter prompter (true); - if (!check_audioengine (_main_window)) { return; } - prompter.set_name (X_("Prompter")); - 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); - - bool finished = false; - while (!finished) { - switch (prompter.run()) { - case RESPONSE_ACCEPT: - finished = process_save_template_prompter (prompter); - break; - - default: - finished = true; - break; - } - } + const std::string desc = SessionMetadata::Metadata()->description (); + SaveTemplateDialog* d = new SaveTemplateDialog (_session->name (), desc); + d->signal_response().connect (sigc::bind (sigc::mem_fun (*this, &ARDOUR_UI::save_template_dialog_response), d)); + d->show (); } void ARDOUR_UI::manage_templates () @@ -3649,8 +3555,6 @@ ARDOUR_UI::load_session (const std::string& path, const std::string& snap_name, } } - session_loaded = false; - loading_message (string_compose (_("Please wait while %1 loads your session"), PROGRAM_NAME)); try { @@ -3659,7 +3563,7 @@ ARDOUR_UI::load_session (const std::string& path, const std::string& snap_name, /* this one is special */ - catch (AudioEngine::PortRegistrationFailure& err) { + catch (AudioEngine::PortRegistrationFailure const& err) { MessageDialog msg (err.what(), true, @@ -3684,7 +3588,7 @@ ARDOUR_UI::load_session (const std::string& path, const std::string& snap_name, } goto out; } - catch (SessionException e) { + catch (SessionException const& e) { MessageDialog msg (string_compose( _("Session \"%1 (snapshot %2)\" did not load successfully:\n%3"), path, snap_name, e.what()), @@ -3760,8 +3664,6 @@ ARDOUR_UI::load_session (const std::string& path, const std::string& snap_name, set_session (new_session); - session_loaded = true; - if (_session) { _session->set_clean (); } @@ -3805,7 +3707,6 @@ ARDOUR_UI::build_session (const std::string& path, const std::string& snap_name, Session *new_session; int x; - session_loaded = false; x = unload_session (); if (x < 0) { @@ -3820,7 +3721,7 @@ ARDOUR_UI::build_session (const std::string& path, const std::string& snap_name, new_session = new Session (*AudioEngine::instance(), path, snap_name, bus_profile); } - catch (SessionException e) { + catch (SessionException const& e) { cerr << "Here are the errors associated with this failed session:\n"; dump_errors (cerr); cerr << "---------\n"; @@ -3870,8 +3771,6 @@ ARDOUR_UI::build_session (const std::string& path, const std::string& snap_name, set_session (new_session); - session_loaded = true; - new_session->save_state(new_session->name()); return 0; @@ -3885,6 +3784,101 @@ static void _lua_print (std::string s) { PBD::info << "LuaInstance: " << s << endmsg; } +std::map +ARDOUR_UI::route_setup_info (const std::string& script_path) +{ + std::map rv; + + if (!Glib::file_test (script_path, Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_REGULAR)) { + return rv; + } + + LuaState lua; + lua.Print.connect (&_lua_print); + lua.sandbox (true); + + lua_State* L = lua.getState(); + LuaInstance::register_classes (L); + LuaBindings::set_session (L, _session); + luabridge::push (L, &PublicEditor::instance()); + lua_setglobal (L, "Editor"); + + lua.do_command ("function ardour () end"); + lua.do_file (script_path); + + try { + luabridge::LuaRef fn = luabridge::getGlobal (L, "route_setup"); + if (!fn.isFunction ()) { + return rv; + } + luabridge::LuaRef rs = fn (); + if (!rs.isTable ()) { + return rv; + } + for (luabridge::Iterator i(rs); !i.isNil (); ++i) { + if (!i.key().isString()) { + continue; + } + std::string key = i.key().tostring(); + if (i.value().isString() || i.value().isNumber() || i.value().isBoolean()) { + rv[key] = i.value().tostring(); + } + } + } catch (luabridge::LuaException const& e) { + cerr << "LuaException:" << e.what () << endl; + } catch (...) { } + return rv; +} + +void +ARDOUR_UI::meta_route_setup (const std::string& script_path) +{ + if (!Glib::file_test (script_path, Glib::FILE_TEST_EXISTS | Glib::FILE_TEST_IS_REGULAR)) { + return; + } + assert (add_route_dialog); + + int count; + if ((count = add_route_dialog->count()) <= 0) { + return; + } + + LuaState lua; + lua.Print.connect (&_lua_print); + lua.sandbox (true); + + lua_State* L = lua.getState(); + LuaInstance::register_classes (L); + LuaBindings::set_session (L, _session); + luabridge::push (L, &PublicEditor::instance()); + lua_setglobal (L, "Editor"); + + lua.do_command ("function ardour () end"); + lua.do_file (script_path); + + luabridge::LuaRef args (luabridge::newTable (L)); + + args["name"] = add_route_dialog->name_template (); + args["insert_at"] = translate_order (add_route_dialog->insert_at()); + args["group"] = add_route_dialog->route_group (); + args["strict_io"] = add_route_dialog->use_strict_io (); + args["instrument"] = add_route_dialog->requested_instrument (); + args["track_mode"] = add_route_dialog->mode (); + args["channels"] = add_route_dialog->channel_count (); + args["how_many"] = count; + + try { + luabridge::LuaRef fn = luabridge::getGlobal (L, "factory"); + if (fn.isFunction()) { + fn (args)(); + } + } catch (luabridge::LuaException const& e) { + cerr << "LuaException:" << e.what () << endl; + } catch (...) { + display_insufficient_ports_message (); + } +} + void ARDOUR_UI::meta_session_setup (const std::string& script_path) { @@ -3906,12 +3900,14 @@ ARDOUR_UI::meta_session_setup (const std::string& script_path) lua.do_file (script_path); try { - luabridge::LuaRef fn = luabridge::getGlobal (L, "session_setup"); + luabridge::LuaRef fn = luabridge::getGlobal (L, "factory"); if (fn.isFunction()) { - fn (); + fn ()(); } } catch (luabridge::LuaException const& e) { cerr << "LuaException:" << e.what () << endl; + } catch (...) { + display_insufficient_ports_message (); } } @@ -3925,13 +3921,7 @@ ARDOUR_UI::launch_chat () switch (dialog.run()) { case RESPONSE_OK: -#ifdef __APPLE__ - open_uri("http://webchat.freenode.net/?channels=ardour-osx"); -#elif defined PLATFORM_WINDOWS - open_uri("http://webchat.freenode.net/?channels=ardour-windows"); -#else open_uri("http://webchat.freenode.net/?channels=ardour"); -#endif break; default: break; @@ -4263,7 +4253,7 @@ ARDOUR_UI::cleanup_peakfiles () RegionSelection rs; TrackViewList empty; empty.clear(); - editor->get_regions_after(rs, (framepos_t) 0, empty); + editor->get_regions_after(rs, (samplepos_t) 0, empty); std::list views = rs.by_layer(); // remove displayed audio-region-views waveforms @@ -4364,10 +4354,24 @@ ARDOUR_UI::add_route_dialog_response (int r) return; } + if (!AudioEngine::instance()->running ()) { + switch (r) { + case AddRouteDialog::Add: + case AddRouteDialog::AddAndClose: + break; + default: + return; + } + add_route_dialog->ArdourDialog::on_response (r); + ARDOUR_UI_UTILS::engine_is_running (); + return; + } + int count; switch (r) { case AddRouteDialog::Add: + add_route_dialog->reset_name_edited (); break; case AddRouteDialog::AddAndClose: add_route_dialog->ArdourDialog::on_response (r); @@ -4379,7 +4383,7 @@ ARDOUR_UI::add_route_dialog_response (int r) std::string template_path = add_route_dialog->get_template_path(); if (!template_path.empty() && template_path.substr (0, 11) == "urn:ardour:") { - meta_session_setup (template_path.substr (11)); + meta_route_setup (template_path.substr (11)); return; } @@ -4437,6 +4441,9 @@ ARDOUR_UI::add_route_dialog_response (int r) case AddRouteDialog::VCAMaster: _session->vca_manager().create_vca (count, name_template); break; + case AddRouteDialog::FoldbackBus: + session_add_foldback_bus (count, name_template); + break; } } @@ -4711,10 +4718,10 @@ ARDOUR_UI::add_video (Gtk::Window* float_window) LTCFileReader ltcr (audio_from_video, video_timeline->get_video_file_fps()); /* TODO ASK user which channel: 0 .. ltcr->channels() - 1 */ - ltc_seq = ltcr.read_ltc (/*channel*/ 0, /*max LTC frames to decode*/ 15); + ltc_seq = ltcr.read_ltc (/*channel*/ 0, /*max LTC samples to decode*/ 15); /* TODO seek near end of file, and read LTC until end. - * if it fails to find any LTC frames, scan complete file + * if it fails to find any LTC samples, scan complete file * * calculate drift of LTC compared to video-duration, * ask user for reference (timecode from start/mid/end) @@ -4730,16 +4737,16 @@ ARDOUR_UI::add_video (Gtk::Window* float_window) } else { /* the very first TC in the file is somteimes not aligned properly */ int i = ltc_seq.size() -1; - ARDOUR::frameoffset_t video_start_offset = - _session->nominal_frame_rate() * (ltc_seq[i].timecode_sec - ltc_seq[i].framepos_sec); + ARDOUR::sampleoffset_t video_start_offset = + _session->nominal_sample_rate() * (ltc_seq[i].timecode_sec - ltc_seq[i].framepos_sec); PBD::info << string_compose (_("Align video-start to %1 [samples]"), video_start_offset) << endmsg; video_timeline->set_offset(video_start_offset); } } _session->maybe_update_session_range( - std::max(video_timeline->get_offset(), (ARDOUR::frameoffset_t) 0), - std::max(video_timeline->get_offset() + video_timeline->get_duration(), (ARDOUR::frameoffset_t) 0)); + std::max(video_timeline->get_offset(), (ARDOUR::sampleoffset_t) 0), + std::max(video_timeline->get_offset() + video_timeline->get_duration(), (ARDOUR::sampleoffset_t) 0)); if (add_video_dialog->launch_xjadeo() && local_file) { @@ -4905,7 +4912,7 @@ ARDOUR_UI::keyboard_settings () const } void -ARDOUR_UI::create_xrun_marker (framepos_t where) +ARDOUR_UI::create_xrun_marker (samplepos_t where) { if (_session) { Location *location = new Location (*_session, where, where, _("xrun"), Location::IsMark, 0); @@ -4922,7 +4929,7 @@ ARDOUR_UI::halt_on_xrun_message () } void -ARDOUR_UI::xrun_handler (framepos_t where) +ARDOUR_UI::xrun_handler (samplepos_t where) { if (!_session) { return; @@ -5146,7 +5153,7 @@ what you would like to do.\n"), PROGRAM_NAME)); } int -ARDOUR_UI::sr_mismatch_dialog (framecnt_t desired, framecnt_t actual) +ARDOUR_UI::sr_mismatch_dialog (samplecnt_t desired, samplecnt_t actual) { HBox* hbox = new HBox(); Image* image = new Image (Stock::DIALOG_WARNING, ICON_SIZE_DIALOG); @@ -5179,7 +5186,7 @@ audio may be played at the wrong sample rate.\n"), desired, PROGRAM_NAME, actual } void -ARDOUR_UI::sr_mismatch_message (framecnt_t desired, framecnt_t actual) +ARDOUR_UI::sr_mismatch_message (samplecnt_t desired, samplecnt_t actual) { MessageDialog msg (string_compose (_("\ This session was created with a sample rate of %1 Hz, but\n\ @@ -5203,18 +5210,36 @@ ARDOUR_UI::use_config () } void -ARDOUR_UI::update_transport_clocks (framepos_t pos) +ARDOUR_UI::update_transport_clocks (samplepos_t pos) { - if (UIConfiguration::instance().get_primary_clock_delta_edit_cursor()) { - primary_clock->set (pos, false, editor->get_preferred_edit_position (EDIT_IGNORE_PHEAD)); - } else { - primary_clock->set (pos); + switch (UIConfiguration::instance().get_primary_clock_delta_mode()) { + case NoDelta: + primary_clock->set (pos); + break; + case DeltaEditPoint: + primary_clock->set (pos, false, editor->get_preferred_edit_position (EDIT_IGNORE_PHEAD)); + break; + case DeltaOriginMarker: + { + Location* loc = _session->locations()->clock_origin_location (); + primary_clock->set (pos, false, loc ? loc->start() : 0); + } + break; } - if (UIConfiguration::instance().get_secondary_clock_delta_edit_cursor()) { - secondary_clock->set (pos, false, editor->get_preferred_edit_position (EDIT_IGNORE_PHEAD)); - } else { - secondary_clock->set (pos); + switch (UIConfiguration::instance().get_secondary_clock_delta_mode()) { + case NoDelta: + secondary_clock->set (pos); + break; + case DeltaEditPoint: + secondary_clock->set (pos, false, editor->get_preferred_edit_position (EDIT_IGNORE_PHEAD)); + break; + case DeltaOriginMarker: + { + Location* loc = _session->locations()->clock_origin_location (); + secondary_clock->set (pos, false, loc ? loc->start() : 0); + } + break; } if (big_clock_window) { @@ -5223,20 +5248,6 @@ ARDOUR_UI::update_transport_clocks (framepos_t pos) ARDOUR_UI::instance()->video_timeline->manual_seek_video_monitor(pos); } -void -ARDOUR_UI::step_edit_status_change (bool yn) -{ - // XXX should really store pre-step edit status of things - // we make insensitive - - if (yn) { - rec_button.set_active_state (Gtkmm2ext::ImplicitActive); - rec_button.set_sensitive (false); - } else { - rec_button.unset_active_state ();; - rec_button.set_sensitive (true); - } -} void ARDOUR_UI::record_state_changed () @@ -5303,86 +5314,6 @@ ARDOUR_UI::store_clock_modes () _session->set_dirty (); } -ARDOUR_UI::TransportControllable::TransportControllable (std::string name, ARDOUR_UI& u, ToggleType tp) - : Controllable (name), ui (u), type(tp) -{ - -} - -void -ARDOUR_UI::TransportControllable::set_value (double val, PBD::Controllable::GroupControlDisposition /*group_override*/) -{ - if (val < 0.5) { - /* do nothing: these are radio-style actions */ - return; - } - - const char *action = 0; - - switch (type) { - case Roll: - action = X_("Roll"); - break; - case Stop: - action = X_("Stop"); - break; - case GotoStart: - action = X_("GotoStart"); - break; - case GotoEnd: - action = X_("GotoEnd"); - break; - case AutoLoop: - action = X_("Loop"); - break; - case PlaySelection: - action = X_("PlaySelection"); - break; - case RecordEnable: - action = X_("Record"); - break; - default: - break; - } - - if (action == 0) { - return; - } - - Glib::RefPtr act = ActionManager::get_action ("Transport", action); - - if (act) { - act->activate (); - } -} - -double -ARDOUR_UI::TransportControllable::get_value (void) const -{ - float val = 0.0; - - switch (type) { - case Roll: - break; - case Stop: - break; - case GotoStart: - break; - case GotoEnd: - break; - case AutoLoop: - break; - case PlaySelection: - break; - case RecordEnable: - break; - default: - break; - } - - return val; -} - void ARDOUR_UI::setup_profile () { @@ -5934,7 +5865,7 @@ ARDOUR_UI::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey } } - DEBUG_TRACE (DEBUG::Accelerators, "\tnot yet handled, try global bindings\n"); + DEBUG_TRACE (DEBUG::Accelerators, string_compose ("\tnot yet handled, try global bindings (%1)\n", global_bindings)); if (global_bindings && global_bindings->activate (k, Bindings::Press)) { DEBUG_TRACE (DEBUG::Accelerators, "\t\thandled\n"); @@ -5984,7 +5915,7 @@ ARDOUR_UI::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey } } - DEBUG_TRACE (DEBUG::Accelerators, "\tnot yet handled, try global bindings\n"); + DEBUG_TRACE (DEBUG::Accelerators, string_compose ("\tnot yet handled, try global bindings (%1)\n", global_bindings)); if (global_bindings && global_bindings->activate (k, Bindings::Press)) { DEBUG_TRACE (DEBUG::Accelerators, "\t\thandled\n"); @@ -5996,14 +5927,6 @@ ARDOUR_UI::key_press_focus_accelerator_handler (Gtk::Window& window, GdkEventKey return true; } -void -ARDOUR_UI::load_bindings () -{ - if ((global_bindings = Bindings::get_bindings (X_("Global"), global_actions)) == 0) { - error << _("Global keybindings are missing") << endmsg; - } -} - void ARDOUR_UI::cancel_solo () { @@ -6063,3 +5986,42 @@ ARDOUR_UI::reset_focus (Gtk::Widget* w) gtk_window_set_focus (GTK_WINDOW(top->gobj()), 0); } + +void +ARDOUR_UI::monitor_dim_all () +{ + boost::shared_ptr mon = _session->monitor_out (); + if (!mon) { + return; + } + boost::shared_ptr _monitor = mon->monitor_control (); + + Glib::RefPtr tact = ActionManager::get_toggle_action (X_("Monitor"), "monitor-dim-all"); + _monitor->set_dim_all (tact->get_active()); +} + +void +ARDOUR_UI::monitor_cut_all () +{ + boost::shared_ptr mon = _session->monitor_out (); + if (!mon) { + return; + } + boost::shared_ptr _monitor = mon->monitor_control (); + + Glib::RefPtr tact = ActionManager::get_toggle_action (X_("Monitor"), "monitor-cut-all"); + _monitor->set_cut_all (tact->get_active()); +} + +void +ARDOUR_UI::monitor_mono () +{ + boost::shared_ptr mon = _session->monitor_out (); + if (!mon) { + return; + } + boost::shared_ptr _monitor = mon->monitor_control (); + + Glib::RefPtr tact = ActionManager::get_toggle_action (X_("Monitor"), "monitor-mono"); + _monitor->set_mono (tact->get_active()); +}