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 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
275 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
276 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_META_MASK },
279 { "Key|Shift", GDK_SHIFT_MASK },
280 { "Control", GDK_CONTROL_MASK },
281 { "Alt", GDK_MOD1_MASK },
282 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
283 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
284 { "Shift-Alt", GDK_SHIFT_MASK|GDK_MOD1_MASK },
285 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
286 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
287 { "Mod2", GDK_MOD2_MASK },
288 { "Mod3", GDK_MOD3_MASK },
289 { "Windows", GDK_MOD4_MASK },
290 { "Mod5", GDK_MOD5_MASK },
296 class KeyboardOptions : public OptionEditorBox
300 _delete_button_adjustment (3, 1, 12),
301 _delete_button_spin (_delete_button_adjustment),
302 _edit_button_adjustment (3, 1, 5),
303 _edit_button_spin (_edit_button_adjustment),
304 _insert_note_button_adjustment (3, 1, 5),
305 _insert_note_button_spin (_insert_note_button_adjustment)
307 /* internationalize and prepare for use with combos */
310 for (int i = 0; modifiers[i].name; ++i) {
311 dumb.push_back (S_(modifiers[i].name));
314 set_popdown_strings (_edit_modifier_combo, dumb);
315 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
317 for (int x = 0; modifiers[x].name; ++x) {
318 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
319 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
324 Table* t = manage (new Table (5, 11));
330 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
331 l->set_name ("OptionsLabel");
335 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
336 strs.push_back (bf->first);
339 set_popdown_strings (_keyboard_layout_selector, strs);
340 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
341 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
343 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
344 t->attach (_keyboard_layout_selector, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
349 l = manage (left_aligned_label (_("When Clicking:")));
350 l->set_name ("OptionEditorHeading");
351 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
356 l = manage (left_aligned_label (_("Edit using:")));
357 l->set_name ("OptionsLabel");
359 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
360 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
362 l = manage (new Label (_("+ button")));
363 l->set_name ("OptionsLabel");
365 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
366 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
368 _edit_button_spin.set_name ("OptionsEntry");
369 _edit_button_adjustment.set_value (Keyboard::edit_button());
370 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
375 set_popdown_strings (_delete_modifier_combo, dumb);
376 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
378 for (int x = 0; modifiers[x].name; ++x) {
379 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
380 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
385 l = manage (left_aligned_label (_("Delete using:")));
386 l->set_name ("OptionsLabel");
388 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
389 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
391 l = manage (new Label (_("+ button")));
392 l->set_name ("OptionsLabel");
394 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
395 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
397 _delete_button_spin.set_name ("OptionsEntry");
398 _delete_button_adjustment.set_value (Keyboard::delete_button());
399 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
404 set_popdown_strings (_insert_note_modifier_combo, dumb);
405 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
407 for (int x = 0; modifiers[x].name; ++x) {
408 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
409 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
414 l = manage (left_aligned_label (_("Insert note using:")));
415 l->set_name ("OptionsLabel");
417 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
418 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
420 l = manage (new Label (_("+ button")));
421 l->set_name ("OptionsLabel");
423 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
424 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
426 _insert_note_button_spin.set_name ("OptionsEntry");
427 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
428 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
432 l = manage (left_aligned_label (_("When Beginning a Drag:")));
433 l->set_name ("OptionEditorHeading");
434 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
440 set_popdown_strings (_copy_modifier_combo, dumb);
441 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
443 for (int x = 0; modifiers[x].name; ++x) {
444 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
445 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
450 l = manage (left_aligned_label (_("Copy items using:")));
451 l->set_name ("OptionsLabel");
453 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
454 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
459 /* constraint modifier */
460 set_popdown_strings (_constraint_modifier_combo, dumb);
461 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
463 for (int x = 0; modifiers[x].name; ++x) {
464 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
465 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
470 l = manage (left_aligned_label (_("Constrain drag using:")));
471 l->set_name ("OptionsLabel");
473 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
474 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
478 l = manage (left_aligned_label (_("When Beginning a Trim:")));
479 l->set_name ("OptionEditorHeading");
480 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
486 set_popdown_strings (_trim_contents_combo, dumb);
487 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
489 for (int x = 0; modifiers[x].name; ++x) {
490 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
491 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
496 l = manage (left_aligned_label (_("Trim contents using:")));
497 l->set_name ("OptionsLabel");
499 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
500 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
506 set_popdown_strings (_trim_anchored_combo, dumb);
507 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
509 for (int x = 0; modifiers[x].name; ++x) {
510 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
511 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
516 l = manage (left_aligned_label (_("Anchored trim using:")));
517 l->set_name ("OptionsLabel");
519 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
521 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
526 /* jump trim disabled for now
527 set_popdown_strings (_trim_jump_combo, dumb);
528 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
530 for (int x = 0; modifiers[x].name; ++x) {
531 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
532 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
537 l = manage (left_aligned_label (_("Jump after trim using:")));
538 l->set_name ("OptionsLabel");
540 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
542 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
548 /* note resize relative */
549 set_popdown_strings (_note_size_relative_combo, dumb);
550 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
552 for (int x = 0; modifiers[x].name; ++x) {
553 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
554 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
559 l = manage (left_aligned_label (_("Resize notes relatively using:")));
560 l->set_name ("OptionsLabel");
562 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
564 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
568 l = manage (left_aligned_label (_("While Dragging:")));
569 l->set_name ("OptionEditorHeading");
570 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
576 set_popdown_strings (_snap_modifier_combo, dumb);
577 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
579 for (int x = 0; modifiers[x].name; ++x) {
580 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
581 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
586 l = manage (left_aligned_label (_("Ignore snap using:")));
587 l->set_name ("OptionsLabel");
589 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
590 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
596 set_popdown_strings (_snap_delta_combo, dumb);
597 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
599 for (int x = 0; modifiers[x].name; ++x) {
600 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
601 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
606 l = manage (left_aligned_label (_("Snap to absolute using:")));
607 l->set_name ("OptionsLabel");
609 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
610 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
614 l = manage (left_aligned_label (_("While Trimming:")));
615 l->set_name ("OptionEditorHeading");
616 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
622 set_popdown_strings (_trim_overlap_combo, dumb);
623 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
625 for (int x = 0; modifiers[x].name; ++x) {
626 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
627 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
632 l = manage (left_aligned_label (_("Resize overlaped regions using:")));
633 l->set_name ("OptionsLabel");
635 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
636 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
640 l = manage (left_aligned_label (_("While Dragging Control Points:")));
641 l->set_name ("OptionEditorHeading");
642 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
648 set_popdown_strings (_fine_adjust_combo, dumb);
649 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
651 for (int x = 0; modifiers[x].name; ++x) {
652 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
653 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
658 l = manage (left_aligned_label (_("Fine adjust using:")));
659 l->set_name ("OptionsLabel");
661 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
662 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
668 set_popdown_strings (_push_points_combo, dumb);
669 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
671 for (int x = 0; modifiers[x].name; ++x) {
672 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
673 _push_points_combo.set_active_text (S_(modifiers[x].name));
678 l = manage (left_aligned_label (_("Push points using:")));
679 l->set_name ("OptionsLabel");
681 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
682 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
684 _box->pack_start (*t, false, false);
687 void parameter_changed (string const &)
689 /* XXX: these aren't really config options... */
692 void set_state_from_config ()
694 /* XXX: these aren't really config options... */
699 void bindings_changed ()
701 string const txt = _keyboard_layout_selector.get_active_text();
703 /* XXX: config...? for all this keyboard stuff */
705 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
706 if (txt == i->first) {
707 if (Keyboard::load_keybindings (i->second)) {
708 Keyboard::save_keybindings ();
714 void edit_modifier_chosen ()
716 string const txt = _edit_modifier_combo.get_active_text();
718 for (int i = 0; modifiers[i].name; ++i) {
719 if (txt == _(modifiers[i].name)) {
720 Keyboard::set_edit_modifier (modifiers[i].modifier);
726 void delete_modifier_chosen ()
728 string const txt = _delete_modifier_combo.get_active_text();
730 for (int i = 0; modifiers[i].name; ++i) {
731 if (txt == _(modifiers[i].name)) {
732 Keyboard::set_delete_modifier (modifiers[i].modifier);
738 void copy_modifier_chosen ()
740 string const txt = _copy_modifier_combo.get_active_text();
742 for (int i = 0; modifiers[i].name; ++i) {
743 if (txt == _(modifiers[i].name)) {
744 Keyboard::set_copy_modifier (modifiers[i].modifier);
750 void insert_note_modifier_chosen ()
752 string const txt = _insert_note_modifier_combo.get_active_text();
754 for (int i = 0; modifiers[i].name; ++i) {
755 if (txt == _(modifiers[i].name)) {
756 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
762 void snap_modifier_chosen ()
764 string const txt = _snap_modifier_combo.get_active_text();
766 for (int i = 0; modifiers[i].name; ++i) {
767 if (txt == _(modifiers[i].name)) {
768 Keyboard::set_snap_modifier (modifiers[i].modifier);
774 void snap_delta_modifier_chosen ()
776 string const txt = _snap_delta_combo.get_active_text();
778 for (int i = 0; modifiers[i].name; ++i) {
779 if (txt == _(modifiers[i].name)) {
780 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
786 void constraint_modifier_chosen ()
788 string const txt = _constraint_modifier_combo.get_active_text();
790 for (int i = 0; modifiers[i].name; ++i) {
791 if (txt == _(modifiers[i].name)) {
792 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
798 void trim_contents_modifier_chosen ()
800 string const txt = _trim_contents_combo.get_active_text();
802 for (int i = 0; modifiers[i].name; ++i) {
803 if (txt == _(modifiers[i].name)) {
804 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
810 void trim_overlap_modifier_chosen ()
812 string const txt = _trim_overlap_combo.get_active_text();
814 for (int i = 0; modifiers[i].name; ++i) {
815 if (txt == _(modifiers[i].name)) {
816 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
822 void trim_anchored_modifier_chosen ()
824 string const txt = _trim_anchored_combo.get_active_text();
826 for (int i = 0; modifiers[i].name; ++i) {
827 if (txt == _(modifiers[i].name)) {
828 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
834 void fine_adjust_modifier_chosen ()
836 string const txt = _fine_adjust_combo.get_active_text();
838 for (int i = 0; modifiers[i].name; ++i) {
839 if (txt == _(modifiers[i].name)) {
840 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
846 void push_points_modifier_chosen ()
848 string const txt = _push_points_combo.get_active_text();
850 for (int i = 0; modifiers[i].name; ++i) {
851 if (txt == _(modifiers[i].name)) {
852 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
858 void note_size_relative_modifier_chosen ()
860 string const txt = _note_size_relative_combo.get_active_text();
862 for (int i = 0; modifiers[i].name; ++i) {
863 if (txt == _(modifiers[i].name)) {
864 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
870 void delete_button_changed ()
872 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
875 void edit_button_changed ()
877 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
880 void insert_note_button_changed ()
882 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
885 ComboBoxText _keyboard_layout_selector;
886 ComboBoxText _edit_modifier_combo;
887 ComboBoxText _delete_modifier_combo;
888 ComboBoxText _copy_modifier_combo;
889 ComboBoxText _insert_note_modifier_combo;
890 ComboBoxText _snap_modifier_combo;
891 ComboBoxText _snap_delta_combo;
892 ComboBoxText _constraint_modifier_combo;
893 ComboBoxText _trim_contents_combo;
894 ComboBoxText _trim_overlap_combo;
895 ComboBoxText _trim_anchored_combo;
896 ComboBoxText _trim_jump_combo;
897 ComboBoxText _fine_adjust_combo;
898 ComboBoxText _push_points_combo;
899 ComboBoxText _note_size_relative_combo;
900 Adjustment _delete_button_adjustment;
901 SpinButton _delete_button_spin;
902 Adjustment _edit_button_adjustment;
903 SpinButton _edit_button_spin;
904 Adjustment _insert_note_button_adjustment;
905 SpinButton _insert_note_button_spin;
909 class FontScalingOptions : public OptionEditorBox
912 FontScalingOptions (UIConfiguration* uic) :
914 _dpi_adjustment (100, 50, 250, 1, 5),
915 _dpi_slider (_dpi_adjustment)
917 _dpi_adjustment.set_value (_ui_config->get_font_scale() / 1024.);
919 Label* l = manage (new Label (_("GUI and Font scaling:")));
920 l->set_name ("OptionsLabel");
922 const Glib::ustring dflt = _("Default");
923 const Glib::ustring empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
925 _dpi_slider.set_name("FontScaleSlider");
926 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
927 _dpi_slider.set_draw_value(false);
928 _dpi_slider.add_mark(50, Gtk::POS_TOP, empty);
929 _dpi_slider.add_mark(60, Gtk::POS_TOP, empty);
930 _dpi_slider.add_mark(70, Gtk::POS_TOP, empty);
931 _dpi_slider.add_mark(80, Gtk::POS_TOP, empty);
932 _dpi_slider.add_mark(90, Gtk::POS_TOP, empty);
933 _dpi_slider.add_mark(100, Gtk::POS_TOP, dflt);
934 _dpi_slider.add_mark(125, Gtk::POS_TOP, empty);
935 _dpi_slider.add_mark(150, Gtk::POS_TOP, empty);
936 _dpi_slider.add_mark(175, Gtk::POS_TOP, empty);
937 _dpi_slider.add_mark(200, Gtk::POS_TOP, empty);
938 _dpi_slider.add_mark(225, Gtk::POS_TOP, empty);
939 _dpi_slider.add_mark(250, Gtk::POS_TOP, empty);
941 HBox* h = manage (new HBox);
943 h->pack_start (*l, false, false);
944 h->pack_start (_dpi_slider, true, true);
946 _box->pack_start (*h, false, false);
948 set_note (_("Adjusting the scale require an application restart to re-layout."));
950 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
953 void parameter_changed (string const & p)
955 if (p == "font-scale") {
956 _dpi_adjustment.set_value (_ui_config->get_font_scale() / 1024.);
960 void set_state_from_config ()
962 parameter_changed ("font-scale");
969 _ui_config->set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024.));
970 /* XXX: should be triggered from the parameter changed signal */
974 UIConfiguration* _ui_config;
975 Adjustment _dpi_adjustment;
979 class ClipLevelOptions : public OptionEditorBox
982 ClipLevelOptions (UIConfiguration* c)
984 , _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
985 , _clip_level_slider (_clip_level_adjustment)
987 _clip_level_adjustment.set_value (_ui_config->get_waveform_clip_level ());
989 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
990 l->set_name ("OptionsLabel");
992 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
993 HBox* h = manage (new HBox);
995 h->pack_start (*l, false, false);
996 h->pack_start (_clip_level_slider, true, true);
998 _box->pack_start (*h, false, false);
1000 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1003 void parameter_changed (string const & p)
1005 if (p == "waveform-clip-level") {
1006 _clip_level_adjustment.set_value (_ui_config->get_waveform_clip_level());
1010 void set_state_from_config ()
1012 parameter_changed ("waveform-clip-level");
1017 void clip_level_changed ()
1019 _ui_config->set_waveform_clip_level (_clip_level_adjustment.get_value());
1020 /* XXX: should be triggered from the parameter changed signal */
1021 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1024 UIConfiguration* _ui_config;
1025 Adjustment _clip_level_adjustment;
1026 HScale _clip_level_slider;
1029 class BufferingOptions : public OptionEditorBox
1032 BufferingOptions (RCConfiguration* c)
1034 , _playback_adjustment (5, 1, 60, 1, 4)
1035 , _capture_adjustment (5, 1, 60, 1, 4)
1036 , _playback_slider (_playback_adjustment)
1037 , _capture_slider (_capture_adjustment)
1039 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1041 Label* l = manage (new Label (_("Playback (seconds of buffering):")));
1042 l->set_name ("OptionsLabel");
1044 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1045 HBox* h = manage (new HBox);
1047 h->pack_start (*l, false, false);
1048 h->pack_start (_playback_slider, true, true);
1050 _box->pack_start (*h, false, false);
1052 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1054 l = manage (new Label (_("Recording (seconds of buffering):")));
1055 l->set_name ("OptionsLabel");
1057 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1058 h = manage (new HBox);
1060 h->pack_start (*l, false, false);
1061 h->pack_start (_capture_slider, true, true);
1063 _box->pack_start (*h, false, false);
1065 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
1066 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
1069 void parameter_changed (string const & p)
1071 if (p == "playback-buffer-seconds") {
1072 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1073 } else if (p == "capture-buffer-seconds") {
1074 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1078 void set_state_from_config ()
1080 parameter_changed ("playback-buffer-seconds");
1081 parameter_changed ("capture-buffer-seconds");
1086 void playback_changed ()
1088 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
1091 void capture_changed ()
1093 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
1096 RCConfiguration* _rc_config;
1097 Adjustment _playback_adjustment;
1098 Adjustment _capture_adjustment;
1099 HScale _playback_slider;
1100 HScale _capture_slider;
1103 class ControlSurfacesOptions : public OptionEditorBox
1106 ControlSurfacesOptions (Gtk::Window& parent)
1108 , _ignore_view_change (0)
1110 _store = ListStore::create (_model);
1111 _view.set_model (_store);
1112 _view.append_column (_("Control Surface Protocol"), _model.name);
1113 _view.get_column(0)->set_resizable (true);
1114 _view.get_column(0)->set_expand (true);
1115 _view.append_column_editable (_("Enabled"), _model.enabled);
1116 _view.append_column_editable (_("Feedback"), _model.feedback);
1118 _box->pack_start (_view, false, false);
1120 Label* label = manage (new Label);
1121 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
1123 _box->pack_start (*label, false, false);
1126 ControlProtocolManager& m = ControlProtocolManager::instance ();
1127 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1128 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1130 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1131 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1134 void parameter_changed (std::string const &)
1139 void set_state_from_config ()
1143 ControlProtocolManager& m = ControlProtocolManager::instance ();
1144 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1146 if (!(*i)->mandatory) {
1147 TreeModel::Row r = *_store->append ();
1148 r[_model.name] = (*i)->name;
1149 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1150 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
1151 r[_model.protocol_info] = *i;
1158 void protocol_status_changed (ControlProtocolInfo* cpi) {
1160 TreeModel::Children rows = _store->children();
1162 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1163 string n = ((*x)[_model.name]);
1165 if ((*x)[_model.protocol_info] == cpi) {
1166 _ignore_view_change++;
1167 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1168 _ignore_view_change--;
1174 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1176 TreeModel::Row r = *i;
1178 if (_ignore_view_change) {
1182 ControlProtocolInfo* cpi = r[_model.protocol_info];
1187 bool const was_enabled = (cpi->protocol != 0);
1188 bool const is_enabled = r[_model.enabled];
1191 if (was_enabled != is_enabled) {
1194 ControlProtocolManager::instance().activate (*cpi);
1196 ControlProtocolManager::instance().deactivate (*cpi);
1200 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
1201 bool const is_feedback = r[_model.feedback];
1203 if (was_feedback != is_feedback && cpi->protocol) {
1204 cpi->protocol->set_feedback (is_feedback);
1208 void edit_clicked (GdkEventButton* ev)
1210 if (ev->type != GDK_2BUTTON_PRESS) {
1215 ControlProtocolInfo* cpi;
1218 row = *(_view.get_selection()->get_selected());
1219 if (!row[_model.enabled]) {
1222 cpi = row[_model.protocol_info];
1223 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1226 Box* box = (Box*) cpi->protocol->get_gui ();
1230 if (box->get_parent()) {
1231 static_cast<ArdourWindow*>(box->get_parent())->present();
1234 string title = row[_model.name];
1235 /* once created, the window is managed by the surface itself (as ->get_parent())
1236 * Surface's tear_down_gui() is called on session close, when de-activating
1237 * or re-initializing a surface.
1238 * tear_down_gui() hides an deletes the Window if it exists.
1240 ArdourWindow* win = new ArdourWindow (_parent, title);
1241 win->set_title ("Control Protocol Options");
1247 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1251 ControlSurfacesModelColumns ()
1256 add (protocol_info);
1259 TreeModelColumn<string> name;
1260 TreeModelColumn<bool> enabled;
1261 TreeModelColumn<bool> feedback;
1262 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1265 Glib::RefPtr<ListStore> _store;
1266 ControlSurfacesModelColumns _model;
1268 Gtk::Window& _parent;
1269 PBD::ScopedConnection protocol_status_connection;
1270 uint32_t _ignore_view_change;
1273 class VideoTimelineOptions : public OptionEditorBox
1276 VideoTimelineOptions (RCConfiguration* c)
1278 , _show_video_export_info_button (_("Show Video Export Info before export"))
1279 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1280 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1282 Table* t = manage (new Table (2, 6));
1283 t->set_spacings (4);
1285 t->attach (_video_advanced_setup_button, 0, 2, 0, 1);
1286 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1287 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1288 _("<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."));
1290 Label* l = manage (new Label (_("Video Server URL:")));
1291 l->set_alignment (0, 0.5);
1292 t->attach (*l, 0, 1, 1, 2, FILL);
1293 t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL);
1294 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1295 _("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"));
1297 l = manage (new Label (_("Video Folder:")));
1298 l->set_alignment (0, 0.5);
1299 t->attach (*l, 0, 1, 2, 3, FILL);
1300 t->attach (_video_server_docroot_entry, 1, 2, 2, 3);
1301 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1302 _("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."));
1304 /* small vspace y=3..4 */
1306 t->attach (_show_video_export_info_button, 0, 2, 4, 5);
1307 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1308 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1309 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1311 t->attach (_show_video_server_dialog_button, 0, 2, 5, 6);
1312 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1313 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1314 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1316 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1317 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1318 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1319 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1321 _box->pack_start (*t,true,true);
1324 void server_url_changed ()
1326 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1329 void server_docroot_changed ()
1331 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1334 void show_video_export_info_toggled ()
1336 bool const x = _show_video_export_info_button.get_active ();
1337 _rc_config->set_show_video_export_info (x);
1340 void show_video_server_dialog_toggled ()
1342 bool const x = _show_video_server_dialog_button.get_active ();
1343 _rc_config->set_show_video_server_dialog (x);
1346 void video_advanced_setup_toggled ()
1348 bool const x = _video_advanced_setup_button.get_active ();
1349 _rc_config->set_video_advanced_setup(x);
1352 void parameter_changed (string const & p)
1354 if (p == "video-server-url") {
1355 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1356 } else if (p == "video-server-docroot") {
1357 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1358 } else if (p == "show-video-export-info") {
1359 bool const x = _rc_config->get_show_video_export_info();
1360 _show_video_export_info_button.set_active (x);
1361 } else if (p == "show-video-server-dialog") {
1362 bool const x = _rc_config->get_show_video_server_dialog();
1363 _show_video_server_dialog_button.set_active (x);
1364 } else if (p == "video-advanced-setup") {
1365 bool const x = _rc_config->get_video_advanced_setup();
1366 _video_advanced_setup_button.set_active(x);
1367 _video_server_docroot_entry.set_sensitive(x);
1368 _video_server_url_entry.set_sensitive(x);
1372 void set_state_from_config ()
1374 parameter_changed ("video-server-url");
1375 parameter_changed ("video-server-docroot");
1376 parameter_changed ("video-monitor-setup-dialog");
1377 parameter_changed ("show-video-export-info");
1378 parameter_changed ("show-video-server-dialog");
1379 parameter_changed ("video-advanced-setup");
1383 RCConfiguration* _rc_config;
1384 Entry _video_server_url_entry;
1385 Entry _video_server_docroot_entry;
1386 CheckButton _show_video_export_info_button;
1387 CheckButton _show_video_server_dialog_button;
1388 CheckButton _video_advanced_setup_button;
1391 class PluginOptions : public OptionEditorBox
1394 PluginOptions (RCConfiguration* c, UIConfiguration* uic)
1397 , _display_plugin_scan_progress (_("Always Display Plugin Scan Progress"))
1398 , _discover_vst_on_start (_("Scan for [new] VST Plugins on Application Start"))
1399 , _discover_au_on_start (_("Scan for AudioUnit Plugins on Application Start"))
1400 , _timeout_adjustment (0, 0, 3000, 50, 50)
1401 , _timeout_slider (_timeout_adjustment)
1404 std::stringstream ss;
1405 Table* t = manage (new Table (2, 6));
1406 t->set_spacings (4);
1410 ss << "<b>" << _("General") << "</b>";
1411 l = manage (left_aligned_label (ss.str()));
1412 l->set_use_markup (true);
1413 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1414 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1416 b = manage (new Button (_("Scan for Plugins")));
1417 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1418 t->attach (*b, 0, 2, n, n+1, FILL); ++n;
1420 t->attach (_display_plugin_scan_progress, 0, 2, n, n+1); ++n;
1421 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1422 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1423 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
1425 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
1426 _timeout_slider.set_digits (0);
1427 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &PluginOptions::timeout_changed));
1429 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1430 _("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."));
1432 l = manage (left_aligned_label (_("Scan Time Out [deciseconds]")));;
1433 HBox* h = manage (new HBox);
1435 h->pack_start (*l, false, false);
1436 h->pack_start (_timeout_slider, true, true);
1437 t->attach (*h, 0, 2, n, n+1); ++n;
1440 ss << "<b>" << _("VST") << "</b>";
1441 l = manage (left_aligned_label (ss.str()));
1442 l->set_use_markup (true);
1443 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1444 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1446 b = manage (new Button (_("Clear VST Cache")));
1447 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_cache_clicked));
1448 t->attach (*b, 0, 1, n, n+1, FILL);
1450 b = manage (new Button (_("Clear VST Blacklist")));
1451 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_blacklist_clicked));
1452 t->attach (*b, 1, 2, n, n+1, FILL);
1455 t->attach (_discover_vst_on_start, 0, 2, n, n+1); ++n;
1456 _discover_vst_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_vst_on_start_toggled));
1457 Gtkmm2ext::UI::instance()->set_tip (_discover_vst_on_start,
1458 _("<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"));
1460 #ifdef LXVST_SUPPORT
1461 t->attach (*manage (left_aligned_label (_("Linux VST Path:"))), 0, 1, n, n+1);
1462 b = manage (new Button (_("Edit")));
1463 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_lxvst_path_clicked));
1464 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1467 #ifdef WINDOWS_VST_SUPPORT
1468 t->attach (*manage (left_aligned_label (_("Windows VST Path:"))), 0, 1, n, n+1);
1469 b = manage (new Button (_("Edit")));
1470 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_vst_path_clicked));
1471 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1475 #ifdef AUDIOUNIT_SUPPORT
1477 ss << "<b>" << _("Audio Unit") << "</b>";
1478 l = manage (left_aligned_label (ss.str()));
1479 l->set_use_markup (true);
1480 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1481 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1483 t->attach (_discover_au_on_start, 0, 2, n, n+1); ++n;
1484 _discover_au_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_au_on_start_toggled));
1485 Gtkmm2ext::UI::instance()->set_tip (_discover_au_on_start,
1486 _("<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."));
1489 b = manage (new Button (_("Clear AU Cache")));
1490 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_cache_clicked));
1491 t->attach (*b, 0, 1, n, n+1, FILL);
1493 b = manage (new Button (_("Clear AU Blacklist")));
1494 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_blacklist_clicked));
1495 t->attach (*b, 1, 2, n, n+1, FILL);
1499 _box->pack_start (*t,true,true);
1502 void parameter_changed (string const & p) {
1503 if (p == "show-plugin-scan-window") {
1504 bool const x = _ui_config->get_show_plugin_scan_window();
1505 _display_plugin_scan_progress.set_active (x);
1507 else if (p == "discover-vst-on-start") {
1508 bool const x = _rc_config->get_discover_vst_on_start();
1509 _discover_vst_on_start.set_active (x);
1511 else if (p == "vst-scan-timeout") {
1512 int const x = _rc_config->get_vst_scan_timeout();
1513 _timeout_adjustment.set_value (x);
1515 else if (p == "discover-audio-units") {
1516 bool const x = _rc_config->get_discover_audio_units();
1517 _discover_au_on_start.set_active (x);
1521 void set_state_from_config () {
1522 parameter_changed ("show-plugin-scan-window");
1523 parameter_changed ("discover-vst-on-start");
1524 parameter_changed ("vst-scan-timeout");
1525 parameter_changed ("discover-audio-units");
1529 RCConfiguration* _rc_config;
1530 UIConfiguration* _ui_config;
1531 CheckButton _display_plugin_scan_progress;
1532 CheckButton _discover_vst_on_start;
1533 CheckButton _discover_au_on_start;
1534 Adjustment _timeout_adjustment;
1535 HScale _timeout_slider;
1537 void display_plugin_scan_progress_toggled () {
1538 bool const x = _display_plugin_scan_progress.get_active();
1539 _ui_config->set_show_plugin_scan_window(x);
1542 void discover_vst_on_start_toggled () {
1543 bool const x = _discover_vst_on_start.get_active();
1544 _rc_config->set_discover_vst_on_start(x);
1547 void discover_au_on_start_toggled () {
1548 bool const x = _discover_au_on_start.get_active();
1549 _rc_config->set_discover_audio_units(x);
1552 void timeout_changed () {
1553 int x = floor(_timeout_adjustment.get_value());
1554 _rc_config->set_vst_scan_timeout(x);
1557 void clear_vst_cache_clicked () {
1558 PluginManager::instance().clear_vst_cache();
1561 void clear_vst_blacklist_clicked () {
1562 PluginManager::instance().clear_vst_blacklist();
1565 void clear_au_cache_clicked () {
1566 PluginManager::instance().clear_au_cache();
1569 void clear_au_blacklist_clicked () {
1570 PluginManager::instance().clear_au_blacklist();
1574 void edit_vst_path_clicked () {
1575 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1576 _("Set Windows VST Search Path"),
1577 _rc_config->get_plugin_path_vst(),
1578 PluginManager::instance().get_default_windows_vst_path()
1580 ResponseType r = (ResponseType) pd->run ();
1582 if (r == RESPONSE_ACCEPT) {
1583 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
1588 // todo consolidate with edit_vst_path_clicked..
1589 void edit_lxvst_path_clicked () {
1590 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1591 _("Set Linux VST Search Path"),
1592 _rc_config->get_plugin_path_lxvst(),
1593 PluginManager::instance().get_default_lxvst_path()
1595 ResponseType r = (ResponseType) pd->run ();
1597 if (r == RESPONSE_ACCEPT) {
1598 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
1603 void refresh_clicked () {
1604 PluginManager::instance().refresh();
1609 /** A class which allows control of visibility of some editor components usign
1610 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1611 * which has the correct members, but with null widget pointers. This
1612 * class allows the user to set visibility of the members, the details
1613 * of which are stored in a configuration variable which can be watched
1614 * by parts of the editor that actually contain the widgets whose visibility
1615 * is being controlled.
1618 class VisibilityOption : public Option
1621 /** @param name User-visible name for this group.
1622 * @param g `Dummy' VisibilityGroup (as described above).
1623 * @param get Method to get the value of the appropriate configuration variable.
1624 * @param set Method to set the value of the appropriate configuration variable.
1626 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1627 : Option (g->get_state_name(), name)
1629 , _visibility_group (g)
1633 /* Watch for changes made by the user to our members */
1634 _visibility_group->VisibilityChanged.connect_same_thread (
1635 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1639 void set_state_from_config ()
1641 /* Set our state from the current configuration */
1642 _visibility_group->set_state (_get ());
1645 void add_to_page (OptionEditorPage* p)
1647 _heading.add_to_page (p);
1648 add_widget_to_page (p, _visibility_group->list_view ());
1651 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1656 /* The user has changed something, so reflect this change
1657 in the RCConfiguration.
1659 _set (_visibility_group->get_state_value ());
1662 OptionEditorHeading _heading;
1663 VisibilityGroup* _visibility_group;
1664 sigc::slot<std::string> _get;
1665 sigc::slot<bool, std::string> _set;
1666 PBD::ScopedConnection _visibility_group_connection;
1671 RCOptionEditor::RCOptionEditor ()
1672 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1673 , _rc_config (Config)
1674 , _ui_config (ARDOUR_UI::config())
1675 , _mixer_strip_visibility ("mixer-element-visibility")
1679 uint32_t hwcpus = hardware_concurrency ();
1681 BoolComboOption* bco;
1684 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1686 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1688 _("Signal processing uses"),
1689 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1690 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1693 procs->add (-1, _("all but one processor"));
1694 procs->add (0, _("all available processors"));
1696 for (uint32_t i = 1; i <= hwcpus; ++i) {
1697 procs->add (i, string_compose (_("%1 processors"), i));
1700 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1702 add_option (_("Misc"), procs);
1705 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1707 add_option (_("Misc"), new UndoOptions (_rc_config));
1709 add_option (_("Misc"),
1711 "verify-remove-last-capture",
1712 _("Verify removal of last capture"),
1713 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1714 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1717 add_option (_("Misc"),
1719 "periodic-safety-backups",
1720 _("Make periodic backups of the session file"),
1721 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1722 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1725 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1727 add_option (_("Misc"),
1729 "only-copy-imported-files",
1730 _("Always copy imported files"),
1731 sigc::mem_fun (*_ui_config, &UIConfiguration::get_only_copy_imported_files),
1732 sigc::mem_fun (*_ui_config, &UIConfiguration::set_only_copy_imported_files)
1735 add_option (_("Misc"), new DirectoryOption (
1736 X_("default-session-parent-dir"),
1737 _("Default folder for new sessions:"),
1738 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1739 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1742 add_option (_("Misc"),
1743 new SpinOption<uint32_t> (
1744 "max-recent-sessions",
1745 _("Maximum number of recent sessions"),
1746 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1747 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1751 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1753 add_option (_("Misc"), new ClickOptions (_rc_config, this));
1755 add_option (_("Misc"),
1758 _("Click gain level"),
1759 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1760 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1763 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1765 add_option (_("Misc"),
1766 new SpinOption<double> (
1767 "automation-thinning-factor",
1768 _("Thinning factor (larger value => less data)"),
1769 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1770 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1774 add_option (_("Misc"),
1775 new SpinOption<double> (
1776 "automation-interval-msecs",
1777 _("Automation sampling interval (milliseconds)"),
1778 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1779 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1787 tsf = new BoolOption (
1788 "latched-record-enable",
1789 _("Keep record-enable engaged on stop"),
1790 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1791 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1793 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1794 add_option (_("Transport"), tsf);
1796 tsf = new BoolOption (
1798 _("Play loop is a transport mode"),
1799 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1800 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1802 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1803 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1804 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1805 add_option (_("Transport"), tsf);
1807 tsf = new BoolOption (
1808 "stop-recording-on-xrun",
1809 _("Stop recording when an xrun occurs"),
1810 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1811 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1813 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1814 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
1816 add_option (_("Transport"), tsf);
1818 tsf = new BoolOption (
1819 "create-xrun-marker",
1820 _("Create markers where xruns occur"),
1821 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
1822 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
1824 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1825 add_option (_("Transport"), tsf);
1827 tsf = new BoolOption (
1828 "stop-at-session-end",
1829 _("Stop at the end of the session"),
1830 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
1831 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
1833 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1834 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
1835 "when it reaches the current session end marker\n\n"
1836 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
1838 add_option (_("Transport"), tsf);
1840 tsf = new BoolOption (
1842 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
1843 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
1844 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
1846 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1847 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
1848 "preventing any need to do a transport locate at the end of the loop\n\n"
1849 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
1850 "which will often cause a small click or delay"), PROGRAM_NAME));
1851 add_option (_("Transport"), tsf);
1853 tsf = new BoolOption (
1854 "disable-disarm-during-roll",
1855 _("Disable per-track record disarm while rolling"),
1856 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
1857 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
1859 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"));
1860 add_option (_("Transport"), tsf);
1862 tsf = new BoolOption (
1864 _("12dB gain reduction during fast-forward and fast-rewind"),
1865 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
1866 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
1868 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
1869 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
1870 add_option (_("Transport"), tsf);
1872 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
1874 _sync_source = new ComboOption<SyncSource> (
1876 _("External timecode source"),
1877 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
1878 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
1881 add_option (_("Transport"), _sync_source);
1883 _sync_framerate = new BoolOption (
1884 "timecode-sync-frame-rate",
1885 _("Match session video frame rate to external timecode"),
1886 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
1887 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
1889 Gtkmm2ext::UI::instance()->set_tip
1890 (_sync_framerate->tip_widget(),
1891 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
1892 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
1893 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
1894 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
1895 "timecode standard and the session standard."), PROGRAM_NAME));
1897 add_option (_("Transport"), _sync_framerate);
1899 _sync_genlock = new BoolOption (
1900 "timecode-source-is-synced",
1901 _("Sync-lock timecode to clock (disable drift compensation)"),
1902 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
1903 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
1905 Gtkmm2ext::UI::instance()->set_tip
1906 (_sync_genlock->tip_widget(),
1907 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
1908 "Sync Lock indicates that the selected external timecode source shares clock-sync "
1909 "(Black & Burst, Wordclock, etc) with the audio interface. "
1910 "This option disables drift compensation. The transport speed is fixed at 1.0. "
1911 "Vari-speed LTC will be ignored and cause drift."
1913 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
1914 "timecode sources shares clock sync."
1918 add_option (_("Transport"), _sync_genlock);
1920 _sync_source_2997 = new BoolOption (
1921 "timecode-source-2997",
1922 _("Lock to 29.9700 fps instead of 30000/1001"),
1923 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
1924 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
1926 Gtkmm2ext::UI::instance()->set_tip
1927 (_sync_source_2997->tip_widget(),
1928 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
1929 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
1930 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
1931 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
1932 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
1933 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
1936 add_option (_("Transport"), _sync_source_2997);
1938 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
1940 _ltc_port = new ComboStringOption (
1942 _("LTC incoming port"),
1943 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
1944 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
1947 vector<string> physical_inputs;
1948 physical_inputs.push_back (_("None"));
1949 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
1950 _ltc_port->set_popdown_strings (physical_inputs);
1952 populate_sync_options ();
1954 add_option (_("Transport"), _ltc_port);
1956 // TODO; rather disable this button than not compile it..
1957 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
1959 add_option (_("Transport"),
1962 _("Enable LTC generator"),
1963 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
1964 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
1967 _ltc_send_continuously = new BoolOption (
1968 "ltc-send-continuously",
1969 _("Send LTC while stopped"),
1970 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
1971 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
1973 Gtkmm2ext::UI::instance()->set_tip
1974 (_ltc_send_continuously->tip_widget(),
1975 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
1976 add_option (_("Transport"), _ltc_send_continuously);
1978 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
1979 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
1980 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
1981 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
1983 Gtkmm2ext::UI::instance()->set_tip
1984 (_ltc_volume_slider->tip_widget(),
1985 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
1987 add_option (_("Transport"), _ltc_volume_slider);
1988 parameter_changed ("send-ltc");
1990 parameter_changed ("sync-source");
1994 add_option (S_("Editor"),
1996 "draggable-playhead",
1997 _("Allow dragging of playhead"),
1998 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_draggable_playhead),
1999 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_draggable_playhead)
2002 add_option (_("Editor"),
2004 "automation-follows-regions",
2005 _("Move relevant automation when audio regions are moved"),
2006 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2007 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2010 add_option (_("Editor"),
2012 "show-track-meters",
2013 _("Show meters on tracks in the editor"),
2014 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_track_meters),
2015 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_track_meters)
2018 add_option (_("Editor"),
2020 "show-editor-meter",
2021 _("Display master-meter in the toolbar"),
2022 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_editor_meter),
2023 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_editor_meter)
2026 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2027 "default-fade-shape",
2028 _("Default fade shape"),
2029 sigc::mem_fun (*_rc_config,
2030 &RCConfiguration::get_default_fade_shape),
2031 sigc::mem_fun (*_rc_config,
2032 &RCConfiguration::set_default_fade_shape)
2035 fadeshape->add (FadeLinear,
2036 _("Linear (for highly correlated material)"));
2037 fadeshape->add (FadeConstantPower, _("Constant power"));
2038 fadeshape->add (FadeSymmetric, _("Symmetric"));
2039 fadeshape->add (FadeSlow, _("Slow"));
2040 fadeshape->add (FadeFast, _("Fast"));
2042 add_option (_("Editor"), fadeshape);
2045 bco = new BoolComboOption (
2046 "use-overlap-equivalency",
2047 _("Regions in active edit groups are edited together"),
2048 _("whenever they overlap in time"),
2049 _("only if they have identical length, position and origin"),
2050 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2051 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2054 add_option (_("Editor"), bco);
2056 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2058 _("Layering model"),
2059 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2060 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2063 lm->add (LaterHigher, _("later is higher"));
2064 lm->add (Manual, _("manual layering"));
2065 add_option (_("Editor"), lm);
2067 add_option (_("Editor"),
2069 "rubberbanding-snaps-to-grid",
2070 _("Make rubberband selection rectangle snap to the grid"),
2071 sigc::mem_fun (*_ui_config, &UIConfiguration::get_rubberbanding_snaps_to_grid),
2072 sigc::mem_fun (*_ui_config, &UIConfiguration::set_rubberbanding_snaps_to_grid)
2075 add_option (_("Editor"),
2078 _("Show waveforms in regions"),
2079 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms),
2080 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms)
2083 add_option (_("Editor"),
2084 new BoolComboOption (
2085 "show-region-gain-envelopes",
2086 _("Show gain envelopes in audio regions"),
2088 _("only in region gain mode"),
2089 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_region_gain),
2090 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_region_gain)
2093 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
2095 _("Waveform scale"),
2096 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_scale),
2097 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_scale)
2100 wfs->add (Linear, _("linear"));
2101 wfs->add (Logarithmic, _("logarithmic"));
2103 add_option (_("Editor"), wfs);
2105 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
2107 _("Waveform shape"),
2108 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_shape),
2109 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_shape)
2112 wfsh->add (Traditional, _("traditional"));
2113 wfsh->add (Rectified, _("rectified"));
2115 add_option (_("Editor"), wfsh);
2117 add_option (_("Editor"), new ClipLevelOptions (_ui_config));
2119 add_option (_("Editor"),
2121 "show-waveforms-while-recording",
2122 _("Show waveforms for audio while it is being recorded"),
2123 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms_while_recording),
2124 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms_while_recording)
2127 add_option (_("Editor"),
2130 _("Show zoom toolbar"),
2131 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_zoom_tools),
2132 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_zoom_tools)
2135 add_option (_("Editor"),
2137 "update-editor-during-summary-drag",
2138 _("Update editor window during drags of the summary"),
2139 sigc::mem_fun (*_ui_config, &UIConfiguration::get_update_editor_during_summary_drag),
2140 sigc::mem_fun (*_ui_config, &UIConfiguration::set_update_editor_during_summary_drag)
2143 bo = new BoolOption (
2145 _("Name new markers"),
2146 sigc::mem_fun (*_ui_config, &UIConfiguration::get_name_new_markers),
2147 sigc::mem_fun (*_ui_config, &UIConfiguration::set_name_new_markers)
2150 add_option (_("Editor"), bo);
2151 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."
2152 "\n\nYou can always rename markers by right-clicking on them"));
2154 add_option (_("Editor"),
2156 "autoscroll-editor",
2157 _("Auto-scroll editor window when dragging near its edges"),
2158 sigc::mem_fun (*_ui_config, &UIConfiguration::get_autoscroll_editor),
2159 sigc::mem_fun (*_ui_config, &UIConfiguration::set_autoscroll_editor)
2162 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2163 "region-selection-after-split",
2164 _("After splitting selected regions, select"),
2165 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2166 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2168 // TODO: decide which of these modes are really useful
2169 rsas->add(None, _("no regions"));
2170 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2171 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2172 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2173 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2174 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2175 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2176 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2178 add_option (_("Editor"), rsas);
2183 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2185 add_option (_("Audio"), new BufferingOptions (_rc_config));
2187 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2189 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2191 _("Record monitoring handled by"),
2192 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2193 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2196 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2197 mm->add (HardwareMonitoring, _("via Audio Driver"));
2200 string prog (PROGRAM_NAME);
2201 boost::algorithm::to_lower (prog);
2202 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2203 mm->add (ExternalMonitoring, _("audio hardware"));
2205 add_option (_("Audio"), mm);
2207 add_option (_("Audio"),
2209 "tape-machine-mode",
2210 _("Tape machine mode"),
2211 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2212 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2215 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
2217 add_option (_("Audio"),
2219 "auto-connect-standard-busses",
2220 _("Auto-connect master/monitor busses"),
2221 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2222 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2225 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2226 "input-auto-connect",
2227 _("Connect track inputs"),
2228 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2229 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2232 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2233 iac->add (ManualConnect, _("manually"));
2235 add_option (_("Audio"), iac);
2237 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2238 "output-auto-connect",
2239 _("Connect track and bus outputs"),
2240 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2241 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2244 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2245 oac->add (AutoConnectMaster, _("automatically to master bus"));
2246 oac->add (ManualConnect, _("manually"));
2248 add_option (_("Audio"), oac);
2250 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2252 add_option (_("Audio"),
2254 "denormal-protection",
2255 _("Use DC bias to protect against denormals"),
2256 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2257 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2260 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2262 _("Processor handling"),
2263 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2264 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2268 dm->add (DenormalNone, _("no processor handling"));
2272 if (fpu.has_flush_to_zero()) {
2274 dm->add (DenormalFTZ, _("use FlushToZero"));
2275 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2276 _rc_config->set_denormal_model(DenormalNone);
2279 if (fpu.has_denormals_are_zero()) {
2281 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2282 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2283 _rc_config->set_denormal_model(DenormalNone);
2286 if (fpu.has_flush_to_zero() && fpu.has_denormals_are_zero()) {
2288 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2289 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2290 _rc_config->set_denormal_model(DenormalNone);
2294 dm->set_sensitive(false);
2297 add_option (_("Audio"), dm);
2299 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
2301 add_option (_("Audio"),
2303 "plugins-stop-with-transport",
2304 _("Silence plugins when the transport is stopped"),
2305 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
2306 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
2309 add_option (_("Audio"),
2311 "new-plugins-active",
2312 _("Make new plugins active"),
2313 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
2314 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
2317 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2319 add_option (_("Audio"),
2321 "auto-analyse-audio",
2322 _("Enable automatic analysis of audio"),
2323 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2324 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2327 add_option (_("Audio"),
2329 "replicate-missing-region-channels",
2330 _("Replicate missing region channels"),
2331 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2332 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2337 add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
2339 add_option (_("Solo / mute"),
2342 _("Solo-in-place mute cut (dB)"),
2343 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2344 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2347 _solo_control_is_listen_control = new BoolOption (
2348 "solo-control-is-listen-control",
2349 _("Solo controls are Listen controls"),
2350 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2351 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2354 add_option (_("Solo / mute"), _solo_control_is_listen_control);
2356 _listen_position = new ComboOption<ListenPosition> (
2358 _("Listen Position"),
2359 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2360 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2363 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2364 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2366 add_option (_("Solo / mute"), _listen_position);
2368 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2370 _("PFL signals come from"),
2371 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2372 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2375 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2376 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2378 add_option (_("Solo / mute"), pp);
2380 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2382 _("AFL signals come from"),
2383 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2384 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2387 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2388 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2390 add_option (_("Solo / mute"), pa);
2392 parameter_changed ("use-monitor-bus");
2394 add_option (_("Solo / mute"),
2397 _("Exclusive solo"),
2398 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2399 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2402 add_option (_("Solo / mute"),
2405 _("Show solo muting"),
2406 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2407 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2410 add_option (_("Solo / mute"),
2412 "solo-mute-override",
2413 _("Soloing overrides muting"),
2414 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2415 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2418 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
2420 add_option (_("Solo / mute"),
2422 "mute-affects-pre-fader",
2423 _("Mute affects pre-fader sends"),
2424 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2425 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2428 add_option (_("Solo / mute"),
2430 "mute-affects-post-fader",
2431 _("Mute affects post-fader sends"),
2432 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2433 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2436 add_option (_("Solo / mute"),
2438 "mute-affects-control-outs",
2439 _("Mute affects control outputs"),
2440 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2441 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2444 add_option (_("Solo / mute"),
2446 "mute-affects-main-outs",
2447 _("Mute affects main outputs"),
2448 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2449 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2452 add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
2454 add_option (_("Solo / mute"),
2456 "link-send-and-route-panner",
2457 _("Link panners of Aux and External Sends with main panner by default"),
2458 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2459 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2462 add_option (_("MIDI"),
2463 new SpinOption<float> (
2465 _("MIDI read-ahead time (seconds)"),
2466 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2467 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2472 add_option (_("MIDI"),
2475 _("Send MIDI Clock"),
2476 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2477 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2480 add_option (_("MIDI"),
2483 _("Send MIDI Time Code"),
2484 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2485 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2488 add_option (_("MIDI"),
2489 new SpinOption<int> (
2490 "mtc-qf-speed-tolerance",
2491 _("Percentage either side of normal transport speed to transmit MTC"),
2492 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2493 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2497 add_option (_("MIDI"),
2500 _("Obey MIDI Machine Control commands"),
2501 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2502 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2505 add_option (_("MIDI"),
2508 _("Send MIDI Machine Control commands"),
2509 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2510 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2513 add_option (_("MIDI"),
2516 _("Send MIDI control feedback"),
2517 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2518 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2521 add_option (_("MIDI"),
2522 new SpinOption<uint8_t> (
2523 "mmc-receive-device-id",
2524 _("Inbound MMC device ID"),
2525 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2526 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2530 add_option (_("MIDI"),
2531 new SpinOption<uint8_t> (
2532 "mmc-send-device-id",
2533 _("Outbound MMC device ID"),
2534 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2535 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2539 add_option (_("MIDI"),
2540 new SpinOption<int32_t> (
2541 "initial-program-change",
2542 _("Initial program change"),
2543 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2544 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2548 add_option (_("MIDI"),
2550 "display-first-midi-bank-as-zero",
2551 _("Display first MIDI bank/program as 0"),
2552 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2553 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2556 add_option (_("MIDI"),
2558 "never-display-periodic-midi",
2559 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2560 sigc::mem_fun (*_ui_config, &UIConfiguration::get_never_display_periodic_midi),
2561 sigc::mem_fun (*_ui_config, &UIConfiguration::set_never_display_periodic_midi)
2564 add_option (_("MIDI"),
2567 _("Sound MIDI notes as they are selected"),
2568 sigc::mem_fun (*_ui_config, &UIConfiguration::get_sound_midi_notes),
2569 sigc::mem_fun (*_ui_config, &UIConfiguration::set_sound_midi_notes)
2572 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2574 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2575 "midi-audition-synth-uri",
2576 _("Midi Audition Synth (LV2)"),
2577 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2578 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2581 audition_synth->add(X_(""), _("None"));
2582 PluginInfoList all_plugs;
2583 PluginManager& manager (PluginManager::instance());
2585 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2587 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2588 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2589 if (!(*i)->is_instrument()) continue;
2590 if ((*i)->type != ARDOUR::LV2) continue;
2591 audition_synth->add((*i)->unique_id, (*i)->name);
2595 add_option (_("MIDI"), audition_synth);
2597 /* USER INTERACTION */
2600 #ifdef PLATFORM_WINDOWS
2603 getenv ("ARDOUR_BUNDLED")
2607 add_option (_("User interaction"),
2609 "enable-translation",
2610 string_compose (_("Use translations of %1 messages\n"
2611 " <i>(requires a restart of %1 to take effect)</i>\n"
2612 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2613 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2614 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2617 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2619 add_option (_("User interaction"), new KeyboardOptions);
2621 /* Control Surfaces */
2623 add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
2625 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2627 _("Control surface remote ID"),
2628 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2629 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2632 rm->add (UserOrdered, _("assigned by user"));
2633 rm->add (MixerOrdered, _("follows order of mixer"));
2635 add_option (_("Control Surfaces"), rm);
2637 /* VIDEO Timeline */
2638 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2640 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2641 /* Plugin options (currrently VST only) */
2642 add_option (_("Plugins"), new PluginOptions (_rc_config, _ui_config));
2647 add_option (S_("Preferences|GUI"),
2650 _("Graphically indicate mouse pointer hovering over various widgets"),
2651 sigc::mem_fun (*_ui_config, &UIConfiguration::get_widget_prelight),
2652 sigc::mem_fun (*_ui_config, &UIConfiguration::set_widget_prelight)
2655 #ifdef TOOLTIPS_GOT_FIXED
2656 add_option (S_("Preferences|GUI"),
2659 _("Show tooltips if mouse hovers over a control"),
2660 sigc::mem_fun (*_ui_config, &UIConfiguration::get_use_tooltips),
2661 sigc::mem_fun (*_ui_config, &UIConfiguration::set_use_tooltips)
2665 add_option (S_("Preferences|GUI"),
2667 "show-name-highlight",
2668 _("Use name highlight bars in region displays (requires a restart)"),
2669 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_name_highlight),
2670 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_name_highlight)
2674 /* font scaling does nothing with GDK/Quartz */
2675 add_option (S_("Preferences|GUI"), new FontScalingOptions (_ui_config));
2678 add_option (S_("GUI"),
2680 "super-rapid-clock-update",
2681 _("update transport clock display at FPS instead of every 100ms"),
2682 sigc::mem_fun (*_ui_config, &UIConfiguration::get_super_rapid_clock_update),
2683 sigc::mem_fun (*_ui_config, &UIConfiguration::set_super_rapid_clock_update)
2686 /* Lock GUI timeout */
2688 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
2689 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2690 _("Lock timeout (seconds)"),
2692 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_lock_gui_after_seconds),
2693 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_lock_gui_after_seconds)
2695 slts->scale().set_digits (0);
2696 Gtkmm2ext::UI::instance()->set_tip
2697 (slts->tip_widget(),
2698 _("Lock GUI after this many idle seconds (zero to never lock)"));
2699 add_option (S_("Preferences|GUI"), slts);
2701 /* The names of these controls must be the same as those given in MixerStrip
2702 for the actual widgets being controlled.
2704 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
2705 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2706 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
2707 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
2708 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
2709 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2712 S_("Preferences|GUI"),
2713 new VisibilityOption (
2715 &_mixer_strip_visibility,
2716 sigc::mem_fun (*_ui_config, &UIConfiguration::get_mixer_strip_visibility),
2717 sigc::mem_fun (*_ui_config, &UIConfiguration::set_mixer_strip_visibility)
2721 add_option (S_("Preferences|GUI"),
2723 "default-narrow_ms",
2724 _("Use narrow strips in the mixer by default"),
2725 sigc::mem_fun (*_ui_config, &UIConfiguration::get_default_narrow_ms),
2726 sigc::mem_fun (*_ui_config, &UIConfiguration::set_default_narrow_ms)
2729 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2731 ComboOption<float>* mht = new ComboOption<float> (
2733 _("Peak hold time"),
2734 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_hold),
2735 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_hold)
2738 mht->add (MeterHoldOff, _("off"));
2739 mht->add (MeterHoldShort, _("short"));
2740 mht->add (MeterHoldMedium, _("medium"));
2741 mht->add (MeterHoldLong, _("long"));
2743 add_option (S_("Preferences|Metering"), mht);
2745 ComboOption<float>* mfo = new ComboOption<float> (
2748 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2749 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2752 mfo->add (METER_FALLOFF_OFF, _("off"));
2753 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2754 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2755 mfo->add (METER_FALLOFF_SLOWISH, _("slowish [12.0dB/sec] (DIN)"));
2756 mfo->add (METER_FALLOFF_MODERATE, _("moderate [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2757 mfo->add (METER_FALLOFF_MEDIUM, _("medium [20dB/sec]"));
2758 mfo->add (METER_FALLOFF_FAST, _("fast [32dB/sec]"));
2759 mfo->add (METER_FALLOFF_FASTER, _("faster [46dB/sec]"));
2760 mfo->add (METER_FALLOFF_FASTEST, _("fastest [70dB/sec]"));
2762 add_option (S_("Preferences|Metering"), mfo);
2764 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2765 "meter-line-up-level",
2766 _("Meter line-up level; 0dBu"),
2767 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_level),
2768 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_level)
2771 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2772 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2773 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2774 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2776 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."));
2778 add_option (S_("Preferences|Metering"), mlu);
2780 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2781 "meter-line-up-din",
2782 _("IEC1/DIN Meter line-up level; 0dBu"),
2783 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_din),
2784 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_din)
2787 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2788 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2789 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2790 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2792 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2794 add_option (S_("Preferences|Metering"), mld);
2796 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2797 "meter-vu-standard",
2798 _("VU Meter standard"),
2799 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_vu_standard),
2800 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_vu_standard)
2803 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2804 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2805 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2806 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2808 add_option (S_("Preferences|Metering"), mvu);
2810 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
2811 HSliderOption *mpks = new HSliderOption("meter-peak",
2812 _("Peak threshold [dBFS]"),
2814 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_peak),
2815 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_peak)
2818 Gtkmm2ext::UI::instance()->set_tip
2819 (mpks->tip_widget(),
2820 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
2822 add_option (S_("Preferences|Metering"), mpks);
2824 add_option (S_("Preferences|Metering"),
2827 _("LED meter style"),
2828 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_style_led),
2829 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_style_led)
2832 /* and now the theme manager */
2834 ThemeManager* tm = manage (new ThemeManager);
2835 add_page (_("Theme"), *tm);
2839 RCOptionEditor::parameter_changed (string const & p)
2841 OptionEditor::parameter_changed (p);
2843 if (p == "use-monitor-bus") {
2844 bool const s = Config->get_use_monitor_bus ();
2846 /* we can't use this if we don't have a monitor bus */
2847 Config->set_solo_control_is_listen_control (false);
2849 _solo_control_is_listen_control->set_sensitive (s);
2850 _listen_position->set_sensitive (s);
2851 } else if (p == "sync-source") {
2852 _sync_source->set_sensitive (true);
2854 _sync_source->set_sensitive (!_session->config.get_external_sync());
2856 switch(Config->get_sync_source()) {
2859 _sync_genlock->set_sensitive (true);
2860 _sync_framerate->set_sensitive (true);
2861 _sync_source_2997->set_sensitive (true);
2864 _sync_genlock->set_sensitive (false);
2865 _sync_framerate->set_sensitive (false);
2866 _sync_source_2997->set_sensitive (false);
2869 } else if (p == "send-ltc") {
2870 bool const s = Config->get_send_ltc ();
2871 _ltc_send_continuously->set_sensitive (s);
2872 _ltc_volume_slider->set_sensitive (s);
2876 void RCOptionEditor::ltc_generator_volume_changed () {
2877 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
2881 RCOptionEditor::populate_sync_options ()
2883 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
2885 _sync_source->clear ();
2887 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
2888 _sync_source->add (*i, sync_source_to_string (*i));
2891 if (sync_opts.empty()) {
2892 _sync_source->set_sensitive(false);
2894 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
2895 _rc_config->set_sync_source(sync_opts.front());