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"
57 #include "theme_manager.h"
58 #include "ui_config.h"
63 using namespace Gtkmm2ext;
65 using namespace ARDOUR;
66 using namespace ARDOUR_UI_UTILS;
68 class ClickOptions : public OptionEditorBox
71 ClickOptions (RCConfiguration* c, Gtk::Window* p)
74 Table* t = manage (new Table (2, 3));
77 Label* l = manage (left_aligned_label (_("Click audio file:")));
78 t->attach (*l, 0, 1, 0, 1, FILL);
79 t->attach (_click_path_entry, 1, 2, 0, 1, FILL);
80 Button* b = manage (new Button (_("Browse...")));
81 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
82 t->attach (*b, 2, 3, 0, 1, FILL);
84 l = manage (left_aligned_label (_("Click emphasis audio file:")));
85 t->attach (*l, 0, 1, 1, 2, FILL);
86 t->attach (_click_emphasis_path_entry, 1, 2, 1, 2, FILL);
87 b = manage (new Button (_("Browse...")));
88 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
89 t->attach (*b, 2, 3, 1, 2, FILL);
91 _box->pack_start (*t, false, false);
93 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
94 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
97 void parameter_changed (string const & p)
99 if (p == "click-sound") {
100 _click_path_entry.set_text (_rc_config->get_click_sound());
101 } else if (p == "click-emphasis-sound") {
102 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
106 void set_state_from_config ()
108 parameter_changed ("click-sound");
109 parameter_changed ("click-emphasis-sound");
114 void click_browse_clicked ()
116 SoundFileChooser sfdb (_("Choose Click"));
118 if (sfdb.run () == RESPONSE_OK) {
119 click_chosen (sfdb.get_filename());
123 void click_chosen (string const & path)
125 _click_path_entry.set_text (path);
126 _rc_config->set_click_sound (path);
129 void click_changed ()
131 click_chosen (_click_path_entry.get_text ());
134 void click_emphasis_browse_clicked ()
136 SoundFileChooser sfdb (_("Choose Click Emphasis"));
141 if (sfdb.run () == RESPONSE_OK) {
142 click_emphasis_chosen (sfdb.get_filename());
146 void click_emphasis_chosen (string const & path)
148 _click_emphasis_path_entry.set_text (path);
149 _rc_config->set_click_emphasis_sound (path);
152 void click_emphasis_changed ()
154 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
157 RCConfiguration* _rc_config;
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 (UIConfiguration* uic) :
536 _dpi_adjustment (100, 50, 250, 1, 5),
537 _dpi_slider (_dpi_adjustment)
539 _dpi_adjustment.set_value (_ui_config->get_font_scale() / 1024.);
541 Label* l = manage (new Label (_("Font scaling:")));
542 l->set_name ("OptionsLabel");
544 const Glib::ustring dflt = _("Default");
545 const Glib::ustring empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
546 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
547 _dpi_slider.set_draw_value(false);
548 _dpi_slider.add_mark(50, Gtk::POS_TOP, empty);
549 _dpi_slider.add_mark(60, Gtk::POS_TOP, empty);
550 _dpi_slider.add_mark(70, Gtk::POS_TOP, empty);
551 _dpi_slider.add_mark(80, Gtk::POS_TOP, empty);
552 _dpi_slider.add_mark(90, Gtk::POS_TOP, empty);
553 _dpi_slider.add_mark(100, Gtk::POS_TOP, dflt);
554 _dpi_slider.add_mark(125, Gtk::POS_TOP, empty);
555 _dpi_slider.add_mark(150, Gtk::POS_TOP, empty);
556 _dpi_slider.add_mark(175, Gtk::POS_TOP, empty);
557 _dpi_slider.add_mark(200, Gtk::POS_TOP, empty);
558 _dpi_slider.add_mark(225, Gtk::POS_TOP, empty);
559 _dpi_slider.add_mark(250, Gtk::POS_TOP, empty);
561 HBox* h = manage (new HBox);
563 h->pack_start (*l, false, false);
564 h->pack_start (_dpi_slider, true, true);
566 _box->pack_start (*h, false, false);
568 set_note (_("Major font-scale changes require an application restart to re-layout."));
570 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
573 void parameter_changed (string const & p)
575 if (p == "font-scale") {
576 _dpi_adjustment.set_value (_ui_config->get_font_scale() / 1024.);
580 void set_state_from_config ()
582 parameter_changed ("font-scale");
589 _ui_config->set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024.));
590 /* XXX: should be triggered from the parameter changed signal */
594 UIConfiguration* _ui_config;
595 Adjustment _dpi_adjustment;
599 class ClipLevelOptions : public OptionEditorBox
602 ClipLevelOptions (UIConfiguration* c)
604 , _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
605 , _clip_level_slider (_clip_level_adjustment)
607 _clip_level_adjustment.set_value (_ui_config->get_waveform_clip_level ());
609 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
610 l->set_name ("OptionsLabel");
612 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
613 HBox* h = manage (new HBox);
615 h->pack_start (*l, false, false);
616 h->pack_start (_clip_level_slider, true, true);
618 _box->pack_start (*h, false, false);
620 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
623 void parameter_changed (string const & p)
625 if (p == "waveform-clip-level") {
626 _clip_level_adjustment.set_value (_ui_config->get_waveform_clip_level());
630 void set_state_from_config ()
632 parameter_changed ("waveform-clip-level");
637 void clip_level_changed ()
639 _ui_config->set_waveform_clip_level (_clip_level_adjustment.get_value());
640 /* XXX: should be triggered from the parameter changed signal */
641 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
644 UIConfiguration* _ui_config;
645 Adjustment _clip_level_adjustment;
646 HScale _clip_level_slider;
649 class BufferingOptions : public OptionEditorBox
652 BufferingOptions (RCConfiguration* c)
654 , _playback_adjustment (5, 1, 60, 1, 4)
655 , _capture_adjustment (5, 1, 60, 1, 4)
656 , _playback_slider (_playback_adjustment)
657 , _capture_slider (_capture_adjustment)
659 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
661 Label* l = manage (new Label (_("Playback (seconds of buffering):")));
662 l->set_name ("OptionsLabel");
664 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
665 HBox* h = manage (new HBox);
667 h->pack_start (*l, false, false);
668 h->pack_start (_playback_slider, true, true);
670 _box->pack_start (*h, false, false);
672 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
674 l = manage (new Label (_("Recording (seconds of buffering):")));
675 l->set_name ("OptionsLabel");
677 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
678 h = manage (new HBox);
680 h->pack_start (*l, false, false);
681 h->pack_start (_capture_slider, true, true);
683 _box->pack_start (*h, false, false);
685 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
686 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
689 void parameter_changed (string const & p)
691 if (p == "playback-buffer-seconds") {
692 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
693 } else if (p == "capture-buffer-seconds") {
694 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
698 void set_state_from_config ()
700 parameter_changed ("playback-buffer-seconds");
701 parameter_changed ("capture-buffer-seconds");
706 void playback_changed ()
708 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
711 void capture_changed ()
713 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
716 RCConfiguration* _rc_config;
717 Adjustment _playback_adjustment;
718 Adjustment _capture_adjustment;
719 HScale _playback_slider;
720 HScale _capture_slider;
723 class ControlSurfacesOptions : public OptionEditorBox
726 ControlSurfacesOptions (Gtk::Window& parent)
728 , _ignore_view_change (0)
730 _store = ListStore::create (_model);
731 _view.set_model (_store);
732 _view.append_column (_("Control Surface Protocol"), _model.name);
733 _view.get_column(0)->set_resizable (true);
734 _view.get_column(0)->set_expand (true);
735 _view.append_column_editable (_("Enabled"), _model.enabled);
736 _view.append_column_editable (_("Feedback"), _model.feedback);
738 _box->pack_start (_view, false, false);
740 Label* label = manage (new Label);
741 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
743 _box->pack_start (*label, false, false);
746 ControlProtocolManager& m = ControlProtocolManager::instance ();
747 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
748 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
750 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
751 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
754 void parameter_changed (std::string const &)
759 void set_state_from_config ()
763 ControlProtocolManager& m = ControlProtocolManager::instance ();
764 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
766 if (!(*i)->mandatory) {
767 TreeModel::Row r = *_store->append ();
768 r[_model.name] = (*i)->name;
769 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
770 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
771 r[_model.protocol_info] = *i;
778 void protocol_status_changed (ControlProtocolInfo* cpi) {
780 TreeModel::Children rows = _store->children();
782 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
783 string n = ((*x)[_model.name]);
785 if ((*x)[_model.protocol_info] == cpi) {
786 _ignore_view_change++;
787 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
788 _ignore_view_change--;
794 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
796 TreeModel::Row r = *i;
798 if (_ignore_view_change) {
802 ControlProtocolInfo* cpi = r[_model.protocol_info];
807 bool const was_enabled = (cpi->protocol != 0);
808 bool const is_enabled = r[_model.enabled];
811 if (was_enabled != is_enabled) {
814 ControlProtocolManager::instance().activate (*cpi);
816 ControlProtocolManager::instance().deactivate (*cpi);
820 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
821 bool const is_feedback = r[_model.feedback];
823 if (was_feedback != is_feedback && cpi->protocol) {
824 cpi->protocol->set_feedback (is_feedback);
828 void edit_clicked (GdkEventButton* ev)
830 if (ev->type != GDK_2BUTTON_PRESS) {
835 ControlProtocolInfo* cpi;
838 row = *(_view.get_selection()->get_selected());
839 if (!row[_model.enabled]) {
842 cpi = row[_model.protocol_info];
843 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
846 Box* box = (Box*) cpi->protocol->get_gui ();
850 if (box->get_parent()) {
851 static_cast<ArdourWindow*>(box->get_parent())->present();
854 string title = row[_model.name];
855 /* once created, the window is managed by the surface itself (as ->get_parent())
856 * Surface's tear_down_gui() is called on session close, when de-activating
857 * or re-initializing a surface.
858 * tear_down_gui() hides an deletes the Window if it exists.
860 ArdourWindow* win = new ArdourWindow (_parent, title);
861 win->set_title ("Control Protocol Options");
867 class ControlSurfacesModelColumns : public TreeModelColumnRecord
871 ControlSurfacesModelColumns ()
879 TreeModelColumn<string> name;
880 TreeModelColumn<bool> enabled;
881 TreeModelColumn<bool> feedback;
882 TreeModelColumn<ControlProtocolInfo*> protocol_info;
885 Glib::RefPtr<ListStore> _store;
886 ControlSurfacesModelColumns _model;
888 Gtk::Window& _parent;
889 PBD::ScopedConnection protocol_status_connection;
890 uint32_t _ignore_view_change;
893 class VideoTimelineOptions : public OptionEditorBox
896 VideoTimelineOptions (RCConfiguration* c)
898 , _show_video_export_info_button (_("Show Video Export Info before export"))
899 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
900 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
902 Table* t = manage (new Table (2, 6));
905 t->attach (_video_advanced_setup_button, 0, 2, 0, 1);
906 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
907 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
908 _("<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."));
910 Label* l = manage (new Label (_("Video Server URL:")));
911 l->set_alignment (0, 0.5);
912 t->attach (*l, 0, 1, 1, 2, FILL);
913 t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL);
914 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
915 _("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"));
917 l = manage (new Label (_("Video Folder:")));
918 l->set_alignment (0, 0.5);
919 t->attach (*l, 0, 1, 2, 3, FILL);
920 t->attach (_video_server_docroot_entry, 1, 2, 2, 3);
921 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
922 _("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."));
924 /* small vspace y=3..4 */
926 t->attach (_show_video_export_info_button, 0, 2, 4, 5);
927 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
928 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
929 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
931 t->attach (_show_video_server_dialog_button, 0, 2, 5, 6);
932 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
933 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
934 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
936 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
937 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
938 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
939 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
941 _box->pack_start (*t,true,true);
944 void server_url_changed ()
946 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
949 void server_docroot_changed ()
951 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
954 void show_video_export_info_toggled ()
956 bool const x = _show_video_export_info_button.get_active ();
957 _rc_config->set_show_video_export_info (x);
960 void show_video_server_dialog_toggled ()
962 bool const x = _show_video_server_dialog_button.get_active ();
963 _rc_config->set_show_video_server_dialog (x);
966 void video_advanced_setup_toggled ()
968 bool const x = _video_advanced_setup_button.get_active ();
969 _rc_config->set_video_advanced_setup(x);
972 void parameter_changed (string const & p)
974 if (p == "video-server-url") {
975 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
976 } else if (p == "video-server-docroot") {
977 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
978 } else if (p == "show-video-export-info") {
979 bool const x = _rc_config->get_show_video_export_info();
980 _show_video_export_info_button.set_active (x);
981 } else if (p == "show-video-server-dialog") {
982 bool const x = _rc_config->get_show_video_server_dialog();
983 _show_video_server_dialog_button.set_active (x);
984 } else if (p == "video-advanced-setup") {
985 bool const x = _rc_config->get_video_advanced_setup();
986 _video_advanced_setup_button.set_active(x);
987 _video_server_docroot_entry.set_sensitive(x);
988 _video_server_url_entry.set_sensitive(x);
992 void set_state_from_config ()
994 parameter_changed ("video-server-url");
995 parameter_changed ("video-server-docroot");
996 parameter_changed ("video-monitor-setup-dialog");
997 parameter_changed ("show-video-export-info");
998 parameter_changed ("show-video-server-dialog");
999 parameter_changed ("video-advanced-setup");
1003 RCConfiguration* _rc_config;
1004 Entry _video_server_url_entry;
1005 Entry _video_server_docroot_entry;
1006 CheckButton _show_video_export_info_button;
1007 CheckButton _show_video_server_dialog_button;
1008 CheckButton _video_advanced_setup_button;
1011 class PluginOptions : public OptionEditorBox
1014 PluginOptions (RCConfiguration* c, UIConfiguration* uic)
1017 , _display_plugin_scan_progress (_("Always Display Plugin Scan Progress"))
1018 , _discover_vst_on_start (_("Scan for [new] VST Plugins on Application Start"))
1019 , _discover_au_on_start (_("Scan for AudioUnit Plugins on Application Start"))
1020 , _timeout_adjustment (0, 0, 3000, 50, 50)
1021 , _timeout_slider (_timeout_adjustment)
1024 std::stringstream ss;
1025 Table* t = manage (new Table (2, 6));
1026 t->set_spacings (4);
1030 ss << "<b>" << _("General") << "</b>";
1031 l = manage (left_aligned_label (ss.str()));
1032 l->set_use_markup (true);
1033 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1034 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1036 b = manage (new Button (_("Scan for Plugins")));
1037 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1038 t->attach (*b, 0, 2, n, n+1, FILL); ++n;
1040 t->attach (_display_plugin_scan_progress, 0, 2, n, n+1); ++n;
1041 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1042 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1043 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
1045 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
1046 _timeout_slider.set_digits (0);
1047 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &PluginOptions::timeout_changed));
1049 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1050 _("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."));
1052 l = manage (left_aligned_label (_("Scan Time Out [deciseconds]")));;
1053 HBox* h = manage (new HBox);
1055 h->pack_start (*l, false, false);
1056 h->pack_start (_timeout_slider, true, true);
1057 t->attach (*h, 0, 2, n, n+1); ++n;
1060 ss << "<b>" << _("VST") << "</b>";
1061 l = manage (left_aligned_label (ss.str()));
1062 l->set_use_markup (true);
1063 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1064 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1066 b = manage (new Button (_("Clear VST Cache")));
1067 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_cache_clicked));
1068 t->attach (*b, 0, 1, n, n+1, FILL);
1070 b = manage (new Button (_("Clear VST Blacklist")));
1071 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_blacklist_clicked));
1072 t->attach (*b, 1, 2, n, n+1, FILL);
1075 t->attach (_discover_vst_on_start, 0, 2, n, n+1); ++n;
1076 _discover_vst_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_vst_on_start_toggled));
1077 Gtkmm2ext::UI::instance()->set_tip (_discover_vst_on_start,
1078 _("<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"));
1080 #ifdef LXVST_SUPPORT
1081 t->attach (*manage (left_aligned_label (_("Linux VST Path:"))), 0, 1, n, n+1);
1082 b = manage (new Button (_("Edit")));
1083 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_lxvst_path_clicked));
1084 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1087 #ifdef WINDOWS_VST_SUPPORT
1088 t->attach (*manage (left_aligned_label (_("Windows VST Path:"))), 0, 1, n, n+1);
1089 b = manage (new Button (_("Edit")));
1090 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_vst_path_clicked));
1091 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1095 #ifdef AUDIOUNIT_SUPPORT
1096 t->attach (_discover_au_on_start, 0, 2, n, n+1); ++n;
1097 _discover_au_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_au_on_start_toggled));
1098 Gtkmm2ext::UI::instance()->set_tip (_discover_au_on_start,
1099 _("<b>When enabled</b> 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."));
1102 _box->pack_start (*t,true,true);
1105 void parameter_changed (string const & p) {
1106 if (p == "show-plugin-scan-window") {
1107 bool const x = _ui_config->get_show_plugin_scan_window();
1108 _display_plugin_scan_progress.set_active (x);
1110 else if (p == "discover-vst-on-start") {
1111 bool const x = _rc_config->get_discover_vst_on_start();
1112 _discover_vst_on_start.set_active (x);
1114 else if (p == "vst-scan-timeout") {
1115 int const x = _rc_config->get_vst_scan_timeout();
1116 _timeout_adjustment.set_value (x);
1118 else if (p == "discover-audio-units") {
1119 bool const x = _rc_config->get_discover_audio_units();
1120 _discover_au_on_start.set_active (x);
1124 void set_state_from_config () {
1125 parameter_changed ("show-plugin-scan-window");
1126 parameter_changed ("discover-vst-on-start");
1127 parameter_changed ("vst-scan-timeout");
1128 parameter_changed ("discover-audio-units");
1132 RCConfiguration* _rc_config;
1133 UIConfiguration* _ui_config;
1134 CheckButton _display_plugin_scan_progress;
1135 CheckButton _discover_vst_on_start;
1136 CheckButton _discover_au_on_start;
1137 Adjustment _timeout_adjustment;
1138 HScale _timeout_slider;
1140 void display_plugin_scan_progress_toggled () {
1141 bool const x = _display_plugin_scan_progress.get_active();
1142 _ui_config->set_show_plugin_scan_window(x);
1145 void discover_vst_on_start_toggled () {
1146 bool const x = _discover_vst_on_start.get_active();
1147 _rc_config->set_discover_vst_on_start(x);
1150 void discover_au_on_start_toggled () {
1151 bool const x = _discover_au_on_start.get_active();
1152 _rc_config->set_discover_audio_units(x);
1155 void timeout_changed () {
1156 int x = floor(_timeout_adjustment.get_value());
1157 _rc_config->set_vst_scan_timeout(x);
1160 void clear_vst_cache_clicked () {
1161 PluginManager::instance().clear_vst_cache();
1164 void clear_vst_blacklist_clicked () {
1165 PluginManager::instance().clear_vst_blacklist();
1168 void edit_vst_path_clicked () {
1169 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1170 _("Set Windows VST Search Path"),
1171 _rc_config->get_plugin_path_vst(),
1172 PluginManager::instance().get_default_windows_vst_path()
1174 ResponseType r = (ResponseType) pd->run ();
1176 if (r == RESPONSE_ACCEPT) {
1177 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
1182 // todo consolidate with edit_vst_path_clicked..
1183 void edit_lxvst_path_clicked () {
1184 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1185 _("Set Linux VST Search Path"),
1186 _rc_config->get_plugin_path_lxvst(),
1187 PluginManager::instance().get_default_lxvst_path()
1189 ResponseType r = (ResponseType) pd->run ();
1191 if (r == RESPONSE_ACCEPT) {
1192 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
1197 void refresh_clicked () {
1198 PluginManager::instance().refresh();
1203 /** A class which allows control of visibility of some editor components usign
1204 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1205 * which has the correct members, but with null widget pointers. This
1206 * class allows the user to set visibility of the members, the details
1207 * of which are stored in a configuration variable which can be watched
1208 * by parts of the editor that actually contain the widgets whose visibility
1209 * is being controlled.
1212 class VisibilityOption : public Option
1215 /** @param name User-visible name for this group.
1216 * @param g `Dummy' VisibilityGroup (as described above).
1217 * @param get Method to get the value of the appropriate configuration variable.
1218 * @param set Method to set the value of the appropriate configuration variable.
1220 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1221 : Option (g->get_state_name(), name)
1223 , _visibility_group (g)
1227 /* Watch for changes made by the user to our members */
1228 _visibility_group->VisibilityChanged.connect_same_thread (
1229 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1233 void set_state_from_config ()
1235 /* Set our state from the current configuration */
1236 _visibility_group->set_state (_get ());
1239 void add_to_page (OptionEditorPage* p)
1241 _heading.add_to_page (p);
1242 add_widget_to_page (p, _visibility_group->list_view ());
1245 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1250 /* The user has changed something, so reflect this change
1251 in the RCConfiguration.
1253 _set (_visibility_group->get_state_value ());
1256 OptionEditorHeading _heading;
1257 VisibilityGroup* _visibility_group;
1258 sigc::slot<std::string> _get;
1259 sigc::slot<bool, std::string> _set;
1260 PBD::ScopedConnection _visibility_group_connection;
1265 RCOptionEditor::RCOptionEditor ()
1266 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1267 , _rc_config (Config)
1268 , _ui_config (ARDOUR_UI::config())
1269 , _mixer_strip_visibility ("mixer-element-visibility")
1273 uint32_t hwcpus = hardware_concurrency ();
1275 BoolComboOption* bco;
1278 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1280 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1282 _("Signal processing uses"),
1283 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1284 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1287 procs->add (-1, _("all but one processor"));
1288 procs->add (0, _("all available processors"));
1290 for (uint32_t i = 1; i <= hwcpus; ++i) {
1291 procs->add (i, string_compose (_("%1 processors"), i));
1294 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1296 add_option (_("Misc"), procs);
1299 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1301 add_option (_("Misc"), new UndoOptions (_rc_config));
1303 add_option (_("Misc"),
1305 "verify-remove-last-capture",
1306 _("Verify removal of last capture"),
1307 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1308 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1311 add_option (_("Misc"),
1313 "periodic-safety-backups",
1314 _("Make periodic backups of the session file"),
1315 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1316 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1319 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1321 add_option (_("Misc"),
1323 "only-copy-imported-files",
1324 _("Always copy imported files"),
1325 sigc::mem_fun (*_ui_config, &UIConfiguration::get_only_copy_imported_files),
1326 sigc::mem_fun (*_ui_config, &UIConfiguration::set_only_copy_imported_files)
1329 add_option (_("Misc"), new DirectoryOption (
1330 X_("default-session-parent-dir"),
1331 _("Default folder for new sessions:"),
1332 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1333 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1336 add_option (_("Misc"),
1337 new SpinOption<uint32_t> (
1338 "max-recent-sessions",
1339 _("Maximum number of recent sessions"),
1340 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1341 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1345 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1347 add_option (_("Misc"), new ClickOptions (_rc_config, this));
1349 add_option (_("Misc"),
1352 _("Click gain level"),
1353 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1354 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1357 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1359 add_option (_("Misc"),
1360 new SpinOption<double> (
1361 "automation-thinning-factor",
1362 _("Thinning factor (larger value => less data)"),
1363 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1364 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1368 add_option (_("Misc"),
1369 new SpinOption<double> (
1370 "automation-interval-msecs",
1371 _("Automation sampling interval (milliseconds)"),
1372 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1373 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1381 tsf = new BoolOption (
1382 "latched-record-enable",
1383 _("Keep record-enable engaged on stop"),
1384 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1385 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1387 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1388 add_option (_("Transport"), tsf);
1390 tsf = new BoolOption (
1391 "stop-recording-on-xrun",
1392 _("Stop recording when an xrun occurs"),
1393 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1394 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1396 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1397 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
1399 add_option (_("Transport"), tsf);
1401 tsf = new BoolOption (
1403 _("Play loop is a transport mode"),
1404 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1405 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1407 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1408 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1409 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1410 add_option (_("Transport"), tsf);
1412 tsf = new BoolOption (
1413 "create-xrun-marker",
1414 _("Create markers where xruns occur"),
1415 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
1416 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
1418 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1419 add_option (_("Transport"), tsf);
1421 tsf = new BoolOption (
1422 "stop-at-session-end",
1423 _("Stop at the end of the session"),
1424 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
1425 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
1427 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1428 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
1429 "when it reaches the current session end marker\n\n"
1430 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
1432 add_option (_("Transport"), tsf);
1434 tsf = new BoolOption (
1436 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
1437 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
1438 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
1440 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1441 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
1442 "preventing any need to do a transport locate at the end of the loop\n\n"
1443 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
1444 "which will often cause a small click or delay"), PROGRAM_NAME));
1445 add_option (_("Transport"), tsf);
1447 tsf = new BoolOption (
1448 "disable-disarm-during-roll",
1449 _("Disable per-track record disarm while rolling"),
1450 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
1451 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
1453 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"));
1454 add_option (_("Transport"), tsf);
1456 tsf = new BoolOption (
1458 _("12dB gain reduction during fast-forward and fast-rewind"),
1459 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
1460 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
1462 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
1463 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
1464 add_option (_("Transport"), tsf);
1466 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
1468 _sync_source = new ComboOption<SyncSource> (
1470 _("External timecode source"),
1471 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
1472 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
1475 populate_sync_options ();
1476 add_option (_("Transport"), _sync_source);
1478 _sync_framerate = new BoolOption (
1479 "timecode-sync-frame-rate",
1480 _("Match session video frame rate to external timecode"),
1481 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
1482 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
1484 Gtkmm2ext::UI::instance()->set_tip
1485 (_sync_framerate->tip_widget(),
1486 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
1487 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
1488 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
1489 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
1490 "timecode standard and the session standard."), PROGRAM_NAME));
1492 add_option (_("Transport"), _sync_framerate);
1494 _sync_genlock = new BoolOption (
1495 "timecode-source-is-synced",
1496 _("External timecode is sync locked"),
1497 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
1498 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
1500 Gtkmm2ext::UI::instance()->set_tip
1501 (_sync_genlock->tip_widget(),
1502 _("<b>When enabled</b> indicates that the selected external timecode source shares sync (Black & Burst, Wordclock, etc) with the audio interface."));
1505 add_option (_("Transport"), _sync_genlock);
1507 _sync_source_2997 = new BoolOption (
1508 "timecode-source-2997",
1509 _("Lock to 29.9700 fps instead of 30000/1001"),
1510 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
1511 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
1513 Gtkmm2ext::UI::instance()->set_tip
1514 (_sync_source_2997->tip_widget(),
1515 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
1516 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
1517 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
1518 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
1519 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
1520 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
1523 add_option (_("Transport"), _sync_source_2997);
1525 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
1527 _ltc_port = new ComboStringOption (
1529 _("LTC incoming port"),
1530 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
1531 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
1534 vector<string> physical_inputs;
1535 physical_inputs.push_back (_("None"));
1536 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
1537 _ltc_port->set_popdown_strings (physical_inputs);
1539 add_option (_("Transport"), _ltc_port);
1541 // TODO; rather disable this button than not compile it..
1542 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
1544 add_option (_("Transport"),
1547 _("Enable LTC generator"),
1548 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
1549 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
1552 _ltc_send_continuously = new BoolOption (
1553 "ltc-send-continuously",
1554 _("Send LTC while stopped"),
1555 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
1556 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
1558 Gtkmm2ext::UI::instance()->set_tip
1559 (_ltc_send_continuously->tip_widget(),
1560 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
1561 add_option (_("Transport"), _ltc_send_continuously);
1563 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
1564 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
1565 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
1566 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
1568 Gtkmm2ext::UI::instance()->set_tip
1569 (_ltc_volume_slider->tip_widget(),
1570 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
1572 add_option (_("Transport"), _ltc_volume_slider);
1573 parameter_changed ("send-ltc");
1575 parameter_changed ("sync-source");
1579 add_option (S_("Editor"),
1581 "draggable-playhead",
1582 _("Allow dragging of playhead"),
1583 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_draggable_playhead),
1584 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_draggable_playhead)
1587 add_option (_("Editor"),
1589 "automation-follows-regions",
1590 _("Move relevant automation when audio regions are moved"),
1591 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
1592 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
1595 add_option (_("Editor"),
1597 "show-track-meters",
1598 _("Show meters on tracks in the editor"),
1599 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_track_meters),
1600 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_track_meters)
1603 add_option (_("Editor"),
1605 "show-editor-meter",
1606 _("Display master-meter in the toolbar"),
1607 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_editor_meter),
1608 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_editor_meter)
1611 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
1612 "default-fade-shape",
1613 _("Default fade shape"),
1614 sigc::mem_fun (*_rc_config,
1615 &RCConfiguration::get_default_fade_shape),
1616 sigc::mem_fun (*_rc_config,
1617 &RCConfiguration::set_default_fade_shape)
1620 fadeshape->add (FadeLinear,
1621 _("Linear (for highly correlated material)"));
1622 fadeshape->add (FadeConstantPower, _("Constant power"));
1623 fadeshape->add (FadeSymmetric, _("Symmetric"));
1624 fadeshape->add (FadeSlow, _("Slow"));
1625 fadeshape->add (FadeFast, _("Fast"));
1627 add_option (_("Editor"), fadeshape);
1630 bco = new BoolComboOption (
1631 "use-overlap-equivalency",
1632 _("Regions in active edit groups are edited together"),
1633 _("whenever they overlap in time"),
1634 _("only if they have identical length, position and origin"),
1635 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
1636 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
1639 add_option (_("Editor"), bco);
1641 add_option (_("Editor"),
1643 "rubberbanding-snaps-to-grid",
1644 _("Make rubberband selection rectangle snap to the grid"),
1645 sigc::mem_fun (*_ui_config, &UIConfiguration::get_rubberbanding_snaps_to_grid),
1646 sigc::mem_fun (*_ui_config, &UIConfiguration::set_rubberbanding_snaps_to_grid)
1649 add_option (_("Editor"),
1652 _("Show waveforms in regions"),
1653 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms),
1654 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms)
1657 add_option (_("Editor"),
1658 new BoolComboOption (
1659 "show-region-gain-envelopes",
1660 _("Show gain envelopes in audio regions"),
1662 _("only in region gain mode"),
1663 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_region_gain),
1664 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_region_gain)
1667 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
1669 _("Waveform scale"),
1670 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_scale),
1671 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_scale)
1674 wfs->add (Linear, _("linear"));
1675 wfs->add (Logarithmic, _("logarithmic"));
1677 add_option (_("Editor"), wfs);
1679 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
1681 _("Waveform shape"),
1682 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_shape),
1683 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_shape)
1686 wfsh->add (Traditional, _("traditional"));
1687 wfsh->add (Rectified, _("rectified"));
1689 add_option (_("Editor"), wfsh);
1691 add_option (_("Editor"), new ClipLevelOptions (_ui_config));
1693 add_option (_("Editor"),
1695 "show-waveforms-while-recording",
1696 _("Show waveforms for audio while it is being recorded"),
1697 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms_while_recording),
1698 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms_while_recording)
1701 add_option (_("Editor"),
1704 _("Show zoom toolbar"),
1705 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_zoom_tools),
1706 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_zoom_tools)
1709 add_option (_("Editor"),
1711 "update-editor-during-summary-drag",
1712 _("Update editor window during drags of the summary"),
1713 sigc::mem_fun (*_ui_config, &UIConfiguration::get_update_editor_during_summary_drag),
1714 sigc::mem_fun (*_ui_config, &UIConfiguration::set_update_editor_during_summary_drag)
1717 add_option (_("Editor"),
1719 "link-editor-and-mixer-selection",
1720 _("Synchronise editor and mixer selection"),
1721 sigc::mem_fun (*_ui_config, &UIConfiguration::get_link_editor_and_mixer_selection),
1722 sigc::mem_fun (*_ui_config, &UIConfiguration::set_link_editor_and_mixer_selection)
1725 bo = new BoolOption (
1727 _("Name new markers"),
1728 sigc::mem_fun (*_ui_config, &UIConfiguration::get_name_new_markers),
1729 sigc::mem_fun (*_ui_config, &UIConfiguration::set_name_new_markers)
1732 add_option (_("Editor"), bo);
1733 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."
1734 "\n\nYou can always rename markers by right-clicking on them"));
1736 add_option (_("Editor"),
1738 "autoscroll-editor",
1739 _("Auto-scroll editor window when dragging near its edges"),
1740 sigc::mem_fun (*_ui_config, &UIConfiguration::get_autoscroll_editor),
1741 sigc::mem_fun (*_ui_config, &UIConfiguration::set_autoscroll_editor)
1744 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
1745 "region-selection-after-split",
1746 _("After splitting selected regions, select"),
1747 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
1748 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
1750 // TODO: decide which of these modes are really useful
1751 rsas->add(None, _("no regions"));
1752 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
1753 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
1754 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
1755 // rsas->add(Existing, _("unmodified regions in the existing selection"));
1756 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
1757 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
1758 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
1760 add_option (_("Editor"), rsas);
1765 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
1767 add_option (_("Audio"), new BufferingOptions (_rc_config));
1769 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
1771 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
1773 _("Record monitoring handled by"),
1774 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
1775 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
1778 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
1779 mm->add (HardwareMonitoring, _("via Audio Driver"));
1782 string prog (PROGRAM_NAME);
1783 boost::algorithm::to_lower (prog);
1784 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
1785 mm->add (ExternalMonitoring, _("audio hardware"));
1787 add_option (_("Audio"), mm);
1789 add_option (_("Audio"),
1791 "tape-machine-mode",
1792 _("Tape machine mode"),
1793 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
1794 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
1797 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
1799 add_option (_("Audio"),
1801 "auto-connect-standard-busses",
1802 _("Auto-connect master/monitor busses"),
1803 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
1804 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
1807 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
1808 "input-auto-connect",
1809 _("Connect track inputs"),
1810 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
1811 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
1814 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
1815 iac->add (ManualConnect, _("manually"));
1817 add_option (_("Audio"), iac);
1819 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
1820 "output-auto-connect",
1821 _("Connect track and bus outputs"),
1822 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
1823 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
1826 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
1827 oac->add (AutoConnectMaster, _("automatically to master bus"));
1828 oac->add (ManualConnect, _("manually"));
1830 add_option (_("Audio"), oac);
1832 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
1834 add_option (_("Audio"),
1836 "denormal-protection",
1837 _("Use DC bias to protect against denormals"),
1838 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
1839 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
1842 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
1844 _("Processor handling"),
1845 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
1846 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
1849 dm->add (DenormalNone, _("no processor handling"));
1853 if (fpu.has_flush_to_zero()) {
1854 dm->add (DenormalFTZ, _("use FlushToZero"));
1857 if (fpu.has_denormals_are_zero()) {
1858 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
1861 if (fpu.has_flush_to_zero() && fpu.has_denormals_are_zero()) {
1862 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
1865 add_option (_("Audio"), dm);
1867 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
1869 add_option (_("Audio"),
1871 "plugins-stop-with-transport",
1872 _("Silence plugins when the transport is stopped"),
1873 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
1874 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
1877 add_option (_("Audio"),
1879 "new-plugins-active",
1880 _("Make new plugins active"),
1881 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
1882 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
1885 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
1887 add_option (_("Audio"),
1889 "auto-analyse-audio",
1890 _("Enable automatic analysis of audio"),
1891 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
1892 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
1895 add_option (_("Audio"),
1897 "replicate-missing-region-channels",
1898 _("Replicate missing region channels"),
1899 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
1900 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
1905 add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
1907 add_option (_("Solo / mute"),
1910 _("Solo-in-place mute cut (dB)"),
1911 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
1912 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
1915 _solo_control_is_listen_control = new BoolOption (
1916 "solo-control-is-listen-control",
1917 _("Solo controls are Listen controls"),
1918 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
1919 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
1922 add_option (_("Solo / mute"), _solo_control_is_listen_control);
1924 _listen_position = new ComboOption<ListenPosition> (
1926 _("Listen Position"),
1927 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
1928 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
1931 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
1932 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
1934 add_option (_("Solo / mute"), _listen_position);
1936 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
1938 _("PFL signals come from"),
1939 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
1940 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
1943 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
1944 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
1946 add_option (_("Solo / mute"), pp);
1948 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
1950 _("AFL signals come from"),
1951 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
1952 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
1955 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
1956 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
1958 add_option (_("Solo / mute"), pa);
1960 parameter_changed ("use-monitor-bus");
1962 add_option (_("Solo / mute"),
1965 _("Exclusive solo"),
1966 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
1967 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
1970 add_option (_("Solo / mute"),
1973 _("Show solo muting"),
1974 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
1975 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
1978 add_option (_("Solo / mute"),
1980 "solo-mute-override",
1981 _("Soloing overrides muting"),
1982 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
1983 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
1986 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
1988 add_option (_("Solo / mute"),
1990 "mute-affects-pre-fader",
1991 _("Mute affects pre-fader sends"),
1992 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
1993 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
1996 add_option (_("Solo / mute"),
1998 "mute-affects-post-fader",
1999 _("Mute affects post-fader sends"),
2000 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2001 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2004 add_option (_("Solo / mute"),
2006 "mute-affects-control-outs",
2007 _("Mute affects control outputs"),
2008 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2009 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2012 add_option (_("Solo / mute"),
2014 "mute-affects-main-outs",
2015 _("Mute affects main outputs"),
2016 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2017 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2020 add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
2022 add_option (_("Solo / mute"),
2024 "link-send-and-route-panner",
2025 _("Link panners of Aux and External Sends with main panner by default"),
2026 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2027 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2030 add_option (_("MIDI"),
2033 _("Send MIDI Clock"),
2034 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2035 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2038 add_option (_("MIDI"),
2041 _("Send MIDI Time Code"),
2042 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2043 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2046 add_option (_("MIDI"),
2047 new SpinOption<int> (
2048 "mtc-qf-speed-tolerance",
2049 _("Percentage either side of normal transport speed to transmit MTC"),
2050 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2051 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2055 add_option (_("MIDI"),
2058 _("Obey MIDI Machine Control commands"),
2059 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2060 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2063 add_option (_("MIDI"),
2066 _("Send MIDI Machine Control commands"),
2067 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2068 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2071 add_option (_("MIDI"),
2074 _("Send MIDI control feedback"),
2075 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2076 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2079 add_option (_("MIDI"),
2080 new SpinOption<uint8_t> (
2081 "mmc-receive-device-id",
2082 _("Inbound MMC device ID"),
2083 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2084 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2088 add_option (_("MIDI"),
2089 new SpinOption<uint8_t> (
2090 "mmc-send-device-id",
2091 _("Outbound MMC device ID"),
2092 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2093 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2097 add_option (_("MIDI"),
2098 new SpinOption<int32_t> (
2099 "initial-program-change",
2100 _("Initial program change"),
2101 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2102 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2106 add_option (_("MIDI"),
2108 "display-first-midi-bank-as-zero",
2109 _("Display first MIDI bank/program as 0"),
2110 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2111 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2114 add_option (_("MIDI"),
2116 "never-display-periodic-midi",
2117 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2118 sigc::mem_fun (*_ui_config, &UIConfiguration::get_never_display_periodic_midi),
2119 sigc::mem_fun (*_ui_config, &UIConfiguration::set_never_display_periodic_midi)
2122 add_option (_("MIDI"),
2125 _("Sound MIDI notes as they are selected"),
2126 sigc::mem_fun (*_ui_config, &UIConfiguration::get_sound_midi_notes),
2127 sigc::mem_fun (*_ui_config, &UIConfiguration::set_sound_midi_notes)
2130 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2132 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2133 "midi-audition-synth-uri",
2134 _("Midi Audition Synth (LV2)"),
2135 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2136 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2139 audition_synth->add(X_(""), _("None"));
2140 PluginInfoList all_plugs;
2141 PluginManager& manager (PluginManager::instance());
2143 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2145 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2146 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2147 if (!(*i)->is_instrument()) continue;
2148 if ((*i)->type != ARDOUR::LV2) continue;
2149 audition_synth->add((*i)->unique_id, (*i)->name);
2153 add_option (_("MIDI"), audition_synth);
2155 /* USER INTERACTION */
2157 if (getenv ("ARDOUR_BUNDLED")) {
2158 add_option (_("User interaction"),
2160 "enable-translation",
2161 string_compose (_("Use translations of %1 messages\n"
2162 " <i>(requires a restart of %1 to take effect)</i>\n"
2163 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2164 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2165 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2168 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2170 add_option (_("User interaction"), new KeyboardOptions);
2172 /* Control Surfaces */
2174 add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
2176 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2178 _("Control surface remote ID"),
2179 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2180 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2183 rm->add (UserOrdered, _("assigned by user"));
2184 rm->add (MixerOrdered, _("follows order of mixer"));
2186 add_option (_("Control Surfaces"), rm);
2188 /* VIDEO Timeline */
2189 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2191 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2192 /* Plugin options (currrently VST only) */
2193 add_option (_("Plugins"), new PluginOptions (_rc_config, _ui_config));
2198 add_option (S_("Preferences|GUI"),
2201 _("Graphically indicate mouse pointer hovering over various widgets"),
2202 sigc::mem_fun (*_ui_config, &UIConfiguration::get_widget_prelight),
2203 sigc::mem_fun (*_ui_config, &UIConfiguration::set_widget_prelight)
2206 add_option (S_("Preferences|GUI"),
2209 _("Show tooltips if mouse hovers over a control"),
2210 sigc::mem_fun (*_ui_config, &UIConfiguration::get_use_tooltips),
2211 sigc::mem_fun (*_ui_config, &UIConfiguration::set_use_tooltips)
2214 add_option (S_("Preferences|GUI"),
2216 "show-name-highlight",
2217 _("Use name highlight bars in region displays"),
2218 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_name_highlight),
2219 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_name_highlight)
2223 /* font scaling does nothing with GDK/Quartz */
2224 add_option (S_("Preferences|GUI"), new FontScalingOptions (_ui_config));
2227 add_option (S_("GUI"),
2229 "super-rapid-clock-update",
2230 _("update transport clock display at FPS instead of every 100ms"),
2231 sigc::mem_fun (*_ui_config, &UIConfiguration::get_super_rapid_clock_update),
2232 sigc::mem_fun (*_ui_config, &UIConfiguration::set_super_rapid_clock_update)
2235 /* Lock GUI timeout */
2237 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
2238 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2239 _("Lock timeout (seconds)"),
2241 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_lock_gui_after_seconds),
2242 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_lock_gui_after_seconds)
2244 slts->scale().set_digits (0);
2245 Gtkmm2ext::UI::instance()->set_tip
2246 (slts->tip_widget(),
2247 _("Lock GUI after this many idle seconds (zero to never lock)"));
2248 add_option (S_("Preferences|GUI"), slts);
2250 /* The names of these controls must be the same as those given in MixerStrip
2251 for the actual widgets being controlled.
2253 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
2254 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2255 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
2256 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
2257 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
2258 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2261 S_("Preferences|GUI"),
2262 new VisibilityOption (
2264 &_mixer_strip_visibility,
2265 sigc::mem_fun (*_ui_config, &UIConfiguration::get_mixer_strip_visibility),
2266 sigc::mem_fun (*_ui_config, &UIConfiguration::set_mixer_strip_visibility)
2270 add_option (S_("Preferences|GUI"),
2272 "default-narrow_ms",
2273 _("Use narrow strips in the mixer by default"),
2274 sigc::mem_fun (*_ui_config, &UIConfiguration::get_default_narrow_ms),
2275 sigc::mem_fun (*_ui_config, &UIConfiguration::set_default_narrow_ms)
2278 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2280 ComboOption<float>* mht = new ComboOption<float> (
2282 _("Peak hold time"),
2283 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_hold),
2284 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_hold)
2287 mht->add (MeterHoldOff, _("off"));
2288 mht->add (MeterHoldShort, _("short"));
2289 mht->add (MeterHoldMedium, _("medium"));
2290 mht->add (MeterHoldLong, _("long"));
2292 add_option (S_("Preferences|Metering"), mht);
2294 ComboOption<float>* mfo = new ComboOption<float> (
2297 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2298 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2301 mfo->add (METER_FALLOFF_OFF, _("off"));
2302 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2303 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2304 mfo->add (METER_FALLOFF_SLOWISH, _("slowish [12.0dB/sec] (DIN)"));
2305 mfo->add (METER_FALLOFF_MODERATE, _("moderate [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2306 mfo->add (METER_FALLOFF_MEDIUM, _("medium [20dB/sec]"));
2307 mfo->add (METER_FALLOFF_FAST, _("fast [32dB/sec]"));
2308 mfo->add (METER_FALLOFF_FASTER, _("faster [46dB/sec]"));
2309 mfo->add (METER_FALLOFF_FASTEST, _("fastest [70dB/sec]"));
2311 add_option (S_("Preferences|Metering"), mfo);
2313 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2314 "meter-line-up-level",
2315 _("Meter line-up level; 0dBu"),
2316 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_level),
2317 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_level)
2320 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2321 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2322 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2323 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2325 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."));
2327 add_option (S_("Preferences|Metering"), mlu);
2329 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2330 "meter-line-up-din",
2331 _("IEC1/DIN Meter line-up level; 0dBu"),
2332 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_din),
2333 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_din)
2336 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2337 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2338 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2339 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2341 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2343 add_option (S_("Preferences|Metering"), mld);
2345 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2346 "meter-vu-standard",
2347 _("VU Meter standard"),
2348 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_vu_standard),
2349 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_vu_standard)
2352 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2353 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2354 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2355 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2357 add_option (S_("Preferences|Metering"), mvu);
2359 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
2360 HSliderOption *mpks = new HSliderOption("meter-peak",
2361 _("Peak threshold [dBFS]"),
2363 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_peak),
2364 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_peak)
2367 Gtkmm2ext::UI::instance()->set_tip
2368 (mpks->tip_widget(),
2369 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
2371 add_option (S_("Preferences|Metering"), mpks);
2373 add_option (S_("Preferences|Metering"),
2376 _("LED meter style"),
2377 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_style_led),
2378 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_style_led)
2381 /* and now the theme manager */
2383 ThemeManager* tm = manage (new ThemeManager);
2384 add_page (_("Theme"), *tm);
2388 RCOptionEditor::parameter_changed (string const & p)
2390 OptionEditor::parameter_changed (p);
2392 if (p == "use-monitor-bus") {
2393 bool const s = Config->get_use_monitor_bus ();
2395 /* we can't use this if we don't have a monitor bus */
2396 Config->set_solo_control_is_listen_control (false);
2398 _solo_control_is_listen_control->set_sensitive (s);
2399 _listen_position->set_sensitive (s);
2400 } else if (p == "sync-source") {
2401 _sync_source->set_sensitive (true);
2403 _sync_source->set_sensitive (!_session->config.get_external_sync());
2405 switch(Config->get_sync_source()) {
2408 _sync_genlock->set_sensitive (true);
2409 _sync_framerate->set_sensitive (true);
2410 _sync_source_2997->set_sensitive (true);
2413 _sync_genlock->set_sensitive (false);
2414 _sync_framerate->set_sensitive (false);
2415 _sync_source_2997->set_sensitive (false);
2418 } else if (p == "send-ltc") {
2419 bool const s = Config->get_send_ltc ();
2420 _ltc_send_continuously->set_sensitive (s);
2421 _ltc_volume_slider->set_sensitive (s);
2425 void RCOptionEditor::ltc_generator_volume_changed () {
2426 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
2430 RCOptionEditor::populate_sync_options ()
2432 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
2434 _sync_source->clear ();
2436 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
2437 _sync_source->add (*i, sync_source_to_string (*i));