2 Copyright (C) 2001-2011 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "gtk2ardour-config.h"
24 #include <boost/algorithm/string.hpp>
26 #include <gtkmm/liststore.h>
27 #include <gtkmm/stock.h>
28 #include <gtkmm/scale.h>
30 #include <gtkmm2ext/utils.h>
31 #include <gtkmm2ext/slider_controller.h>
32 #include <gtkmm2ext/gtk_ui.h>
33 #include <gtkmm2ext/paths_dialog.h>
38 #include "ardour/audioengine.h"
39 #include "ardour/dB.h"
40 #include "ardour/rc_configuration.h"
41 #include "ardour/control_protocol_manager.h"
42 #include "ardour/plugin_manager.h"
43 #include "control_protocol/control_protocol.h"
45 #include "canvas/wave_view.h"
47 #include "ardour_ui.h"
48 #include "ardour_window.h"
49 #include "ardour_dialog.h"
50 #include "gui_thread.h"
51 #include "midi_tracer.h"
52 #include "rc_option_editor.h"
54 #include "midi_port_dialog.h"
57 #include "theme_manager.h"
58 #include "ui_config.h"
63 using namespace Gtkmm2ext;
65 using namespace ARDOUR;
66 using namespace ARDOUR_UI_UTILS;
68 class ClickOptions : public OptionEditorBox
71 ClickOptions (RCConfiguration* c, Gtk::Window* p)
74 Table* t = manage (new Table (2, 3));
77 Label* l = manage (left_aligned_label (_("Click audio file:")));
78 t->attach (*l, 0, 1, 0, 1, FILL);
79 t->attach (_click_path_entry, 1, 2, 0, 1, FILL);
80 Button* b = manage (new Button (_("Browse...")));
81 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
82 t->attach (*b, 2, 3, 0, 1, FILL);
84 l = manage (left_aligned_label (_("Click emphasis audio file:")));
85 t->attach (*l, 0, 1, 1, 2, FILL);
86 t->attach (_click_emphasis_path_entry, 1, 2, 1, 2, FILL);
87 b = manage (new Button (_("Browse...")));
88 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
89 t->attach (*b, 2, 3, 1, 2, FILL);
91 _box->pack_start (*t, false, false);
93 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
94 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
97 void parameter_changed (string const & p)
99 if (p == "click-sound") {
100 _click_path_entry.set_text (_rc_config->get_click_sound());
101 } else if (p == "click-emphasis-sound") {
102 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
106 void set_state_from_config ()
108 parameter_changed ("click-sound");
109 parameter_changed ("click-emphasis-sound");
114 void click_browse_clicked ()
116 SoundFileChooser sfdb (_("Choose Click"));
121 if (sfdb.run () == RESPONSE_OK) {
122 click_chosen (sfdb.get_filename());
126 void click_chosen (string const & path)
128 _click_path_entry.set_text (path);
129 _rc_config->set_click_sound (path);
132 void click_changed ()
134 click_chosen (_click_path_entry.get_text ());
137 void click_emphasis_browse_clicked ()
139 SoundFileChooser sfdb (_("Choose Click Emphasis"));
144 if (sfdb.run () == RESPONSE_OK) {
145 click_emphasis_chosen (sfdb.get_filename());
149 void click_emphasis_chosen (string const & path)
151 _click_emphasis_path_entry.set_text (path);
152 _rc_config->set_click_emphasis_sound (path);
155 void click_emphasis_changed ()
157 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
160 RCConfiguration* _rc_config;
161 Entry _click_path_entry;
162 Entry _click_emphasis_path_entry;
165 class UndoOptions : public OptionEditorBox
168 UndoOptions (RCConfiguration* c) :
170 _limit_undo_button (_("Limit undo history to")),
171 _save_undo_button (_("Save undo history of"))
173 Table* t = new Table (2, 3);
176 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
177 _limit_undo_spin.set_range (0, 512);
178 _limit_undo_spin.set_increments (1, 10);
179 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
180 Label* l = manage (left_aligned_label (_("commands")));
181 t->attach (*l, 2, 3, 0, 1);
183 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
184 _save_undo_spin.set_range (0, 512);
185 _save_undo_spin.set_increments (1, 10);
186 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
187 l = manage (left_aligned_label (_("commands")));
188 t->attach (*l, 2, 3, 1, 2);
190 _box->pack_start (*t);
192 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
193 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
194 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
195 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
198 void parameter_changed (string const & p)
200 if (p == "history-depth") {
201 int32_t const d = _rc_config->get_history_depth();
202 _limit_undo_button.set_active (d != 0);
203 _limit_undo_spin.set_sensitive (d != 0);
204 _limit_undo_spin.set_value (d);
205 } else if (p == "save-history") {
206 bool const x = _rc_config->get_save_history ();
207 _save_undo_button.set_active (x);
208 _save_undo_spin.set_sensitive (x);
209 } else if (p == "save-history-depth") {
210 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
214 void set_state_from_config ()
216 parameter_changed ("save-history");
217 parameter_changed ("history-depth");
218 parameter_changed ("save-history-depth");
221 void limit_undo_toggled ()
223 bool const x = _limit_undo_button.get_active ();
224 _limit_undo_spin.set_sensitive (x);
225 int32_t const n = x ? 16 : 0;
226 _limit_undo_spin.set_value (n);
227 _rc_config->set_history_depth (n);
230 void limit_undo_changed ()
232 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
235 void save_undo_toggled ()
237 bool const x = _save_undo_button.get_active ();
238 _rc_config->set_save_history (x);
241 void save_undo_changed ()
243 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
247 RCConfiguration* _rc_config;
248 CheckButton _limit_undo_button;
249 SpinButton _limit_undo_spin;
250 CheckButton _save_undo_button;
251 SpinButton _save_undo_spin;
256 static const struct {
268 { "Key|Shift", GDK_SHIFT_MASK },
269 { "Command", GDK_META_MASK },
270 { "Control", GDK_CONTROL_MASK },
271 { "Option", GDK_MOD1_MASK },
272 { "Command-Shift", GDK_META_MASK|GDK_SHIFT_MASK },
273 { "Command-Option", GDK_MOD1_MASK|GDK_META_MASK },
274 { "Shift-Option", GDK_SHIFT_MASK|GDK_MOD1_MASK },
275 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_META_MASK },
278 { "Key|Shift", GDK_SHIFT_MASK },
279 { "Control", GDK_CONTROL_MASK },
280 { "Alt (Mod1)", GDK_MOD1_MASK },
281 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
282 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
283 { "Shift-Alt", GDK_SHIFT_MASK|GDK_MOD1_MASK },
284 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
285 { "Mod2", GDK_MOD2_MASK },
286 { "Mod3", GDK_MOD3_MASK },
287 { "Mod4", GDK_MOD4_MASK },
288 { "Mod5", GDK_MOD5_MASK },
294 class KeyboardOptions : public OptionEditorBox
298 _delete_button_adjustment (3, 1, 12),
299 _delete_button_spin (_delete_button_adjustment),
300 _edit_button_adjustment (3, 1, 5),
301 _edit_button_spin (_edit_button_adjustment),
302 _insert_note_button_adjustment (3, 1, 5),
303 _insert_note_button_spin (_insert_note_button_adjustment)
305 /* internationalize and prepare for use with combos */
308 for (int i = 0; modifiers[i].name; ++i) {
309 dumb.push_back (S_(modifiers[i].name));
312 set_popdown_strings (_edit_modifier_combo, dumb);
313 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
315 for (int x = 0; modifiers[x].name; ++x) {
316 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
317 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
322 Table* t = manage (new Table (5, 11));
328 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
329 l->set_name ("OptionsLabel");
333 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
334 strs.push_back (bf->first);
337 set_popdown_strings (_keyboard_layout_selector, strs);
338 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
339 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
341 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
342 t->attach (_keyboard_layout_selector, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
347 l = manage (left_aligned_label (_("When Clicking:")));
348 l->set_name ("OptionEditorHeading");
349 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
354 l = manage (left_aligned_label (_("Edit using:")));
355 l->set_name ("OptionsLabel");
357 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
358 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
360 l = manage (new Label (_("+ button")));
361 l->set_name ("OptionsLabel");
363 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
364 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
366 _edit_button_spin.set_name ("OptionsEntry");
367 _edit_button_adjustment.set_value (Keyboard::edit_button());
368 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
373 set_popdown_strings (_delete_modifier_combo, dumb);
374 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
376 for (int x = 0; modifiers[x].name; ++x) {
377 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
378 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
383 l = manage (left_aligned_label (_("Delete using:")));
384 l->set_name ("OptionsLabel");
386 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
387 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
389 l = manage (new Label (_("+ button")));
390 l->set_name ("OptionsLabel");
392 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
393 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
395 _delete_button_spin.set_name ("OptionsEntry");
396 _delete_button_adjustment.set_value (Keyboard::delete_button());
397 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
402 set_popdown_strings (_insert_note_modifier_combo, dumb);
403 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
405 for (int x = 0; modifiers[x].name; ++x) {
406 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
407 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
412 l = manage (left_aligned_label (_("Insert note using:")));
413 l->set_name ("OptionsLabel");
415 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
416 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
418 l = manage (new Label (_("+ button")));
419 l->set_name ("OptionsLabel");
421 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
422 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
424 _insert_note_button_spin.set_name ("OptionsEntry");
425 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
426 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
430 l = manage (left_aligned_label (_("When Beginning a Drag:")));
431 l->set_name ("OptionEditorHeading");
432 t->attach (*l, 0, 1, row, row + 1, FILL | EXPAND, FILL);
438 set_popdown_strings (_copy_modifier_combo, dumb);
439 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
441 for (int x = 0; modifiers[x].name; ++x) {
442 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
443 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
448 l = manage (left_aligned_label (_("Copy items using:")));
449 l->set_name ("OptionsLabel");
451 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
452 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
456 l = manage (left_aligned_label (_("When Beginning a Trim:")));
457 l->set_name ("OptionEditorHeading");
458 t->attach (*l, 0, 1, row, row + 1, FILL | EXPAND, FILL);
464 set_popdown_strings (_trim_contents_combo, dumb);
465 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
467 for (int x = 0; modifiers[x].name; ++x) {
468 if (modifiers[x].modifier == (guint) Keyboard::trim_contents_modifier ()) {
469 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
474 l = manage (left_aligned_label (_("Trim contents using:")));
475 l->set_name ("OptionsLabel");
477 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
478 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
484 set_popdown_strings (_trim_anchored_combo, dumb);
485 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
487 for (int x = 0; modifiers[x].name; ++x) {
488 if (modifiers[x].modifier == (guint) Keyboard::trim_anchored_modifier ()) {
489 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
494 l = manage (left_aligned_label (_("Anchored trim using:")));
495 l->set_name ("OptionsLabel");
497 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
499 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
505 set_popdown_strings (_trim_jump_combo, dumb);
506 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
508 for (int x = 0; modifiers[x].name; ++x) {
509 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
510 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
515 l = manage (left_aligned_label (_("Jump after trim using:")));
516 l->set_name ("OptionsLabel");
518 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
520 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
525 /* note resize relative */
526 set_popdown_strings (_note_size_relative_combo, dumb);
527 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
529 for (int x = 0; modifiers[x].name; ++x) {
530 if (modifiers[x].modifier == (guint) Keyboard::note_size_relative_modifier ()) {
531 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
536 l = manage (left_aligned_label (_("Resize notes relatively using:")));
537 l->set_name ("OptionsLabel");
539 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
541 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
545 l = manage (left_aligned_label (_("While Dragging:")));
546 l->set_name ("OptionEditorHeading");
547 t->attach (*l, 0, 1, row, row + 1, FILL | EXPAND, FILL);
553 set_popdown_strings (_snap_modifier_combo, dumb);
554 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
556 for (int x = 0; modifiers[x].name; ++x) {
557 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
558 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
563 l = manage (left_aligned_label (_("Ignore snap using:")));
564 l->set_name ("OptionsLabel");
566 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
567 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
573 set_popdown_strings (_snap_delta_combo, dumb);
574 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
576 for (int x = 0; modifiers[x].name; ++x) {
577 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
578 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
583 l = manage (left_aligned_label (_("Snap to absolute using:")));
584 l->set_name ("OptionsLabel");
586 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
587 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
591 l = manage (left_aligned_label (_("While Trimming:")));
592 l->set_name ("OptionEditorHeading");
593 t->attach (*l, 0, 1, row, row + 1, FILL | EXPAND, FILL);
599 set_popdown_strings (_trim_overlap_combo, dumb);
600 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
602 for (int x = 0; modifiers[x].name; ++x) {
603 if (modifiers[x].modifier == (guint) Keyboard::trim_overlap_modifier ()) {
604 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
609 l = manage (left_aligned_label (_("Resize overlaped regions using:")));
610 l->set_name ("OptionsLabel");
612 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
613 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
617 l = manage (left_aligned_label (_("While Dragging Control Points:")));
618 l->set_name ("OptionEditorHeading");
619 t->attach (*l, 0, 1, row, row + 1, FILL | EXPAND, FILL);
625 set_popdown_strings (_fine_adjust_combo, dumb);
626 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
628 for (int x = 0; modifiers[x].name; ++x) {
629 if (modifiers[x].modifier == (guint) Keyboard::fine_adjust_modifier ()) {
630 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
635 l = manage (left_aligned_label (_("Fine adjust using:")));
636 l->set_name ("OptionsLabel");
638 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
639 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
645 set_popdown_strings (_push_points_combo, dumb);
646 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
648 for (int x = 0; modifiers[x].name; ++x) {
649 if (modifiers[x].modifier == (guint) Keyboard::push_points_modifier ()) {
650 _push_points_combo.set_active_text (S_(modifiers[x].name));
655 l = manage (left_aligned_label (_("Push points using:")));
656 l->set_name ("OptionsLabel");
658 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
659 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
663 _box->pack_start (*t, false, false);
666 void parameter_changed (string const &)
668 /* XXX: these aren't really config options... */
671 void set_state_from_config ()
673 /* XXX: these aren't really config options... */
678 void bindings_changed ()
680 string const txt = _keyboard_layout_selector.get_active_text();
682 /* XXX: config...? for all this keyboard stuff */
684 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
685 if (txt == i->first) {
686 if (Keyboard::load_keybindings (i->second)) {
687 Keyboard::save_keybindings ();
693 void edit_modifier_chosen ()
695 string const txt = _edit_modifier_combo.get_active_text();
697 for (int i = 0; modifiers[i].name; ++i) {
698 if (txt == _(modifiers[i].name)) {
699 Keyboard::set_edit_modifier (modifiers[i].modifier);
705 void delete_modifier_chosen ()
707 string const txt = _delete_modifier_combo.get_active_text();
709 for (int i = 0; modifiers[i].name; ++i) {
710 if (txt == _(modifiers[i].name)) {
711 Keyboard::set_delete_modifier (modifiers[i].modifier);
717 void copy_modifier_chosen ()
719 string const txt = _copy_modifier_combo.get_active_text();
721 for (int i = 0; modifiers[i].name; ++i) {
722 if (txt == _(modifiers[i].name)) {
723 Keyboard::set_copy_modifier (modifiers[i].modifier);
729 void insert_note_modifier_chosen ()
731 string const txt = _insert_note_modifier_combo.get_active_text();
733 for (int i = 0; modifiers[i].name; ++i) {
734 if (txt == _(modifiers[i].name)) {
735 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
741 void snap_modifier_chosen ()
743 string const txt = _snap_modifier_combo.get_active_text();
745 for (int i = 0; modifiers[i].name; ++i) {
746 if (txt == _(modifiers[i].name)) {
747 Keyboard::set_snap_modifier (modifiers[i].modifier);
753 void snap_delta_modifier_chosen ()
755 string const txt = _snap_delta_combo.get_active_text();
757 for (int i = 0; modifiers[i].name; ++i) {
758 if (txt == _(modifiers[i].name)) {
759 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
765 void trim_contents_modifier_chosen ()
767 string const txt = _trim_contents_combo.get_active_text();
769 for (int i = 0; modifiers[i].name; ++i) {
770 if (txt == _(modifiers[i].name)) {
771 Keyboard::set_trim_contents_modifier (modifiers[i].modifier);
777 void trim_overlap_modifier_chosen ()
779 string const txt = _trim_overlap_combo.get_active_text();
781 for (int i = 0; modifiers[i].name; ++i) {
782 if (txt == _(modifiers[i].name)) {
783 Keyboard::set_trim_overlap_modifier (modifiers[i].modifier);
789 void trim_anchored_modifier_chosen ()
791 string const txt = _trim_anchored_combo.get_active_text();
793 for (int i = 0; modifiers[i].name; ++i) {
794 if (txt == _(modifiers[i].name)) {
795 Keyboard::set_trim_anchored_modifier (modifiers[i].modifier);
801 void trim_jump_modifier_chosen ()
803 string const txt = _trim_jump_combo.get_active_text();
805 for (int i = 0; modifiers[i].name; ++i) {
806 if (txt == _(modifiers[i].name)) {
807 Keyboard::set_trim_jump_modifier (modifiers[i].modifier);
813 void fine_adjust_modifier_chosen ()
815 string const txt = _fine_adjust_combo.get_active_text();
817 for (int i = 0; modifiers[i].name; ++i) {
818 if (txt == _(modifiers[i].name)) {
819 Keyboard::set_fine_adjust_modifier (modifiers[i].modifier);
825 void push_points_modifier_chosen ()
827 string const txt = _push_points_combo.get_active_text();
829 for (int i = 0; modifiers[i].name; ++i) {
830 if (txt == _(modifiers[i].name)) {
831 Keyboard::set_push_points_modifier (modifiers[i].modifier);
837 void note_size_relative_modifier_chosen ()
839 string const txt = _note_size_relative_combo.get_active_text();
841 for (int i = 0; modifiers[i].name; ++i) {
842 if (txt == _(modifiers[i].name)) {
843 Keyboard::set_note_size_relative_modifier (modifiers[i].modifier);
849 void delete_button_changed ()
851 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
854 void edit_button_changed ()
856 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
859 void insert_note_button_changed ()
861 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
864 ComboBoxText _keyboard_layout_selector;
865 ComboBoxText _edit_modifier_combo;
866 ComboBoxText _delete_modifier_combo;
867 ComboBoxText _copy_modifier_combo;
868 ComboBoxText _insert_note_modifier_combo;
869 ComboBoxText _snap_modifier_combo;
870 ComboBoxText _snap_delta_combo;
871 ComboBoxText _trim_contents_combo;
872 ComboBoxText _trim_overlap_combo;
873 ComboBoxText _trim_anchored_combo;
874 ComboBoxText _trim_jump_combo;
875 ComboBoxText _fine_adjust_combo;
876 ComboBoxText _push_points_combo;
877 ComboBoxText _note_size_relative_combo;
878 Adjustment _delete_button_adjustment;
879 SpinButton _delete_button_spin;
880 Adjustment _edit_button_adjustment;
881 SpinButton _edit_button_spin;
882 Adjustment _insert_note_button_adjustment;
883 SpinButton _insert_note_button_spin;
887 class FontScalingOptions : public OptionEditorBox
890 FontScalingOptions (UIConfiguration* uic) :
892 _dpi_adjustment (100, 50, 250, 1, 5),
893 _dpi_slider (_dpi_adjustment)
895 _dpi_adjustment.set_value (_ui_config->get_font_scale() / 1024.);
897 Label* l = manage (new Label (_("GUI and Font scaling:")));
898 l->set_name ("OptionsLabel");
900 const Glib::ustring dflt = _("Default");
901 const Glib::ustring empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
903 _dpi_slider.set_name("FontScaleSlider");
904 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
905 _dpi_slider.set_draw_value(false);
906 _dpi_slider.add_mark(50, Gtk::POS_TOP, empty);
907 _dpi_slider.add_mark(60, Gtk::POS_TOP, empty);
908 _dpi_slider.add_mark(70, Gtk::POS_TOP, empty);
909 _dpi_slider.add_mark(80, Gtk::POS_TOP, empty);
910 _dpi_slider.add_mark(90, Gtk::POS_TOP, empty);
911 _dpi_slider.add_mark(100, Gtk::POS_TOP, dflt);
912 _dpi_slider.add_mark(125, Gtk::POS_TOP, empty);
913 _dpi_slider.add_mark(150, Gtk::POS_TOP, empty);
914 _dpi_slider.add_mark(175, Gtk::POS_TOP, empty);
915 _dpi_slider.add_mark(200, Gtk::POS_TOP, empty);
916 _dpi_slider.add_mark(225, Gtk::POS_TOP, empty);
917 _dpi_slider.add_mark(250, Gtk::POS_TOP, empty);
919 HBox* h = manage (new HBox);
921 h->pack_start (*l, false, false);
922 h->pack_start (_dpi_slider, true, true);
924 _box->pack_start (*h, false, false);
926 set_note (_("Adjusting the scale require an application restart to re-layout."));
928 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
931 void parameter_changed (string const & p)
933 if (p == "font-scale") {
934 _dpi_adjustment.set_value (_ui_config->get_font_scale() / 1024.);
938 void set_state_from_config ()
940 parameter_changed ("font-scale");
947 _ui_config->set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024.));
948 /* XXX: should be triggered from the parameter changed signal */
952 UIConfiguration* _ui_config;
953 Adjustment _dpi_adjustment;
957 class ClipLevelOptions : public OptionEditorBox
960 ClipLevelOptions (UIConfiguration* c)
962 , _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
963 , _clip_level_slider (_clip_level_adjustment)
965 _clip_level_adjustment.set_value (_ui_config->get_waveform_clip_level ());
967 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
968 l->set_name ("OptionsLabel");
970 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
971 HBox* h = manage (new HBox);
973 h->pack_start (*l, false, false);
974 h->pack_start (_clip_level_slider, true, true);
976 _box->pack_start (*h, false, false);
978 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
981 void parameter_changed (string const & p)
983 if (p == "waveform-clip-level") {
984 _clip_level_adjustment.set_value (_ui_config->get_waveform_clip_level());
988 void set_state_from_config ()
990 parameter_changed ("waveform-clip-level");
995 void clip_level_changed ()
997 _ui_config->set_waveform_clip_level (_clip_level_adjustment.get_value());
998 /* XXX: should be triggered from the parameter changed signal */
999 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1002 UIConfiguration* _ui_config;
1003 Adjustment _clip_level_adjustment;
1004 HScale _clip_level_slider;
1007 class BufferingOptions : public OptionEditorBox
1010 BufferingOptions (RCConfiguration* c)
1012 , _playback_adjustment (5, 1, 60, 1, 4)
1013 , _capture_adjustment (5, 1, 60, 1, 4)
1014 , _playback_slider (_playback_adjustment)
1015 , _capture_slider (_capture_adjustment)
1017 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1019 Label* l = manage (new Label (_("Playback (seconds of buffering):")));
1020 l->set_name ("OptionsLabel");
1022 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1023 HBox* h = manage (new HBox);
1025 h->pack_start (*l, false, false);
1026 h->pack_start (_playback_slider, true, true);
1028 _box->pack_start (*h, false, false);
1030 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1032 l = manage (new Label (_("Recording (seconds of buffering):")));
1033 l->set_name ("OptionsLabel");
1035 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1036 h = manage (new HBox);
1038 h->pack_start (*l, false, false);
1039 h->pack_start (_capture_slider, true, true);
1041 _box->pack_start (*h, false, false);
1043 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
1044 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
1047 void parameter_changed (string const & p)
1049 if (p == "playback-buffer-seconds") {
1050 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1051 } else if (p == "capture-buffer-seconds") {
1052 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1056 void set_state_from_config ()
1058 parameter_changed ("playback-buffer-seconds");
1059 parameter_changed ("capture-buffer-seconds");
1064 void playback_changed ()
1066 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
1069 void capture_changed ()
1071 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
1074 RCConfiguration* _rc_config;
1075 Adjustment _playback_adjustment;
1076 Adjustment _capture_adjustment;
1077 HScale _playback_slider;
1078 HScale _capture_slider;
1081 class ControlSurfacesOptions : public OptionEditorBox
1084 ControlSurfacesOptions (Gtk::Window& parent)
1086 , _ignore_view_change (0)
1088 _store = ListStore::create (_model);
1089 _view.set_model (_store);
1090 _view.append_column (_("Control Surface Protocol"), _model.name);
1091 _view.get_column(0)->set_resizable (true);
1092 _view.get_column(0)->set_expand (true);
1093 _view.append_column_editable (_("Enabled"), _model.enabled);
1094 _view.append_column_editable (_("Feedback"), _model.feedback);
1096 _box->pack_start (_view, false, false);
1098 Label* label = manage (new Label);
1099 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
1101 _box->pack_start (*label, false, false);
1104 ControlProtocolManager& m = ControlProtocolManager::instance ();
1105 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1106 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1108 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1109 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1112 void parameter_changed (std::string const &)
1117 void set_state_from_config ()
1121 ControlProtocolManager& m = ControlProtocolManager::instance ();
1122 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1124 if (!(*i)->mandatory) {
1125 TreeModel::Row r = *_store->append ();
1126 r[_model.name] = (*i)->name;
1127 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1128 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
1129 r[_model.protocol_info] = *i;
1136 void protocol_status_changed (ControlProtocolInfo* cpi) {
1138 TreeModel::Children rows = _store->children();
1140 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1141 string n = ((*x)[_model.name]);
1143 if ((*x)[_model.protocol_info] == cpi) {
1144 _ignore_view_change++;
1145 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1146 _ignore_view_change--;
1152 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1154 TreeModel::Row r = *i;
1156 if (_ignore_view_change) {
1160 ControlProtocolInfo* cpi = r[_model.protocol_info];
1165 bool const was_enabled = (cpi->protocol != 0);
1166 bool const is_enabled = r[_model.enabled];
1169 if (was_enabled != is_enabled) {
1172 ControlProtocolManager::instance().activate (*cpi);
1174 ControlProtocolManager::instance().deactivate (*cpi);
1178 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
1179 bool const is_feedback = r[_model.feedback];
1181 if (was_feedback != is_feedback && cpi->protocol) {
1182 cpi->protocol->set_feedback (is_feedback);
1186 void edit_clicked (GdkEventButton* ev)
1188 if (ev->type != GDK_2BUTTON_PRESS) {
1193 ControlProtocolInfo* cpi;
1196 row = *(_view.get_selection()->get_selected());
1197 if (!row[_model.enabled]) {
1200 cpi = row[_model.protocol_info];
1201 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1204 Box* box = (Box*) cpi->protocol->get_gui ();
1208 if (box->get_parent()) {
1209 static_cast<ArdourWindow*>(box->get_parent())->present();
1212 string title = row[_model.name];
1213 /* once created, the window is managed by the surface itself (as ->get_parent())
1214 * Surface's tear_down_gui() is called on session close, when de-activating
1215 * or re-initializing a surface.
1216 * tear_down_gui() hides an deletes the Window if it exists.
1218 ArdourWindow* win = new ArdourWindow (_parent, title);
1219 win->set_title ("Control Protocol Options");
1225 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1229 ControlSurfacesModelColumns ()
1234 add (protocol_info);
1237 TreeModelColumn<string> name;
1238 TreeModelColumn<bool> enabled;
1239 TreeModelColumn<bool> feedback;
1240 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1243 Glib::RefPtr<ListStore> _store;
1244 ControlSurfacesModelColumns _model;
1246 Gtk::Window& _parent;
1247 PBD::ScopedConnection protocol_status_connection;
1248 uint32_t _ignore_view_change;
1251 class VideoTimelineOptions : public OptionEditorBox
1254 VideoTimelineOptions (RCConfiguration* c)
1256 , _show_video_export_info_button (_("Show Video Export Info before export"))
1257 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1258 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1260 Table* t = manage (new Table (2, 6));
1261 t->set_spacings (4);
1263 t->attach (_video_advanced_setup_button, 0, 2, 0, 1);
1264 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1265 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1266 _("<b>When enabled</b> you can speficify a custom video-server URL and docroot. - Do not enable this option unless you know what you are doing."));
1268 Label* l = manage (new Label (_("Video Server URL:")));
1269 l->set_alignment (0, 0.5);
1270 t->attach (*l, 0, 1, 1, 2, FILL);
1271 t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL);
1272 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1273 _("Base URL of the video-server including http prefix. This is usually 'http://hostname.example.org:1554/' and defaults to 'http://localhost:1554/' when the video-server is running locally"));
1275 l = manage (new Label (_("Video Folder:")));
1276 l->set_alignment (0, 0.5);
1277 t->attach (*l, 0, 1, 2, 3, FILL);
1278 t->attach (_video_server_docroot_entry, 1, 2, 2, 3);
1279 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1280 _("Local path to the video-server document-root. Only files below this directory will be accessible by the video-server. If the server run on a remote host, it should point to a network mounted folder of the server's docroot or be left empty if it is unvailable. It is used for the local video-monitor and file-browsing when opening/adding a video file."));
1282 /* small vspace y=3..4 */
1284 t->attach (_show_video_export_info_button, 0, 2, 4, 5);
1285 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1286 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1287 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1289 t->attach (_show_video_server_dialog_button, 0, 2, 5, 6);
1290 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1291 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1292 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1294 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1295 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1296 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1297 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1299 _box->pack_start (*t,true,true);
1302 void server_url_changed ()
1304 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1307 void server_docroot_changed ()
1309 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1312 void show_video_export_info_toggled ()
1314 bool const x = _show_video_export_info_button.get_active ();
1315 _rc_config->set_show_video_export_info (x);
1318 void show_video_server_dialog_toggled ()
1320 bool const x = _show_video_server_dialog_button.get_active ();
1321 _rc_config->set_show_video_server_dialog (x);
1324 void video_advanced_setup_toggled ()
1326 bool const x = _video_advanced_setup_button.get_active ();
1327 _rc_config->set_video_advanced_setup(x);
1330 void parameter_changed (string const & p)
1332 if (p == "video-server-url") {
1333 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1334 } else if (p == "video-server-docroot") {
1335 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1336 } else if (p == "show-video-export-info") {
1337 bool const x = _rc_config->get_show_video_export_info();
1338 _show_video_export_info_button.set_active (x);
1339 } else if (p == "show-video-server-dialog") {
1340 bool const x = _rc_config->get_show_video_server_dialog();
1341 _show_video_server_dialog_button.set_active (x);
1342 } else if (p == "video-advanced-setup") {
1343 bool const x = _rc_config->get_video_advanced_setup();
1344 _video_advanced_setup_button.set_active(x);
1345 _video_server_docroot_entry.set_sensitive(x);
1346 _video_server_url_entry.set_sensitive(x);
1350 void set_state_from_config ()
1352 parameter_changed ("video-server-url");
1353 parameter_changed ("video-server-docroot");
1354 parameter_changed ("video-monitor-setup-dialog");
1355 parameter_changed ("show-video-export-info");
1356 parameter_changed ("show-video-server-dialog");
1357 parameter_changed ("video-advanced-setup");
1361 RCConfiguration* _rc_config;
1362 Entry _video_server_url_entry;
1363 Entry _video_server_docroot_entry;
1364 CheckButton _show_video_export_info_button;
1365 CheckButton _show_video_server_dialog_button;
1366 CheckButton _video_advanced_setup_button;
1369 class PluginOptions : public OptionEditorBox
1372 PluginOptions (RCConfiguration* c, UIConfiguration* uic)
1375 , _display_plugin_scan_progress (_("Always Display Plugin Scan Progress"))
1376 , _discover_vst_on_start (_("Scan for [new] VST Plugins on Application Start"))
1377 , _discover_au_on_start (_("Scan for AudioUnit Plugins on Application Start"))
1378 , _timeout_adjustment (0, 0, 3000, 50, 50)
1379 , _timeout_slider (_timeout_adjustment)
1382 std::stringstream ss;
1383 Table* t = manage (new Table (2, 6));
1384 t->set_spacings (4);
1388 ss << "<b>" << _("General") << "</b>";
1389 l = manage (left_aligned_label (ss.str()));
1390 l->set_use_markup (true);
1391 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1392 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1394 b = manage (new Button (_("Scan for Plugins")));
1395 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1396 t->attach (*b, 0, 2, n, n+1, FILL); ++n;
1398 t->attach (_display_plugin_scan_progress, 0, 2, n, n+1); ++n;
1399 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1400 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1401 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
1403 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
1404 _timeout_slider.set_digits (0);
1405 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &PluginOptions::timeout_changed));
1407 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1408 _("Specify the default timeout for plugin instantiation in 1/10 seconds. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1410 l = manage (left_aligned_label (_("Scan Time Out [deciseconds]")));;
1411 HBox* h = manage (new HBox);
1413 h->pack_start (*l, false, false);
1414 h->pack_start (_timeout_slider, true, true);
1415 t->attach (*h, 0, 2, n, n+1); ++n;
1418 ss << "<b>" << _("VST") << "</b>";
1419 l = manage (left_aligned_label (ss.str()));
1420 l->set_use_markup (true);
1421 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1422 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1424 b = manage (new Button (_("Clear VST Cache")));
1425 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_cache_clicked));
1426 t->attach (*b, 0, 1, n, n+1, FILL);
1428 b = manage (new Button (_("Clear VST Blacklist")));
1429 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_blacklist_clicked));
1430 t->attach (*b, 1, 2, n, n+1, FILL);
1433 t->attach (_discover_vst_on_start, 0, 2, n, n+1); ++n;
1434 _discover_vst_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_vst_on_start_toggled));
1435 Gtkmm2ext::UI::instance()->set_tip (_discover_vst_on_start,
1436 _("<b>When enabled</b> new VST plugins are searched, tested and added to the cache index on application start. When disabled new plugins will only be available after triggering a 'Scan' manually"));
1438 #ifdef LXVST_SUPPORT
1439 t->attach (*manage (left_aligned_label (_("Linux VST Path:"))), 0, 1, n, n+1);
1440 b = manage (new Button (_("Edit")));
1441 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_lxvst_path_clicked));
1442 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1445 #ifdef WINDOWS_VST_SUPPORT
1446 t->attach (*manage (left_aligned_label (_("Windows VST Path:"))), 0, 1, n, n+1);
1447 b = manage (new Button (_("Edit")));
1448 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_vst_path_clicked));
1449 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1453 #ifdef AUDIOUNIT_SUPPORT
1455 ss << "<b>" << _("Audio Unit") << "</b>";
1456 l = manage (left_aligned_label (ss.str()));
1457 l->set_use_markup (true);
1458 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1459 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1461 t->attach (_discover_au_on_start, 0, 2, n, n+1); ++n;
1462 _discover_au_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_au_on_start_toggled));
1463 Gtkmm2ext::UI::instance()->set_tip (_discover_au_on_start,
1464 _("<b>When enabled</b> Audio Unit Plugins are discovered on application start. When disabled AU plugins will only be available after triggering a 'Scan' manually. The first successful scan will enable AU auto-scan, Any crash during plugin discovery will disable it."));
1467 b = manage (new Button (_("Clear AU Cache")));
1468 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_cache_clicked));
1469 t->attach (*b, 0, 1, n, n+1, FILL);
1471 b = manage (new Button (_("Clear AU Blacklist")));
1472 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_blacklist_clicked));
1473 t->attach (*b, 1, 2, n, n+1, FILL);
1477 _box->pack_start (*t,true,true);
1480 void parameter_changed (string const & p) {
1481 if (p == "show-plugin-scan-window") {
1482 bool const x = _ui_config->get_show_plugin_scan_window();
1483 _display_plugin_scan_progress.set_active (x);
1485 else if (p == "discover-vst-on-start") {
1486 bool const x = _rc_config->get_discover_vst_on_start();
1487 _discover_vst_on_start.set_active (x);
1489 else if (p == "vst-scan-timeout") {
1490 int const x = _rc_config->get_vst_scan_timeout();
1491 _timeout_adjustment.set_value (x);
1493 else if (p == "discover-audio-units") {
1494 bool const x = _rc_config->get_discover_audio_units();
1495 _discover_au_on_start.set_active (x);
1499 void set_state_from_config () {
1500 parameter_changed ("show-plugin-scan-window");
1501 parameter_changed ("discover-vst-on-start");
1502 parameter_changed ("vst-scan-timeout");
1503 parameter_changed ("discover-audio-units");
1507 RCConfiguration* _rc_config;
1508 UIConfiguration* _ui_config;
1509 CheckButton _display_plugin_scan_progress;
1510 CheckButton _discover_vst_on_start;
1511 CheckButton _discover_au_on_start;
1512 Adjustment _timeout_adjustment;
1513 HScale _timeout_slider;
1515 void display_plugin_scan_progress_toggled () {
1516 bool const x = _display_plugin_scan_progress.get_active();
1517 _ui_config->set_show_plugin_scan_window(x);
1520 void discover_vst_on_start_toggled () {
1521 bool const x = _discover_vst_on_start.get_active();
1522 _rc_config->set_discover_vst_on_start(x);
1525 void discover_au_on_start_toggled () {
1526 bool const x = _discover_au_on_start.get_active();
1527 _rc_config->set_discover_audio_units(x);
1530 void timeout_changed () {
1531 int x = floor(_timeout_adjustment.get_value());
1532 _rc_config->set_vst_scan_timeout(x);
1535 void clear_vst_cache_clicked () {
1536 PluginManager::instance().clear_vst_cache();
1539 void clear_vst_blacklist_clicked () {
1540 PluginManager::instance().clear_vst_blacklist();
1543 void clear_au_cache_clicked () {
1544 PluginManager::instance().clear_au_cache();
1547 void clear_au_blacklist_clicked () {
1548 PluginManager::instance().clear_au_blacklist();
1552 void edit_vst_path_clicked () {
1553 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1554 _("Set Windows VST Search Path"),
1555 _rc_config->get_plugin_path_vst(),
1556 PluginManager::instance().get_default_windows_vst_path()
1558 ResponseType r = (ResponseType) pd->run ();
1560 if (r == RESPONSE_ACCEPT) {
1561 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
1566 // todo consolidate with edit_vst_path_clicked..
1567 void edit_lxvst_path_clicked () {
1568 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1569 _("Set Linux VST Search Path"),
1570 _rc_config->get_plugin_path_lxvst(),
1571 PluginManager::instance().get_default_lxvst_path()
1573 ResponseType r = (ResponseType) pd->run ();
1575 if (r == RESPONSE_ACCEPT) {
1576 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
1581 void refresh_clicked () {
1582 PluginManager::instance().refresh();
1587 /** A class which allows control of visibility of some editor components usign
1588 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1589 * which has the correct members, but with null widget pointers. This
1590 * class allows the user to set visibility of the members, the details
1591 * of which are stored in a configuration variable which can be watched
1592 * by parts of the editor that actually contain the widgets whose visibility
1593 * is being controlled.
1596 class VisibilityOption : public Option
1599 /** @param name User-visible name for this group.
1600 * @param g `Dummy' VisibilityGroup (as described above).
1601 * @param get Method to get the value of the appropriate configuration variable.
1602 * @param set Method to set the value of the appropriate configuration variable.
1604 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1605 : Option (g->get_state_name(), name)
1607 , _visibility_group (g)
1611 /* Watch for changes made by the user to our members */
1612 _visibility_group->VisibilityChanged.connect_same_thread (
1613 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1617 void set_state_from_config ()
1619 /* Set our state from the current configuration */
1620 _visibility_group->set_state (_get ());
1623 void add_to_page (OptionEditorPage* p)
1625 _heading.add_to_page (p);
1626 add_widget_to_page (p, _visibility_group->list_view ());
1629 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1634 /* The user has changed something, so reflect this change
1635 in the RCConfiguration.
1637 _set (_visibility_group->get_state_value ());
1640 OptionEditorHeading _heading;
1641 VisibilityGroup* _visibility_group;
1642 sigc::slot<std::string> _get;
1643 sigc::slot<bool, std::string> _set;
1644 PBD::ScopedConnection _visibility_group_connection;
1649 RCOptionEditor::RCOptionEditor ()
1650 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1651 , _rc_config (Config)
1652 , _ui_config (ARDOUR_UI::config())
1653 , _mixer_strip_visibility ("mixer-element-visibility")
1657 uint32_t hwcpus = hardware_concurrency ();
1659 BoolComboOption* bco;
1662 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1664 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1666 _("Signal processing uses"),
1667 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1668 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1671 procs->add (-1, _("all but one processor"));
1672 procs->add (0, _("all available processors"));
1674 for (uint32_t i = 1; i <= hwcpus; ++i) {
1675 procs->add (i, string_compose (_("%1 processors"), i));
1678 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1680 add_option (_("Misc"), procs);
1683 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1685 add_option (_("Misc"), new UndoOptions (_rc_config));
1687 add_option (_("Misc"),
1689 "verify-remove-last-capture",
1690 _("Verify removal of last capture"),
1691 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1692 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1695 add_option (_("Misc"),
1697 "periodic-safety-backups",
1698 _("Make periodic backups of the session file"),
1699 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1700 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1703 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1705 add_option (_("Misc"),
1707 "only-copy-imported-files",
1708 _("Always copy imported files"),
1709 sigc::mem_fun (*_ui_config, &UIConfiguration::get_only_copy_imported_files),
1710 sigc::mem_fun (*_ui_config, &UIConfiguration::set_only_copy_imported_files)
1713 add_option (_("Misc"), new DirectoryOption (
1714 X_("default-session-parent-dir"),
1715 _("Default folder for new sessions:"),
1716 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1717 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1720 add_option (_("Misc"),
1721 new SpinOption<uint32_t> (
1722 "max-recent-sessions",
1723 _("Maximum number of recent sessions"),
1724 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1725 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1729 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1731 add_option (_("Misc"), new ClickOptions (_rc_config, this));
1733 add_option (_("Misc"),
1736 _("Click gain level"),
1737 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1738 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1741 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1743 add_option (_("Misc"),
1744 new SpinOption<double> (
1745 "automation-thinning-factor",
1746 _("Thinning factor (larger value => less data)"),
1747 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1748 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1752 add_option (_("Misc"),
1753 new SpinOption<double> (
1754 "automation-interval-msecs",
1755 _("Automation sampling interval (milliseconds)"),
1756 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1757 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1765 tsf = new BoolOption (
1766 "latched-record-enable",
1767 _("Keep record-enable engaged on stop"),
1768 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1769 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1771 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1772 add_option (_("Transport"), tsf);
1774 tsf = new BoolOption (
1776 _("Play loop is a transport mode"),
1777 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1778 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1780 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1781 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1782 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1783 add_option (_("Transport"), tsf);
1785 tsf = new BoolOption (
1786 "stop-recording-on-xrun",
1787 _("Stop recording when an xrun occurs"),
1788 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1789 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1791 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1792 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
1794 add_option (_("Transport"), tsf);
1796 tsf = new BoolOption (
1797 "create-xrun-marker",
1798 _("Create markers where xruns occur"),
1799 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
1800 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
1802 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1803 add_option (_("Transport"), tsf);
1805 tsf = new BoolOption (
1806 "stop-at-session-end",
1807 _("Stop at the end of the session"),
1808 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
1809 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
1811 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1812 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
1813 "when it reaches the current session end marker\n\n"
1814 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
1816 add_option (_("Transport"), tsf);
1818 tsf = new BoolOption (
1820 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
1821 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
1822 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
1824 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1825 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
1826 "preventing any need to do a transport locate at the end of the loop\n\n"
1827 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
1828 "which will often cause a small click or delay"), PROGRAM_NAME));
1829 add_option (_("Transport"), tsf);
1831 tsf = new BoolOption (
1832 "disable-disarm-during-roll",
1833 _("Disable per-track record disarm while rolling"),
1834 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
1835 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
1837 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"));
1838 add_option (_("Transport"), tsf);
1840 tsf = new BoolOption (
1842 _("12dB gain reduction during fast-forward and fast-rewind"),
1843 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
1844 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
1846 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
1847 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
1848 add_option (_("Transport"), tsf);
1850 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
1852 _sync_source = new ComboOption<SyncSource> (
1854 _("External timecode source"),
1855 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
1856 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
1859 add_option (_("Transport"), _sync_source);
1861 _sync_framerate = new BoolOption (
1862 "timecode-sync-frame-rate",
1863 _("Match session video frame rate to external timecode"),
1864 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
1865 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
1867 Gtkmm2ext::UI::instance()->set_tip
1868 (_sync_framerate->tip_widget(),
1869 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
1870 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
1871 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
1872 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
1873 "timecode standard and the session standard."), PROGRAM_NAME));
1875 add_option (_("Transport"), _sync_framerate);
1877 _sync_genlock = new BoolOption (
1878 "timecode-source-is-synced",
1879 _("Sync-lock timecode to clock (disable drift compensation)"),
1880 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
1881 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
1883 Gtkmm2ext::UI::instance()->set_tip
1884 (_sync_genlock->tip_widget(),
1885 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
1886 "Sync Lock indicates that the selected external timecode source shares clock-sync "
1887 "(Black & Burst, Wordclock, etc) with the audio interface. "
1888 "This option disables drift compensation. The transport speed is fixed at 1.0. "
1889 "Vari-speed LTC will be ignored and cause drift."
1891 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
1892 "timecode sources shares clock sync."
1896 add_option (_("Transport"), _sync_genlock);
1898 _sync_source_2997 = new BoolOption (
1899 "timecode-source-2997",
1900 _("Lock to 29.9700 fps instead of 30000/1001"),
1901 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
1902 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
1904 Gtkmm2ext::UI::instance()->set_tip
1905 (_sync_source_2997->tip_widget(),
1906 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
1907 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
1908 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
1909 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
1910 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
1911 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
1914 add_option (_("Transport"), _sync_source_2997);
1916 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
1918 _ltc_port = new ComboStringOption (
1920 _("LTC incoming port"),
1921 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
1922 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
1925 vector<string> physical_inputs;
1926 physical_inputs.push_back (_("None"));
1927 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
1928 _ltc_port->set_popdown_strings (physical_inputs);
1930 populate_sync_options ();
1932 add_option (_("Transport"), _ltc_port);
1934 // TODO; rather disable this button than not compile it..
1935 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
1937 add_option (_("Transport"),
1940 _("Enable LTC generator"),
1941 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
1942 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
1945 _ltc_send_continuously = new BoolOption (
1946 "ltc-send-continuously",
1947 _("Send LTC while stopped"),
1948 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
1949 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
1951 Gtkmm2ext::UI::instance()->set_tip
1952 (_ltc_send_continuously->tip_widget(),
1953 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
1954 add_option (_("Transport"), _ltc_send_continuously);
1956 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
1957 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
1958 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
1959 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
1961 Gtkmm2ext::UI::instance()->set_tip
1962 (_ltc_volume_slider->tip_widget(),
1963 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
1965 add_option (_("Transport"), _ltc_volume_slider);
1966 parameter_changed ("send-ltc");
1968 parameter_changed ("sync-source");
1972 add_option (S_("Editor"),
1974 "draggable-playhead",
1975 _("Allow dragging of playhead"),
1976 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_draggable_playhead),
1977 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_draggable_playhead)
1980 add_option (_("Editor"),
1982 "automation-follows-regions",
1983 _("Move relevant automation when audio regions are moved"),
1984 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
1985 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
1988 add_option (_("Editor"),
1990 "show-track-meters",
1991 _("Show meters on tracks in the editor"),
1992 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_track_meters),
1993 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_track_meters)
1996 add_option (_("Editor"),
1998 "show-editor-meter",
1999 _("Display master-meter in the toolbar"),
2000 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_editor_meter),
2001 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_editor_meter)
2004 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2005 "default-fade-shape",
2006 _("Default fade shape"),
2007 sigc::mem_fun (*_rc_config,
2008 &RCConfiguration::get_default_fade_shape),
2009 sigc::mem_fun (*_rc_config,
2010 &RCConfiguration::set_default_fade_shape)
2013 fadeshape->add (FadeLinear,
2014 _("Linear (for highly correlated material)"));
2015 fadeshape->add (FadeConstantPower, _("Constant power"));
2016 fadeshape->add (FadeSymmetric, _("Symmetric"));
2017 fadeshape->add (FadeSlow, _("Slow"));
2018 fadeshape->add (FadeFast, _("Fast"));
2020 add_option (_("Editor"), fadeshape);
2023 bco = new BoolComboOption (
2024 "use-overlap-equivalency",
2025 _("Regions in active edit groups are edited together"),
2026 _("whenever they overlap in time"),
2027 _("only if they have identical length, position and origin"),
2028 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2029 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2032 add_option (_("Editor"), bco);
2034 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2036 _("Layering model"),
2037 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2038 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2041 lm->add (LaterHigher, _("later is higher"));
2042 lm->add (Manual, _("manual layering"));
2043 add_option (_("Editor"), lm);
2045 add_option (_("Editor"),
2047 "rubberbanding-snaps-to-grid",
2048 _("Make rubberband selection rectangle snap to the grid"),
2049 sigc::mem_fun (*_ui_config, &UIConfiguration::get_rubberbanding_snaps_to_grid),
2050 sigc::mem_fun (*_ui_config, &UIConfiguration::set_rubberbanding_snaps_to_grid)
2053 add_option (_("Editor"),
2056 _("Show waveforms in regions"),
2057 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms),
2058 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms)
2061 add_option (_("Editor"),
2062 new BoolComboOption (
2063 "show-region-gain-envelopes",
2064 _("Show gain envelopes in audio regions"),
2066 _("only in region gain mode"),
2067 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_region_gain),
2068 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_region_gain)
2071 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
2073 _("Waveform scale"),
2074 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_scale),
2075 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_scale)
2078 wfs->add (Linear, _("linear"));
2079 wfs->add (Logarithmic, _("logarithmic"));
2081 add_option (_("Editor"), wfs);
2083 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
2085 _("Waveform shape"),
2086 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_shape),
2087 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_shape)
2090 wfsh->add (Traditional, _("traditional"));
2091 wfsh->add (Rectified, _("rectified"));
2093 add_option (_("Editor"), wfsh);
2095 add_option (_("Editor"), new ClipLevelOptions (_ui_config));
2097 add_option (_("Editor"),
2099 "show-waveforms-while-recording",
2100 _("Show waveforms for audio while it is being recorded"),
2101 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms_while_recording),
2102 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms_while_recording)
2105 add_option (_("Editor"),
2108 _("Show zoom toolbar"),
2109 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_zoom_tools),
2110 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_zoom_tools)
2113 add_option (_("Editor"),
2115 "update-editor-during-summary-drag",
2116 _("Update editor window during drags of the summary"),
2117 sigc::mem_fun (*_ui_config, &UIConfiguration::get_update_editor_during_summary_drag),
2118 sigc::mem_fun (*_ui_config, &UIConfiguration::set_update_editor_during_summary_drag)
2121 bo = new BoolOption (
2123 _("Name new markers"),
2124 sigc::mem_fun (*_ui_config, &UIConfiguration::get_name_new_markers),
2125 sigc::mem_fun (*_ui_config, &UIConfiguration::set_name_new_markers)
2128 add_option (_("Editor"), bo);
2129 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(), _("If enabled, popup a dialog when a new marker is created to allow its name to be set as it is created."
2130 "\n\nYou can always rename markers by right-clicking on them"));
2132 add_option (_("Editor"),
2134 "autoscroll-editor",
2135 _("Auto-scroll editor window when dragging near its edges"),
2136 sigc::mem_fun (*_ui_config, &UIConfiguration::get_autoscroll_editor),
2137 sigc::mem_fun (*_ui_config, &UIConfiguration::set_autoscroll_editor)
2140 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2141 "region-selection-after-split",
2142 _("After splitting selected regions, select"),
2143 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2144 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2146 // TODO: decide which of these modes are really useful
2147 rsas->add(None, _("no regions"));
2148 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2149 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2150 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2151 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2152 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2153 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2154 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2156 add_option (_("Editor"), rsas);
2161 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2163 add_option (_("Audio"), new BufferingOptions (_rc_config));
2165 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2167 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2169 _("Record monitoring handled by"),
2170 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2171 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2174 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2175 mm->add (HardwareMonitoring, _("via Audio Driver"));
2178 string prog (PROGRAM_NAME);
2179 boost::algorithm::to_lower (prog);
2180 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2181 mm->add (ExternalMonitoring, _("audio hardware"));
2183 add_option (_("Audio"), mm);
2185 add_option (_("Audio"),
2187 "tape-machine-mode",
2188 _("Tape machine mode"),
2189 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2190 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2193 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
2195 add_option (_("Audio"),
2197 "auto-connect-standard-busses",
2198 _("Auto-connect master/monitor busses"),
2199 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2200 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2203 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2204 "input-auto-connect",
2205 _("Connect track inputs"),
2206 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2207 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2210 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2211 iac->add (ManualConnect, _("manually"));
2213 add_option (_("Audio"), iac);
2215 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2216 "output-auto-connect",
2217 _("Connect track and bus outputs"),
2218 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2219 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2222 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2223 oac->add (AutoConnectMaster, _("automatically to master bus"));
2224 oac->add (ManualConnect, _("manually"));
2226 add_option (_("Audio"), oac);
2228 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2230 add_option (_("Audio"),
2232 "denormal-protection",
2233 _("Use DC bias to protect against denormals"),
2234 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2235 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2238 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2240 _("Processor handling"),
2241 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2242 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2246 dm->add (DenormalNone, _("no processor handling"));
2250 if (fpu.has_flush_to_zero()) {
2252 dm->add (DenormalFTZ, _("use FlushToZero"));
2253 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2254 _rc_config->set_denormal_model(DenormalNone);
2257 if (fpu.has_denormals_are_zero()) {
2259 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2260 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2261 _rc_config->set_denormal_model(DenormalNone);
2264 if (fpu.has_flush_to_zero() && fpu.has_denormals_are_zero()) {
2266 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2267 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2268 _rc_config->set_denormal_model(DenormalNone);
2272 dm->set_sensitive(false);
2275 add_option (_("Audio"), dm);
2277 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
2279 add_option (_("Audio"),
2281 "plugins-stop-with-transport",
2282 _("Silence plugins when the transport is stopped"),
2283 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
2284 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
2287 add_option (_("Audio"),
2289 "new-plugins-active",
2290 _("Make new plugins active"),
2291 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
2292 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
2295 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2297 add_option (_("Audio"),
2299 "auto-analyse-audio",
2300 _("Enable automatic analysis of audio"),
2301 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2302 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2305 add_option (_("Audio"),
2307 "replicate-missing-region-channels",
2308 _("Replicate missing region channels"),
2309 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2310 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2315 add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
2317 add_option (_("Solo / mute"),
2320 _("Solo-in-place mute cut (dB)"),
2321 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2322 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2325 _solo_control_is_listen_control = new BoolOption (
2326 "solo-control-is-listen-control",
2327 _("Solo controls are Listen controls"),
2328 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2329 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2332 add_option (_("Solo / mute"), _solo_control_is_listen_control);
2334 _listen_position = new ComboOption<ListenPosition> (
2336 _("Listen Position"),
2337 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2338 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2341 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2342 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2344 add_option (_("Solo / mute"), _listen_position);
2346 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2348 _("PFL signals come from"),
2349 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2350 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2353 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2354 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2356 add_option (_("Solo / mute"), pp);
2358 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2360 _("AFL signals come from"),
2361 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2362 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2365 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2366 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2368 add_option (_("Solo / mute"), pa);
2370 parameter_changed ("use-monitor-bus");
2372 add_option (_("Solo / mute"),
2375 _("Exclusive solo"),
2376 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2377 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2380 add_option (_("Solo / mute"),
2383 _("Show solo muting"),
2384 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2385 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2388 add_option (_("Solo / mute"),
2390 "solo-mute-override",
2391 _("Soloing overrides muting"),
2392 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2393 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2396 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
2398 add_option (_("Solo / mute"),
2400 "mute-affects-pre-fader",
2401 _("Mute affects pre-fader sends"),
2402 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2403 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2406 add_option (_("Solo / mute"),
2408 "mute-affects-post-fader",
2409 _("Mute affects post-fader sends"),
2410 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2411 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2414 add_option (_("Solo / mute"),
2416 "mute-affects-control-outs",
2417 _("Mute affects control outputs"),
2418 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2419 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2422 add_option (_("Solo / mute"),
2424 "mute-affects-main-outs",
2425 _("Mute affects main outputs"),
2426 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2427 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2430 add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
2432 add_option (_("Solo / mute"),
2434 "link-send-and-route-panner",
2435 _("Link panners of Aux and External Sends with main panner by default"),
2436 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2437 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2440 add_option (_("MIDI"),
2441 new SpinOption<float> (
2443 _("MIDI read-ahead time (seconds)"),
2444 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2445 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2450 add_option (_("MIDI"),
2453 _("Send MIDI Clock"),
2454 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2455 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2458 add_option (_("MIDI"),
2461 _("Send MIDI Time Code"),
2462 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2463 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2466 add_option (_("MIDI"),
2467 new SpinOption<int> (
2468 "mtc-qf-speed-tolerance",
2469 _("Percentage either side of normal transport speed to transmit MTC"),
2470 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2471 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2475 add_option (_("MIDI"),
2478 _("Obey MIDI Machine Control commands"),
2479 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2480 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2483 add_option (_("MIDI"),
2486 _("Send MIDI Machine Control commands"),
2487 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2488 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2491 add_option (_("MIDI"),
2494 _("Send MIDI control feedback"),
2495 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2496 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2499 add_option (_("MIDI"),
2500 new SpinOption<uint8_t> (
2501 "mmc-receive-device-id",
2502 _("Inbound MMC device ID"),
2503 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2504 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2508 add_option (_("MIDI"),
2509 new SpinOption<uint8_t> (
2510 "mmc-send-device-id",
2511 _("Outbound MMC device ID"),
2512 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2513 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2517 add_option (_("MIDI"),
2518 new SpinOption<int32_t> (
2519 "initial-program-change",
2520 _("Initial program change"),
2521 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2522 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2526 add_option (_("MIDI"),
2528 "display-first-midi-bank-as-zero",
2529 _("Display first MIDI bank/program as 0"),
2530 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2531 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2534 add_option (_("MIDI"),
2536 "never-display-periodic-midi",
2537 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2538 sigc::mem_fun (*_ui_config, &UIConfiguration::get_never_display_periodic_midi),
2539 sigc::mem_fun (*_ui_config, &UIConfiguration::set_never_display_periodic_midi)
2542 add_option (_("MIDI"),
2545 _("Sound MIDI notes as they are selected"),
2546 sigc::mem_fun (*_ui_config, &UIConfiguration::get_sound_midi_notes),
2547 sigc::mem_fun (*_ui_config, &UIConfiguration::set_sound_midi_notes)
2550 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2552 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2553 "midi-audition-synth-uri",
2554 _("Midi Audition Synth (LV2)"),
2555 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2556 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2559 audition_synth->add(X_(""), _("None"));
2560 PluginInfoList all_plugs;
2561 PluginManager& manager (PluginManager::instance());
2563 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2565 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2566 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2567 if (!(*i)->is_instrument()) continue;
2568 if ((*i)->type != ARDOUR::LV2) continue;
2569 audition_synth->add((*i)->unique_id, (*i)->name);
2573 add_option (_("MIDI"), audition_synth);
2575 /* USER INTERACTION */
2578 #ifdef PLATFORM_WINDOWS
2581 getenv ("ARDOUR_BUNDLED")
2585 add_option (_("User interaction"),
2587 "enable-translation",
2588 string_compose (_("Use translations of %1 messages\n"
2589 " <i>(requires a restart of %1 to take effect)</i>\n"
2590 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2591 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2592 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2595 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2597 add_option (_("User interaction"), new KeyboardOptions);
2599 /* Control Surfaces */
2601 add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
2603 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2605 _("Control surface remote ID"),
2606 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2607 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2610 rm->add (UserOrdered, _("assigned by user"));
2611 rm->add (MixerOrdered, _("follows order of mixer"));
2613 add_option (_("Control Surfaces"), rm);
2615 /* VIDEO Timeline */
2616 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2618 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2619 /* Plugin options (currrently VST only) */
2620 add_option (_("Plugins"), new PluginOptions (_rc_config, _ui_config));
2625 add_option (S_("Preferences|GUI"),
2628 _("Graphically indicate mouse pointer hovering over various widgets"),
2629 sigc::mem_fun (*_ui_config, &UIConfiguration::get_widget_prelight),
2630 sigc::mem_fun (*_ui_config, &UIConfiguration::set_widget_prelight)
2633 #ifdef TOOLTIPS_GOT_FIXED
2634 add_option (S_("Preferences|GUI"),
2637 _("Show tooltips if mouse hovers over a control"),
2638 sigc::mem_fun (*_ui_config, &UIConfiguration::get_use_tooltips),
2639 sigc::mem_fun (*_ui_config, &UIConfiguration::set_use_tooltips)
2643 add_option (S_("Preferences|GUI"),
2645 "show-name-highlight",
2646 _("Use name highlight bars in region displays (requires a restart)"),
2647 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_name_highlight),
2648 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_name_highlight)
2652 /* font scaling does nothing with GDK/Quartz */
2653 add_option (S_("Preferences|GUI"), new FontScalingOptions (_ui_config));
2656 add_option (S_("GUI"),
2658 "super-rapid-clock-update",
2659 _("update transport clock display at FPS instead of every 100ms"),
2660 sigc::mem_fun (*_ui_config, &UIConfiguration::get_super_rapid_clock_update),
2661 sigc::mem_fun (*_ui_config, &UIConfiguration::set_super_rapid_clock_update)
2664 /* Lock GUI timeout */
2666 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
2667 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2668 _("Lock timeout (seconds)"),
2670 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_lock_gui_after_seconds),
2671 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_lock_gui_after_seconds)
2673 slts->scale().set_digits (0);
2674 Gtkmm2ext::UI::instance()->set_tip
2675 (slts->tip_widget(),
2676 _("Lock GUI after this many idle seconds (zero to never lock)"));
2677 add_option (S_("Preferences|GUI"), slts);
2679 /* The names of these controls must be the same as those given in MixerStrip
2680 for the actual widgets being controlled.
2682 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
2683 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2684 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
2685 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
2686 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
2687 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2690 S_("Preferences|GUI"),
2691 new VisibilityOption (
2693 &_mixer_strip_visibility,
2694 sigc::mem_fun (*_ui_config, &UIConfiguration::get_mixer_strip_visibility),
2695 sigc::mem_fun (*_ui_config, &UIConfiguration::set_mixer_strip_visibility)
2699 add_option (S_("Preferences|GUI"),
2701 "default-narrow_ms",
2702 _("Use narrow strips in the mixer by default"),
2703 sigc::mem_fun (*_ui_config, &UIConfiguration::get_default_narrow_ms),
2704 sigc::mem_fun (*_ui_config, &UIConfiguration::set_default_narrow_ms)
2707 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2709 ComboOption<float>* mht = new ComboOption<float> (
2711 _("Peak hold time"),
2712 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_hold),
2713 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_hold)
2716 mht->add (MeterHoldOff, _("off"));
2717 mht->add (MeterHoldShort, _("short"));
2718 mht->add (MeterHoldMedium, _("medium"));
2719 mht->add (MeterHoldLong, _("long"));
2721 add_option (S_("Preferences|Metering"), mht);
2723 ComboOption<float>* mfo = new ComboOption<float> (
2726 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2727 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2730 mfo->add (METER_FALLOFF_OFF, _("off"));
2731 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2732 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2733 mfo->add (METER_FALLOFF_SLOWISH, _("slowish [12.0dB/sec] (DIN)"));
2734 mfo->add (METER_FALLOFF_MODERATE, _("moderate [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2735 mfo->add (METER_FALLOFF_MEDIUM, _("medium [20dB/sec]"));
2736 mfo->add (METER_FALLOFF_FAST, _("fast [32dB/sec]"));
2737 mfo->add (METER_FALLOFF_FASTER, _("faster [46dB/sec]"));
2738 mfo->add (METER_FALLOFF_FASTEST, _("fastest [70dB/sec]"));
2740 add_option (S_("Preferences|Metering"), mfo);
2742 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2743 "meter-line-up-level",
2744 _("Meter line-up level; 0dBu"),
2745 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_level),
2746 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_level)
2749 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2750 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2751 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2752 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2754 Gtkmm2ext::UI::instance()->set_tip (mlu->tip_widget(), _("Configure meter-marks and color-knee point for dBFS scale DPM, set reference level for IEC1/Nordic, IEC2 PPM and VU meter."));
2756 add_option (S_("Preferences|Metering"), mlu);
2758 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2759 "meter-line-up-din",
2760 _("IEC1/DIN Meter line-up level; 0dBu"),
2761 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_din),
2762 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_din)
2765 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2766 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2767 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2768 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2770 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2772 add_option (S_("Preferences|Metering"), mld);
2774 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2775 "meter-vu-standard",
2776 _("VU Meter standard"),
2777 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_vu_standard),
2778 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_vu_standard)
2781 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2782 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2783 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2784 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2786 add_option (S_("Preferences|Metering"), mvu);
2788 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
2789 HSliderOption *mpks = new HSliderOption("meter-peak",
2790 _("Peak threshold [dBFS]"),
2792 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_peak),
2793 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_peak)
2796 Gtkmm2ext::UI::instance()->set_tip
2797 (mpks->tip_widget(),
2798 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
2800 add_option (S_("Preferences|Metering"), mpks);
2802 add_option (S_("Preferences|Metering"),
2805 _("LED meter style"),
2806 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_style_led),
2807 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_style_led)
2810 /* and now the theme manager */
2812 ThemeManager* tm = manage (new ThemeManager);
2813 add_page (_("Theme"), *tm);
2817 RCOptionEditor::parameter_changed (string const & p)
2819 OptionEditor::parameter_changed (p);
2821 if (p == "use-monitor-bus") {
2822 bool const s = Config->get_use_monitor_bus ();
2824 /* we can't use this if we don't have a monitor bus */
2825 Config->set_solo_control_is_listen_control (false);
2827 _solo_control_is_listen_control->set_sensitive (s);
2828 _listen_position->set_sensitive (s);
2829 } else if (p == "sync-source") {
2830 _sync_source->set_sensitive (true);
2832 _sync_source->set_sensitive (!_session->config.get_external_sync());
2834 switch(Config->get_sync_source()) {
2837 _sync_genlock->set_sensitive (true);
2838 _sync_framerate->set_sensitive (true);
2839 _sync_source_2997->set_sensitive (true);
2842 _sync_genlock->set_sensitive (false);
2843 _sync_framerate->set_sensitive (false);
2844 _sync_source_2997->set_sensitive (false);
2847 } else if (p == "send-ltc") {
2848 bool const s = Config->get_send_ltc ();
2849 _ltc_send_continuously->set_sensitive (s);
2850 _ltc_volume_slider->set_sensitive (s);
2854 void RCOptionEditor::ltc_generator_volume_changed () {
2855 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
2859 RCOptionEditor::populate_sync_options ()
2861 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
2863 _sync_source->clear ();
2865 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
2866 _sync_source->add (*i, sync_source_to_string (*i));
2869 if (sync_opts.empty()) {
2870 _sync_source->set_sensitive(false);
2872 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
2873 _rc_config->set_sync_source(sync_opts.front());