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 (50, 50, 250, 1, 10),
537 _dpi_slider (_dpi_adjustment)
539 _dpi_adjustment.set_value (floor ((double)(uic->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 set_note (_("Major font-scale changes require an application restart to re-layout."));
554 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
557 void parameter_changed (string const & p)
559 if (p == "font-scale") {
560 _dpi_adjustment.set_value (floor ((double)(_ui_config->get_font_scale() / 1024)));
564 void set_state_from_config ()
566 parameter_changed ("font-scale");
573 _ui_config->set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024));
574 /* XXX: should be triggered from the parameter changed signal */
578 UIConfiguration* _ui_config;
579 Adjustment _dpi_adjustment;
583 class ClipLevelOptions : public OptionEditorBox
586 ClipLevelOptions (UIConfiguration* c)
588 , _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
589 , _clip_level_slider (_clip_level_adjustment)
591 _clip_level_adjustment.set_value (_ui_config->get_waveform_clip_level ());
593 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
594 l->set_name ("OptionsLabel");
596 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
597 HBox* h = manage (new HBox);
599 h->pack_start (*l, false, false);
600 h->pack_start (_clip_level_slider, true, true);
602 _box->pack_start (*h, false, false);
604 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
607 void parameter_changed (string const & p)
609 if (p == "waveform-clip-level") {
610 _clip_level_adjustment.set_value (_ui_config->get_waveform_clip_level());
614 void set_state_from_config ()
616 parameter_changed ("waveform-clip-level");
621 void clip_level_changed ()
623 _ui_config->set_waveform_clip_level (_clip_level_adjustment.get_value());
624 /* XXX: should be triggered from the parameter changed signal */
625 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
628 UIConfiguration* _ui_config;
629 Adjustment _clip_level_adjustment;
630 HScale _clip_level_slider;
633 class BufferingOptions : public OptionEditorBox
636 BufferingOptions (RCConfiguration* c)
638 , _playback_adjustment (5, 1, 60, 1, 4)
639 , _capture_adjustment (5, 1, 60, 1, 4)
640 , _playback_slider (_playback_adjustment)
641 , _capture_slider (_capture_adjustment)
643 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
645 Label* l = manage (new Label (_("Playback (seconds of buffering):")));
646 l->set_name ("OptionsLabel");
648 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
649 HBox* h = manage (new HBox);
651 h->pack_start (*l, false, false);
652 h->pack_start (_playback_slider, true, true);
654 _box->pack_start (*h, false, false);
656 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
658 l = manage (new Label (_("Recording (seconds of buffering):")));
659 l->set_name ("OptionsLabel");
661 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
662 h = manage (new HBox);
664 h->pack_start (*l, false, false);
665 h->pack_start (_capture_slider, true, true);
667 _box->pack_start (*h, false, false);
669 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
670 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
673 void parameter_changed (string const & p)
675 if (p == "playback-buffer-seconds") {
676 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
677 } else if (p == "capture-buffer-seconds") {
678 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
682 void set_state_from_config ()
684 parameter_changed ("playback-buffer-seconds");
685 parameter_changed ("capture-buffer-seconds");
690 void playback_changed ()
692 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
695 void capture_changed ()
697 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
700 RCConfiguration* _rc_config;
701 Adjustment _playback_adjustment;
702 Adjustment _capture_adjustment;
703 HScale _playback_slider;
704 HScale _capture_slider;
707 class ControlSurfacesOptions : public OptionEditorBox
710 ControlSurfacesOptions (Gtk::Window& parent)
712 , _ignore_view_change (0)
714 _store = ListStore::create (_model);
715 _view.set_model (_store);
716 _view.append_column (_("Control Surface Protocol"), _model.name);
717 _view.get_column(0)->set_resizable (true);
718 _view.get_column(0)->set_expand (true);
719 _view.append_column_editable (_("Enabled"), _model.enabled);
720 _view.append_column_editable (_("Feedback"), _model.feedback);
722 _box->pack_start (_view, false, false);
724 Label* label = manage (new Label);
725 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
727 _box->pack_start (*label, false, false);
730 ControlProtocolManager& m = ControlProtocolManager::instance ();
731 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
732 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
734 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
735 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
738 void parameter_changed (std::string const &)
743 void set_state_from_config ()
747 ControlProtocolManager& m = ControlProtocolManager::instance ();
748 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
750 if (!(*i)->mandatory) {
751 TreeModel::Row r = *_store->append ();
752 r[_model.name] = (*i)->name;
753 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
754 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
755 r[_model.protocol_info] = *i;
762 void protocol_status_changed (ControlProtocolInfo* cpi) {
764 TreeModel::Children rows = _store->children();
766 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
767 string n = ((*x)[_model.name]);
769 if ((*x)[_model.protocol_info] == cpi) {
770 _ignore_view_change++;
771 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
772 _ignore_view_change--;
778 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
780 TreeModel::Row r = *i;
782 if (_ignore_view_change) {
786 ControlProtocolInfo* cpi = r[_model.protocol_info];
791 bool const was_enabled = (cpi->protocol != 0);
792 bool const is_enabled = r[_model.enabled];
795 if (was_enabled != is_enabled) {
798 ControlProtocolManager::instance().activate (*cpi);
800 ControlProtocolManager::instance().deactivate (*cpi);
804 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
805 bool const is_feedback = r[_model.feedback];
807 if (was_feedback != is_feedback && cpi->protocol) {
808 cpi->protocol->set_feedback (is_feedback);
812 void edit_clicked (GdkEventButton* ev)
814 if (ev->type != GDK_2BUTTON_PRESS) {
819 ControlProtocolInfo* cpi;
822 row = *(_view.get_selection()->get_selected());
823 if (!row[_model.enabled]) {
826 cpi = row[_model.protocol_info];
827 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
830 Box* box = (Box*) cpi->protocol->get_gui ();
834 if (box->get_parent()) {
835 static_cast<ArdourWindow*>(box->get_parent())->present();
838 string title = row[_model.name];
839 /* once created, the window is managed by the surface itself (as ->get_parent())
840 * Surface's tear_down_gui() is called on session close, when de-activating
841 * or re-initializing a surface.
842 * tear_down_gui() hides an deletes the Window if it exists.
844 ArdourWindow* win = new ArdourWindow (_parent, title);
845 win->set_title ("Control Protocol Options");
851 class ControlSurfacesModelColumns : public TreeModelColumnRecord
855 ControlSurfacesModelColumns ()
863 TreeModelColumn<string> name;
864 TreeModelColumn<bool> enabled;
865 TreeModelColumn<bool> feedback;
866 TreeModelColumn<ControlProtocolInfo*> protocol_info;
869 Glib::RefPtr<ListStore> _store;
870 ControlSurfacesModelColumns _model;
872 Gtk::Window& _parent;
873 PBD::ScopedConnection protocol_status_connection;
874 uint32_t _ignore_view_change;
877 class VideoTimelineOptions : public OptionEditorBox
880 VideoTimelineOptions (RCConfiguration* c)
882 , _show_video_export_info_button (_("Show Video Export Info before export"))
883 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
884 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
886 Table* t = manage (new Table (2, 6));
889 t->attach (_video_advanced_setup_button, 0, 2, 0, 1);
890 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
891 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
892 _("<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."));
894 Label* l = manage (new Label (_("Video Server URL:")));
895 l->set_alignment (0, 0.5);
896 t->attach (*l, 0, 1, 1, 2, FILL);
897 t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL);
898 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
899 _("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"));
901 l = manage (new Label (_("Video Folder:")));
902 l->set_alignment (0, 0.5);
903 t->attach (*l, 0, 1, 2, 3, FILL);
904 t->attach (_video_server_docroot_entry, 1, 2, 2, 3);
905 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
906 _("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."));
908 /* small vspace y=3..4 */
910 t->attach (_show_video_export_info_button, 0, 2, 4, 5);
911 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
912 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
913 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
915 t->attach (_show_video_server_dialog_button, 0, 2, 5, 6);
916 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
917 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
918 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
920 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
921 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
922 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
923 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
925 _box->pack_start (*t,true,true);
928 void server_url_changed ()
930 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
933 void server_docroot_changed ()
935 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
938 void show_video_export_info_toggled ()
940 bool const x = _show_video_export_info_button.get_active ();
941 _rc_config->set_show_video_export_info (x);
944 void show_video_server_dialog_toggled ()
946 bool const x = _show_video_server_dialog_button.get_active ();
947 _rc_config->set_show_video_server_dialog (x);
950 void video_advanced_setup_toggled ()
952 bool const x = _video_advanced_setup_button.get_active ();
953 _rc_config->set_video_advanced_setup(x);
956 void parameter_changed (string const & p)
958 if (p == "video-server-url") {
959 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
960 } else if (p == "video-server-docroot") {
961 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
962 } else if (p == "show-video-export-info") {
963 bool const x = _rc_config->get_show_video_export_info();
964 _show_video_export_info_button.set_active (x);
965 } else if (p == "show-video-server-dialog") {
966 bool const x = _rc_config->get_show_video_server_dialog();
967 _show_video_server_dialog_button.set_active (x);
968 } else if (p == "video-advanced-setup") {
969 bool const x = _rc_config->get_video_advanced_setup();
970 _video_advanced_setup_button.set_active(x);
971 _video_server_docroot_entry.set_sensitive(x);
972 _video_server_url_entry.set_sensitive(x);
976 void set_state_from_config ()
978 parameter_changed ("video-server-url");
979 parameter_changed ("video-server-docroot");
980 parameter_changed ("video-monitor-setup-dialog");
981 parameter_changed ("show-video-export-info");
982 parameter_changed ("show-video-server-dialog");
983 parameter_changed ("video-advanced-setup");
987 RCConfiguration* _rc_config;
988 Entry _video_server_url_entry;
989 Entry _video_server_docroot_entry;
990 CheckButton _show_video_export_info_button;
991 CheckButton _show_video_server_dialog_button;
992 CheckButton _video_advanced_setup_button;
995 class PluginOptions : public OptionEditorBox
998 PluginOptions (RCConfiguration* c, UIConfiguration* uic)
1001 , _display_plugin_scan_progress (_("Always Display Plugin Scan Progress"))
1002 , _discover_vst_on_start (_("Scan for [new] VST Plugins on Application Start"))
1003 , _discover_au_on_start (_("Scan for AudioUnit Plugins on Application Start"))
1004 , _timeout_adjustment (0, 0, 3000, 50, 50)
1005 , _timeout_slider (_timeout_adjustment)
1008 std::stringstream ss;
1009 Table* t = manage (new Table (2, 6));
1010 t->set_spacings (4);
1014 ss << "<b>" << _("General") << "</b>";
1015 l = manage (left_aligned_label (ss.str()));
1016 l->set_use_markup (true);
1017 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1018 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1020 b = manage (new Button (_("Scan for Plugins")));
1021 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1022 t->attach (*b, 0, 2, n, n+1, FILL); ++n;
1024 t->attach (_display_plugin_scan_progress, 0, 2, n, n+1); ++n;
1025 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1026 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1027 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
1029 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
1030 _timeout_slider.set_digits (0);
1031 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &PluginOptions::timeout_changed));
1033 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1034 _("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."));
1036 l = manage (left_aligned_label (_("Scan Time Out [deciseconds]")));;
1037 HBox* h = manage (new HBox);
1039 h->pack_start (*l, false, false);
1040 h->pack_start (_timeout_slider, true, true);
1041 t->attach (*h, 0, 2, n, n+1); ++n;
1044 ss << "<b>" << _("VST") << "</b>";
1045 l = manage (left_aligned_label (ss.str()));
1046 l->set_use_markup (true);
1047 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1048 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1050 b = manage (new Button (_("Clear VST Cache")));
1051 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_cache_clicked));
1052 t->attach (*b, 0, 1, n, n+1, FILL);
1054 b = manage (new Button (_("Clear VST Blacklist")));
1055 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_blacklist_clicked));
1056 t->attach (*b, 1, 2, n, n+1, FILL);
1059 t->attach (_discover_vst_on_start, 0, 2, n, n+1); ++n;
1060 _discover_vst_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_vst_on_start_toggled));
1061 Gtkmm2ext::UI::instance()->set_tip (_discover_vst_on_start,
1062 _("<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"));
1064 #ifdef LXVST_SUPPORT
1065 t->attach (*manage (left_aligned_label (_("Linux VST Path:"))), 0, 1, n, n+1);
1066 b = manage (new Button (_("Edit")));
1067 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_lxvst_path_clicked));
1068 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1071 #ifdef WINDOWS_VST_SUPPORT
1072 t->attach (*manage (left_aligned_label (_("Windows VST Path:"))), 0, 1, n, n+1);
1073 b = manage (new Button (_("Edit")));
1074 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_vst_path_clicked));
1075 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1079 #ifdef AUDIOUNIT_SUPPORT
1080 t->attach (_discover_au_on_start, 0, 2, n, n+1); ++n;
1081 _discover_au_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_au_on_start_toggled));
1082 Gtkmm2ext::UI::instance()->set_tip (_discover_au_on_start,
1083 _("<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."));
1086 _box->pack_start (*t,true,true);
1089 void parameter_changed (string const & p) {
1090 if (p == "show-plugin-scan-window") {
1091 bool const x = _ui_config->get_show_plugin_scan_window();
1092 _display_plugin_scan_progress.set_active (x);
1094 else if (p == "discover-vst-on-start") {
1095 bool const x = _rc_config->get_discover_vst_on_start();
1096 _discover_vst_on_start.set_active (x);
1098 else if (p == "vst-scan-timeout") {
1099 int const x = _rc_config->get_vst_scan_timeout();
1100 _timeout_adjustment.set_value (x);
1102 else if (p == "discover-audio-units") {
1103 bool const x = _rc_config->get_discover_audio_units();
1104 _discover_au_on_start.set_active (x);
1108 void set_state_from_config () {
1109 parameter_changed ("show-plugin-scan-window");
1110 parameter_changed ("discover-vst-on-start");
1111 parameter_changed ("vst-scan-timeout");
1112 parameter_changed ("discover-audio-units");
1116 RCConfiguration* _rc_config;
1117 UIConfiguration* _ui_config;
1118 CheckButton _display_plugin_scan_progress;
1119 CheckButton _discover_vst_on_start;
1120 CheckButton _discover_au_on_start;
1121 Adjustment _timeout_adjustment;
1122 HScale _timeout_slider;
1124 void display_plugin_scan_progress_toggled () {
1125 bool const x = _display_plugin_scan_progress.get_active();
1126 _ui_config->set_show_plugin_scan_window(x);
1129 void discover_vst_on_start_toggled () {
1130 bool const x = _discover_vst_on_start.get_active();
1131 _rc_config->set_discover_vst_on_start(x);
1134 void discover_au_on_start_toggled () {
1135 bool const x = _discover_au_on_start.get_active();
1136 _rc_config->set_discover_audio_units(x);
1139 void timeout_changed () {
1140 int x = floor(_timeout_adjustment.get_value());
1141 _rc_config->set_vst_scan_timeout(x);
1144 void clear_vst_cache_clicked () {
1145 PluginManager::instance().clear_vst_cache();
1148 void clear_vst_blacklist_clicked () {
1149 PluginManager::instance().clear_vst_blacklist();
1152 void edit_vst_path_clicked () {
1153 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1154 _("Set Windows VST Search Path"),
1155 _rc_config->get_plugin_path_vst(),
1156 PluginManager::instance().get_default_windows_vst_path()
1158 ResponseType r = (ResponseType) pd->run ();
1160 if (r == RESPONSE_ACCEPT) {
1161 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
1166 // todo consolidate with edit_vst_path_clicked..
1167 void edit_lxvst_path_clicked () {
1168 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1169 _("Set Linux VST Search Path"),
1170 _rc_config->get_plugin_path_lxvst(),
1171 PluginManager::instance().get_default_lxvst_path()
1173 ResponseType r = (ResponseType) pd->run ();
1175 if (r == RESPONSE_ACCEPT) {
1176 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
1181 void refresh_clicked () {
1182 PluginManager::instance().refresh();
1187 /** A class which allows control of visibility of some editor components usign
1188 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1189 * which has the correct members, but with null widget pointers. This
1190 * class allows the user to set visibility of the members, the details
1191 * of which are stored in a configuration variable which can be watched
1192 * by parts of the editor that actually contain the widgets whose visibility
1193 * is being controlled.
1196 class VisibilityOption : public Option
1199 /** @param name User-visible name for this group.
1200 * @param g `Dummy' VisibilityGroup (as described above).
1201 * @param get Method to get the value of the appropriate configuration variable.
1202 * @param set Method to set the value of the appropriate configuration variable.
1204 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1205 : Option (g->get_state_name(), name)
1207 , _visibility_group (g)
1211 /* Watch for changes made by the user to our members */
1212 _visibility_group->VisibilityChanged.connect_same_thread (
1213 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1217 void set_state_from_config ()
1219 /* Set our state from the current configuration */
1220 _visibility_group->set_state (_get ());
1223 void add_to_page (OptionEditorPage* p)
1225 _heading.add_to_page (p);
1226 add_widget_to_page (p, _visibility_group->list_view ());
1229 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1234 /* The user has changed something, so reflect this change
1235 in the RCConfiguration.
1237 _set (_visibility_group->get_state_value ());
1240 OptionEditorHeading _heading;
1241 VisibilityGroup* _visibility_group;
1242 sigc::slot<std::string> _get;
1243 sigc::slot<bool, std::string> _set;
1244 PBD::ScopedConnection _visibility_group_connection;
1249 RCOptionEditor::RCOptionEditor ()
1250 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1251 , _rc_config (Config)
1252 , _ui_config (ARDOUR_UI::config())
1253 , _mixer_strip_visibility ("mixer-element-visibility")
1257 uint32_t hwcpus = hardware_concurrency ();
1259 BoolComboOption* bco;
1262 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1264 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1266 _("Signal processing uses"),
1267 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1268 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1271 procs->add (-1, _("all but one processor"));
1272 procs->add (0, _("all available processors"));
1274 for (uint32_t i = 1; i <= hwcpus; ++i) {
1275 procs->add (i, string_compose (_("%1 processors"), i));
1278 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1280 add_option (_("Misc"), procs);
1283 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1285 add_option (_("Misc"), new UndoOptions (_rc_config));
1287 add_option (_("Misc"),
1289 "verify-remove-last-capture",
1290 _("Verify removal of last capture"),
1291 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1292 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1295 add_option (_("Misc"),
1297 "periodic-safety-backups",
1298 _("Make periodic backups of the session file"),
1299 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1300 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1303 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1305 add_option (_("Misc"),
1307 "only-copy-imported-files",
1308 _("Always copy imported files"),
1309 sigc::mem_fun (*_ui_config, &UIConfiguration::get_only_copy_imported_files),
1310 sigc::mem_fun (*_ui_config, &UIConfiguration::set_only_copy_imported_files)
1313 add_option (_("Misc"), new DirectoryOption (
1314 X_("default-session-parent-dir"),
1315 _("Default folder for new sessions:"),
1316 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1317 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1320 add_option (_("Misc"),
1321 new SpinOption<uint32_t> (
1322 "max-recent-sessions",
1323 _("Maximum number of recent sessions"),
1324 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1325 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1329 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1331 add_option (_("Misc"), new ClickOptions (_rc_config, this));
1333 add_option (_("Misc"),
1336 _("Click gain level"),
1337 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1338 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1341 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1343 add_option (_("Misc"),
1344 new SpinOption<double> (
1345 "automation-thinning-factor",
1346 _("Thinning factor (larger value => less data)"),
1347 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1348 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1352 add_option (_("Misc"),
1353 new SpinOption<double> (
1354 "automation-interval-msecs",
1355 _("Automation sampling interval (milliseconds)"),
1356 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1357 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1365 tsf = new BoolOption (
1366 "latched-record-enable",
1367 _("Keep record-enable engaged on stop"),
1368 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1369 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1371 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1372 add_option (_("Transport"), tsf);
1374 tsf = new BoolOption (
1375 "stop-recording-on-xrun",
1376 _("Stop recording when an xrun occurs"),
1377 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1378 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1380 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1381 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
1383 add_option (_("Transport"), tsf);
1385 tsf = new BoolOption (
1387 _("Play loop is a transport mode"),
1388 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1389 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1391 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1392 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1393 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1394 add_option (_("Transport"), tsf);
1396 tsf = new BoolOption (
1397 "create-xrun-marker",
1398 _("Create markers where xruns occur"),
1399 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
1400 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
1402 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1403 add_option (_("Transport"), tsf);
1405 tsf = new BoolOption (
1406 "stop-at-session-end",
1407 _("Stop at the end of the session"),
1408 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
1409 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
1411 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1412 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
1413 "when it reaches the current session end marker\n\n"
1414 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
1416 add_option (_("Transport"), tsf);
1418 tsf = new BoolOption (
1420 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
1421 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
1422 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
1424 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1425 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
1426 "preventing any need to do a transport locate at the end of the loop\n\n"
1427 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
1428 "which will often cause a small click or delay"), PROGRAM_NAME));
1429 add_option (_("Transport"), tsf);
1431 tsf = new BoolOption (
1432 "disable-disarm-during-roll",
1433 _("Disable per-track record disarm while rolling"),
1434 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
1435 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
1437 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"));
1438 add_option (_("Transport"), tsf);
1440 tsf = new BoolOption (
1442 _("12dB gain reduction during fast-forward and fast-rewind"),
1443 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
1444 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
1446 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
1447 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
1448 add_option (_("Transport"), tsf);
1450 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
1452 _sync_source = new ComboOption<SyncSource> (
1454 _("External timecode source"),
1455 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
1456 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
1459 populate_sync_options ();
1460 add_option (_("Transport"), _sync_source);
1462 _sync_framerate = new BoolOption (
1463 "timecode-sync-frame-rate",
1464 _("Match session video frame rate to external timecode"),
1465 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
1466 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
1468 Gtkmm2ext::UI::instance()->set_tip
1469 (_sync_framerate->tip_widget(),
1470 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
1471 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
1472 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
1473 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
1474 "timecode standard and the session standard."), PROGRAM_NAME));
1476 add_option (_("Transport"), _sync_framerate);
1478 _sync_genlock = new BoolOption (
1479 "timecode-source-is-synced",
1480 _("External timecode is sync locked"),
1481 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
1482 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
1484 Gtkmm2ext::UI::instance()->set_tip
1485 (_sync_genlock->tip_widget(),
1486 _("<b>When enabled</b> indicates that the selected external timecode source shares sync (Black & Burst, Wordclock, etc) with the audio interface."));
1489 add_option (_("Transport"), _sync_genlock);
1491 _sync_source_2997 = new BoolOption (
1492 "timecode-source-2997",
1493 _("Lock to 29.9700 fps instead of 30000/1001"),
1494 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
1495 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
1497 Gtkmm2ext::UI::instance()->set_tip
1498 (_sync_source_2997->tip_widget(),
1499 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
1500 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
1501 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
1502 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
1503 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
1504 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
1507 add_option (_("Transport"), _sync_source_2997);
1509 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
1511 _ltc_port = new ComboStringOption (
1513 _("LTC incoming port"),
1514 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
1515 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
1518 vector<string> physical_inputs;
1519 physical_inputs.push_back (_("None"));
1520 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
1521 _ltc_port->set_popdown_strings (physical_inputs);
1523 add_option (_("Transport"), _ltc_port);
1525 // TODO; rather disable this button than not compile it..
1526 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
1528 add_option (_("Transport"),
1531 _("Enable LTC generator"),
1532 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
1533 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
1536 _ltc_send_continuously = new BoolOption (
1537 "ltc-send-continuously",
1538 _("Send LTC while stopped"),
1539 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
1540 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
1542 Gtkmm2ext::UI::instance()->set_tip
1543 (_ltc_send_continuously->tip_widget(),
1544 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
1545 add_option (_("Transport"), _ltc_send_continuously);
1547 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
1548 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
1549 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
1550 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
1552 Gtkmm2ext::UI::instance()->set_tip
1553 (_ltc_volume_slider->tip_widget(),
1554 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
1556 add_option (_("Transport"), _ltc_volume_slider);
1557 parameter_changed ("send-ltc");
1559 parameter_changed ("sync-source");
1563 add_option (S_("Editor"),
1565 "draggable-playhead",
1566 _("Allow dragging of playhead"),
1567 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_draggable_playhead),
1568 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_draggable_playhead)
1571 add_option (_("Editor"),
1573 "automation-follows-regions",
1574 _("Move relevant automation when audio regions are moved"),
1575 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
1576 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
1579 add_option (_("Editor"),
1581 "show-track-meters",
1582 _("Show meters on tracks in the editor"),
1583 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_track_meters),
1584 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_track_meters)
1587 add_option (_("Editor"),
1589 "show-editor-meter",
1590 _("Display master-meter in the toolbar"),
1591 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_editor_meter),
1592 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_editor_meter)
1595 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
1596 "default-fade-shape",
1597 _("Default fade shape"),
1598 sigc::mem_fun (*_rc_config,
1599 &RCConfiguration::get_default_fade_shape),
1600 sigc::mem_fun (*_rc_config,
1601 &RCConfiguration::set_default_fade_shape)
1604 fadeshape->add (FadeLinear,
1605 _("Linear (for highly correlated material)"));
1606 fadeshape->add (FadeConstantPower, _("Constant power"));
1607 fadeshape->add (FadeSymmetric, _("Symmetric"));
1608 fadeshape->add (FadeSlow, _("Slow"));
1609 fadeshape->add (FadeFast, _("Fast"));
1611 add_option (_("Editor"), fadeshape);
1614 bco = new BoolComboOption (
1615 "use-overlap-equivalency",
1616 _("Regions in active edit groups are edited together"),
1617 _("whenever they overlap in time"),
1618 _("only if they have identical length, position and origin"),
1619 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
1620 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
1623 add_option (_("Editor"), bco);
1625 add_option (_("Editor"),
1627 "rubberbanding-snaps-to-grid",
1628 _("Make rubberband selection rectangle snap to the grid"),
1629 sigc::mem_fun (*_ui_config, &UIConfiguration::get_rubberbanding_snaps_to_grid),
1630 sigc::mem_fun (*_ui_config, &UIConfiguration::set_rubberbanding_snaps_to_grid)
1633 add_option (_("Editor"),
1636 _("Show waveforms in regions"),
1637 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms),
1638 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms)
1641 add_option (_("Editor"),
1642 new BoolComboOption (
1643 "show-region-gain-envelopes",
1644 _("Show gain envelopes in audio regions"),
1646 _("only in region gain mode"),
1647 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_region_gain),
1648 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_region_gain)
1651 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
1653 _("Waveform scale"),
1654 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_scale),
1655 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_scale)
1658 wfs->add (Linear, _("linear"));
1659 wfs->add (Logarithmic, _("logarithmic"));
1661 add_option (_("Editor"), wfs);
1663 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
1665 _("Waveform shape"),
1666 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_shape),
1667 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_shape)
1670 wfsh->add (Traditional, _("traditional"));
1671 wfsh->add (Rectified, _("rectified"));
1673 add_option (_("Editor"), wfsh);
1675 add_option (_("Editor"), new ClipLevelOptions (_ui_config));
1677 add_option (_("Editor"),
1679 "show-waveforms-while-recording",
1680 _("Show waveforms for audio while it is being recorded"),
1681 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms_while_recording),
1682 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms_while_recording)
1685 add_option (_("Editor"),
1688 _("Show zoom toolbar"),
1689 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_zoom_tools),
1690 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_zoom_tools)
1693 add_option (_("Editor"),
1695 "update-editor-during-summary-drag",
1696 _("Update editor window during drags of the summary"),
1697 sigc::mem_fun (*_ui_config, &UIConfiguration::get_update_editor_during_summary_drag),
1698 sigc::mem_fun (*_ui_config, &UIConfiguration::set_update_editor_during_summary_drag)
1701 add_option (_("Editor"),
1703 "link-editor-and-mixer-selection",
1704 _("Synchronise editor and mixer selection"),
1705 sigc::mem_fun (*_ui_config, &UIConfiguration::get_link_editor_and_mixer_selection),
1706 sigc::mem_fun (*_ui_config, &UIConfiguration::set_link_editor_and_mixer_selection)
1709 bo = new BoolOption (
1711 _("Name new markers"),
1712 sigc::mem_fun (*_ui_config, &UIConfiguration::get_name_new_markers),
1713 sigc::mem_fun (*_ui_config, &UIConfiguration::set_name_new_markers)
1716 add_option (_("Editor"), bo);
1717 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."
1718 "\n\nYou can always rename markers by right-clicking on them"));
1720 add_option (_("Editor"),
1722 "autoscroll-editor",
1723 _("Auto-scroll editor window when dragging near its edges"),
1724 sigc::mem_fun (*_ui_config, &UIConfiguration::get_autoscroll_editor),
1725 sigc::mem_fun (*_ui_config, &UIConfiguration::set_autoscroll_editor)
1728 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
1729 "region-selection-after-split",
1730 _("After splitting selected regions, select"),
1731 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
1732 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
1734 // TODO: decide which of these modes are really useful
1735 rsas->add(None, _("no regions"));
1736 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
1737 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
1738 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
1739 // rsas->add(Existing, _("unmodified regions in the existing selection"));
1740 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
1741 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
1742 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
1744 add_option (_("Editor"), rsas);
1749 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
1751 add_option (_("Audio"), new BufferingOptions (_rc_config));
1753 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
1755 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
1757 _("Record monitoring handled by"),
1758 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
1759 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
1762 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
1763 mm->add (HardwareMonitoring, _("via Audio Driver"));
1766 string prog (PROGRAM_NAME);
1767 boost::algorithm::to_lower (prog);
1768 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
1769 mm->add (ExternalMonitoring, _("audio hardware"));
1771 add_option (_("Audio"), mm);
1773 add_option (_("Audio"),
1775 "tape-machine-mode",
1776 _("Tape machine mode"),
1777 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
1778 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
1781 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
1783 add_option (_("Audio"),
1785 "auto-connect-standard-busses",
1786 _("Auto-connect master/monitor busses"),
1787 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
1788 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
1791 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
1792 "input-auto-connect",
1793 _("Connect track inputs"),
1794 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
1795 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
1798 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
1799 iac->add (ManualConnect, _("manually"));
1801 add_option (_("Audio"), iac);
1803 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
1804 "output-auto-connect",
1805 _("Connect track and bus outputs"),
1806 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
1807 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
1810 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
1811 oac->add (AutoConnectMaster, _("automatically to master bus"));
1812 oac->add (ManualConnect, _("manually"));
1814 add_option (_("Audio"), oac);
1816 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
1818 add_option (_("Audio"),
1820 "denormal-protection",
1821 _("Use DC bias to protect against denormals"),
1822 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
1823 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
1826 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
1828 _("Processor handling"),
1829 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
1830 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
1833 dm->add (DenormalNone, _("no processor handling"));
1837 if (fpu.has_flush_to_zero()) {
1838 dm->add (DenormalFTZ, _("use FlushToZero"));
1841 if (fpu.has_denormals_are_zero()) {
1842 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
1845 if (fpu.has_flush_to_zero() && fpu.has_denormals_are_zero()) {
1846 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
1849 add_option (_("Audio"), dm);
1851 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
1853 add_option (_("Audio"),
1855 "plugins-stop-with-transport",
1856 _("Silence plugins when the transport is stopped"),
1857 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
1858 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
1861 add_option (_("Audio"),
1863 "new-plugins-active",
1864 _("Make new plugins active"),
1865 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
1866 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
1869 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
1871 add_option (_("Audio"),
1873 "auto-analyse-audio",
1874 _("Enable automatic analysis of audio"),
1875 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
1876 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
1879 add_option (_("Audio"),
1881 "replicate-missing-region-channels",
1882 _("Replicate missing region channels"),
1883 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
1884 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
1889 add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
1891 add_option (_("Solo / mute"),
1894 _("Solo-in-place mute cut (dB)"),
1895 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
1896 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
1899 _solo_control_is_listen_control = new BoolOption (
1900 "solo-control-is-listen-control",
1901 _("Solo controls are Listen controls"),
1902 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
1903 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
1906 add_option (_("Solo / mute"), _solo_control_is_listen_control);
1908 _listen_position = new ComboOption<ListenPosition> (
1910 _("Listen Position"),
1911 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
1912 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
1915 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
1916 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
1918 add_option (_("Solo / mute"), _listen_position);
1920 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
1922 _("PFL signals come from"),
1923 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
1924 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
1927 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
1928 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
1930 add_option (_("Solo / mute"), pp);
1932 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
1934 _("AFL signals come from"),
1935 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
1936 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
1939 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
1940 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
1942 add_option (_("Solo / mute"), pa);
1944 parameter_changed ("use-monitor-bus");
1946 add_option (_("Solo / mute"),
1949 _("Exclusive solo"),
1950 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
1951 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
1954 add_option (_("Solo / mute"),
1957 _("Show solo muting"),
1958 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
1959 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
1962 add_option (_("Solo / mute"),
1964 "solo-mute-override",
1965 _("Soloing overrides muting"),
1966 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
1967 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
1970 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
1972 add_option (_("Solo / mute"),
1974 "mute-affects-pre-fader",
1975 _("Mute affects pre-fader sends"),
1976 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
1977 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
1980 add_option (_("Solo / mute"),
1982 "mute-affects-post-fader",
1983 _("Mute affects post-fader sends"),
1984 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
1985 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
1988 add_option (_("Solo / mute"),
1990 "mute-affects-control-outs",
1991 _("Mute affects control outputs"),
1992 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
1993 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
1996 add_option (_("Solo / mute"),
1998 "mute-affects-main-outs",
1999 _("Mute affects main outputs"),
2000 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2001 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2004 add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
2006 add_option (_("Solo / mute"),
2008 "link-send-and-route-panner",
2009 _("Link panners of Aux and External Sends with main panner by default"),
2010 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2011 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2014 add_option (_("MIDI"),
2017 _("Send MIDI Clock"),
2018 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2019 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2022 add_option (_("MIDI"),
2025 _("Send MIDI Time Code"),
2026 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2027 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2030 add_option (_("MIDI"),
2031 new SpinOption<int> (
2032 "mtc-qf-speed-tolerance",
2033 _("Percentage either side of normal transport speed to transmit MTC"),
2034 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2035 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2039 add_option (_("MIDI"),
2042 _("Obey MIDI Machine Control commands"),
2043 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2044 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2047 add_option (_("MIDI"),
2050 _("Send MIDI Machine Control commands"),
2051 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2052 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2055 add_option (_("MIDI"),
2058 _("Send MIDI control feedback"),
2059 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2060 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2063 add_option (_("MIDI"),
2064 new SpinOption<uint8_t> (
2065 "mmc-receive-device-id",
2066 _("Inbound MMC device ID"),
2067 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2068 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2072 add_option (_("MIDI"),
2073 new SpinOption<uint8_t> (
2074 "mmc-send-device-id",
2075 _("Outbound MMC device ID"),
2076 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2077 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2081 add_option (_("MIDI"),
2082 new SpinOption<int32_t> (
2083 "initial-program-change",
2084 _("Initial program change"),
2085 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2086 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2090 add_option (_("MIDI"),
2092 "display-first-midi-bank-as-zero",
2093 _("Display first MIDI bank/program as 0"),
2094 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2095 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2098 add_option (_("MIDI"),
2100 "never-display-periodic-midi",
2101 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2102 sigc::mem_fun (*_ui_config, &UIConfiguration::get_never_display_periodic_midi),
2103 sigc::mem_fun (*_ui_config, &UIConfiguration::set_never_display_periodic_midi)
2106 add_option (_("MIDI"),
2109 _("Sound MIDI notes as they are selected"),
2110 sigc::mem_fun (*_ui_config, &UIConfiguration::get_sound_midi_notes),
2111 sigc::mem_fun (*_ui_config, &UIConfiguration::set_sound_midi_notes)
2114 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2116 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2117 "midi-audition-synth-uri",
2118 _("Midi Audition Synth (LV2)"),
2119 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2120 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2123 audition_synth->add(X_(""), _("None"));
2124 PluginInfoList all_plugs;
2125 PluginManager& manager (PluginManager::instance());
2127 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2129 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2130 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2131 if (!(*i)->is_instrument()) continue;
2132 if ((*i)->type != ARDOUR::LV2) continue;
2133 audition_synth->add((*i)->unique_id, (*i)->name);
2137 add_option (_("MIDI"), audition_synth);
2139 /* USER INTERACTION */
2141 if (getenv ("ARDOUR_BUNDLED")) {
2142 add_option (_("User interaction"),
2144 "enable-translation",
2145 string_compose (_("Use translations of %1 messages\n"
2146 " <i>(requires a restart of %1 to take effect)</i>\n"
2147 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2148 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2149 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2152 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2154 add_option (_("User interaction"), new KeyboardOptions);
2156 /* Control Surfaces */
2158 add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
2160 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2162 _("Control surface remote ID"),
2163 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2164 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2167 rm->add (UserOrdered, _("assigned by user"));
2168 rm->add (MixerOrdered, _("follows order of mixer"));
2170 add_option (_("Control Surfaces"), rm);
2172 /* VIDEO Timeline */
2173 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2175 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2176 /* Plugin options (currrently VST only) */
2177 add_option (_("Plugins"), new PluginOptions (_rc_config, _ui_config));
2182 add_option (S_("Preferences|GUI"),
2185 _("Graphically indicate mouse pointer hovering over various widgets"),
2186 sigc::mem_fun (*_ui_config, &UIConfiguration::get_widget_prelight),
2187 sigc::mem_fun (*_ui_config, &UIConfiguration::set_widget_prelight)
2190 add_option (S_("Preferences|GUI"),
2193 _("Show tooltips if mouse hovers over a control"),
2194 sigc::mem_fun (*_ui_config, &UIConfiguration::get_use_tooltips),
2195 sigc::mem_fun (*_ui_config, &UIConfiguration::set_use_tooltips)
2198 add_option (S_("Preferences|GUI"),
2200 "show-name-highlight",
2201 _("Use name highlight bars in region displays"),
2202 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_name_highlight),
2203 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_name_highlight)
2207 /* font scaling does nothing with GDK/Quartz */
2208 add_option (S_("Preferences|GUI"), new FontScalingOptions (_ui_config));
2211 add_option (S_("GUI"),
2213 "super-rapid-clock-update",
2214 _("update transport clock display at FPS instead of every 100ms"),
2215 sigc::mem_fun (*_ui_config, &UIConfiguration::get_super_rapid_clock_update),
2216 sigc::mem_fun (*_ui_config, &UIConfiguration::set_super_rapid_clock_update)
2219 /* Lock GUI timeout */
2221 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
2222 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2223 _("Lock timeout (seconds)"),
2225 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_lock_gui_after_seconds),
2226 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_lock_gui_after_seconds)
2228 slts->scale().set_digits (0);
2229 Gtkmm2ext::UI::instance()->set_tip
2230 (slts->tip_widget(),
2231 _("Lock GUI after this many idle seconds (zero to never lock)"));
2232 add_option (S_("Preferences|GUI"), slts);
2234 /* The names of these controls must be the same as those given in MixerStrip
2235 for the actual widgets being controlled.
2237 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
2238 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2239 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
2240 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
2241 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
2242 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2245 S_("Preferences|GUI"),
2246 new VisibilityOption (
2248 &_mixer_strip_visibility,
2249 sigc::mem_fun (*_ui_config, &UIConfiguration::get_mixer_strip_visibility),
2250 sigc::mem_fun (*_ui_config, &UIConfiguration::set_mixer_strip_visibility)
2254 add_option (S_("Preferences|GUI"),
2256 "default-narrow_ms",
2257 _("Use narrow strips in the mixer by default"),
2258 sigc::mem_fun (*_ui_config, &UIConfiguration::get_default_narrow_ms),
2259 sigc::mem_fun (*_ui_config, &UIConfiguration::set_default_narrow_ms)
2262 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2264 ComboOption<float>* mht = new ComboOption<float> (
2266 _("Peak hold time"),
2267 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_hold),
2268 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_hold)
2271 mht->add (MeterHoldOff, _("off"));
2272 mht->add (MeterHoldShort, _("short"));
2273 mht->add (MeterHoldMedium, _("medium"));
2274 mht->add (MeterHoldLong, _("long"));
2276 add_option (S_("Preferences|Metering"), mht);
2278 ComboOption<float>* mfo = new ComboOption<float> (
2281 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2282 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2285 mfo->add (METER_FALLOFF_OFF, _("off"));
2286 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2287 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2288 mfo->add (METER_FALLOFF_SLOWISH, _("slowish [12.0dB/sec] (DIN)"));
2289 mfo->add (METER_FALLOFF_MODERATE, _("moderate [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2290 mfo->add (METER_FALLOFF_MEDIUM, _("medium [20dB/sec]"));
2291 mfo->add (METER_FALLOFF_FAST, _("fast [32dB/sec]"));
2292 mfo->add (METER_FALLOFF_FASTER, _("faster [46dB/sec]"));
2293 mfo->add (METER_FALLOFF_FASTEST, _("fastest [70dB/sec]"));
2295 add_option (S_("Preferences|Metering"), mfo);
2297 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2298 "meter-line-up-level",
2299 _("Meter line-up level; 0dBu"),
2300 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_level),
2301 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_level)
2304 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2305 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2306 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2307 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2309 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."));
2311 add_option (S_("Preferences|Metering"), mlu);
2313 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2314 "meter-line-up-din",
2315 _("IEC1/DIN Meter line-up level; 0dBu"),
2316 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_din),
2317 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_din)
2320 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2321 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2322 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2323 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2325 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2327 add_option (S_("Preferences|Metering"), mld);
2329 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2330 "meter-vu-standard",
2331 _("VU Meter standard"),
2332 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_vu_standard),
2333 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_vu_standard)
2336 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2337 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2338 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2339 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2341 add_option (S_("Preferences|Metering"), mvu);
2343 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
2344 HSliderOption *mpks = new HSliderOption("meter-peak",
2345 _("Peak threshold [dBFS]"),
2347 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_peak),
2348 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_peak)
2351 Gtkmm2ext::UI::instance()->set_tip
2352 (mpks->tip_widget(),
2353 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
2355 add_option (S_("Preferences|Metering"), mpks);
2357 add_option (S_("Preferences|Metering"),
2360 _("LED meter style"),
2361 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_style_led),
2362 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_style_led)
2365 /* and now the theme manager */
2367 ThemeManager* tm = manage (new ThemeManager);
2368 add_page (_("Theme"), *tm);
2372 RCOptionEditor::parameter_changed (string const & p)
2374 OptionEditor::parameter_changed (p);
2376 if (p == "use-monitor-bus") {
2377 bool const s = Config->get_use_monitor_bus ();
2379 /* we can't use this if we don't have a monitor bus */
2380 Config->set_solo_control_is_listen_control (false);
2382 _solo_control_is_listen_control->set_sensitive (s);
2383 _listen_position->set_sensitive (s);
2384 } else if (p == "sync-source") {
2385 _sync_source->set_sensitive (true);
2387 _sync_source->set_sensitive (!_session->config.get_external_sync());
2389 switch(Config->get_sync_source()) {
2392 _sync_genlock->set_sensitive (true);
2393 _sync_framerate->set_sensitive (true);
2394 _sync_source_2997->set_sensitive (true);
2397 _sync_genlock->set_sensitive (false);
2398 _sync_framerate->set_sensitive (false);
2399 _sync_source_2997->set_sensitive (false);
2402 } else if (p == "send-ltc") {
2403 bool const s = Config->get_send_ltc ();
2404 _ltc_send_continuously->set_sensitive (s);
2405 _ltc_volume_slider->set_sensitive (s);
2409 void RCOptionEditor::ltc_generator_volume_changed () {
2410 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
2414 RCOptionEditor::populate_sync_options ()
2416 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
2418 _sync_source->clear ();
2420 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
2421 _sync_source->add (*i, sync_source_to_string (*i));