1 #include <gtkmm/liststore.h>
2 #include <gtkmm/stock.h>
3 #include <gtkmm/scale.h>
4 #include <gtkmm2ext/utils.h>
6 #include "midi++/manager.h"
7 #include "midi++/factory.h"
8 #include "ardour/rc_configuration.h"
9 #include "ardour/control_protocol_manager.h"
10 #include "control_protocol/control_protocol.h"
11 #include "rc_option_editor.h"
13 #include "midi_port_dialog.h"
21 using namespace Gtkmm2ext;
23 using namespace ARDOUR;
25 class MIDIPorts : public OptionEditorBox
28 MIDIPorts (RCConfiguration* c)
30 _add_port_button (Stock::ADD)
32 _store = ListStore::create (_model);
33 _view.set_model (_store);
34 _view.append_column (_("Name"), _model.name);
35 _view.get_column(0)->set_resizable (true);
36 _view.get_column(0)->set_expand (true);
37 _view.append_column_editable (_("Online"), _model.online);
38 _view.append_column_editable (_("Trace input"), _model.trace_input);
39 _view.append_column_editable (_("Trace output"), _model.trace_output);
41 HBox* h = manage (new HBox);
43 h->pack_start (_view, true, true);
45 VBox* v = manage (new VBox);
47 v->pack_start (_add_port_button, false, false);
48 h->pack_start (*v, false, false);
50 _box->pack_start (*h);
52 Table* t = manage (new Table (2, 4));
56 Label* l = manage (new Label (_("MTC:")));
57 l->set_alignment (1, 0.5);
58 t->attach (*l, 0, 1, n, n + 1, EXPAND | FILL, FILL);
59 t->attach (_mtc_combo, 1, 2, n, n + 1, EXPAND | FILL, EXPAND | FILL);
62 l = manage (new Label (_("MIDI clock:")));
63 l->set_alignment (1, 0.5);
64 t->attach (*l, 0, 1, n, n + 1, FILL, FILL);
65 t->attach (_midi_clock_combo, 1, 2, n, n + 1, FILL, FILL);
68 l = manage (new Label (_("MMC:")));
69 l->set_alignment (1, 0.5);
70 t->attach (*l, 0, 1, n, n + 1, FILL, FILL);
71 t->attach (_mmc_combo, 1, 2, n, n + 1, FILL, FILL);
74 l = manage (new Label (_("MIDI parameter control:")));
75 l->set_alignment (1, 0.5);
76 t->attach (*l, 0, 1, n, n + 1, FILL, FILL);
77 t->attach (_mpc_combo, 1, 2, n, n + 1, FILL, FILL);
80 _box->pack_start (*t, true, true);
84 _add_port_button.signal_clicked().connect (mem_fun (*this, &MIDIPorts::add_port_clicked));
85 _mtc_combo.signal_changed().connect (mem_fun (*this, &MIDIPorts::mtc_combo_changed));
86 _mmc_combo.signal_changed().connect (mem_fun (*this, &MIDIPorts::mmc_combo_changed));
87 _mpc_combo.signal_changed().connect (mem_fun (*this, &MIDIPorts::mpc_combo_changed));
88 _midi_clock_combo.signal_changed().connect (mem_fun (*this, &MIDIPorts::midi_clock_combo_changed));
91 void parameter_changed (string const & p)
93 if (p == "mtc-port-name") {
94 _mtc_combo.set_active_text (_rc_config->get_mtc_port_name());
95 } else if (p == "mmc-port-name") {
96 _mmc_combo.set_active_text (_rc_config->get_mmc_port_name());
97 } else if (p == "midi-port-name") {
98 _mpc_combo.set_active_text (_rc_config->get_midi_port_name());
99 } else if (p == "midi-clock-port-name") {
100 _midi_clock_combo.set_active_text (_rc_config->get_midi_clock_port_name());
104 void set_state_from_config ()
106 parameter_changed ("mtc-port-name");
107 parameter_changed ("mmc-port-name");
108 parameter_changed ("midi-port-name");
109 parameter_changed ("midi-clock-port-name");
112 void mtc_combo_changed ()
114 _rc_config->set_mtc_port_name (_mtc_combo.get_active_text());
117 void mmc_combo_changed ()
119 _rc_config->set_mmc_port_name (_mmc_combo.get_active_text());
122 void mpc_combo_changed ()
124 _rc_config->set_midi_port_name (_mpc_combo.get_active_text());
127 void midi_clock_combo_changed ()
129 _rc_config->set_midi_clock_port_name (_midi_clock_combo.get_active_text());
134 void setup_ports_combo (ComboBoxText& c)
137 MIDI::Manager::PortMap const & ports = MIDI::Manager::instance()->get_midi_ports ();
138 for (MIDI::Manager::PortMap::const_iterator i = ports.begin(); i != ports.end(); ++i) {
139 c.append_text (i->first);
143 void ports_changed ()
145 /* XXX: why is this coming from here? */
146 MIDI::Manager::PortMap const & ports = MIDI::Manager::instance()->get_midi_ports ();
150 for (MIDI::Manager::PortMap::const_iterator i = ports.begin(); i != ports.end(); ++i) {
151 TreeModel::Row r = *_store->append ();
152 r[_model.name] = i->first;
153 r[_model.online] = !i->second->input()->offline();
154 r[_model.trace_input] = i->second->input()->tracing();
155 r[_model.trace_output] = i->second->output()->tracing();
158 setup_ports_combo (_mtc_combo);
159 setup_ports_combo (_midi_clock_combo);
160 setup_ports_combo (_mmc_combo);
161 setup_ports_combo (_mpc_combo);
164 void add_port_clicked ()
166 MidiPortDialog dialog;
168 dialog.set_position (WIN_POS_MOUSE);
172 int const r = dialog.run ();
175 case RESPONSE_ACCEPT:
182 Glib::ustring const mode = dialog.port_mode_combo.get_active_text ();
185 if (mode == _("input")) {
187 } else if (mode == (_("output"))) {
193 XMLNode node (X_("MIDI-port"));
195 node.add_property ("tag", dialog.port_name.get_text());
196 node.add_property ("device", X_("ardour")); // XXX this can't be right for all types
197 node.add_property ("type", MIDI::PortFactory::default_port_type());
198 node.add_property ("mode", smod);
200 if (MIDI::Manager::instance()->add_port (node) != 0) {
205 class MIDIModelColumns : public TreeModelColumnRecord
216 TreeModelColumn<string> name;
217 TreeModelColumn<bool> online;
218 TreeModelColumn<bool> trace_input;
219 TreeModelColumn<bool> trace_output;
222 RCConfiguration* _rc_config;
223 Glib::RefPtr<ListStore> _store;
224 MIDIModelColumns _model;
226 Button _add_port_button;
227 ComboBoxText _mtc_combo;
228 ComboBoxText _midi_clock_combo;
229 ComboBoxText _mmc_combo;
230 ComboBoxText _mpc_combo;
234 class ClickOptions : public OptionEditorBox
237 ClickOptions (RCConfiguration* c, ArdourDialog* p)
241 Table* t = manage (new Table (2, 3));
244 Label* l = manage (new Label (_("Click audio file:")));
245 l->set_alignment (1, 0.5);
246 t->attach (*l, 0, 1, 0, 1, FILL);
247 t->attach (_click_path_entry, 1, 2, 0, 1, FILL);
248 Button* b = manage (new Button (_("Browse...")));
249 b->signal_clicked().connect (mem_fun (*this, &ClickOptions::click_browse_clicked));
250 t->attach (*b, 2, 3, 0, 1, FILL);
252 l = manage (new Label (_("Click emphasis audio file:")));
253 l->set_alignment (1, 0.5);
254 t->attach (*l, 0, 1, 1, 2, FILL);
255 t->attach (_click_emphasis_path_entry, 1, 2, 1, 2, FILL);
256 b = manage (new Button (_("Browse...")));
257 b->signal_clicked().connect (mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
258 t->attach (*b, 2, 3, 1, 2, FILL);
260 _box->pack_start (*t, false, false);
263 void parameter_changed (string const & p)
265 if (p == "click-sound") {
266 _click_path_entry.set_text (_rc_config->get_click_sound());
267 } else if (p == "click-emphasis-sound") {
268 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
272 void set_state_from_config ()
274 parameter_changed ("click-sound");
275 parameter_changed ("click-emphasis-sound");
280 void click_browse_clicked ()
282 SoundFileChooser sfdb (*_parent, _("Choose Click"));
287 if (sfdb.run () == RESPONSE_OK) {
288 click_chosen (sfdb.get_filename());
292 void click_chosen (string const & path)
294 _click_path_entry.set_text (path);
295 _rc_config->set_click_sound (path);
298 void click_emphasis_browse_clicked ()
300 SoundFileChooser sfdb (*_parent, _("Choose Click Emphasis"));
305 if (sfdb.run () == RESPONSE_OK) {
306 click_emphasis_chosen (sfdb.get_filename());
310 void click_emphasis_chosen (string const & path)
312 _click_emphasis_path_entry.set_text (path);
313 _rc_config->set_click_emphasis_sound (path);
316 RCConfiguration* _rc_config;
317 ArdourDialog* _parent;
318 Entry _click_path_entry;
319 Entry _click_emphasis_path_entry;
322 class UndoOptions : public OptionEditorBox
325 UndoOptions (RCConfiguration* c) :
327 _limit_undo_button (_("Limit undo history to")),
328 _save_undo_button (_("Save undo history of"))
330 Table* t = new Table (2, 3);
333 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
334 _limit_undo_spin.set_range (0, 512);
335 _limit_undo_spin.set_increments (1, 10);
336 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
337 Label* l = manage (new Label (_("commands")));
338 l->set_alignment (0, 0.5);
339 t->attach (*l, 2, 3, 0, 1);
341 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
342 _save_undo_spin.set_range (0, 512);
343 _save_undo_spin.set_increments (1, 10);
344 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
345 l = manage (new Label (_("commands")));
346 l->set_alignment (0, 0.5);
347 t->attach (*l, 2, 3, 1, 2);
349 _box->pack_start (*t);
351 _limit_undo_button.signal_toggled().connect (mem_fun (*this, &UndoOptions::limit_undo_toggled));
352 _limit_undo_spin.signal_value_changed().connect (mem_fun (*this, &UndoOptions::limit_undo_changed));
353 _save_undo_button.signal_toggled().connect (mem_fun (*this, &UndoOptions::save_undo_toggled));
354 _save_undo_spin.signal_value_changed().connect (mem_fun (*this, &UndoOptions::save_undo_changed));
357 void parameter_changed (string const & p)
359 if (p == "history-depth") {
360 int32_t const d = _rc_config->get_history_depth();
361 _limit_undo_button.set_active (d != 0);
362 _limit_undo_spin.set_sensitive (d != 0);
363 _limit_undo_spin.set_value (d);
364 } else if (p == "save-history") {
365 bool const x = _rc_config->get_save_history ();
366 _save_undo_button.set_active (x);
367 _save_undo_spin.set_sensitive (x);
368 } else if (p == "save-history-depth") {
369 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
373 void set_state_from_config ()
375 parameter_changed ("save-history");
376 parameter_changed ("history-depth");
377 parameter_changed ("save-history-depth");
380 void limit_undo_toggled ()
382 bool const x = _limit_undo_button.get_active ();
383 _limit_undo_spin.set_sensitive (x);
384 int32_t const n = x ? 16 : 0;
385 _limit_undo_spin.set_value (n);
386 _rc_config->set_history_depth (n);
389 void limit_undo_changed ()
391 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
394 void save_undo_toggled ()
396 bool const x = _save_undo_button.get_active ();
397 _rc_config->set_save_history (x);
400 void save_undo_changed ()
402 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
406 RCConfiguration* _rc_config;
407 CheckButton _limit_undo_button;
408 SpinButton _limit_undo_spin;
409 CheckButton _save_undo_button;
410 SpinButton _save_undo_spin;
415 static const struct {
426 { "Shift", GDK_SHIFT_MASK },
427 { "Command", GDK_META_MASK },
428 { "Control", GDK_CONTROL_MASK },
429 { "Option", GDK_MOD1_MASK },
430 { "Command-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
431 { "Command-Option", GDK_MOD1_MASK|GDK_MOD5_MASK },
432 { "Shift-Option", GDK_SHIFT_MASK|GDK_MOD5_MASK },
433 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
436 { "Shift", GDK_SHIFT_MASK },
437 { "Control", GDK_CONTROL_MASK },
438 { "Alt (Mod1)", GDK_MOD1_MASK },
439 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
440 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
441 { "Shift-Alt", GDK_SHIFT_MASK|GDK_MOD1_MASK },
442 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
443 { "Mod2", GDK_MOD2_MASK },
444 { "Mod3", GDK_MOD3_MASK },
445 { "Mod4", GDK_MOD4_MASK },
446 { "Mod5", GDK_MOD5_MASK },
452 class KeyboardOptions : public OptionEditorBox
456 _delete_button_adjustment (3, 1, 5),
457 _delete_button_spin (_delete_button_adjustment),
458 _edit_button_adjustment (3, 1, 5),
459 _edit_button_spin (_edit_button_adjustment)
462 /* internationalize and prepare for use with combos */
465 for (int i = 0; modifiers[i].name; ++i) {
466 dumb.push_back (_(modifiers[i].name));
469 set_popdown_strings (_edit_modifier_combo, dumb);
470 _edit_modifier_combo.signal_changed().connect (mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
472 for (int x = 0; modifiers[x].name; ++x) {
473 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
474 _edit_modifier_combo.set_active_text (_(modifiers[x].name));
479 Table* t = manage (new Table (4, 4));
482 Label* l = manage (new Label (_("Edit using:")));
483 l->set_name ("OptionsLabel");
484 l->set_alignment (1.0, 0.5);
486 t->attach (*l, 0, 1, 0, 1, FILL | EXPAND, FILL);
487 t->attach (_edit_modifier_combo, 1, 2, 0, 1, FILL | EXPAND, FILL);
489 l = manage (new Label (_("+ button")));
490 l->set_name ("OptionsLabel");
492 t->attach (*l, 3, 4, 0, 1, FILL | EXPAND, FILL);
493 t->attach (_edit_button_spin, 4, 5, 0, 1, FILL | EXPAND, FILL);
495 _edit_button_spin.set_name ("OptionsEntry");
496 _edit_button_adjustment.set_value (Keyboard::edit_button());
497 _edit_button_adjustment.signal_value_changed().connect (mem_fun(*this, &KeyboardOptions::edit_button_changed));
499 set_popdown_strings (_delete_modifier_combo, dumb);
500 _delete_modifier_combo.signal_changed().connect (mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
502 for (int x = 0; modifiers[x].name; ++x) {
503 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
504 _delete_modifier_combo.set_active_text (_(modifiers[x].name));
509 l = manage (new Label (_("Delete using:")));
510 l->set_name ("OptionsLabel");
511 l->set_alignment (1.0, 0.5);
513 t->attach (*l, 0, 1, 1, 2, FILL | EXPAND, FILL);
514 t->attach (_delete_modifier_combo, 1, 2, 1, 2, FILL | EXPAND, FILL);
516 l = manage (new Label (_("+ button")));
517 l->set_name ("OptionsLabel");
519 t->attach (*l, 3, 4, 1, 2, FILL | EXPAND, FILL);
520 t->attach (_delete_button_spin, 4, 5, 1, 2, FILL | EXPAND, FILL);
522 _delete_button_spin.set_name ("OptionsEntry");
523 _delete_button_adjustment.set_value (Keyboard::delete_button());
524 _delete_button_adjustment.signal_value_changed().connect (mem_fun(*this, &KeyboardOptions::delete_button_changed));
526 set_popdown_strings (_snap_modifier_combo, dumb);
527 _snap_modifier_combo.signal_changed().connect (mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
529 for (int x = 0; modifiers[x].name; ++x) {
530 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
531 _snap_modifier_combo.set_active_text (_(modifiers[x].name));
536 l = manage (new Label (_("Ignore snap using:")));
537 l->set_name ("OptionsLabel");
538 l->set_alignment (1.0, 0.5);
540 t->attach (*l, 0, 1, 2, 3, FILL | EXPAND, FILL);
541 t->attach (_snap_modifier_combo, 1, 2, 2, 3, FILL | EXPAND, FILL);
545 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
546 strs.push_back (bf->first);
549 set_popdown_strings (_keyboard_layout_selector, strs);
550 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
551 _keyboard_layout_selector.signal_changed().connect (mem_fun (*this, &KeyboardOptions::bindings_changed));
553 l = manage (new Label (_("Keyboard layout:")));
554 l->set_name ("OptionsLabel");
555 l->set_alignment (1.0, 0.5);
557 t->attach (*l, 0, 1, 3, 4, FILL | EXPAND, FILL);
558 t->attach (_keyboard_layout_selector, 1, 2, 3, 4, FILL | EXPAND, FILL);
560 _box->pack_start (*t, false, false);
563 void parameter_changed (string const & p)
565 /* XXX: these aren't really config options... */
568 void set_state_from_config ()
570 /* XXX: these aren't really config options... */
575 void bindings_changed ()
577 string const txt = _keyboard_layout_selector.get_active_text();
579 /* XXX: config...? for all this keyboard stuff */
581 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
582 if (txt == i->first) {
583 if (Keyboard::load_keybindings (i->second)) {
584 Keyboard::save_keybindings ();
590 void edit_modifier_chosen ()
592 string const txt = _edit_modifier_combo.get_active_text();
594 for (int i = 0; modifiers[i].name; ++i) {
595 if (txt == _(modifiers[i].name)) {
596 Keyboard::set_edit_modifier (modifiers[i].modifier);
602 void delete_modifier_chosen ()
604 string const txt = _delete_modifier_combo.get_active_text();
606 for (int i = 0; modifiers[i].name; ++i) {
607 if (txt == _(modifiers[i].name)) {
608 Keyboard::set_delete_modifier (modifiers[i].modifier);
614 void snap_modifier_chosen ()
616 string const txt = _snap_modifier_combo.get_active_text();
618 for (int i = 0; modifiers[i].name; ++i) {
619 if (txt == _(modifiers[i].name)) {
620 Keyboard::set_snap_modifier (modifiers[i].modifier);
626 void delete_button_changed ()
628 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
631 void edit_button_changed ()
633 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
636 ComboBoxText _keyboard_layout_selector;
637 ComboBoxText _edit_modifier_combo;
638 ComboBoxText _delete_modifier_combo;
639 ComboBoxText _snap_modifier_combo;
640 Adjustment _delete_button_adjustment;
641 SpinButton _delete_button_spin;
642 Adjustment _edit_button_adjustment;
643 SpinButton _edit_button_spin;
646 class FontScalingOptions : public OptionEditorBox
649 FontScalingOptions (RCConfiguration* c) :
651 _dpi_adjustment (50, 50, 250, 1, 10),
652 _dpi_slider (_dpi_adjustment)
654 _dpi_adjustment.set_value (_rc_config->get_font_scale ());
656 Label* l = manage (new Label (_("Font scaling:")));
657 l->set_name ("OptionsLabel");
659 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
660 HBox* h = manage (new HBox);
662 h->pack_start (*l, false, false);
663 h->pack_start (_dpi_slider, true, true);
665 _box->pack_start (*h, false, false);
667 _dpi_adjustment.signal_value_changed().connect (mem_fun (*this, &FontScalingOptions::dpi_changed));
670 void parameter_changed (string const & p)
672 if (p == "font-scale") {
673 _dpi_adjustment.set_value (_rc_config->get_font_scale() / 1024.);
677 void set_state_from_config ()
679 parameter_changed ("font-scale");
686 _rc_config->set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024));
687 /* XXX: should be triggered from the parameter changed signal */
691 RCConfiguration* _rc_config;
692 Adjustment _dpi_adjustment;
697 class ControlSurfacesOptions : public OptionEditorBox
700 ControlSurfacesOptions ()
702 _store = ListStore::create (_model);
703 _view.set_model (_store);
704 _view.append_column (_("Name"), _model.name);
705 _view.get_column(0)->set_resizable (true);
706 _view.get_column(0)->set_expand (true);
707 _view.append_column_editable (_("Enabled"), _model.enabled);
708 _view.append_column_editable (_("Feedback"), _model.feedback);
710 _box->pack_start (_view, false, false);
712 _store->signal_row_changed().connect (mem_fun (*this, &ControlSurfacesOptions::model_changed));
715 void parameter_changed (std::string const &)
720 void set_state_from_config ()
724 ControlProtocolManager& m = ControlProtocolManager::instance ();
725 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
727 if (!(*i)->mandatory) {
728 TreeModel::Row r = *_store->append ();
729 r[_model.name] = (*i)->name;
730 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
731 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
732 r[_model.protocol_info] = *i;
739 void model_changed (TreeModel::Path const & p, TreeModel::iterator const & i)
741 TreeModel::Row r = *i;
743 ControlProtocolInfo* cpi = r[_model.protocol_info];
748 bool const was_enabled = (cpi->protocol != 0);
749 bool const is_enabled = r[_model.enabled];
751 if (was_enabled != is_enabled) {
753 ControlProtocolManager::instance().instantiate (*cpi);
755 ControlProtocolManager::instance().teardown (*cpi);
759 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
760 bool const is_feedback = r[_model.feedback];
762 if (was_feedback != is_feedback && cpi->protocol) {
763 cpi->protocol->set_feedback (is_feedback);
767 class ControlSurfacesModelColumns : public TreeModelColumnRecord
771 ControlSurfacesModelColumns ()
779 TreeModelColumn<string> name;
780 TreeModelColumn<bool> enabled;
781 TreeModelColumn<bool> feedback;
782 TreeModelColumn<ControlProtocolInfo*> protocol_info;
785 Glib::RefPtr<ListStore> _store;
786 ControlSurfacesModelColumns _model;
791 RCOptionEditor::RCOptionEditor ()
792 : OptionEditor (Config, _("Ardour Preferences")),
797 add_option (_("Misc"), new OptionEditorHeading (_("Metering")));
799 ComboOption<float>* mht = new ComboOption<float> (
801 _("Meter hold time"),
802 mem_fun (*_rc_config, &RCConfiguration::get_meter_hold),
803 mem_fun (*_rc_config, &RCConfiguration::set_meter_hold)
806 mht->add (MeterHoldOff, _("off"));
807 mht->add (MeterHoldShort, _("short"));
808 mht->add (MeterHoldMedium, _("medium"));
809 mht->add (MeterHoldLong, _("long"));
811 add_option (_("Misc"), mht);
813 ComboOption<float>* mfo = new ComboOption<float> (
816 mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
817 mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
820 mfo->add (METER_FALLOFF_OFF, _("off"));
821 mfo->add (METER_FALLOFF_SLOWEST, _("slowest"));
822 mfo->add (METER_FALLOFF_SLOW, _("slow"));
823 mfo->add (METER_FALLOFF_MEDIUM, _("medium"));
824 mfo->add (METER_FALLOFF_FAST, _("fast"));
825 mfo->add (METER_FALLOFF_FASTER, _("faster"));
826 mfo->add (METER_FALLOFF_FASTEST, _("fastest"));
828 add_option (_("Misc"), mfo);
830 add_option (_("Misc"), new OptionEditorHeading (_("Undo")));
832 add_option (_("Misc"), new UndoOptions (_rc_config));
834 add_option (_("Misc"), new OptionEditorHeading (_("Misc")));
837 /* font scaling does nothing with GDK/Quartz */
838 add_option (_("Misc"), new FontScalingOptions (_rc_config));
841 add_option (_("Misc"),
843 "verify-remove-last-capture",
844 _("Verify removal of last capture"),
845 mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
846 mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
849 add_option (_("Misc"),
851 "periodic-safety-backups",
852 _("Make periodic backups of the session file"),
853 mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
854 mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
857 add_option (_("Misc"),
859 "sync-all-route-ordering",
860 _("Syncronise editor and mixer track order"),
861 mem_fun (*_rc_config, &RCConfiguration::get_sync_all_route_ordering),
862 mem_fun (*_rc_config, &RCConfiguration::set_sync_all_route_ordering)
865 add_option (_("Misc"),
867 "only-copy-imported-files",
868 _("Always copy imported files"),
869 mem_fun (*_rc_config, &RCConfiguration::get_only_copy_imported_files),
870 mem_fun (*_rc_config, &RCConfiguration::set_only_copy_imported_files)
873 add_option (_("Misc"),
876 _("Use narrow mixer strips"),
877 mem_fun (*_rc_config, &RCConfiguration::get_default_narrow_ms),
878 mem_fun (*_rc_config, &RCConfiguration::set_default_narrow_ms)
881 add_option (_("Misc"),
884 _("Name new markers"),
885 mem_fun (*_rc_config, &RCConfiguration::get_name_new_markers),
886 mem_fun (*_rc_config, &RCConfiguration::set_name_new_markers)
891 add_option (_("Transport"),
893 "latched-record-enable",
894 _("Keep record-enable engaged on stop"),
895 mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
896 mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
899 add_option (_("Transport"),
901 "stop-recording-on-xrun",
902 _("Stop recording when an xrun occurs"),
903 mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
904 mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
907 add_option (_("Transport"),
909 "create-xrun-marker",
910 _("Create markers where xruns occur"),
911 mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
912 mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
915 add_option (_("Transport"),
917 "stop-at-session-end",
918 _("Stop at the end of the session"),
919 mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
920 mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
923 add_option (_("Transport"),
925 "primary-clock-delta-edit-cursor",
926 _("Primary clock delta to edit cursor"),
927 mem_fun (*_rc_config, &RCConfiguration::get_primary_clock_delta_edit_cursor),
928 mem_fun (*_rc_config, &RCConfiguration::set_primary_clock_delta_edit_cursor)
931 add_option (_("Transport"),
933 "secondary-clock-delta-edit-cursor",
934 _("Secondary clock delta to edit cursor"),
935 mem_fun (*_rc_config, &RCConfiguration::get_secondary_clock_delta_edit_cursor),
936 mem_fun (*_rc_config, &RCConfiguration::set_secondary_clock_delta_edit_cursor)
941 add_option (_("Editor"),
943 "link-region-and-track-selection",
944 _("Link selection of regions and tracks"),
945 mem_fun (*_rc_config, &RCConfiguration::get_link_region_and_track_selection),
946 mem_fun (*_rc_config, &RCConfiguration::set_link_region_and_track_selection)
949 add_option (_("Editor"),
951 "automation-follows-regions",
952 _("Move relevant automation when regions are moved"),
953 mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
954 mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
957 add_option (_("Editor"),
960 _("Show meters on tracks in the editor"),
961 mem_fun (*_rc_config, &RCConfiguration::get_show_track_meters),
962 mem_fun (*_rc_config, &RCConfiguration::set_show_track_meters)
965 add_option (_("Editor"),
967 "use-overlap-equivalency",
968 _("Use overlap equivalency for regions"),
969 mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
970 mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
973 add_option (_("Editor"),
975 "rubberbanding-snaps-to-grid",
976 _("Make rubberband selection rectangle snap to the grid"),
977 mem_fun (*_rc_config, &RCConfiguration::get_rubberbanding_snaps_to_grid),
978 mem_fun (*_rc_config, &RCConfiguration::set_rubberbanding_snaps_to_grid)
983 add_option (_("Audio"), new OptionEditorHeading (_("Solo")));
985 ComboOption<SoloModel>* sm = new ComboOption<SoloModel> (
988 mem_fun (*_rc_config, &RCConfiguration::get_solo_model),
989 mem_fun (*_rc_config, &RCConfiguration::set_solo_model)
992 sm->add (InverseMute, _("in place"));
993 sm->add (SoloBus, _("via bus"));
995 add_option (_("Audio"), sm);
997 add_option (_("Audio"),
1001 mem_fun (*_rc_config, &RCConfiguration::get_solo_latched),
1002 mem_fun (*_rc_config, &RCConfiguration::set_solo_latched)
1005 add_option (_("Audio"),
1008 _("Show solo muting"),
1009 mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
1010 mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
1013 add_option (_("Audio"),
1015 "solo-mute-override",
1016 _("Override muting"),
1017 mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
1018 mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
1021 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
1023 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
1025 _("Monitoring handled by"),
1026 mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
1027 mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
1030 mm->add (HardwareMonitoring, _("JACK"));
1031 mm->add (SoftwareMonitoring, _("ardour"));
1032 mm->add (ExternalMonitoring, _("audio hardware"));
1034 add_option (_("Audio"), mm);
1036 add_option (_("Audio"),
1038 "tape-machine-mode",
1039 _("Tape machine mode"),
1040 mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
1041 mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
1044 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
1046 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
1047 "input-auto-connect",
1048 _("Connect track and bus inputs"),
1049 mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
1050 mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
1053 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
1054 iac->add (ManualConnect, _("manually"));
1056 add_option (_("Audio"), iac);
1058 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
1059 "output-auto-connect",
1060 _("Connect track and bus outputs"),
1061 mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
1062 mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
1065 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
1066 oac->add (AutoConnectMaster, _("automatically to master outputs"));
1067 oac->add (ManualConnect, _("manually"));
1069 add_option (_("Audio"), oac);
1071 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
1073 add_option (_("Audio"),
1075 "denormal-protection",
1076 _("Use DC bias to protect against denormals"),
1077 mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
1078 mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
1081 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
1083 _("Processor handling"),
1084 mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
1085 mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
1088 dm->add (DenormalNone, _("no processor handling"));
1092 if (fpu.has_flush_to_zero()) {
1093 dm->add (DenormalFTZ, _("use FlushToZero"));
1096 if (fpu.has_denormals_are_zero()) {
1097 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
1100 if (fpu.has_flush_to_zero() && fpu.has_denormals_are_zero()) {
1101 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZerO"));
1104 add_option (_("Audio"), dm);
1106 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
1108 add_option (_("Audio"),
1110 "plugins-stop-with-transport",
1111 _("Stop plugins when the transport is stopped"),
1112 mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
1113 mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
1116 add_option (_("Audio"),
1118 "do-not-record-plugins",
1119 _("Disable plugins during recording"),
1120 mem_fun (*_rc_config, &RCConfiguration::get_do_not_record_plugins),
1121 mem_fun (*_rc_config, &RCConfiguration::set_do_not_record_plugins)
1124 add_option (_("Audio"),
1126 "new-plugins-active",
1127 _("Make new plugins active"),
1128 mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
1129 mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
1132 add_option (_("Audio"),
1134 "auto-analyse-audio",
1135 _("Enable automatic analysis of audio"),
1136 mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
1137 mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
1142 add_option (_("MIDI control"), new MIDIPorts (_rc_config));
1144 add_option (_("MIDI control"),
1145 new SpinOption<uint8_t> (
1146 "mmc-receive-device-id",
1147 _("Inbound MMC device ID"),
1148 mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
1149 mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
1153 add_option (_("MIDI control"),
1154 new SpinOption<uint8_t> (
1155 "mmc-send-device-id",
1156 _("Outbound MMC device ID"),
1157 mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
1158 mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
1162 add_option (_("MIDI control"),
1163 new SpinOption<int32_t> (
1164 "initial-program-change",
1165 _("Initial program change"),
1166 mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
1167 mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
1171 /* CONTROL SURFACES */
1173 add_option (_("Control surfaces"), new ControlSurfacesOptions);
1175 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
1177 _("Control surface remote ID"),
1178 mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
1179 mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
1182 rm->add (UserOrdered, _("assigned by user"));
1183 rm->add (MixerOrdered, _("follows order of mixer"));
1184 rm->add (EditorOrdered, _("follows order of editor"));
1186 add_option (_("Control surfaces"), rm);
1190 add_option (_("Click"), new ClickOptions (_rc_config, this));
1194 add_option (_("Keyboard"), new KeyboardOptions);