X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Frc_option_editor.cc;h=b2eaddfafbea80782ad83fdfe0c3ffaf0c6072c4;hb=234b06a18cf3e8c07bc44fb4f8c1218e17fb65f1;hp=ccb0e5fcddaf4be56a343f7b50568ec769a41685;hpb=59076a7e4c66db12bbbfbf01f012ca2f6ba4bf56;p=ardour.git diff --git a/gtk2_ardour/rc_option_editor.cc b/gtk2_ardour/rc_option_editor.cc index ccb0e5fcdd..b2eaddfafb 100644 --- a/gtk2_ardour/rc_option_editor.cc +++ b/gtk2_ardour/rc_option_editor.cc @@ -21,17 +21,29 @@ #include "gtk2ardour-config.h" #endif +#if !defined USE_CAIRO_IMAGE_SURFACE && !defined NDEBUG +#define OPTIONAL_CAIRO_IMAGE_SURFACE +#endif + +#include + +#include + #include #include #include + #include #include #include +#include +#include #include "pbd/fpu.h" #include "pbd/cpus.h" #include "ardour/audioengine.h" +#include "ardour/profile.h" #include "ardour/dB.h" #include "ardour/rc_configuration.h" #include "ardour/control_protocol_manager.h" @@ -42,13 +54,17 @@ #include "ardour_window.h" #include "ardour_dialog.h" +#include "ardour_ui.h" #include "gui_thread.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 "ui_config.h" #include "i18n.h" using namespace std; @@ -56,35 +72,59 @@ using namespace Gtk; using namespace Gtkmm2ext; using namespace PBD; using namespace ARDOUR; +using namespace ARDOUR_UI_UTILS; class ClickOptions : public OptionEditorBox { public: - ClickOptions (RCConfiguration* c, Gtk::Window* p) - : _rc_config (c), - _parent (p) + ClickOptions (RCConfiguration* c) + : _rc_config (c) + , _click_browse_button (_("Browse...")) + , _click_emphasis_browse_button (_("Browse...")) { - Table* t = manage (new Table (2, 3)); + Table* t = manage (new Table (4, 3)); t->set_spacings (4); - Label* l = manage (left_aligned_label (_("Click audio file:"))); + 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.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 (_click_path_entry, 1, 2, 0, 1, FILL); - Button* b = manage (new Button (_("Browse..."))); - b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_browse_clicked)); - t->attach (*b, 2, 3, 0, 1, FILL); + t->attach (_use_default_click_check_button, 1, 2, 0, 1, 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); + _click_browse_button.signal_clicked ().connect ( + sigc::mem_fun (*this, &ClickOptions::click_browse_clicked)); + t->attach (_click_browse_button, 2, 3, 2, 3, FILL); l = manage (left_aligned_label (_("Click emphasis audio file:"))); - t->attach (*l, 0, 1, 1, 2, FILL); - t->attach (_click_emphasis_path_entry, 1, 2, 1, 2, FILL); - b = manage (new Button (_("Browse..."))); - b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked)); - t->attach (*b, 2, 3, 1, 2, FILL); - + t->attach (*l, 0, 1, 3, 4, FILL); + t->attach (_click_emphasis_path_entry, 1, 2, 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); + _box->pack_start (*t, false, false); - _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed)); + _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)); + + if (_rc_config->get_click_sound ().empty() && + _rc_config->get_click_emphasis_sound().empty()) { + _use_default_click_check_button.set_active (true); + _use_emphasis_on_click_check_button.set_active (true); + + } else { + _use_default_click_check_button.set_active (false); + _use_emphasis_on_click_check_button.set_active (false); + } } void parameter_changed (string const & p) @@ -93,6 +133,9 @@ public: _click_path_entry.set_text (_rc_config->get_click_sound()); } else if (p == "click-emphasis-sound") { _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound()); + } else if (p == "use-click-emphasis") { + bool x = _rc_config->get_use_click_emphasis (); + _use_emphasis_on_click_check_button.set_active (x); } } @@ -100,6 +143,7 @@ public: { parameter_changed ("click-sound"); parameter_changed ("click-emphasis-sound"); + parameter_changed ("use-click-emphasis"); } private: @@ -108,6 +152,9 @@ private: { SoundFileChooser sfdb (_("Choose Click")); + sfdb.show_all (); + sfdb.present (); + if (sfdb.run () == RESPONSE_OK) { click_chosen (sfdb.get_filename()); } @@ -123,7 +170,7 @@ private: { click_chosen (_click_path_entry.get_text ()); } - + void click_emphasis_browse_clicked () { SoundFileChooser sfdb (_("Choose Click Emphasis")); @@ -147,10 +194,39 @@ private: click_emphasis_chosen (_click_emphasis_path_entry.get_text ()); } + void use_default_click_toggled () + { + if (_use_default_click_check_button.get_active ()) { + _rc_config->set_click_sound (""); + _rc_config->set_click_emphasis_sound (""); + _click_path_entry.set_sensitive (false); + _click_emphasis_path_entry.set_sensitive (false); + _click_browse_button.set_sensitive (false); + _click_emphasis_browse_button.set_sensitive (false); + } else { + _click_path_entry.set_sensitive (true); + _click_emphasis_path_entry.set_sensitive (true); + _click_browse_button.set_sensitive (true); + _click_emphasis_browse_button.set_sensitive (true); + } + } + + void use_emphasis_on_click_toggled () + { + if (_use_emphasis_on_click_check_button.get_active ()) { + _rc_config->set_use_click_emphasis(true); + } else { + _rc_config->set_use_click_emphasis(false); + } + } + RCConfiguration* _rc_config; - Gtk::Window* _parent; + CheckButton _use_default_click_check_button; + CheckButton _use_emphasis_on_click_check_button; Entry _click_path_entry; Entry _click_emphasis_path_entry; + Button _click_browse_button; + Button _click_emphasis_browse_button; }; class UndoOptions : public OptionEditorBox @@ -251,31 +327,36 @@ static const struct { { "Unmodified", 0 }, -#ifdef GTKOSX +#ifdef __APPLE__ /* Command = Meta Option/Alt = Mod1 */ { "Key|Shift", GDK_SHIFT_MASK }, - { "Command", GDK_META_MASK }, + { "Command", GDK_MOD2_MASK }, { "Control", GDK_CONTROL_MASK }, { "Option", GDK_MOD1_MASK }, - { "Command-Shift", GDK_META_MASK|GDK_SHIFT_MASK }, - { "Command-Option", GDK_MOD1_MASK|GDK_META_MASK }, - { "Shift-Option", GDK_SHIFT_MASK|GDK_MOD1_MASK }, - { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_META_MASK }, + { "Command-Shift", GDK_MOD2_MASK|GDK_SHIFT_MASK }, + { "Command-Option", GDK_MOD2_MASK|GDK_MOD1_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 }, + { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK }, + { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_MOD2_MASK }, #else { "Key|Shift", GDK_SHIFT_MASK }, { "Control", GDK_CONTROL_MASK }, - { "Alt (Mod1)", GDK_MOD1_MASK }, + { "Alt", GDK_MOD1_MASK }, { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK }, { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK }, - { "Shift-Alt", GDK_SHIFT_MASK|GDK_MOD1_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 }, + { "Alt-Shift-Windows", GDK_MOD1_MASK|GDK_SHIFT_MASK|GDK_MOD4_MASK }, { "Mod2", GDK_MOD2_MASK }, { "Mod3", GDK_MOD3_MASK }, - { "Mod4", GDK_MOD4_MASK }, + { "Windows", GDK_MOD4_MASK }, { "Mod5", GDK_MOD5_MASK }, #endif { 0, 0 } @@ -293,6 +374,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."); /* internationalize and prepare for use with combos */ vector dumb; @@ -302,7 +384,8 @@ public: set_popdown_strings (_edit_modifier_combo, dumb); _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen)); - + Gtkmm2ext::UI::instance()->set_tip (_edit_modifier_combo, + (string_compose (_("Recommended Setting: %1 + button 3 (right mouse button)%2"), Keyboard::primary_modifier_name (), restart_msg))); for (int x = 0; modifiers[x].name; ++x) { if (modifiers[x].modifier == Keyboard::edit_modifier ()) { _edit_modifier_combo.set_active_text (S_(modifiers[x].name)); @@ -310,28 +393,61 @@ public: } } - Table* t = manage (new Table (4, 4)); + Table* t = manage (new Table (5, 11)); t->set_spacings (4); - Label* l = manage (left_aligned_label (_("Edit using:"))); + int row = 0; + int col = 0; + + Label* l = manage (left_aligned_label (_("Select Keyboard layout:"))); + l->set_name ("OptionsLabel"); + + vector strs; + + for (map::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) { + strs.push_back (bf->first); + } + + set_popdown_strings (_keyboard_layout_selector, strs); + _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name()); + _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed)); + + t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL); + t->attach (_keyboard_layout_selector, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL); + + ++row; + col = 0; + + l = manage (left_aligned_label (_("When Clicking:"))); + l->set_name ("OptionEditorHeading"); + t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL); + + ++row; + col = 1; + + l = manage (left_aligned_label (_("Edit using:"))); l->set_name ("OptionsLabel"); - t->attach (*l, 0, 1, 0, 1, FILL | EXPAND, FILL); - t->attach (_edit_modifier_combo, 1, 2, 0, 1, FILL | EXPAND, FILL); + t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL); + t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL); l = manage (new Label (_("+ button"))); l->set_name ("OptionsLabel"); - t->attach (*l, 3, 4, 0, 1, FILL | EXPAND, FILL); - t->attach (_edit_button_spin, 4, 5, 0, 1, FILL | EXPAND, FILL); + t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL); + t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL); _edit_button_spin.set_name ("OptionsEntry"); _edit_button_adjustment.set_value (Keyboard::edit_button()); _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed)); + ++row; + col = 1; + set_popdown_strings (_delete_modifier_combo, dumb); _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen)); - + Gtkmm2ext::UI::instance()->set_tip (_delete_modifier_combo, + (string_compose (_("Recommended Setting: %1 + button 3 (right mouse button)%2"), Keyboard::tertiary_modifier_name (), restart_msg))); for (int x = 0; modifiers[x].name; ++x) { if (modifiers[x].modifier == Keyboard::delete_modifier ()) { _delete_modifier_combo.set_active_text (S_(modifiers[x].name)); @@ -342,23 +458,26 @@ public: l = manage (left_aligned_label (_("Delete using:"))); l->set_name ("OptionsLabel"); - t->attach (*l, 0, 1, 1, 2, FILL | EXPAND, FILL); - t->attach (_delete_modifier_combo, 1, 2, 1, 2, FILL | EXPAND, FILL); + t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL); + t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL); l = manage (new Label (_("+ button"))); l->set_name ("OptionsLabel"); - t->attach (*l, 3, 4, 1, 2, FILL | EXPAND, FILL); - t->attach (_delete_button_spin, 4, 5, 1, 2, FILL | EXPAND, FILL); + t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL); + t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL); _delete_button_spin.set_name ("OptionsEntry"); _delete_button_adjustment.set_value (Keyboard::delete_button()); _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed)); + ++row; + col = 1; set_popdown_strings (_insert_note_modifier_combo, dumb); _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen)); - + Gtkmm2ext::UI::instance()->set_tip (_insert_note_modifier_combo, + (string_compose (_("Recommended Setting: %1 + button 1 (left mouse button)%2"), Keyboard::primary_modifier_name (), restart_msg))); for (int x = 0; modifiers[x].name; ++x) { if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) { _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name)); @@ -369,23 +488,191 @@ public: l = manage (left_aligned_label (_("Insert note using:"))); l->set_name ("OptionsLabel"); - t->attach (*l, 0, 1, 2, 3, FILL | EXPAND, FILL); - t->attach (_insert_note_modifier_combo, 1, 2, 2, 3, FILL | EXPAND, FILL); + t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL); + t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL); l = manage (new Label (_("+ button"))); l->set_name ("OptionsLabel"); - t->attach (*l, 3, 4, 2, 3, FILL | EXPAND, FILL); - t->attach (_insert_note_button_spin, 4, 5, 2, 3, FILL | EXPAND, FILL); + t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL); + t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL); _insert_note_button_spin.set_name ("OptionsEntry"); _insert_note_button_adjustment.set_value (Keyboard::insert_note_button()); _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed)); + ++row; + + l = manage (left_aligned_label (_("When Beginning a Drag:"))); + l->set_name ("OptionEditorHeading"); + t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL); + + ++row; + col = 1; + + /* copy modifier */ + set_popdown_strings (_copy_modifier_combo, dumb); + _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 __APPLE__ + Keyboard::secondary_modifier_name (), +#else + Keyboard::primary_modifier_name (), +#endif + restart_msg))); + for (int x = 0; modifiers[x].name; ++x) { + if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) { + _copy_modifier_combo.set_active_text (S_(modifiers[x].name)); + break; + } + } + + l = manage (left_aligned_label (_("Copy items using:"))); + l->set_name ("OptionsLabel"); + + t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL); + t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL); + + ++row; + col = 1; + + /* constraint modifier */ + set_popdown_strings (_constraint_modifier_combo, dumb); + _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen)); + Gtkmm2ext::UI::instance()->set_tip (_constraint_modifier_combo, + (string_compose (_("Recommended Setting: %1%2"), +#ifdef __APPLE__ + Keyboard::primary_modifier_name (), +#else + Keyboard::secondary_modifier_name (), +#endif + restart_msg))); + for (int x = 0; modifiers[x].name; ++x) { + if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) { + _constraint_modifier_combo.set_active_text (S_(modifiers[x].name)); + break; + } + } + + l = manage (left_aligned_label (_("Constrain drag using:"))); + l->set_name ("OptionsLabel"); + + 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; + + l = manage (left_aligned_label (_("When Beginning a Trim:"))); + l->set_name ("OptionEditorHeading"); + t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL); + + ++row; + col = 1; + + /* trim_contents */ + set_popdown_strings (_trim_contents_combo, dumb); + _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen)); + Gtkmm2ext::UI::instance()->set_tip (_trim_contents_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::trim_contents_modifier ()) { + _trim_contents_combo.set_active_text (S_(modifiers[x].name)); + break; + } + } + + l = manage (left_aligned_label (_("Trim contents using:"))); + l->set_name ("OptionsLabel"); + + t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL); + t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL); + + ++row; + col = 1; + + /* anchored trim */ + set_popdown_strings (_trim_anchored_combo, dumb); + _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen)); + Gtkmm2ext::UI::instance()->set_tip (_trim_anchored_combo, + (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::trim_anchored_modifier ()) { + _trim_anchored_combo.set_active_text (S_(modifiers[x].name)); + break; + } + } + + l = manage (left_aligned_label (_("Anchored trim using:"))); + l->set_name ("OptionsLabel"); + t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL); + ++col; + t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL); + + ++row; + col = 1; + + /* jump trim disabled for now + set_popdown_strings (_trim_jump_combo, dumb); + _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen)); + + for (int x = 0; modifiers[x].name; ++x) { + if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) { + _trim_jump_combo.set_active_text (S_(modifiers[x].name)); + break; + } + } + + l = manage (left_aligned_label (_("Jump after trim using:"))); + l->set_name ("OptionsLabel"); + + t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL); + ++col; + t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL); + + ++row; + col = 1; + */ + + /* note resize relative */ + 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))); + 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)); + break; + } + } + + l = manage (left_aligned_label (_("Resize notes relatively using:"))); + l->set_name ("OptionsLabel"); + + t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL); + ++col; + t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL); + + ++row; + + l = manage (left_aligned_label (_("While Dragging:"))); + l->set_name ("OptionEditorHeading"); + t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL); + + ++row; + col = 1; + + /* ignore snap */ set_popdown_strings (_snap_modifier_combo, dumb); _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen)); - +#ifdef __APPLE__ + Glib::ustring mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ()); +#else + Glib::ustring 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))); for (int x = 0; modifiers[x].name; ++x) { if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) { _snap_modifier_combo.set_active_text (S_(modifiers[x].name)); @@ -396,24 +683,113 @@ public: l = manage (left_aligned_label (_("Ignore snap using:"))); l->set_name ("OptionsLabel"); - t->attach (*l, 0, 1, 3, 4, FILL | EXPAND, FILL); - t->attach (_snap_modifier_combo, 1, 2, 3, 4, FILL | EXPAND, FILL); + t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL); + t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL); - vector strs; + ++row; + col = 1; - for (map::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) { - strs.push_back (bf->first); + /* 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 __APPLE__ + mod_str = Keyboard::level4_modifier_name (); +#else + mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::level4_modifier_name ()); +#endif + Gtkmm2ext::UI::instance()->set_tip (_snap_delta_combo, + (string_compose (_("Recommended Setting: %1%2"), mod_str, restart_msg))); + for (int x = 0; modifiers[x].name; ++x) { + if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) { + _snap_delta_combo.set_active_text (S_(modifiers[x].name)); + break; + } } - set_popdown_strings (_keyboard_layout_selector, strs); - _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name()); - _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed)); + l = manage (left_aligned_label (_("Snap relatively using:"))); + l->set_name ("OptionsLabel"); + + t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL); + t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL); + + ++row; + + l = manage (left_aligned_label (_("While Trimming:"))); + l->set_name ("OptionEditorHeading"); + t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL); + + ++row; + col = 1; + + /* trim_overlap */ + set_popdown_strings (_trim_overlap_combo, dumb); + _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen)); + + Gtkmm2ext::UI::instance()->set_tip (_trim_overlap_combo, + (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::trim_overlap_modifier ()) { + _trim_overlap_combo.set_active_text (S_(modifiers[x].name)); + break; + } + } + + l = manage (left_aligned_label (_("Resize overlapped regions using:"))); + l->set_name ("OptionsLabel"); + + t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL); + t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL); + + ++row; + + l = manage (left_aligned_label (_("While Dragging Control Points:"))); + l->set_name ("OptionEditorHeading"); + t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL); + + ++row; + col = 1; + + /* fine adjust */ + 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 ()); + 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) { + if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) { + _fine_adjust_combo.set_active_text (S_(modifiers[x].name)); + break; + } + } + + l = manage (left_aligned_label (_("Fine adjust using:"))); + l->set_name ("OptionsLabel"); + + 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); - l = manage (left_aligned_label (_("Keyboard layout:"))); + ++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, 0, 1, 4, 5, FILL | EXPAND, FILL); - t->attach (_keyboard_layout_selector, 1, 2, 4, 5, FILL | EXPAND, FILL); + 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); } @@ -469,6 +845,18 @@ private: } } + void copy_modifier_chosen () + { + string const txt = _copy_modifier_combo.get_active_text(); + + for (int i = 0; modifiers[i].name; ++i) { + if (txt == _(modifiers[i].name)) { + Keyboard::set_copy_modifier (modifiers[i].modifier); + break; + } + } + } + void insert_note_modifier_chosen () { string const txt = _insert_note_modifier_combo.get_active_text(); @@ -493,6 +881,102 @@ private: } } + void snap_delta_modifier_chosen () + { + string const txt = _snap_delta_combo.get_active_text(); + + for (int i = 0; modifiers[i].name; ++i) { + if (txt == _(modifiers[i].name)) { + Keyboard::set_snap_delta_modifier (modifiers[i].modifier); + break; + } + } + } + + void constraint_modifier_chosen () + { + string const txt = _constraint_modifier_combo.get_active_text(); + + for (int i = 0; modifiers[i].name; ++i) { + if (txt == _(modifiers[i].name)) { + ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier); + break; + } + } + } + + void trim_contents_modifier_chosen () + { + string const txt = _trim_contents_combo.get_active_text(); + + for (int i = 0; modifiers[i].name; ++i) { + if (txt == _(modifiers[i].name)) { + ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier); + break; + } + } + } + + void trim_overlap_modifier_chosen () + { + string const txt = _trim_overlap_combo.get_active_text(); + + for (int i = 0; modifiers[i].name; ++i) { + if (txt == _(modifiers[i].name)) { + ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier); + break; + } + } + } + + void trim_anchored_modifier_chosen () + { + string const txt = _trim_anchored_combo.get_active_text(); + + for (int i = 0; modifiers[i].name; ++i) { + if (txt == _(modifiers[i].name)) { + ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier); + break; + } + } + } + + void fine_adjust_modifier_chosen () + { + string const txt = _fine_adjust_combo.get_active_text(); + + for (int i = 0; modifiers[i].name; ++i) { + if (txt == _(modifiers[i].name)) { + ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier); + break; + } + } + } + + void push_points_modifier_chosen () + { + string const txt = _push_points_combo.get_active_text(); + + for (int i = 0; modifiers[i].name; ++i) { + if (txt == _(modifiers[i].name)) { + ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier); + break; + } + } + } + + void note_size_relative_modifier_chosen () + { + string const txt = _note_size_relative_combo.get_active_text(); + + for (int i = 0; modifiers[i].name; ++i) { + if (txt == _(modifiers[i].name)) { + ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier); + break; + } + } + } + void delete_button_changed () { Keyboard::set_delete_button (_delete_button_spin.get_value_as_int()); @@ -511,8 +995,18 @@ private: ComboBoxText _keyboard_layout_selector; ComboBoxText _edit_modifier_combo; ComboBoxText _delete_modifier_combo; + ComboBoxText _copy_modifier_combo; ComboBoxText _insert_note_modifier_combo; ComboBoxText _snap_modifier_combo; + ComboBoxText _snap_delta_combo; + ComboBoxText _constraint_modifier_combo; + ComboBoxText _trim_contents_combo; + ComboBoxText _trim_overlap_combo; + ComboBoxText _trim_anchored_combo; + ComboBoxText _trim_jump_combo; + ComboBoxText _fine_adjust_combo; + ComboBoxText _push_points_combo; + ComboBoxText _note_size_relative_combo; Adjustment _delete_button_adjustment; SpinButton _delete_button_spin; Adjustment _edit_button_adjustment; @@ -525,17 +1019,34 @@ private: class FontScalingOptions : public OptionEditorBox { public: - FontScalingOptions (RCConfiguration* c) : - _rc_config (c), - _dpi_adjustment (50, 50, 250, 1, 10), + FontScalingOptions () : + _dpi_adjustment (100, 50, 250, 1, 5), _dpi_slider (_dpi_adjustment) { - _dpi_adjustment.set_value (floor ((double)(_rc_config->get_font_scale () / 1024))); + _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.); - Label* l = manage (new Label (_("Font scaling:"))); + 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 + + _dpi_slider.set_name("FontScaleSlider"); _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS); + _dpi_slider.set_draw_value(false); + _dpi_slider.add_mark(50, Gtk::POS_TOP, empty); + _dpi_slider.add_mark(60, Gtk::POS_TOP, empty); + _dpi_slider.add_mark(70, Gtk::POS_TOP, empty); + _dpi_slider.add_mark(80, Gtk::POS_TOP, empty); + _dpi_slider.add_mark(90, Gtk::POS_TOP, empty); + _dpi_slider.add_mark(100, Gtk::POS_TOP, dflt); + _dpi_slider.add_mark(125, Gtk::POS_TOP, empty); + _dpi_slider.add_mark(150, Gtk::POS_TOP, empty); + _dpi_slider.add_mark(175, Gtk::POS_TOP, empty); + _dpi_slider.add_mark(200, Gtk::POS_TOP, empty); + _dpi_slider.add_mark(225, Gtk::POS_TOP, empty); + _dpi_slider.add_mark(250, Gtk::POS_TOP, empty); + HBox* h = manage (new HBox); h->set_spacing (4); h->pack_start (*l, false, false); @@ -543,13 +1054,15 @@ public: _box->pack_start (*h, false, false); + set_note (_("Adjusting the scale requires an application restart to re-layout.")); + _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed)); } void parameter_changed (string const & p) { if (p == "font-scale") { - _dpi_adjustment.set_value (floor ((double)(_rc_config->get_font_scale() / 1024))); + _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.); } } @@ -562,26 +1075,86 @@ private: void dpi_changed () { - _rc_config->set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024)); + UIConfiguration::instance().set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024.)); /* XXX: should be triggered from the parameter changed signal */ - reset_dpi (); + UIConfiguration::instance().reset_dpi (); } - RCConfiguration* _rc_config; Adjustment _dpi_adjustment; HScale _dpi_slider; }; -class ClipLevelOptions : public OptionEditorBox +class VstTimeOutSliderOption : public OptionEditorBox { public: - ClipLevelOptions (RCConfiguration* c) + VstTimeOutSliderOption (RCConfiguration* c) : _rc_config (c) - , _clip_level_adjustment (0, -128.0, 2.0, 0.1, 1.0) /* units of dB */ - , _clip_level_slider (_clip_level_adjustment) + , _timeout_adjustment (0, 0, 3000, 50, 50) + , _timeout_slider (_timeout_adjustment) { - _clip_level_adjustment.set_value (_rc_config->get_waveform_clip_level ()); - + _timeout_slider.set_digits (0); + _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &VstTimeOutSliderOption::timeout_changed)); + + _timeout_slider.set_draw_value(false); + _timeout_slider.add_mark( 0, Gtk::POS_TOP, _("\u221e")); // infinity + _timeout_slider.add_mark( 300, Gtk::POS_TOP, _("30 sec")); + _timeout_slider.add_mark( 600, Gtk::POS_TOP, _("1 min")); + _timeout_slider.add_mark(1200, Gtk::POS_TOP, _("2 mins")); + _timeout_slider.add_mark(1800, Gtk::POS_TOP, _("3 mins")); + _timeout_slider.add_mark(2400, Gtk::POS_TOP, _("4 mins")); + _timeout_slider.add_mark(3000, Gtk::POS_TOP, _("5 mins")); + + Gtkmm2ext::UI::instance()->set_tip(_timeout_slider, + _("Specify the default timeout for plugin instantiation. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout.")); + + Label* l = manage (left_aligned_label (_("Scan Time Out:"))); + HBox* h = manage (new HBox); + h->set_spacing (4); + h->pack_start (*l, false, false); + h->pack_start (_timeout_slider, true, true); + + _box->pack_start (*h, false, false); + } + + void parameter_changed (string const & p) + { + if (p == "vst-scan-timeout") { + int const x = _rc_config->get_vst_scan_timeout(); + _timeout_adjustment.set_value (x); + } + } + + void set_state_from_config () + { + parameter_changed ("vst-scan-timeout"); + } + +private: + + void timeout_changed () + { + int x = floor(_timeout_adjustment.get_value()); + _rc_config->set_vst_scan_timeout(x); + } + + RCConfiguration* _rc_config; + Adjustment _timeout_adjustment; + HScale _timeout_slider; +}; + + + + + +class ClipLevelOptions : public OptionEditorBox +{ +public: + ClipLevelOptions () + : _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */ + , _clip_level_slider (_clip_level_adjustment) + { + _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level ()); + Label* l = manage (new Label (_("Waveform Clip Level (dBFS):"))); l->set_name ("OptionsLabel"); @@ -599,7 +1172,7 @@ public: void parameter_changed (string const & p) { if (p == "waveform-clip-level") { - _clip_level_adjustment.set_value (_rc_config->get_waveform_clip_level()); + _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level()); } } @@ -612,12 +1185,11 @@ private: void clip_level_changed () { - _rc_config->set_waveform_clip_level (_clip_level_adjustment.get_value()); + UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value()); /* XXX: should be triggered from the parameter changed signal */ ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value()); } - RCConfiguration* _rc_config; Adjustment _clip_level_adjustment; HScale _clip_level_slider; }; @@ -632,13 +1204,34 @@ public: , _playback_slider (_playback_adjustment) , _capture_slider (_capture_adjustment) { + vector presets; + + /* these must match the order of the enums for BufferingPreset */ + + presets.push_back (_("Small sessions (4-16 tracks)")); + presets.push_back (_("Medium sessions (16-64 tracks)")); + presets.push_back (_("Large sessions (64+ tracks)")); + presets.push_back (_("Custom (set by sliders below)")); + + set_popdown_strings (_buffering_presets_combo, presets); + + Label* l = manage (new Label (_("Preset:"))); + l->set_name ("OptionsLabel"); + HBox* h = manage (new HBox); + h->set_spacing (12); + h->pack_start (*l, false, false); + h->pack_start (_buffering_presets_combo, true, true); + _box->pack_start (*h, false, false); + + _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed)); + _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds()); - Label* l = manage (new Label (_("Playback (seconds of buffering):"))); + l = manage (new Label (_("Playback (seconds of buffering):"))); l->set_name ("OptionsLabel"); _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS); - HBox* h = manage (new HBox); + h = manage (new HBox); h->set_spacing (4); h->pack_start (*l, false, false); h->pack_start (_playback_slider, true, true); @@ -664,6 +1257,31 @@ public: 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") { @@ -673,12 +1291,38 @@ public: void set_state_from_config () { + parameter_changed ("buffering-preset"); parameter_changed ("playback-buffer-seconds"); parameter_changed ("capture-buffer-seconds"); } 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 playback_changed () { _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value()); @@ -694,14 +1338,14 @@ private: Adjustment _capture_adjustment; HScale _playback_slider; HScale _capture_slider; + ComboBoxText _buffering_presets_combo; }; class ControlSurfacesOptions : public OptionEditorBox { public: - ControlSurfacesOptions (Gtk::Window& parent) - : _parent (parent) - , _ignore_view_change (0) + ControlSurfacesOptions () + : _ignore_view_change (0) { _store = ListStore::create (_model); _view.set_model (_store); @@ -713,18 +1357,29 @@ public: _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_markup (string_compose (X_("%1"), _("Double-click on a name to edit settings for an enabled protocol"))); - - _box->pack_start (*label, false, false); + 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 &) @@ -754,7 +1409,7 @@ private: void protocol_status_changed (ControlProtocolInfo* cpi) { /* find the row */ TreeModel::Children rows = _store->children(); - + for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) { string n = ((*x)[_model.name]); @@ -767,6 +1422,16 @@ private: } } + 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; @@ -789,17 +1454,7 @@ private: if (!was_enabled) { ControlProtocolManager::instance().activate (*cpi); } else { - Gtk::Window* win = r[_model.editor]; - if (win) { - win->hide (); - } - ControlProtocolManager::instance().deactivate (*cpi); - - if (win) { - delete win; - r[_model.editor] = 0; - } } } @@ -811,37 +1466,50 @@ private: } } - void edit_clicked (GdkEventButton* ev) - { - if (ev->type != GDK_2BUTTON_PRESS) { - return; - } - + void edit_btn_clicked () + { std::string name; ControlProtocolInfo* cpi; TreeModel::Row row; row = *(_view.get_selection()->get_selected()); - - Window* win = row[_model.editor]; - if (win && !win->is_visible()) { - win->present (); - } else { - cpi = row[_model.protocol_info]; - - if (cpi && cpi->protocol && cpi->protocol->has_editor ()) { - Box* box = (Box*) cpi->protocol->get_gui (); - if (box) { - string title = row[_model.name]; - ArdourWindow* win = new ArdourWindow (_parent, title); - win->set_title ("Control Protocol Options"); - win->add (*box); - box->show (); - win->present (); - row[_model.editor] = win; - } - } + 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; + } + + edit_btn_clicked(); } class ControlSurfacesModelColumns : public TreeModelColumnRecord @@ -854,22 +1522,20 @@ private: add (enabled); add (feedback); add (protocol_info); - add (editor); } TreeModelColumn name; TreeModelColumn enabled; TreeModelColumn feedback; TreeModelColumn protocol_info; - TreeModelColumn editor; }; Glib::RefPtr _store; ControlSurfacesModelColumns _model; TreeView _view; - Gtk::Window& _parent; PBD::ScopedConnection protocol_status_connection; uint32_t _ignore_view_change; + Gtk::Button* edit_button; }; class VideoTimelineOptions : public OptionEditorBox @@ -880,45 +1546,78 @@ public: , _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 = manage (new Table (2, 6)); + Table* t = manage (new Table (8, 4)); t->set_spacings (4); - t->attach (_video_advanced_setup_button, 0, 2, 0, 1); + std::stringstream s; + s << "" << _("Video Server") << ""; + Label* l = manage (new Label (s.str())); + l->set_use_markup (true); + l->set_alignment (0, 0.5); + t->attach (*l, 0, 4, 0, 1, EXPAND | FILL, FILL | EXPAND, 0, 8); + + t->attach (_video_advanced_setup_button, 1, 4, 1, 2); _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.")); - Label* l = manage (new Label (_("Video Server URL:"))); + 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); + t->attach (*l, 1, 2, 2, 3, FILL); + t->attach (_video_server_url_entry, 2, 4, 2, 3, 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, 0, 1, 2, 3, FILL); - t->attach (_video_server_docroot_entry, 1, 2, 2, 3); + t->attach (*l, 1, 2, 3, 4, FILL); + t->attach (_video_server_docroot_entry, 2, 4, 3, 4); 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.")); - /* small vspace y=3..4 */ - - t->attach (_show_video_export_info_button, 0, 2, 4, 5); + t->attach (_show_video_export_info_button, 1, 4, 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.")); - t->attach (_show_video_server_dialog_button, 0, 2, 5, 6); + t->attach (_show_video_server_dialog_button, 1, 4, 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")); + s.str (std::string ()); + s << "" << _("Video Monitor") << ""; + l = manage (new Label (s.str())); + l->set_use_markup (true); + l->set_alignment (0, 0.5); + t->attach (*l, 0, 4, 6, 7, EXPAND | FILL, FILL | EXPAND, 0, 8); + + 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, 7, 8, FILL); + t->attach (_custom_xjadeo_path, 2, 3, 8, 9); + 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, 8, 9, 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); } @@ -951,6 +1650,30 @@ public: _rc_config->set_video_advanced_setup(x); } + void custom_xjadeo_path_changed () + { + UIConfiguration::instance().set_xjadeo_binary (_custom_xjadeo_path.get_text()); + } + + 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); + } + } + } + void parameter_changed (string const & p) { if (p == "video-server-url") { @@ -968,6 +1691,8 @@ public: _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()); } } @@ -979,17 +1704,21 @@ public: parameter_changed ("show-video-export-info"); parameter_changed ("show-video-server-dialog"); parameter_changed ("video-advanced-setup"); + parameter_changed ("xjadeo-binary"); } 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; }; + /** A class which allows control of visibility of some editor components usign * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup * which has the correct members, but with null widget pointers. This @@ -1042,7 +1771,7 @@ private: */ _set (_visibility_group->get_state_value ()); } - + OptionEditorHeading _heading; VisibilityGroup* _visibility_group; sigc::slot _get; @@ -1053,10 +1782,14 @@ private: 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) - , _mixer_strip_visibility ("mixer-strip-visibility") + , _mixer_strip_visibility ("mixer-element-visibility") { + + UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed)); + /* MISC */ uint32_t hwcpus = hardware_concurrency (); @@ -1097,6 +1830,8 @@ RCOptionEditor::RCOptionEditor () sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture) )); + add_option (_("Misc"), new OptionEditorHeading (_("Session Management"))); + add_option (_("Misc"), new BoolOption ( "periodic-safety-backups", @@ -1105,14 +1840,12 @@ RCOptionEditor::RCOptionEditor () sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups) )); - add_option (_("Misc"), new OptionEditorHeading (_("Session Management"))); - add_option (_("Misc"), new BoolOption ( "only-copy-imported-files", _("Always copy imported files"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_only_copy_imported_files), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_only_copy_imported_files) + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files) )); add_option (_("Misc"), new DirectoryOption ( @@ -1133,7 +1866,7 @@ RCOptionEditor::RCOptionEditor () add_option (_("Misc"), new OptionEditorHeading (_("Click"))); - add_option (_("Misc"), new ClickOptions (_rc_config, this)); + add_option (_("Misc"), new ClickOptions (_rc_config)); add_option (_("Misc"), new FaderOption ( @@ -1165,6 +1898,8 @@ RCOptionEditor::RCOptionEditor () /* TRANSPORT */ + add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options"))); + BoolOption* tsf; tsf = new BoolOption ( @@ -1176,13 +1911,24 @@ RCOptionEditor::RCOptionEditor () // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("")); add_option (_("Transport"), tsf); + tsf = new BoolOption ( + "loop-is-mode", + _("Play loop is a transport mode"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode) + ); + Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), + (_("When enabled the loop button does not start playback but forces playback to always play the loop\n\n" + "When disabled the loop button starts playing the loop, but stop then cancels loop playback"))); + add_option (_("Transport"), tsf); + tsf = new BoolOption ( "stop-recording-on-xrun", _("Stop recording when an xrun occurs"), sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun), sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun) ); - Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), + Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), string_compose (_("When enabled %1 will stop recording if an over- or underrun is detected by the audio engine"), PROGRAM_NAME)); add_option (_("Transport"), tsf); @@ -1202,7 +1948,7 @@ RCOptionEditor::RCOptionEditor () sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end), sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end) ); - Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), + Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), string_compose (_("When enabled if %1 is not recording, it will stop the transport " "when it reaches the current session end marker\n\n" "When disabled %1 will continue to roll past the session end marker at all times"), @@ -1215,7 +1961,7 @@ RCOptionEditor::RCOptionEditor () sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop), sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop) ); - Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), + Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), string_compose (_("When enabled this will loop by reading ahead and wrapping around at the loop point, " "preventing any need to do a transport locate at the end of the loop\n\n" "When disabled looping is done by locating back to the start of the loop when %1 reaches the end " @@ -1241,7 +1987,24 @@ RCOptionEditor::RCOptionEditor () "that occurs when fast-forwarding or rewinding through some kinds of audio")); add_option (_("Transport"), tsf); - add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave"))); + ComboOption* psc = new ComboOption ( + "preroll-seconds", + _("Preroll"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds) + ); + Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(), + (_("The amount of preroll (in seconds) to apply when Play with Preroll is initiated.\n\n" + "If Follow Edits is enabled, the preroll is applied to the playhead position when a region is selected or trimmed."))); + psc->add (0.0, _("0 (no pre-roll)")); + psc->add (0.1, _("0.1 second")); + psc->add (0.25, _("0.25 second")); + psc->add (0.5, _("0.5 second")); + psc->add (1.0, _("1.0 second")); + psc->add (2.0, _("2.0 seconds")); + add_option (_("Transport"), psc); + + add_option (_("Transport/Sync"), new OptionEditorHeading (S_("Synchronization and Slave Options"))); _sync_source = new ComboOption ( "sync-source", @@ -1250,8 +2013,7 @@ RCOptionEditor::RCOptionEditor () sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source) ); - populate_sync_options (); - add_option (_("Transport"), _sync_source); + add_option (_("Transport/Sync"), _sync_source); _sync_framerate = new BoolOption ( "timecode-sync-frame-rate", @@ -1259,7 +2021,7 @@ RCOptionEditor::RCOptionEditor () sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate), sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate) ); - Gtkmm2ext::UI::instance()->set_tip + Gtkmm2ext::UI::instance()->set_tip (_sync_framerate->tip_widget(), string_compose (_("This option controls the value of the video frame rate while chasing an external timecode source.\n\n" "When enabled the session video frame rate will be changed to match that of the selected external timecode source.\n\n" @@ -1267,20 +2029,28 @@ 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", - _("External timecode is sync locked"), + _("Sync-lock timecode to clock (disable drift compensation)"), sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced), sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced) ); - Gtkmm2ext::UI::instance()->set_tip - (_sync_genlock->tip_widget(), - _("When enabled indicates that the selected external timecode source shares sync (Black & Burst, Wordclock, etc) with the audio interface.")); + Gtkmm2ext::UI::instance()->set_tip + (_sync_genlock->tip_widget(), + string_compose (_("When enabled %1 will never varispeed when slaved to external timecode. " + "Sync Lock indicates that the selected external timecode source shares clock-sync " + "(Black & Burst, Wordclock, etc) with the audio interface. " + "This option disables drift compensation. The transport speed is fixed at 1.0. " + "Vari-speed LTC will be ignored and cause drift." + "\n\n" + "When disabled %1 will compensate for potential drift, regardless if the " + "timecode sources shares clock sync." + ), PROGRAM_NAME)); - add_option (_("Transport"), _sync_genlock); + add_option (_("Transport/Sync"), _sync_genlock); _sync_source_2997 = new BoolOption ( "timecode-source-2997", @@ -1298,9 +2068,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", @@ -1314,12 +2084,15 @@ RCOptionEditor::RCOptionEditor () AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs); _ltc_port->set_popdown_strings (physical_inputs); - add_option (_("Transport"), _ltc_port); + populate_sync_options (); + AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context()); + + 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"), @@ -1329,7 +2102,7 @@ RCOptionEditor::RCOptionEditor () _ltc_send_continuously = new BoolOption ( "ltc-send-continuously", - _("send LTC while stopped"), + _("Send LTC while stopped"), sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously), sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously) ); @@ -1347,45 +2120,125 @@ RCOptionEditor::RCOptionEditor () (_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")); - add_option (_("Transport"), _ltc_volume_slider); - parameter_changed ("send-ltc"); - - parameter_changed ("sync-source"); + add_option (_("Transport/Sync"), _ltc_volume_slider); /* EDITOR */ add_option (_("Editor"), new BoolOption ( - "link-region-and-track-selection", - _("Link selection of regions and tracks"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_region_and_track_selection), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_region_and_track_selection) + "rubberbanding-snaps-to-grid", + _("Make rubberband selection rectangle snap to the grid"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid) )); - add_option (_("Editor"), + bo = new BoolOption ( + "name-new-markers", + _("Name new markers"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers) + ); + add_option (_("Editor"), bo); + Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(), _("If enabled, popup a dialog when a new marker is created to allow its name to be set as it is created." + "\n\nYou can always rename markers by right-clicking on them")); + + add_option (S_("Editor"), new BoolOption ( - "automation-follows-regions", - _("Move relevant automation when audio regions are moved"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions) + "draggable-playhead", + _("Allow dragging of playhead"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead), + 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 (*_rc_config, &RCConfiguration::get_show_track_meters), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_track_meters) + 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 (*_rc_config, &RCConfiguration::get_show_editor_meter), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_editor_meter) + 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 ( + "show-zoom-tools", + _("Show zoom toolbar (if torn off)"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_zoom_tools), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_zoom_tools) + )); + + add_option (_("Editor"), + new BoolOption ( + "use-mouse-position-as-zoom-focus-on-scroll", + _("Always use mouse cursor position as zoom focus when zooming using mouse scroll wheel"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll) + )); +} // !mixbus + + add_option (_("Editor"), + new BoolOption ( + "update-editor-during-summary-drag", + _("Update editor window during drags of the summary"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag) + )); + + add_option (_("Editor"), + new BoolOption ( + "autoscroll-editor", + _("Auto-scroll editor window when dragging near its edges"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor) + )); + + add_option (_("Editor"), + new BoolComboOption ( + "show-region-gain-envelopes", + _("Show gain envelopes in audio regions"), + _("in all modes"), + _("only in Draw and Internal Edit modes"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain) )); + add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior"))); + + add_option (_("Editor"), + new BoolOption ( + "automation-follows-regions", + _("Move relevant automation when audio regions are moved"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions) + )); + + ComboOption* fadeshape = new ComboOption ( + "default-fade-shape", + _("Default fade shape"), + sigc::mem_fun (*_rc_config, + &RCConfiguration::get_default_fade_shape), + sigc::mem_fun (*_rc_config, + &RCConfiguration::set_default_fade_shape) + ); + + fadeshape->add (FadeLinear, + _("Linear (for highly correlated material)")); + fadeshape->add (FadeConstantPower, _("Constant power")); + fadeshape->add (FadeSymmetric, _("Symmetric")); + fadeshape->add (FadeSlow, _("Slow")); + fadeshape->add (FadeFast, _("Fast")); + + add_option (_("Editor"), fadeshape); + + bco = new BoolComboOption ( "use-overlap-equivalency", _("Regions in active edit groups are edited together"), @@ -1397,37 +2250,60 @@ RCOptionEditor::RCOptionEditor () add_option (_("Editor"), bco); - add_option (_("Editor"), - new BoolOption ( - "rubberbanding-snaps-to-grid", - _("Make rubberband selection rectangle snap to the grid"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_rubberbanding_snaps_to_grid), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_rubberbanding_snaps_to_grid) - )); + ComboOption* lm = new ComboOption ( + "layer-model", + _("Layering model"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model) + ); + + lm->add (LaterHigher, _("later is higher")); + lm->add (Manual, _("manual layering")); + add_option (_("Editor"), lm); + + ComboOption *rsas = new ComboOption ( + "region-selection-after-split", + _("After splitting selected regions, select"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split)); + + // TODO: decide which of these modes are really useful + rsas->add(None, _("no regions")); + // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split")); + // rsas->add(NewlyCreatedRight, _("newly-created regions after the split")); + rsas->add(NewlyCreatedBoth, _("newly-created regions")); + // rsas->add(Existing, _("unmodified regions in the existing selection")); + // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split")); + // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split")); + rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions")); + + add_option (_("Editor"), rsas); + + add_option (_("Editor"), new OptionEditorHeading (_("Waveforms"))); +if (!Profile->get_mixbus()) { add_option (_("Editor"), new BoolOption ( "show-waveforms", _("Show waveforms in regions"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms) + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms) )); +} // !mixbus add_option (_("Editor"), - new BoolComboOption ( - "show-region-gain-envelopes", - _("Show gain envelopes in audio regions"), - _("in all modes"), - _("only in region gain mode"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_region_gain), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_region_gain) + new BoolOption ( + "show-waveforms-while-recording", + _("Show waveforms for audio while it is being recorded"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording) )); ComboOption* wfs = new ComboOption ( "waveform-scale", _("Waveform scale"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_scale), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_scale) + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale) ); wfs->add (Linear, _("linear")); @@ -1438,8 +2314,8 @@ RCOptionEditor::RCOptionEditor () ComboOption* wfsh = new ComboOption ( "waveform-shape", _("Waveform shape"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_shape), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_shape) + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape) ); wfsh->add (Traditional, _("traditional")); @@ -1447,58 +2323,8 @@ RCOptionEditor::RCOptionEditor () add_option (_("Editor"), wfsh); - add_option (_("Editor"), new ClipLevelOptions (_rc_config)); + add_option (_("Editor"), new ClipLevelOptions ()); - add_option (_("Editor"), - new BoolOption ( - "show-waveforms-while-recording", - _("Show waveforms for audio while it is being recorded"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms_while_recording), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms_while_recording) - )); - - add_option (_("Editor"), - new BoolOption ( - "show-zoom-tools", - _("Show zoom toolbar"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_zoom_tools), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_zoom_tools) - )); - - add_option (_("Editor"), - new BoolOption ( - "update-editor-during-summary-drag", - _("Update editor window during drags of the summary"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_update_editor_during_summary_drag), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_update_editor_during_summary_drag) - )); - - add_option (_("Editor"), - new BoolOption ( - "link-editor-and-mixer-selection", - _("Synchronise editor and mixer selection"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_editor_and_mixer_selection), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_editor_and_mixer_selection) - )); - - bo = new BoolOption ( - "name-new-markers", - _("Name new markers"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_name_new_markers), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_name_new_markers) - ); - - add_option (_("Editor"), bo); - Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(), _("If enabled, popup a dialog when a new marker is created to allow its name to be set as it is created." - "\n\nYou can always rename markers by right-clicking on them")); - - add_option (_("Editor"), - new BoolOption ( - "autoscroll-editor", - _("Auto-scroll editor window when dragging near its edges"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_autoscroll_editor), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_autoscroll_editor) - )); /* AUDIO */ @@ -1519,7 +2345,9 @@ RCOptionEditor::RCOptionEditor () mm->add (HardwareMonitoring, _("via Audio Driver")); } - mm->add (SoftwareMonitoring, _("ardour")); + string prog (PROGRAM_NAME); + boost::algorithm::to_lower (prog); + mm->add (SoftwareMonitoring, string_compose (_("%1"), prog)); mm->add (ExternalMonitoring, _("audio hardware")); add_option (_("Audio"), mm); @@ -1533,6 +2361,7 @@ RCOptionEditor::RCOptionEditor () )); add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses"))); +if (!Profile->get_mixbus()) { add_option (_("Audio"), new BoolOption ( @@ -1566,6 +2395,19 @@ RCOptionEditor::RCOptionEditor () oac->add (ManualConnect, _("manually")); add_option (_("Audio"), oac); +} // !mixbus + + 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.")); + add_option (_("Audio"), new OptionEditorHeading (_("Denormals"))); @@ -1584,20 +2426,34 @@ RCOptionEditor::RCOptionEditor () sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model) ); + int dmsize = 1; dm->add (DenormalNone, _("no processor handling")); - FPU fpu; + FPU* fpu = FPU::instance(); - if (fpu.has_flush_to_zero()) { + if (fpu->has_flush_to_zero()) { + ++dmsize; dm->add (DenormalFTZ, _("use FlushToZero")); + } else if (_rc_config->get_denormal_model() == DenormalFTZ) { + _rc_config->set_denormal_model(DenormalNone); } - if (fpu.has_denormals_are_zero()) { + if (fpu->has_denormals_are_zero()) { + ++dmsize; dm->add (DenormalDAZ, _("use DenormalsAreZero")); + } else if (_rc_config->get_denormal_model() == DenormalDAZ) { + _rc_config->set_denormal_model(DenormalNone); } - if (fpu.has_flush_to_zero() && fpu.has_denormals_are_zero()) { + if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) { + ++dmsize; dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero")); + } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) { + _rc_config->set_denormal_model(DenormalNone); + } + + if (dmsize == 1) { + dm->set_sensitive(false); } add_option (_("Audio"), dm); @@ -1620,6 +2476,8 @@ RCOptionEditor::RCOptionEditor () sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active) )); + add_option (_("Audio"), new OptionEditorHeading (_("Regions"))); + add_option (_("Audio"), new BoolOption ( "auto-analyse-audio", @@ -1638,15 +2496,7 @@ RCOptionEditor::RCOptionEditor () /* SOLO AND MUTE */ - add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo"))); - - add_option (_("Solo / mute"), - new FaderOption ( - "solo-mute-gain", - _("Solo-in-place mute cut (dB)"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain) - )); + add_option (_("Solo & mute"), new OptionEditorHeading (_("Solo"))); _solo_control_is_listen_control = new BoolOption ( "solo-control-is-listen-control", @@ -1655,7 +2505,39 @@ RCOptionEditor::RCOptionEditor () 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"), + new BoolOption ( + "exclusive-solo", + _("Exclusive solo"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo) + )); + + add_option (_("Solo & mute"), + new BoolOption ( + "show-solo-mutes", + _("Show solo muting"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes) + )); + + add_option (_("Solo & mute"), + new BoolOption ( + "solo-mute-override", + _("Soloing overrides muting"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override) + )); + + add_option (_("Solo & mute"), + new FaderOption ( + "solo-mute-gain", + _("Solo-in-place mute cut (dB)"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain) + )); _listen_position = new ComboOption ( "listen-position", @@ -1667,7 +2549,7 @@ RCOptionEditor::RCOptionEditor () _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", @@ -1679,7 +2561,7 @@ RCOptionEditor::RCOptionEditor () 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", @@ -1691,37 +2573,11 @@ RCOptionEditor::RCOptionEditor () pa->add (AFLFromBeforeProcessors, _("immediately post-fader")); pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)")); - add_option (_("Solo / mute"), pa); - - parameter_changed ("use-monitor-bus"); - - add_option (_("Solo / mute"), - new BoolOption ( - "exclusive-solo", - _("Exclusive solo"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo) - )); - - add_option (_("Solo / mute"), - new BoolOption ( - "show-solo-mutes", - _("Show solo muting"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes) - )); - - add_option (_("Solo / mute"), - new BoolOption ( - "solo-mute-override", - _("Soloing overrides muting"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override) - )); + 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"), @@ -1729,7 +2585,7 @@ RCOptionEditor::RCOptionEditor () 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"), @@ -1737,7 +2593,7 @@ RCOptionEditor::RCOptionEditor () 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"), @@ -1745,7 +2601,7 @@ RCOptionEditor::RCOptionEditor () 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"), @@ -1753,9 +2609,9 @@ RCOptionEditor::RCOptionEditor () sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs) )); - add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing"))); + add_option (_("Solo & mute"), new OptionEditorHeading (_("Send Routing"))); - add_option (_("Solo / mute"), + add_option (_("Solo & mute"), new BoolOption ( "link-send-and-route-panner", _("Link panners of Aux and External Sends with main panner by default"), @@ -1763,6 +2619,61 @@ RCOptionEditor::RCOptionEditor () sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner) )); + add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Preferences"))); + + add_option (_("MIDI"), + new SpinOption ( + "midi-readahead", + _("MIDI read-ahead time (seconds)"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead), + 0.1, 10, 0.1, 1, + "", 1.0, 1 + )); + + add_option (_("MIDI"), + new SpinOption ( + "initial-program-change", + _("Initial program change"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change), + -1, 65536, 1, 10 + )); + + add_option (_("MIDI"), + new BoolOption ( + "display-first-midi-bank-as-zero", + _("Display first MIDI bank/program as 0"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero) + )); + + add_option (_("MIDI"), + new BoolOption ( + "never-display-periodic-midi", + _("Never display periodic MIDI messages (MTC, MIDI Clock)"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi) + )); + + add_option (_("MIDI"), + new BoolOption ( + "sound-midi-notes", + _("Sound MIDI notes as they are selected in the editor"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes) + )); + + add_option (_("MIDI"), + new BoolOption ( + "midi-feedback", + _("Send MIDI control feedback"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback) + )); + + add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Clock"))); + add_option (_("MIDI"), new BoolOption ( "send-midi-clock", @@ -1771,6 +2682,8 @@ RCOptionEditor::RCOptionEditor () sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock) )); + add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Time Code (MTC)"))); + add_option (_("MIDI"), new BoolOption ( "send-mtc", @@ -1788,6 +2701,8 @@ RCOptionEditor::RCOptionEditor () 0, 20, 1, 5 )); + add_option (_("MIDI"), new OptionEditorHeading (_("Midi Machine Control (MMC)"))); + add_option (_("MIDI"), new BoolOption ( "mmc-control", @@ -1804,14 +2719,6 @@ RCOptionEditor::RCOptionEditor () sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc) )); - add_option (_("MIDI"), - new BoolOption ( - "midi-feedback", - _("Send MIDI control feedback"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback) - )); - add_option (_("MIDI"), new SpinOption ( "mmc-receive-device-id", @@ -1830,39 +2737,6 @@ RCOptionEditor::RCOptionEditor () 0, 128, 1, 10 )); - add_option (_("MIDI"), - new SpinOption ( - "initial-program-change", - _("Initial program change"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change), - -1, 65536, 1, 10 - )); - - add_option (_("MIDI"), - new BoolOption ( - "diplay-first-midi-bank-as-zero", - _("Display first MIDI bank/program as 0"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero) - )); - - add_option (_("MIDI"), - new BoolOption ( - "never-display-periodic-midi", - _("Never display periodic MIDI messages (MTC, MIDI Clock)"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_never_display_periodic_midi), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_never_display_periodic_midi) - )); - - add_option (_("MIDI"), - new BoolOption ( - "sound-midi-notes", - _("Sound MIDI notes as they are selected"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_sound_midi_notes), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_sound_midi_notes) - )); - add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition"))); ComboOption* audition_synth = new ComboOption ( @@ -1890,8 +2764,15 @@ RCOptionEditor::RCOptionEditor () /* USER INTERACTION */ - if (getenv ("ARDOUR_BUNDLED")) { - add_option (_("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" @@ -1907,7 +2788,7 @@ RCOptionEditor::RCOptionEditor () /* Control Surfaces */ - add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this)); + add_option (_("Control Surfaces"), new ControlSurfacesOptions); ComboOption* rm = new ComboOption ( "remote-model", @@ -1924,53 +2805,260 @@ RCOptionEditor::RCOptionEditor () /* 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"))); + + add_option (_("Plugins"), + new RcActionButton (_("Scan for Plugins"), + sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh))); + + bo = new BoolOption ( + "show-plugin-scan-window", + _("Always Display Plugin Scan Progress"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window) + ); + 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 ( + "discover-vst-on-start", + _("Scan for [new] VST Plugins on Application Start"), + 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); + 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")); + +#ifdef WINDOWS_VST_SUPPORT + // currently verbose logging is only implemented for Windows VST. + bo = new BoolOption ( + "verbose-plugin-scan", + _("Verbose Plugin Scan"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan) + ); + add_option (_("Plugins"), 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"), + new RcActionButton (_("Clear"), + sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache), + _("VST Cache:"))); + + add_option (_("Plugins"), + new RcActionButton (_("Clear"), + sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist), + _("VST Blacklist:"))); +#endif + +#ifdef LXVST_SUPPORT + add_option (_("Plugins"), + new RcActionButton (_("Edit"), + sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path), + _("Linux VST Path:"))); + + add_option (_("Plugins"), + new RcConfigDisplay ( + "plugin-path-lxvst", + _("Path:"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst), + ':')); +#endif + +#ifdef WINDOWS_VST_SUPPORT + add_option (_("Plugins"), + new RcActionButton (_("Edit"), + sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path), + _("Windows VST Path:"))); + add_option (_("Plugins"), + new RcConfigDisplay ( + "plugin-path-vst", + _("Path:"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst), + ';')); +#endif + +#ifdef AUDIOUNIT_SUPPORT + add_option (_("Plugins"), new OptionEditorHeading (_("Audio Unit"))); + + bo = new BoolOption ( + "discover-audio-units", + _("Scan for 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); + 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"), + new RcActionButton (_("Clear"), + sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache), + _("AU Cache:"))); + + add_option (_("Plugins"), + 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) + 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 (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin) + )); + +#ifdef LV2_SUPPORT + 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 +#endif + /* INTERFACE */ +#ifdef OPTIONAL_CAIRO_IMAGE_SURFACE + BoolOption* bgc = new BoolOption ( + "cairo-image-surface", + _("Disable Graphics Hardware Acceleration (requires restart)"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface) + ); + + Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose ( + _("Render large parts of the application user-interface in software, instead of using 2D-graphics acceleration.\nThis requires restarting %1 before having an effect"), PROGRAM_NAME)); + add_option (S_("Preferences|GUI"), bgc); +#endif + +#ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE + BoolOption* bgo = new BoolOption ( + "buggy-gradients", + _("Possibly improve slow graphical performance (requires restart)"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients) + ); + + Gtkmm2ext::UI::instance()->set_tip (bgo->tip_widget(), string_compose (_("Disables hardware gradient rendering on buggy video drivers (\"buggy gradients patch\").\nThis requires restarting %1 before having an effect"), PROGRAM_NAME)); + add_option (S_("Preferences|GUI"), bgo); +#endif + add_option (S_("Preferences|GUI"), new BoolOption ( "widget-prelight", _("Graphically indicate mouse pointer hovering over various widgets"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_widget_prelight), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_widget_prelight) + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight) )); +#ifdef TOOLTIPS_GOT_FIXED add_option (S_("Preferences|GUI"), new BoolOption ( "use-tooltips", _("Show tooltips if mouse hovers over a control"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_tooltips), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_tooltips) + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips) )); - -#ifndef GTKOSX - /* font scaling does nothing with GDK/Quartz */ - add_option (S_("Preferences|GUI"), new FontScalingOptions (_rc_config)); #endif - add_option (S_("GUI"), + add_option (S_("Preferences|GUI"), + new BoolOption ( + "show-name-highlight", + _("Use name highlight bars in region displays (requires a restart)"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight) + )); + + add_option (S_("Preferences|GUI"), new BoolOption ( "super-rapid-clock-update", - _("update transport clock display every 40ms instead of every 100ms"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_super_rapid_clock_update), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_super_rapid_clock_update) + _("Update transport clock display at FPS instead of every 100ms"), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update) )); + +#ifndef __APPLE__ + /* font scaling does nothing with GDK/Quartz */ + add_option (S_("Preferences|GUI"), new FontScalingOptions ()); +#endif + + /* Image cache size */ + + Gtk::Adjustment *ics = manage (new Gtk::Adjustment(0, 1, 1024, 10)); /* 1 MB to 1GB in steps of 10MB */ + HSliderOption *sics = new HSliderOption("waveform-cache-size", + _("Waveform image cache size (megabytes)"), + ics, + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size) + ); + sics->scale().set_digits (0); + Gtkmm2ext::UI::instance()->set_tip + (sics->tip_widget(), + _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance.")); + add_option (S_("Preferences|GUI"), sics); + +if (!ARDOUR::Profile->get_mixbus()) { + /* Lock GUI timeout */ + + Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10)); + HSliderOption *slts = new HSliderOption("lock-gui-after-seconds", + _("Lock timeout (seconds)"), + lts, + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds) + ); + slts->scale().set_digits (0); + Gtkmm2ext::UI::instance()->set_tip + (slts->tip_widget(), + _("Lock GUI after this many idle seconds (zero to never lock)")); + add_option (S_("Preferences|GUI"), slts); +} // !mixbus + /* The names of these controls must be the same as those given in MixerStrip for the actual widgets being controlled. */ + _mixer_strip_visibility.add (0, X_("Input"), _("Input")); _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert")); - _mixer_strip_visibility.add (0, X_("SoloSafe"), _("Solo Safe")); - _mixer_strip_visibility.add (0, X_("SoloIsolated"), _("Solo Isolated")); + _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor")); + _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_("MeterPoint"), _("Meter Point")); - + add_option ( S_("Preferences|GUI"), new VisibilityOption ( _("Mixer Strip"), &_mixer_strip_visibility, - sigc::mem_fun (*_rc_config, &RCConfiguration::get_mixer_strip_visibility), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_mixer_strip_visibility) + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility) ) ); @@ -1978,17 +3066,17 @@ RCOptionEditor::RCOptionEditor () new BoolOption ( "default-narrow_ms", _("Use narrow strips in the mixer by default"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_narrow_ms), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_narrow_ms) + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms) )); - add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Metering"))); + add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering"))); ComboOption* mht = new ComboOption ( "meter-hold", _("Peak hold time"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_hold), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_hold) + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold) ); mht->add (MeterHoldOff, _("off")); @@ -1996,7 +3084,7 @@ RCOptionEditor::RCOptionEditor () mht->add (MeterHoldMedium, _("medium")); mht->add (MeterHoldLong, _("long")); - add_option (S_("Preferences|GUI"), mht); + add_option (S_("Preferences|Metering"), mht); ComboOption* mfo = new ComboOption ( "meter-falloff", @@ -2008,20 +3096,18 @@ RCOptionEditor::RCOptionEditor () mfo->add (METER_FALLOFF_OFF, _("off")); mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]")); mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)")); - mfo->add (METER_FALLOFF_SLOWISH, _("slowish [12.0dB/sec] (DIN)")); - mfo->add (METER_FALLOFF_MODERATE, _("moderate [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)")); - mfo->add (METER_FALLOFF_MEDIUM, _("medium [20dB/sec]")); - mfo->add (METER_FALLOFF_FAST, _("fast [32dB/sec]")); - mfo->add (METER_FALLOFF_FASTER, _("faster [46dB/sec]")); - mfo->add (METER_FALLOFF_FASTEST, _("fastest [70dB/sec]")); + mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)")); + mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)")); + mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]")); + mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]")); - add_option (S_("Preferences|GUI"), mfo); + add_option (S_("Preferences|Metering"), mfo); ComboOption* mlu = new ComboOption ( "meter-line-up-level", _("Meter line-up level; 0dBu"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_line_up_level), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_line_up_level) + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level) ); mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)")); @@ -2031,13 +3117,13 @@ RCOptionEditor::RCOptionEditor () Gtkmm2ext::UI::instance()->set_tip (mlu->tip_widget(), _("Configure meter-marks and color-knee point for dBFS scale DPM, set reference level for IEC1/Nordic, IEC2 PPM and VU meter.")); - add_option (S_("Preferences|GUI"), mlu); + add_option (S_("Preferences|Metering"), mlu); ComboOption* mld = new ComboOption ( "meter-line-up-din", _("IEC1/DIN Meter line-up level; 0dBu"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_line_up_din), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_line_up_din) + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din) ); mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)")); @@ -2047,13 +3133,13 @@ RCOptionEditor::RCOptionEditor () Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter.")); - add_option (S_("Preferences|GUI"), mld); + add_option (S_("Preferences|Metering"), mld); ComboOption* mvu = new ComboOption ( "meter-vu-standard", _("VU Meter standard"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_vu_standard), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_vu_standard) + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard) ); mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)")); @@ -2061,30 +3147,87 @@ RCOptionEditor::RCOptionEditor () mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)")); mvu->add (MeteringVUeight, _("0VU = +8dBu")); - add_option (S_("Preferences|GUI"), mvu); + add_option (S_("Preferences|Metering"), mvu); Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1)); HSliderOption *mpks = new HSliderOption("meter-peak", _("Peak threshold [dBFS]"), mpk, - sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_peak), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_peak) + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak) ); + + ComboOption* mtm = new ComboOption ( + "meter-type-master", + _("Default Meter Type for Master Bus"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master) + ); + mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak)); + mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20)); + mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14)); + mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12)); + mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN)); + mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR)); + mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC)); + mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU)); + + add_option (S_("Preferences|Metering"), mtm); + + + ComboOption* mtb = new ComboOption ( + "meter-type-bus", + _("Default Meter Type for Busses"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus) + ); + mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak)); + mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20)); + mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14)); + mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12)); + mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN)); + mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR)); + mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC)); + mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU)); + + add_option (S_("Preferences|Metering"), mtb); + + ComboOption* mtt = new ComboOption ( + "meter-type-track", + _("Default Meter Type for Tracks"), + sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track), + sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track) + ); + mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak)); + mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB)); + + add_option (S_("Preferences|Metering"), mtt); + + 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.")); - add_option (S_("Preferences|GUI"), mpks); + add_option (S_("Preferences|Metering"), mpks); - add_option (S_("Preferences|GUI"), + add_option (S_("Preferences|Metering"), new BoolOption ( "meter-style-led", _("LED meter style"), - sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_style_led), - sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_style_led) + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led), + sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led) )); + /* and now the theme manager */ + + ThemeManager* tm = manage (new ThemeManager); + add_page (_("Theme"), *tm); + + //trigger some parameter-changed messages which affect widget-visibility or -sensitivity + parameter_changed ("send-ltc"); + parameter_changed ("sync-source"); + parameter_changed ("use-monitor-bus"); } void @@ -2122,6 +3265,10 @@ 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") { +#ifdef LV2_SUPPORT + _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default()); +#endif } } @@ -2129,6 +3276,56 @@ void RCOptionEditor::ltc_generator_volume_changed () { _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20)); } +void RCOptionEditor::plugin_scan_refresh () { + PluginManager::instance().refresh(); +} + +void RCOptionEditor::clear_vst_cache () { + PluginManager::instance().clear_vst_cache(); +} + +void RCOptionEditor::clear_vst_blacklist () { + PluginManager::instance().clear_vst_blacklist(); +} + +void RCOptionEditor::clear_au_cache () { + PluginManager::instance().clear_au_cache(); +} + +void RCOptionEditor::clear_au_blacklist () { + PluginManager::instance().clear_au_blacklist(); +} + +void RCOptionEditor::edit_lxvst_path () { + Glib::RefPtr win = get_parent_window (); + Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog ( + *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) { + _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths()); + } + delete pd; +} + +void RCOptionEditor::edit_vst_path () { + Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog ( + *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) { + _rc_config->set_plugin_path_vst(pd->get_serialized_paths()); + } + delete pd; +} + + void RCOptionEditor::populate_sync_options () { @@ -2139,4 +3336,29 @@ RCOptionEditor::populate_sync_options () for (vector::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) { _sync_source->add (*i, sync_source_to_string (*i)); } + + if (sync_opts.empty()) { + _sync_source->set_sensitive(false); + } else { + if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) { + _rc_config->set_sync_source(sync_opts.front()); + } + } + + parameter_changed ("sync-source"); +} + +Gtk::Window* +RCOptionEditor::use_own_window (bool and_fill_it) +{ + 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); + } + + return win; }