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 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
555 void parameter_changed (string const & p)
557 if (p == "font-scale") {
558 _dpi_adjustment.set_value (floor ((double)(_ui_config->get_font_scale() / 1024)));
562 void set_state_from_config ()
564 parameter_changed ("font-scale");
571 _ui_config->set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024));
572 /* XXX: should be triggered from the parameter changed signal */
576 UIConfiguration* _ui_config;
577 Adjustment _dpi_adjustment;
581 class ClipLevelOptions : public OptionEditorBox
584 ClipLevelOptions (UIConfiguration* c)
586 , _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
587 , _clip_level_slider (_clip_level_adjustment)
589 _clip_level_adjustment.set_value (_ui_config->get_waveform_clip_level ());
591 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
592 l->set_name ("OptionsLabel");
594 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
595 HBox* h = manage (new HBox);
597 h->pack_start (*l, false, false);
598 h->pack_start (_clip_level_slider, true, true);
600 _box->pack_start (*h, false, false);
602 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
605 void parameter_changed (string const & p)
607 if (p == "waveform-clip-level") {
608 _clip_level_adjustment.set_value (_ui_config->get_waveform_clip_level());
612 void set_state_from_config ()
614 parameter_changed ("waveform-clip-level");
619 void clip_level_changed ()
621 _ui_config->set_waveform_clip_level (_clip_level_adjustment.get_value());
622 /* XXX: should be triggered from the parameter changed signal */
623 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
626 UIConfiguration* _ui_config;
627 Adjustment _clip_level_adjustment;
628 HScale _clip_level_slider;
631 class BufferingOptions : public OptionEditorBox
634 BufferingOptions (RCConfiguration* c)
636 , _playback_adjustment (5, 1, 60, 1, 4)
637 , _capture_adjustment (5, 1, 60, 1, 4)
638 , _playback_slider (_playback_adjustment)
639 , _capture_slider (_capture_adjustment)
641 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
643 Label* l = manage (new Label (_("Playback (seconds of buffering):")));
644 l->set_name ("OptionsLabel");
646 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
647 HBox* h = manage (new HBox);
649 h->pack_start (*l, false, false);
650 h->pack_start (_playback_slider, true, true);
652 _box->pack_start (*h, false, false);
654 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
656 l = manage (new Label (_("Recording (seconds of buffering):")));
657 l->set_name ("OptionsLabel");
659 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
660 h = manage (new HBox);
662 h->pack_start (*l, false, false);
663 h->pack_start (_capture_slider, true, true);
665 _box->pack_start (*h, false, false);
667 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
668 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
671 void parameter_changed (string const & p)
673 if (p == "playback-buffer-seconds") {
674 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
675 } else if (p == "capture-buffer-seconds") {
676 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
680 void set_state_from_config ()
682 parameter_changed ("playback-buffer-seconds");
683 parameter_changed ("capture-buffer-seconds");
688 void playback_changed ()
690 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
693 void capture_changed ()
695 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
698 RCConfiguration* _rc_config;
699 Adjustment _playback_adjustment;
700 Adjustment _capture_adjustment;
701 HScale _playback_slider;
702 HScale _capture_slider;
705 class ControlSurfacesOptions : public OptionEditorBox
708 ControlSurfacesOptions (Gtk::Window& parent)
710 , _ignore_view_change (0)
712 _store = ListStore::create (_model);
713 _view.set_model (_store);
714 _view.append_column (_("Control Surface Protocol"), _model.name);
715 _view.get_column(0)->set_resizable (true);
716 _view.get_column(0)->set_expand (true);
717 _view.append_column_editable (_("Enabled"), _model.enabled);
718 _view.append_column_editable (_("Feedback"), _model.feedback);
720 _box->pack_start (_view, false, false);
722 Label* label = manage (new Label);
723 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
725 _box->pack_start (*label, false, false);
728 ControlProtocolManager& m = ControlProtocolManager::instance ();
729 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
730 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
732 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
733 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
736 void parameter_changed (std::string const &)
741 void set_state_from_config ()
745 ControlProtocolManager& m = ControlProtocolManager::instance ();
746 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
748 if (!(*i)->mandatory) {
749 TreeModel::Row r = *_store->append ();
750 r[_model.name] = (*i)->name;
751 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
752 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
753 r[_model.protocol_info] = *i;
760 void protocol_status_changed (ControlProtocolInfo* cpi) {
762 TreeModel::Children rows = _store->children();
764 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
765 string n = ((*x)[_model.name]);
767 if ((*x)[_model.protocol_info] == cpi) {
768 _ignore_view_change++;
769 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
770 _ignore_view_change--;
776 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
778 TreeModel::Row r = *i;
780 if (_ignore_view_change) {
784 ControlProtocolInfo* cpi = r[_model.protocol_info];
789 bool const was_enabled = (cpi->protocol != 0);
790 bool const is_enabled = r[_model.enabled];
793 if (was_enabled != is_enabled) {
796 ControlProtocolManager::instance().activate (*cpi);
798 ControlProtocolManager::instance().deactivate (*cpi);
802 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
803 bool const is_feedback = r[_model.feedback];
805 if (was_feedback != is_feedback && cpi->protocol) {
806 cpi->protocol->set_feedback (is_feedback);
810 void edit_clicked (GdkEventButton* ev)
812 if (ev->type != GDK_2BUTTON_PRESS) {
817 ControlProtocolInfo* cpi;
820 row = *(_view.get_selection()->get_selected());
821 if (!row[_model.enabled]) {
824 cpi = row[_model.protocol_info];
825 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
828 Box* box = (Box*) cpi->protocol->get_gui ();
832 if (box->get_parent()) {
833 static_cast<ArdourWindow*>(box->get_parent())->present();
836 string title = row[_model.name];
837 /* once created, the window is managed by the surface itself (as ->get_parent())
838 * Surface's tear_down_gui() is called on session close, when de-activating
839 * or re-initializing a surface.
840 * tear_down_gui() hides an deletes the Window if it exists.
842 ArdourWindow* win = new ArdourWindow (_parent, title);
843 win->set_title ("Control Protocol Options");
849 class ControlSurfacesModelColumns : public TreeModelColumnRecord
853 ControlSurfacesModelColumns ()
861 TreeModelColumn<string> name;
862 TreeModelColumn<bool> enabled;
863 TreeModelColumn<bool> feedback;
864 TreeModelColumn<ControlProtocolInfo*> protocol_info;
867 Glib::RefPtr<ListStore> _store;
868 ControlSurfacesModelColumns _model;
870 Gtk::Window& _parent;
871 PBD::ScopedConnection protocol_status_connection;
872 uint32_t _ignore_view_change;
875 class VideoTimelineOptions : public OptionEditorBox
878 VideoTimelineOptions (RCConfiguration* c)
880 , _show_video_export_info_button (_("Show Video Export Info before export"))
881 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
882 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
884 Table* t = manage (new Table (2, 6));
887 t->attach (_video_advanced_setup_button, 0, 2, 0, 1);
888 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
889 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
890 _("<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."));
892 Label* l = manage (new Label (_("Video Server URL:")));
893 l->set_alignment (0, 0.5);
894 t->attach (*l, 0, 1, 1, 2, FILL);
895 t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL);
896 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
897 _("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"));
899 l = manage (new Label (_("Video Folder:")));
900 l->set_alignment (0, 0.5);
901 t->attach (*l, 0, 1, 2, 3, FILL);
902 t->attach (_video_server_docroot_entry, 1, 2, 2, 3);
903 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
904 _("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."));
906 /* small vspace y=3..4 */
908 t->attach (_show_video_export_info_button, 0, 2, 4, 5);
909 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
910 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
911 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
913 t->attach (_show_video_server_dialog_button, 0, 2, 5, 6);
914 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
915 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
916 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
918 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
919 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
920 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
921 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
923 _box->pack_start (*t,true,true);
926 void server_url_changed ()
928 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
931 void server_docroot_changed ()
933 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
936 void show_video_export_info_toggled ()
938 bool const x = _show_video_export_info_button.get_active ();
939 _rc_config->set_show_video_export_info (x);
942 void show_video_server_dialog_toggled ()
944 bool const x = _show_video_server_dialog_button.get_active ();
945 _rc_config->set_show_video_server_dialog (x);
948 void video_advanced_setup_toggled ()
950 bool const x = _video_advanced_setup_button.get_active ();
951 _rc_config->set_video_advanced_setup(x);
954 void parameter_changed (string const & p)
956 if (p == "video-server-url") {
957 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
958 } else if (p == "video-server-docroot") {
959 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
960 } else if (p == "show-video-export-info") {
961 bool const x = _rc_config->get_show_video_export_info();
962 _show_video_export_info_button.set_active (x);
963 } else if (p == "show-video-server-dialog") {
964 bool const x = _rc_config->get_show_video_server_dialog();
965 _show_video_server_dialog_button.set_active (x);
966 } else if (p == "video-advanced-setup") {
967 bool const x = _rc_config->get_video_advanced_setup();
968 _video_advanced_setup_button.set_active(x);
969 _video_server_docroot_entry.set_sensitive(x);
970 _video_server_url_entry.set_sensitive(x);
974 void set_state_from_config ()
976 parameter_changed ("video-server-url");
977 parameter_changed ("video-server-docroot");
978 parameter_changed ("video-monitor-setup-dialog");
979 parameter_changed ("show-video-export-info");
980 parameter_changed ("show-video-server-dialog");
981 parameter_changed ("video-advanced-setup");
985 RCConfiguration* _rc_config;
986 Entry _video_server_url_entry;
987 Entry _video_server_docroot_entry;
988 CheckButton _show_video_export_info_button;
989 CheckButton _show_video_server_dialog_button;
990 CheckButton _video_advanced_setup_button;
993 class PluginOptions : public OptionEditorBox
996 PluginOptions (RCConfiguration* c, UIConfiguration* uic)
999 , _display_plugin_scan_progress (_("Always Display Plugin Scan Progress"))
1000 , _discover_vst_on_start (_("Scan for [new] VST Plugins on Application Start"))
1001 , _discover_au_on_start (_("Scan for AudioUnit Plugins on Application Start"))
1002 , _timeout_adjustment (0, 0, 3000, 50, 50)
1003 , _timeout_slider (_timeout_adjustment)
1006 std::stringstream ss;
1007 Table* t = manage (new Table (2, 6));
1008 t->set_spacings (4);
1012 ss << "<b>" << _("General") << "</b>";
1013 l = manage (left_aligned_label (ss.str()));
1014 l->set_use_markup (true);
1015 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1016 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1018 b = manage (new Button (_("Scan for Plugins")));
1019 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1020 t->attach (*b, 0, 2, n, n+1, FILL); ++n;
1022 t->attach (_display_plugin_scan_progress, 0, 2, n, n+1); ++n;
1023 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1024 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1025 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
1027 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
1028 _timeout_slider.set_digits (0);
1029 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &PluginOptions::timeout_changed));
1031 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1032 _("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."));
1034 l = manage (left_aligned_label (_("Scan Time Out [deciseconds]")));;
1035 HBox* h = manage (new HBox);
1037 h->pack_start (*l, false, false);
1038 h->pack_start (_timeout_slider, true, true);
1039 t->attach (*h, 0, 2, n, n+1); ++n;
1042 ss << "<b>" << _("VST") << "</b>";
1043 l = manage (left_aligned_label (ss.str()));
1044 l->set_use_markup (true);
1045 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1046 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1048 b = manage (new Button (_("Clear VST Cache")));
1049 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_cache_clicked));
1050 t->attach (*b, 0, 1, n, n+1, FILL);
1052 b = manage (new Button (_("Clear VST Blacklist")));
1053 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_blacklist_clicked));
1054 t->attach (*b, 1, 2, n, n+1, FILL);
1057 t->attach (_discover_vst_on_start, 0, 2, n, n+1); ++n;
1058 _discover_vst_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_vst_on_start_toggled));
1059 Gtkmm2ext::UI::instance()->set_tip (_discover_vst_on_start,
1060 _("<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"));
1062 #ifdef LXVST_SUPPORT
1063 t->attach (*manage (left_aligned_label (_("Linux VST Path:"))), 0, 1, n, n+1);
1064 b = manage (new Button (_("Edit")));
1065 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_lxvst_path_clicked));
1066 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1069 #ifdef WINDOWS_VST_SUPPORT
1070 t->attach (*manage (left_aligned_label (_("Windows VST Path:"))), 0, 1, n, n+1);
1071 b = manage (new Button (_("Edit")));
1072 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_vst_path_clicked));
1073 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1077 #ifdef AUDIOUNIT_SUPPORT
1078 t->attach (_discover_au_on_start, 0, 2, n, n+1); ++n;
1079 _discover_au_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_au_on_start_toggled));
1080 Gtkmm2ext::UI::instance()->set_tip (_discover_au_on_start,
1081 _("<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."));
1084 _box->pack_start (*t,true,true);
1087 void parameter_changed (string const & p) {
1088 if (p == "show-plugin-scan-window") {
1089 bool const x = _ui_config->get_show_plugin_scan_window();
1090 _display_plugin_scan_progress.set_active (x);
1092 else if (p == "discover-vst-on-start") {
1093 bool const x = _rc_config->get_discover_vst_on_start();
1094 _discover_vst_on_start.set_active (x);
1096 else if (p == "vst-scan-timeout") {
1097 int const x = _rc_config->get_vst_scan_timeout();
1098 _timeout_adjustment.set_value (x);
1100 else if (p == "discover-audio-units") {
1101 bool const x = _rc_config->get_discover_audio_units();
1102 _discover_au_on_start.set_active (x);
1106 void set_state_from_config () {
1107 parameter_changed ("show-plugin-scan-window");
1108 parameter_changed ("discover-vst-on-start");
1109 parameter_changed ("vst-scan-timeout");
1110 parameter_changed ("discover-audio-units");
1114 RCConfiguration* _rc_config;
1115 UIConfiguration* _ui_config;
1116 CheckButton _display_plugin_scan_progress;
1117 CheckButton _discover_vst_on_start;
1118 CheckButton _discover_au_on_start;
1119 Adjustment _timeout_adjustment;
1120 HScale _timeout_slider;
1122 void display_plugin_scan_progress_toggled () {
1123 bool const x = _display_plugin_scan_progress.get_active();
1124 _ui_config->set_show_plugin_scan_window(x);
1127 void discover_vst_on_start_toggled () {
1128 bool const x = _discover_vst_on_start.get_active();
1129 _rc_config->set_discover_vst_on_start(x);
1132 void discover_au_on_start_toggled () {
1133 bool const x = _discover_au_on_start.get_active();
1134 _rc_config->set_discover_audio_units(x);
1137 void timeout_changed () {
1138 int x = floor(_timeout_adjustment.get_value());
1139 _rc_config->set_vst_scan_timeout(x);
1142 void clear_vst_cache_clicked () {
1143 PluginManager::instance().clear_vst_cache();
1146 void clear_vst_blacklist_clicked () {
1147 PluginManager::instance().clear_vst_blacklist();
1150 void edit_vst_path_clicked () {
1151 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1152 _("Set Windows VST Search Path"),
1153 _rc_config->get_plugin_path_vst(),
1154 PluginManager::instance().get_default_windows_vst_path()
1156 ResponseType r = (ResponseType) pd->run ();
1158 if (r == RESPONSE_ACCEPT) {
1159 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
1164 // todo consolidate with edit_vst_path_clicked..
1165 void edit_lxvst_path_clicked () {
1166 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1167 _("Set Linux VST Search Path"),
1168 _rc_config->get_plugin_path_lxvst(),
1169 PluginManager::instance().get_default_lxvst_path()
1171 ResponseType r = (ResponseType) pd->run ();
1173 if (r == RESPONSE_ACCEPT) {
1174 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
1179 void refresh_clicked () {
1180 PluginManager::instance().refresh();
1185 /** A class which allows control of visibility of some editor components usign
1186 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1187 * which has the correct members, but with null widget pointers. This
1188 * class allows the user to set visibility of the members, the details
1189 * of which are stored in a configuration variable which can be watched
1190 * by parts of the editor that actually contain the widgets whose visibility
1191 * is being controlled.
1194 class VisibilityOption : public Option
1197 /** @param name User-visible name for this group.
1198 * @param g `Dummy' VisibilityGroup (as described above).
1199 * @param get Method to get the value of the appropriate configuration variable.
1200 * @param set Method to set the value of the appropriate configuration variable.
1202 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1203 : Option (g->get_state_name(), name)
1205 , _visibility_group (g)
1209 /* Watch for changes made by the user to our members */
1210 _visibility_group->VisibilityChanged.connect_same_thread (
1211 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1215 void set_state_from_config ()
1217 /* Set our state from the current configuration */
1218 _visibility_group->set_state (_get ());
1221 void add_to_page (OptionEditorPage* p)
1223 _heading.add_to_page (p);
1224 add_widget_to_page (p, _visibility_group->list_view ());
1227 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1232 /* The user has changed something, so reflect this change
1233 in the RCConfiguration.
1235 _set (_visibility_group->get_state_value ());
1238 OptionEditorHeading _heading;
1239 VisibilityGroup* _visibility_group;
1240 sigc::slot<std::string> _get;
1241 sigc::slot<bool, std::string> _set;
1242 PBD::ScopedConnection _visibility_group_connection;
1247 RCOptionEditor::RCOptionEditor ()
1248 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1249 , _rc_config (Config)
1250 , _ui_config (ARDOUR_UI::config())
1251 , _mixer_strip_visibility ("mixer-element-visibility")
1255 uint32_t hwcpus = hardware_concurrency ();
1257 BoolComboOption* bco;
1260 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1262 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1264 _("Signal processing uses"),
1265 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1266 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1269 procs->add (-1, _("all but one processor"));
1270 procs->add (0, _("all available processors"));
1272 for (uint32_t i = 1; i <= hwcpus; ++i) {
1273 procs->add (i, string_compose (_("%1 processors"), i));
1276 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1278 add_option (_("Misc"), procs);
1281 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1283 add_option (_("Misc"), new UndoOptions (_rc_config));
1285 add_option (_("Misc"),
1287 "verify-remove-last-capture",
1288 _("Verify removal of last capture"),
1289 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1290 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1293 add_option (_("Misc"),
1295 "periodic-safety-backups",
1296 _("Make periodic backups of the session file"),
1297 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1298 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1301 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1303 add_option (_("Misc"),
1305 "only-copy-imported-files",
1306 _("Always copy imported files"),
1307 sigc::mem_fun (*_ui_config, &UIConfiguration::get_only_copy_imported_files),
1308 sigc::mem_fun (*_ui_config, &UIConfiguration::set_only_copy_imported_files)
1311 add_option (_("Misc"), new DirectoryOption (
1312 X_("default-session-parent-dir"),
1313 _("Default folder for new sessions:"),
1314 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1315 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1318 add_option (_("Misc"),
1319 new SpinOption<uint32_t> (
1320 "max-recent-sessions",
1321 _("Maximum number of recent sessions"),
1322 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1323 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1327 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1329 add_option (_("Misc"), new ClickOptions (_rc_config, this));
1331 add_option (_("Misc"),
1334 _("Click gain level"),
1335 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1336 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1339 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1341 add_option (_("Misc"),
1342 new SpinOption<double> (
1343 "automation-thinning-factor",
1344 _("Thinning factor (larger value => less data)"),
1345 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1346 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1350 add_option (_("Misc"),
1351 new SpinOption<double> (
1352 "automation-interval-msecs",
1353 _("Automation sampling interval (milliseconds)"),
1354 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1355 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1363 tsf = new BoolOption (
1364 "latched-record-enable",
1365 _("Keep record-enable engaged on stop"),
1366 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1367 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1369 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1370 add_option (_("Transport"), tsf);
1372 tsf = new BoolOption (
1373 "stop-recording-on-xrun",
1374 _("Stop recording when an xrun occurs"),
1375 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1376 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1378 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1379 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
1381 add_option (_("Transport"), tsf);
1383 tsf = new BoolOption (
1385 _("Play loop is a transport mode"),
1386 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1387 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1389 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1390 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1391 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1392 add_option (_("Transport"), tsf);
1394 tsf = new BoolOption (
1395 "create-xrun-marker",
1396 _("Create markers where xruns occur"),
1397 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
1398 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
1400 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1401 add_option (_("Transport"), tsf);
1403 tsf = new BoolOption (
1404 "stop-at-session-end",
1405 _("Stop at the end of the session"),
1406 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
1407 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
1409 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1410 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
1411 "when it reaches the current session end marker\n\n"
1412 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
1414 add_option (_("Transport"), tsf);
1416 tsf = new BoolOption (
1418 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
1419 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
1420 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
1422 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1423 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
1424 "preventing any need to do a transport locate at the end of the loop\n\n"
1425 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
1426 "which will often cause a small click or delay"), PROGRAM_NAME));
1427 add_option (_("Transport"), tsf);
1429 tsf = new BoolOption (
1430 "disable-disarm-during-roll",
1431 _("Disable per-track record disarm while rolling"),
1432 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
1433 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
1435 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"));
1436 add_option (_("Transport"), tsf);
1438 tsf = new BoolOption (
1440 _("12dB gain reduction during fast-forward and fast-rewind"),
1441 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
1442 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
1444 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
1445 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
1446 add_option (_("Transport"), tsf);
1448 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
1450 _sync_source = new ComboOption<SyncSource> (
1452 _("External timecode source"),
1453 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
1454 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
1457 populate_sync_options ();
1458 add_option (_("Transport"), _sync_source);
1460 _sync_framerate = new BoolOption (
1461 "timecode-sync-frame-rate",
1462 _("Match session video frame rate to external timecode"),
1463 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
1464 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
1466 Gtkmm2ext::UI::instance()->set_tip
1467 (_sync_framerate->tip_widget(),
1468 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
1469 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
1470 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
1471 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
1472 "timecode standard and the session standard."), PROGRAM_NAME));
1474 add_option (_("Transport"), _sync_framerate);
1476 _sync_genlock = new BoolOption (
1477 "timecode-source-is-synced",
1478 _("External timecode is sync locked"),
1479 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
1480 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
1482 Gtkmm2ext::UI::instance()->set_tip
1483 (_sync_genlock->tip_widget(),
1484 _("<b>When enabled</b> indicates that the selected external timecode source shares sync (Black & Burst, Wordclock, etc) with the audio interface."));
1487 add_option (_("Transport"), _sync_genlock);
1489 _sync_source_2997 = new BoolOption (
1490 "timecode-source-2997",
1491 _("Lock to 29.9700 fps instead of 30000/1001"),
1492 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
1493 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
1495 Gtkmm2ext::UI::instance()->set_tip
1496 (_sync_source_2997->tip_widget(),
1497 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
1498 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
1499 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
1500 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
1501 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
1502 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
1505 add_option (_("Transport"), _sync_source_2997);
1507 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
1509 _ltc_port = new ComboStringOption (
1511 _("LTC incoming port"),
1512 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
1513 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
1516 vector<string> physical_inputs;
1517 physical_inputs.push_back (_("None"));
1518 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
1519 _ltc_port->set_popdown_strings (physical_inputs);
1521 add_option (_("Transport"), _ltc_port);
1523 // TODO; rather disable this button than not compile it..
1524 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
1526 add_option (_("Transport"),
1529 _("Enable LTC generator"),
1530 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
1531 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
1534 _ltc_send_continuously = new BoolOption (
1535 "ltc-send-continuously",
1536 _("Send LTC while stopped"),
1537 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
1538 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
1540 Gtkmm2ext::UI::instance()->set_tip
1541 (_ltc_send_continuously->tip_widget(),
1542 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
1543 add_option (_("Transport"), _ltc_send_continuously);
1545 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
1546 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
1547 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
1548 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
1550 Gtkmm2ext::UI::instance()->set_tip
1551 (_ltc_volume_slider->tip_widget(),
1552 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
1554 add_option (_("Transport"), _ltc_volume_slider);
1555 parameter_changed ("send-ltc");
1557 parameter_changed ("sync-source");
1561 add_option (S_("Editor"),
1563 "draggable-playhead",
1564 _("Allow dragging of playhead"),
1565 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_draggable_playhead),
1566 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_draggable_playhead)
1569 add_option (_("Editor"),
1571 "automation-follows-regions",
1572 _("Move relevant automation when audio regions are moved"),
1573 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
1574 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
1577 add_option (_("Editor"),
1579 "show-track-meters",
1580 _("Show meters on tracks in the editor"),
1581 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_track_meters),
1582 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_track_meters)
1585 add_option (_("Editor"),
1587 "show-editor-meter",
1588 _("Display master-meter in the toolbar"),
1589 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_editor_meter),
1590 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_editor_meter)
1593 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
1594 "default-fade-shape",
1595 _("Default fade shape"),
1596 sigc::mem_fun (*_rc_config,
1597 &RCConfiguration::get_default_fade_shape),
1598 sigc::mem_fun (*_rc_config,
1599 &RCConfiguration::set_default_fade_shape)
1602 fadeshape->add (FadeLinear,
1603 _("Linear (for highly correlated material)"));
1604 fadeshape->add (FadeConstantPower, _("Constant power"));
1605 fadeshape->add (FadeSymmetric, _("Symmetric"));
1606 fadeshape->add (FadeSlow, _("Slow"));
1607 fadeshape->add (FadeFast, _("Fast"));
1609 add_option (_("Editor"), fadeshape);
1612 bco = new BoolComboOption (
1613 "use-overlap-equivalency",
1614 _("Regions in active edit groups are edited together"),
1615 _("whenever they overlap in time"),
1616 _("only if they have identical length, position and origin"),
1617 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
1618 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
1621 add_option (_("Editor"), bco);
1623 add_option (_("Editor"),
1625 "rubberbanding-snaps-to-grid",
1626 _("Make rubberband selection rectangle snap to the grid"),
1627 sigc::mem_fun (*_ui_config, &UIConfiguration::get_rubberbanding_snaps_to_grid),
1628 sigc::mem_fun (*_ui_config, &UIConfiguration::set_rubberbanding_snaps_to_grid)
1631 add_option (_("Editor"),
1634 _("Show waveforms in regions"),
1635 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms),
1636 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms)
1639 add_option (_("Editor"),
1640 new BoolComboOption (
1641 "show-region-gain-envelopes",
1642 _("Show gain envelopes in audio regions"),
1644 _("only in region gain mode"),
1645 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_region_gain),
1646 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_region_gain)
1649 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
1651 _("Waveform scale"),
1652 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_scale),
1653 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_scale)
1656 wfs->add (Linear, _("linear"));
1657 wfs->add (Logarithmic, _("logarithmic"));
1659 add_option (_("Editor"), wfs);
1661 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
1663 _("Waveform shape"),
1664 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_shape),
1665 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_shape)
1668 wfsh->add (Traditional, _("traditional"));
1669 wfsh->add (Rectified, _("rectified"));
1671 add_option (_("Editor"), wfsh);
1673 add_option (_("Editor"), new ClipLevelOptions (_ui_config));
1675 add_option (_("Editor"),
1677 "show-waveforms-while-recording",
1678 _("Show waveforms for audio while it is being recorded"),
1679 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms_while_recording),
1680 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms_while_recording)
1683 add_option (_("Editor"),
1686 _("Show zoom toolbar"),
1687 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_zoom_tools),
1688 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_zoom_tools)
1691 add_option (_("Editor"),
1693 "update-editor-during-summary-drag",
1694 _("Update editor window during drags of the summary"),
1695 sigc::mem_fun (*_ui_config, &UIConfiguration::get_update_editor_during_summary_drag),
1696 sigc::mem_fun (*_ui_config, &UIConfiguration::set_update_editor_during_summary_drag)
1699 add_option (_("Editor"),
1701 "link-editor-and-mixer-selection",
1702 _("Synchronise editor and mixer selection"),
1703 sigc::mem_fun (*_ui_config, &UIConfiguration::get_link_editor_and_mixer_selection),
1704 sigc::mem_fun (*_ui_config, &UIConfiguration::set_link_editor_and_mixer_selection)
1707 bo = new BoolOption (
1709 _("Name new markers"),
1710 sigc::mem_fun (*_ui_config, &UIConfiguration::get_name_new_markers),
1711 sigc::mem_fun (*_ui_config, &UIConfiguration::set_name_new_markers)
1714 add_option (_("Editor"), bo);
1715 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."
1716 "\n\nYou can always rename markers by right-clicking on them"));
1718 add_option (_("Editor"),
1720 "autoscroll-editor",
1721 _("Auto-scroll editor window when dragging near its edges"),
1722 sigc::mem_fun (*_ui_config, &UIConfiguration::get_autoscroll_editor),
1723 sigc::mem_fun (*_ui_config, &UIConfiguration::set_autoscroll_editor)
1726 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
1727 "region-selection-after-split",
1728 _("After splitting selected regions, select"),
1729 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
1730 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
1732 // TODO: decide which of these modes are really useful
1733 rsas->add(None, _("no regions"));
1734 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
1735 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
1736 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
1737 // rsas->add(Existing, _("unmodified regions in the existing selection"));
1738 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
1739 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
1740 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
1742 add_option (_("Editor"), rsas);
1747 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
1749 add_option (_("Audio"), new BufferingOptions (_rc_config));
1751 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
1753 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
1755 _("Record monitoring handled by"),
1756 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
1757 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
1760 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
1761 mm->add (HardwareMonitoring, _("via Audio Driver"));
1764 string prog (PROGRAM_NAME);
1765 boost::algorithm::to_lower (prog);
1766 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
1767 mm->add (ExternalMonitoring, _("audio hardware"));
1769 add_option (_("Audio"), mm);
1771 add_option (_("Audio"),
1773 "tape-machine-mode",
1774 _("Tape machine mode"),
1775 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
1776 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
1779 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
1781 add_option (_("Audio"),
1783 "auto-connect-standard-busses",
1784 _("Auto-connect master/monitor busses"),
1785 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
1786 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
1789 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
1790 "input-auto-connect",
1791 _("Connect track inputs"),
1792 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
1793 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
1796 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
1797 iac->add (ManualConnect, _("manually"));
1799 add_option (_("Audio"), iac);
1801 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
1802 "output-auto-connect",
1803 _("Connect track and bus outputs"),
1804 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
1805 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
1808 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
1809 oac->add (AutoConnectMaster, _("automatically to master bus"));
1810 oac->add (ManualConnect, _("manually"));
1812 add_option (_("Audio"), oac);
1814 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
1816 add_option (_("Audio"),
1818 "denormal-protection",
1819 _("Use DC bias to protect against denormals"),
1820 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
1821 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
1824 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
1826 _("Processor handling"),
1827 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
1828 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
1831 dm->add (DenormalNone, _("no processor handling"));
1835 if (fpu.has_flush_to_zero()) {
1836 dm->add (DenormalFTZ, _("use FlushToZero"));
1839 if (fpu.has_denormals_are_zero()) {
1840 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
1843 if (fpu.has_flush_to_zero() && fpu.has_denormals_are_zero()) {
1844 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
1847 add_option (_("Audio"), dm);
1849 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
1851 add_option (_("Audio"),
1853 "plugins-stop-with-transport",
1854 _("Silence plugins when the transport is stopped"),
1855 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
1856 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
1859 add_option (_("Audio"),
1861 "new-plugins-active",
1862 _("Make new plugins active"),
1863 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
1864 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
1867 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
1869 add_option (_("Audio"),
1871 "auto-analyse-audio",
1872 _("Enable automatic analysis of audio"),
1873 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
1874 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
1877 add_option (_("Audio"),
1879 "replicate-missing-region-channels",
1880 _("Replicate missing region channels"),
1881 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
1882 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
1887 add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
1889 add_option (_("Solo / mute"),
1892 _("Solo-in-place mute cut (dB)"),
1893 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
1894 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
1897 _solo_control_is_listen_control = new BoolOption (
1898 "solo-control-is-listen-control",
1899 _("Solo controls are Listen controls"),
1900 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
1901 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
1904 add_option (_("Solo / mute"), _solo_control_is_listen_control);
1906 _listen_position = new ComboOption<ListenPosition> (
1908 _("Listen Position"),
1909 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
1910 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
1913 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
1914 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
1916 add_option (_("Solo / mute"), _listen_position);
1918 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
1920 _("PFL signals come from"),
1921 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
1922 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
1925 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
1926 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
1928 add_option (_("Solo / mute"), pp);
1930 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
1932 _("AFL signals come from"),
1933 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
1934 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
1937 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
1938 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
1940 add_option (_("Solo / mute"), pa);
1942 parameter_changed ("use-monitor-bus");
1944 add_option (_("Solo / mute"),
1947 _("Exclusive solo"),
1948 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
1949 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
1952 add_option (_("Solo / mute"),
1955 _("Show solo muting"),
1956 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
1957 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
1960 add_option (_("Solo / mute"),
1962 "solo-mute-override",
1963 _("Soloing overrides muting"),
1964 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
1965 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
1968 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
1970 add_option (_("Solo / mute"),
1972 "mute-affects-pre-fader",
1973 _("Mute affects pre-fader sends"),
1974 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
1975 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
1978 add_option (_("Solo / mute"),
1980 "mute-affects-post-fader",
1981 _("Mute affects post-fader sends"),
1982 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
1983 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
1986 add_option (_("Solo / mute"),
1988 "mute-affects-control-outs",
1989 _("Mute affects control outputs"),
1990 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
1991 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
1994 add_option (_("Solo / mute"),
1996 "mute-affects-main-outs",
1997 _("Mute affects main outputs"),
1998 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
1999 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2002 add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
2004 add_option (_("Solo / mute"),
2006 "link-send-and-route-panner",
2007 _("Link panners of Aux and External Sends with main panner by default"),
2008 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2009 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2012 add_option (_("MIDI"),
2015 _("Send MIDI Clock"),
2016 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2017 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2020 add_option (_("MIDI"),
2023 _("Send MIDI Time Code"),
2024 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2025 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2028 add_option (_("MIDI"),
2029 new SpinOption<int> (
2030 "mtc-qf-speed-tolerance",
2031 _("Percentage either side of normal transport speed to transmit MTC"),
2032 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2033 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2037 add_option (_("MIDI"),
2040 _("Obey MIDI Machine Control commands"),
2041 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2042 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2045 add_option (_("MIDI"),
2048 _("Send MIDI Machine Control commands"),
2049 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2050 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2053 add_option (_("MIDI"),
2056 _("Send MIDI control feedback"),
2057 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2058 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2061 add_option (_("MIDI"),
2062 new SpinOption<uint8_t> (
2063 "mmc-receive-device-id",
2064 _("Inbound MMC device ID"),
2065 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2066 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2070 add_option (_("MIDI"),
2071 new SpinOption<uint8_t> (
2072 "mmc-send-device-id",
2073 _("Outbound MMC device ID"),
2074 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2075 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2079 add_option (_("MIDI"),
2080 new SpinOption<int32_t> (
2081 "initial-program-change",
2082 _("Initial program change"),
2083 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2084 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2088 add_option (_("MIDI"),
2090 "display-first-midi-bank-as-zero",
2091 _("Display first MIDI bank/program as 0"),
2092 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2093 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2096 add_option (_("MIDI"),
2098 "never-display-periodic-midi",
2099 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2100 sigc::mem_fun (*_ui_config, &UIConfiguration::get_never_display_periodic_midi),
2101 sigc::mem_fun (*_ui_config, &UIConfiguration::set_never_display_periodic_midi)
2104 add_option (_("MIDI"),
2107 _("Sound MIDI notes as they are selected"),
2108 sigc::mem_fun (*_ui_config, &UIConfiguration::get_sound_midi_notes),
2109 sigc::mem_fun (*_ui_config, &UIConfiguration::set_sound_midi_notes)
2112 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2114 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2115 "midi-audition-synth-uri",
2116 _("Midi Audition Synth (LV2)"),
2117 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2118 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2121 audition_synth->add(X_(""), _("None"));
2122 PluginInfoList all_plugs;
2123 PluginManager& manager (PluginManager::instance());
2125 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2127 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2128 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2129 if (!(*i)->is_instrument()) continue;
2130 if ((*i)->type != ARDOUR::LV2) continue;
2131 audition_synth->add((*i)->unique_id, (*i)->name);
2135 add_option (_("MIDI"), audition_synth);
2137 /* USER INTERACTION */
2139 if (getenv ("ARDOUR_BUNDLED")) {
2140 add_option (_("User interaction"),
2142 "enable-translation",
2143 string_compose (_("Use translations of %1 messages\n"
2144 " <i>(requires a restart of %1 to take effect)</i>\n"
2145 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2146 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2147 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2150 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2152 add_option (_("User interaction"), new KeyboardOptions);
2154 /* Control Surfaces */
2156 add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
2158 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2160 _("Control surface remote ID"),
2161 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2162 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2165 rm->add (UserOrdered, _("assigned by user"));
2166 rm->add (MixerOrdered, _("follows order of mixer"));
2168 add_option (_("Control Surfaces"), rm);
2170 /* VIDEO Timeline */
2171 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2173 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2174 /* Plugin options (currrently VST only) */
2175 add_option (_("Plugins"), new PluginOptions (_rc_config, _ui_config));
2180 add_option (S_("Preferences|GUI"),
2183 _("Graphically indicate mouse pointer hovering over various widgets"),
2184 sigc::mem_fun (*_ui_config, &UIConfiguration::get_widget_prelight),
2185 sigc::mem_fun (*_ui_config, &UIConfiguration::set_widget_prelight)
2188 add_option (S_("Preferences|GUI"),
2191 _("Show tooltips if mouse hovers over a control"),
2192 sigc::mem_fun (*_ui_config, &UIConfiguration::get_use_tooltips),
2193 sigc::mem_fun (*_ui_config, &UIConfiguration::set_use_tooltips)
2196 add_option (S_("Preferences|GUI"),
2198 "show-name-highlight",
2199 _("Use name highlight bars in region displays"),
2200 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_name_highlight),
2201 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_name_highlight)
2205 /* font scaling does nothing with GDK/Quartz */
2206 add_option (S_("Preferences|GUI"), new FontScalingOptions (_ui_config));
2209 add_option (S_("GUI"),
2211 "super-rapid-clock-update",
2212 _("update transport clock display at FPS instead of every 100ms"),
2213 sigc::mem_fun (*_ui_config, &UIConfiguration::get_super_rapid_clock_update),
2214 sigc::mem_fun (*_ui_config, &UIConfiguration::set_super_rapid_clock_update)
2217 /* Lock GUI timeout */
2219 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
2220 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2221 _("Lock timeout (seconds)"),
2223 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_lock_gui_after_seconds),
2224 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_lock_gui_after_seconds)
2226 slts->scale().set_digits (0);
2227 Gtkmm2ext::UI::instance()->set_tip
2228 (slts->tip_widget(),
2229 _("Lock GUI after this many idle seconds (zero to never lock)"));
2230 add_option (S_("Preferences|GUI"), slts);
2232 /* The names of these controls must be the same as those given in MixerStrip
2233 for the actual widgets being controlled.
2235 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
2236 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2237 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
2238 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
2239 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
2240 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2243 S_("Preferences|GUI"),
2244 new VisibilityOption (
2246 &_mixer_strip_visibility,
2247 sigc::mem_fun (*_ui_config, &UIConfiguration::get_mixer_strip_visibility),
2248 sigc::mem_fun (*_ui_config, &UIConfiguration::set_mixer_strip_visibility)
2252 add_option (S_("Preferences|GUI"),
2254 "default-narrow_ms",
2255 _("Use narrow strips in the mixer by default"),
2256 sigc::mem_fun (*_ui_config, &UIConfiguration::get_default_narrow_ms),
2257 sigc::mem_fun (*_ui_config, &UIConfiguration::set_default_narrow_ms)
2260 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2262 ComboOption<float>* mht = new ComboOption<float> (
2264 _("Peak hold time"),
2265 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_hold),
2266 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_hold)
2269 mht->add (MeterHoldOff, _("off"));
2270 mht->add (MeterHoldShort, _("short"));
2271 mht->add (MeterHoldMedium, _("medium"));
2272 mht->add (MeterHoldLong, _("long"));
2274 add_option (S_("Preferences|Metering"), mht);
2276 ComboOption<float>* mfo = new ComboOption<float> (
2279 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2280 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2283 mfo->add (METER_FALLOFF_OFF, _("off"));
2284 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2285 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2286 mfo->add (METER_FALLOFF_SLOWISH, _("slowish [12.0dB/sec] (DIN)"));
2287 mfo->add (METER_FALLOFF_MODERATE, _("moderate [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2288 mfo->add (METER_FALLOFF_MEDIUM, _("medium [20dB/sec]"));
2289 mfo->add (METER_FALLOFF_FAST, _("fast [32dB/sec]"));
2290 mfo->add (METER_FALLOFF_FASTER, _("faster [46dB/sec]"));
2291 mfo->add (METER_FALLOFF_FASTEST, _("fastest [70dB/sec]"));
2293 add_option (S_("Preferences|Metering"), mfo);
2295 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2296 "meter-line-up-level",
2297 _("Meter line-up level; 0dBu"),
2298 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_level),
2299 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_level)
2302 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2303 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2304 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2305 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2307 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."));
2309 add_option (S_("Preferences|Metering"), mlu);
2311 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2312 "meter-line-up-din",
2313 _("IEC1/DIN Meter line-up level; 0dBu"),
2314 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_din),
2315 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_din)
2318 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2319 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2320 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2321 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2323 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2325 add_option (S_("Preferences|Metering"), mld);
2327 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2328 "meter-vu-standard",
2329 _("VU Meter standard"),
2330 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_vu_standard),
2331 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_vu_standard)
2334 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2335 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2336 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2337 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2339 add_option (S_("Preferences|Metering"), mvu);
2341 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
2342 HSliderOption *mpks = new HSliderOption("meter-peak",
2343 _("Peak threshold [dBFS]"),
2345 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_peak),
2346 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_peak)
2349 Gtkmm2ext::UI::instance()->set_tip
2350 (mpks->tip_widget(),
2351 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
2353 add_option (S_("Preferences|Metering"), mpks);
2355 add_option (S_("Preferences|Metering"),
2358 _("LED meter style"),
2359 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_style_led),
2360 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_style_led)
2363 /* and now the theme manager */
2365 ThemeManager* tm = manage (new ThemeManager);
2366 add_page (_("Theme"), *tm);
2370 RCOptionEditor::parameter_changed (string const & p)
2372 OptionEditor::parameter_changed (p);
2374 if (p == "use-monitor-bus") {
2375 bool const s = Config->get_use_monitor_bus ();
2377 /* we can't use this if we don't have a monitor bus */
2378 Config->set_solo_control_is_listen_control (false);
2380 _solo_control_is_listen_control->set_sensitive (s);
2381 _listen_position->set_sensitive (s);
2382 } else if (p == "sync-source") {
2383 _sync_source->set_sensitive (true);
2385 _sync_source->set_sensitive (!_session->config.get_external_sync());
2387 switch(Config->get_sync_source()) {
2390 _sync_genlock->set_sensitive (true);
2391 _sync_framerate->set_sensitive (true);
2392 _sync_source_2997->set_sensitive (true);
2395 _sync_genlock->set_sensitive (false);
2396 _sync_framerate->set_sensitive (false);
2397 _sync_source_2997->set_sensitive (false);
2400 } else if (p == "send-ltc") {
2401 bool const s = Config->get_send_ltc ();
2402 _ltc_send_continuously->set_sensitive (s);
2403 _ltc_volume_slider->set_sensitive (s);
2407 void RCOptionEditor::ltc_generator_volume_changed () {
2408 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
2412 RCOptionEditor::populate_sync_options ()
2414 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
2416 _sync_source->clear ();
2418 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
2419 _sync_source->add (*i, sync_source_to_string (*i));