2 Copyright (C) 2001-2011 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "gtk2ardour-config.h"
24 #include <boost/algorithm/string.hpp>
26 #include <gtkmm/liststore.h>
27 #include <gtkmm/stock.h>
28 #include <gtkmm/scale.h>
30 #include <gtkmm2ext/utils.h>
31 #include <gtkmm2ext/slider_controller.h>
32 #include <gtkmm2ext/gtk_ui.h>
33 #include <gtkmm2ext/paths_dialog.h>
38 #include "ardour/audioengine.h"
39 #include "ardour/dB.h"
40 #include "ardour/rc_configuration.h"
41 #include "ardour/control_protocol_manager.h"
42 #include "ardour/plugin_manager.h"
43 #include "control_protocol/control_protocol.h"
45 #include "canvas/wave_view.h"
47 #include "ardour_ui.h"
48 #include "ardour_window.h"
49 #include "ardour_dialog.h"
50 #include "gui_thread.h"
51 #include "midi_tracer.h"
52 #include "rc_option_editor.h"
54 #include "midi_port_dialog.h"
61 using namespace Gtkmm2ext;
63 using namespace ARDOUR;
64 using namespace ARDOUR_UI_UTILS;
66 class ClickOptions : public OptionEditorBox
69 ClickOptions (RCConfiguration* c, Gtk::Window* p)
73 Table* t = manage (new Table (2, 3));
76 Label* l = manage (left_aligned_label (_("Click audio file:")));
77 t->attach (*l, 0, 1, 0, 1, FILL);
78 t->attach (_click_path_entry, 1, 2, 0, 1, FILL);
79 Button* b = manage (new Button (_("Browse...")));
80 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
81 t->attach (*b, 2, 3, 0, 1, FILL);
83 l = manage (left_aligned_label (_("Click emphasis audio file:")));
84 t->attach (*l, 0, 1, 1, 2, FILL);
85 t->attach (_click_emphasis_path_entry, 1, 2, 1, 2, FILL);
86 b = manage (new Button (_("Browse...")));
87 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
88 t->attach (*b, 2, 3, 1, 2, FILL);
90 _box->pack_start (*t, false, false);
92 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
93 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
96 void parameter_changed (string const & p)
98 if (p == "click-sound") {
99 _click_path_entry.set_text (_rc_config->get_click_sound());
100 } else if (p == "click-emphasis-sound") {
101 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
105 void set_state_from_config ()
107 parameter_changed ("click-sound");
108 parameter_changed ("click-emphasis-sound");
113 void click_browse_clicked ()
115 SoundFileChooser sfdb (_("Choose Click"));
117 if (sfdb.run () == RESPONSE_OK) {
118 click_chosen (sfdb.get_filename());
122 void click_chosen (string const & path)
124 _click_path_entry.set_text (path);
125 _rc_config->set_click_sound (path);
128 void click_changed ()
130 click_chosen (_click_path_entry.get_text ());
133 void click_emphasis_browse_clicked ()
135 SoundFileChooser sfdb (_("Choose Click Emphasis"));
140 if (sfdb.run () == RESPONSE_OK) {
141 click_emphasis_chosen (sfdb.get_filename());
145 void click_emphasis_chosen (string const & path)
147 _click_emphasis_path_entry.set_text (path);
148 _rc_config->set_click_emphasis_sound (path);
151 void click_emphasis_changed ()
153 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
156 RCConfiguration* _rc_config;
157 Gtk::Window* _parent;
158 Entry _click_path_entry;
159 Entry _click_emphasis_path_entry;
162 class UndoOptions : public OptionEditorBox
165 UndoOptions (RCConfiguration* c) :
167 _limit_undo_button (_("Limit undo history to")),
168 _save_undo_button (_("Save undo history of"))
170 Table* t = new Table (2, 3);
173 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
174 _limit_undo_spin.set_range (0, 512);
175 _limit_undo_spin.set_increments (1, 10);
176 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
177 Label* l = manage (left_aligned_label (_("commands")));
178 t->attach (*l, 2, 3, 0, 1);
180 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
181 _save_undo_spin.set_range (0, 512);
182 _save_undo_spin.set_increments (1, 10);
183 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
184 l = manage (left_aligned_label (_("commands")));
185 t->attach (*l, 2, 3, 1, 2);
187 _box->pack_start (*t);
189 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
190 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
191 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
192 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
195 void parameter_changed (string const & p)
197 if (p == "history-depth") {
198 int32_t const d = _rc_config->get_history_depth();
199 _limit_undo_button.set_active (d != 0);
200 _limit_undo_spin.set_sensitive (d != 0);
201 _limit_undo_spin.set_value (d);
202 } else if (p == "save-history") {
203 bool const x = _rc_config->get_save_history ();
204 _save_undo_button.set_active (x);
205 _save_undo_spin.set_sensitive (x);
206 } else if (p == "save-history-depth") {
207 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
211 void set_state_from_config ()
213 parameter_changed ("save-history");
214 parameter_changed ("history-depth");
215 parameter_changed ("save-history-depth");
218 void limit_undo_toggled ()
220 bool const x = _limit_undo_button.get_active ();
221 _limit_undo_spin.set_sensitive (x);
222 int32_t const n = x ? 16 : 0;
223 _limit_undo_spin.set_value (n);
224 _rc_config->set_history_depth (n);
227 void limit_undo_changed ()
229 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
232 void save_undo_toggled ()
234 bool const x = _save_undo_button.get_active ();
235 _rc_config->set_save_history (x);
238 void save_undo_changed ()
240 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
244 RCConfiguration* _rc_config;
245 CheckButton _limit_undo_button;
246 SpinButton _limit_undo_spin;
247 CheckButton _save_undo_button;
248 SpinButton _save_undo_spin;
253 static const struct {
265 { "Key|Shift", GDK_SHIFT_MASK },
266 { "Command", GDK_META_MASK },
267 { "Control", GDK_CONTROL_MASK },
268 { "Option", GDK_MOD1_MASK },
269 { "Command-Shift", GDK_META_MASK|GDK_SHIFT_MASK },
270 { "Command-Option", GDK_MOD1_MASK|GDK_META_MASK },
271 { "Shift-Option", GDK_SHIFT_MASK|GDK_MOD1_MASK },
272 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_META_MASK },
275 { "Key|Shift", GDK_SHIFT_MASK },
276 { "Control", GDK_CONTROL_MASK },
277 { "Alt (Mod1)", GDK_MOD1_MASK },
278 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
279 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
280 { "Shift-Alt", GDK_SHIFT_MASK|GDK_MOD1_MASK },
281 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
282 { "Mod2", GDK_MOD2_MASK },
283 { "Mod3", GDK_MOD3_MASK },
284 { "Mod4", GDK_MOD4_MASK },
285 { "Mod5", GDK_MOD5_MASK },
291 class KeyboardOptions : public OptionEditorBox
295 _delete_button_adjustment (3, 1, 12),
296 _delete_button_spin (_delete_button_adjustment),
297 _edit_button_adjustment (3, 1, 5),
298 _edit_button_spin (_edit_button_adjustment),
299 _insert_note_button_adjustment (3, 1, 5),
300 _insert_note_button_spin (_insert_note_button_adjustment)
302 /* internationalize and prepare for use with combos */
305 for (int i = 0; modifiers[i].name; ++i) {
306 dumb.push_back (S_(modifiers[i].name));
309 set_popdown_strings (_edit_modifier_combo, dumb);
310 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
312 for (int x = 0; modifiers[x].name; ++x) {
313 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
314 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
319 Table* t = manage (new Table (4, 4));
322 Label* l = manage (left_aligned_label (_("Edit using:")));
323 l->set_name ("OptionsLabel");
325 t->attach (*l, 0, 1, 0, 1, FILL | EXPAND, FILL);
326 t->attach (_edit_modifier_combo, 1, 2, 0, 1, FILL | EXPAND, FILL);
328 l = manage (new Label (_("+ button")));
329 l->set_name ("OptionsLabel");
331 t->attach (*l, 3, 4, 0, 1, FILL | EXPAND, FILL);
332 t->attach (_edit_button_spin, 4, 5, 0, 1, FILL | EXPAND, FILL);
334 _edit_button_spin.set_name ("OptionsEntry");
335 _edit_button_adjustment.set_value (Keyboard::edit_button());
336 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
338 set_popdown_strings (_delete_modifier_combo, dumb);
339 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
341 for (int x = 0; modifiers[x].name; ++x) {
342 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
343 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
348 l = manage (left_aligned_label (_("Delete using:")));
349 l->set_name ("OptionsLabel");
351 t->attach (*l, 0, 1, 1, 2, FILL | EXPAND, FILL);
352 t->attach (_delete_modifier_combo, 1, 2, 1, 2, FILL | EXPAND, FILL);
354 l = manage (new Label (_("+ button")));
355 l->set_name ("OptionsLabel");
357 t->attach (*l, 3, 4, 1, 2, FILL | EXPAND, FILL);
358 t->attach (_delete_button_spin, 4, 5, 1, 2, FILL | EXPAND, FILL);
360 _delete_button_spin.set_name ("OptionsEntry");
361 _delete_button_adjustment.set_value (Keyboard::delete_button());
362 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
365 set_popdown_strings (_insert_note_modifier_combo, dumb);
366 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
368 for (int x = 0; modifiers[x].name; ++x) {
369 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
370 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
375 l = manage (left_aligned_label (_("Insert note using:")));
376 l->set_name ("OptionsLabel");
378 t->attach (*l, 0, 1, 2, 3, FILL | EXPAND, FILL);
379 t->attach (_insert_note_modifier_combo, 1, 2, 2, 3, FILL | EXPAND, FILL);
381 l = manage (new Label (_("+ button")));
382 l->set_name ("OptionsLabel");
384 t->attach (*l, 3, 4, 2, 3, FILL | EXPAND, FILL);
385 t->attach (_insert_note_button_spin, 4, 5, 2, 3, FILL | EXPAND, FILL);
387 _insert_note_button_spin.set_name ("OptionsEntry");
388 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
389 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
392 set_popdown_strings (_snap_modifier_combo, dumb);
393 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
395 for (int x = 0; modifiers[x].name; ++x) {
396 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
397 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
402 l = manage (left_aligned_label (_("Ignore snap using:")));
403 l->set_name ("OptionsLabel");
405 t->attach (*l, 0, 1, 3, 4, FILL | EXPAND, FILL);
406 t->attach (_snap_modifier_combo, 1, 2, 3, 4, FILL | EXPAND, FILL);
410 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
411 strs.push_back (bf->first);
414 set_popdown_strings (_keyboard_layout_selector, strs);
415 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
416 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
418 l = manage (left_aligned_label (_("Keyboard layout:")));
419 l->set_name ("OptionsLabel");
421 t->attach (*l, 0, 1, 4, 5, FILL | EXPAND, FILL);
422 t->attach (_keyboard_layout_selector, 1, 2, 4, 5, FILL | EXPAND, FILL);
424 _box->pack_start (*t, false, false);
427 void parameter_changed (string const &)
429 /* XXX: these aren't really config options... */
432 void set_state_from_config ()
434 /* XXX: these aren't really config options... */
439 void bindings_changed ()
441 string const txt = _keyboard_layout_selector.get_active_text();
443 /* XXX: config...? for all this keyboard stuff */
445 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
446 if (txt == i->first) {
447 if (Keyboard::load_keybindings (i->second)) {
448 Keyboard::save_keybindings ();
454 void edit_modifier_chosen ()
456 string const txt = _edit_modifier_combo.get_active_text();
458 for (int i = 0; modifiers[i].name; ++i) {
459 if (txt == _(modifiers[i].name)) {
460 Keyboard::set_edit_modifier (modifiers[i].modifier);
466 void delete_modifier_chosen ()
468 string const txt = _delete_modifier_combo.get_active_text();
470 for (int i = 0; modifiers[i].name; ++i) {
471 if (txt == _(modifiers[i].name)) {
472 Keyboard::set_delete_modifier (modifiers[i].modifier);
478 void insert_note_modifier_chosen ()
480 string const txt = _insert_note_modifier_combo.get_active_text();
482 for (int i = 0; modifiers[i].name; ++i) {
483 if (txt == _(modifiers[i].name)) {
484 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
490 void snap_modifier_chosen ()
492 string const txt = _snap_modifier_combo.get_active_text();
494 for (int i = 0; modifiers[i].name; ++i) {
495 if (txt == _(modifiers[i].name)) {
496 Keyboard::set_snap_modifier (modifiers[i].modifier);
502 void delete_button_changed ()
504 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
507 void edit_button_changed ()
509 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
512 void insert_note_button_changed ()
514 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
517 ComboBoxText _keyboard_layout_selector;
518 ComboBoxText _edit_modifier_combo;
519 ComboBoxText _delete_modifier_combo;
520 ComboBoxText _insert_note_modifier_combo;
521 ComboBoxText _snap_modifier_combo;
522 Adjustment _delete_button_adjustment;
523 SpinButton _delete_button_spin;
524 Adjustment _edit_button_adjustment;
525 SpinButton _edit_button_spin;
526 Adjustment _insert_note_button_adjustment;
527 SpinButton _insert_note_button_spin;
531 class FontScalingOptions : public OptionEditorBox
534 FontScalingOptions (RCConfiguration* c) :
536 _dpi_adjustment (50, 50, 250, 1, 10),
537 _dpi_slider (_dpi_adjustment)
539 _dpi_adjustment.set_value (floor ((double)(_rc_config->get_font_scale () / 1024)));
541 Label* l = manage (new Label (_("Font scaling:")));
542 l->set_name ("OptionsLabel");
544 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
545 HBox* h = manage (new HBox);
547 h->pack_start (*l, false, false);
548 h->pack_start (_dpi_slider, true, true);
550 _box->pack_start (*h, false, false);
552 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
555 void parameter_changed (string const & p)
557 if (p == "font-scale") {
558 _dpi_adjustment.set_value (floor ((double)(_rc_config->get_font_scale() / 1024)));
562 void set_state_from_config ()
564 parameter_changed ("font-scale");
571 _rc_config->set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024));
572 /* XXX: should be triggered from the parameter changed signal */
576 RCConfiguration* _rc_config;
577 Adjustment _dpi_adjustment;
581 class ClipLevelOptions : public OptionEditorBox
584 ClipLevelOptions (RCConfiguration* c)
586 , _clip_level_adjustment (0, -128.0, 2.0, 0.1, 1.0) /* units of dB */
587 , _clip_level_slider (_clip_level_adjustment)
589 _clip_level_adjustment.set_value (_rc_config->get_waveform_clip_level ());
591 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
592 l->set_name ("OptionsLabel");
594 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
595 HBox* h = manage (new HBox);
597 h->pack_start (*l, false, false);
598 h->pack_start (_clip_level_slider, true, true);
600 _box->pack_start (*h, false, false);
602 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
605 void parameter_changed (string const & p)
607 if (p == "waveform-clip-level") {
608 _clip_level_adjustment.set_value (_rc_config->get_waveform_clip_level());
612 void set_state_from_config ()
614 parameter_changed ("waveform-clip-level");
619 void clip_level_changed ()
621 _rc_config->set_waveform_clip_level (_clip_level_adjustment.get_value());
622 /* XXX: should be triggered from the parameter changed signal */
623 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
626 RCConfiguration* _rc_config;
627 Adjustment _clip_level_adjustment;
628 HScale _clip_level_slider;
631 class BufferingOptions : public OptionEditorBox
634 BufferingOptions (RCConfiguration* c)
636 , _playback_adjustment (5, 1, 60, 1, 4)
637 , _capture_adjustment (5, 1, 60, 1, 4)
638 , _playback_slider (_playback_adjustment)
639 , _capture_slider (_capture_adjustment)
641 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
643 Label* l = manage (new Label (_("Playback (seconds of buffering):")));
644 l->set_name ("OptionsLabel");
646 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
647 HBox* h = manage (new HBox);
649 h->pack_start (*l, false, false);
650 h->pack_start (_playback_slider, true, true);
652 _box->pack_start (*h, false, false);
654 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
656 l = manage (new Label (_("Recording (seconds of buffering):")));
657 l->set_name ("OptionsLabel");
659 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
660 h = manage (new HBox);
662 h->pack_start (*l, false, false);
663 h->pack_start (_capture_slider, true, true);
665 _box->pack_start (*h, false, false);
667 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
668 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
671 void parameter_changed (string const & p)
673 if (p == "playback-buffer-seconds") {
674 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
675 } else if (p == "capture-buffer-seconds") {
676 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
680 void set_state_from_config ()
682 parameter_changed ("playback-buffer-seconds");
683 parameter_changed ("capture-buffer-seconds");
688 void playback_changed ()
690 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
693 void capture_changed ()
695 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
698 RCConfiguration* _rc_config;
699 Adjustment _playback_adjustment;
700 Adjustment _capture_adjustment;
701 HScale _playback_slider;
702 HScale _capture_slider;
705 class ControlSurfacesOptions : public OptionEditorBox
708 ControlSurfacesOptions (Gtk::Window& parent)
710 , _ignore_view_change (0)
712 _store = ListStore::create (_model);
713 _view.set_model (_store);
714 _view.append_column (_("Control Surface Protocol"), _model.name);
715 _view.get_column(0)->set_resizable (true);
716 _view.get_column(0)->set_expand (true);
717 _view.append_column_editable (_("Enabled"), _model.enabled);
718 _view.append_column_editable (_("Feedback"), _model.feedback);
720 _box->pack_start (_view, false, false);
722 Label* label = manage (new Label);
723 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
725 _box->pack_start (*label, false, false);
728 ControlProtocolManager& m = ControlProtocolManager::instance ();
729 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
730 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
732 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
733 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
736 void parameter_changed (std::string const &)
741 void set_state_from_config ()
745 ControlProtocolManager& m = ControlProtocolManager::instance ();
746 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
748 if (!(*i)->mandatory) {
749 TreeModel::Row r = *_store->append ();
750 r[_model.name] = (*i)->name;
751 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
752 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
753 r[_model.protocol_info] = *i;
760 void protocol_status_changed (ControlProtocolInfo* cpi) {
762 TreeModel::Children rows = _store->children();
764 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
765 string n = ((*x)[_model.name]);
767 if ((*x)[_model.protocol_info] == cpi) {
768 _ignore_view_change++;
769 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
770 _ignore_view_change--;
776 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
778 TreeModel::Row r = *i;
780 if (_ignore_view_change) {
784 ControlProtocolInfo* cpi = r[_model.protocol_info];
789 bool const was_enabled = (cpi->protocol != 0);
790 bool const is_enabled = r[_model.enabled];
793 if (was_enabled != is_enabled) {
796 ControlProtocolManager::instance().activate (*cpi);
798 Gtk::Window* win = r[_model.editor];
803 ControlProtocolManager::instance().deactivate (*cpi);
807 r[_model.editor] = 0;
812 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
813 bool const is_feedback = r[_model.feedback];
815 if (was_feedback != is_feedback && cpi->protocol) {
816 cpi->protocol->set_feedback (is_feedback);
820 void edit_clicked (GdkEventButton* ev)
822 if (ev->type != GDK_2BUTTON_PRESS) {
827 ControlProtocolInfo* cpi;
830 row = *(_view.get_selection()->get_selected());
832 Window* win = row[_model.editor];
833 if (win && !win->is_visible()) {
836 cpi = row[_model.protocol_info];
838 if (cpi && cpi->protocol && cpi->protocol->has_editor ()) {
839 Box* box = (Box*) cpi->protocol->get_gui ();
841 string title = row[_model.name];
842 ArdourWindow* win = new ArdourWindow (_parent, title);
843 win->set_title ("Control Protocol Options");
847 row[_model.editor] = win;
853 class ControlSurfacesModelColumns : public TreeModelColumnRecord
857 ControlSurfacesModelColumns ()
866 TreeModelColumn<string> name;
867 TreeModelColumn<bool> enabled;
868 TreeModelColumn<bool> feedback;
869 TreeModelColumn<ControlProtocolInfo*> protocol_info;
870 TreeModelColumn<Gtk::Window*> editor;
873 Glib::RefPtr<ListStore> _store;
874 ControlSurfacesModelColumns _model;
876 Gtk::Window& _parent;
877 PBD::ScopedConnection protocol_status_connection;
878 uint32_t _ignore_view_change;
881 class VideoTimelineOptions : public OptionEditorBox
884 VideoTimelineOptions (RCConfiguration* c)
886 , _show_video_export_info_button (_("Show Video Export Info before export"))
887 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
888 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
890 Table* t = manage (new Table (2, 6));
893 t->attach (_video_advanced_setup_button, 0, 2, 0, 1);
894 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
895 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
896 _("<b>When enabled</b> you can speficify a custom video-server URL and docroot. - Do not enable this option unless you know what you are doing."));
898 Label* l = manage (new Label (_("Video Server URL:")));
899 l->set_alignment (0, 0.5);
900 t->attach (*l, 0, 1, 1, 2, FILL);
901 t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL);
902 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
903 _("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"));
905 l = manage (new Label (_("Video Folder:")));
906 l->set_alignment (0, 0.5);
907 t->attach (*l, 0, 1, 2, 3, FILL);
908 t->attach (_video_server_docroot_entry, 1, 2, 2, 3);
909 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
910 _("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."));
912 /* small vspace y=3..4 */
914 t->attach (_show_video_export_info_button, 0, 2, 4, 5);
915 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
916 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
917 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
919 t->attach (_show_video_server_dialog_button, 0, 2, 5, 6);
920 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
921 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
922 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
924 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
925 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
926 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
927 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
929 _box->pack_start (*t,true,true);
932 void server_url_changed ()
934 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
937 void server_docroot_changed ()
939 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
942 void show_video_export_info_toggled ()
944 bool const x = _show_video_export_info_button.get_active ();
945 _rc_config->set_show_video_export_info (x);
948 void show_video_server_dialog_toggled ()
950 bool const x = _show_video_server_dialog_button.get_active ();
951 _rc_config->set_show_video_server_dialog (x);
954 void video_advanced_setup_toggled ()
956 bool const x = _video_advanced_setup_button.get_active ();
957 _rc_config->set_video_advanced_setup(x);
960 void parameter_changed (string const & p)
962 if (p == "video-server-url") {
963 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
964 } else if (p == "video-server-docroot") {
965 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
966 } else if (p == "show-video-export-info") {
967 bool const x = _rc_config->get_show_video_export_info();
968 _show_video_export_info_button.set_active (x);
969 } else if (p == "show-video-server-dialog") {
970 bool const x = _rc_config->get_show_video_server_dialog();
971 _show_video_server_dialog_button.set_active (x);
972 } else if (p == "video-advanced-setup") {
973 bool const x = _rc_config->get_video_advanced_setup();
974 _video_advanced_setup_button.set_active(x);
975 _video_server_docroot_entry.set_sensitive(x);
976 _video_server_url_entry.set_sensitive(x);
980 void set_state_from_config ()
982 parameter_changed ("video-server-url");
983 parameter_changed ("video-server-docroot");
984 parameter_changed ("video-monitor-setup-dialog");
985 parameter_changed ("show-video-export-info");
986 parameter_changed ("show-video-server-dialog");
987 parameter_changed ("video-advanced-setup");
991 RCConfiguration* _rc_config;
992 Entry _video_server_url_entry;
993 Entry _video_server_docroot_entry;
994 CheckButton _show_video_export_info_button;
995 CheckButton _show_video_server_dialog_button;
996 CheckButton _video_advanced_setup_button;
999 class PluginOptions : public OptionEditorBox
1002 PluginOptions (RCConfiguration* c)
1004 , _display_plugin_scan_progress (_("Always Display Plugin Scan Progress"))
1005 , _discover_vst_on_start (_("Scan for new VST Plugins on Application Start"))
1006 , _timeout_adjustment (0, 0, 3000, 50, 50)
1007 , _timeout_slider (_timeout_adjustment)
1010 std::stringstream ss;
1011 Table* t = manage (new Table (2, 6));
1012 t->set_spacings (4);
1016 ss << "<b>" << _("General") << "</b>";
1017 l = manage (left_aligned_label (ss.str()));
1018 l->set_use_markup (true);
1019 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1020 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1022 b = manage (new Button (_("Scan for Plugins")));
1023 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1024 t->attach (*b, 0, 2, n, n+1, FILL); ++n;
1026 t->attach (_display_plugin_scan_progress, 0, 2, n, n+1); ++n;
1027 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1028 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1029 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
1031 _timeout_slider.set_digits (0);
1032 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &PluginOptions::timeout_changed));
1034 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1035 _("Specify the default timeout for plugin instantiation in 1/10 seconds. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1037 l = manage (left_aligned_label (_("Scan Time Out [deciseconds]")));;
1038 HBox* h = manage (new HBox);
1040 h->pack_start (*l, false, false);
1041 h->pack_start (_timeout_slider, true, true);
1042 t->attach (*h, 0, 2, n, n+1); ++n;
1045 ss << "<b>" << _("VST") << "</b>";
1046 l = manage (left_aligned_label (ss.str()));
1047 l->set_use_markup (true);
1048 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1049 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1051 b = manage (new Button (_("Clear VST Cache")));
1052 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_cache_clicked));
1053 t->attach (*b, 0, 1, n, n+1, FILL);
1055 b = manage (new Button (_("Clear VST Blacklist")));
1056 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_blacklist_clicked));
1057 t->attach (*b, 1, 2, n, n+1, FILL);
1060 t->attach (_discover_vst_on_start, 0, 2, n, n+1); ++n;
1061 _discover_vst_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_vst_on_start_toggled));
1062 Gtkmm2ext::UI::instance()->set_tip (_discover_vst_on_start,
1063 _("<b>When enabled</b> 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"));
1065 #ifdef LXVST_SUPPORT
1066 t->attach (*manage (left_aligned_label (_("Linux VST Path:"))), 0, 1, n, n+1);
1067 b = manage (new Button (_("Edit")));
1068 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_lxvst_path_clicked));
1069 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1072 #ifdef WINDOWS_VST_SUPPORT
1073 t->attach (*manage (left_aligned_label (_("Windows VST Path:"))), 0, 1, n, n+1);
1074 b = manage (new Button (_("Edit")));
1075 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_vst_path_clicked));
1076 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1079 _box->pack_start (*t,true,true);
1082 void parameter_changed (string const & p) {
1083 if (p == "show-plugin-scan-window") {
1084 bool const x = _rc_config->get_show_plugin_scan_window();
1085 _display_plugin_scan_progress.set_active (x);
1087 else if (p == "discover-vst-on-start") {
1088 bool const x = _rc_config->get_discover_vst_on_start();
1089 _discover_vst_on_start.set_active (x);
1091 else if (p == "vst-scan-timeout") {
1092 int const x = _rc_config->get_vst_scan_timeout();
1093 _timeout_adjustment.set_value (x);
1097 void set_state_from_config () {
1098 parameter_changed ("show-plugin-scan-window");
1099 parameter_changed ("discover-vst-on-start");
1100 parameter_changed ("vst-scan-timeout");
1104 RCConfiguration* _rc_config;
1105 CheckButton _display_plugin_scan_progress;
1106 CheckButton _discover_vst_on_start;
1107 Adjustment _timeout_adjustment;
1108 HScale _timeout_slider;
1110 void display_plugin_scan_progress_toggled () {
1111 bool const x = _display_plugin_scan_progress.get_active();
1112 _rc_config->set_show_plugin_scan_window(x);
1115 void discover_vst_on_start_toggled () {
1116 bool const x = _discover_vst_on_start.get_active();
1117 _rc_config->set_discover_vst_on_start(x);
1120 void timeout_changed () {
1121 int x = floor(_timeout_adjustment.get_value());
1122 _rc_config->set_vst_scan_timeout(x);
1125 void clear_vst_cache_clicked () {
1126 PluginManager::instance().clear_vst_cache();
1129 void clear_vst_blacklist_clicked () {
1130 PluginManager::instance().clear_vst_blacklist();
1133 void edit_vst_path_clicked () {
1134 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1135 _("Set Windows VST Search Path"),
1136 _rc_config->get_plugin_path_vst(),
1137 PluginManager::instance().get_default_windows_vst_path()
1139 ResponseType r = (ResponseType) pd->run ();
1141 if (r == RESPONSE_ACCEPT) {
1142 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
1147 // todo consolidate with edit_vst_path_clicked..
1148 void edit_lxvst_path_clicked () {
1149 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1150 _("Set Linux VST Search Path"),
1151 _rc_config->get_plugin_path_lxvst(),
1152 PluginManager::instance().get_default_lxvst_path()
1154 ResponseType r = (ResponseType) pd->run ();
1156 if (r == RESPONSE_ACCEPT) {
1157 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
1162 void refresh_clicked () {
1163 PluginManager::instance().refresh();
1168 /** A class which allows control of visibility of some editor components usign
1169 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1170 * which has the correct members, but with null widget pointers. This
1171 * class allows the user to set visibility of the members, the details
1172 * of which are stored in a configuration variable which can be watched
1173 * by parts of the editor that actually contain the widgets whose visibility
1174 * is being controlled.
1177 class VisibilityOption : public Option
1180 /** @param name User-visible name for this group.
1181 * @param g `Dummy' VisibilityGroup (as described above).
1182 * @param get Method to get the value of the appropriate configuration variable.
1183 * @param set Method to set the value of the appropriate configuration variable.
1185 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1186 : Option (g->get_state_name(), name)
1188 , _visibility_group (g)
1192 /* Watch for changes made by the user to our members */
1193 _visibility_group->VisibilityChanged.connect_same_thread (
1194 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1198 void set_state_from_config ()
1200 /* Set our state from the current configuration */
1201 _visibility_group->set_state (_get ());
1204 void add_to_page (OptionEditorPage* p)
1206 _heading.add_to_page (p);
1207 add_widget_to_page (p, _visibility_group->list_view ());
1210 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1215 /* The user has changed something, so reflect this change
1216 in the RCConfiguration.
1218 _set (_visibility_group->get_state_value ());
1221 OptionEditorHeading _heading;
1222 VisibilityGroup* _visibility_group;
1223 sigc::slot<std::string> _get;
1224 sigc::slot<bool, std::string> _set;
1225 PBD::ScopedConnection _visibility_group_connection;
1230 RCOptionEditor::RCOptionEditor ()
1231 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1232 , _rc_config (Config)
1233 , _mixer_strip_visibility ("mixer-strip-visibility")
1237 uint32_t hwcpus = hardware_concurrency ();
1239 BoolComboOption* bco;
1242 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1244 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1246 _("Signal processing uses"),
1247 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1248 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1251 procs->add (-1, _("all but one processor"));
1252 procs->add (0, _("all available processors"));
1254 for (uint32_t i = 1; i <= hwcpus; ++i) {
1255 procs->add (i, string_compose (_("%1 processors"), i));
1258 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1260 add_option (_("Misc"), procs);
1263 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1265 add_option (_("Misc"), new UndoOptions (_rc_config));
1267 add_option (_("Misc"),
1269 "verify-remove-last-capture",
1270 _("Verify removal of last capture"),
1271 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1272 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1275 add_option (_("Misc"),
1277 "periodic-safety-backups",
1278 _("Make periodic backups of the session file"),
1279 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1280 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1283 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1285 add_option (_("Misc"),
1287 "only-copy-imported-files",
1288 _("Always copy imported files"),
1289 sigc::mem_fun (*_rc_config, &RCConfiguration::get_only_copy_imported_files),
1290 sigc::mem_fun (*_rc_config, &RCConfiguration::set_only_copy_imported_files)
1293 add_option (_("Misc"), new DirectoryOption (
1294 X_("default-session-parent-dir"),
1295 _("Default folder for new sessions:"),
1296 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1297 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1300 add_option (_("Misc"),
1301 new SpinOption<uint32_t> (
1302 "max-recent-sessions",
1303 _("Maximum number of recent sessions"),
1304 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1305 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1309 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1311 add_option (_("Misc"), new ClickOptions (_rc_config, this));
1313 add_option (_("Misc"),
1316 _("Click gain level"),
1317 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1318 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1321 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1323 add_option (_("Misc"),
1324 new SpinOption<double> (
1325 "automation-thinning-factor",
1326 _("Thinning factor (larger value => less data)"),
1327 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1328 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1332 add_option (_("Misc"),
1333 new SpinOption<double> (
1334 "automation-interval-msecs",
1335 _("Automation sampling interval (milliseconds)"),
1336 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1337 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1345 tsf = new BoolOption (
1346 "latched-record-enable",
1347 _("Keep record-enable engaged on stop"),
1348 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1349 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1351 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1352 add_option (_("Transport"), tsf);
1354 tsf = new BoolOption (
1355 "stop-recording-on-xrun",
1356 _("Stop recording when an xrun occurs"),
1357 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1358 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1360 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1361 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
1363 add_option (_("Transport"), tsf);
1365 tsf = new BoolOption (
1367 _("Play loop is a transport mode"),
1368 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1369 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1371 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1372 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1373 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1374 add_option (_("Transport"), tsf);
1376 tsf = new BoolOption (
1377 "create-xrun-marker",
1378 _("Create markers where xruns occur"),
1379 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
1380 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
1382 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1383 add_option (_("Transport"), tsf);
1385 tsf = new BoolOption (
1386 "stop-at-session-end",
1387 _("Stop at the end of the session"),
1388 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
1389 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
1391 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1392 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
1393 "when it reaches the current session end marker\n\n"
1394 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
1396 add_option (_("Transport"), tsf);
1398 tsf = new BoolOption (
1400 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
1401 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
1402 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
1404 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1405 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
1406 "preventing any need to do a transport locate at the end of the loop\n\n"
1407 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
1408 "which will often cause a small click or delay"), PROGRAM_NAME));
1409 add_option (_("Transport"), tsf);
1411 tsf = new BoolOption (
1412 "disable-disarm-during-roll",
1413 _("Disable per-track record disarm while rolling"),
1414 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
1415 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
1417 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("<b>When enabled</b> this will prevent you from accidentally stopping specific tracks recording during a take"));
1418 add_option (_("Transport"), tsf);
1420 tsf = new BoolOption (
1422 _("12dB gain reduction during fast-forward and fast-rewind"),
1423 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
1424 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
1426 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
1427 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
1428 add_option (_("Transport"), tsf);
1430 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
1432 _sync_source = new ComboOption<SyncSource> (
1434 _("External timecode source"),
1435 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
1436 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
1439 populate_sync_options ();
1440 add_option (_("Transport"), _sync_source);
1442 _sync_framerate = new BoolOption (
1443 "timecode-sync-frame-rate",
1444 _("Match session video frame rate to external timecode"),
1445 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
1446 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
1448 Gtkmm2ext::UI::instance()->set_tip
1449 (_sync_framerate->tip_widget(),
1450 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
1451 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
1452 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
1453 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
1454 "timecode standard and the session standard."), PROGRAM_NAME));
1456 add_option (_("Transport"), _sync_framerate);
1458 _sync_genlock = new BoolOption (
1459 "timecode-source-is-synced",
1460 _("External timecode is sync locked"),
1461 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
1462 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
1464 Gtkmm2ext::UI::instance()->set_tip
1465 (_sync_genlock->tip_widget(),
1466 _("<b>When enabled</b> indicates that the selected external timecode source shares sync (Black & Burst, Wordclock, etc) with the audio interface."));
1469 add_option (_("Transport"), _sync_genlock);
1471 _sync_source_2997 = new BoolOption (
1472 "timecode-source-2997",
1473 _("Lock to 29.9700 fps instead of 30000/1001"),
1474 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
1475 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
1477 Gtkmm2ext::UI::instance()->set_tip
1478 (_sync_source_2997->tip_widget(),
1479 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
1480 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
1481 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
1482 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
1483 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
1484 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
1487 add_option (_("Transport"), _sync_source_2997);
1489 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
1491 _ltc_port = new ComboStringOption (
1493 _("LTC incoming port"),
1494 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
1495 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
1498 vector<string> physical_inputs;
1499 physical_inputs.push_back (_("None"));
1500 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
1501 _ltc_port->set_popdown_strings (physical_inputs);
1503 add_option (_("Transport"), _ltc_port);
1505 // TODO; rather disable this button than not compile it..
1506 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
1508 add_option (_("Transport"),
1511 _("Enable LTC generator"),
1512 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
1513 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
1516 _ltc_send_continuously = new BoolOption (
1517 "ltc-send-continuously",
1518 _("Send LTC while stopped"),
1519 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
1520 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
1522 Gtkmm2ext::UI::instance()->set_tip
1523 (_ltc_send_continuously->tip_widget(),
1524 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
1525 add_option (_("Transport"), _ltc_send_continuously);
1527 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
1528 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
1529 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
1530 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
1532 Gtkmm2ext::UI::instance()->set_tip
1533 (_ltc_volume_slider->tip_widget(),
1534 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
1536 add_option (_("Transport"), _ltc_volume_slider);
1537 parameter_changed ("send-ltc");
1539 parameter_changed ("sync-source");
1543 add_option (S_("Editor"),
1545 "draggable-playhead",
1546 _("Allow dragging of playhead"),
1547 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_draggable_playhead),
1548 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_draggable_playhead)
1551 add_option (_("Editor"),
1553 "link-region-and-track-selection",
1554 _("Link selection of regions and tracks"),
1555 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_region_and_track_selection),
1556 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_region_and_track_selection)
1559 add_option (_("Editor"),
1561 "automation-follows-regions",
1562 _("Move relevant automation when audio regions are moved"),
1563 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
1564 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
1567 add_option (_("Editor"),
1569 "show-track-meters",
1570 _("Show meters on tracks in the editor"),
1571 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_track_meters),
1572 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_track_meters)
1575 add_option (_("Editor"),
1577 "show-editor-meter",
1578 _("Display master-meter in the toolbar"),
1579 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_editor_meter),
1580 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_editor_meter)
1583 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
1584 "default-fade-shape",
1585 _("Default fade shape"),
1586 sigc::mem_fun (*_rc_config,
1587 &RCConfiguration::get_default_fade_shape),
1588 sigc::mem_fun (*_rc_config,
1589 &RCConfiguration::set_default_fade_shape)
1592 fadeshape->add (FadeLinear,
1593 _("Linear (for highly correlated material)"));
1594 fadeshape->add (FadeConstantPower, _("Constant power"));
1595 fadeshape->add (FadeSymmetric, _("Symmetric"));
1596 fadeshape->add (FadeSlow, _("Slow"));
1597 fadeshape->add (FadeFast, _("Fast"));
1599 add_option (_("Editor"), fadeshape);
1602 bco = new BoolComboOption (
1603 "use-overlap-equivalency",
1604 _("Regions in active edit groups are edited together"),
1605 _("whenever they overlap in time"),
1606 _("only if they have identical length, position and origin"),
1607 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
1608 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
1611 add_option (_("Editor"), bco);
1613 add_option (_("Editor"),
1615 "rubberbanding-snaps-to-grid",
1616 _("Make rubberband selection rectangle snap to the grid"),
1617 sigc::mem_fun (*_rc_config, &RCConfiguration::get_rubberbanding_snaps_to_grid),
1618 sigc::mem_fun (*_rc_config, &RCConfiguration::set_rubberbanding_snaps_to_grid)
1621 add_option (_("Editor"),
1624 _("Show waveforms in regions"),
1625 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms),
1626 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms)
1629 add_option (_("Editor"),
1630 new BoolComboOption (
1631 "show-region-gain-envelopes",
1632 _("Show gain envelopes in audio regions"),
1634 _("only in region gain mode"),
1635 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_region_gain),
1636 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_region_gain)
1639 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
1641 _("Waveform scale"),
1642 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_scale),
1643 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_scale)
1646 wfs->add (Linear, _("linear"));
1647 wfs->add (Logarithmic, _("logarithmic"));
1649 add_option (_("Editor"), wfs);
1651 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
1653 _("Waveform shape"),
1654 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_shape),
1655 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_shape)
1658 wfsh->add (Traditional, _("traditional"));
1659 wfsh->add (Rectified, _("rectified"));
1661 add_option (_("Editor"), wfsh);
1663 add_option (_("Editor"), new ClipLevelOptions (_rc_config));
1665 add_option (_("Editor"),
1667 "show-waveforms-while-recording",
1668 _("Show waveforms for audio while it is being recorded"),
1669 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms_while_recording),
1670 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms_while_recording)
1673 add_option (_("Editor"),
1676 _("Show zoom toolbar"),
1677 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_zoom_tools),
1678 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_zoom_tools)
1681 add_option (_("Editor"),
1683 "update-editor-during-summary-drag",
1684 _("Update editor window during drags of the summary"),
1685 sigc::mem_fun (*_rc_config, &RCConfiguration::get_update_editor_during_summary_drag),
1686 sigc::mem_fun (*_rc_config, &RCConfiguration::set_update_editor_during_summary_drag)
1689 add_option (_("Editor"),
1691 "link-editor-and-mixer-selection",
1692 _("Synchronise editor and mixer selection"),
1693 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_editor_and_mixer_selection),
1694 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_editor_and_mixer_selection)
1697 bo = new BoolOption (
1699 _("Name new markers"),
1700 sigc::mem_fun (*_rc_config, &RCConfiguration::get_name_new_markers),
1701 sigc::mem_fun (*_rc_config, &RCConfiguration::set_name_new_markers)
1704 add_option (_("Editor"), bo);
1705 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."
1706 "\n\nYou can always rename markers by right-clicking on them"));
1708 add_option (_("Editor"),
1710 "autoscroll-editor",
1711 _("Auto-scroll editor window when dragging near its edges"),
1712 sigc::mem_fun (*_rc_config, &RCConfiguration::get_autoscroll_editor),
1713 sigc::mem_fun (*_rc_config, &RCConfiguration::set_autoscroll_editor)
1718 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
1720 add_option (_("Audio"), new BufferingOptions (_rc_config));
1722 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
1724 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
1726 _("Record monitoring handled by"),
1727 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
1728 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
1731 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
1732 mm->add (HardwareMonitoring, _("via Audio Driver"));
1735 string prog (PROGRAM_NAME);
1736 boost::algorithm::to_lower (prog);
1737 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
1738 mm->add (ExternalMonitoring, _("audio hardware"));
1740 add_option (_("Audio"), mm);
1742 add_option (_("Audio"),
1744 "tape-machine-mode",
1745 _("Tape machine mode"),
1746 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
1747 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
1750 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
1752 add_option (_("Audio"),
1754 "auto-connect-standard-busses",
1755 _("Auto-connect master/monitor busses"),
1756 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
1757 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
1760 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
1761 "input-auto-connect",
1762 _("Connect track inputs"),
1763 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
1764 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
1767 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
1768 iac->add (ManualConnect, _("manually"));
1770 add_option (_("Audio"), iac);
1772 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
1773 "output-auto-connect",
1774 _("Connect track and bus outputs"),
1775 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
1776 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
1779 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
1780 oac->add (AutoConnectMaster, _("automatically to master bus"));
1781 oac->add (ManualConnect, _("manually"));
1783 add_option (_("Audio"), oac);
1785 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
1787 add_option (_("Audio"),
1789 "denormal-protection",
1790 _("Use DC bias to protect against denormals"),
1791 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
1792 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
1795 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
1797 _("Processor handling"),
1798 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
1799 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
1802 dm->add (DenormalNone, _("no processor handling"));
1806 if (fpu.has_flush_to_zero()) {
1807 dm->add (DenormalFTZ, _("use FlushToZero"));
1810 if (fpu.has_denormals_are_zero()) {
1811 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
1814 if (fpu.has_flush_to_zero() && fpu.has_denormals_are_zero()) {
1815 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
1818 add_option (_("Audio"), dm);
1820 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
1822 add_option (_("Audio"),
1824 "plugins-stop-with-transport",
1825 _("Silence plugins when the transport is stopped"),
1826 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
1827 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
1830 add_option (_("Audio"),
1832 "new-plugins-active",
1833 _("Make new plugins active"),
1834 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
1835 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
1838 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
1840 add_option (_("Audio"),
1842 "auto-analyse-audio",
1843 _("Enable automatic analysis of audio"),
1844 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
1845 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
1848 add_option (_("Audio"),
1850 "replicate-missing-region-channels",
1851 _("Replicate missing region channels"),
1852 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
1853 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
1858 add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
1860 add_option (_("Solo / mute"),
1863 _("Solo-in-place mute cut (dB)"),
1864 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
1865 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
1868 _solo_control_is_listen_control = new BoolOption (
1869 "solo-control-is-listen-control",
1870 _("Solo controls are Listen controls"),
1871 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
1872 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
1875 add_option (_("Solo / mute"), _solo_control_is_listen_control);
1877 _listen_position = new ComboOption<ListenPosition> (
1879 _("Listen Position"),
1880 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
1881 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
1884 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
1885 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
1887 add_option (_("Solo / mute"), _listen_position);
1889 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
1891 _("PFL signals come from"),
1892 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
1893 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
1896 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
1897 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
1899 add_option (_("Solo / mute"), pp);
1901 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
1903 _("AFL signals come from"),
1904 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
1905 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
1908 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
1909 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
1911 add_option (_("Solo / mute"), pa);
1913 parameter_changed ("use-monitor-bus");
1915 add_option (_("Solo / mute"),
1918 _("Exclusive solo"),
1919 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
1920 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
1923 add_option (_("Solo / mute"),
1926 _("Show solo muting"),
1927 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
1928 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
1931 add_option (_("Solo / mute"),
1933 "solo-mute-override",
1934 _("Soloing overrides muting"),
1935 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
1936 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
1939 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
1941 add_option (_("Solo / mute"),
1943 "mute-affects-pre-fader",
1944 _("Mute affects pre-fader sends"),
1945 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
1946 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
1949 add_option (_("Solo / mute"),
1951 "mute-affects-post-fader",
1952 _("Mute affects post-fader sends"),
1953 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
1954 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
1957 add_option (_("Solo / mute"),
1959 "mute-affects-control-outs",
1960 _("Mute affects control outputs"),
1961 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
1962 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
1965 add_option (_("Solo / mute"),
1967 "mute-affects-main-outs",
1968 _("Mute affects main outputs"),
1969 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
1970 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
1973 add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
1975 add_option (_("Solo / mute"),
1977 "link-send-and-route-panner",
1978 _("Link panners of Aux and External Sends with main panner by default"),
1979 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
1980 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
1983 add_option (_("MIDI"),
1986 _("Send MIDI Clock"),
1987 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
1988 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
1991 add_option (_("MIDI"),
1994 _("Send MIDI Time Code"),
1995 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
1996 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
1999 add_option (_("MIDI"),
2000 new SpinOption<int> (
2001 "mtc-qf-speed-tolerance",
2002 _("Percentage either side of normal transport speed to transmit MTC"),
2003 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2004 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2008 add_option (_("MIDI"),
2011 _("Obey MIDI Machine Control commands"),
2012 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2013 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2016 add_option (_("MIDI"),
2019 _("Send MIDI Machine Control commands"),
2020 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2021 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2024 add_option (_("MIDI"),
2027 _("Send MIDI control feedback"),
2028 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2029 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2032 add_option (_("MIDI"),
2033 new SpinOption<uint8_t> (
2034 "mmc-receive-device-id",
2035 _("Inbound MMC device ID"),
2036 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2037 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2041 add_option (_("MIDI"),
2042 new SpinOption<uint8_t> (
2043 "mmc-send-device-id",
2044 _("Outbound MMC device ID"),
2045 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2046 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2050 add_option (_("MIDI"),
2051 new SpinOption<int32_t> (
2052 "initial-program-change",
2053 _("Initial program change"),
2054 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2055 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2059 add_option (_("MIDI"),
2061 "display-first-midi-bank-as-zero",
2062 _("Display first MIDI bank/program as 0"),
2063 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2064 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2067 add_option (_("MIDI"),
2069 "never-display-periodic-midi",
2070 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2071 sigc::mem_fun (*_rc_config, &RCConfiguration::get_never_display_periodic_midi),
2072 sigc::mem_fun (*_rc_config, &RCConfiguration::set_never_display_periodic_midi)
2075 add_option (_("MIDI"),
2078 _("Sound MIDI notes as they are selected"),
2079 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sound_midi_notes),
2080 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sound_midi_notes)
2083 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2085 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2086 "midi-audition-synth-uri",
2087 _("Midi Audition Synth (LV2)"),
2088 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2089 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2092 audition_synth->add(X_(""), _("None"));
2093 PluginInfoList all_plugs;
2094 PluginManager& manager (PluginManager::instance());
2096 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2098 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2099 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2100 if (!(*i)->is_instrument()) continue;
2101 if ((*i)->type != ARDOUR::LV2) continue;
2102 audition_synth->add((*i)->unique_id, (*i)->name);
2106 add_option (_("MIDI"), audition_synth);
2108 /* USER INTERACTION */
2110 if (getenv ("ARDOUR_BUNDLED")) {
2111 add_option (_("User interaction"),
2113 "enable-translation",
2114 string_compose (_("Use translations of %1 messages\n"
2115 " <i>(requires a restart of %1 to take effect)</i>\n"
2116 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2117 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2118 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2121 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2123 add_option (_("User interaction"), new KeyboardOptions);
2125 /* Control Surfaces */
2127 add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
2129 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2131 _("Control surface remote ID"),
2132 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2133 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2136 rm->add (UserOrdered, _("assigned by user"));
2137 rm->add (MixerOrdered, _("follows order of mixer"));
2139 add_option (_("Control Surfaces"), rm);
2141 /* VIDEO Timeline */
2142 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2144 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
2145 /* Plugin options (currrently VST only) */
2146 add_option (_("Plugins"), new PluginOptions (_rc_config));
2151 add_option (S_("Preferences|GUI"),
2154 _("Graphically indicate mouse pointer hovering over various widgets"),
2155 sigc::mem_fun (*_rc_config, &RCConfiguration::get_widget_prelight),
2156 sigc::mem_fun (*_rc_config, &RCConfiguration::set_widget_prelight)
2159 add_option (S_("Preferences|GUI"),
2162 _("Show tooltips if mouse hovers over a control"),
2163 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_tooltips),
2164 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_tooltips)
2167 add_option (S_("Preferences|GUI"),
2169 "show-name-highlight",
2170 _("Use name highlight bars in region displays"),
2171 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_name_highlight),
2172 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_name_highlight)
2176 /* font scaling does nothing with GDK/Quartz */
2177 add_option (S_("Preferences|GUI"), new FontScalingOptions (_rc_config));
2180 add_option (S_("GUI"),
2182 "super-rapid-clock-update",
2183 _("update transport clock display every 40ms instead of every 100ms"),
2184 sigc::mem_fun (*_rc_config, &RCConfiguration::get_super_rapid_clock_update),
2185 sigc::mem_fun (*_rc_config, &RCConfiguration::set_super_rapid_clock_update)
2188 /* Lock GUI timeout */
2190 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
2191 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2192 _("Lock timeout (seconds)"),
2194 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_lock_gui_after_seconds),
2195 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_lock_gui_after_seconds)
2197 slts->scale().set_digits (0);
2198 Gtkmm2ext::UI::instance()->set_tip
2199 (slts->tip_widget(),
2200 _("Lock GUI after this many idle seconds (zero to never lock)"));
2201 add_option (S_("Preferences|GUI"), slts);
2203 /* The names of these controls must be the same as those given in MixerStrip
2204 for the actual widgets being controlled.
2206 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2207 _mixer_strip_visibility.add (0, X_("SoloSafe"), _("Solo Safe"));
2208 _mixer_strip_visibility.add (0, X_("SoloIsolated"), _("Solo Isolated"));
2209 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2210 _mixer_strip_visibility.add (0, X_("Group"), _("Group"));
2211 _mixer_strip_visibility.add (0, X_("MeterPoint"), _("Meter Point"));
2214 S_("Preferences|GUI"),
2215 new VisibilityOption (
2217 &_mixer_strip_visibility,
2218 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mixer_strip_visibility),
2219 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mixer_strip_visibility)
2223 add_option (S_("Preferences|GUI"),
2225 "default-narrow_ms",
2226 _("Use narrow strips in the mixer by default"),
2227 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_narrow_ms),
2228 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_narrow_ms)
2231 add_option (S_("Preferences|GUI"), new OptionEditorHeading (_("Metering")));
2233 ComboOption<float>* mht = new ComboOption<float> (
2235 _("Peak hold time"),
2236 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_hold),
2237 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_hold)
2240 mht->add (MeterHoldOff, _("off"));
2241 mht->add (MeterHoldShort, _("short"));
2242 mht->add (MeterHoldMedium, _("medium"));
2243 mht->add (MeterHoldLong, _("long"));
2245 add_option (S_("Preferences|GUI"), mht);
2247 ComboOption<float>* mfo = new ComboOption<float> (
2250 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2251 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2254 mfo->add (METER_FALLOFF_OFF, _("off"));
2255 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2256 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2257 mfo->add (METER_FALLOFF_SLOWISH, _("slowish [12.0dB/sec] (DIN)"));
2258 mfo->add (METER_FALLOFF_MODERATE, _("moderate [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2259 mfo->add (METER_FALLOFF_MEDIUM, _("medium [20dB/sec]"));
2260 mfo->add (METER_FALLOFF_FAST, _("fast [32dB/sec]"));
2261 mfo->add (METER_FALLOFF_FASTER, _("faster [46dB/sec]"));
2262 mfo->add (METER_FALLOFF_FASTEST, _("fastest [70dB/sec]"));
2264 add_option (S_("Preferences|GUI"), mfo);
2266 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2267 "meter-line-up-level",
2268 _("Meter line-up level; 0dBu"),
2269 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_line_up_level),
2270 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_line_up_level)
2273 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2274 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2275 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2276 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2278 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."));
2280 add_option (S_("Preferences|GUI"), mlu);
2282 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2283 "meter-line-up-din",
2284 _("IEC1/DIN Meter line-up level; 0dBu"),
2285 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_line_up_din),
2286 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_line_up_din)
2289 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2290 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2291 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2292 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2294 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2296 add_option (S_("Preferences|GUI"), mld);
2298 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2299 "meter-vu-standard",
2300 _("VU Meter standard"),
2301 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_vu_standard),
2302 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_vu_standard)
2305 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2306 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2307 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2308 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2310 add_option (S_("Preferences|GUI"), mvu);
2312 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
2313 HSliderOption *mpks = new HSliderOption("meter-peak",
2314 _("Peak threshold [dBFS]"),
2316 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_peak),
2317 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_peak)
2320 Gtkmm2ext::UI::instance()->set_tip
2321 (mpks->tip_widget(),
2322 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
2324 add_option (S_("Preferences|GUI"), mpks);
2326 add_option (S_("Preferences|GUI"),
2329 _("LED meter style"),
2330 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_style_led),
2331 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_style_led)
2337 RCOptionEditor::parameter_changed (string const & p)
2339 OptionEditor::parameter_changed (p);
2341 if (p == "use-monitor-bus") {
2342 bool const s = Config->get_use_monitor_bus ();
2344 /* we can't use this if we don't have a monitor bus */
2345 Config->set_solo_control_is_listen_control (false);
2347 _solo_control_is_listen_control->set_sensitive (s);
2348 _listen_position->set_sensitive (s);
2349 } else if (p == "sync-source") {
2350 _sync_source->set_sensitive (true);
2352 _sync_source->set_sensitive (!_session->config.get_external_sync());
2354 switch(Config->get_sync_source()) {
2357 _sync_genlock->set_sensitive (true);
2358 _sync_framerate->set_sensitive (true);
2359 _sync_source_2997->set_sensitive (true);
2362 _sync_genlock->set_sensitive (false);
2363 _sync_framerate->set_sensitive (false);
2364 _sync_source_2997->set_sensitive (false);
2367 } else if (p == "send-ltc") {
2368 bool const s = Config->get_send_ltc ();
2369 _ltc_send_continuously->set_sensitive (s);
2370 _ltc_volume_slider->set_sensitive (s);
2374 void RCOptionEditor::ltc_generator_volume_changed () {
2375 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
2379 RCOptionEditor::populate_sync_options ()
2381 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
2383 _sync_source->clear ();
2385 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
2386 _sync_source->add (*i, sync_source_to_string (*i));