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 <gtkmm/liststore.h>
25 #include <gtkmm/stock.h>
26 #include <gtkmm/scale.h>
27 #include <gtkmm2ext/utils.h>
28 #include <gtkmm2ext/slider_controller.h>
29 #include <gtkmm2ext/gtk_ui.h>
34 #include "midi++/manager.h"
36 #include "ardour/audioengine.h"
37 #include "ardour/dB.h"
38 #include "ardour/rc_configuration.h"
39 #include "ardour/control_protocol_manager.h"
40 #include "control_protocol/control_protocol.h"
42 #include "ardour_window.h"
43 #include "ardour_dialog.h"
44 #include "gui_thread.h"
45 #include "midi_tracer.h"
46 #include "rc_option_editor.h"
48 #include "midi_port_dialog.h"
55 using namespace Gtkmm2ext;
57 using namespace ARDOUR;
59 class ClickOptions : public OptionEditorBox
62 ClickOptions (RCConfiguration* c, Gtk::Window* p)
66 Table* t = manage (new Table (2, 3));
69 Label* l = manage (left_aligned_label (_("Click audio file:")));
70 t->attach (*l, 0, 1, 0, 1, FILL);
71 t->attach (_click_path_entry, 1, 2, 0, 1, FILL);
72 Button* b = manage (new Button (_("Browse...")));
73 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
74 t->attach (*b, 2, 3, 0, 1, FILL);
76 l = manage (left_aligned_label (_("Click emphasis audio file:")));
77 t->attach (*l, 0, 1, 1, 2, FILL);
78 t->attach (_click_emphasis_path_entry, 1, 2, 1, 2, FILL);
79 b = manage (new Button (_("Browse...")));
80 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
81 t->attach (*b, 2, 3, 1, 2, FILL);
83 _box->pack_start (*t, false, false);
85 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
86 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
89 void parameter_changed (string const & p)
91 if (p == "click-sound") {
92 _click_path_entry.set_text (_rc_config->get_click_sound());
93 } else if (p == "click-emphasis-sound") {
94 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
98 void set_state_from_config ()
100 parameter_changed ("click-sound");
101 parameter_changed ("click-emphasis-sound");
106 void click_browse_clicked ()
108 SoundFileChooser sfdb (*_parent, _("Choose Click"));
113 if (sfdb.run () == RESPONSE_OK) {
114 click_chosen (sfdb.get_filename());
118 void click_chosen (string const & path)
120 _click_path_entry.set_text (path);
121 _rc_config->set_click_sound (path);
124 void click_changed ()
126 click_chosen (_click_path_entry.get_text ());
129 void click_emphasis_browse_clicked ()
131 SoundFileChooser sfdb (*_parent, _("Choose Click Emphasis"));
136 if (sfdb.run () == RESPONSE_OK) {
137 click_emphasis_chosen (sfdb.get_filename());
141 void click_emphasis_chosen (string const & path)
143 _click_emphasis_path_entry.set_text (path);
144 _rc_config->set_click_emphasis_sound (path);
147 void click_emphasis_changed ()
149 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
152 RCConfiguration* _rc_config;
153 Gtk::Window* _parent;
154 Entry _click_path_entry;
155 Entry _click_emphasis_path_entry;
158 class UndoOptions : public OptionEditorBox
161 UndoOptions (RCConfiguration* c) :
163 _limit_undo_button (_("Limit undo history to")),
164 _save_undo_button (_("Save undo history of"))
166 Table* t = new Table (2, 3);
169 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
170 _limit_undo_spin.set_range (0, 512);
171 _limit_undo_spin.set_increments (1, 10);
172 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
173 Label* l = manage (left_aligned_label (_("commands")));
174 t->attach (*l, 2, 3, 0, 1);
176 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
177 _save_undo_spin.set_range (0, 512);
178 _save_undo_spin.set_increments (1, 10);
179 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
180 l = manage (left_aligned_label (_("commands")));
181 t->attach (*l, 2, 3, 1, 2);
183 _box->pack_start (*t);
185 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
186 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
187 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
188 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
191 void parameter_changed (string const & p)
193 if (p == "history-depth") {
194 int32_t const d = _rc_config->get_history_depth();
195 _limit_undo_button.set_active (d != 0);
196 _limit_undo_spin.set_sensitive (d != 0);
197 _limit_undo_spin.set_value (d);
198 } else if (p == "save-history") {
199 bool const x = _rc_config->get_save_history ();
200 _save_undo_button.set_active (x);
201 _save_undo_spin.set_sensitive (x);
202 } else if (p == "save-history-depth") {
203 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
207 void set_state_from_config ()
209 parameter_changed ("save-history");
210 parameter_changed ("history-depth");
211 parameter_changed ("save-history-depth");
214 void limit_undo_toggled ()
216 bool const x = _limit_undo_button.get_active ();
217 _limit_undo_spin.set_sensitive (x);
218 int32_t const n = x ? 16 : 0;
219 _limit_undo_spin.set_value (n);
220 _rc_config->set_history_depth (n);
223 void limit_undo_changed ()
225 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
228 void save_undo_toggled ()
230 bool const x = _save_undo_button.get_active ();
231 _rc_config->set_save_history (x);
234 void save_undo_changed ()
236 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
240 RCConfiguration* _rc_config;
241 CheckButton _limit_undo_button;
242 SpinButton _limit_undo_spin;
243 CheckButton _save_undo_button;
244 SpinButton _save_undo_spin;
249 static const struct {
261 { "Key|Shift", GDK_SHIFT_MASK },
262 { "Command", GDK_META_MASK },
263 { "Control", GDK_CONTROL_MASK },
264 { "Option", GDK_MOD1_MASK },
265 { "Command-Shift", GDK_META_MASK|GDK_SHIFT_MASK },
266 { "Command-Option", GDK_MOD1_MASK|GDK_META_MASK },
267 { "Shift-Option", GDK_SHIFT_MASK|GDK_MOD1_MASK },
268 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_META_MASK },
271 { "Key|Shift", GDK_SHIFT_MASK },
272 { "Control", GDK_CONTROL_MASK },
273 { "Alt (Mod1)", GDK_MOD1_MASK },
274 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
275 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
276 { "Shift-Alt", GDK_SHIFT_MASK|GDK_MOD1_MASK },
277 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
278 { "Mod2", GDK_MOD2_MASK },
279 { "Mod3", GDK_MOD3_MASK },
280 { "Mod4", GDK_MOD4_MASK },
281 { "Mod5", GDK_MOD5_MASK },
287 class KeyboardOptions : public OptionEditorBox
291 _delete_button_adjustment (3, 1, 12),
292 _delete_button_spin (_delete_button_adjustment),
293 _edit_button_adjustment (3, 1, 5),
294 _edit_button_spin (_edit_button_adjustment),
295 _insert_note_button_adjustment (3, 1, 5),
296 _insert_note_button_spin (_insert_note_button_adjustment)
298 /* internationalize and prepare for use with combos */
301 for (int i = 0; modifiers[i].name; ++i) {
302 dumb.push_back (S_(modifiers[i].name));
305 set_popdown_strings (_edit_modifier_combo, dumb);
306 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
308 for (int x = 0; modifiers[x].name; ++x) {
309 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
310 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
315 Table* t = manage (new Table (4, 4));
318 Label* l = manage (left_aligned_label (_("Edit using:")));
319 l->set_name ("OptionsLabel");
321 t->attach (*l, 0, 1, 0, 1, FILL | EXPAND, FILL);
322 t->attach (_edit_modifier_combo, 1, 2, 0, 1, FILL | EXPAND, FILL);
324 l = manage (new Label (_("+ button")));
325 l->set_name ("OptionsLabel");
327 t->attach (*l, 3, 4, 0, 1, FILL | EXPAND, FILL);
328 t->attach (_edit_button_spin, 4, 5, 0, 1, FILL | EXPAND, FILL);
330 _edit_button_spin.set_name ("OptionsEntry");
331 _edit_button_adjustment.set_value (Keyboard::edit_button());
332 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
334 set_popdown_strings (_delete_modifier_combo, dumb);
335 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
337 for (int x = 0; modifiers[x].name; ++x) {
338 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
339 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
344 l = manage (left_aligned_label (_("Delete using:")));
345 l->set_name ("OptionsLabel");
347 t->attach (*l, 0, 1, 1, 2, FILL | EXPAND, FILL);
348 t->attach (_delete_modifier_combo, 1, 2, 1, 2, FILL | EXPAND, FILL);
350 l = manage (new Label (_("+ button")));
351 l->set_name ("OptionsLabel");
353 t->attach (*l, 3, 4, 1, 2, FILL | EXPAND, FILL);
354 t->attach (_delete_button_spin, 4, 5, 1, 2, FILL | EXPAND, FILL);
356 _delete_button_spin.set_name ("OptionsEntry");
357 _delete_button_adjustment.set_value (Keyboard::delete_button());
358 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
361 set_popdown_strings (_insert_note_modifier_combo, dumb);
362 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
364 for (int x = 0; modifiers[x].name; ++x) {
365 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
366 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
371 l = manage (left_aligned_label (_("Insert note using:")));
372 l->set_name ("OptionsLabel");
374 t->attach (*l, 0, 1, 2, 3, FILL | EXPAND, FILL);
375 t->attach (_insert_note_modifier_combo, 1, 2, 2, 3, FILL | EXPAND, FILL);
377 l = manage (new Label (_("+ button")));
378 l->set_name ("OptionsLabel");
380 t->attach (*l, 3, 4, 2, 3, FILL | EXPAND, FILL);
381 t->attach (_insert_note_button_spin, 4, 5, 2, 3, FILL | EXPAND, FILL);
383 _insert_note_button_spin.set_name ("OptionsEntry");
384 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
385 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
388 set_popdown_strings (_snap_modifier_combo, dumb);
389 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
391 for (int x = 0; modifiers[x].name; ++x) {
392 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
393 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
398 l = manage (left_aligned_label (_("Toggle snap using:")));
399 l->set_name ("OptionsLabel");
401 t->attach (*l, 0, 1, 3, 4, FILL | EXPAND, FILL);
402 t->attach (_snap_modifier_combo, 1, 2, 3, 4, FILL | EXPAND, FILL);
406 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
407 strs.push_back (bf->first);
410 set_popdown_strings (_keyboard_layout_selector, strs);
411 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
412 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
414 l = manage (left_aligned_label (_("Keyboard layout:")));
415 l->set_name ("OptionsLabel");
417 t->attach (*l, 0, 1, 4, 5, FILL | EXPAND, FILL);
418 t->attach (_keyboard_layout_selector, 1, 2, 4, 5, FILL | EXPAND, FILL);
420 _box->pack_start (*t, false, false);
423 void parameter_changed (string const &)
425 /* XXX: these aren't really config options... */
428 void set_state_from_config ()
430 /* XXX: these aren't really config options... */
435 void bindings_changed ()
437 string const txt = _keyboard_layout_selector.get_active_text();
439 /* XXX: config...? for all this keyboard stuff */
441 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
442 if (txt == i->first) {
443 if (Keyboard::load_keybindings (i->second)) {
444 Keyboard::save_keybindings ();
450 void edit_modifier_chosen ()
452 string const txt = _edit_modifier_combo.get_active_text();
454 for (int i = 0; modifiers[i].name; ++i) {
455 if (txt == _(modifiers[i].name)) {
456 Keyboard::set_edit_modifier (modifiers[i].modifier);
462 void delete_modifier_chosen ()
464 string const txt = _delete_modifier_combo.get_active_text();
466 for (int i = 0; modifiers[i].name; ++i) {
467 if (txt == _(modifiers[i].name)) {
468 Keyboard::set_delete_modifier (modifiers[i].modifier);
474 void insert_note_modifier_chosen ()
476 string const txt = _insert_note_modifier_combo.get_active_text();
478 for (int i = 0; modifiers[i].name; ++i) {
479 if (txt == _(modifiers[i].name)) {
480 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
486 void snap_modifier_chosen ()
488 string const txt = _snap_modifier_combo.get_active_text();
490 for (int i = 0; modifiers[i].name; ++i) {
491 if (txt == _(modifiers[i].name)) {
492 Keyboard::set_snap_modifier (modifiers[i].modifier);
498 void delete_button_changed ()
500 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
503 void edit_button_changed ()
505 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
508 void insert_note_button_changed ()
510 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
513 ComboBoxText _keyboard_layout_selector;
514 ComboBoxText _edit_modifier_combo;
515 ComboBoxText _delete_modifier_combo;
516 ComboBoxText _insert_note_modifier_combo;
517 ComboBoxText _snap_modifier_combo;
518 Adjustment _delete_button_adjustment;
519 SpinButton _delete_button_spin;
520 Adjustment _edit_button_adjustment;
521 SpinButton _edit_button_spin;
522 Adjustment _insert_note_button_adjustment;
523 SpinButton _insert_note_button_spin;
527 class FontScalingOptions : public OptionEditorBox
530 FontScalingOptions (RCConfiguration* c) :
532 _dpi_adjustment (50, 50, 250, 1, 10),
533 _dpi_slider (_dpi_adjustment)
535 _dpi_adjustment.set_value (_rc_config->get_font_scale () / 1024);
537 Label* l = manage (new Label (_("Font scaling:")));
538 l->set_name ("OptionsLabel");
540 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
541 HBox* h = manage (new HBox);
543 h->pack_start (*l, false, false);
544 h->pack_start (_dpi_slider, true, true);
546 _box->pack_start (*h, false, false);
548 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
551 void parameter_changed (string const & p)
553 if (p == "font-scale") {
554 _dpi_adjustment.set_value (_rc_config->get_font_scale() / 1024);
558 void set_state_from_config ()
560 parameter_changed ("font-scale");
567 _rc_config->set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024));
568 /* XXX: should be triggered from the parameter changed signal */
572 RCConfiguration* _rc_config;
573 Adjustment _dpi_adjustment;
577 class BufferingOptions : public OptionEditorBox
580 BufferingOptions (RCConfiguration* c)
582 , _playback_adjustment (5, 1, 60, 1, 4)
583 , _capture_adjustment (5, 1, 60, 1, 4)
584 , _playback_slider (_playback_adjustment)
585 , _capture_slider (_capture_adjustment)
587 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
589 Label* l = manage (new Label (_("Playback (seconds of buffering):")));
590 l->set_name ("OptionsLabel");
592 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
593 HBox* h = manage (new HBox);
595 h->pack_start (*l, false, false);
596 h->pack_start (_playback_slider, true, true);
598 _box->pack_start (*h, false, false);
600 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
602 l = manage (new Label (_("Recording (seconds of buffering):")));
603 l->set_name ("OptionsLabel");
605 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
606 h = manage (new HBox);
608 h->pack_start (*l, false, false);
609 h->pack_start (_capture_slider, true, true);
611 _box->pack_start (*h, false, false);
613 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
614 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
617 void parameter_changed (string const & p)
619 if (p == "playback-buffer-seconds") {
620 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
621 } else if (p == "capture-buffer-seconds") {
622 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
626 void set_state_from_config ()
628 parameter_changed ("playback-buffer-seconds");
629 parameter_changed ("capture-buffer-seconds");
634 void playback_changed ()
636 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
639 void capture_changed ()
641 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
644 RCConfiguration* _rc_config;
645 Adjustment _playback_adjustment;
646 Adjustment _capture_adjustment;
647 HScale _playback_slider;
648 HScale _capture_slider;
651 class ControlSurfacesOptions : public OptionEditorBox
654 ControlSurfacesOptions (Gtk::Window& parent)
657 _store = ListStore::create (_model);
658 _view.set_model (_store);
659 _view.append_column (_("Name"), _model.name);
660 _view.get_column(0)->set_resizable (true);
661 _view.get_column(0)->set_expand (true);
662 _view.append_column_editable (_("Enabled"), _model.enabled);
663 _view.append_column_editable (_("Feedback"), _model.feedback);
665 _box->pack_start (_view, false, false);
667 Label* label = manage (new Label);
668 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
670 _box->pack_start (*label, false, false);
673 ControlProtocolManager& m = ControlProtocolManager::instance ();
674 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
675 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
677 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
678 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
681 void parameter_changed (std::string const &)
686 void set_state_from_config ()
690 ControlProtocolManager& m = ControlProtocolManager::instance ();
691 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
693 if (!(*i)->mandatory) {
694 TreeModel::Row r = *_store->append ();
695 r[_model.name] = (*i)->name;
696 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
697 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
698 r[_model.protocol_info] = *i;
705 void protocol_status_changed (ControlProtocolInfo* cpi) {
707 TreeModel::Children rows = _store->children();
708 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
709 if ((*x)[_model.protocol_info] == cpi) {
710 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
716 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
718 TreeModel::Row r = *i;
720 ControlProtocolInfo* cpi = r[_model.protocol_info];
725 bool const was_enabled = (cpi->protocol != 0);
726 bool const is_enabled = r[_model.enabled];
728 if (was_enabled != is_enabled) {
730 ControlProtocolManager::instance().instantiate (*cpi);
732 Gtk::Window* win = r[_model.editor];
737 ControlProtocolManager::instance().teardown (*cpi);
742 r[_model.editor] = 0;
743 cpi->requested = false;
747 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
748 bool const is_feedback = r[_model.feedback];
750 if (was_feedback != is_feedback && cpi->protocol) {
751 cpi->protocol->set_feedback (is_feedback);
755 void edit_clicked (GdkEventButton* ev)
757 if (ev->type != GDK_2BUTTON_PRESS) {
762 ControlProtocolInfo* cpi;
765 row = *(_view.get_selection()->get_selected());
767 Window* win = row[_model.editor];
768 if (win && !win->is_visible()) {
771 cpi = row[_model.protocol_info];
773 if (cpi && cpi->protocol && cpi->protocol->has_editor ()) {
774 Box* box = (Box*) cpi->protocol->get_gui ();
776 string title = row[_model.name];
777 ArdourWindow* win = new ArdourWindow (_parent, title);
778 win->set_title ("Control Protocol Options");
782 row[_model.editor] = win;
788 class ControlSurfacesModelColumns : public TreeModelColumnRecord
792 ControlSurfacesModelColumns ()
801 TreeModelColumn<string> name;
802 TreeModelColumn<bool> enabled;
803 TreeModelColumn<bool> feedback;
804 TreeModelColumn<ControlProtocolInfo*> protocol_info;
805 TreeModelColumn<Gtk::Window*> editor;
808 Glib::RefPtr<ListStore> _store;
809 ControlSurfacesModelColumns _model;
811 Gtk::Window& _parent;
812 PBD::ScopedConnection protocol_status_connection;
815 /** A class which allows control of visibility of some editor components usign
816 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
817 * which has the correct members, but with null widget pointers. This
818 * class allows the user to set visibility of the members, the details
819 * of which are stored in a configuration variable which can be watched
820 * by parts of the editor that actually contain the widgets whose visibility
821 * is being controlled.
824 class VisibilityOption : public Option
827 /** @param name User-visible name for this group.
828 * @param g `Dummy' VisibilityGroup (as described above).
829 * @param get Method to get the value of the appropriate configuration variable.
830 * @param set Method to set the value of the appropriate configuration variable.
832 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
833 : Option (g->get_state_name(), name)
835 , _visibility_group (g)
839 /* Watch for changes made by the user to our members */
840 _visibility_group->VisibilityChanged.connect_same_thread (
841 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
845 void set_state_from_config ()
847 /* Set our state from the current configuration */
848 _visibility_group->set_state (_get ());
851 void add_to_page (OptionEditorPage* p)
853 _heading.add_to_page (p);
854 add_widget_to_page (p, _visibility_group->list_view ());
857 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
862 /* The user has changed something, so reflect this change
863 in the RCConfiguration.
865 _set (_visibility_group->get_state_value ());
868 OptionEditorHeading _heading;
869 VisibilityGroup* _visibility_group;
870 sigc::slot<std::string> _get;
871 sigc::slot<bool, std::string> _set;
872 PBD::ScopedConnection _visibility_group_connection;
876 RCOptionEditor::RCOptionEditor ()
877 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
878 , _rc_config (Config)
879 , _mixer_strip_visibility ("mixer-strip-visibility")
883 uint32_t hwcpus = hardware_concurrency ();
886 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
888 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
890 _("Signal processing uses"),
891 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
892 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
895 procs->add (-1, _("all but one processor"));
896 procs->add (0, _("all available processors"));
898 for (uint32_t i = 1; i <= hwcpus; ++i) {
899 procs->add (i, string_compose (_("%1 processors"), i));
902 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
904 add_option (_("Misc"), procs);
907 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
909 add_option (_("Misc"), new UndoOptions (_rc_config));
911 add_option (_("Misc"),
913 "verify-remove-last-capture",
914 _("Verify removal of last capture"),
915 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
916 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
919 add_option (_("Misc"),
921 "periodic-safety-backups",
922 _("Make periodic backups of the session file"),
923 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
924 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
927 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
929 add_option (_("Misc"),
931 "only-copy-imported-files",
932 _("Always copy imported files"),
933 sigc::mem_fun (*_rc_config, &RCConfiguration::get_only_copy_imported_files),
934 sigc::mem_fun (*_rc_config, &RCConfiguration::set_only_copy_imported_files)
937 add_option (_("Misc"), new DirectoryOption (
938 X_("default-session-parent-dir"),
939 _("Default folder for new sessions:"),
940 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
941 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
944 add_option (_("Misc"),
945 new SpinOption<uint32_t> (
946 "max-recent-sessions",
947 _("Maximum number of recent sessions"),
948 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
949 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
953 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
955 add_option (_("Misc"), new ClickOptions (_rc_config, this));
957 add_option (_("Misc"),
960 _("Click gain level"),
961 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
962 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
965 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
967 add_option (_("Misc"),
968 new SpinOption<double> (
969 "automation-thinning-factor",
970 _("Thinning factor (larger value => less data)"),
971 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
972 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
980 tsf = new BoolOption (
981 "latched-record-enable",
982 _("Keep record-enable engaged on stop"),
983 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
984 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
986 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
987 add_option (_("Transport"), tsf);
989 tsf = new BoolOption (
990 "stop-recording-on-xrun",
991 _("Stop recording when an xrun occurs"),
992 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
993 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
995 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("<b>When enabled</b> Ardour will stop recording if an over- or underrun is detected by the audio engine"));
996 add_option (_("Transport"), tsf);
998 tsf = new BoolOption (
999 "create-xrun-marker",
1000 _("Create markers where xruns occur"),
1001 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
1002 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
1004 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1005 add_option (_("Transport"), tsf);
1007 tsf = new BoolOption (
1008 "stop-at-session-end",
1009 _("Stop at the end of the session"),
1010 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
1011 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
1013 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("<b>When enabled</b> if Ardour is <b>not recording</b>, it will stop the transport "
1014 "when it reaches the current session end marker\n\n"
1015 "<b>When disabled</b> Ardour will continue to roll past the session end marker at all times"));
1016 add_option (_("Transport"), tsf);
1018 tsf = new BoolOption (
1020 _("Do seamless looping (not possible when slaved to MTC, JACK etc)"),
1021 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
1022 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
1024 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
1025 "preventing any need to do a transport locate at the end of the loop\n\n"
1026 "<b>When disabled</b> looping is done by locating back to the start of the loop when Ardour reaches the end "
1027 "which will often cause a small click or delay"));
1028 add_option (_("Transport"), tsf);
1030 tsf = new BoolOption (
1031 "disable-disarm-during-roll",
1032 _("Disable per-track record disarm while rolling"),
1033 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
1034 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
1036 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"));
1037 add_option (_("Transport"), tsf);
1039 tsf = new BoolOption (
1041 _("12dB gain reduction during fast-forward and fast-rewind"),
1042 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
1043 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
1045 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
1046 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
1047 add_option (_("Transport"), tsf);
1049 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
1051 _sync_source = new ComboOption<SyncSource> (
1053 _("External timecode source"),
1054 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
1055 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
1058 populate_sync_options ();
1059 add_option (_("Transport"), _sync_source);
1061 _sync_framerate = new BoolOption (
1062 "timecode-sync-frame-rate",
1063 _("Match session video frame rate to external timecode"),
1064 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
1065 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
1067 Gtkmm2ext::UI::instance()->set_tip
1068 (_sync_framerate->tip_widget(),
1069 _("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
1070 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
1071 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
1072 "Instead the frame rate indication in the main clock will flash red and Ardour will convert between the external "
1073 "timecode standard and the session standard"));
1075 add_option (_("Transport"), _sync_framerate);
1077 _sync_genlock = new BoolOption (
1078 "timecode-source-is-synced",
1079 _("External timecode is sync locked"),
1080 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
1081 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
1083 Gtkmm2ext::UI::instance()->set_tip
1084 (_sync_genlock->tip_widget(),
1085 _("<b>When enabled</b> indicates that the selected external timecode source shares sync (Black & Burst, Wordclock, etc) with the audio interface"));
1088 add_option (_("Transport"), _sync_genlock);
1090 _ltc_port = new ComboStringOption (
1092 _("LTC incoming port"),
1093 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
1094 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
1097 vector<string> physical_inputs;
1098 physical_inputs.push_back (_("None"));
1099 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
1100 _ltc_port->set_popdown_strings (physical_inputs);
1102 add_option (_("Transport"), _ltc_port);
1105 // TODO; rather disable this button than not compile it..
1106 add_option (_("Transport"),
1109 _("Generate Linear/Longitudinal Time Code"),
1110 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
1111 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
1115 parameter_changed ("sync-source");
1119 add_option (_("Editor"),
1121 "link-region-and-track-selection",
1122 _("Link selection of regions and tracks"),
1123 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_region_and_track_selection),
1124 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_region_and_track_selection)
1127 add_option (_("Editor"),
1129 "automation-follows-regions",
1130 _("Move relevant automation when audio regions are moved"),
1131 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
1132 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
1135 add_option (_("Editor"),
1137 "show-track-meters",
1138 _("Show meters on tracks in the editor"),
1139 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_track_meters),
1140 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_track_meters)
1143 add_option (_("Editor"),
1145 "use-overlap-equivalency",
1146 _("Use overlap equivalency for regions"),
1147 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
1148 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
1151 add_option (_("Editor"),
1153 "rubberbanding-snaps-to-grid",
1154 _("Make rubberband selection rectangle snap to the grid"),
1155 sigc::mem_fun (*_rc_config, &RCConfiguration::get_rubberbanding_snaps_to_grid),
1156 sigc::mem_fun (*_rc_config, &RCConfiguration::set_rubberbanding_snaps_to_grid)
1159 add_option (_("Editor"),
1162 _("Show waveforms in regions"),
1163 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms),
1164 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms)
1167 add_option (_("Editor"),
1168 new BoolComboOption (
1169 "show-region-gain-envelopes",
1170 _("Show gain envelopes in audio regions"),
1172 _("only in region gain mode"),
1173 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_region_gain),
1174 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_region_gain)
1177 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
1179 _("Waveform scale"),
1180 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_scale),
1181 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_scale)
1184 wfs->add (Linear, _("linear"));
1185 wfs->add (Logarithmic, _("logarithmic"));
1187 add_option (_("Editor"), wfs);
1189 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
1191 _("Waveform shape"),
1192 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_shape),
1193 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_shape)
1196 wfsh->add (Traditional, _("traditional"));
1197 wfsh->add (Rectified, _("rectified"));
1199 add_option (_("Editor"), wfsh);
1201 add_option (_("Editor"),
1203 "show-waveforms-while-recording",
1204 _("Show waveforms for audio while it is being recorded"),
1205 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms_while_recording),
1206 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms_while_recording)
1209 add_option (_("Editor"),
1212 _("Show zoom toolbar"),
1213 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_zoom_tools),
1214 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_zoom_tools)
1217 add_option (_("Editor"),
1219 "color-regions-using-track-color",
1220 _("Color regions using their track's color"),
1221 sigc::mem_fun (*_rc_config, &RCConfiguration::get_color_regions_using_track_color),
1222 sigc::mem_fun (*_rc_config, &RCConfiguration::set_color_regions_using_track_color)
1225 add_option (_("Editor"),
1227 "update-editor-during-summary-drag",
1228 _("Update editor window during drags of the summary"),
1229 sigc::mem_fun (*_rc_config, &RCConfiguration::get_update_editor_during_summary_drag),
1230 sigc::mem_fun (*_rc_config, &RCConfiguration::set_update_editor_during_summary_drag)
1233 add_option (_("Editor"),
1235 "sync-all-route-ordering",
1236 _("Synchronise editor and mixer track order"),
1237 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_all_route_ordering),
1238 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_all_route_ordering)
1241 add_option (_("Editor"),
1243 "link-editor-and-mixer-selection",
1244 _("Synchronise editor and mixer selection"),
1245 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_editor_and_mixer_selection),
1246 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_editor_and_mixer_selection)
1249 add_option (_("Editor"),
1252 _("Name new markers"),
1253 sigc::mem_fun (*_rc_config, &RCConfiguration::get_name_new_markers),
1254 sigc::mem_fun (*_rc_config, &RCConfiguration::set_name_new_markers)
1257 add_option (_("Editor"),
1259 "autoscroll-editor",
1260 _("Auto-scroll editor window when dragging near its edges"),
1261 sigc::mem_fun (*_rc_config, &RCConfiguration::get_autoscroll_editor),
1262 sigc::mem_fun (*_rc_config, &RCConfiguration::set_autoscroll_editor)
1267 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
1269 add_option (_("Audio"), new BufferingOptions (_rc_config));
1271 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
1273 add_option (_("Audio"),
1276 _("Use a monitor bus (allows AFL/PFL and more control)"),
1277 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_monitor_bus),
1278 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_monitor_bus)
1281 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
1283 _("Record monitoring handled by"),
1284 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
1285 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
1289 /* no JACK monitoring on CoreAudio */
1290 if (AudioEngine::instance()->can_request_hardware_monitoring()) {
1291 mm->add (HardwareMonitoring, _("JACK"));
1294 mm->add (SoftwareMonitoring, _("ardour"));
1295 mm->add (ExternalMonitoring, _("audio hardware"));
1297 add_option (_("Audio"), mm);
1299 add_option (_("Audio"),
1301 "tape-machine-mode",
1302 _("Tape machine mode"),
1303 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
1304 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
1307 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
1309 add_option (_("Audio"),
1311 "auto-connect-standard-busses",
1312 _("Auto-connect master/monitor busses"),
1313 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
1314 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
1317 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
1318 "input-auto-connect",
1319 _("Connect track inputs"),
1320 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
1321 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
1324 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
1325 iac->add (ManualConnect, _("manually"));
1327 add_option (_("Audio"), iac);
1329 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
1330 "output-auto-connect",
1331 _("Connect track and bus outputs"),
1332 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
1333 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
1336 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
1337 oac->add (AutoConnectMaster, _("automatically to master bus"));
1338 oac->add (ManualConnect, _("manually"));
1340 add_option (_("Audio"), oac);
1342 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
1344 add_option (_("Audio"),
1346 "denormal-protection",
1347 _("Use DC bias to protect against denormals"),
1348 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
1349 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
1352 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
1354 _("Processor handling"),
1355 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
1356 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
1359 dm->add (DenormalNone, _("no processor handling"));
1363 if (fpu.has_flush_to_zero()) {
1364 dm->add (DenormalFTZ, _("use FlushToZero"));
1367 if (fpu.has_denormals_are_zero()) {
1368 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
1371 if (fpu.has_flush_to_zero() && fpu.has_denormals_are_zero()) {
1372 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
1375 add_option (_("Audio"), dm);
1377 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
1379 add_option (_("Audio"),
1381 "plugins-stop-with-transport",
1382 _("Silence plugins when the transport is stopped"),
1383 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
1384 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
1387 add_option (_("Audio"),
1389 "do-not-record-plugins",
1390 _("Disable plugins during recording"),
1391 sigc::mem_fun (*_rc_config, &RCConfiguration::get_do_not_record_plugins),
1392 sigc::mem_fun (*_rc_config, &RCConfiguration::set_do_not_record_plugins)
1395 add_option (_("Audio"),
1397 "new-plugins-active",
1398 _("Make new plugins active"),
1399 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
1400 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
1403 add_option (_("Audio"),
1405 "auto-analyse-audio",
1406 _("Enable automatic analysis of audio"),
1407 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
1408 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
1411 add_option (_("Audio"),
1413 "replicate-missing-region-channels",
1414 _("Replicate missing region channels"),
1415 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
1416 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
1421 add_option (_("Solo / mute"),
1424 _("Solo-in-place mute cut (dB)"),
1425 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
1426 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
1429 _solo_control_is_listen_control = new BoolOption (
1430 "solo-control-is-listen-control",
1431 _("Solo controls are Listen controls"),
1432 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
1433 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
1436 add_option (_("Solo / mute"), _solo_control_is_listen_control);
1438 _listen_position = new ComboOption<ListenPosition> (
1440 _("Listen Position"),
1441 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
1442 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
1445 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
1446 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
1448 add_option (_("Solo / mute"), _listen_position);
1450 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
1452 _("PFL signals come from"),
1453 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
1454 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
1457 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
1458 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
1460 add_option (_("Solo / mute"), pp);
1462 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
1464 _("AFL signals come from"),
1465 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
1466 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
1469 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
1470 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
1472 add_option (_("Solo / mute"), pa);
1474 parameter_changed ("use-monitor-bus");
1476 add_option (_("Solo / mute"),
1479 _("Exclusive solo"),
1480 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
1481 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
1484 add_option (_("Solo / mute"),
1487 _("Show solo muting"),
1488 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
1489 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
1492 add_option (_("Solo / mute"),
1494 "solo-mute-override",
1495 _("Soloing overrides muting"),
1496 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
1497 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
1500 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
1502 add_option (_("Solo / mute"),
1504 "mute-affects-pre-fader",
1505 _("Mute affects pre-fader sends"),
1506 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
1507 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
1510 add_option (_("Solo / mute"),
1512 "mute-affects-post-fader",
1513 _("Mute affects post-fader sends"),
1514 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
1515 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
1518 add_option (_("Solo / mute"),
1520 "mute-affects-control-outs",
1521 _("Mute affects control outputs"),
1522 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
1523 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
1526 add_option (_("Solo / mute"),
1528 "mute-affects-main-outs",
1529 _("Mute affects main outputs"),
1530 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
1531 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
1534 add_option (_("MIDI"),
1537 _("Send MIDI Clock"),
1538 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
1539 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
1542 add_option (_("MIDI"),
1545 _("Send MIDI Time Code"),
1546 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
1547 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
1550 add_option (_("MIDI"),
1551 new SpinOption<int> (
1552 "mtc-qf-speed-tolerance",
1553 _("Percentage either side of normal transport speed to transmit MTC"),
1554 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
1555 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
1559 add_option (_("MIDI"),
1562 _("Obey MIDI Machine Control commands"),
1563 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
1564 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
1567 add_option (_("MIDI"),
1570 _("Send MIDI Machine Control commands"),
1571 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
1572 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
1575 add_option (_("MIDI"),
1578 _("Send MIDI control feedback"),
1579 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
1580 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
1583 add_option (_("MIDI"),
1584 new SpinOption<uint8_t> (
1585 "mmc-receive-device-id",
1586 _("Inbound MMC device ID"),
1587 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
1588 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
1592 add_option (_("MIDI"),
1593 new SpinOption<uint8_t> (
1594 "mmc-send-device-id",
1595 _("Outbound MMC device ID"),
1596 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
1597 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
1601 add_option (_("MIDI"),
1602 new SpinOption<int32_t> (
1603 "initial-program-change",
1604 _("Initial program change"),
1605 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
1606 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
1610 add_option (_("MIDI"),
1612 "diplay-first-midi-bank-as-zero",
1613 _("Display first MIDI bank/program as 0"),
1614 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
1615 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
1618 add_option (_("MIDI"),
1620 "never-display-periodic-midi",
1621 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
1622 sigc::mem_fun (*_rc_config, &RCConfiguration::get_never_display_periodic_midi),
1623 sigc::mem_fun (*_rc_config, &RCConfiguration::set_never_display_periodic_midi)
1626 add_option (_("MIDI"),
1629 _("Sound MIDI notes as they are selected"),
1630 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sound_midi_notes),
1631 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sound_midi_notes)
1634 /* USER INTERACTION */
1636 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
1638 add_option (_("User interaction"), new KeyboardOptions);
1640 add_option (_("User interaction"), new OptionEditorHeading (_("Control surfaces")));
1642 add_option (_("User interaction"), new ControlSurfacesOptions (*this));
1644 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
1646 _("Control surface remote ID"),
1647 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
1648 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
1651 rm->add (UserOrdered, _("assigned by user"));
1652 rm->add (MixerOrdered, _("follows order of mixer"));
1653 rm->add (EditorOrdered, _("follows order of editor"));
1655 add_option (_("User interaction"), rm);
1659 add_option (S_("GUI"),
1662 _("Graphically indicate mouse pointer hovering over various widgets"),
1663 sigc::mem_fun (*_rc_config, &RCConfiguration::get_widget_prelight),
1664 sigc::mem_fun (*_rc_config, &RCConfiguration::set_widget_prelight)
1668 /* font scaling does nothing with GDK/Quartz */
1669 add_option (S_("GUI"), new FontScalingOptions (_rc_config));
1671 add_option (S_("GUI"),
1673 "use-own-plugin-gui",
1674 _("Use plugins' own interfaces instead of Ardour's"),
1675 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_plugin_own_gui),
1676 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_plugin_own_gui)
1679 /* The names of these controls must be the same as those given in MixerStrip
1680 for the actual widgets being controlled.
1682 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
1683 _mixer_strip_visibility.add (0, X_("SoloSafe"), _("Solo Safe"));
1684 _mixer_strip_visibility.add (0, X_("SoloIsolated"), _("Solo Isolated"));
1685 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
1686 _mixer_strip_visibility.add (0, X_("Group"), _("Group"));
1687 _mixer_strip_visibility.add (0, X_("MeterPoint"), _("Meter Point"));
1691 new VisibilityOption (
1693 &_mixer_strip_visibility,
1694 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mixer_strip_visibility),
1695 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mixer_strip_visibility)
1699 add_option (S_("GUI"),
1701 "default-narrow_ms",
1702 _("Use narrow strips in the mixer by default"),
1703 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_narrow_ms),
1704 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_narrow_ms)
1707 add_option (S_("GUI"), new OptionEditorHeading (_("Metering")));
1709 ComboOption<float>* mht = new ComboOption<float> (
1711 _("Meter hold time"),
1712 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_hold),
1713 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_hold)
1716 mht->add (MeterHoldOff, _("off"));
1717 mht->add (MeterHoldShort, _("short"));
1718 mht->add (MeterHoldMedium, _("medium"));
1719 mht->add (MeterHoldLong, _("long"));
1721 add_option (S_("GUI"), mht);
1723 ComboOption<float>* mfo = new ComboOption<float> (
1725 _("Meter fall-off"),
1726 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
1727 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
1730 mfo->add (METER_FALLOFF_OFF, _("off"));
1731 mfo->add (METER_FALLOFF_SLOWEST, _("slowest"));
1732 mfo->add (METER_FALLOFF_SLOW, _("slow"));
1733 mfo->add (METER_FALLOFF_MEDIUM, _("medium"));
1734 mfo->add (METER_FALLOFF_FAST, _("fast"));
1735 mfo->add (METER_FALLOFF_FASTER, _("faster"));
1736 mfo->add (METER_FALLOFF_FASTEST, _("fastest"));
1738 add_option (S_("GUI"), mfo);
1742 RCOptionEditor::parameter_changed (string const & p)
1744 OptionEditor::parameter_changed (p);
1746 if (p == "use-monitor-bus") {
1747 bool const s = Config->get_use_monitor_bus ();
1749 /* we can't use this if we don't have a monitor bus */
1750 Config->set_solo_control_is_listen_control (false);
1752 _solo_control_is_listen_control->set_sensitive (s);
1753 _listen_position->set_sensitive (s);
1754 } else if (p == "sync-source") {
1755 switch(Config->get_sync_source()) {
1758 _sync_genlock->set_sensitive (true);
1759 _sync_framerate->set_sensitive (true);
1762 _sync_genlock->set_sensitive (false);
1763 _sync_framerate->set_sensitive (false);
1770 RCOptionEditor::populate_sync_options ()
1772 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
1774 _sync_source->clear ();
1776 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
1777 _sync_source->add (*i, sync_source_to_string (*i));