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);
458 l = manage (left_aligned_label (_("When Beginning a Trim:")));
459 l->set_name ("OptionEditorHeading");
460 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
466 set_popdown_strings (_trim_contents_combo, dumb);
467 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
469 for (int x = 0; modifiers[x].name; ++x) {
470 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
471 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
476 l = manage (left_aligned_label (_("Trim contents using:")));
477 l->set_name ("OptionsLabel");
479 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
480 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
486 set_popdown_strings (_trim_anchored_combo, dumb);
487 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
489 for (int x = 0; modifiers[x].name; ++x) {
490 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
491 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
496 l = manage (left_aligned_label (_("Anchored trim using:")));
497 l->set_name ("OptionsLabel");
499 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
501 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
506 /* jump trim disabled for now
507 set_popdown_strings (_trim_jump_combo, dumb);
508 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
510 for (int x = 0; modifiers[x].name; ++x) {
511 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
512 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
517 l = manage (left_aligned_label (_("Jump after trim using:")));
518 l->set_name ("OptionsLabel");
520 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
522 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
528 /* note resize relative */
529 set_popdown_strings (_note_size_relative_combo, dumb);
530 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
532 for (int x = 0; modifiers[x].name; ++x) {
533 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
534 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
539 l = manage (left_aligned_label (_("Resize notes relatively using:")));
540 l->set_name ("OptionsLabel");
542 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
544 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
548 l = manage (left_aligned_label (_("While Dragging:")));
549 l->set_name ("OptionEditorHeading");
550 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
556 set_popdown_strings (_snap_modifier_combo, dumb);
557 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
559 for (int x = 0; modifiers[x].name; ++x) {
560 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
561 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
566 l = manage (left_aligned_label (_("Ignore snap using:")));
567 l->set_name ("OptionsLabel");
569 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
570 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
576 set_popdown_strings (_snap_delta_combo, dumb);
577 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
579 for (int x = 0; modifiers[x].name; ++x) {
580 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
581 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
586 l = manage (left_aligned_label (_("Snap to absolute using:")));
587 l->set_name ("OptionsLabel");
589 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
590 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
594 l = manage (left_aligned_label (_("While Trimming:")));
595 l->set_name ("OptionEditorHeading");
596 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
602 set_popdown_strings (_trim_overlap_combo, dumb);
603 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
605 for (int x = 0; modifiers[x].name; ++x) {
606 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
607 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
612 l = manage (left_aligned_label (_("Resize overlaped regions using:")));
613 l->set_name ("OptionsLabel");
615 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
616 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
620 l = manage (left_aligned_label (_("While Dragging Control Points:")));
621 l->set_name ("OptionEditorHeading");
622 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
628 set_popdown_strings (_fine_adjust_combo, dumb);
629 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
631 for (int x = 0; modifiers[x].name; ++x) {
632 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
633 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
638 l = manage (left_aligned_label (_("Fine adjust using:")));
639 l->set_name ("OptionsLabel");
641 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
642 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
648 set_popdown_strings (_push_points_combo, dumb);
649 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
651 for (int x = 0; modifiers[x].name; ++x) {
652 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
653 _push_points_combo.set_active_text (S_(modifiers[x].name));
658 l = manage (left_aligned_label (_("Push points using:")));
659 l->set_name ("OptionsLabel");
661 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
662 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
664 _box->pack_start (*t, false, false);
667 void parameter_changed (string const &)
669 /* XXX: these aren't really config options... */
672 void set_state_from_config ()
674 /* XXX: these aren't really config options... */
679 void bindings_changed ()
681 string const txt = _keyboard_layout_selector.get_active_text();
683 /* XXX: config...? for all this keyboard stuff */
685 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
686 if (txt == i->first) {
687 if (Keyboard::load_keybindings (i->second)) {
688 Keyboard::save_keybindings ();
694 void edit_modifier_chosen ()
696 string const txt = _edit_modifier_combo.get_active_text();
698 for (int i = 0; modifiers[i].name; ++i) {
699 if (txt == _(modifiers[i].name)) {
700 Keyboard::set_edit_modifier (modifiers[i].modifier);
706 void delete_modifier_chosen ()
708 string const txt = _delete_modifier_combo.get_active_text();
710 for (int i = 0; modifiers[i].name; ++i) {
711 if (txt == _(modifiers[i].name)) {
712 Keyboard::set_delete_modifier (modifiers[i].modifier);
718 void copy_modifier_chosen ()
720 string const txt = _copy_modifier_combo.get_active_text();
722 for (int i = 0; modifiers[i].name; ++i) {
723 if (txt == _(modifiers[i].name)) {
724 Keyboard::set_copy_modifier (modifiers[i].modifier);
730 void insert_note_modifier_chosen ()
732 string const txt = _insert_note_modifier_combo.get_active_text();
734 for (int i = 0; modifiers[i].name; ++i) {
735 if (txt == _(modifiers[i].name)) {
736 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
742 void snap_modifier_chosen ()
744 string const txt = _snap_modifier_combo.get_active_text();
746 for (int i = 0; modifiers[i].name; ++i) {
747 if (txt == _(modifiers[i].name)) {
748 Keyboard::set_snap_modifier (modifiers[i].modifier);
754 void snap_delta_modifier_chosen ()
756 string const txt = _snap_delta_combo.get_active_text();
758 for (int i = 0; modifiers[i].name; ++i) {
759 if (txt == _(modifiers[i].name)) {
760 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
766 void trim_contents_modifier_chosen ()
768 string const txt = _trim_contents_combo.get_active_text();
770 for (int i = 0; modifiers[i].name; ++i) {
771 if (txt == _(modifiers[i].name)) {
772 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
778 void trim_overlap_modifier_chosen ()
780 string const txt = _trim_overlap_combo.get_active_text();
782 for (int i = 0; modifiers[i].name; ++i) {
783 if (txt == _(modifiers[i].name)) {
784 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
790 void trim_anchored_modifier_chosen ()
792 string const txt = _trim_anchored_combo.get_active_text();
794 for (int i = 0; modifiers[i].name; ++i) {
795 if (txt == _(modifiers[i].name)) {
796 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
802 void fine_adjust_modifier_chosen ()
804 string const txt = _fine_adjust_combo.get_active_text();
806 for (int i = 0; modifiers[i].name; ++i) {
807 if (txt == _(modifiers[i].name)) {
808 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
814 void push_points_modifier_chosen ()
816 string const txt = _push_points_combo.get_active_text();
818 for (int i = 0; modifiers[i].name; ++i) {
819 if (txt == _(modifiers[i].name)) {
820 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
826 void note_size_relative_modifier_chosen ()
828 string const txt = _note_size_relative_combo.get_active_text();
830 for (int i = 0; modifiers[i].name; ++i) {
831 if (txt == _(modifiers[i].name)) {
832 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
838 void delete_button_changed ()
840 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
843 void edit_button_changed ()
845 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
848 void insert_note_button_changed ()
850 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
853 ComboBoxText _keyboard_layout_selector;
854 ComboBoxText _edit_modifier_combo;
855 ComboBoxText _delete_modifier_combo;
856 ComboBoxText _copy_modifier_combo;
857 ComboBoxText _insert_note_modifier_combo;
858 ComboBoxText _snap_modifier_combo;
859 ComboBoxText _snap_delta_combo;
860 ComboBoxText _trim_contents_combo;
861 ComboBoxText _trim_overlap_combo;
862 ComboBoxText _trim_anchored_combo;
863 ComboBoxText _trim_jump_combo;
864 ComboBoxText _fine_adjust_combo;
865 ComboBoxText _push_points_combo;
866 ComboBoxText _note_size_relative_combo;
867 Adjustment _delete_button_adjustment;
868 SpinButton _delete_button_spin;
869 Adjustment _edit_button_adjustment;
870 SpinButton _edit_button_spin;
871 Adjustment _insert_note_button_adjustment;
872 SpinButton _insert_note_button_spin;
876 class FontScalingOptions : public OptionEditorBox
879 FontScalingOptions (UIConfiguration* uic) :
881 _dpi_adjustment (100, 50, 250, 1, 5),
882 _dpi_slider (_dpi_adjustment)
884 _dpi_adjustment.set_value (_ui_config->get_font_scale() / 1024.);
886 Label* l = manage (new Label (_("GUI and Font scaling:")));
887 l->set_name ("OptionsLabel");
889 const Glib::ustring dflt = _("Default");
890 const Glib::ustring empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
892 _dpi_slider.set_name("FontScaleSlider");
893 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
894 _dpi_slider.set_draw_value(false);
895 _dpi_slider.add_mark(50, Gtk::POS_TOP, empty);
896 _dpi_slider.add_mark(60, Gtk::POS_TOP, empty);
897 _dpi_slider.add_mark(70, Gtk::POS_TOP, empty);
898 _dpi_slider.add_mark(80, Gtk::POS_TOP, empty);
899 _dpi_slider.add_mark(90, Gtk::POS_TOP, empty);
900 _dpi_slider.add_mark(100, Gtk::POS_TOP, dflt);
901 _dpi_slider.add_mark(125, Gtk::POS_TOP, empty);
902 _dpi_slider.add_mark(150, Gtk::POS_TOP, empty);
903 _dpi_slider.add_mark(175, Gtk::POS_TOP, empty);
904 _dpi_slider.add_mark(200, Gtk::POS_TOP, empty);
905 _dpi_slider.add_mark(225, Gtk::POS_TOP, empty);
906 _dpi_slider.add_mark(250, Gtk::POS_TOP, empty);
908 HBox* h = manage (new HBox);
910 h->pack_start (*l, false, false);
911 h->pack_start (_dpi_slider, true, true);
913 _box->pack_start (*h, false, false);
915 set_note (_("Adjusting the scale require an application restart to re-layout."));
917 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
920 void parameter_changed (string const & p)
922 if (p == "font-scale") {
923 _dpi_adjustment.set_value (_ui_config->get_font_scale() / 1024.);
927 void set_state_from_config ()
929 parameter_changed ("font-scale");
936 _ui_config->set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024.));
937 /* XXX: should be triggered from the parameter changed signal */
941 UIConfiguration* _ui_config;
942 Adjustment _dpi_adjustment;
946 class ClipLevelOptions : public OptionEditorBox
949 ClipLevelOptions (UIConfiguration* c)
951 , _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
952 , _clip_level_slider (_clip_level_adjustment)
954 _clip_level_adjustment.set_value (_ui_config->get_waveform_clip_level ());
956 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
957 l->set_name ("OptionsLabel");
959 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
960 HBox* h = manage (new HBox);
962 h->pack_start (*l, false, false);
963 h->pack_start (_clip_level_slider, true, true);
965 _box->pack_start (*h, false, false);
967 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
970 void parameter_changed (string const & p)
972 if (p == "waveform-clip-level") {
973 _clip_level_adjustment.set_value (_ui_config->get_waveform_clip_level());
977 void set_state_from_config ()
979 parameter_changed ("waveform-clip-level");
984 void clip_level_changed ()
986 _ui_config->set_waveform_clip_level (_clip_level_adjustment.get_value());
987 /* XXX: should be triggered from the parameter changed signal */
988 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
991 UIConfiguration* _ui_config;
992 Adjustment _clip_level_adjustment;
993 HScale _clip_level_slider;
996 class BufferingOptions : public OptionEditorBox
999 BufferingOptions (RCConfiguration* c)
1001 , _playback_adjustment (5, 1, 60, 1, 4)
1002 , _capture_adjustment (5, 1, 60, 1, 4)
1003 , _playback_slider (_playback_adjustment)
1004 , _capture_slider (_capture_adjustment)
1006 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1008 Label* l = manage (new Label (_("Playback (seconds of buffering):")));
1009 l->set_name ("OptionsLabel");
1011 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1012 HBox* h = manage (new HBox);
1014 h->pack_start (*l, false, false);
1015 h->pack_start (_playback_slider, true, true);
1017 _box->pack_start (*h, false, false);
1019 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1021 l = manage (new Label (_("Recording (seconds of buffering):")));
1022 l->set_name ("OptionsLabel");
1024 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1025 h = manage (new HBox);
1027 h->pack_start (*l, false, false);
1028 h->pack_start (_capture_slider, true, true);
1030 _box->pack_start (*h, false, false);
1032 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
1033 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
1036 void parameter_changed (string const & p)
1038 if (p == "playback-buffer-seconds") {
1039 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1040 } else if (p == "capture-buffer-seconds") {
1041 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1045 void set_state_from_config ()
1047 parameter_changed ("playback-buffer-seconds");
1048 parameter_changed ("capture-buffer-seconds");
1053 void playback_changed ()
1055 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
1058 void capture_changed ()
1060 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
1063 RCConfiguration* _rc_config;
1064 Adjustment _playback_adjustment;
1065 Adjustment _capture_adjustment;
1066 HScale _playback_slider;
1067 HScale _capture_slider;
1070 class ControlSurfacesOptions : public OptionEditorBox
1073 ControlSurfacesOptions (Gtk::Window& parent)
1075 , _ignore_view_change (0)
1077 _store = ListStore::create (_model);
1078 _view.set_model (_store);
1079 _view.append_column (_("Control Surface Protocol"), _model.name);
1080 _view.get_column(0)->set_resizable (true);
1081 _view.get_column(0)->set_expand (true);
1082 _view.append_column_editable (_("Enabled"), _model.enabled);
1083 _view.append_column_editable (_("Feedback"), _model.feedback);
1085 _box->pack_start (_view, false, false);
1087 Label* label = manage (new Label);
1088 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
1090 _box->pack_start (*label, false, false);
1093 ControlProtocolManager& m = ControlProtocolManager::instance ();
1094 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1095 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1097 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1098 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1101 void parameter_changed (std::string const &)
1106 void set_state_from_config ()
1110 ControlProtocolManager& m = ControlProtocolManager::instance ();
1111 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1113 if (!(*i)->mandatory) {
1114 TreeModel::Row r = *_store->append ();
1115 r[_model.name] = (*i)->name;
1116 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1117 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
1118 r[_model.protocol_info] = *i;
1125 void protocol_status_changed (ControlProtocolInfo* cpi) {
1127 TreeModel::Children rows = _store->children();
1129 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1130 string n = ((*x)[_model.name]);
1132 if ((*x)[_model.protocol_info] == cpi) {
1133 _ignore_view_change++;
1134 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1135 _ignore_view_change--;
1141 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1143 TreeModel::Row r = *i;
1145 if (_ignore_view_change) {
1149 ControlProtocolInfo* cpi = r[_model.protocol_info];
1154 bool const was_enabled = (cpi->protocol != 0);
1155 bool const is_enabled = r[_model.enabled];
1158 if (was_enabled != is_enabled) {
1161 ControlProtocolManager::instance().activate (*cpi);
1163 ControlProtocolManager::instance().deactivate (*cpi);
1167 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
1168 bool const is_feedback = r[_model.feedback];
1170 if (was_feedback != is_feedback && cpi->protocol) {
1171 cpi->protocol->set_feedback (is_feedback);
1175 void edit_clicked (GdkEventButton* ev)
1177 if (ev->type != GDK_2BUTTON_PRESS) {
1182 ControlProtocolInfo* cpi;
1185 row = *(_view.get_selection()->get_selected());
1186 if (!row[_model.enabled]) {
1189 cpi = row[_model.protocol_info];
1190 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1193 Box* box = (Box*) cpi->protocol->get_gui ();
1197 if (box->get_parent()) {
1198 static_cast<ArdourWindow*>(box->get_parent())->present();
1201 string title = row[_model.name];
1202 /* once created, the window is managed by the surface itself (as ->get_parent())
1203 * Surface's tear_down_gui() is called on session close, when de-activating
1204 * or re-initializing a surface.
1205 * tear_down_gui() hides an deletes the Window if it exists.
1207 ArdourWindow* win = new ArdourWindow (_parent, title);
1208 win->set_title ("Control Protocol Options");
1214 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1218 ControlSurfacesModelColumns ()
1223 add (protocol_info);
1226 TreeModelColumn<string> name;
1227 TreeModelColumn<bool> enabled;
1228 TreeModelColumn<bool> feedback;
1229 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1232 Glib::RefPtr<ListStore> _store;
1233 ControlSurfacesModelColumns _model;
1235 Gtk::Window& _parent;
1236 PBD::ScopedConnection protocol_status_connection;
1237 uint32_t _ignore_view_change;
1240 class VideoTimelineOptions : public OptionEditorBox
1243 VideoTimelineOptions (RCConfiguration* c)
1245 , _show_video_export_info_button (_("Show Video Export Info before export"))
1246 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1247 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1249 Table* t = manage (new Table (2, 6));
1250 t->set_spacings (4);
1252 t->attach (_video_advanced_setup_button, 0, 2, 0, 1);
1253 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1254 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1255 _("<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."));
1257 Label* l = manage (new Label (_("Video Server URL:")));
1258 l->set_alignment (0, 0.5);
1259 t->attach (*l, 0, 1, 1, 2, FILL);
1260 t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL);
1261 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1262 _("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"));
1264 l = manage (new Label (_("Video Folder:")));
1265 l->set_alignment (0, 0.5);
1266 t->attach (*l, 0, 1, 2, 3, FILL);
1267 t->attach (_video_server_docroot_entry, 1, 2, 2, 3);
1268 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1269 _("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."));
1271 /* small vspace y=3..4 */
1273 t->attach (_show_video_export_info_button, 0, 2, 4, 5);
1274 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1275 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1276 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1278 t->attach (_show_video_server_dialog_button, 0, 2, 5, 6);
1279 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1280 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1281 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1283 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1284 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1285 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1286 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1288 _box->pack_start (*t,true,true);
1291 void server_url_changed ()
1293 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1296 void server_docroot_changed ()
1298 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1301 void show_video_export_info_toggled ()
1303 bool const x = _show_video_export_info_button.get_active ();
1304 _rc_config->set_show_video_export_info (x);
1307 void show_video_server_dialog_toggled ()
1309 bool const x = _show_video_server_dialog_button.get_active ();
1310 _rc_config->set_show_video_server_dialog (x);
1313 void video_advanced_setup_toggled ()
1315 bool const x = _video_advanced_setup_button.get_active ();
1316 _rc_config->set_video_advanced_setup(x);
1319 void parameter_changed (string const & p)
1321 if (p == "video-server-url") {
1322 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1323 } else if (p == "video-server-docroot") {
1324 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1325 } else if (p == "show-video-export-info") {
1326 bool const x = _rc_config->get_show_video_export_info();
1327 _show_video_export_info_button.set_active (x);
1328 } else if (p == "show-video-server-dialog") {
1329 bool const x = _rc_config->get_show_video_server_dialog();
1330 _show_video_server_dialog_button.set_active (x);
1331 } else if (p == "video-advanced-setup") {
1332 bool const x = _rc_config->get_video_advanced_setup();
1333 _video_advanced_setup_button.set_active(x);
1334 _video_server_docroot_entry.set_sensitive(x);
1335 _video_server_url_entry.set_sensitive(x);
1339 void set_state_from_config ()
1341 parameter_changed ("video-server-url");
1342 parameter_changed ("video-server-docroot");
1343 parameter_changed ("video-monitor-setup-dialog");
1344 parameter_changed ("show-video-export-info");
1345 parameter_changed ("show-video-server-dialog");
1346 parameter_changed ("video-advanced-setup");
1350 RCConfiguration* _rc_config;
1351 Entry _video_server_url_entry;
1352 Entry _video_server_docroot_entry;
1353 CheckButton _show_video_export_info_button;
1354 CheckButton _show_video_server_dialog_button;
1355 CheckButton _video_advanced_setup_button;
1358 class PluginOptions : public OptionEditorBox
1361 PluginOptions (RCConfiguration* c, UIConfiguration* uic)
1364 , _display_plugin_scan_progress (_("Always Display Plugin Scan Progress"))
1365 , _discover_vst_on_start (_("Scan for [new] VST Plugins on Application Start"))
1366 , _discover_au_on_start (_("Scan for AudioUnit Plugins on Application Start"))
1367 , _timeout_adjustment (0, 0, 3000, 50, 50)
1368 , _timeout_slider (_timeout_adjustment)
1371 std::stringstream ss;
1372 Table* t = manage (new Table (2, 6));
1373 t->set_spacings (4);
1377 ss << "<b>" << _("General") << "</b>";
1378 l = manage (left_aligned_label (ss.str()));
1379 l->set_use_markup (true);
1380 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1381 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1383 b = manage (new Button (_("Scan for Plugins")));
1384 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1385 t->attach (*b, 0, 2, n, n+1, FILL); ++n;
1387 t->attach (_display_plugin_scan_progress, 0, 2, n, n+1); ++n;
1388 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1389 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1390 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
1392 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
1393 _timeout_slider.set_digits (0);
1394 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &PluginOptions::timeout_changed));
1396 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1397 _("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."));
1399 l = manage (left_aligned_label (_("Scan Time Out [deciseconds]")));;
1400 HBox* h = manage (new HBox);
1402 h->pack_start (*l, false, false);
1403 h->pack_start (_timeout_slider, true, true);
1404 t->attach (*h, 0, 2, n, n+1); ++n;
1407 ss << "<b>" << _("VST") << "</b>";
1408 l = manage (left_aligned_label (ss.str()));
1409 l->set_use_markup (true);
1410 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1411 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1413 b = manage (new Button (_("Clear VST Cache")));
1414 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_cache_clicked));
1415 t->attach (*b, 0, 1, n, n+1, FILL);
1417 b = manage (new Button (_("Clear VST Blacklist")));
1418 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_blacklist_clicked));
1419 t->attach (*b, 1, 2, n, n+1, FILL);
1422 t->attach (_discover_vst_on_start, 0, 2, n, n+1); ++n;
1423 _discover_vst_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_vst_on_start_toggled));
1424 Gtkmm2ext::UI::instance()->set_tip (_discover_vst_on_start,
1425 _("<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"));
1427 #ifdef LXVST_SUPPORT
1428 t->attach (*manage (left_aligned_label (_("Linux VST Path:"))), 0, 1, n, n+1);
1429 b = manage (new Button (_("Edit")));
1430 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_lxvst_path_clicked));
1431 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1434 #ifdef WINDOWS_VST_SUPPORT
1435 t->attach (*manage (left_aligned_label (_("Windows VST Path:"))), 0, 1, n, n+1);
1436 b = manage (new Button (_("Edit")));
1437 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_vst_path_clicked));
1438 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1442 #ifdef AUDIOUNIT_SUPPORT
1444 ss << "<b>" << _("Audio Unit") << "</b>";
1445 l = manage (left_aligned_label (ss.str()));
1446 l->set_use_markup (true);
1447 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1448 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1450 t->attach (_discover_au_on_start, 0, 2, n, n+1); ++n;
1451 _discover_au_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_au_on_start_toggled));
1452 Gtkmm2ext::UI::instance()->set_tip (_discover_au_on_start,
1453 _("<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."));
1456 b = manage (new Button (_("Clear AU Cache")));
1457 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_cache_clicked));
1458 t->attach (*b, 0, 1, n, n+1, FILL);
1460 b = manage (new Button (_("Clear AU Blacklist")));
1461 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_blacklist_clicked));
1462 t->attach (*b, 1, 2, n, n+1, FILL);
1466 _box->pack_start (*t,true,true);
1469 void parameter_changed (string const & p) {
1470 if (p == "show-plugin-scan-window") {
1471 bool const x = _ui_config->get_show_plugin_scan_window();
1472 _display_plugin_scan_progress.set_active (x);
1474 else if (p == "discover-vst-on-start") {
1475 bool const x = _rc_config->get_discover_vst_on_start();
1476 _discover_vst_on_start.set_active (x);
1478 else if (p == "vst-scan-timeout") {
1479 int const x = _rc_config->get_vst_scan_timeout();
1480 _timeout_adjustment.set_value (x);
1482 else if (p == "discover-audio-units") {
1483 bool const x = _rc_config->get_discover_audio_units();
1484 _discover_au_on_start.set_active (x);
1488 void set_state_from_config () {
1489 parameter_changed ("show-plugin-scan-window");
1490 parameter_changed ("discover-vst-on-start");
1491 parameter_changed ("vst-scan-timeout");
1492 parameter_changed ("discover-audio-units");
1496 RCConfiguration* _rc_config;
1497 UIConfiguration* _ui_config;
1498 CheckButton _display_plugin_scan_progress;
1499 CheckButton _discover_vst_on_start;
1500 CheckButton _discover_au_on_start;
1501 Adjustment _timeout_adjustment;
1502 HScale _timeout_slider;
1504 void display_plugin_scan_progress_toggled () {
1505 bool const x = _display_plugin_scan_progress.get_active();
1506 _ui_config->set_show_plugin_scan_window(x);
1509 void discover_vst_on_start_toggled () {
1510 bool const x = _discover_vst_on_start.get_active();
1511 _rc_config->set_discover_vst_on_start(x);
1514 void discover_au_on_start_toggled () {
1515 bool const x = _discover_au_on_start.get_active();
1516 _rc_config->set_discover_audio_units(x);
1519 void timeout_changed () {
1520 int x = floor(_timeout_adjustment.get_value());
1521 _rc_config->set_vst_scan_timeout(x);
1524 void clear_vst_cache_clicked () {
1525 PluginManager::instance().clear_vst_cache();
1528 void clear_vst_blacklist_clicked () {
1529 PluginManager::instance().clear_vst_blacklist();
1532 void clear_au_cache_clicked () {
1533 PluginManager::instance().clear_au_cache();
1536 void clear_au_blacklist_clicked () {
1537 PluginManager::instance().clear_au_blacklist();
1541 void edit_vst_path_clicked () {
1542 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1543 _("Set Windows VST Search Path"),
1544 _rc_config->get_plugin_path_vst(),
1545 PluginManager::instance().get_default_windows_vst_path()
1547 ResponseType r = (ResponseType) pd->run ();
1549 if (r == RESPONSE_ACCEPT) {
1550 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
1555 // todo consolidate with edit_vst_path_clicked..
1556 void edit_lxvst_path_clicked () {
1557 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1558 _("Set Linux VST Search Path"),
1559 _rc_config->get_plugin_path_lxvst(),
1560 PluginManager::instance().get_default_lxvst_path()
1562 ResponseType r = (ResponseType) pd->run ();
1564 if (r == RESPONSE_ACCEPT) {
1565 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
1570 void refresh_clicked () {
1571 PluginManager::instance().refresh();
1576 /** A class which allows control of visibility of some editor components usign
1577 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1578 * which has the correct members, but with null widget pointers. This
1579 * class allows the user to set visibility of the members, the details
1580 * of which are stored in a configuration variable which can be watched
1581 * by parts of the editor that actually contain the widgets whose visibility
1582 * is being controlled.
1585 class VisibilityOption : public Option
1588 /** @param name User-visible name for this group.
1589 * @param g `Dummy' VisibilityGroup (as described above).
1590 * @param get Method to get the value of the appropriate configuration variable.
1591 * @param set Method to set the value of the appropriate configuration variable.
1593 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1594 : Option (g->get_state_name(), name)
1596 , _visibility_group (g)
1600 /* Watch for changes made by the user to our members */
1601 _visibility_group->VisibilityChanged.connect_same_thread (
1602 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1606 void set_state_from_config ()
1608 /* Set our state from the current configuration */
1609 _visibility_group->set_state (_get ());
1612 void add_to_page (OptionEditorPage* p)
1614 _heading.add_to_page (p);
1615 add_widget_to_page (p, _visibility_group->list_view ());
1618 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1623 /* The user has changed something, so reflect this change
1624 in the RCConfiguration.
1626 _set (_visibility_group->get_state_value ());
1629 OptionEditorHeading _heading;
1630 VisibilityGroup* _visibility_group;
1631 sigc::slot<std::string> _get;
1632 sigc::slot<bool, std::string> _set;
1633 PBD::ScopedConnection _visibility_group_connection;
1638 RCOptionEditor::RCOptionEditor ()
1639 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1640 , _rc_config (Config)
1641 , _ui_config (ARDOUR_UI::config())
1642 , _mixer_strip_visibility ("mixer-element-visibility")
1646 uint32_t hwcpus = hardware_concurrency ();
1648 BoolComboOption* bco;
1651 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1653 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1655 _("Signal processing uses"),
1656 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1657 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1660 procs->add (-1, _("all but one processor"));
1661 procs->add (0, _("all available processors"));
1663 for (uint32_t i = 1; i <= hwcpus; ++i) {
1664 procs->add (i, string_compose (_("%1 processors"), i));
1667 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1669 add_option (_("Misc"), procs);
1672 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1674 add_option (_("Misc"), new UndoOptions (_rc_config));
1676 add_option (_("Misc"),
1678 "verify-remove-last-capture",
1679 _("Verify removal of last capture"),
1680 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1681 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1684 add_option (_("Misc"),
1686 "periodic-safety-backups",
1687 _("Make periodic backups of the session file"),
1688 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1689 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1692 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1694 add_option (_("Misc"),
1696 "only-copy-imported-files",
1697 _("Always copy imported files"),
1698 sigc::mem_fun (*_ui_config, &UIConfiguration::get_only_copy_imported_files),
1699 sigc::mem_fun (*_ui_config, &UIConfiguration::set_only_copy_imported_files)
1702 add_option (_("Misc"), new DirectoryOption (
1703 X_("default-session-parent-dir"),
1704 _("Default folder for new sessions:"),
1705 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1706 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1709 add_option (_("Misc"),
1710 new SpinOption<uint32_t> (
1711 "max-recent-sessions",
1712 _("Maximum number of recent sessions"),
1713 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1714 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1718 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1720 add_option (_("Misc"), new ClickOptions (_rc_config, this));
1722 add_option (_("Misc"),
1725 _("Click gain level"),
1726 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1727 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1730 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1732 add_option (_("Misc"),
1733 new SpinOption<double> (
1734 "automation-thinning-factor",
1735 _("Thinning factor (larger value => less data)"),
1736 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1737 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1741 add_option (_("Misc"),
1742 new SpinOption<double> (
1743 "automation-interval-msecs",
1744 _("Automation sampling interval (milliseconds)"),
1745 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1746 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1754 tsf = new BoolOption (
1755 "latched-record-enable",
1756 _("Keep record-enable engaged on stop"),
1757 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1758 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1760 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1761 add_option (_("Transport"), tsf);
1763 tsf = new BoolOption (
1765 _("Play loop is a transport mode"),
1766 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1767 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1769 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1770 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1771 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1772 add_option (_("Transport"), tsf);
1774 tsf = new BoolOption (
1775 "stop-recording-on-xrun",
1776 _("Stop recording when an xrun occurs"),
1777 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1778 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1780 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1781 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
1783 add_option (_("Transport"), tsf);
1785 tsf = new BoolOption (
1786 "create-xrun-marker",
1787 _("Create markers where xruns occur"),
1788 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
1789 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
1791 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1792 add_option (_("Transport"), tsf);
1794 tsf = new BoolOption (
1795 "stop-at-session-end",
1796 _("Stop at the end of the session"),
1797 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
1798 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
1800 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1801 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
1802 "when it reaches the current session end marker\n\n"
1803 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
1805 add_option (_("Transport"), tsf);
1807 tsf = new BoolOption (
1809 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
1810 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
1811 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
1813 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1814 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
1815 "preventing any need to do a transport locate at the end of the loop\n\n"
1816 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
1817 "which will often cause a small click or delay"), PROGRAM_NAME));
1818 add_option (_("Transport"), tsf);
1820 tsf = new BoolOption (
1821 "disable-disarm-during-roll",
1822 _("Disable per-track record disarm while rolling"),
1823 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
1824 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
1826 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"));
1827 add_option (_("Transport"), tsf);
1829 tsf = new BoolOption (
1831 _("12dB gain reduction during fast-forward and fast-rewind"),
1832 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
1833 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
1835 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
1836 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
1837 add_option (_("Transport"), tsf);
1839 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
1841 _sync_source = new ComboOption<SyncSource> (
1843 _("External timecode source"),
1844 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
1845 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
1848 add_option (_("Transport"), _sync_source);
1850 _sync_framerate = new BoolOption (
1851 "timecode-sync-frame-rate",
1852 _("Match session video frame rate to external timecode"),
1853 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
1854 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
1856 Gtkmm2ext::UI::instance()->set_tip
1857 (_sync_framerate->tip_widget(),
1858 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
1859 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
1860 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
1861 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
1862 "timecode standard and the session standard."), PROGRAM_NAME));
1864 add_option (_("Transport"), _sync_framerate);
1866 _sync_genlock = new BoolOption (
1867 "timecode-source-is-synced",
1868 _("Sync-lock timecode to clock (disable drift compensation)"),
1869 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
1870 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
1872 Gtkmm2ext::UI::instance()->set_tip
1873 (_sync_genlock->tip_widget(),
1874 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
1875 "Sync Lock indicates that the selected external timecode source shares clock-sync "
1876 "(Black & Burst, Wordclock, etc) with the audio interface. "
1877 "This option disables drift compensation. The transport speed is fixed at 1.0. "
1878 "Vari-speed LTC will be ignored and cause drift."
1880 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
1881 "timecode sources shares clock sync."
1885 add_option (_("Transport"), _sync_genlock);
1887 _sync_source_2997 = new BoolOption (
1888 "timecode-source-2997",
1889 _("Lock to 29.9700 fps instead of 30000/1001"),
1890 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
1891 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
1893 Gtkmm2ext::UI::instance()->set_tip
1894 (_sync_source_2997->tip_widget(),
1895 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
1896 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
1897 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
1898 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
1899 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
1900 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
1903 add_option (_("Transport"), _sync_source_2997);
1905 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
1907 _ltc_port = new ComboStringOption (
1909 _("LTC incoming port"),
1910 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
1911 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
1914 vector<string> physical_inputs;
1915 physical_inputs.push_back (_("None"));
1916 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
1917 _ltc_port->set_popdown_strings (physical_inputs);
1919 populate_sync_options ();
1921 add_option (_("Transport"), _ltc_port);
1923 // TODO; rather disable this button than not compile it..
1924 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
1926 add_option (_("Transport"),
1929 _("Enable LTC generator"),
1930 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
1931 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
1934 _ltc_send_continuously = new BoolOption (
1935 "ltc-send-continuously",
1936 _("Send LTC while stopped"),
1937 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
1938 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
1940 Gtkmm2ext::UI::instance()->set_tip
1941 (_ltc_send_continuously->tip_widget(),
1942 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
1943 add_option (_("Transport"), _ltc_send_continuously);
1945 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
1946 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
1947 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
1948 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
1950 Gtkmm2ext::UI::instance()->set_tip
1951 (_ltc_volume_slider->tip_widget(),
1952 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
1954 add_option (_("Transport"), _ltc_volume_slider);
1955 parameter_changed ("send-ltc");
1957 parameter_changed ("sync-source");
1961 add_option (S_("Editor"),
1963 "draggable-playhead",
1964 _("Allow dragging of playhead"),
1965 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_draggable_playhead),
1966 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_draggable_playhead)
1969 add_option (_("Editor"),
1971 "automation-follows-regions",
1972 _("Move relevant automation when audio regions are moved"),
1973 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
1974 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
1977 add_option (_("Editor"),
1979 "show-track-meters",
1980 _("Show meters on tracks in the editor"),
1981 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_track_meters),
1982 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_track_meters)
1985 add_option (_("Editor"),
1987 "show-editor-meter",
1988 _("Display master-meter in the toolbar"),
1989 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_editor_meter),
1990 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_editor_meter)
1993 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
1994 "default-fade-shape",
1995 _("Default fade shape"),
1996 sigc::mem_fun (*_rc_config,
1997 &RCConfiguration::get_default_fade_shape),
1998 sigc::mem_fun (*_rc_config,
1999 &RCConfiguration::set_default_fade_shape)
2002 fadeshape->add (FadeLinear,
2003 _("Linear (for highly correlated material)"));
2004 fadeshape->add (FadeConstantPower, _("Constant power"));
2005 fadeshape->add (FadeSymmetric, _("Symmetric"));
2006 fadeshape->add (FadeSlow, _("Slow"));
2007 fadeshape->add (FadeFast, _("Fast"));
2009 add_option (_("Editor"), fadeshape);
2012 bco = new BoolComboOption (
2013 "use-overlap-equivalency",
2014 _("Regions in active edit groups are edited together"),
2015 _("whenever they overlap in time"),
2016 _("only if they have identical length, position and origin"),
2017 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2018 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2021 add_option (_("Editor"), bco);
2023 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2025 _("Layering model"),
2026 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2027 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2030 lm->add (LaterHigher, _("later is higher"));
2031 lm->add (Manual, _("manual layering"));
2032 add_option (_("Editor"), lm);
2034 add_option (_("Editor"),
2036 "rubberbanding-snaps-to-grid",
2037 _("Make rubberband selection rectangle snap to the grid"),
2038 sigc::mem_fun (*_ui_config, &UIConfiguration::get_rubberbanding_snaps_to_grid),
2039 sigc::mem_fun (*_ui_config, &UIConfiguration::set_rubberbanding_snaps_to_grid)
2042 add_option (_("Editor"),
2045 _("Show waveforms in regions"),
2046 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms),
2047 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms)
2050 add_option (_("Editor"),
2051 new BoolComboOption (
2052 "show-region-gain-envelopes",
2053 _("Show gain envelopes in audio regions"),
2055 _("only in region gain mode"),
2056 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_region_gain),
2057 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_region_gain)
2060 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
2062 _("Waveform scale"),
2063 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_scale),
2064 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_scale)
2067 wfs->add (Linear, _("linear"));
2068 wfs->add (Logarithmic, _("logarithmic"));
2070 add_option (_("Editor"), wfs);
2072 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
2074 _("Waveform shape"),
2075 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_shape),
2076 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_shape)
2079 wfsh->add (Traditional, _("traditional"));
2080 wfsh->add (Rectified, _("rectified"));
2082 add_option (_("Editor"), wfsh);
2084 add_option (_("Editor"), new ClipLevelOptions (_ui_config));
2086 add_option (_("Editor"),
2088 "show-waveforms-while-recording",
2089 _("Show waveforms for audio while it is being recorded"),
2090 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms_while_recording),
2091 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms_while_recording)
2094 add_option (_("Editor"),
2097 _("Show zoom toolbar"),
2098 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_zoom_tools),
2099 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_zoom_tools)
2102 add_option (_("Editor"),
2104 "update-editor-during-summary-drag",
2105 _("Update editor window during drags of the summary"),
2106 sigc::mem_fun (*_ui_config, &UIConfiguration::get_update_editor_during_summary_drag),
2107 sigc::mem_fun (*_ui_config, &UIConfiguration::set_update_editor_during_summary_drag)
2110 bo = new BoolOption (
2112 _("Name new markers"),
2113 sigc::mem_fun (*_ui_config, &UIConfiguration::get_name_new_markers),
2114 sigc::mem_fun (*_ui_config, &UIConfiguration::set_name_new_markers)
2117 add_option (_("Editor"), bo);
2118 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."
2119 "\n\nYou can always rename markers by right-clicking on them"));
2121 add_option (_("Editor"),
2123 "autoscroll-editor",
2124 _("Auto-scroll editor window when dragging near its edges"),
2125 sigc::mem_fun (*_ui_config, &UIConfiguration::get_autoscroll_editor),
2126 sigc::mem_fun (*_ui_config, &UIConfiguration::set_autoscroll_editor)
2129 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2130 "region-selection-after-split",
2131 _("After splitting selected regions, select"),
2132 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2133 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2135 // TODO: decide which of these modes are really useful
2136 rsas->add(None, _("no regions"));
2137 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2138 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2139 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2140 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2141 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2142 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2143 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2145 add_option (_("Editor"), rsas);
2150 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2152 add_option (_("Audio"), new BufferingOptions (_rc_config));
2154 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2156 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2158 _("Record monitoring handled by"),
2159 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2160 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2163 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2164 mm->add (HardwareMonitoring, _("via Audio Driver"));
2167 string prog (PROGRAM_NAME);
2168 boost::algorithm::to_lower (prog);
2169 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2170 mm->add (ExternalMonitoring, _("audio hardware"));
2172 add_option (_("Audio"), mm);
2174 add_option (_("Audio"),
2176 "tape-machine-mode",
2177 _("Tape machine mode"),
2178 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2179 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2182 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
2184 add_option (_("Audio"),
2186 "auto-connect-standard-busses",
2187 _("Auto-connect master/monitor busses"),
2188 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2189 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2192 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2193 "input-auto-connect",
2194 _("Connect track inputs"),
2195 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2196 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2199 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2200 iac->add (ManualConnect, _("manually"));
2202 add_option (_("Audio"), iac);
2204 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2205 "output-auto-connect",
2206 _("Connect track and bus outputs"),
2207 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2208 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2211 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2212 oac->add (AutoConnectMaster, _("automatically to master bus"));
2213 oac->add (ManualConnect, _("manually"));
2215 add_option (_("Audio"), oac);
2217 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2219 add_option (_("Audio"),
2221 "denormal-protection",
2222 _("Use DC bias to protect against denormals"),
2223 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2224 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2227 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2229 _("Processor handling"),
2230 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2231 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2235 dm->add (DenormalNone, _("no processor handling"));
2239 if (fpu.has_flush_to_zero()) {
2241 dm->add (DenormalFTZ, _("use FlushToZero"));
2242 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2243 _rc_config->set_denormal_model(DenormalNone);
2246 if (fpu.has_denormals_are_zero()) {
2248 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2249 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2250 _rc_config->set_denormal_model(DenormalNone);
2253 if (fpu.has_flush_to_zero() && fpu.has_denormals_are_zero()) {
2255 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2256 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2257 _rc_config->set_denormal_model(DenormalNone);
2261 dm->set_sensitive(false);
2264 add_option (_("Audio"), dm);
2266 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
2268 add_option (_("Audio"),
2270 "plugins-stop-with-transport",
2271 _("Silence plugins when the transport is stopped"),
2272 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
2273 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
2276 add_option (_("Audio"),
2278 "new-plugins-active",
2279 _("Make new plugins active"),
2280 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
2281 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
2284 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2286 add_option (_("Audio"),
2288 "auto-analyse-audio",
2289 _("Enable automatic analysis of audio"),
2290 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2291 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2294 add_option (_("Audio"),
2296 "replicate-missing-region-channels",
2297 _("Replicate missing region channels"),
2298 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2299 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2304 add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
2306 add_option (_("Solo / mute"),
2309 _("Solo-in-place mute cut (dB)"),
2310 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2311 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2314 _solo_control_is_listen_control = new BoolOption (
2315 "solo-control-is-listen-control",
2316 _("Solo controls are Listen controls"),
2317 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2318 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2321 add_option (_("Solo / mute"), _solo_control_is_listen_control);
2323 _listen_position = new ComboOption<ListenPosition> (
2325 _("Listen Position"),
2326 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2327 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2330 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2331 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2333 add_option (_("Solo / mute"), _listen_position);
2335 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2337 _("PFL signals come from"),
2338 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2339 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2342 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2343 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2345 add_option (_("Solo / mute"), pp);
2347 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2349 _("AFL signals come from"),
2350 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2351 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2354 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2355 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2357 add_option (_("Solo / mute"), pa);
2359 parameter_changed ("use-monitor-bus");
2361 add_option (_("Solo / mute"),
2364 _("Exclusive solo"),
2365 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2366 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2369 add_option (_("Solo / mute"),
2372 _("Show solo muting"),
2373 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2374 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2377 add_option (_("Solo / mute"),
2379 "solo-mute-override",
2380 _("Soloing overrides muting"),
2381 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2382 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2385 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
2387 add_option (_("Solo / mute"),
2389 "mute-affects-pre-fader",
2390 _("Mute affects pre-fader sends"),
2391 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2392 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2395 add_option (_("Solo / mute"),
2397 "mute-affects-post-fader",
2398 _("Mute affects post-fader sends"),
2399 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2400 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2403 add_option (_("Solo / mute"),
2405 "mute-affects-control-outs",
2406 _("Mute affects control outputs"),
2407 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2408 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2411 add_option (_("Solo / mute"),
2413 "mute-affects-main-outs",
2414 _("Mute affects main outputs"),
2415 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2416 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2419 add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
2421 add_option (_("Solo / mute"),
2423 "link-send-and-route-panner",
2424 _("Link panners of Aux and External Sends with main panner by default"),
2425 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2426 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2429 add_option (_("MIDI"),
2430 new SpinOption<float> (
2432 _("MIDI read-ahead time (seconds)"),
2433 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2434 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2439 add_option (_("MIDI"),
2442 _("Send MIDI Clock"),
2443 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2444 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2447 add_option (_("MIDI"),
2450 _("Send MIDI Time Code"),
2451 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2452 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2455 add_option (_("MIDI"),
2456 new SpinOption<int> (
2457 "mtc-qf-speed-tolerance",
2458 _("Percentage either side of normal transport speed to transmit MTC"),
2459 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2460 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2464 add_option (_("MIDI"),
2467 _("Obey MIDI Machine Control commands"),
2468 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2469 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2472 add_option (_("MIDI"),
2475 _("Send MIDI Machine Control commands"),
2476 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2477 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2480 add_option (_("MIDI"),
2483 _("Send MIDI control feedback"),
2484 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2485 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2488 add_option (_("MIDI"),
2489 new SpinOption<uint8_t> (
2490 "mmc-receive-device-id",
2491 _("Inbound MMC device ID"),
2492 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2493 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2497 add_option (_("MIDI"),
2498 new SpinOption<uint8_t> (
2499 "mmc-send-device-id",
2500 _("Outbound MMC device ID"),
2501 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2502 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2506 add_option (_("MIDI"),
2507 new SpinOption<int32_t> (
2508 "initial-program-change",
2509 _("Initial program change"),
2510 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2511 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2515 add_option (_("MIDI"),
2517 "display-first-midi-bank-as-zero",
2518 _("Display first MIDI bank/program as 0"),
2519 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2520 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2523 add_option (_("MIDI"),
2525 "never-display-periodic-midi",
2526 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2527 sigc::mem_fun (*_ui_config, &UIConfiguration::get_never_display_periodic_midi),
2528 sigc::mem_fun (*_ui_config, &UIConfiguration::set_never_display_periodic_midi)
2531 add_option (_("MIDI"),
2534 _("Sound MIDI notes as they are selected"),
2535 sigc::mem_fun (*_ui_config, &UIConfiguration::get_sound_midi_notes),
2536 sigc::mem_fun (*_ui_config, &UIConfiguration::set_sound_midi_notes)
2539 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2541 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2542 "midi-audition-synth-uri",
2543 _("Midi Audition Synth (LV2)"),
2544 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2545 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2548 audition_synth->add(X_(""), _("None"));
2549 PluginInfoList all_plugs;
2550 PluginManager& manager (PluginManager::instance());
2552 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2554 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2555 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2556 if (!(*i)->is_instrument()) continue;
2557 if ((*i)->type != ARDOUR::LV2) continue;
2558 audition_synth->add((*i)->unique_id, (*i)->name);
2562 add_option (_("MIDI"), audition_synth);
2564 /* USER INTERACTION */
2567 #ifdef PLATFORM_WINDOWS
2570 getenv ("ARDOUR_BUNDLED")
2574 add_option (_("User interaction"),
2576 "enable-translation",
2577 string_compose (_("Use translations of %1 messages\n"
2578 " <i>(requires a restart of %1 to take effect)</i>\n"
2579 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2580 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2581 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2584 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2586 add_option (_("User interaction"), new KeyboardOptions);
2588 /* Control Surfaces */
2590 add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
2592 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2594 _("Control surface remote ID"),
2595 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2596 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2599 rm->add (UserOrdered, _("assigned by user"));
2600 rm->add (MixerOrdered, _("follows order of mixer"));
2602 add_option (_("Control Surfaces"), rm);
2604 /* VIDEO Timeline */
2605 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2607 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2608 /* Plugin options (currrently VST only) */
2609 add_option (_("Plugins"), new PluginOptions (_rc_config, _ui_config));
2614 add_option (S_("Preferences|GUI"),
2617 _("Graphically indicate mouse pointer hovering over various widgets"),
2618 sigc::mem_fun (*_ui_config, &UIConfiguration::get_widget_prelight),
2619 sigc::mem_fun (*_ui_config, &UIConfiguration::set_widget_prelight)
2622 #ifdef TOOLTIPS_GOT_FIXED
2623 add_option (S_("Preferences|GUI"),
2626 _("Show tooltips if mouse hovers over a control"),
2627 sigc::mem_fun (*_ui_config, &UIConfiguration::get_use_tooltips),
2628 sigc::mem_fun (*_ui_config, &UIConfiguration::set_use_tooltips)
2632 add_option (S_("Preferences|GUI"),
2634 "show-name-highlight",
2635 _("Use name highlight bars in region displays (requires a restart)"),
2636 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_name_highlight),
2637 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_name_highlight)
2641 /* font scaling does nothing with GDK/Quartz */
2642 add_option (S_("Preferences|GUI"), new FontScalingOptions (_ui_config));
2645 add_option (S_("GUI"),
2647 "super-rapid-clock-update",
2648 _("update transport clock display at FPS instead of every 100ms"),
2649 sigc::mem_fun (*_ui_config, &UIConfiguration::get_super_rapid_clock_update),
2650 sigc::mem_fun (*_ui_config, &UIConfiguration::set_super_rapid_clock_update)
2653 /* Lock GUI timeout */
2655 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
2656 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2657 _("Lock timeout (seconds)"),
2659 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_lock_gui_after_seconds),
2660 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_lock_gui_after_seconds)
2662 slts->scale().set_digits (0);
2663 Gtkmm2ext::UI::instance()->set_tip
2664 (slts->tip_widget(),
2665 _("Lock GUI after this many idle seconds (zero to never lock)"));
2666 add_option (S_("Preferences|GUI"), slts);
2668 /* The names of these controls must be the same as those given in MixerStrip
2669 for the actual widgets being controlled.
2671 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
2672 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2673 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
2674 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
2675 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
2676 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2679 S_("Preferences|GUI"),
2680 new VisibilityOption (
2682 &_mixer_strip_visibility,
2683 sigc::mem_fun (*_ui_config, &UIConfiguration::get_mixer_strip_visibility),
2684 sigc::mem_fun (*_ui_config, &UIConfiguration::set_mixer_strip_visibility)
2688 add_option (S_("Preferences|GUI"),
2690 "default-narrow_ms",
2691 _("Use narrow strips in the mixer by default"),
2692 sigc::mem_fun (*_ui_config, &UIConfiguration::get_default_narrow_ms),
2693 sigc::mem_fun (*_ui_config, &UIConfiguration::set_default_narrow_ms)
2696 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2698 ComboOption<float>* mht = new ComboOption<float> (
2700 _("Peak hold time"),
2701 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_hold),
2702 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_hold)
2705 mht->add (MeterHoldOff, _("off"));
2706 mht->add (MeterHoldShort, _("short"));
2707 mht->add (MeterHoldMedium, _("medium"));
2708 mht->add (MeterHoldLong, _("long"));
2710 add_option (S_("Preferences|Metering"), mht);
2712 ComboOption<float>* mfo = new ComboOption<float> (
2715 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2716 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2719 mfo->add (METER_FALLOFF_OFF, _("off"));
2720 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2721 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2722 mfo->add (METER_FALLOFF_SLOWISH, _("slowish [12.0dB/sec] (DIN)"));
2723 mfo->add (METER_FALLOFF_MODERATE, _("moderate [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2724 mfo->add (METER_FALLOFF_MEDIUM, _("medium [20dB/sec]"));
2725 mfo->add (METER_FALLOFF_FAST, _("fast [32dB/sec]"));
2726 mfo->add (METER_FALLOFF_FASTER, _("faster [46dB/sec]"));
2727 mfo->add (METER_FALLOFF_FASTEST, _("fastest [70dB/sec]"));
2729 add_option (S_("Preferences|Metering"), mfo);
2731 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2732 "meter-line-up-level",
2733 _("Meter line-up level; 0dBu"),
2734 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_level),
2735 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_level)
2738 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2739 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2740 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2741 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2743 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."));
2745 add_option (S_("Preferences|Metering"), mlu);
2747 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2748 "meter-line-up-din",
2749 _("IEC1/DIN Meter line-up level; 0dBu"),
2750 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_din),
2751 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_din)
2754 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2755 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2756 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2757 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2759 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2761 add_option (S_("Preferences|Metering"), mld);
2763 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2764 "meter-vu-standard",
2765 _("VU Meter standard"),
2766 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_vu_standard),
2767 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_vu_standard)
2770 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2771 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2772 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2773 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2775 add_option (S_("Preferences|Metering"), mvu);
2777 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
2778 HSliderOption *mpks = new HSliderOption("meter-peak",
2779 _("Peak threshold [dBFS]"),
2781 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_peak),
2782 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_peak)
2785 Gtkmm2ext::UI::instance()->set_tip
2786 (mpks->tip_widget(),
2787 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
2789 add_option (S_("Preferences|Metering"), mpks);
2791 add_option (S_("Preferences|Metering"),
2794 _("LED meter style"),
2795 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_style_led),
2796 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_style_led)
2799 /* and now the theme manager */
2801 ThemeManager* tm = manage (new ThemeManager);
2802 add_page (_("Theme"), *tm);
2806 RCOptionEditor::parameter_changed (string const & p)
2808 OptionEditor::parameter_changed (p);
2810 if (p == "use-monitor-bus") {
2811 bool const s = Config->get_use_monitor_bus ();
2813 /* we can't use this if we don't have a monitor bus */
2814 Config->set_solo_control_is_listen_control (false);
2816 _solo_control_is_listen_control->set_sensitive (s);
2817 _listen_position->set_sensitive (s);
2818 } else if (p == "sync-source") {
2819 _sync_source->set_sensitive (true);
2821 _sync_source->set_sensitive (!_session->config.get_external_sync());
2823 switch(Config->get_sync_source()) {
2826 _sync_genlock->set_sensitive (true);
2827 _sync_framerate->set_sensitive (true);
2828 _sync_source_2997->set_sensitive (true);
2831 _sync_genlock->set_sensitive (false);
2832 _sync_framerate->set_sensitive (false);
2833 _sync_source_2997->set_sensitive (false);
2836 } else if (p == "send-ltc") {
2837 bool const s = Config->get_send_ltc ();
2838 _ltc_send_continuously->set_sensitive (s);
2839 _ltc_volume_slider->set_sensitive (s);
2843 void RCOptionEditor::ltc_generator_volume_changed () {
2844 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
2848 RCOptionEditor::populate_sync_options ()
2850 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
2852 _sync_source->clear ();
2854 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
2855 _sync_source->add (*i, sync_source_to_string (*i));
2858 if (sync_opts.empty()) {
2859 _sync_source->set_sensitive(false);
2861 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
2862 _rc_config->set_sync_source(sync_opts.front());