X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Frc_option_editor.cc;h=30b55259bd89c8b585a481e47625a3d64e740c6a;hb=52275254a7adb9a446c104cc7dcfde82d1792786;hp=fee9e4709407006e7bba921a2db26e041270f91a;hpb=5723676092d53abc797ad221828a238214034368;p=ardour.git diff --git a/gtk2_ardour/rc_option_editor.cc b/gtk2_ardour/rc_option_editor.cc index fee9e47094..30b55259bd 100644 --- a/gtk2_ardour/rc_option_editor.cc +++ b/gtk2_ardour/rc_option_editor.cc @@ -41,30 +41,34 @@ #include "pbd/fpu.h" #include "pbd/cpus.h" +#include "pbd/i18n.h" +#include "ardour/audio_backend.h" #include "ardour/audioengine.h" #include "ardour/profile.h" #include "ardour/dB.h" #include "ardour/rc_configuration.h" #include "ardour/control_protocol_manager.h" +#include "ardour/port_manager.h" #include "ardour/plugin_manager.h" #include "control_protocol/control_protocol.h" #include "canvas/wave_view.h" -#include "ardour_window.h" #include "ardour_dialog.h" +#include "ardour_ui.h" +#include "ardour_window.h" +#include "color_theme_manager.h" #include "gui_thread.h" +#include "keyboard.h" #include "meter_patterns.h" #include "midi_tracer.h" #include "rc_option_editor.h" -#include "utils.h" -#include "midi_port_dialog.h" #include "sfdb_ui.h" -#include "keyboard.h" #include "theme_manager.h" +#include "tooltips.h" #include "ui_config.h" -#include "i18n.h" +#include "utils.h" using namespace std; using namespace Gtk; @@ -73,7 +77,7 @@ using namespace PBD; using namespace ARDOUR; using namespace ARDOUR_UI_UTILS; -class ClickOptions : public OptionEditorBox +class ClickOptions : public OptionEditorPageBox, public OptionEditorPage { public: ClickOptions (RCConfiguration* c) @@ -81,36 +85,45 @@ public: , _click_browse_button (_("Browse...")) , _click_emphasis_browse_button (_("Browse...")) { - Table* t = manage (new Table (4, 3)); - t->set_spacings (4); + Table* t = &table; Label* l = manage (left_aligned_label (_("Emphasis on first beat:"))); - t->attach (*l, 0, 1, 1, 2, FILL); - t->attach (_use_emphasis_on_click_check_button, 1, 2, 1, 2, FILL); + _use_emphasis_on_click_check_button.add (*l); + t->attach (_use_emphasis_on_click_check_button, 1, 3, 0, 1, FILL); _use_emphasis_on_click_check_button.signal_toggled().connect ( sigc::mem_fun (*this, &ClickOptions::use_emphasis_on_click_toggled)); l = manage (left_aligned_label (_("Use default Click:"))); - t->attach (*l, 0, 1, 0, 1, FILL); - t->attach (_use_default_click_check_button, 1, 2, 0, 1, FILL); + _use_default_click_check_button.add (*l); + t->attach (_use_default_click_check_button, 1, 3, 1, 2, FILL); _use_default_click_check_button.signal_toggled().connect ( sigc::mem_fun (*this, &ClickOptions::use_default_click_toggled)); l = manage (left_aligned_label (_("Click audio file:"))); - t->attach (*l, 0, 1, 2, 3, FILL); - t->attach (_click_path_entry, 1, 2, 2, 3, FILL); + t->attach (*l, 1, 2, 2, 3, FILL); + t->attach (_click_path_entry, 2, 3, 2, 3, FILL); _click_browse_button.signal_clicked ().connect ( sigc::mem_fun (*this, &ClickOptions::click_browse_clicked)); - t->attach (_click_browse_button, 2, 3, 2, 3, FILL); + t->attach (_click_browse_button, 3, 4, 2, 3, FILL); l = manage (left_aligned_label (_("Click emphasis audio file:"))); - t->attach (*l, 0, 1, 3, 4, FILL); - t->attach (_click_emphasis_path_entry, 1, 2, 3, 4, FILL); + t->attach (*l, 1, 2, 3, 4, FILL); + t->attach (_click_emphasis_path_entry, 2, 3, 3, 4, FILL); _click_emphasis_browse_button.signal_clicked ().connect ( sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked)); - t->attach (_click_emphasis_browse_button, 2, 3, 3, 4, FILL); + t->attach (_click_emphasis_browse_button, 3, 4, 3, 4, FILL); - _box->pack_start (*t, false, false); + FaderOption* fo = new FaderOption ( + "click-gain", + _("Click gain level"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain) + ); + + fo->add_to_page (this); + fo->set_state_from_config (); + + _box->pack_start (table, true, true); _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed)); _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed)); @@ -320,13 +333,13 @@ private: static const struct { - const char *name; - guint modifier; + const char *name; + guint modifier; } modifiers[] = { { "Unmodified", 0 }, -#ifdef GTKOSX +#ifdef __APPLE__ /* Command = Meta Option/Alt = Mod1 @@ -337,6 +350,7 @@ static const struct { { "Option", GDK_MOD1_MASK }, { "Command-Shift", GDK_MOD2_MASK|GDK_SHIFT_MASK }, { "Command-Option", GDK_MOD2_MASK|GDK_MOD1_MASK }, + { "Command-Control", GDK_MOD2_MASK|GDK_CONTROL_MASK }, { "Command-Option-Control", GDK_MOD2_MASK|GDK_MOD1_MASK|GDK_CONTROL_MASK }, { "Option-Control", GDK_MOD1_MASK|GDK_CONTROL_MASK }, { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK }, @@ -349,6 +363,7 @@ static const struct { { "Alt", GDK_MOD1_MASK }, { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK }, { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK }, + { "Control-Windows", GDK_CONTROL_MASK|GDK_MOD4_MASK }, { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK }, { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK }, { "Alt-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK }, @@ -373,7 +388,7 @@ public: _insert_note_button_adjustment (3, 1, 5), _insert_note_button_spin (_insert_note_button_adjustment) { - const Glib::ustring restart_msg = _("\nChanges to this setting will only persist after your project has been saved."); + const std::string restart_msg = _("\nChanges to this setting will only persist after your project has been saved."); /* internationalize and prepare for use with combos */ vector dumb; @@ -514,7 +529,7 @@ public: _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen)); Gtkmm2ext::UI::instance()->set_tip (_copy_modifier_combo, (string_compose (_("Recommended Setting: %1%2"), -#ifdef GTKOSX +#ifdef __APPLE__ Keyboard::secondary_modifier_name (), #else Keyboard::primary_modifier_name (), @@ -539,12 +554,13 @@ public: /* constraint modifier */ set_popdown_strings (_constraint_modifier_combo, dumb); _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen)); + std::string mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ()); Gtkmm2ext::UI::instance()->set_tip (_constraint_modifier_combo, (string_compose (_("Recommended Setting: %1%2"), -#ifdef GTKOSX +#ifdef __APPLE__ Keyboard::primary_modifier_name (), #else - Keyboard::secondary_modifier_name (), + Keyboard::tertiary_modifier_name (), #endif restart_msg))); for (int x = 0; modifiers[x].name; ++x) { @@ -560,6 +576,29 @@ public: t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL); t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL); + ++row; + col = 1; + + /* push points */ + set_popdown_strings (_push_points_combo, dumb); + _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen)); + + mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ()); + Gtkmm2ext::UI::instance()->set_tip (_push_points_combo, + (string_compose (_("Recommended Setting: %1%2"), mod_str, restart_msg))); + for (int x = 0; modifiers[x].name; ++x) { + if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) { + _push_points_combo.set_active_text (S_(modifiers[x].name)); + break; + } + } + + l = manage (left_aligned_label (_("Push points using:"))); + l->set_name ("OptionsLabel"); + + t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL); + t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL); + ++row; l = manage (left_aligned_label (_("When Beginning a Trim:"))); @@ -593,8 +632,10 @@ public: /* anchored trim */ set_popdown_strings (_trim_anchored_combo, dumb); _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen)); + + mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::tertiary_modifier_name ()); Gtkmm2ext::UI::instance()->set_tip (_trim_anchored_combo, - (string_compose (_("Recommended Setting: %1%2"), Keyboard::tertiary_modifier_name (), restart_msg))); + (string_compose (_("Recommended Setting: %1%2"), mod_str, restart_msg))); for (int x = 0; modifiers[x].name; ++x) { if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) { _trim_anchored_combo.set_active_text (S_(modifiers[x].name)); @@ -638,7 +679,7 @@ public: set_popdown_strings (_note_size_relative_combo, dumb); _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen)); Gtkmm2ext::UI::instance()->set_tip (_note_size_relative_combo, - (string_compose (_("Recommended Setting: %1%2"), Keyboard::primary_modifier_name (), restart_msg))); + (string_compose (_("Recommended Setting: %1%2"), Keyboard::tertiary_modifier_name (), restart_msg))); for (int x = 0; modifiers[x].name; ++x) { if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) { _note_size_relative_combo.set_active_text (S_(modifiers[x].name)); @@ -665,10 +706,10 @@ public: /* ignore snap */ set_popdown_strings (_snap_modifier_combo, dumb); _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen)); -#ifdef GTKOSX - Glib::ustring mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ()); +#ifdef __APPLE__ + mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ()); #else - Glib::ustring mod_str = Keyboard::secondary_modifier_name(); + mod_str = Keyboard::secondary_modifier_name(); #endif Gtkmm2ext::UI::instance()->set_tip (_snap_modifier_combo, (string_compose (_("Recommended Setting: %1%2"), mod_str, restart_msg))); @@ -691,7 +732,7 @@ public: /* snap delta */ set_popdown_strings (_snap_delta_combo, dumb); _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen)); -#ifdef GTKOSX +#ifdef __APPLE__ mod_str = Keyboard::level4_modifier_name (); #else mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::level4_modifier_name ()); @@ -752,7 +793,7 @@ public: set_popdown_strings (_fine_adjust_combo, dumb); _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen)); - mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::tertiary_modifier_name ()); + mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::secondary_modifier_name ()); Gtkmm2ext::UI::instance()->set_tip (_fine_adjust_combo, (string_compose (_("Recommended Setting: %1%2"), mod_str, restart_msg))); for (int x = 0; modifiers[x].name; ++x) { @@ -768,28 +809,6 @@ public: t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL); t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL); - ++row; - col = 1; - - /* push points */ - set_popdown_strings (_push_points_combo, dumb); - _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen)); - - Gtkmm2ext::UI::instance()->set_tip (_push_points_combo, - (string_compose (_("Recommended Setting: %1%2"), Keyboard::primary_modifier_name (), restart_msg))); - for (int x = 0; modifiers[x].name; ++x) { - if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) { - _push_points_combo.set_active_text (S_(modifiers[x].name)); - break; - } - } - - l = manage (left_aligned_label (_("Push points using:"))); - l->set_name ("OptionsLabel"); - - t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL); - t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL); - _box->pack_start (*t, false, false); } @@ -825,7 +844,7 @@ private: string const txt = _edit_modifier_combo.get_active_text(); for (int i = 0; modifiers[i].name; ++i) { - if (txt == _(modifiers[i].name)) { + if (txt == S_(modifiers[i].name)) { Keyboard::set_edit_modifier (modifiers[i].modifier); break; } @@ -837,7 +856,7 @@ private: string const txt = _delete_modifier_combo.get_active_text(); for (int i = 0; modifiers[i].name; ++i) { - if (txt == _(modifiers[i].name)) { + if (txt == S_(modifiers[i].name)) { Keyboard::set_delete_modifier (modifiers[i].modifier); break; } @@ -849,7 +868,7 @@ private: string const txt = _copy_modifier_combo.get_active_text(); for (int i = 0; modifiers[i].name; ++i) { - if (txt == _(modifiers[i].name)) { + if (txt == S_(modifiers[i].name)) { Keyboard::set_copy_modifier (modifiers[i].modifier); break; } @@ -861,7 +880,7 @@ private: string const txt = _insert_note_modifier_combo.get_active_text(); for (int i = 0; modifiers[i].name; ++i) { - if (txt == _(modifiers[i].name)) { + if (txt == S_(modifiers[i].name)) { Keyboard::set_insert_note_modifier (modifiers[i].modifier); break; } @@ -873,7 +892,7 @@ private: string const txt = _snap_modifier_combo.get_active_text(); for (int i = 0; modifiers[i].name; ++i) { - if (txt == _(modifiers[i].name)) { + if (txt == S_(modifiers[i].name)) { Keyboard::set_snap_modifier (modifiers[i].modifier); break; } @@ -885,7 +904,7 @@ private: string const txt = _snap_delta_combo.get_active_text(); for (int i = 0; modifiers[i].name; ++i) { - if (txt == _(modifiers[i].name)) { + if (txt == S_(modifiers[i].name)) { Keyboard::set_snap_delta_modifier (modifiers[i].modifier); break; } @@ -897,7 +916,7 @@ private: string const txt = _constraint_modifier_combo.get_active_text(); for (int i = 0; modifiers[i].name; ++i) { - if (txt == _(modifiers[i].name)) { + if (txt == S_(modifiers[i].name)) { ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier); break; } @@ -909,7 +928,7 @@ private: string const txt = _trim_contents_combo.get_active_text(); for (int i = 0; modifiers[i].name; ++i) { - if (txt == _(modifiers[i].name)) { + if (txt == S_(modifiers[i].name)) { ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier); break; } @@ -921,7 +940,7 @@ private: string const txt = _trim_overlap_combo.get_active_text(); for (int i = 0; modifiers[i].name; ++i) { - if (txt == _(modifiers[i].name)) { + if (txt == S_(modifiers[i].name)) { ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier); break; } @@ -933,7 +952,7 @@ private: string const txt = _trim_anchored_combo.get_active_text(); for (int i = 0; modifiers[i].name; ++i) { - if (txt == _(modifiers[i].name)) { + if (txt == S_(modifiers[i].name)) { ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier); break; } @@ -945,7 +964,7 @@ private: string const txt = _fine_adjust_combo.get_active_text(); for (int i = 0; modifiers[i].name; ++i) { - if (txt == _(modifiers[i].name)) { + if (txt == S_(modifiers[i].name)) { ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier); break; } @@ -957,7 +976,7 @@ private: string const txt = _push_points_combo.get_active_text(); for (int i = 0; modifiers[i].name; ++i) { - if (txt == _(modifiers[i].name)) { + if (txt == S_(modifiers[i].name)) { ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier); break; } @@ -969,7 +988,7 @@ private: string const txt = _note_size_relative_combo.get_active_text(); for (int i = 0; modifiers[i].name; ++i) { - if (txt == _(modifiers[i].name)) { + if (txt == S_(modifiers[i].name)) { ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier); break; } @@ -1027,8 +1046,8 @@ public: Label* l = manage (new Label (_("GUI and Font scaling:"))); l->set_name ("OptionsLabel"); - const Glib::ustring dflt = _("Default"); - const Glib::ustring empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference + const std::string dflt = _("Default"); + const std::string empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference _dpi_slider.set_name("FontScaleSlider"); _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS); @@ -1195,13 +1214,13 @@ private: class BufferingOptions : public OptionEditorBox { -public: - BufferingOptions (RCConfiguration* c) - : _rc_config (c) - , _playback_adjustment (5, 1, 60, 1, 4) - , _capture_adjustment (5, 1, 60, 1, 4) - , _playback_slider (_playback_adjustment) - , _capture_slider (_capture_adjustment) + public: + BufferingOptions (RCConfiguration* c) + : _rc_config (c) + , _playback_adjustment (5, 1, 60, 1, 4) + , _capture_adjustment (5, 1, 60, 1, 4) + , _playback_slider (_playback_adjustment) + , _capture_slider (_capture_adjustment) { vector presets; @@ -1254,405 +1273,526 @@ public: _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed)); } - void parameter_changed (string const & p) - { - if (p == "buffering-preset") { - switch (_rc_config->get_buffering_preset()) { - case Small: - _playback_slider.set_sensitive (false); - _capture_slider.set_sensitive (false); - _buffering_presets_combo.set_active (0); - break; - case Medium: - _playback_slider.set_sensitive (false); - _capture_slider.set_sensitive (false); - _buffering_presets_combo.set_active (1); - break; - case Large: - _playback_slider.set_sensitive (false); - _capture_slider.set_sensitive (false); - _buffering_presets_combo.set_active (2); - break; - case Custom: - _playback_slider.set_sensitive (true); - _capture_slider.set_sensitive (true); - _buffering_presets_combo.set_active (3); - break; + void parameter_changed (string const & p) + { + if (p == "buffering-preset") { + switch (_rc_config->get_buffering_preset()) { + case Small: + _playback_slider.set_sensitive (false); + _capture_slider.set_sensitive (false); + _buffering_presets_combo.set_active (0); + break; + case Medium: + _playback_slider.set_sensitive (false); + _capture_slider.set_sensitive (false); + _buffering_presets_combo.set_active (1); + break; + case Large: + _playback_slider.set_sensitive (false); + _capture_slider.set_sensitive (false); + _buffering_presets_combo.set_active (2); + break; + case Custom: + _playback_slider.set_sensitive (true); + _capture_slider.set_sensitive (true); + _buffering_presets_combo.set_active (3); + break; + } } - } - if (p == "playback-buffer-seconds") { - _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds()); - } else if (p == "capture-buffer-seconds") { - _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds()); - } - } + if (p == "playback-buffer-seconds") { + _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds()); + } else if (p == "capture-buffer-seconds") { + _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds()); + } + } - void set_state_from_config () - { - parameter_changed ("buffering-preset"); - parameter_changed ("playback-buffer-seconds"); - parameter_changed ("capture-buffer-seconds"); - } + void set_state_from_config () + { + parameter_changed ("buffering-preset"); + parameter_changed ("playback-buffer-seconds"); + parameter_changed ("capture-buffer-seconds"); + } -private: + private: - void preset_changed () - { - int index = _buffering_presets_combo.get_active_row_number (); - if (index < 0) { - return; - } - switch (index) { - case 0: - _rc_config->set_buffering_preset (Small); - break; - case 1: - _rc_config->set_buffering_preset (Medium); - break; - case 2: - _rc_config->set_buffering_preset (Large); - break; - case 3: - _rc_config->set_buffering_preset (Custom); - break; - default: - error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg; - break; + void preset_changed () + { + int index = _buffering_presets_combo.get_active_row_number (); + if (index < 0) { + return; + } + switch (index) { + case 0: + _rc_config->set_buffering_preset (Small); + break; + case 1: + _rc_config->set_buffering_preset (Medium); + break; + case 2: + _rc_config->set_buffering_preset (Large); + break; + case 3: + _rc_config->set_buffering_preset (Custom); + break; + default: + error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg; + break; + } } - } - void playback_changed () - { - _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value()); - } + void playback_changed () + { + _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value()); + } - void capture_changed () - { - _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value()); - } + void capture_changed () + { + _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value()); + } - RCConfiguration* _rc_config; - Adjustment _playback_adjustment; - Adjustment _capture_adjustment; - HScale _playback_slider; - HScale _capture_slider; - ComboBoxText _buffering_presets_combo; + RCConfiguration* _rc_config; + Adjustment _playback_adjustment; + Adjustment _capture_adjustment; + HScale _playback_slider; + HScale _capture_slider; + ComboBoxText _buffering_presets_combo; }; -class ControlSurfacesOptions : public OptionEditorBox +class ControlSurfacesOptions : public OptionEditorPageBox { -public: - ControlSurfacesOptions () - : _ignore_view_change (0) - { - _store = ListStore::create (_model); - _view.set_model (_store); - _view.append_column (_("Control Surface Protocol"), _model.name); - _view.get_column(0)->set_resizable (true); - _view.get_column(0)->set_expand (true); - _view.append_column_editable (_("Enabled"), _model.enabled); - _view.append_column_editable (_("Feedback"), _model.feedback); - - _box->pack_start (_view, false, false); - - Gtk::HBox* edit_box = manage (new Gtk::HBox); - edit_box->set_spacing(3); - _box->pack_start (*edit_box, false, false); - edit_box->show (); - - Label* label = manage (new Label); - label->set_text (_("Click to edit the settings for selected protocol ( it must be ENABLED first ):")); - edit_box->pack_start (*label, false, false); - label->show (); - - edit_button = manage (new Button(_("Show Protocol Settings"))); - edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked)); - edit_box->pack_start (*edit_button, true, true); - edit_button->set_sensitive (false); - edit_button->show (); - - ControlProtocolManager& m = ControlProtocolManager::instance (); - m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR, - boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context()); - - _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed)); - _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked)); - _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed)); - } - - void parameter_changed (std::string const &) - { + public: + ControlSurfacesOptions () + : _ignore_view_change (0) + { + _store = ListStore::create (_model); + _view.set_model (_store); + _view.append_column (_("Control Surface Protocol"), _model.name); + _view.get_column(0)->set_resizable (true); + _view.get_column(0)->set_expand (true); + _view.append_column_editable (_("Enable"), _model.enabled); + + Label* l = manage (new Label (string_compose ("%1", _("Control Surfaces")))); + l->set_alignment (0, 0.5); + l->set_use_markup (true); + _box->pack_start (*l, false, false); + _box->pack_start (_view, false, false); + + Gtk::HBox* edit_box = manage (new Gtk::HBox); + edit_box->set_spacing(3); + _box->pack_start (*edit_box, false, false); + edit_box->show (); + + Label* label = manage (new Label); + label->set_text (_("Edit the settings for selected protocol (it must be ENABLED first):")); + edit_box->pack_start (*label, false, false); + label->show (); + + edit_button = manage (new Button(_("Show Protocol Settings"))); + edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked)); + edit_box->pack_start (*edit_button, true, true); + edit_button->set_sensitive (false); + edit_button->show (); - } + ControlProtocolManager& m = ControlProtocolManager::instance (); + m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR, + boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context()); - void set_state_from_config () - { - _store->clear (); + _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed)); + _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked)); + _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed)); + } - ControlProtocolManager& m = ControlProtocolManager::instance (); - for (list::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) { + void parameter_changed (std::string const &) + { - if (!(*i)->mandatory) { - TreeModel::Row r = *_store->append (); - r[_model.name] = (*i)->name; - r[_model.enabled] = ((*i)->protocol || (*i)->requested); - r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ()); - r[_model.protocol_info] = *i; - } } - } - -private: - void protocol_status_changed (ControlProtocolInfo* cpi) { - /* find the row */ - TreeModel::Children rows = _store->children(); + void set_state_from_config () + { + _store->clear (); - for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) { - string n = ((*x)[_model.name]); + ControlProtocolManager& m = ControlProtocolManager::instance (); + for (list::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) { - if ((*x)[_model.protocol_info] == cpi) { - _ignore_view_change++; - (*x)[_model.enabled] = (cpi->protocol || cpi->requested); - _ignore_view_change--; - break; + if (!(*i)->mandatory) { + TreeModel::Row r = *_store->append (); + r[_model.name] = (*i)->name; + r[_model.enabled] = ((*i)->protocol || (*i)->requested); + r[_model.protocol_info] = *i; + } } } - } - void selection_changed () - { - //enable the Edit button when a row is selected for editing - TreeModel::Row row = *(_view.get_selection()->get_selected()); - if (row && row[_model.enabled]) - edit_button->set_sensitive (true); - else - edit_button->set_sensitive (false); - } - - void view_changed (TreeModel::Path const &, TreeModel::iterator const & i) - { - TreeModel::Row r = *i; + private: + + void protocol_status_changed (ControlProtocolInfo* cpi) { + /* find the row */ + TreeModel::Children rows = _store->children(); - if (_ignore_view_change) { - return; + for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) { + string n = ((*x)[_model.name]); + + if ((*x)[_model.protocol_info] == cpi) { + _ignore_view_change++; + (*x)[_model.enabled] = (cpi->protocol || cpi->requested); + _ignore_view_change--; + break; + } + } } - ControlProtocolInfo* cpi = r[_model.protocol_info]; - if (!cpi) { - return; + void selection_changed () + { + //enable the Edit button when a row is selected for editing + TreeModel::Row row = *(_view.get_selection()->get_selected()); + if (row && row[_model.enabled]) + edit_button->set_sensitive (true); + else + edit_button->set_sensitive (false); } - bool const was_enabled = (cpi->protocol != 0); - bool const is_enabled = r[_model.enabled]; + void view_changed (TreeModel::Path const &, TreeModel::iterator const & i) + { + TreeModel::Row r = *i; + if (_ignore_view_change) { + return; + } - if (was_enabled != is_enabled) { + ControlProtocolInfo* cpi = r[_model.protocol_info]; + if (!cpi) { + return; + } - if (!was_enabled) { - ControlProtocolManager::instance().activate (*cpi); - } else { - ControlProtocolManager::instance().deactivate (*cpi); + bool const was_enabled = (cpi->protocol != 0); + bool const is_enabled = r[_model.enabled]; + + + if (was_enabled != is_enabled) { + + if (!was_enabled) { + ControlProtocolManager::instance().activate (*cpi); + } else { + ControlProtocolManager::instance().deactivate (*cpi); + } } + + selection_changed (); } - bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ()); - bool const is_feedback = r[_model.feedback]; + void edit_btn_clicked () + { + std::string name; + ControlProtocolInfo* cpi; + TreeModel::Row row; - if (was_feedback != is_feedback && cpi->protocol) { - cpi->protocol->set_feedback (is_feedback); + row = *(_view.get_selection()->get_selected()); + if (!row[_model.enabled]) { + return; + } + cpi = row[_model.protocol_info]; + if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) { + return; + } + Box* box = (Box*) cpi->protocol->get_gui (); + if (!box) { + return; + } + if (box->get_parent()) { + static_cast(box->get_parent())->present(); + return; + } + WindowTitle title (Glib::get_application_name()); + title += row[_model.name]; + title += _("Configuration"); + /* once created, the window is managed by the surface itself (as ->get_parent()) + * Surface's tear_down_gui() is called on session close, when de-activating + * or re-initializing a surface. + * tear_down_gui() hides an deletes the Window if it exists. + */ + ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string()); + win->set_title ("Control Protocol Options"); + win->add (*box); + box->show (); + win->present (); } - } - void edit_btn_clicked () - { - std::string name; - ControlProtocolInfo* cpi; - TreeModel::Row row; - - row = *(_view.get_selection()->get_selected()); - if (!row[_model.enabled]) { - return; - } - cpi = row[_model.protocol_info]; - if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) { - return; - } - Box* box = (Box*) cpi->protocol->get_gui (); - if (!box) { - return; - } - if (box->get_parent()) { - static_cast(box->get_parent())->present(); - return; - } - WindowTitle title (Glib::get_application_name()); - title += row[_model.name]; - title += _("Configuration"); - /* once created, the window is managed by the surface itself (as ->get_parent()) - * Surface's tear_down_gui() is called on session close, when de-activating - * or re-initializing a surface. - * tear_down_gui() hides an deletes the Window if it exists. - */ - ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string()); - win->set_title ("Control Protocol Options"); - win->add (*box); - box->show (); - win->present (); - } - - void edit_clicked (GdkEventButton* ev) - { - if (ev->type != GDK_2BUTTON_PRESS) { - return; - } + void edit_clicked (GdkEventButton* ev) + { + if (ev->type != GDK_2BUTTON_PRESS) { + return; + } - edit_btn_clicked(); - } + edit_btn_clicked(); + } - class ControlSurfacesModelColumns : public TreeModelColumnRecord + class ControlSurfacesModelColumns : public TreeModelColumnRecord { - public: + public: - ControlSurfacesModelColumns () - { - add (name); - add (enabled); - add (feedback); - add (protocol_info); - } + ControlSurfacesModelColumns () + { + add (name); + add (enabled); + add (protocol_info); + } - TreeModelColumn name; - TreeModelColumn enabled; - TreeModelColumn feedback; - TreeModelColumn protocol_info; + TreeModelColumn name; + TreeModelColumn enabled; + TreeModelColumn protocol_info; }; - Glib::RefPtr _store; - ControlSurfacesModelColumns _model; - TreeView _view; - PBD::ScopedConnection protocol_status_connection; - uint32_t _ignore_view_change; - Gtk::Button* edit_button; + Glib::RefPtr _store; + ControlSurfacesModelColumns _model; + TreeView _view; + PBD::ScopedConnection protocol_status_connection; + uint32_t _ignore_view_change; + Gtk::Button* edit_button; }; -class VideoTimelineOptions : public OptionEditorBox +class VideoTimelineOptions : public OptionEditorPageBox, public OptionEditorPage { -public: - VideoTimelineOptions (RCConfiguration* c) - : _rc_config (c) - , _show_video_export_info_button (_("Show Video Export Info before export")) - , _show_video_server_dialog_button (_("Show Video Server Startup Dialog")) - , _video_advanced_setup_button (_("Advanced Setup (remote video server)")) - { - Table* t = manage (new Table (2, 6)); - t->set_spacings (4); + public: + VideoTimelineOptions (RCConfiguration* c) + : _rc_config (c) + , _show_video_export_info_button (_("Show Video Export Info before export")) + , _show_video_server_dialog_button (_("Show Video Server Startup Dialog")) + , _video_advanced_setup_button (_("Advanced Setup (remote video server)")) + , _xjadeo_browse_button (_("Browse...")) + { + Table* t = &table; + + Label* l = manage (new Label (string_compose ("%1", _("Video Server")))); + l->set_use_markup (true); + l->set_alignment (0, 0.5); + t->attach (*l, 0, 4, 0, 1, EXPAND | FILL, FILL | EXPAND, 0, 0); + + t->attach (_show_video_export_info_button, 1, 4, 1, 2); + _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled)); + Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button, + _("When enabled an information window with details is displayed before the video-export dialog.")); + + t->attach (_show_video_server_dialog_button, 1, 4, 2, 3); + _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled)); + Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button, + _("When enabled the video server is never launched automatically without confirmation")); + + t->attach (_video_advanced_setup_button, 1, 4, 3, 4, FILL); + _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled)); + Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button, + _("When enabled you can speficify a custom video-server URL and docroot. - Do not enable this option unless you know what you are doing.")); + + l = manage (new Label (_("Video Server URL:"))); + l->set_alignment (0, 0.5); + t->attach (*l, 1, 2, 4, 5, FILL); + t->attach (_video_server_url_entry, 2, 4, 4, 5, FILL); + Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry, + _("Base URL of the video-server including http prefix. This is usually 'http://hostname.example.org:1554/' and defaults to 'http://localhost:1554/' when the video-server is running locally")); + + l = manage (new Label (_("Video Folder:"))); + l->set_alignment (0, 0.5); + t->attach (*l, 1, 2, 5, 6, FILL); + t->attach (_video_server_docroot_entry, 2, 4, 5, 6); + Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry, + _("Local path to the video-server document-root. Only files below this directory will be accessible by the video-server. If the server run on a remote host, it should point to a network mounted folder of the server's docroot or be left empty if it is unvailable. It is used for the local video-monitor and file-browsing when opening/adding a video file.")); + + l = manage (new Label ("")); + t->attach (*l, 0, 4, 6, 7, EXPAND | FILL); + + l = manage (new Label (string_compose ("%1", _("Video Monitor")))); + l->set_use_markup (true); + l->set_alignment (0, 0.5); + t->attach (*l, 0, 4, 7, 8, EXPAND | FILL); + + l = manage (new Label (string_compose (_("Custom Path to Video Monitor (%1) - leave empty for default:"), +#ifdef __APPLE__ + "Jadeo.app" +#elif defined PLATFORM_WINDOWS + "xjadeo.exe" +#else + "xjadeo" +#endif + ))); + l->set_alignment (0, 0.5); + t->attach (*l, 1, 4, 8, 9, FILL); + t->attach (_custom_xjadeo_path, 2, 3, 9, 10, EXPAND|FILL); + Gtkmm2ext::UI::instance()->set_tip (_custom_xjadeo_path, _("Set a custom path to the Video Monitor Executable, changing this requires a restart.")); + t->attach (_xjadeo_browse_button, 3, 4, 9, 10, FILL); + + _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed)); + _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed)); + _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed)); + _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed)); + _custom_xjadeo_path.signal_changed().connect (sigc::mem_fun (*this, &VideoTimelineOptions::custom_xjadeo_path_changed)); + _xjadeo_browse_button.signal_clicked ().connect (sigc::mem_fun (*this, &VideoTimelineOptions::xjadeo_browse_clicked)); + + // xjadeo-path is a UIConfig parameter + UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &VideoTimelineOptions::parameter_changed)); + + _box->pack_start (*t, true, true); + } - t->attach (_video_advanced_setup_button, 0, 2, 0, 1); - _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled)); - Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button, - _("When enabled you can speficify a custom video-server URL and docroot. - Do not enable this option unless you know what you are doing.")); + void server_url_changed () + { + _rc_config->set_video_server_url (_video_server_url_entry.get_text()); + } - Label* l = manage (new Label (_("Video Server URL:"))); - l->set_alignment (0, 0.5); - t->attach (*l, 0, 1, 1, 2, FILL); - t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL); - Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry, - _("Base URL of the video-server including http prefix. This is usually 'http://hostname.example.org:1554/' and defaults to 'http://localhost:1554/' when the video-server is running locally")); + void server_docroot_changed () + { + _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text()); + } - l = manage (new Label (_("Video Folder:"))); - l->set_alignment (0, 0.5); - t->attach (*l, 0, 1, 2, 3, FILL); - t->attach (_video_server_docroot_entry, 1, 2, 2, 3); - Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry, - _("Local path to the video-server document-root. Only files below this directory will be accessible by the video-server. If the server run on a remote host, it should point to a network mounted folder of the server's docroot or be left empty if it is unvailable. It is used for the local video-monitor and file-browsing when opening/adding a video file.")); + void show_video_export_info_toggled () + { + bool const x = _show_video_export_info_button.get_active (); + _rc_config->set_show_video_export_info (x); + } - /* small vspace y=3..4 */ + void show_video_server_dialog_toggled () + { + bool const x = _show_video_server_dialog_button.get_active (); + _rc_config->set_show_video_server_dialog (x); + } - t->attach (_show_video_export_info_button, 0, 2, 4, 5); - _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled)); - Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button, - _("When enabled an information window with details is displayed before the video-export dialog.")); + void video_advanced_setup_toggled () + { + bool const x = _video_advanced_setup_button.get_active (); + _rc_config->set_video_advanced_setup(x); + } - t->attach (_show_video_server_dialog_button, 0, 2, 5, 6); - _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled)); - Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button, - _("When enabled the video server is never launched automatically without confirmation")); + void custom_xjadeo_path_changed () + { + UIConfiguration::instance().set_xjadeo_binary (_custom_xjadeo_path.get_text()); + } - _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed)); - _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed)); - _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed)); - _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed)); + void xjadeo_browse_clicked () + { + Gtk::FileChooserDialog dialog(_("Set Video Monitor Executable"), Gtk::FILE_CHOOSER_ACTION_OPEN); + dialog.set_filename (UIConfiguration::instance().get_xjadeo_binary()); + dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK); + if (dialog.run () == Gtk::RESPONSE_OK) { + const std::string& filename = dialog.get_filename(); + if (!filename.empty() && ( +#ifdef __APPLE__ + Glib::file_test (filename + "/Contents/MacOS/xjadeo", Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) || +#endif + Glib::file_test (filename, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) + )) { + UIConfiguration::instance().set_xjadeo_binary (filename); + } + } + } - _box->pack_start (*t,true,true); - } + void parameter_changed (string const & p) + { + if (p == "video-server-url") { + _video_server_url_entry.set_text (_rc_config->get_video_server_url()); + } else if (p == "video-server-docroot") { + _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot()); + } else if (p == "show-video-export-info") { + bool const x = _rc_config->get_show_video_export_info(); + _show_video_export_info_button.set_active (x); + } else if (p == "show-video-server-dialog") { + bool const x = _rc_config->get_show_video_server_dialog(); + _show_video_server_dialog_button.set_active (x); + } else if (p == "video-advanced-setup") { + bool const x = _rc_config->get_video_advanced_setup(); + _video_advanced_setup_button.set_active(x); + _video_server_docroot_entry.set_sensitive(x); + _video_server_url_entry.set_sensitive(x); + } else if (p == "xjadeo-binary") { + _custom_xjadeo_path.set_text (UIConfiguration::instance().get_xjadeo_binary()); + } + } - void server_url_changed () - { - _rc_config->set_video_server_url (_video_server_url_entry.get_text()); - } + void set_state_from_config () + { + parameter_changed ("video-server-url"); + parameter_changed ("video-server-docroot"); + parameter_changed ("video-monitor-setup-dialog"); + parameter_changed ("show-video-export-info"); + parameter_changed ("show-video-server-dialog"); + parameter_changed ("video-advanced-setup"); + parameter_changed ("xjadeo-binary"); + } - void server_docroot_changed () + private: + RCConfiguration* _rc_config; + Entry _video_server_url_entry; + Entry _video_server_docroot_entry; + Entry _custom_xjadeo_path; + CheckButton _show_video_export_info_button; + CheckButton _show_video_server_dialog_button; + CheckButton _video_advanced_setup_button; + Button _xjadeo_browse_button; +}; + +class ColumVisibilityOption : public Option +{ + public: + ColumVisibilityOption (string id, string name, uint32_t n_col, sigc::slot get, sigc::slot set) + : Option (id, name) + , _heading (name) + , _n_col (n_col) + , _get (get) + , _set (set) { - _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text()); + cb = (CheckButton**) malloc (sizeof (CheckButton*) * n_col); + for (uint32_t i = 0; i < n_col; ++i) { + CheckButton* col = manage (new CheckButton (string_compose (_("Column %1"), i + 1))); + col->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &ColumVisibilityOption::column_toggled), i)); + _hbox.pack_start (*col); + cb[i] = col; + } + parameter_changed (id); } - void show_video_export_info_toggled () - { - bool const x = _show_video_export_info_button.get_active (); - _rc_config->set_show_video_export_info (x); + ~ColumVisibilityOption () { + free (cb); } - void show_video_server_dialog_toggled () + Gtk::Widget& tip_widget() { return _hbox; } + + void set_state_from_config () { - bool const x = _show_video_server_dialog_button.get_active (); - _rc_config->set_show_video_server_dialog (x); + uint32_t c = _get(); + for (uint32_t i = 0; i < _n_col; ++i) { + bool en = (c & (1<get_active () != en) { + cb[i]->set_active (en); + } + } } - void video_advanced_setup_toggled () + void add_to_page (OptionEditorPage* p) { - bool const x = _video_advanced_setup_button.get_active (); - _rc_config->set_video_advanced_setup(x); + _heading.add_to_page (p); + add_widget_to_page (p, &_hbox); } + private: - void parameter_changed (string const & p) - { - if (p == "video-server-url") { - _video_server_url_entry.set_text (_rc_config->get_video_server_url()); - } else if (p == "video-server-docroot") { - _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot()); - } else if (p == "show-video-export-info") { - bool const x = _rc_config->get_show_video_export_info(); - _show_video_export_info_button.set_active (x); - } else if (p == "show-video-server-dialog") { - bool const x = _rc_config->get_show_video_server_dialog(); - _show_video_server_dialog_button.set_active (x); - } else if (p == "video-advanced-setup") { - bool const x = _rc_config->get_video_advanced_setup(); - _video_advanced_setup_button.set_active(x); - _video_server_docroot_entry.set_sensitive(x); - _video_server_url_entry.set_sensitive(x); + void column_toggled (int b) { + uint32_t c = _get(); + uint32_t cc = c; + if (cb[b]->get_active ()) { + c |= (1< _get; + sigc::slot _set; }; @@ -1686,71 +1826,373 @@ public: ); } - void set_state_from_config () - { - /* Set our state from the current configuration */ - _visibility_group->set_state (_get ()); + void set_state_from_config () + { + /* Set our state from the current configuration */ + _visibility_group->set_state (_get ()); + } + + void add_to_page (OptionEditorPage* p) + { + _heading.add_to_page (p); + add_widget_to_page (p, _visibility_group->list_view ()); + } + + Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); } + +private: + void changed () + { + /* The user has changed something, so reflect this change + in the RCConfiguration. + */ + _set (_visibility_group->get_state_value ()); + } + + OptionEditorHeading _heading; + VisibilityGroup* _visibility_group; + sigc::slot _get; + sigc::slot _set; + PBD::ScopedConnection _visibility_group_connection; +}; + + +class MidiPortOptions : public OptionEditorPageBox, public sigc::trackable +{ + public: + MidiPortOptions() { + + setup_midi_port_view (midi_output_view, false); + setup_midi_port_view (midi_input_view, true); + + + _box->pack_start (*manage (new Label("")), false, false); + input_label.set_markup (string_compose ("%1", _("MIDI Inputs"))); + _box->pack_start (input_label, false, false); + + Gtk::ScrolledWindow* scroller = manage (new Gtk::ScrolledWindow); + scroller->add (midi_input_view); + scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC); + scroller->set_size_request (-1, 180); + _box->pack_start (*scroller, false, false); + + _box->pack_start (*manage (new Label("")), false, false); + output_label.set_markup (string_compose ("%1", _("MIDI Outputs"))); + _box->pack_start (output_label, false, false); + + scroller = manage (new Gtk::ScrolledWindow); + scroller->add (midi_output_view); + scroller->set_policy (POLICY_NEVER, POLICY_AUTOMATIC); + scroller->set_size_request (-1, 180); + _box->pack_start (*scroller, false, false); + + midi_output_view.show (); + midi_input_view.show (); + + _box->signal_show().connect (sigc::mem_fun (*this, &MidiPortOptions::on_show)); + } + + void parameter_changed (string const&) {} + void set_state_from_config() {} + + void on_show () { + refill (); + + AudioEngine::instance()->PortRegisteredOrUnregistered.connect (connections, + invalidator (*this), + boost::bind (&MidiPortOptions::refill, this), + gui_context()); + AudioEngine::instance()->MidiPortInfoChanged.connect (connections, + invalidator (*this), + boost::bind (&MidiPortOptions::refill, this), + gui_context()); + AudioEngine::instance()->MidiSelectionPortsChanged.connect (connections, + invalidator (*this), + boost::bind (&MidiPortOptions::refill, this), + gui_context()); + } + + void refill () { + + if (refill_midi_ports (true, midi_input_view)) { + input_label.show (); + } else { + input_label.hide (); + } + if (refill_midi_ports (false, midi_output_view)) { + output_label.show (); + } else { + output_label.hide (); + } + } + + private: + PBD::ScopedConnectionList connections; + + /* MIDI port management */ + struct MidiPortColumns : public Gtk::TreeModel::ColumnRecord { + + MidiPortColumns () { + add (pretty_name); + add (music_data); + add (control_data); + add (selection); + add (name); + add (filler); + } + + Gtk::TreeModelColumn pretty_name; + Gtk::TreeModelColumn music_data; + Gtk::TreeModelColumn control_data; + Gtk::TreeModelColumn selection; + Gtk::TreeModelColumn name; + Gtk::TreeModelColumn filler; + }; + + MidiPortColumns midi_port_columns; + Gtk::TreeView midi_input_view; + Gtk::TreeView midi_output_view; + Gtk::Label input_label; + Gtk::Label output_label; + + void setup_midi_port_view (Gtk::TreeView&, bool with_selection); + bool refill_midi_ports (bool for_input, Gtk::TreeView&); + void pretty_name_edit (std::string const & path, std::string const & new_text, Gtk::TreeView*); + void midi_music_column_toggled (std::string const & path, Gtk::TreeView*); + void midi_control_column_toggled (std::string const & path, Gtk::TreeView*); + void midi_selection_column_toggled (std::string const & path, Gtk::TreeView*); +}; + +void +MidiPortOptions::setup_midi_port_view (Gtk::TreeView& view, bool with_selection) +{ + int pretty_name_column; + int music_column; + int control_column; + int selection_column; + TreeViewColumn* col; + Gtk::Label* l; + + pretty_name_column = view.append_column_editable (_("Name (click to edit)"), midi_port_columns.pretty_name) - 1; + + col = manage (new TreeViewColumn ("", midi_port_columns.music_data)); + col->set_alignment (ALIGN_CENTER); + l = manage (new Label (_("Music Data"))); + set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of music performance data."), PROGRAM_NAME)); + col->set_widget (*l); + l->show (); + music_column = view.append_column (*col) - 1; + + col = manage (new TreeViewColumn ("", midi_port_columns.control_data)); + col->set_alignment (ALIGN_CENTER); + l = manage (new Label (_("Control Data"))); + set_tooltip (*l, string_compose (_("If ticked, %1 will consider this port to be a source of control data."), PROGRAM_NAME)); + col->set_widget (*l); + l->show (); + control_column = view.append_column (*col) - 1; + + if (with_selection) { + col = manage (new TreeViewColumn (_("Follow Selection"), midi_port_columns.selection)); + selection_column = view.append_column (*col) - 1; + l = manage (new Label (_("Follow Selection"))); + set_tooltip (*l, string_compose (_("If ticked, and \"MIDI input follows selection\" is enabled,\n%1 will automatically connect the first selected MIDI track to this port.\n"), PROGRAM_NAME)); + col->set_widget (*l); + l->show (); + } + + /* filler column so that the last real column doesn't expand */ + view.append_column ("", midi_port_columns.filler); + + CellRendererText* pretty_name_cell = dynamic_cast (view.get_column_cell_renderer (pretty_name_column)); + pretty_name_cell->property_editable() = true; + pretty_name_cell->signal_edited().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::pretty_name_edit), &view)); + + CellRendererToggle* toggle_cell; + + toggle_cell = dynamic_cast (view.get_column_cell_renderer (music_column)); + toggle_cell->property_activatable() = true; + toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_music_column_toggled), &view)); + + toggle_cell = dynamic_cast (view.get_column_cell_renderer (control_column)); + toggle_cell->property_activatable() = true; + toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_control_column_toggled), &view)); + + if (with_selection) { + toggle_cell = dynamic_cast (view.get_column_cell_renderer (selection_column)); + toggle_cell->property_activatable() = true; + toggle_cell->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &MidiPortOptions::midi_selection_column_toggled), &view)); + } + + view.get_selection()->set_mode (SELECTION_NONE); + view.set_tooltip_column (4); /* port "real" name */ + view.get_column(0)->set_resizable (true); + view.get_column(0)->set_expand (true); +} + +bool +MidiPortOptions::refill_midi_ports (bool for_input, Gtk::TreeView& view) +{ + using namespace ARDOUR; + + std::vector ports; + + AudioEngine::instance()->get_known_midi_ports (ports); + + if (ports.empty()) { + view.hide (); + return false; + } + + Glib::RefPtr model = Gtk::ListStore::create (midi_port_columns); + + for (vector::const_iterator s = ports.begin(); s != ports.end(); ++s) { + + if (AudioEngine::instance()->port_is_mine (*s)) { + continue; + } + + PortManager::MidiPortInformation mpi (AudioEngine::instance()->midi_port_information (*s)); + + if (mpi.pretty_name.empty()) { + /* vanished since get_known_midi_ports() */ + continue; + } + + if (for_input != mpi.input) { + continue; + } + + TreeModel::Row row = *(model->append()); + + row[midi_port_columns.pretty_name] = mpi.pretty_name; + row[midi_port_columns.music_data] = mpi.properties & MidiPortMusic; + row[midi_port_columns.control_data] = mpi.properties & MidiPortControl; + row[midi_port_columns.selection] = mpi.properties & MidiPortSelection; + row[midi_port_columns.name] = *s; + } + + view.set_model (model); + + return true; +} + +void +MidiPortOptions::midi_music_column_toggled (string const & path, TreeView* view) +{ + TreeIter iter = view->get_model()->get_iter (path); + + if (!iter) { + return; + } + + bool new_value = ! bool ((*iter)[midi_port_columns.music_data]); + + /* don't reset model - wait for MidiPortInfoChanged signal */ + + if (new_value) { + ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic); + } else { + ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortMusic); + } +} + +void +MidiPortOptions::midi_control_column_toggled (string const & path, TreeView* view) +{ + TreeIter iter = view->get_model()->get_iter (path); + + if (!iter) { + return; + } + + bool new_value = ! bool ((*iter)[midi_port_columns.control_data]); + + /* don't reset model - wait for MidiPortInfoChanged signal */ + + if (new_value) { + ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl); + } else { + ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortControl); } +} - void add_to_page (OptionEditorPage* p) - { - _heading.add_to_page (p); - add_widget_to_page (p, _visibility_group->list_view ()); +void +MidiPortOptions::midi_selection_column_toggled (string const & path, TreeView* view) +{ + TreeIter iter = view->get_model()->get_iter (path); + + if (!iter) { + return; } - Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); } + bool new_value = ! bool ((*iter)[midi_port_columns.selection]); -private: - void changed () - { - /* The user has changed something, so reflect this change - in the RCConfiguration. - */ - _set (_visibility_group->get_state_value ()); + /* don't reset model - wait for MidiSelectionPortsChanged signal */ + + if (new_value) { + ARDOUR::AudioEngine::instance()->add_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection); + } else { + ARDOUR::AudioEngine::instance()->remove_midi_port_flags ((*iter)[midi_port_columns.name], MidiPortSelection); } +} - OptionEditorHeading _heading; - VisibilityGroup* _visibility_group; - sigc::slot _get; - sigc::slot _set; - PBD::ScopedConnection _visibility_group_connection; -}; +void +MidiPortOptions::pretty_name_edit (std::string const & path, string const & new_text, Gtk::TreeView* view) +{ + TreeIter iter = view->get_model()->get_iter (path); + + if (!iter) { + return; + } + + boost::shared_ptr backend = ARDOUR::AudioEngine::instance()->current_backend(); + if (backend) { + ARDOUR::PortEngine::PortHandle ph = backend->get_port_by_name ((*iter)[midi_port_columns.name]); + if (ph) { + backend->set_port_property (ph, "http://jackaudio.org/metadata/pretty-name", new_text, ""); + (*iter)[midi_port_columns.pretty_name] = new_text; + } + } +} +/*============*/ RCOptionEditor::RCOptionEditor () - : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME)) + : OptionEditorContainer (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME)) , Tabbable (*this, _("Preferences")) /* pack self-as-vbox into tabbable */ - , _rc_config (Config) + , _rc_config (Config) , _mixer_strip_visibility ("mixer-element-visibility") { + UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed)); + /* MISC */ - uint32_t hwcpus = hardware_concurrency (); + uint32_t hwcpus = hardware_concurrency (); BoolOption* bo; BoolComboOption* bco; - if (hwcpus > 1) { - add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization"))); + if (hwcpus > 1) { + add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization"))); - ComboOption* procs = new ComboOption ( - "processor-usage", - _("Signal processing uses"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage) - ); + ComboOption* procs = new ComboOption ( + "processor-usage", + _("Signal processing uses"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage) + ); - procs->add (-1, _("all but one processor")); - procs->add (0, _("all available processors")); + procs->add (-1, _("all but one processor")); + procs->add (0, _("all available processors")); - for (uint32_t i = 1; i <= hwcpus; ++i) { - procs->add (i, string_compose (_("%1 processors"), i)); - } + for (uint32_t i = 1; i <= hwcpus; ++i) { + procs->add (i, string_compose (P_("%1 processor", "%1 processors", i), i)); + } procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME)); - add_option (_("Misc"), procs); - } + add_option (_("Misc"), procs); + } add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo"))); @@ -1798,17 +2240,9 @@ RCOptionEditor::RCOptionEditor () 0, 1000, 1, 20 )); - add_option (_("Misc"), new OptionEditorHeading (_("Click"))); + add_option (_("Misc/Click"), new OptionEditorHeading (_("Click"))); - add_option (_("Misc"), new ClickOptions (_rc_config)); - - add_option (_("Misc"), - new FaderOption ( - "click-gain", - _("Click gain level"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain) - )); + add_option (_("Misc/Click"), new ClickOptions (_rc_config)); add_option (_("Misc"), new OptionEditorHeading (_("Automation"))); @@ -1830,13 +2264,26 @@ RCOptionEditor::RCOptionEditor () 1, 1000, 1, 20 )); + add_option (_("Misc"), new OptionEditorHeading (_("Tempo"))); + + BoolOption* tsf; + + tsf = new BoolOption ( + "allow-non-quarter-pulse", + _("Allow non quarter-note pulse"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_allow_non_quarter_pulse), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_allow_non_quarter_pulse) + ); + Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), + string_compose (_("When enabled %1 will allow tempo to be expressed in divisions per minute\n" + "When disabled %1 will only allow tempo to be expressed in quarter notes per minute"), + PROGRAM_NAME)); + add_option (_("Misc"), tsf); + /* TRANSPORT */ - add_option (_("Transport"), new OptionEditorHeading (S_("Playhead Behaviour"))); add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options"))); - BoolOption* tsf; - tsf = new BoolOption ( "latched-record-enable", _("Keep record-enable engaged on stop"), @@ -1938,8 +2385,8 @@ RCOptionEditor::RCOptionEditor () psc->add (1.0, _("1.0 second")); psc->add (2.0, _("2.0 seconds")); add_option (_("Transport"), psc); - - add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave"))); + + add_option (_("Transport/Sync"), new OptionEditorHeading (S_("Synchronization and Slave Options"))); _sync_source = new ComboOption ( "sync-source", @@ -1948,7 +2395,7 @@ RCOptionEditor::RCOptionEditor () sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source) ); - add_option (_("Transport"), _sync_source); + add_option (_("Transport/Sync"), _sync_source); _sync_framerate = new BoolOption ( "timecode-sync-frame-rate", @@ -1964,7 +2411,7 @@ RCOptionEditor::RCOptionEditor () "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external " "timecode standard and the session standard."), PROGRAM_NAME)); - add_option (_("Transport"), _sync_framerate); + add_option (_("Transport/Sync"), _sync_framerate); _sync_genlock = new BoolOption ( "timecode-source-is-synced", @@ -1985,7 +2432,7 @@ RCOptionEditor::RCOptionEditor () ), PROGRAM_NAME)); - add_option (_("Transport"), _sync_genlock); + add_option (_("Transport/Sync"), _sync_genlock); _sync_source_2997 = new BoolOption ( "timecode-source-2997", @@ -2003,9 +2450,9 @@ RCOptionEditor::RCOptionEditor () "because the variant of using exactly 29.97 fps has zero timecode drift.\n" )); - add_option (_("Transport"), _sync_source_2997); + add_option (_("Transport/Sync"), _sync_source_2997); - add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader"))); + add_option (_("Transport/Sync"), new OptionEditorHeading (S_("LTC Reader"))); _ltc_port = new ComboStringOption ( "ltc-source-port", @@ -2022,12 +2469,12 @@ RCOptionEditor::RCOptionEditor () populate_sync_options (); AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context()); - add_option (_("Transport"), _ltc_port); + add_option (_("Transport/Sync"), _ltc_port); // TODO; rather disable this button than not compile it.. - add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator"))); + add_option (_("Transport/Sync"), new OptionEditorHeading (S_("LTC Generator"))); - add_option (_("Transport"), + add_option (_("Transport/Sync"), new BoolOption ( "send-ltc", _("Enable LTC generator"), @@ -2044,7 +2491,7 @@ RCOptionEditor::RCOptionEditor () Gtkmm2ext::UI::instance()->set_tip (_ltc_send_continuously->tip_widget(), string_compose (_("When enabled %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME)); - add_option (_("Transport"), _ltc_send_continuously); + add_option (_("Transport/Sync"), _ltc_send_continuously); _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5); _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume())); @@ -2053,12 +2500,14 @@ RCOptionEditor::RCOptionEditor () Gtkmm2ext::UI::instance()->set_tip (_ltc_volume_slider->tip_widget(), - _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system")); + _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system")); - add_option (_("Transport"), _ltc_volume_slider); + add_option (_("Transport/Sync"), _ltc_volume_slider); /* EDITOR */ + add_option (_("Editor"), new OptionEditorHeading (_("Editor Settings"))); + add_option (_("Editor"), new BoolOption ( "rubberbanding-snaps-to-grid", @@ -2085,22 +2534,6 @@ RCOptionEditor::RCOptionEditor () sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead) )); - add_option (_("Editor"), - new BoolOption ( - "show-track-meters", - _("Show meters on tracks in the editor"), - sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters), - sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters) - )); - - add_option (_("Editor"), - new BoolOption ( - "show-editor-meter", - _("Display master-meter in the toolbar"), - sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter), - sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter) - )); - if (!Profile->get_mixbus()) { add_option (_("Editor"), new BoolOption ( @@ -2119,6 +2552,22 @@ if (!Profile->get_mixbus()) { )); } // !mixbus + add_option (_("Editor"), + new BoolOption ( + "use-time-rulers-to-zoom-with-vertical-drag", + _("Use time rulers area to zoom when clicking and dragging vertically"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_time_rulers_to_zoom_with_vertical_drag), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_time_rulers_to_zoom_with_vertical_drag) + )); + + add_option (_("Editor"), + new BoolOption ( + "use-double-click-to-zoom-to-selection", + _("Use double mouse click to zoom to selection"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_double_click_to_zoom_to_selection), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_double_click_to_zoom_to_selection) + )); + add_option (_("Editor"), new BoolOption ( "update-editor-during-summary-drag", @@ -2173,18 +2622,20 @@ if (!Profile->get_mixbus()) { add_option (_("Editor"), fadeshape); +#if 1 bco = new BoolComboOption ( "use-overlap-equivalency", - _("Regions in active edit groups are edited together"), + _("Regions in edit groups are edited together"), _("whenever they overlap in time"), - _("only if they have identical length, position and origin"), + _("only if they have identical length and position"), sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency), sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency) ); add_option (_("Editor"), bco); +#endif ComboOption* lm = new ComboOption ( "layer-model", _("Layering model"), @@ -2213,11 +2664,11 @@ if (!Profile->get_mixbus()) { rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions")); add_option (_("Editor"), rsas); - - add_option (_("Editor"), new OptionEditorHeading (_("Waveforms"))); + + add_option (_("Editor/Waveforms"), new OptionEditorHeading (_("Waveforms"))); if (!Profile->get_mixbus()) { - add_option (_("Editor"), + add_option (_("Editor/Waveforms"), new BoolOption ( "show-waveforms", _("Show waveforms in regions"), @@ -2226,7 +2677,7 @@ if (!Profile->get_mixbus()) { )); } // !mixbus - add_option (_("Editor"), + add_option (_("Editor/Waveforms"), new BoolOption ( "show-waveforms-while-recording", _("Show waveforms for audio while it is being recorded"), @@ -2244,7 +2695,7 @@ if (!Profile->get_mixbus()) { wfs->add (Linear, _("linear")); wfs->add (Logarithmic, _("logarithmic")); - add_option (_("Editor"), wfs); + add_option (_("Editor/Waveforms"), wfs); ComboOption* wfsh = new ComboOption ( "waveform-shape", @@ -2256,9 +2707,9 @@ if (!Profile->get_mixbus()) { wfsh->add (Traditional, _("traditional")); wfsh->add (Rectified, _("rectified")); - add_option (_("Editor"), wfsh); + add_option (_("Editor/Waveforms"), wfsh); - add_option (_("Editor"), new ClipLevelOptions ()); + add_option (_("Editor/Waveforms"), new ClipLevelOptions ()); /* AUDIO */ @@ -2276,9 +2727,9 @@ if (!Profile->get_mixbus()) { sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model) ); - if (AudioEngine::instance()->port_engine().can_monitor_input()) { - mm->add (HardwareMonitoring, _("via Audio Driver")); - } + if (AudioEngine::instance()->port_engine().can_monitor_input()) { + mm->add (HardwareMonitoring, _("via Audio Driver")); + } string prog (PROGRAM_NAME); boost::algorithm::to_lower (prog); @@ -2295,8 +2746,8 @@ if (!Profile->get_mixbus()) { sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode) )); -if (!Profile->get_mixbus()) { add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses"))); +if (!Profile->get_mixbus()) { add_option (_("Audio"), new BoolOption ( @@ -2330,6 +2781,18 @@ if (!Profile->get_mixbus()) { oac->add (ManualConnect, _("manually")); add_option (_("Audio"), oac); + + bo = new BoolOption ( + "strict-io", + _("Use 'Strict-I/O' for new tracks or Busses"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io) + ); + + add_option (_("Audio"), bo); + Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(), + _("With strict-i/o enabled, Effect Processors will not modify the number of channels on a track. The number of output channels will always match the number of input channels.")); + } // !mixbus add_option (_("Audio"), new OptionEditorHeading (_("Denormals"))); @@ -2381,24 +2844,6 @@ if (!Profile->get_mixbus()) { add_option (_("Audio"), dm); - add_option (_("Audio"), new OptionEditorHeading (_("Plugins"))); - - add_option (_("Audio"), - new BoolOption ( - "plugins-stop-with-transport", - _("Silence plugins when the transport is stopped"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport) - )); - - add_option (_("Audio"), - new BoolOption ( - "new-plugins-active", - _("Make new plugins active"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active) - )); - add_option (_("Audio"), new OptionEditorHeading (_("Regions"))); add_option (_("Audio"), @@ -2419,7 +2864,7 @@ if (!Profile->get_mixbus()) { /* SOLO AND MUTE */ - add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo"))); + add_option (_("Solo & mute"), new OptionEditorHeading (_("Solo"))); _solo_control_is_listen_control = new BoolOption ( "solo-control-is-listen-control", @@ -2428,9 +2873,9 @@ if (!Profile->get_mixbus()) { sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control) ); - add_option (_("Solo / mute"), _solo_control_is_listen_control); + add_option (_("Solo & mute"), _solo_control_is_listen_control); - add_option (_("Solo / mute"), + add_option (_("Solo & mute"), new BoolOption ( "exclusive-solo", _("Exclusive solo"), @@ -2438,7 +2883,7 @@ if (!Profile->get_mixbus()) { sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo) )); - add_option (_("Solo / mute"), + add_option (_("Solo & mute"), new BoolOption ( "show-solo-mutes", _("Show solo muting"), @@ -2446,7 +2891,7 @@ if (!Profile->get_mixbus()) { sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes) )); - add_option (_("Solo / mute"), + add_option (_("Solo & mute"), new BoolOption ( "solo-mute-override", _("Soloing overrides muting"), @@ -2454,7 +2899,7 @@ if (!Profile->get_mixbus()) { sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override) )); - add_option (_("Solo / mute"), + add_option (_("Solo & mute"), new FaderOption ( "solo-mute-gain", _("Solo-in-place mute cut (dB)"), @@ -2472,7 +2917,7 @@ if (!Profile->get_mixbus()) { _listen_position->add (AfterFaderListen, _("after-fader (AFL)")); _listen_position->add (PreFaderListen, _("pre-fader (PFL)")); - add_option (_("Solo / mute"), _listen_position); + add_option (_("Solo & mute"), _listen_position); ComboOption* pp = new ComboOption ( "pfl-position", @@ -2484,7 +2929,7 @@ if (!Profile->get_mixbus()) { pp->add (PFLFromBeforeProcessors, _("before pre-fader processors")); pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors")); - add_option (_("Solo / mute"), pp); + add_option (_("Solo & mute"), pp); ComboOption* pa = new ComboOption ( "afl-position", @@ -2496,11 +2941,11 @@ if (!Profile->get_mixbus()) { pa->add (AFLFromBeforeProcessors, _("immediately post-fader")); pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)")); - add_option (_("Solo / mute"), pa); + add_option (_("Solo & mute"), pa); - add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options"))); + add_option (_("Solo & mute"), new OptionEditorHeading (_("Default track / bus muting options"))); - add_option (_("Solo / mute"), + add_option (_("Solo & mute"), new BoolOption ( "mute-affects-pre-fader", _("Mute affects pre-fader sends"), @@ -2508,7 +2953,7 @@ if (!Profile->get_mixbus()) { sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader) )); - add_option (_("Solo / mute"), + add_option (_("Solo & mute"), new BoolOption ( "mute-affects-post-fader", _("Mute affects post-fader sends"), @@ -2516,7 +2961,7 @@ if (!Profile->get_mixbus()) { sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader) )); - add_option (_("Solo / mute"), + add_option (_("Solo & mute"), new BoolOption ( "mute-affects-control-outs", _("Mute affects control outputs"), @@ -2524,7 +2969,7 @@ if (!Profile->get_mixbus()) { sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs) )); - add_option (_("Solo / mute"), + add_option (_("Solo & mute"), new BoolOption ( "mute-affects-main-outs", _("Mute affects main outputs"), @@ -2532,15 +2977,17 @@ if (!Profile->get_mixbus()) { sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs) )); - add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing"))); - add_option (_("Solo / mute"), +if (!ARDOUR::Profile->get_mixbus()) { + add_option (_("Solo & mute"), new OptionEditorHeading (_("Send Routing"))); + add_option (_("Solo & mute"), new BoolOption ( "link-send-and-route-panner", _("Link panners of Aux and External Sends with main panner by default"), sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner), sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner) )); +} add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Preferences"))); @@ -2595,9 +3042,21 @@ if (!Profile->get_mixbus()) { sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback) )); - add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Clock"))); + add_option (_("MIDI/Ports"), new OptionEditorHeading (_("MIDI Port Options"))); - add_option (_("MIDI"), + add_option (_("MIDI/Ports"), + new BoolOption ( + "get-midi-input-follows-selection", + _("MIDI input follows MIDI track selection"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_input_follows_selection), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_input_follows_selection) + )); + + add_option (_("MIDI/Ports"), new MidiPortOptions ()); + + add_option (_("MIDI/Sync"), new OptionEditorHeading (_("MIDI Clock"))); + + add_option (_("MIDI/Sync"), new BoolOption ( "send-midi-clock", _("Send MIDI Clock"), @@ -2605,9 +3064,9 @@ if (!Profile->get_mixbus()) { sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock) )); - add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC)"))); + add_option (_("MIDI/Sync"), new OptionEditorHeading (_("MIDI Time Code (MTC)"))); - add_option (_("MIDI"), + add_option (_("MIDI/Sync"), new BoolOption ( "send-mtc", _("Send MIDI Time Code"), @@ -2615,7 +3074,7 @@ if (!Profile->get_mixbus()) { sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc) )); - add_option (_("MIDI"), + add_option (_("MIDI/Sync"), new SpinOption ( "mtc-qf-speed-tolerance", _("Percentage either side of normal transport speed to transmit MTC"), @@ -2624,9 +3083,9 @@ if (!Profile->get_mixbus()) { 0, 20, 1, 5 )); - add_option (_("MIDI"), new OptionEditorHeading (_("Midi Machine Control (MMC)"))); + add_option (_("MIDI/Sync"), new OptionEditorHeading (_("Midi Machine Control (MMC)"))); - add_option (_("MIDI"), + add_option (_("MIDI/Sync"), new BoolOption ( "mmc-control", _("Obey MIDI Machine Control commands"), @@ -2634,7 +3093,7 @@ if (!Profile->get_mixbus()) { sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control) )); - add_option (_("MIDI"), + add_option (_("MIDI/Sync"), new BoolOption ( "send-mmc", _("Send MIDI Machine Control commands"), @@ -2642,7 +3101,7 @@ if (!Profile->get_mixbus()) { sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc) )); - add_option (_("MIDI"), + add_option (_("MIDI/Sync"), new SpinOption ( "mmc-receive-device-id", _("Inbound MMC device ID"), @@ -2651,7 +3110,7 @@ if (!Profile->get_mixbus()) { 0, 128, 1, 10 )); - add_option (_("MIDI"), + add_option (_("MIDI/Sync"), new SpinOption ( "mmc-send-device-id", _("Outbound MMC device ID"), @@ -2679,62 +3138,34 @@ if (!Profile->get_mixbus()) { if (manager.get_status (*i) == PluginManager::Hidden) continue; if (!(*i)->is_instrument()) continue; if ((*i)->type != ARDOUR::LV2) continue; - audition_synth->add((*i)->unique_id, (*i)->name); + if ((*i)->name.length() > 46) { + audition_synth->add((*i)->unique_id, (*i)->name.substr (0, 44) + "..."); + } else { + audition_synth->add((*i)->unique_id, (*i)->name); + } } #endif add_option (_("MIDI"), audition_synth); - /* USER INTERACTION */ - - if ( -#ifdef PLATFORM_WINDOWS - true -#else - getenv ("ARDOUR_BUNDLED") -#endif - ) - { - add_option (_("User interaction"), - new BoolOption ( - "enable-translation", - string_compose (_("Use translations of %1 messages\n" - " (requires a restart of %1 to take effect)\n" - " (if available for your language preferences)"), PROGRAM_NAME), - sigc::ptr_fun (ARDOUR::translations_are_enabled), - sigc::ptr_fun (ARDOUR::set_translations_enabled))); - } - - add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard"))); - - add_option (_("User interaction"), new KeyboardOptions); - /* Control Surfaces */ - add_option (_("Control Surfaces"), new ControlSurfacesOptions); - - ComboOption* rm = new ComboOption ( - "remote-model", - _("Control surface remote ID"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model) - ); - - rm->add (UserOrdered, _("assigned by user")); - rm->add (MixerOrdered, _("follows order of mixer")); - - add_option (_("Control Surfaces"), rm); + add_option (_("Control Surfaces"), new ControlSurfacesOptions ()); /* VIDEO Timeline */ add_option (_("Video"), new VideoTimelineOptions (_rc_config)); -#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT) - add_option (_("Plugins"), new OptionEditorHeading (_("General"))); - +#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT) + add_option (_("Plugins"), new OptionEditorHeading (_("Scan/Discover"))); add_option (_("Plugins"), new RcActionButton (_("Scan for Plugins"), sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh))); +#endif + + add_option (_("Plugins"), new OptionEditorHeading (_("General"))); + +#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT) bo = new BoolOption ( "show-plugin-scan-window", _("Always Display Plugin Scan Progress"), @@ -2744,11 +3175,43 @@ if (!Profile->get_mixbus()) { add_option (_("Plugins"), bo); Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(), _("When enabled a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)")); - #endif -#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT) - add_option (_("Plugins"), new OptionEditorHeading (_("VST"))); + bo = new BoolOption ( + "plugins-stop-with-transport", + _("Silence plugins when the transport is stopped"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport) + ); + add_option (_("Plugins"), bo); + Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(), + _("When enabled plugins will be reset at transport stop. When disabled plugins will be left unchanged at transport stop.\n\nThis mostly affects plugins with a \"tail\" like Reverbs.")); + + bo = new BoolOption ( + "new-plugins-active", + _("Make new plugins active"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active) + ); + add_option (_("Plugins"), bo); + Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(), + _("When enabled plugins will be activated when they are added to tracks/busses. When disabled plugins will be left inactive when they are added to tracks/busses")); + +#if (defined WINDOWS_VST_SUPPORT || defined MACVST_SUPPORT || defined LXVST_SUPPORT) + add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST"))); + add_option (_("Plugins/VST"), + new RcActionButton (_("Scan for Plugins"), + sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh))); + +#if (defined AUDIOUNIT_SUPPORT && defined MACVST_SUPPORT) + bo = new BoolOption ( + "", + _("Enable Mac VST support (requires restart or re-scan)"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_macvst), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_macvst) + ); + add_option (_("Plugins/VST"), bo); +#endif bo = new BoolOption ( "discover-vst-on-start", @@ -2756,7 +3219,7 @@ if (!Profile->get_mixbus()) { sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start), sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start) ); - add_option (_("Plugins"), bo); + add_option (_("Plugins/VST"), bo); Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(), _("When enabled new VST plugins are searched, tested and added to the cache index on application start. When disabled new plugins will only be available after triggering a 'Scan' manually")); @@ -2768,40 +3231,40 @@ if (!Profile->get_mixbus()) { sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan), sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan) ); - add_option (_("Plugins"), bo); + add_option (_("Plugins/VST"), bo); Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(), _("When enabled additional information for every plugin is added to the Log Window.")); #endif - add_option (_("Plugins"), new VstTimeOutSliderOption (_rc_config)); + add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config)); - add_option (_("Plugins"), + add_option (_("Plugins/VST"), new RcActionButton (_("Clear"), sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache), _("VST Cache:"))); - add_option (_("Plugins"), + add_option (_("Plugins/VST"), new RcActionButton (_("Clear"), sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist), _("VST Blacklist:"))); #endif #ifdef LXVST_SUPPORT - add_option (_("Plugins"), + add_option (_("Plugins/VST"), new RcActionButton (_("Edit"), sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path), _("Linux VST Path:"))); - add_option (_("Plugins"), + add_option (_("Plugins/VST"), new RcConfigDisplay ( "plugin-path-lxvst", _("Path:"), sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst), - ':')); + 0)); #endif #ifdef WINDOWS_VST_SUPPORT - add_option (_("Plugins"), + add_option (_("Plugins/VST"), new RcActionButton (_("Edit"), sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path), _("Windows VST Path:"))); @@ -2814,41 +3277,87 @@ if (!Profile->get_mixbus()) { #endif #ifdef AUDIOUNIT_SUPPORT - add_option (_("Plugins"), new OptionEditorHeading (_("Audio Unit"))); + + add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit"))); + add_option (_("Plugins/Audio Unit"), + new RcActionButton (_("Scan for Plugins"), + sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh))); bo = new BoolOption ( "discover-audio-units", - _("Scan for AudioUnit Plugins on Application Start"), + _("Scan for [new] AudioUnit Plugins on Application Start"), sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units), sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units) ); - add_option (_("Plugins"), bo); + add_option (_("Plugins/Audio Unit"), bo); Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(), _("When enabled Audio Unit Plugins are discovered on application start. When disabled AU plugins will only be available after triggering a 'Scan' manually. The first successful scan will enable AU auto-scan, Any crash during plugin discovery will disable it.")); - add_option (_("Plugins"), + add_option (_("Plugins/Audio Unit"), new RcActionButton (_("Clear"), sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache), _("AU Cache:"))); - add_option (_("Plugins"), + add_option (_("Plugins/Audio Unit"), new RcActionButton (_("Clear"), sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist), _("AU Blacklist:"))); #endif -#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2) +#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2) add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI"))); add_option (_("Plugins"), new BoolOption ( "open-gui-after-adding-plugin", _("Automatically open the plugin GUI when adding a new plugin"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_open_gui_after_adding_plugin), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_open_gui_after_adding_plugin) + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin) + )); + +#if (defined LV2_SUPPORT && defined LV2_EXTENDED) + add_option (_("Plugins"), + new BoolOption ( + "show-inline-display-by-default", + _("Show Plugin Inline Display on Mixerstrip by default"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default) )); + + _plugin_prefer_inline = new BoolOption ( + "prefer-inline-over-gui", + _("Don't automatically open the plugin GUI when the plugin has an inline display mode"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui) + ); + add_option (_("Plugins"), _plugin_prefer_inline); +#endif + + add_option (_("Plugins"), new OptionEditorHeading (_("Instrument"))); + + bo = new BoolOption ( + "ask-replace-instrument", + _("Ask to replace existing instrument plugin"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument) + ); + add_option (_("Plugins"), bo); + + bo = new BoolOption ( + "ask-setup_instrument", + _("Interactively configure instrument plugins on insert"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument) + ); + add_option (_("Plugins"), bo); + Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(), + _("When enabled show a dialog to select instrument channel configuration before adding a multichannel plugin.")); + #endif /* INTERFACE */ +#if (defined OPTIONAL_CAIRO_IMAGE_SURFACE || defined CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE) + add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Graphics Acceleration"))); +#endif #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE BoolOption* bgc = new BoolOption ( @@ -2875,6 +3384,15 @@ if (!Profile->get_mixbus()) { add_option (S_("Preferences|GUI"), bgo); #endif + add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Graphical User Interface"))); + add_option (S_("Preferences|GUI"), + new BoolOption ( + "use-wm-visibility", + _("Use Window Manager/Desktop visibility information"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility) + )); + add_option (S_("Preferences|GUI"), new BoolOption ( "widget-prelight", @@ -2883,7 +3401,6 @@ if (!Profile->get_mixbus()) { sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight) )); -#ifdef TOOLTIPS_GOT_FIXED add_option (S_("Preferences|GUI"), new BoolOption ( "use-tooltips", @@ -2891,7 +3408,6 @@ if (!Profile->get_mixbus()) { sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips), sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips) )); -#endif add_option (S_("Preferences|GUI"), new BoolOption ( @@ -2901,7 +3417,7 @@ if (!Profile->get_mixbus()) { sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight) )); - add_option (S_("GUI"), + add_option (S_("Preferences|GUI"), new BoolOption ( "super-rapid-clock-update", _("Update transport clock display at FPS instead of every 100ms"), @@ -2910,7 +3426,7 @@ if (!Profile->get_mixbus()) { )); -#ifndef GTKOSX +#ifndef __APPLE__ /* font scaling does nothing with GDK/Quartz */ add_option (S_("Preferences|GUI"), new FontScalingOptions ()); #endif @@ -2956,6 +3472,7 @@ if (!ARDOUR::Profile->get_mixbus()) { _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock")); _mixer_strip_visibility.add (0, X_("Output"), _("Output")); _mixer_strip_visibility.add (0, X_("Comments"), _("Comments")); + _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns")); add_option ( S_("Preferences|GUI"), @@ -2975,6 +3492,84 @@ if (!ARDOUR::Profile->get_mixbus()) { sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms) )); +#ifdef ENABLE_NLS + OptionEditorHeading* i18n_head = new OptionEditorHeading (_("Internationalization")); + i18n_head->set_note (string_compose (_("These settings will only take effect after %1 is restarted (if available for your language preferences)."), PROGRAM_NAME)); + + add_option (_("GUI/Translation"), i18n_head); + + bo = new BoolOption ( + "enable-translation", + _("Use translations"), + sigc::ptr_fun (ARDOUR::translations_are_enabled), + sigc::ptr_fun (ARDOUR::set_translations_enabled) + ); + + add_option (_("GUI/Translation"), bo); + + _l10n = new ComboOption ( + "locale-mode", + _("Localization"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_locale_mode), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_locale_mode) + ); + + _l10n->add (ARDOUR::SET_LC_ALL, _("Set complete locale")); + _l10n->add (ARDOUR::SET_LC_MESSAGES, _("Enable only message translation")); + _l10n->add (ARDOUR::SET_LC_MESSAGES_AND_LC_NUMERIC, _("Translate messages and format numeric format")); + _l10n->set_note (_("This setting is provided for plugin compatibility. e.g. some plugins on some systems expect the decimal point to be a dot.")); + + add_option (_("GUI/Translation"), _l10n); + parameter_changed ("enable-translation"); +#endif // ENABLE_NLS + + add_option (_("GUI/Keyboard"), new OptionEditorHeading (_("Keyboard"))); + add_option (_("GUI/Keyboard"), new KeyboardOptions); + + add_option (_("GUI/Toolbar"), new OptionEditorHeading (_("Main Transport Toolbar Items"))); + + add_option (_("GUI/Toolbar"), + new BoolOption ( + "show-toolbar-selclock", + _("Display Selection Clock in the Toolbar"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_toolbar_selclock), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_toolbar_selclock) + )); + + if (!ARDOUR::Profile->get_small_screen()) { + add_option (_("GUI/Toolbar"), + new BoolOption ( + "show-secondary-clock", + _("Display Secondary Clock in the Toolbar"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_secondary_clock), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_secondary_clock) + )); + } + + add_option (_("GUI/Toolbar"), + new BoolOption ( + "show-mini-timeline", + _("Display Navigation Timeline in the Toolbar"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_mini_timeline), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_mini_timeline) + )); + + add_option (_("GUI/Toolbar"), + new BoolOption ( + "show-editor-meter", + _("Display Master Level Meter in the Toolbar"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter) + )); + + add_option (_("GUI/Toolbar"), + new ColumVisibilityOption ( + "action-table-columns", _("Lua Action Script Button Visibility"), 4, + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns) + ) + ); + add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering"))); ComboOption* mht = new ComboOption ( @@ -3112,7 +3707,7 @@ if (!ARDOUR::Profile->get_mixbus()) { Gtkmm2ext::UI::instance()->set_tip (mpks->tip_widget(), - _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red.")); + _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red.")); add_option (S_("Preferences|Metering"), mpks); @@ -3124,15 +3719,57 @@ if (!ARDOUR::Profile->get_mixbus()) { sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led) )); + add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Editor Meters"))); + + add_option (S_("Preferences|Metering"), + new BoolOption ( + "show-track-meters", + _("Show meters on tracks in the editor"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters) + )); + + add_option (S_("Preferences|Metering"), + new BoolOption ( + "editor-stereo-only-meters", + _("Show at most stereo meters in the track-header"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters) + )); + + add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis"))); + + add_option (S_("Preferences|Metering"), + new BoolOption ( + "save-export-analysis-image", + _("Save loudness analysis as image file"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image) + )); + /* and now the theme manager */ ThemeManager* tm = manage (new ThemeManager); + add_option (_("Theme"), new OptionEditorHeading (_("Theme"))); add_page (_("Theme"), *tm); + add_option (_("Theme/Colors"), new ColorThemeManager); + + Widget::show_all (); + //trigger some parameter-changed messages which affect widget-visibility or -sensitivity parameter_changed ("send-ltc"); parameter_changed ("sync-source"); parameter_changed ("use-monitor-bus"); + parameter_changed ("open-gui-after-adding-plugin"); + + XMLNode* node = ARDOUR_UI::instance()->preferences_settings(); + if (node) { + /* gcc4 complains about ambiguity with Gtk::Widget::set_state + (Gtk::StateType) here !!! + */ + Tabbable::set_state (*node, Stateful::loading_state_version); + } } void @@ -3170,6 +3807,14 @@ RCOptionEditor::parameter_changed (string const & p) bool const s = Config->get_send_ltc (); _ltc_send_continuously->set_sensitive (s); _ltc_volume_slider->set_sensitive (s); + } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") { +#if (defined LV2_SUPPORT && defined LV2_EXTENDED) + _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default()); +#endif +#ifdef ENABLE_NLS + } else if (p == "enable-translation") { + _l10n->set_sensitive (ARDOUR::translations_are_enabled ()); +#endif } } @@ -3200,10 +3845,10 @@ void RCOptionEditor::clear_au_blacklist () { void RCOptionEditor::edit_lxvst_path () { Glib::RefPtr win = get_parent_window (); Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog ( - *this, _("Set Linux VST Search Path"), - _rc_config->get_plugin_path_lxvst(), - PluginManager::instance().get_default_lxvst_path() - ); + *current_toplevel(), _("Set Linux VST Search Path"), + _rc_config->get_plugin_path_lxvst(), + PluginManager::instance().get_default_lxvst_path() + ); ResponseType r = (ResponseType) pd->run (); pd->hide(); if (r == RESPONSE_ACCEPT) { @@ -3214,10 +3859,10 @@ void RCOptionEditor::edit_lxvst_path () { void RCOptionEditor::edit_vst_path () { Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog ( - *this, _("Set Windows VST Search Path"), - _rc_config->get_plugin_path_vst(), - PluginManager::instance().get_default_windows_vst_path() - ); + *current_toplevel(), _("Set Windows VST Search Path"), + _rc_config->get_plugin_path_vst(), + PluginManager::instance().get_default_windows_vst_path() + ); ResponseType r = (ResponseType) pd->run (); pd->hide(); if (r == RESPONSE_ACCEPT) { @@ -3250,18 +3895,24 @@ RCOptionEditor::populate_sync_options () } Gtk::Window* -RCOptionEditor::use_own_window () +RCOptionEditor::use_own_window (bool and_fill_it) { - bool new_window = !own_window(); - - Gtk::Window* win = Tabbable::use_own_window (); + bool new_window = !own_window (); + + Gtk::Window* win = Tabbable::use_own_window (and_fill_it); if (win && new_window) { win->set_name ("PreferencesWindow"); ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this); - - cerr << "created prefs window\n"; } return win; } + +XMLNode& +RCOptionEditor::get_state () +{ + XMLNode* node = new XMLNode (X_("Preferences")); + node->add_child_nocopy (Tabbable::get_state()); + return *node; +}