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"
62 using namespace Gtkmm2ext;
64 using namespace ARDOUR;
65 using namespace ARDOUR_UI_UTILS;
67 class ClickOptions : public OptionEditorBox
70 ClickOptions (RCConfiguration* c, Gtk::Window* p)
73 Table* t = manage (new Table (2, 3));
76 Label* l = manage (left_aligned_label (_("Click audio file:")));
77 t->attach (*l, 0, 1, 0, 1, FILL);
78 t->attach (_click_path_entry, 1, 2, 0, 1, FILL);
79 Button* b = manage (new Button (_("Browse...")));
80 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
81 t->attach (*b, 2, 3, 0, 1, FILL);
83 l = manage (left_aligned_label (_("Click emphasis audio file:")));
84 t->attach (*l, 0, 1, 1, 2, FILL);
85 t->attach (_click_emphasis_path_entry, 1, 2, 1, 2, FILL);
86 b = manage (new Button (_("Browse...")));
87 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
88 t->attach (*b, 2, 3, 1, 2, FILL);
90 _box->pack_start (*t, false, false);
92 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
93 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
96 void parameter_changed (string const & p)
98 if (p == "click-sound") {
99 _click_path_entry.set_text (_rc_config->get_click_sound());
100 } else if (p == "click-emphasis-sound") {
101 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
105 void set_state_from_config ()
107 parameter_changed ("click-sound");
108 parameter_changed ("click-emphasis-sound");
113 void click_browse_clicked ()
115 SoundFileChooser sfdb (_("Choose Click"));
117 if (sfdb.run () == RESPONSE_OK) {
118 click_chosen (sfdb.get_filename());
122 void click_chosen (string const & path)
124 _click_path_entry.set_text (path);
125 _rc_config->set_click_sound (path);
128 void click_changed ()
130 click_chosen (_click_path_entry.get_text ());
133 void click_emphasis_browse_clicked ()
135 SoundFileChooser sfdb (_("Choose Click Emphasis"));
140 if (sfdb.run () == RESPONSE_OK) {
141 click_emphasis_chosen (sfdb.get_filename());
145 void click_emphasis_chosen (string const & path)
147 _click_emphasis_path_entry.set_text (path);
148 _rc_config->set_click_emphasis_sound (path);
151 void click_emphasis_changed ()
153 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
156 RCConfiguration* _rc_config;
157 Entry _click_path_entry;
158 Entry _click_emphasis_path_entry;
161 class UndoOptions : public OptionEditorBox
164 UndoOptions (RCConfiguration* c) :
166 _limit_undo_button (_("Limit undo history to")),
167 _save_undo_button (_("Save undo history of"))
169 Table* t = new Table (2, 3);
172 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
173 _limit_undo_spin.set_range (0, 512);
174 _limit_undo_spin.set_increments (1, 10);
175 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
176 Label* l = manage (left_aligned_label (_("commands")));
177 t->attach (*l, 2, 3, 0, 1);
179 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
180 _save_undo_spin.set_range (0, 512);
181 _save_undo_spin.set_increments (1, 10);
182 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
183 l = manage (left_aligned_label (_("commands")));
184 t->attach (*l, 2, 3, 1, 2);
186 _box->pack_start (*t);
188 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
189 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
190 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
191 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
194 void parameter_changed (string const & p)
196 if (p == "history-depth") {
197 int32_t const d = _rc_config->get_history_depth();
198 _limit_undo_button.set_active (d != 0);
199 _limit_undo_spin.set_sensitive (d != 0);
200 _limit_undo_spin.set_value (d);
201 } else if (p == "save-history") {
202 bool const x = _rc_config->get_save_history ();
203 _save_undo_button.set_active (x);
204 _save_undo_spin.set_sensitive (x);
205 } else if (p == "save-history-depth") {
206 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
210 void set_state_from_config ()
212 parameter_changed ("save-history");
213 parameter_changed ("history-depth");
214 parameter_changed ("save-history-depth");
217 void limit_undo_toggled ()
219 bool const x = _limit_undo_button.get_active ();
220 _limit_undo_spin.set_sensitive (x);
221 int32_t const n = x ? 16 : 0;
222 _limit_undo_spin.set_value (n);
223 _rc_config->set_history_depth (n);
226 void limit_undo_changed ()
228 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
231 void save_undo_toggled ()
233 bool const x = _save_undo_button.get_active ();
234 _rc_config->set_save_history (x);
237 void save_undo_changed ()
239 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
243 RCConfiguration* _rc_config;
244 CheckButton _limit_undo_button;
245 SpinButton _limit_undo_spin;
246 CheckButton _save_undo_button;
247 SpinButton _save_undo_spin;
252 static const struct {
264 { "Key|Shift", GDK_SHIFT_MASK },
265 { "Command", GDK_META_MASK },
266 { "Control", GDK_CONTROL_MASK },
267 { "Option", GDK_MOD1_MASK },
268 { "Command-Shift", GDK_META_MASK|GDK_SHIFT_MASK },
269 { "Command-Option", GDK_MOD1_MASK|GDK_META_MASK },
270 { "Shift-Option", GDK_SHIFT_MASK|GDK_MOD1_MASK },
271 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_META_MASK },
274 { "Key|Shift", GDK_SHIFT_MASK },
275 { "Control", GDK_CONTROL_MASK },
276 { "Alt (Mod1)", GDK_MOD1_MASK },
277 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
278 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
279 { "Shift-Alt", GDK_SHIFT_MASK|GDK_MOD1_MASK },
280 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
281 { "Mod2", GDK_MOD2_MASK },
282 { "Mod3", GDK_MOD3_MASK },
283 { "Mod4", GDK_MOD4_MASK },
284 { "Mod5", GDK_MOD5_MASK },
290 class KeyboardOptions : public OptionEditorBox
294 _delete_button_adjustment (3, 1, 12),
295 _delete_button_spin (_delete_button_adjustment),
296 _edit_button_adjustment (3, 1, 5),
297 _edit_button_spin (_edit_button_adjustment),
298 _insert_note_button_adjustment (3, 1, 5),
299 _insert_note_button_spin (_insert_note_button_adjustment)
301 /* internationalize and prepare for use with combos */
304 for (int i = 0; modifiers[i].name; ++i) {
305 dumb.push_back (S_(modifiers[i].name));
308 set_popdown_strings (_edit_modifier_combo, dumb);
309 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
311 for (int x = 0; modifiers[x].name; ++x) {
312 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
313 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
318 Table* t = manage (new Table (4, 4));
321 Label* l = manage (left_aligned_label (_("Edit using:")));
322 l->set_name ("OptionsLabel");
324 t->attach (*l, 0, 1, 0, 1, FILL | EXPAND, FILL);
325 t->attach (_edit_modifier_combo, 1, 2, 0, 1, FILL | EXPAND, FILL);
327 l = manage (new Label (_("+ button")));
328 l->set_name ("OptionsLabel");
330 t->attach (*l, 3, 4, 0, 1, FILL | EXPAND, FILL);
331 t->attach (_edit_button_spin, 4, 5, 0, 1, FILL | EXPAND, FILL);
333 _edit_button_spin.set_name ("OptionsEntry");
334 _edit_button_adjustment.set_value (Keyboard::edit_button());
335 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
337 set_popdown_strings (_delete_modifier_combo, dumb);
338 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
340 for (int x = 0; modifiers[x].name; ++x) {
341 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
342 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
347 l = manage (left_aligned_label (_("Delete using:")));
348 l->set_name ("OptionsLabel");
350 t->attach (*l, 0, 1, 1, 2, FILL | EXPAND, FILL);
351 t->attach (_delete_modifier_combo, 1, 2, 1, 2, FILL | EXPAND, FILL);
353 l = manage (new Label (_("+ button")));
354 l->set_name ("OptionsLabel");
356 t->attach (*l, 3, 4, 1, 2, FILL | EXPAND, FILL);
357 t->attach (_delete_button_spin, 4, 5, 1, 2, FILL | EXPAND, FILL);
359 _delete_button_spin.set_name ("OptionsEntry");
360 _delete_button_adjustment.set_value (Keyboard::delete_button());
361 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
364 set_popdown_strings (_insert_note_modifier_combo, dumb);
365 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
367 for (int x = 0; modifiers[x].name; ++x) {
368 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
369 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
374 l = manage (left_aligned_label (_("Insert note using:")));
375 l->set_name ("OptionsLabel");
377 t->attach (*l, 0, 1, 2, 3, FILL | EXPAND, FILL);
378 t->attach (_insert_note_modifier_combo, 1, 2, 2, 3, FILL | EXPAND, FILL);
380 l = manage (new Label (_("+ button")));
381 l->set_name ("OptionsLabel");
383 t->attach (*l, 3, 4, 2, 3, FILL | EXPAND, FILL);
384 t->attach (_insert_note_button_spin, 4, 5, 2, 3, FILL | EXPAND, FILL);
386 _insert_note_button_spin.set_name ("OptionsEntry");
387 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
388 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
391 set_popdown_strings (_snap_modifier_combo, dumb);
392 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
394 for (int x = 0; modifiers[x].name; ++x) {
395 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
396 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
401 l = manage (left_aligned_label (_("Ignore snap using:")));
402 l->set_name ("OptionsLabel");
404 t->attach (*l, 0, 1, 3, 4, FILL | EXPAND, FILL);
405 t->attach (_snap_modifier_combo, 1, 2, 3, 4, FILL | EXPAND, FILL);
409 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
410 strs.push_back (bf->first);
413 set_popdown_strings (_keyboard_layout_selector, strs);
414 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
415 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
417 l = manage (left_aligned_label (_("Keyboard layout:")));
418 l->set_name ("OptionsLabel");
420 t->attach (*l, 0, 1, 4, 5, FILL | EXPAND, FILL);
421 t->attach (_keyboard_layout_selector, 1, 2, 4, 5, FILL | EXPAND, FILL);
423 _box->pack_start (*t, false, false);
426 void parameter_changed (string const &)
428 /* XXX: these aren't really config options... */
431 void set_state_from_config ()
433 /* XXX: these aren't really config options... */
438 void bindings_changed ()
440 string const txt = _keyboard_layout_selector.get_active_text();
442 /* XXX: config...? for all this keyboard stuff */
444 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
445 if (txt == i->first) {
446 if (Keyboard::load_keybindings (i->second)) {
447 Keyboard::save_keybindings ();
453 void edit_modifier_chosen ()
455 string const txt = _edit_modifier_combo.get_active_text();
457 for (int i = 0; modifiers[i].name; ++i) {
458 if (txt == _(modifiers[i].name)) {
459 Keyboard::set_edit_modifier (modifiers[i].modifier);
465 void delete_modifier_chosen ()
467 string const txt = _delete_modifier_combo.get_active_text();
469 for (int i = 0; modifiers[i].name; ++i) {
470 if (txt == _(modifiers[i].name)) {
471 Keyboard::set_delete_modifier (modifiers[i].modifier);
477 void insert_note_modifier_chosen ()
479 string const txt = _insert_note_modifier_combo.get_active_text();
481 for (int i = 0; modifiers[i].name; ++i) {
482 if (txt == _(modifiers[i].name)) {
483 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
489 void snap_modifier_chosen ()
491 string const txt = _snap_modifier_combo.get_active_text();
493 for (int i = 0; modifiers[i].name; ++i) {
494 if (txt == _(modifiers[i].name)) {
495 Keyboard::set_snap_modifier (modifiers[i].modifier);
501 void delete_button_changed ()
503 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
506 void edit_button_changed ()
508 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
511 void insert_note_button_changed ()
513 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
516 ComboBoxText _keyboard_layout_selector;
517 ComboBoxText _edit_modifier_combo;
518 ComboBoxText _delete_modifier_combo;
519 ComboBoxText _insert_note_modifier_combo;
520 ComboBoxText _snap_modifier_combo;
521 Adjustment _delete_button_adjustment;
522 SpinButton _delete_button_spin;
523 Adjustment _edit_button_adjustment;
524 SpinButton _edit_button_spin;
525 Adjustment _insert_note_button_adjustment;
526 SpinButton _insert_note_button_spin;
530 class FontScalingOptions : public OptionEditorBox
533 FontScalingOptions (RCConfiguration* c) :
535 _dpi_adjustment (50, 50, 250, 1, 10),
536 _dpi_slider (_dpi_adjustment)
538 _dpi_adjustment.set_value (floor ((double)(_rc_config->get_font_scale () / 1024)));
540 Label* l = manage (new Label (_("Font scaling:")));
541 l->set_name ("OptionsLabel");
543 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
544 HBox* h = manage (new HBox);
546 h->pack_start (*l, false, false);
547 h->pack_start (_dpi_slider, true, true);
549 _box->pack_start (*h, false, false);
551 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
554 void parameter_changed (string const & p)
556 if (p == "font-scale") {
557 _dpi_adjustment.set_value (floor ((double)(_rc_config->get_font_scale() / 1024)));
561 void set_state_from_config ()
563 parameter_changed ("font-scale");
570 _rc_config->set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024));
571 /* XXX: should be triggered from the parameter changed signal */
575 RCConfiguration* _rc_config;
576 Adjustment _dpi_adjustment;
580 class ClipLevelOptions : public OptionEditorBox
583 ClipLevelOptions (RCConfiguration* c)
585 , _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
586 , _clip_level_slider (_clip_level_adjustment)
588 _clip_level_adjustment.set_value (_rc_config->get_waveform_clip_level ());
590 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
591 l->set_name ("OptionsLabel");
593 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
594 HBox* h = manage (new HBox);
596 h->pack_start (*l, false, false);
597 h->pack_start (_clip_level_slider, true, true);
599 _box->pack_start (*h, false, false);
601 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
604 void parameter_changed (string const & p)
606 if (p == "waveform-clip-level") {
607 _clip_level_adjustment.set_value (_rc_config->get_waveform_clip_level());
611 void set_state_from_config ()
613 parameter_changed ("waveform-clip-level");
618 void clip_level_changed ()
620 _rc_config->set_waveform_clip_level (_clip_level_adjustment.get_value());
621 /* XXX: should be triggered from the parameter changed signal */
622 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
625 RCConfiguration* _rc_config;
626 Adjustment _clip_level_adjustment;
627 HScale _clip_level_slider;
630 class BufferingOptions : public OptionEditorBox
633 BufferingOptions (RCConfiguration* c)
635 , _playback_adjustment (5, 1, 60, 1, 4)
636 , _capture_adjustment (5, 1, 60, 1, 4)
637 , _playback_slider (_playback_adjustment)
638 , _capture_slider (_capture_adjustment)
640 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
642 Label* l = manage (new Label (_("Playback (seconds of buffering):")));
643 l->set_name ("OptionsLabel");
645 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
646 HBox* h = manage (new HBox);
648 h->pack_start (*l, false, false);
649 h->pack_start (_playback_slider, true, true);
651 _box->pack_start (*h, false, false);
653 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
655 l = manage (new Label (_("Recording (seconds of buffering):")));
656 l->set_name ("OptionsLabel");
658 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
659 h = manage (new HBox);
661 h->pack_start (*l, false, false);
662 h->pack_start (_capture_slider, true, true);
664 _box->pack_start (*h, false, false);
666 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
667 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
670 void parameter_changed (string const & p)
672 if (p == "playback-buffer-seconds") {
673 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
674 } else if (p == "capture-buffer-seconds") {
675 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
679 void set_state_from_config ()
681 parameter_changed ("playback-buffer-seconds");
682 parameter_changed ("capture-buffer-seconds");
687 void playback_changed ()
689 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
692 void capture_changed ()
694 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
697 RCConfiguration* _rc_config;
698 Adjustment _playback_adjustment;
699 Adjustment _capture_adjustment;
700 HScale _playback_slider;
701 HScale _capture_slider;
704 class ControlSurfacesOptions : public OptionEditorBox
707 ControlSurfacesOptions (Gtk::Window& parent)
709 , _ignore_view_change (0)
711 _store = ListStore::create (_model);
712 _view.set_model (_store);
713 _view.append_column (_("Control Surface Protocol"), _model.name);
714 _view.get_column(0)->set_resizable (true);
715 _view.get_column(0)->set_expand (true);
716 _view.append_column_editable (_("Enabled"), _model.enabled);
717 _view.append_column_editable (_("Feedback"), _model.feedback);
719 _box->pack_start (_view, false, false);
721 Label* label = manage (new Label);
722 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
724 _box->pack_start (*label, false, false);
727 ControlProtocolManager& m = ControlProtocolManager::instance ();
728 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
729 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
731 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
732 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
735 void parameter_changed (std::string const &)
740 void set_state_from_config ()
744 ControlProtocolManager& m = ControlProtocolManager::instance ();
745 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
747 if (!(*i)->mandatory) {
748 TreeModel::Row r = *_store->append ();
749 r[_model.name] = (*i)->name;
750 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
751 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
752 r[_model.protocol_info] = *i;
759 void protocol_status_changed (ControlProtocolInfo* cpi) {
761 TreeModel::Children rows = _store->children();
763 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
764 string n = ((*x)[_model.name]);
766 if ((*x)[_model.protocol_info] == cpi) {
767 _ignore_view_change++;
768 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
769 _ignore_view_change--;
775 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
777 TreeModel::Row r = *i;
779 if (_ignore_view_change) {
783 ControlProtocolInfo* cpi = r[_model.protocol_info];
788 bool const was_enabled = (cpi->protocol != 0);
789 bool const is_enabled = r[_model.enabled];
792 if (was_enabled != is_enabled) {
795 ControlProtocolManager::instance().activate (*cpi);
797 ControlProtocolManager::instance().deactivate (*cpi);
801 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
802 bool const is_feedback = r[_model.feedback];
804 if (was_feedback != is_feedback && cpi->protocol) {
805 cpi->protocol->set_feedback (is_feedback);
809 void edit_clicked (GdkEventButton* ev)
811 if (ev->type != GDK_2BUTTON_PRESS) {
816 ControlProtocolInfo* cpi;
819 row = *(_view.get_selection()->get_selected());
820 if (!row[_model.enabled]) {
823 cpi = row[_model.protocol_info];
824 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
827 Box* box = (Box*) cpi->protocol->get_gui ();
831 if (box->get_parent()) {
832 static_cast<ArdourWindow*>(box->get_parent())->present();
835 string title = row[_model.name];
836 /* once created, the window is managed by the surface itself (as ->get_parent())
837 * Surface's tear_down_gui() is called on session close, when de-activating
838 * or re-initializing a surface.
839 * tear_down_gui() hides an deletes the Window if it exists.
841 ArdourWindow* win = new ArdourWindow (_parent, title);
842 win->set_title ("Control Protocol Options");
848 class ControlSurfacesModelColumns : public TreeModelColumnRecord
852 ControlSurfacesModelColumns ()
860 TreeModelColumn<string> name;
861 TreeModelColumn<bool> enabled;
862 TreeModelColumn<bool> feedback;
863 TreeModelColumn<ControlProtocolInfo*> protocol_info;
866 Glib::RefPtr<ListStore> _store;
867 ControlSurfacesModelColumns _model;
869 Gtk::Window& _parent;
870 PBD::ScopedConnection protocol_status_connection;
871 uint32_t _ignore_view_change;
874 class VideoTimelineOptions : public OptionEditorBox
877 VideoTimelineOptions (RCConfiguration* c)
879 , _show_video_export_info_button (_("Show Video Export Info before export"))
880 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
881 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
883 Table* t = manage (new Table (2, 6));
886 t->attach (_video_advanced_setup_button, 0, 2, 0, 1);
887 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
888 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
889 _("<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."));
891 Label* l = manage (new Label (_("Video Server URL:")));
892 l->set_alignment (0, 0.5);
893 t->attach (*l, 0, 1, 1, 2, FILL);
894 t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL);
895 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
896 _("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"));
898 l = manage (new Label (_("Video Folder:")));
899 l->set_alignment (0, 0.5);
900 t->attach (*l, 0, 1, 2, 3, FILL);
901 t->attach (_video_server_docroot_entry, 1, 2, 2, 3);
902 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
903 _("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."));
905 /* small vspace y=3..4 */
907 t->attach (_show_video_export_info_button, 0, 2, 4, 5);
908 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
909 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
910 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
912 t->attach (_show_video_server_dialog_button, 0, 2, 5, 6);
913 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
914 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
915 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
917 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
918 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
919 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
920 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
922 _box->pack_start (*t,true,true);
925 void server_url_changed ()
927 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
930 void server_docroot_changed ()
932 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
935 void show_video_export_info_toggled ()
937 bool const x = _show_video_export_info_button.get_active ();
938 _rc_config->set_show_video_export_info (x);
941 void show_video_server_dialog_toggled ()
943 bool const x = _show_video_server_dialog_button.get_active ();
944 _rc_config->set_show_video_server_dialog (x);
947 void video_advanced_setup_toggled ()
949 bool const x = _video_advanced_setup_button.get_active ();
950 _rc_config->set_video_advanced_setup(x);
953 void parameter_changed (string const & p)
955 if (p == "video-server-url") {
956 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
957 } else if (p == "video-server-docroot") {
958 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
959 } else if (p == "show-video-export-info") {
960 bool const x = _rc_config->get_show_video_export_info();
961 _show_video_export_info_button.set_active (x);
962 } else if (p == "show-video-server-dialog") {
963 bool const x = _rc_config->get_show_video_server_dialog();
964 _show_video_server_dialog_button.set_active (x);
965 } else if (p == "video-advanced-setup") {
966 bool const x = _rc_config->get_video_advanced_setup();
967 _video_advanced_setup_button.set_active(x);
968 _video_server_docroot_entry.set_sensitive(x);
969 _video_server_url_entry.set_sensitive(x);
973 void set_state_from_config ()
975 parameter_changed ("video-server-url");
976 parameter_changed ("video-server-docroot");
977 parameter_changed ("video-monitor-setup-dialog");
978 parameter_changed ("show-video-export-info");
979 parameter_changed ("show-video-server-dialog");
980 parameter_changed ("video-advanced-setup");
984 RCConfiguration* _rc_config;
985 Entry _video_server_url_entry;
986 Entry _video_server_docroot_entry;
987 CheckButton _show_video_export_info_button;
988 CheckButton _show_video_server_dialog_button;
989 CheckButton _video_advanced_setup_button;
992 class PluginOptions : public OptionEditorBox
995 PluginOptions (RCConfiguration* c)
997 , _display_plugin_scan_progress (_("Always Display Plugin Scan Progress"))
998 , _discover_vst_on_start (_("Scan for [new] VST Plugins on Application Start"))
999 , _discover_au_on_start (_("Scan for AudioUnit Plugins on Application Start"))
1000 , _timeout_adjustment (0, 0, 3000, 50, 50)
1001 , _timeout_slider (_timeout_adjustment)
1004 std::stringstream ss;
1005 Table* t = manage (new Table (2, 6));
1006 t->set_spacings (4);
1010 ss << "<b>" << _("General") << "</b>";
1011 l = manage (left_aligned_label (ss.str()));
1012 l->set_use_markup (true);
1013 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1014 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1016 b = manage (new Button (_("Scan for Plugins")));
1017 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1018 t->attach (*b, 0, 2, n, n+1, FILL); ++n;
1020 t->attach (_display_plugin_scan_progress, 0, 2, n, n+1); ++n;
1021 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1022 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1023 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
1025 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
1026 _timeout_slider.set_digits (0);
1027 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &PluginOptions::timeout_changed));
1029 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1030 _("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."));
1032 l = manage (left_aligned_label (_("Scan Time Out [deciseconds]")));;
1033 HBox* h = manage (new HBox);
1035 h->pack_start (*l, false, false);
1036 h->pack_start (_timeout_slider, true, true);
1037 t->attach (*h, 0, 2, n, n+1); ++n;
1040 ss << "<b>" << _("VST") << "</b>";
1041 l = manage (left_aligned_label (ss.str()));
1042 l->set_use_markup (true);
1043 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1044 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1046 b = manage (new Button (_("Clear VST Cache")));
1047 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_cache_clicked));
1048 t->attach (*b, 0, 1, n, n+1, FILL);
1050 b = manage (new Button (_("Clear VST Blacklist")));
1051 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_blacklist_clicked));
1052 t->attach (*b, 1, 2, n, n+1, FILL);
1055 t->attach (_discover_vst_on_start, 0, 2, n, n+1); ++n;
1056 _discover_vst_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_vst_on_start_toggled));
1057 Gtkmm2ext::UI::instance()->set_tip (_discover_vst_on_start,
1058 _("<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"));
1060 #ifdef LXVST_SUPPORT
1061 t->attach (*manage (left_aligned_label (_("Linux VST Path:"))), 0, 1, n, n+1);
1062 b = manage (new Button (_("Edit")));
1063 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_lxvst_path_clicked));
1064 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1067 #ifdef WINDOWS_VST_SUPPORT
1068 t->attach (*manage (left_aligned_label (_("Windows VST Path:"))), 0, 1, n, n+1);
1069 b = manage (new Button (_("Edit")));
1070 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_vst_path_clicked));
1071 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1075 #ifdef AUDIOUNIT_SUPPORT
1076 t->attach (_discover_au_on_start, 0, 2, n, n+1); ++n;
1077 _discover_au_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_au_on_start_toggled));
1078 Gtkmm2ext::UI::instance()->set_tip (_discover_au_on_start,
1079 _("<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."));
1082 _box->pack_start (*t,true,true);
1085 void parameter_changed (string const & p) {
1086 if (p == "show-plugin-scan-window") {
1087 bool const x = _rc_config->get_show_plugin_scan_window();
1088 _display_plugin_scan_progress.set_active (x);
1090 else if (p == "discover-vst-on-start") {
1091 bool const x = _rc_config->get_discover_vst_on_start();
1092 _discover_vst_on_start.set_active (x);
1094 else if (p == "vst-scan-timeout") {
1095 int const x = _rc_config->get_vst_scan_timeout();
1096 _timeout_adjustment.set_value (x);
1098 else if (p == "discover-audio-units") {
1099 bool const x = _rc_config->get_discover_audio_units();
1100 _discover_au_on_start.set_active (x);
1104 void set_state_from_config () {
1105 parameter_changed ("show-plugin-scan-window");
1106 parameter_changed ("discover-vst-on-start");
1107 parameter_changed ("vst-scan-timeout");
1108 parameter_changed ("discover-audio-units");
1112 RCConfiguration* _rc_config;
1113 CheckButton _display_plugin_scan_progress;
1114 CheckButton _discover_vst_on_start;
1115 CheckButton _discover_au_on_start;
1116 Adjustment _timeout_adjustment;
1117 HScale _timeout_slider;
1119 void display_plugin_scan_progress_toggled () {
1120 bool const x = _display_plugin_scan_progress.get_active();
1121 _rc_config->set_show_plugin_scan_window(x);
1124 void discover_vst_on_start_toggled () {
1125 bool const x = _discover_vst_on_start.get_active();
1126 _rc_config->set_discover_vst_on_start(x);
1129 void discover_au_on_start_toggled () {
1130 bool const x = _discover_au_on_start.get_active();
1131 _rc_config->set_discover_audio_units(x);
1134 void timeout_changed () {
1135 int x = floor(_timeout_adjustment.get_value());
1136 _rc_config->set_vst_scan_timeout(x);
1139 void clear_vst_cache_clicked () {
1140 PluginManager::instance().clear_vst_cache();
1143 void clear_vst_blacklist_clicked () {
1144 PluginManager::instance().clear_vst_blacklist();
1147 void edit_vst_path_clicked () {
1148 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1149 _("Set Windows VST Search Path"),
1150 _rc_config->get_plugin_path_vst(),
1151 PluginManager::instance().get_default_windows_vst_path()
1153 ResponseType r = (ResponseType) pd->run ();
1155 if (r == RESPONSE_ACCEPT) {
1156 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
1161 // todo consolidate with edit_vst_path_clicked..
1162 void edit_lxvst_path_clicked () {
1163 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1164 _("Set Linux VST Search Path"),
1165 _rc_config->get_plugin_path_lxvst(),
1166 PluginManager::instance().get_default_lxvst_path()
1168 ResponseType r = (ResponseType) pd->run ();
1170 if (r == RESPONSE_ACCEPT) {
1171 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
1176 void refresh_clicked () {
1177 PluginManager::instance().refresh();
1182 /** A class which allows control of visibility of some editor components usign
1183 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1184 * which has the correct members, but with null widget pointers. This
1185 * class allows the user to set visibility of the members, the details
1186 * of which are stored in a configuration variable which can be watched
1187 * by parts of the editor that actually contain the widgets whose visibility
1188 * is being controlled.
1191 class VisibilityOption : public Option
1194 /** @param name User-visible name for this group.
1195 * @param g `Dummy' VisibilityGroup (as described above).
1196 * @param get Method to get the value of the appropriate configuration variable.
1197 * @param set Method to set the value of the appropriate configuration variable.
1199 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1200 : Option (g->get_state_name(), name)
1202 , _visibility_group (g)
1206 /* Watch for changes made by the user to our members */
1207 _visibility_group->VisibilityChanged.connect_same_thread (
1208 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1212 void set_state_from_config ()
1214 /* Set our state from the current configuration */
1215 _visibility_group->set_state (_get ());
1218 void add_to_page (OptionEditorPage* p)
1220 _heading.add_to_page (p);
1221 add_widget_to_page (p, _visibility_group->list_view ());
1224 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1229 /* The user has changed something, so reflect this change
1230 in the RCConfiguration.
1232 _set (_visibility_group->get_state_value ());
1235 OptionEditorHeading _heading;
1236 VisibilityGroup* _visibility_group;
1237 sigc::slot<std::string> _get;
1238 sigc::slot<bool, std::string> _set;
1239 PBD::ScopedConnection _visibility_group_connection;
1244 RCOptionEditor::RCOptionEditor ()
1245 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1246 , _rc_config (Config)
1247 , _mixer_strip_visibility ("mixer-element-visibility")
1251 uint32_t hwcpus = hardware_concurrency ();
1253 BoolComboOption* bco;
1256 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1258 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1260 _("Signal processing uses"),
1261 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1262 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1265 procs->add (-1, _("all but one processor"));
1266 procs->add (0, _("all available processors"));
1268 for (uint32_t i = 1; i <= hwcpus; ++i) {
1269 procs->add (i, string_compose (_("%1 processors"), i));
1272 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1274 add_option (_("Misc"), procs);
1277 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1279 add_option (_("Misc"), new UndoOptions (_rc_config));
1281 add_option (_("Misc"),
1283 "verify-remove-last-capture",
1284 _("Verify removal of last capture"),
1285 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1286 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1289 add_option (_("Misc"),
1291 "periodic-safety-backups",
1292 _("Make periodic backups of the session file"),
1293 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1294 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1297 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1299 add_option (_("Misc"),
1301 "only-copy-imported-files",
1302 _("Always copy imported files"),
1303 sigc::mem_fun (*_rc_config, &RCConfiguration::get_only_copy_imported_files),
1304 sigc::mem_fun (*_rc_config, &RCConfiguration::set_only_copy_imported_files)
1307 add_option (_("Misc"), new DirectoryOption (
1308 X_("default-session-parent-dir"),
1309 _("Default folder for new sessions:"),
1310 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1311 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1314 add_option (_("Misc"),
1315 new SpinOption<uint32_t> (
1316 "max-recent-sessions",
1317 _("Maximum number of recent sessions"),
1318 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1319 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1323 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1325 add_option (_("Misc"), new ClickOptions (_rc_config, this));
1327 add_option (_("Misc"),
1330 _("Click gain level"),
1331 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1332 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1335 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1337 add_option (_("Misc"),
1338 new SpinOption<double> (
1339 "automation-thinning-factor",
1340 _("Thinning factor (larger value => less data)"),
1341 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1342 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1346 add_option (_("Misc"),
1347 new SpinOption<double> (
1348 "automation-interval-msecs",
1349 _("Automation sampling interval (milliseconds)"),
1350 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1351 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1359 tsf = new BoolOption (
1360 "latched-record-enable",
1361 _("Keep record-enable engaged on stop"),
1362 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1363 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1365 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1366 add_option (_("Transport"), tsf);
1368 tsf = new BoolOption (
1369 "stop-recording-on-xrun",
1370 _("Stop recording when an xrun occurs"),
1371 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1372 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1374 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1375 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
1377 add_option (_("Transport"), tsf);
1379 tsf = new BoolOption (
1381 _("Play loop is a transport mode"),
1382 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1383 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1385 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1386 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1387 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1388 add_option (_("Transport"), tsf);
1390 tsf = new BoolOption (
1391 "create-xrun-marker",
1392 _("Create markers where xruns occur"),
1393 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
1394 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
1396 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1397 add_option (_("Transport"), tsf);
1399 tsf = new BoolOption (
1400 "stop-at-session-end",
1401 _("Stop at the end of the session"),
1402 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
1403 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
1405 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1406 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
1407 "when it reaches the current session end marker\n\n"
1408 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
1410 add_option (_("Transport"), tsf);
1412 tsf = new BoolOption (
1414 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
1415 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
1416 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
1418 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1419 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
1420 "preventing any need to do a transport locate at the end of the loop\n\n"
1421 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
1422 "which will often cause a small click or delay"), PROGRAM_NAME));
1423 add_option (_("Transport"), tsf);
1425 tsf = new BoolOption (
1426 "disable-disarm-during-roll",
1427 _("Disable per-track record disarm while rolling"),
1428 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
1429 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
1431 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"));
1432 add_option (_("Transport"), tsf);
1434 tsf = new BoolOption (
1436 _("12dB gain reduction during fast-forward and fast-rewind"),
1437 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
1438 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
1440 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
1441 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
1442 add_option (_("Transport"), tsf);
1444 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
1446 _sync_source = new ComboOption<SyncSource> (
1448 _("External timecode source"),
1449 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
1450 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
1453 populate_sync_options ();
1454 add_option (_("Transport"), _sync_source);
1456 _sync_framerate = new BoolOption (
1457 "timecode-sync-frame-rate",
1458 _("Match session video frame rate to external timecode"),
1459 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
1460 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
1462 Gtkmm2ext::UI::instance()->set_tip
1463 (_sync_framerate->tip_widget(),
1464 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
1465 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
1466 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
1467 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
1468 "timecode standard and the session standard."), PROGRAM_NAME));
1470 add_option (_("Transport"), _sync_framerate);
1472 _sync_genlock = new BoolOption (
1473 "timecode-source-is-synced",
1474 _("External timecode is sync locked"),
1475 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
1476 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
1478 Gtkmm2ext::UI::instance()->set_tip
1479 (_sync_genlock->tip_widget(),
1480 _("<b>When enabled</b> indicates that the selected external timecode source shares sync (Black & Burst, Wordclock, etc) with the audio interface."));
1483 add_option (_("Transport"), _sync_genlock);
1485 _sync_source_2997 = new BoolOption (
1486 "timecode-source-2997",
1487 _("Lock to 29.9700 fps instead of 30000/1001"),
1488 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
1489 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
1491 Gtkmm2ext::UI::instance()->set_tip
1492 (_sync_source_2997->tip_widget(),
1493 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
1494 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
1495 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
1496 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
1497 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
1498 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
1501 add_option (_("Transport"), _sync_source_2997);
1503 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
1505 _ltc_port = new ComboStringOption (
1507 _("LTC incoming port"),
1508 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
1509 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
1512 vector<string> physical_inputs;
1513 physical_inputs.push_back (_("None"));
1514 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
1515 _ltc_port->set_popdown_strings (physical_inputs);
1517 add_option (_("Transport"), _ltc_port);
1519 // TODO; rather disable this button than not compile it..
1520 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
1522 add_option (_("Transport"),
1525 _("Enable LTC generator"),
1526 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
1527 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
1530 _ltc_send_continuously = new BoolOption (
1531 "ltc-send-continuously",
1532 _("Send LTC while stopped"),
1533 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
1534 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
1536 Gtkmm2ext::UI::instance()->set_tip
1537 (_ltc_send_continuously->tip_widget(),
1538 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
1539 add_option (_("Transport"), _ltc_send_continuously);
1541 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
1542 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
1543 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
1544 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
1546 Gtkmm2ext::UI::instance()->set_tip
1547 (_ltc_volume_slider->tip_widget(),
1548 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
1550 add_option (_("Transport"), _ltc_volume_slider);
1551 parameter_changed ("send-ltc");
1553 parameter_changed ("sync-source");
1557 add_option (S_("Editor"),
1559 "draggable-playhead",
1560 _("Allow dragging of playhead"),
1561 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_draggable_playhead),
1562 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_draggable_playhead)
1565 add_option (_("Editor"),
1567 "automation-follows-regions",
1568 _("Move relevant automation when audio regions are moved"),
1569 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
1570 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
1573 add_option (_("Editor"),
1575 "show-track-meters",
1576 _("Show meters on tracks in the editor"),
1577 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_track_meters),
1578 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_track_meters)
1581 add_option (_("Editor"),
1583 "show-editor-meter",
1584 _("Display master-meter in the toolbar"),
1585 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_editor_meter),
1586 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_editor_meter)
1589 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
1590 "default-fade-shape",
1591 _("Default fade shape"),
1592 sigc::mem_fun (*_rc_config,
1593 &RCConfiguration::get_default_fade_shape),
1594 sigc::mem_fun (*_rc_config,
1595 &RCConfiguration::set_default_fade_shape)
1598 fadeshape->add (FadeLinear,
1599 _("Linear (for highly correlated material)"));
1600 fadeshape->add (FadeConstantPower, _("Constant power"));
1601 fadeshape->add (FadeSymmetric, _("Symmetric"));
1602 fadeshape->add (FadeSlow, _("Slow"));
1603 fadeshape->add (FadeFast, _("Fast"));
1605 add_option (_("Editor"), fadeshape);
1608 bco = new BoolComboOption (
1609 "use-overlap-equivalency",
1610 _("Regions in active edit groups are edited together"),
1611 _("whenever they overlap in time"),
1612 _("only if they have identical length, position and origin"),
1613 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
1614 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
1617 add_option (_("Editor"), bco);
1619 add_option (_("Editor"),
1621 "rubberbanding-snaps-to-grid",
1622 _("Make rubberband selection rectangle snap to the grid"),
1623 sigc::mem_fun (*_rc_config, &RCConfiguration::get_rubberbanding_snaps_to_grid),
1624 sigc::mem_fun (*_rc_config, &RCConfiguration::set_rubberbanding_snaps_to_grid)
1627 add_option (_("Editor"),
1630 _("Show waveforms in regions"),
1631 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms),
1632 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms)
1635 add_option (_("Editor"),
1636 new BoolComboOption (
1637 "show-region-gain-envelopes",
1638 _("Show gain envelopes in audio regions"),
1640 _("only in region gain mode"),
1641 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_region_gain),
1642 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_region_gain)
1645 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
1647 _("Waveform scale"),
1648 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_scale),
1649 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_scale)
1652 wfs->add (Linear, _("linear"));
1653 wfs->add (Logarithmic, _("logarithmic"));
1655 add_option (_("Editor"), wfs);
1657 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
1659 _("Waveform shape"),
1660 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_shape),
1661 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_shape)
1664 wfsh->add (Traditional, _("traditional"));
1665 wfsh->add (Rectified, _("rectified"));
1667 add_option (_("Editor"), wfsh);
1669 add_option (_("Editor"), new ClipLevelOptions (_rc_config));
1671 add_option (_("Editor"),
1673 "show-waveforms-while-recording",
1674 _("Show waveforms for audio while it is being recorded"),
1675 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms_while_recording),
1676 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms_while_recording)
1679 add_option (_("Editor"),
1682 _("Show zoom toolbar"),
1683 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_zoom_tools),
1684 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_zoom_tools)
1687 add_option (_("Editor"),
1689 "update-editor-during-summary-drag",
1690 _("Update editor window during drags of the summary"),
1691 sigc::mem_fun (*_rc_config, &RCConfiguration::get_update_editor_during_summary_drag),
1692 sigc::mem_fun (*_rc_config, &RCConfiguration::set_update_editor_during_summary_drag)
1695 add_option (_("Editor"),
1697 "link-editor-and-mixer-selection",
1698 _("Synchronise editor and mixer selection"),
1699 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_editor_and_mixer_selection),
1700 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_editor_and_mixer_selection)
1703 bo = new BoolOption (
1705 _("Name new markers"),
1706 sigc::mem_fun (*_rc_config, &RCConfiguration::get_name_new_markers),
1707 sigc::mem_fun (*_rc_config, &RCConfiguration::set_name_new_markers)
1710 add_option (_("Editor"), bo);
1711 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."
1712 "\n\nYou can always rename markers by right-clicking on them"));
1714 add_option (_("Editor"),
1716 "autoscroll-editor",
1717 _("Auto-scroll editor window when dragging near its edges"),
1718 sigc::mem_fun (*_rc_config, &RCConfiguration::get_autoscroll_editor),
1719 sigc::mem_fun (*_rc_config, &RCConfiguration::set_autoscroll_editor)
1722 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
1723 "region-selection-after-split",
1724 _("After splitting selected regions, select"),
1725 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
1726 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
1728 // TODO: decide which of these modes are really useful
1729 rsas->add(None, _("no regions"));
1730 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
1731 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
1732 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
1733 // rsas->add(Existing, _("unmodified regions in the existing selection"));
1734 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
1735 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
1736 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
1738 add_option (_("Editor"), rsas);
1743 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
1745 add_option (_("Audio"), new BufferingOptions (_rc_config));
1747 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
1749 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
1751 _("Record monitoring handled by"),
1752 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
1753 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
1756 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
1757 mm->add (HardwareMonitoring, _("via Audio Driver"));
1760 string prog (PROGRAM_NAME);
1761 boost::algorithm::to_lower (prog);
1762 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
1763 mm->add (ExternalMonitoring, _("audio hardware"));
1765 add_option (_("Audio"), mm);
1767 add_option (_("Audio"),
1769 "tape-machine-mode",
1770 _("Tape machine mode"),
1771 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
1772 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
1775 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
1777 add_option (_("Audio"),
1779 "auto-connect-standard-busses",
1780 _("Auto-connect master/monitor busses"),
1781 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
1782 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
1785 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
1786 "input-auto-connect",
1787 _("Connect track inputs"),
1788 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
1789 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
1792 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
1793 iac->add (ManualConnect, _("manually"));
1795 add_option (_("Audio"), iac);
1797 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
1798 "output-auto-connect",
1799 _("Connect track and bus outputs"),
1800 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
1801 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
1804 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
1805 oac->add (AutoConnectMaster, _("automatically to master bus"));
1806 oac->add (ManualConnect, _("manually"));
1808 add_option (_("Audio"), oac);
1810 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
1812 add_option (_("Audio"),
1814 "denormal-protection",
1815 _("Use DC bias to protect against denormals"),
1816 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
1817 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
1820 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
1822 _("Processor handling"),
1823 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
1824 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
1827 dm->add (DenormalNone, _("no processor handling"));
1831 if (fpu.has_flush_to_zero()) {
1832 dm->add (DenormalFTZ, _("use FlushToZero"));
1835 if (fpu.has_denormals_are_zero()) {
1836 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
1839 if (fpu.has_flush_to_zero() && fpu.has_denormals_are_zero()) {
1840 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
1843 add_option (_("Audio"), dm);
1845 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
1847 add_option (_("Audio"),
1849 "plugins-stop-with-transport",
1850 _("Silence plugins when the transport is stopped"),
1851 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
1852 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
1855 add_option (_("Audio"),
1857 "new-plugins-active",
1858 _("Make new plugins active"),
1859 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
1860 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
1863 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
1865 add_option (_("Audio"),
1867 "auto-analyse-audio",
1868 _("Enable automatic analysis of audio"),
1869 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
1870 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
1873 add_option (_("Audio"),
1875 "replicate-missing-region-channels",
1876 _("Replicate missing region channels"),
1877 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
1878 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
1883 add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
1885 add_option (_("Solo / mute"),
1888 _("Solo-in-place mute cut (dB)"),
1889 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
1890 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
1893 _solo_control_is_listen_control = new BoolOption (
1894 "solo-control-is-listen-control",
1895 _("Solo controls are Listen controls"),
1896 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
1897 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
1900 add_option (_("Solo / mute"), _solo_control_is_listen_control);
1902 _listen_position = new ComboOption<ListenPosition> (
1904 _("Listen Position"),
1905 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
1906 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
1909 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
1910 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
1912 add_option (_("Solo / mute"), _listen_position);
1914 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
1916 _("PFL signals come from"),
1917 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
1918 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
1921 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
1922 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
1924 add_option (_("Solo / mute"), pp);
1926 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
1928 _("AFL signals come from"),
1929 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
1930 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
1933 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
1934 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
1936 add_option (_("Solo / mute"), pa);
1938 parameter_changed ("use-monitor-bus");
1940 add_option (_("Solo / mute"),
1943 _("Exclusive solo"),
1944 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
1945 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
1948 add_option (_("Solo / mute"),
1951 _("Show solo muting"),
1952 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
1953 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
1956 add_option (_("Solo / mute"),
1958 "solo-mute-override",
1959 _("Soloing overrides muting"),
1960 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
1961 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
1964 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
1966 add_option (_("Solo / mute"),
1968 "mute-affects-pre-fader",
1969 _("Mute affects pre-fader sends"),
1970 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
1971 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
1974 add_option (_("Solo / mute"),
1976 "mute-affects-post-fader",
1977 _("Mute affects post-fader sends"),
1978 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
1979 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
1982 add_option (_("Solo / mute"),
1984 "mute-affects-control-outs",
1985 _("Mute affects control outputs"),
1986 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
1987 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
1990 add_option (_("Solo / mute"),
1992 "mute-affects-main-outs",
1993 _("Mute affects main outputs"),
1994 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
1995 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
1998 add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
2000 add_option (_("Solo / mute"),
2002 "link-send-and-route-panner",
2003 _("Link panners of Aux and External Sends with main panner by default"),
2004 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2005 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2008 add_option (_("MIDI"),
2011 _("Send MIDI Clock"),
2012 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2013 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2016 add_option (_("MIDI"),
2019 _("Send MIDI Time Code"),
2020 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2021 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2024 add_option (_("MIDI"),
2025 new SpinOption<int> (
2026 "mtc-qf-speed-tolerance",
2027 _("Percentage either side of normal transport speed to transmit MTC"),
2028 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2029 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2033 add_option (_("MIDI"),
2036 _("Obey MIDI Machine Control commands"),
2037 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2038 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2041 add_option (_("MIDI"),
2044 _("Send MIDI Machine Control commands"),
2045 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2046 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2049 add_option (_("MIDI"),
2052 _("Send MIDI control feedback"),
2053 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2054 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2057 add_option (_("MIDI"),
2058 new SpinOption<uint8_t> (
2059 "mmc-receive-device-id",
2060 _("Inbound MMC device ID"),
2061 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2062 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2066 add_option (_("MIDI"),
2067 new SpinOption<uint8_t> (
2068 "mmc-send-device-id",
2069 _("Outbound MMC device ID"),
2070 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2071 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2075 add_option (_("MIDI"),
2076 new SpinOption<int32_t> (
2077 "initial-program-change",
2078 _("Initial program change"),
2079 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2080 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2084 add_option (_("MIDI"),
2086 "display-first-midi-bank-as-zero",
2087 _("Display first MIDI bank/program as 0"),
2088 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2089 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2092 add_option (_("MIDI"),
2094 "never-display-periodic-midi",
2095 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2096 sigc::mem_fun (*_rc_config, &RCConfiguration::get_never_display_periodic_midi),
2097 sigc::mem_fun (*_rc_config, &RCConfiguration::set_never_display_periodic_midi)
2100 add_option (_("MIDI"),
2103 _("Sound MIDI notes as they are selected"),
2104 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sound_midi_notes),
2105 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sound_midi_notes)
2108 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2110 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2111 "midi-audition-synth-uri",
2112 _("Midi Audition Synth (LV2)"),
2113 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2114 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2117 audition_synth->add(X_(""), _("None"));
2118 PluginInfoList all_plugs;
2119 PluginManager& manager (PluginManager::instance());
2121 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2123 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2124 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2125 if (!(*i)->is_instrument()) continue;
2126 if ((*i)->type != ARDOUR::LV2) continue;
2127 audition_synth->add((*i)->unique_id, (*i)->name);
2131 add_option (_("MIDI"), audition_synth);
2133 /* USER INTERACTION */
2135 if (getenv ("ARDOUR_BUNDLED")) {
2136 add_option (_("User interaction"),
2138 "enable-translation",
2139 string_compose (_("Use translations of %1 messages\n"
2140 " <i>(requires a restart of %1 to take effect)</i>\n"
2141 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2142 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2143 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2146 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2148 add_option (_("User interaction"), new KeyboardOptions);
2150 /* Control Surfaces */
2152 add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
2154 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2156 _("Control surface remote ID"),
2157 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2158 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2161 rm->add (UserOrdered, _("assigned by user"));
2162 rm->add (MixerOrdered, _("follows order of mixer"));
2164 add_option (_("Control Surfaces"), rm);
2166 /* VIDEO Timeline */
2167 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2169 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2170 /* Plugin options (currrently VST only) */
2171 add_option (_("Plugins"), new PluginOptions (_rc_config));
2176 add_option (S_("Preferences|GUI"),
2179 _("Graphically indicate mouse pointer hovering over various widgets"),
2180 sigc::mem_fun (*_rc_config, &RCConfiguration::get_widget_prelight),
2181 sigc::mem_fun (*_rc_config, &RCConfiguration::set_widget_prelight)
2184 add_option (S_("Preferences|GUI"),
2187 _("Show tooltips if mouse hovers over a control"),
2188 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_tooltips),
2189 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_tooltips)
2192 add_option (S_("Preferences|GUI"),
2194 "show-name-highlight",
2195 _("Use name highlight bars in region displays"),
2196 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_name_highlight),
2197 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_name_highlight)
2201 /* font scaling does nothing with GDK/Quartz */
2202 add_option (S_("Preferences|GUI"), new FontScalingOptions (_rc_config));
2205 add_option (S_("GUI"),
2207 "super-rapid-clock-update",
2208 _("update transport clock display at FPS instead of every 100ms"),
2209 sigc::mem_fun (*_rc_config, &RCConfiguration::get_super_rapid_clock_update),
2210 sigc::mem_fun (*_rc_config, &RCConfiguration::set_super_rapid_clock_update)
2213 /* Lock GUI timeout */
2215 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
2216 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2217 _("Lock timeout (seconds)"),
2219 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_lock_gui_after_seconds),
2220 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_lock_gui_after_seconds)
2222 slts->scale().set_digits (0);
2223 Gtkmm2ext::UI::instance()->set_tip
2224 (slts->tip_widget(),
2225 _("Lock GUI after this many idle seconds (zero to never lock)"));
2226 add_option (S_("Preferences|GUI"), slts);
2228 /* The names of these controls must be the same as those given in MixerStrip
2229 for the actual widgets being controlled.
2231 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
2232 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2233 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
2234 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
2235 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
2236 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2239 S_("Preferences|GUI"),
2240 new VisibilityOption (
2242 &_mixer_strip_visibility,
2243 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mixer_strip_visibility),
2244 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mixer_strip_visibility)
2248 add_option (S_("Preferences|GUI"),
2250 "default-narrow_ms",
2251 _("Use narrow strips in the mixer by default"),
2252 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_narrow_ms),
2253 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_narrow_ms)
2256 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2258 ComboOption<float>* mht = new ComboOption<float> (
2260 _("Peak hold time"),
2261 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_hold),
2262 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_hold)
2265 mht->add (MeterHoldOff, _("off"));
2266 mht->add (MeterHoldShort, _("short"));
2267 mht->add (MeterHoldMedium, _("medium"));
2268 mht->add (MeterHoldLong, _("long"));
2270 add_option (S_("Preferences|Metering"), mht);
2272 ComboOption<float>* mfo = new ComboOption<float> (
2275 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2276 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2279 mfo->add (METER_FALLOFF_OFF, _("off"));
2280 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2281 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2282 mfo->add (METER_FALLOFF_SLOWISH, _("slowish [12.0dB/sec] (DIN)"));
2283 mfo->add (METER_FALLOFF_MODERATE, _("moderate [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2284 mfo->add (METER_FALLOFF_MEDIUM, _("medium [20dB/sec]"));
2285 mfo->add (METER_FALLOFF_FAST, _("fast [32dB/sec]"));
2286 mfo->add (METER_FALLOFF_FASTER, _("faster [46dB/sec]"));
2287 mfo->add (METER_FALLOFF_FASTEST, _("fastest [70dB/sec]"));
2289 add_option (S_("Preferences|Metering"), mfo);
2291 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2292 "meter-line-up-level",
2293 _("Meter line-up level; 0dBu"),
2294 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_line_up_level),
2295 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_line_up_level)
2298 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2299 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2300 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2301 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2303 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."));
2305 add_option (S_("Preferences|Metering"), mlu);
2307 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2308 "meter-line-up-din",
2309 _("IEC1/DIN Meter line-up level; 0dBu"),
2310 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_line_up_din),
2311 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_line_up_din)
2314 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2315 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2316 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2317 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2319 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2321 add_option (S_("Preferences|Metering"), mld);
2323 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2324 "meter-vu-standard",
2325 _("VU Meter standard"),
2326 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_vu_standard),
2327 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_vu_standard)
2330 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2331 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2332 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2333 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2335 add_option (S_("Preferences|Metering"), mvu);
2337 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
2338 HSliderOption *mpks = new HSliderOption("meter-peak",
2339 _("Peak threshold [dBFS]"),
2341 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_peak),
2342 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_peak)
2345 Gtkmm2ext::UI::instance()->set_tip
2346 (mpks->tip_widget(),
2347 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
2349 add_option (S_("Preferences|Metering"), mpks);
2351 add_option (S_("Preferences|Metering"),
2354 _("LED meter style"),
2355 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_style_led),
2356 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_style_led)
2359 /* and now the theme manager */
2361 ThemeManager* tm = manage (new ThemeManager);
2362 add_page (_("Theme"), *tm);
2366 RCOptionEditor::parameter_changed (string const & p)
2368 OptionEditor::parameter_changed (p);
2370 if (p == "use-monitor-bus") {
2371 bool const s = Config->get_use_monitor_bus ();
2373 /* we can't use this if we don't have a monitor bus */
2374 Config->set_solo_control_is_listen_control (false);
2376 _solo_control_is_listen_control->set_sensitive (s);
2377 _listen_position->set_sensitive (s);
2378 } else if (p == "sync-source") {
2379 _sync_source->set_sensitive (true);
2381 _sync_source->set_sensitive (!_session->config.get_external_sync());
2383 switch(Config->get_sync_source()) {
2386 _sync_genlock->set_sensitive (true);
2387 _sync_framerate->set_sensitive (true);
2388 _sync_source_2997->set_sensitive (true);
2391 _sync_genlock->set_sensitive (false);
2392 _sync_framerate->set_sensitive (false);
2393 _sync_source_2997->set_sensitive (false);
2396 } else if (p == "send-ltc") {
2397 bool const s = Config->get_send_ltc ();
2398 _ltc_send_continuously->set_sensitive (s);
2399 _ltc_volume_slider->set_sensitive (s);
2403 void RCOptionEditor::ltc_generator_volume_changed () {
2404 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
2408 RCOptionEditor::populate_sync_options ()
2410 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
2412 _sync_source->clear ();
2414 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
2415 _sync_source->add (*i, sync_source_to_string (*i));