2 #include "gtk2ardour-config.h"
5 #include <gtkmm/liststore.h>
6 #include <gtkmm/stock.h>
7 #include <gtkmm/scale.h>
8 #include <gtkmm2ext/utils.h>
9 #include <gtkmm2ext/slider_controller.h>
14 #include "midi++/manager.h"
16 #include "ardour/audioengine.h"
17 #include "ardour/dB.h"
18 #include "ardour/rc_configuration.h"
19 #include "ardour/control_protocol_manager.h"
20 #include "control_protocol/control_protocol.h"
22 #include "gui_thread.h"
23 #include "midi_tracer.h"
24 #include "rc_option_editor.h"
26 #include "midi_port_dialog.h"
33 using namespace Gtkmm2ext;
35 using namespace ARDOUR;
37 class ClickOptions : public OptionEditorBox
40 ClickOptions (RCConfiguration* c, ArdourDialog* p)
44 Table* t = manage (new Table (2, 3));
47 Label* l = manage (new Label (_("Click audio file:")));
48 l->set_alignment (0, 0.5);
49 t->attach (*l, 0, 1, 0, 1, FILL);
50 t->attach (_click_path_entry, 1, 2, 0, 1, FILL);
51 Button* b = manage (new Button (_("Browse...")));
52 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
53 t->attach (*b, 2, 3, 0, 1, FILL);
55 l = manage (new Label (_("Click emphasis audio file:")));
56 l->set_alignment (0, 0.5);
57 t->attach (*l, 0, 1, 1, 2, FILL);
58 t->attach (_click_emphasis_path_entry, 1, 2, 1, 2, FILL);
59 b = manage (new Button (_("Browse...")));
60 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
61 t->attach (*b, 2, 3, 1, 2, FILL);
63 _box->pack_start (*t, false, false);
66 void parameter_changed (string const & p)
68 if (p == "click-sound") {
69 _click_path_entry.set_text (_rc_config->get_click_sound());
70 } else if (p == "click-emphasis-sound") {
71 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
75 void set_state_from_config ()
77 parameter_changed ("click-sound");
78 parameter_changed ("click-emphasis-sound");
83 void click_browse_clicked ()
85 SoundFileChooser sfdb (*_parent, _("Choose Click"));
90 if (sfdb.run () == RESPONSE_OK) {
91 click_chosen (sfdb.get_filename());
95 void click_chosen (string const & path)
97 _click_path_entry.set_text (path);
98 _rc_config->set_click_sound (path);
101 void click_emphasis_browse_clicked ()
103 SoundFileChooser sfdb (*_parent, _("Choose Click Emphasis"));
108 if (sfdb.run () == RESPONSE_OK) {
109 click_emphasis_chosen (sfdb.get_filename());
113 void click_emphasis_chosen (string const & path)
115 _click_emphasis_path_entry.set_text (path);
116 _rc_config->set_click_emphasis_sound (path);
119 RCConfiguration* _rc_config;
120 ArdourDialog* _parent;
121 Entry _click_path_entry;
122 Entry _click_emphasis_path_entry;
125 class UndoOptions : public OptionEditorBox
128 UndoOptions (RCConfiguration* c) :
130 _limit_undo_button (_("Limit undo history to")),
131 _save_undo_button (_("Save undo history of"))
133 Table* t = new Table (2, 3);
136 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
137 _limit_undo_spin.set_range (0, 512);
138 _limit_undo_spin.set_increments (1, 10);
139 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
140 Label* l = manage (new Label (_("commands")));
141 l->set_alignment (0, 0.5);
142 t->attach (*l, 2, 3, 0, 1);
144 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
145 _save_undo_spin.set_range (0, 512);
146 _save_undo_spin.set_increments (1, 10);
147 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
148 l = manage (new Label (_("commands")));
149 l->set_alignment (0, 0.5);
150 t->attach (*l, 2, 3, 1, 2);
152 _box->pack_start (*t);
154 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
155 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
156 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
157 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
160 void parameter_changed (string const & p)
162 if (p == "history-depth") {
163 int32_t const d = _rc_config->get_history_depth();
164 _limit_undo_button.set_active (d != 0);
165 _limit_undo_spin.set_sensitive (d != 0);
166 _limit_undo_spin.set_value (d);
167 } else if (p == "save-history") {
168 bool const x = _rc_config->get_save_history ();
169 _save_undo_button.set_active (x);
170 _save_undo_spin.set_sensitive (x);
171 } else if (p == "save-history-depth") {
172 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
176 void set_state_from_config ()
178 parameter_changed ("save-history");
179 parameter_changed ("history-depth");
180 parameter_changed ("save-history-depth");
183 void limit_undo_toggled ()
185 bool const x = _limit_undo_button.get_active ();
186 _limit_undo_spin.set_sensitive (x);
187 int32_t const n = x ? 16 : 0;
188 _limit_undo_spin.set_value (n);
189 _rc_config->set_history_depth (n);
192 void limit_undo_changed ()
194 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
197 void save_undo_toggled ()
199 bool const x = _save_undo_button.get_active ();
200 _rc_config->set_save_history (x);
203 void save_undo_changed ()
205 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
209 RCConfiguration* _rc_config;
210 CheckButton _limit_undo_button;
211 SpinButton _limit_undo_spin;
212 CheckButton _save_undo_button;
213 SpinButton _save_undo_spin;
218 static const struct {
230 { "Shift", GDK_SHIFT_MASK },
231 { "Command", GDK_META_MASK },
232 { "Control", GDK_CONTROL_MASK },
233 { "Option", GDK_MOD1_MASK },
234 { "Command-Shift", GDK_META_MASK|GDK_SHIFT_MASK },
235 { "Command-Option", GDK_MOD1_MASK|GDK_META_MASK },
236 { "Shift-Option", GDK_SHIFT_MASK|GDK_MOD1_MASK },
237 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_META_MASK },
240 { "Shift", GDK_SHIFT_MASK },
241 { "Control", GDK_CONTROL_MASK },
242 { "Alt (Mod1)", GDK_MOD1_MASK },
243 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
244 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
245 { "Shift-Alt", GDK_SHIFT_MASK|GDK_MOD1_MASK },
246 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
247 { "Mod2", GDK_MOD2_MASK },
248 { "Mod3", GDK_MOD3_MASK },
249 { "Mod4", GDK_MOD4_MASK },
250 { "Mod5", GDK_MOD5_MASK },
256 class KeyboardOptions : public OptionEditorBox
260 _delete_button_adjustment (3, 1, 12),
261 _delete_button_spin (_delete_button_adjustment),
262 _edit_button_adjustment (3, 1, 5),
263 _edit_button_spin (_edit_button_adjustment)
266 /* internationalize and prepare for use with combos */
269 for (int i = 0; modifiers[i].name; ++i) {
270 dumb.push_back (_(modifiers[i].name));
273 set_popdown_strings (_edit_modifier_combo, dumb);
274 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
276 for (int x = 0; modifiers[x].name; ++x) {
277 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
278 _edit_modifier_combo.set_active_text (_(modifiers[x].name));
283 Table* t = manage (new Table (4, 4));
286 Label* l = manage (new Label (_("Edit using:")));
287 l->set_name ("OptionsLabel");
288 l->set_alignment (0, 0.5);
290 t->attach (*l, 0, 1, 0, 1, FILL | EXPAND, FILL);
291 t->attach (_edit_modifier_combo, 1, 2, 0, 1, FILL | EXPAND, FILL);
293 l = manage (new Label (_("+ button")));
294 l->set_name ("OptionsLabel");
296 t->attach (*l, 3, 4, 0, 1, FILL | EXPAND, FILL);
297 t->attach (_edit_button_spin, 4, 5, 0, 1, FILL | EXPAND, FILL);
299 _edit_button_spin.set_name ("OptionsEntry");
300 _edit_button_adjustment.set_value (Keyboard::edit_button());
301 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
303 set_popdown_strings (_delete_modifier_combo, dumb);
304 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
306 for (int x = 0; modifiers[x].name; ++x) {
307 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
308 _delete_modifier_combo.set_active_text (_(modifiers[x].name));
313 l = manage (new Label (_("Delete using:")));
314 l->set_name ("OptionsLabel");
315 l->set_alignment (0, 0.5);
317 t->attach (*l, 0, 1, 1, 2, FILL | EXPAND, FILL);
318 t->attach (_delete_modifier_combo, 1, 2, 1, 2, FILL | EXPAND, FILL);
320 l = manage (new Label (_("+ button")));
321 l->set_name ("OptionsLabel");
323 t->attach (*l, 3, 4, 1, 2, FILL | EXPAND, FILL);
324 t->attach (_delete_button_spin, 4, 5, 1, 2, FILL | EXPAND, FILL);
326 _delete_button_spin.set_name ("OptionsEntry");
327 _delete_button_adjustment.set_value (Keyboard::delete_button());
328 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
330 set_popdown_strings (_snap_modifier_combo, dumb);
331 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
333 for (int x = 0; modifiers[x].name; ++x) {
334 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
335 _snap_modifier_combo.set_active_text (_(modifiers[x].name));
340 l = manage (new Label (_("Toggle snap using:")));
341 l->set_name ("OptionsLabel");
342 l->set_alignment (0, 0.5);
344 t->attach (*l, 0, 1, 2, 3, FILL | EXPAND, FILL);
345 t->attach (_snap_modifier_combo, 1, 2, 2, 3, FILL | EXPAND, FILL);
349 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
350 strs.push_back (bf->first);
353 set_popdown_strings (_keyboard_layout_selector, strs);
354 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
355 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
357 l = manage (new Label (_("Keyboard layout:")));
358 l->set_name ("OptionsLabel");
359 l->set_alignment (0, 0.5);
361 t->attach (*l, 0, 1, 3, 4, FILL | EXPAND, FILL);
362 t->attach (_keyboard_layout_selector, 1, 2, 3, 4, FILL | EXPAND, FILL);
364 _box->pack_start (*t, false, false);
367 void parameter_changed (string const &)
369 /* XXX: these aren't really config options... */
372 void set_state_from_config ()
374 /* XXX: these aren't really config options... */
379 void bindings_changed ()
381 string const txt = _keyboard_layout_selector.get_active_text();
383 /* XXX: config...? for all this keyboard stuff */
385 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
386 if (txt == i->first) {
387 if (Keyboard::load_keybindings (i->second)) {
388 Keyboard::save_keybindings ();
394 void edit_modifier_chosen ()
396 string const txt = _edit_modifier_combo.get_active_text();
398 for (int i = 0; modifiers[i].name; ++i) {
399 if (txt == _(modifiers[i].name)) {
400 Keyboard::set_edit_modifier (modifiers[i].modifier);
406 void delete_modifier_chosen ()
408 string const txt = _delete_modifier_combo.get_active_text();
410 for (int i = 0; modifiers[i].name; ++i) {
411 if (txt == _(modifiers[i].name)) {
412 Keyboard::set_delete_modifier (modifiers[i].modifier);
418 void snap_modifier_chosen ()
420 string const txt = _snap_modifier_combo.get_active_text();
422 for (int i = 0; modifiers[i].name; ++i) {
423 if (txt == _(modifiers[i].name)) {
424 Keyboard::set_snap_modifier (modifiers[i].modifier);
430 void delete_button_changed ()
432 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
435 void edit_button_changed ()
437 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
440 ComboBoxText _keyboard_layout_selector;
441 ComboBoxText _edit_modifier_combo;
442 ComboBoxText _delete_modifier_combo;
443 ComboBoxText _snap_modifier_combo;
444 Adjustment _delete_button_adjustment;
445 SpinButton _delete_button_spin;
446 Adjustment _edit_button_adjustment;
447 SpinButton _edit_button_spin;
450 class FontScalingOptions : public OptionEditorBox
453 FontScalingOptions (RCConfiguration* c) :
455 _dpi_adjustment (50, 50, 250, 1, 10),
456 _dpi_slider (_dpi_adjustment)
458 _dpi_adjustment.set_value (_rc_config->get_font_scale () / 1024);
460 Label* l = manage (new Label (_("Font scaling:")));
461 l->set_name ("OptionsLabel");
463 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
464 HBox* h = manage (new HBox);
466 h->pack_start (*l, false, false);
467 h->pack_start (_dpi_slider, true, true);
469 _box->pack_start (*h, false, false);
471 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
474 void parameter_changed (string const & p)
476 if (p == "font-scale") {
477 _dpi_adjustment.set_value (_rc_config->get_font_scale() / 1024);
481 void set_state_from_config ()
483 parameter_changed ("font-scale");
490 _rc_config->set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024));
491 /* XXX: should be triggered from the parameter changed signal */
495 RCConfiguration* _rc_config;
496 Adjustment _dpi_adjustment;
500 class BufferingOptions : public OptionEditorBox
503 BufferingOptions (RCConfiguration* c)
505 , _playback_adjustment (5, 1, 60, 1, 4)
506 , _capture_adjustment (5, 1, 60, 1, 4)
507 , _playback_slider (_playback_adjustment)
508 , _capture_slider (_capture_adjustment)
510 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
512 Label* l = manage (new Label (_("Playback (seconds of buffering):")));
513 l->set_name ("OptionsLabel");
515 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
516 HBox* h = manage (new HBox);
518 h->pack_start (*l, false, false);
519 h->pack_start (_playback_slider, true, true);
521 _box->pack_start (*h, false, false);
523 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
525 l = manage (new Label (_("Recording (seconds of buffering):")));
526 l->set_name ("OptionsLabel");
528 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
529 h = manage (new HBox);
531 h->pack_start (*l, false, false);
532 h->pack_start (_capture_slider, true, true);
534 _box->pack_start (*h, false, false);
536 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
537 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
540 void parameter_changed (string const & p)
542 if (p == "playback-buffer-seconds") {
543 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
544 } else if (p == "capture-buffer-seconds") {
545 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
549 void set_state_from_config ()
551 parameter_changed ("playback-buffer-seconds");
552 parameter_changed ("capture-buffer-seconds");
557 void playback_changed ()
559 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
562 void capture_changed ()
564 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
567 RCConfiguration* _rc_config;
568 Adjustment _playback_adjustment;
569 Adjustment _capture_adjustment;
570 HScale _playback_slider;
571 HScale _capture_slider;
574 class ControlSurfacesOptions : public OptionEditorBox
577 ControlSurfacesOptions (ArdourDialog& parent)
580 _store = ListStore::create (_model);
581 _view.set_model (_store);
582 _view.append_column (_("Name"), _model.name);
583 _view.get_column(0)->set_resizable (true);
584 _view.get_column(0)->set_expand (true);
585 _view.append_column_editable (_("Enabled"), _model.enabled);
586 _view.append_column_editable (_("Feedback"), _model.feedback);
588 _box->pack_start (_view, false, false);
590 Label* label = manage (new Label);
591 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
593 _box->pack_start (*label, false, false);
596 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::model_changed));
597 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
600 void parameter_changed (std::string const &)
605 void set_state_from_config ()
609 ControlProtocolManager& m = ControlProtocolManager::instance ();
610 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
612 if (!(*i)->mandatory) {
613 TreeModel::Row r = *_store->append ();
614 r[_model.name] = (*i)->name;
615 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
616 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
617 r[_model.protocol_info] = *i;
624 void model_changed (TreeModel::Path const &, TreeModel::iterator const & i)
626 TreeModel::Row r = *i;
628 ControlProtocolInfo* cpi = r[_model.protocol_info];
633 bool const was_enabled = (cpi->protocol != 0);
634 bool const is_enabled = r[_model.enabled];
636 if (was_enabled != is_enabled) {
638 ControlProtocolManager::instance().instantiate (*cpi);
640 ControlProtocolManager::instance().teardown (*cpi);
644 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
645 bool const is_feedback = r[_model.feedback];
647 if (was_feedback != is_feedback && cpi->protocol) {
648 cpi->protocol->set_feedback (is_feedback);
652 void edit_clicked (GdkEventButton* ev)
654 if (ev->type != GDK_2BUTTON_PRESS) {
659 ControlProtocolInfo* cpi;
662 row = *(_view.get_selection()->get_selected());
664 Window* win = row[_model.editor];
665 if (win && !win->is_visible()) {
668 cpi = row[_model.protocol_info];
670 if (cpi && cpi->protocol && cpi->protocol->has_editor ()) {
671 Box* box = (Box*) cpi->protocol->get_gui ();
673 string title = row[_model.name];
674 ArdourDialog* win = new ArdourDialog (_parent, title);
675 win->get_vbox()->pack_start (*box, false, false);
678 row[_model.editor] = win;
684 class ControlSurfacesModelColumns : public TreeModelColumnRecord
688 ControlSurfacesModelColumns ()
697 TreeModelColumn<string> name;
698 TreeModelColumn<bool> enabled;
699 TreeModelColumn<bool> feedback;
700 TreeModelColumn<ControlProtocolInfo*> protocol_info;
701 TreeModelColumn<Gtk::Window*> editor;
704 Glib::RefPtr<ListStore> _store;
705 ControlSurfacesModelColumns _model;
707 Gtk::Window& _parent;
711 RCOptionEditor::RCOptionEditor ()
712 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
713 , _rc_config (Config)
717 uint32_t hwcpus = hardware_concurrency ();
720 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
722 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
724 _("Signal processing uses"),
725 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
726 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
729 procs->add (-1, _("all but one processor"));
730 procs->add (0, _("all available processors"));
732 for (uint32_t i = 2; i < hwcpus; ++i) {
733 procs->add (1, string_compose (_("%1 processors"), i));
736 add_option (_("Misc"), procs);
739 add_option (_("Misc"), new OptionEditorHeading (_("Metering")));
741 ComboOption<float>* mht = new ComboOption<float> (
743 _("Meter hold time"),
744 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_hold),
745 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_hold)
748 mht->add (MeterHoldOff, _("off"));
749 mht->add (MeterHoldShort, _("short"));
750 mht->add (MeterHoldMedium, _("medium"));
751 mht->add (MeterHoldLong, _("long"));
753 add_option (_("Misc"), mht);
755 ComboOption<float>* mfo = new ComboOption<float> (
758 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
759 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
762 mfo->add (METER_FALLOFF_OFF, _("off"));
763 mfo->add (METER_FALLOFF_SLOWEST, _("slowest"));
764 mfo->add (METER_FALLOFF_SLOW, _("slow"));
765 mfo->add (METER_FALLOFF_MEDIUM, _("medium"));
766 mfo->add (METER_FALLOFF_FAST, _("fast"));
767 mfo->add (METER_FALLOFF_FASTER, _("faster"));
768 mfo->add (METER_FALLOFF_FASTEST, _("fastest"));
770 add_option (_("Misc"), mfo);
772 add_option (_("Misc"), new OptionEditorHeading (_("Undo")));
774 add_option (_("Misc"), new UndoOptions (_rc_config));
776 add_option (_("Misc"), new OptionEditorHeading (_("Misc")));
779 /* font scaling does nothing with GDK/Quartz */
780 add_option (_("Misc"), new FontScalingOptions (_rc_config));
783 add_option (_("Misc"),
785 "verify-remove-last-capture",
786 _("Verify removal of last capture"),
787 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
788 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
791 add_option (_("Misc"),
793 "periodic-safety-backups",
794 _("Make periodic backups of the session file"),
795 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
796 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
799 add_option (_("Misc"),
801 "sync-all-route-ordering",
802 _("Syncronise editor and mixer track order"),
803 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_all_route_ordering),
804 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_all_route_ordering)
807 add_option (_("Misc"),
809 "only-copy-imported-files",
810 _("Always copy imported files"),
811 sigc::mem_fun (*_rc_config, &RCConfiguration::get_only_copy_imported_files),
812 sigc::mem_fun (*_rc_config, &RCConfiguration::set_only_copy_imported_files)
815 add_option (_("Misc"),
818 _("Use narrow mixer strips"),
819 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_narrow_ms),
820 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_narrow_ms)
823 add_option (_("Misc"),
826 _("Name new markers"),
827 sigc::mem_fun (*_rc_config, &RCConfiguration::get_name_new_markers),
828 sigc::mem_fun (*_rc_config, &RCConfiguration::set_name_new_markers)
831 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
833 add_option (_("Misc"), new ClickOptions (_rc_config, this));
837 add_option (_("Transport"),
839 "latched-record-enable",
840 _("Keep record-enable engaged on stop"),
841 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
842 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
845 add_option (_("Transport"),
847 "stop-recording-on-xrun",
848 _("Stop recording when an xrun occurs"),
849 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
850 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
853 add_option (_("Transport"),
855 "create-xrun-marker",
856 _("Create markers where xruns occur"),
857 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
858 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
861 add_option (_("Transport"),
863 "stop-at-session-end",
864 _("Stop at the end of the session"),
865 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
866 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
869 add_option (_("Transport"),
872 _("Do seamless looping (not possible when slaved to MTC, JACK etc)"),
873 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
874 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
877 add_option (_("Transport"),
879 "primary-clock-delta-edit-cursor",
880 _("Primary clock delta to edit cursor"),
881 sigc::mem_fun (*_rc_config, &RCConfiguration::get_primary_clock_delta_edit_cursor),
882 sigc::mem_fun (*_rc_config, &RCConfiguration::set_primary_clock_delta_edit_cursor)
885 add_option (_("Transport"),
887 "secondary-clock-delta-edit-cursor",
888 _("Secondary clock delta to edit cursor"),
889 sigc::mem_fun (*_rc_config, &RCConfiguration::get_secondary_clock_delta_edit_cursor),
890 sigc::mem_fun (*_rc_config, &RCConfiguration::set_secondary_clock_delta_edit_cursor)
893 add_option (_("Transport"),
895 "disable-disarm-during-roll",
896 _("Disable per-track record disarm while rolling"),
897 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
898 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
901 add_option (_("Transport"),
904 _("12dB gain reduction during fast-forward and fast-rewind"),
905 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
906 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
911 add_option (_("Editor"),
913 "link-region-and-track-selection",
914 _("Link selection of regions and tracks"),
915 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_region_and_track_selection),
916 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_region_and_track_selection)
919 add_option (_("Editor"),
921 "automation-follows-regions",
922 _("Move relevant automation when audio regions are moved"),
923 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
924 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
927 add_option (_("Editor"),
930 _("Show meters on tracks in the editor"),
931 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_track_meters),
932 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_track_meters)
935 add_option (_("Editor"),
937 "use-overlap-equivalency",
938 _("Use overlap equivalency for regions"),
939 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
940 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
943 add_option (_("Editor"),
945 "rubberbanding-snaps-to-grid",
946 _("Make rubberband selection rectangle snap to the grid"),
947 sigc::mem_fun (*_rc_config, &RCConfiguration::get_rubberbanding_snaps_to_grid),
948 sigc::mem_fun (*_rc_config, &RCConfiguration::set_rubberbanding_snaps_to_grid)
951 add_option (_("Editor"),
954 _("Show waveforms in regions"),
955 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms),
956 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms)
959 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
962 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_scale),
963 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_scale)
966 wfs->add (Linear, _("linear"));
967 wfs->add (Logarithmic, _("logarithmic"));
969 add_option (_("Editor"), wfs);
971 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
974 sigc::mem_fun (*_rc_config, &RCConfiguration::get_waveform_shape),
975 sigc::mem_fun (*_rc_config, &RCConfiguration::set_waveform_shape)
978 wfsh->add (Traditional, _("traditional"));
979 wfsh->add (Rectified, _("rectified"));
981 add_option (_("Editor"), wfsh);
983 add_option (_("Editor"),
985 "show-waveforms-while-recording",
986 _("Show waveforms for audio while it is being recorded"),
987 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_waveforms_while_recording),
988 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_waveforms_while_recording)
993 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
995 add_option (_("Audio"), new BufferingOptions (_rc_config));
997 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
999 add_option (_("Audio"),
1002 _("Use a monitor bus (allows AFL/PFL and more control)"),
1003 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_monitor_bus),
1004 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_monitor_bus)
1007 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
1009 _("Monitoring handled by"),
1010 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
1011 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
1015 /* no JACK monitoring on CoreAudio */
1016 if (AudioEngine::instance()->can_request_hardware_monitoring()) {
1017 mm->add (HardwareMonitoring, _("JACK"));
1020 mm->add (SoftwareMonitoring, _("ardour"));
1021 mm->add (ExternalMonitoring, _("audio hardware"));
1023 add_option (_("Audio"), mm);
1025 add_option (_("Audio"),
1027 "tape-machine-mode",
1028 _("Tape machine mode"),
1029 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
1030 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
1033 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
1035 add_option (_("Audio"),
1037 "auto-connect-standard-busses",
1038 _("Auto-connect master/monitor busses"),
1039 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
1040 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
1043 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
1044 "input-auto-connect",
1045 _("Connect track inputs"),
1046 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
1047 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
1050 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
1051 iac->add (ManualConnect, _("manually"));
1053 add_option (_("Audio"), iac);
1055 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
1056 "output-auto-connect",
1057 _("Connect track and bus outputs"),
1058 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
1059 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
1062 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
1063 oac->add (AutoConnectMaster, _("automatically to master bus"));
1064 oac->add (ManualConnect, _("manually"));
1066 add_option (_("Audio"), oac);
1068 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
1070 add_option (_("Audio"),
1072 "denormal-protection",
1073 _("Use DC bias to protect against denormals"),
1074 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
1075 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
1078 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
1080 _("Processor handling"),
1081 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
1082 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
1085 dm->add (DenormalNone, _("no processor handling"));
1089 if (fpu.has_flush_to_zero()) {
1090 dm->add (DenormalFTZ, _("use FlushToZero"));
1093 if (fpu.has_denormals_are_zero()) {
1094 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
1097 if (fpu.has_flush_to_zero() && fpu.has_denormals_are_zero()) {
1098 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZerO"));
1101 add_option (_("Audio"), dm);
1103 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
1105 add_option (_("Audio"),
1107 "plugins-stop-with-transport",
1108 _("Stop plugins when the transport is stopped"),
1109 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
1110 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
1113 add_option (_("Audio"),
1115 "do-not-record-plugins",
1116 _("Disable plugins during recording"),
1117 sigc::mem_fun (*_rc_config, &RCConfiguration::get_do_not_record_plugins),
1118 sigc::mem_fun (*_rc_config, &RCConfiguration::set_do_not_record_plugins)
1121 add_option (_("Audio"),
1123 "new-plugins-active",
1124 _("Make new plugins active"),
1125 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
1126 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
1129 add_option (_("Audio"),
1131 "auto-analyse-audio",
1132 _("Enable automatic analysis of audio"),
1133 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
1134 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
1137 add_option (_("Audio"),
1139 "replicate-missing-region-channels",
1140 _("Replicate missing region channels"),
1141 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
1142 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
1147 add_option (_("Solo / mute"),
1150 _("Solo mute cut (dB)"),
1151 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
1152 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
1155 add_option (_("Solo / mute"),
1157 "solo-control-is-listen-control",
1158 _("Solo controls are Listen controls"),
1159 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
1160 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
1163 ComboOption<ListenPosition>* lp = new ComboOption<ListenPosition> (
1165 _("Listen Position"),
1166 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
1167 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
1170 lp->add (AfterFaderListen, _("after-fader listen"));
1171 lp->add (PreFaderListen, _("pre-fader listen"));
1173 add_option (_("Solo / mute"), lp);
1175 add_option (_("Solo / mute"),
1178 _("Exclusive solo"),
1179 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
1180 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
1183 add_option (_("Solo / mute"),
1186 _("Show solo muting"),
1187 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
1188 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
1191 add_option (_("Solo / mute"),
1193 "solo-mute-override",
1194 _("Soloing overrides muting"),
1195 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
1196 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
1199 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
1201 add_option (_("Solo / mute"),
1203 "mute-affects-pre-fader",
1204 _("Mute affects pre-fader sends"),
1205 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
1206 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
1209 add_option (_("Solo / mute"),
1211 "mute-affects-post-fader",
1212 _("Mute affects post-fader sends"),
1213 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
1214 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
1217 add_option (_("Solo / mute"),
1219 "mute-affects-control-outs",
1220 _("Mute affects control outputs"),
1221 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
1222 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
1225 add_option (_("Solo / mute"),
1227 "mute-affects-main-outs",
1228 _("Mute affects main outputs"),
1229 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
1230 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
1233 add_option (_("MIDI control"),
1236 _("Send MIDI Clock"),
1237 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
1238 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
1241 add_option (_("MIDI control"),
1244 _("Send MIDI Time Code"),
1245 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
1246 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
1249 add_option (_("MIDI control"),
1252 _("Obey MIDI Machine Control commands"),
1253 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
1254 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
1258 add_option (_("MIDI control"),
1261 _("Send MIDI Machine Control commands"),
1262 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
1263 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
1266 add_option (_("MIDI control"),
1269 _("Send MIDI control feedback"),
1270 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
1271 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
1274 add_option (_("MIDI control"),
1275 new SpinOption<uint8_t> (
1276 "mmc-receive-device-id",
1277 _("Inbound MMC device ID"),
1278 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
1279 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
1283 add_option (_("MIDI control"),
1284 new SpinOption<uint8_t> (
1285 "mmc-send-device-id",
1286 _("Outbound MMC device ID"),
1287 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
1288 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
1292 add_option (_("MIDI control"),
1293 new SpinOption<int32_t> (
1294 "initial-program-change",
1295 _("Initial program change"),
1296 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
1297 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
1301 /* CONTROL SURFACES */
1303 add_option (_("Control surfaces"), new ControlSurfacesOptions (*this));
1305 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
1307 _("Control surface remote ID"),
1308 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
1309 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
1312 rm->add (UserOrdered, _("assigned by user"));
1313 rm->add (MixerOrdered, _("follows order of mixer"));
1314 rm->add (EditorOrdered, _("follows order of editor"));
1316 add_option (_("Control surfaces"), rm);
1320 add_option (_("Keyboard"), new KeyboardOptions);