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 <cairo/cairo.h>
26 #include <boost/algorithm/string.hpp>
28 #include <gtkmm/liststore.h>
29 #include <gtkmm/stock.h>
30 #include <gtkmm/scale.h>
32 #include <gtkmm2ext/utils.h>
33 #include <gtkmm2ext/slider_controller.h>
34 #include <gtkmm2ext/gtk_ui.h>
35 #include <gtkmm2ext/paths_dialog.h>
40 #include "ardour/audioengine.h"
41 #include "ardour/dB.h"
42 #include "ardour/rc_configuration.h"
43 #include "ardour/control_protocol_manager.h"
44 #include "ardour/plugin_manager.h"
45 #include "control_protocol/control_protocol.h"
47 #include "canvas/wave_view.h"
49 #include "ardour_ui.h"
50 #include "ardour_window.h"
51 #include "ardour_dialog.h"
52 #include "gui_thread.h"
53 #include "midi_tracer.h"
54 #include "rc_option_editor.h"
56 #include "midi_port_dialog.h"
59 #include "theme_manager.h"
60 #include "ui_config.h"
65 using namespace Gtkmm2ext;
67 using namespace ARDOUR;
68 using namespace ARDOUR_UI_UTILS;
70 class ClickOptions : public OptionEditorBox
73 ClickOptions (RCConfiguration* c, Gtk::Window* p)
76 Table* t = manage (new Table (2, 3));
79 Label* l = manage (left_aligned_label (_("Click audio file:")));
80 t->attach (*l, 0, 1, 0, 1, FILL);
81 t->attach (_click_path_entry, 1, 2, 0, 1, FILL);
82 Button* b = manage (new Button (_("Browse...")));
83 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
84 t->attach (*b, 2, 3, 0, 1, FILL);
86 l = manage (left_aligned_label (_("Click emphasis audio file:")));
87 t->attach (*l, 0, 1, 1, 2, FILL);
88 t->attach (_click_emphasis_path_entry, 1, 2, 1, 2, FILL);
89 b = manage (new Button (_("Browse...")));
90 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
91 t->attach (*b, 2, 3, 1, 2, FILL);
93 _box->pack_start (*t, false, false);
95 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
96 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
99 void parameter_changed (string const & p)
101 if (p == "click-sound") {
102 _click_path_entry.set_text (_rc_config->get_click_sound());
103 } else if (p == "click-emphasis-sound") {
104 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
108 void set_state_from_config ()
110 parameter_changed ("click-sound");
111 parameter_changed ("click-emphasis-sound");
116 void click_browse_clicked ()
118 SoundFileChooser sfdb (_("Choose Click"));
123 if (sfdb.run () == RESPONSE_OK) {
124 click_chosen (sfdb.get_filename());
128 void click_chosen (string const & path)
130 _click_path_entry.set_text (path);
131 _rc_config->set_click_sound (path);
134 void click_changed ()
136 click_chosen (_click_path_entry.get_text ());
139 void click_emphasis_browse_clicked ()
141 SoundFileChooser sfdb (_("Choose Click Emphasis"));
146 if (sfdb.run () == RESPONSE_OK) {
147 click_emphasis_chosen (sfdb.get_filename());
151 void click_emphasis_chosen (string const & path)
153 _click_emphasis_path_entry.set_text (path);
154 _rc_config->set_click_emphasis_sound (path);
157 void click_emphasis_changed ()
159 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
162 RCConfiguration* _rc_config;
163 Entry _click_path_entry;
164 Entry _click_emphasis_path_entry;
167 class UndoOptions : public OptionEditorBox
170 UndoOptions (RCConfiguration* c) :
172 _limit_undo_button (_("Limit undo history to")),
173 _save_undo_button (_("Save undo history of"))
175 Table* t = new Table (2, 3);
178 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
179 _limit_undo_spin.set_range (0, 512);
180 _limit_undo_spin.set_increments (1, 10);
181 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
182 Label* l = manage (left_aligned_label (_("commands")));
183 t->attach (*l, 2, 3, 0, 1);
185 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
186 _save_undo_spin.set_range (0, 512);
187 _save_undo_spin.set_increments (1, 10);
188 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
189 l = manage (left_aligned_label (_("commands")));
190 t->attach (*l, 2, 3, 1, 2);
192 _box->pack_start (*t);
194 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
195 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
196 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
197 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
200 void parameter_changed (string const & p)
202 if (p == "history-depth") {
203 int32_t const d = _rc_config->get_history_depth();
204 _limit_undo_button.set_active (d != 0);
205 _limit_undo_spin.set_sensitive (d != 0);
206 _limit_undo_spin.set_value (d);
207 } else if (p == "save-history") {
208 bool const x = _rc_config->get_save_history ();
209 _save_undo_button.set_active (x);
210 _save_undo_spin.set_sensitive (x);
211 } else if (p == "save-history-depth") {
212 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
216 void set_state_from_config ()
218 parameter_changed ("save-history");
219 parameter_changed ("history-depth");
220 parameter_changed ("save-history-depth");
223 void limit_undo_toggled ()
225 bool const x = _limit_undo_button.get_active ();
226 _limit_undo_spin.set_sensitive (x);
227 int32_t const n = x ? 16 : 0;
228 _limit_undo_spin.set_value (n);
229 _rc_config->set_history_depth (n);
232 void limit_undo_changed ()
234 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
237 void save_undo_toggled ()
239 bool const x = _save_undo_button.get_active ();
240 _rc_config->set_save_history (x);
243 void save_undo_changed ()
245 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
249 RCConfiguration* _rc_config;
250 CheckButton _limit_undo_button;
251 SpinButton _limit_undo_spin;
252 CheckButton _save_undo_button;
253 SpinButton _save_undo_spin;
258 static const struct {
270 { "Key|Shift", GDK_SHIFT_MASK },
271 { "Command", GDK_META_MASK },
272 { "Control", GDK_CONTROL_MASK },
273 { "Option", GDK_MOD1_MASK },
274 { "Command-Shift", GDK_META_MASK|GDK_SHIFT_MASK },
275 { "Command-Option", GDK_MOD1_MASK|GDK_META_MASK },
276 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
277 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
278 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_META_MASK },
281 { "Key|Shift", GDK_SHIFT_MASK },
282 { "Control", GDK_CONTROL_MASK },
283 { "Alt", GDK_MOD1_MASK },
284 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
285 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
286 { "Shift-Alt", GDK_SHIFT_MASK|GDK_MOD1_MASK },
287 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
288 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
289 { "Mod2", GDK_MOD2_MASK },
290 { "Mod3", GDK_MOD3_MASK },
291 { "Windows", GDK_MOD4_MASK },
292 { "Mod5", GDK_MOD5_MASK },
298 class KeyboardOptions : public OptionEditorBox
302 _delete_button_adjustment (3, 1, 12),
303 _delete_button_spin (_delete_button_adjustment),
304 _edit_button_adjustment (3, 1, 5),
305 _edit_button_spin (_edit_button_adjustment),
306 _insert_note_button_adjustment (3, 1, 5),
307 _insert_note_button_spin (_insert_note_button_adjustment)
309 /* internationalize and prepare for use with combos */
312 for (int i = 0; modifiers[i].name; ++i) {
313 dumb.push_back (S_(modifiers[i].name));
316 set_popdown_strings (_edit_modifier_combo, dumb);
317 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
319 for (int x = 0; modifiers[x].name; ++x) {
320 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
321 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
326 Table* t = manage (new Table (5, 11));
332 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
333 l->set_name ("OptionsLabel");
337 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
338 strs.push_back (bf->first);
341 set_popdown_strings (_keyboard_layout_selector, strs);
342 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
343 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
345 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
346 t->attach (_keyboard_layout_selector, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
351 l = manage (left_aligned_label (_("When Clicking:")));
352 l->set_name ("OptionEditorHeading");
353 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
358 l = manage (left_aligned_label (_("Edit using:")));
359 l->set_name ("OptionsLabel");
361 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
362 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
364 l = manage (new Label (_("+ button")));
365 l->set_name ("OptionsLabel");
367 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
368 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
370 _edit_button_spin.set_name ("OptionsEntry");
371 _edit_button_adjustment.set_value (Keyboard::edit_button());
372 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
377 set_popdown_strings (_delete_modifier_combo, dumb);
378 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
380 for (int x = 0; modifiers[x].name; ++x) {
381 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
382 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
387 l = manage (left_aligned_label (_("Delete using:")));
388 l->set_name ("OptionsLabel");
390 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
391 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
393 l = manage (new Label (_("+ button")));
394 l->set_name ("OptionsLabel");
396 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
397 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
399 _delete_button_spin.set_name ("OptionsEntry");
400 _delete_button_adjustment.set_value (Keyboard::delete_button());
401 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
406 set_popdown_strings (_insert_note_modifier_combo, dumb);
407 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
409 for (int x = 0; modifiers[x].name; ++x) {
410 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
411 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
416 l = manage (left_aligned_label (_("Insert note using:")));
417 l->set_name ("OptionsLabel");
419 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
420 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
422 l = manage (new Label (_("+ button")));
423 l->set_name ("OptionsLabel");
425 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
426 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
428 _insert_note_button_spin.set_name ("OptionsEntry");
429 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
430 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
434 l = manage (left_aligned_label (_("When Beginning a Drag:")));
435 l->set_name ("OptionEditorHeading");
436 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
442 set_popdown_strings (_copy_modifier_combo, dumb);
443 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
445 for (int x = 0; modifiers[x].name; ++x) {
446 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
447 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
452 l = manage (left_aligned_label (_("Copy items using:")));
453 l->set_name ("OptionsLabel");
455 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
456 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
461 /* constraint modifier */
462 set_popdown_strings (_constraint_modifier_combo, dumb);
463 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
465 for (int x = 0; modifiers[x].name; ++x) {
466 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
467 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
472 l = manage (left_aligned_label (_("Constrain drag using:")));
473 l->set_name ("OptionsLabel");
475 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
476 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
480 l = manage (left_aligned_label (_("When Beginning a Trim:")));
481 l->set_name ("OptionEditorHeading");
482 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
488 set_popdown_strings (_trim_contents_combo, dumb);
489 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
491 for (int x = 0; modifiers[x].name; ++x) {
492 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
493 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
498 l = manage (left_aligned_label (_("Trim contents using:")));
499 l->set_name ("OptionsLabel");
501 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
502 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
508 set_popdown_strings (_trim_anchored_combo, dumb);
509 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
511 for (int x = 0; modifiers[x].name; ++x) {
512 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
513 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
518 l = manage (left_aligned_label (_("Anchored trim using:")));
519 l->set_name ("OptionsLabel");
521 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
523 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
528 /* jump trim disabled for now
529 set_popdown_strings (_trim_jump_combo, dumb);
530 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
532 for (int x = 0; modifiers[x].name; ++x) {
533 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
534 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
539 l = manage (left_aligned_label (_("Jump after trim using:")));
540 l->set_name ("OptionsLabel");
542 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
544 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
550 /* note resize relative */
551 set_popdown_strings (_note_size_relative_combo, dumb);
552 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
554 for (int x = 0; modifiers[x].name; ++x) {
555 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
556 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
561 l = manage (left_aligned_label (_("Resize notes relatively using:")));
562 l->set_name ("OptionsLabel");
564 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
566 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
570 l = manage (left_aligned_label (_("While Dragging:")));
571 l->set_name ("OptionEditorHeading");
572 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
578 set_popdown_strings (_snap_modifier_combo, dumb);
579 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
581 for (int x = 0; modifiers[x].name; ++x) {
582 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
583 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
588 l = manage (left_aligned_label (_("Ignore snap using:")));
589 l->set_name ("OptionsLabel");
591 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
592 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
598 set_popdown_strings (_snap_delta_combo, dumb);
599 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
601 for (int x = 0; modifiers[x].name; ++x) {
602 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
603 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
608 l = manage (left_aligned_label (_("Snap relatively using:")));
609 l->set_name ("OptionsLabel");
611 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
612 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
616 l = manage (left_aligned_label (_("While Trimming:")));
617 l->set_name ("OptionEditorHeading");
618 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
624 set_popdown_strings (_trim_overlap_combo, dumb);
625 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
627 for (int x = 0; modifiers[x].name; ++x) {
628 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
629 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
634 l = manage (left_aligned_label (_("Resize overlaped regions using:")));
635 l->set_name ("OptionsLabel");
637 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
638 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
642 l = manage (left_aligned_label (_("While Dragging Control Points:")));
643 l->set_name ("OptionEditorHeading");
644 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
650 set_popdown_strings (_fine_adjust_combo, dumb);
651 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
653 for (int x = 0; modifiers[x].name; ++x) {
654 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
655 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
660 l = manage (left_aligned_label (_("Fine adjust using:")));
661 l->set_name ("OptionsLabel");
663 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
664 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
670 set_popdown_strings (_push_points_combo, dumb);
671 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
673 for (int x = 0; modifiers[x].name; ++x) {
674 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
675 _push_points_combo.set_active_text (S_(modifiers[x].name));
680 l = manage (left_aligned_label (_("Push points using:")));
681 l->set_name ("OptionsLabel");
683 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
684 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
686 _box->pack_start (*t, false, false);
689 void parameter_changed (string const &)
691 /* XXX: these aren't really config options... */
694 void set_state_from_config ()
696 /* XXX: these aren't really config options... */
701 void bindings_changed ()
703 string const txt = _keyboard_layout_selector.get_active_text();
705 /* XXX: config...? for all this keyboard stuff */
707 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
708 if (txt == i->first) {
709 if (Keyboard::load_keybindings (i->second)) {
710 Keyboard::save_keybindings ();
716 void edit_modifier_chosen ()
718 string const txt = _edit_modifier_combo.get_active_text();
720 for (int i = 0; modifiers[i].name; ++i) {
721 if (txt == _(modifiers[i].name)) {
722 Keyboard::set_edit_modifier (modifiers[i].modifier);
728 void delete_modifier_chosen ()
730 string const txt = _delete_modifier_combo.get_active_text();
732 for (int i = 0; modifiers[i].name; ++i) {
733 if (txt == _(modifiers[i].name)) {
734 Keyboard::set_delete_modifier (modifiers[i].modifier);
740 void copy_modifier_chosen ()
742 string const txt = _copy_modifier_combo.get_active_text();
744 for (int i = 0; modifiers[i].name; ++i) {
745 if (txt == _(modifiers[i].name)) {
746 Keyboard::set_copy_modifier (modifiers[i].modifier);
752 void insert_note_modifier_chosen ()
754 string const txt = _insert_note_modifier_combo.get_active_text();
756 for (int i = 0; modifiers[i].name; ++i) {
757 if (txt == _(modifiers[i].name)) {
758 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
764 void snap_modifier_chosen ()
766 string const txt = _snap_modifier_combo.get_active_text();
768 for (int i = 0; modifiers[i].name; ++i) {
769 if (txt == _(modifiers[i].name)) {
770 Keyboard::set_snap_modifier (modifiers[i].modifier);
776 void snap_delta_modifier_chosen ()
778 string const txt = _snap_delta_combo.get_active_text();
780 for (int i = 0; modifiers[i].name; ++i) {
781 if (txt == _(modifiers[i].name)) {
782 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
788 void constraint_modifier_chosen ()
790 string const txt = _constraint_modifier_combo.get_active_text();
792 for (int i = 0; modifiers[i].name; ++i) {
793 if (txt == _(modifiers[i].name)) {
794 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
800 void trim_contents_modifier_chosen ()
802 string const txt = _trim_contents_combo.get_active_text();
804 for (int i = 0; modifiers[i].name; ++i) {
805 if (txt == _(modifiers[i].name)) {
806 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
812 void trim_overlap_modifier_chosen ()
814 string const txt = _trim_overlap_combo.get_active_text();
816 for (int i = 0; modifiers[i].name; ++i) {
817 if (txt == _(modifiers[i].name)) {
818 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
824 void trim_anchored_modifier_chosen ()
826 string const txt = _trim_anchored_combo.get_active_text();
828 for (int i = 0; modifiers[i].name; ++i) {
829 if (txt == _(modifiers[i].name)) {
830 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
836 void fine_adjust_modifier_chosen ()
838 string const txt = _fine_adjust_combo.get_active_text();
840 for (int i = 0; modifiers[i].name; ++i) {
841 if (txt == _(modifiers[i].name)) {
842 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
848 void push_points_modifier_chosen ()
850 string const txt = _push_points_combo.get_active_text();
852 for (int i = 0; modifiers[i].name; ++i) {
853 if (txt == _(modifiers[i].name)) {
854 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
860 void note_size_relative_modifier_chosen ()
862 string const txt = _note_size_relative_combo.get_active_text();
864 for (int i = 0; modifiers[i].name; ++i) {
865 if (txt == _(modifiers[i].name)) {
866 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
872 void delete_button_changed ()
874 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
877 void edit_button_changed ()
879 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
882 void insert_note_button_changed ()
884 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
887 ComboBoxText _keyboard_layout_selector;
888 ComboBoxText _edit_modifier_combo;
889 ComboBoxText _delete_modifier_combo;
890 ComboBoxText _copy_modifier_combo;
891 ComboBoxText _insert_note_modifier_combo;
892 ComboBoxText _snap_modifier_combo;
893 ComboBoxText _snap_delta_combo;
894 ComboBoxText _constraint_modifier_combo;
895 ComboBoxText _trim_contents_combo;
896 ComboBoxText _trim_overlap_combo;
897 ComboBoxText _trim_anchored_combo;
898 ComboBoxText _trim_jump_combo;
899 ComboBoxText _fine_adjust_combo;
900 ComboBoxText _push_points_combo;
901 ComboBoxText _note_size_relative_combo;
902 Adjustment _delete_button_adjustment;
903 SpinButton _delete_button_spin;
904 Adjustment _edit_button_adjustment;
905 SpinButton _edit_button_spin;
906 Adjustment _insert_note_button_adjustment;
907 SpinButton _insert_note_button_spin;
911 class FontScalingOptions : public OptionEditorBox
914 FontScalingOptions (UIConfiguration* uic) :
916 _dpi_adjustment (100, 50, 250, 1, 5),
917 _dpi_slider (_dpi_adjustment)
919 _dpi_adjustment.set_value (_ui_config->get_font_scale() / 1024.);
921 Label* l = manage (new Label (_("GUI and Font scaling:")));
922 l->set_name ("OptionsLabel");
924 const Glib::ustring dflt = _("Default");
925 const Glib::ustring empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
927 _dpi_slider.set_name("FontScaleSlider");
928 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
929 _dpi_slider.set_draw_value(false);
930 _dpi_slider.add_mark(50, Gtk::POS_TOP, empty);
931 _dpi_slider.add_mark(60, Gtk::POS_TOP, empty);
932 _dpi_slider.add_mark(70, Gtk::POS_TOP, empty);
933 _dpi_slider.add_mark(80, Gtk::POS_TOP, empty);
934 _dpi_slider.add_mark(90, Gtk::POS_TOP, empty);
935 _dpi_slider.add_mark(100, Gtk::POS_TOP, dflt);
936 _dpi_slider.add_mark(125, Gtk::POS_TOP, empty);
937 _dpi_slider.add_mark(150, Gtk::POS_TOP, empty);
938 _dpi_slider.add_mark(175, Gtk::POS_TOP, empty);
939 _dpi_slider.add_mark(200, Gtk::POS_TOP, empty);
940 _dpi_slider.add_mark(225, Gtk::POS_TOP, empty);
941 _dpi_slider.add_mark(250, Gtk::POS_TOP, empty);
943 HBox* h = manage (new HBox);
945 h->pack_start (*l, false, false);
946 h->pack_start (_dpi_slider, true, true);
948 _box->pack_start (*h, false, false);
950 set_note (_("Adjusting the scale require an application restart to re-layout."));
952 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
955 void parameter_changed (string const & p)
957 if (p == "font-scale") {
958 _dpi_adjustment.set_value (_ui_config->get_font_scale() / 1024.);
962 void set_state_from_config ()
964 parameter_changed ("font-scale");
971 _ui_config->set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024.));
972 /* XXX: should be triggered from the parameter changed signal */
976 UIConfiguration* _ui_config;
977 Adjustment _dpi_adjustment;
981 class ClipLevelOptions : public OptionEditorBox
984 ClipLevelOptions (UIConfiguration* c)
986 , _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
987 , _clip_level_slider (_clip_level_adjustment)
989 _clip_level_adjustment.set_value (_ui_config->get_waveform_clip_level ());
991 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
992 l->set_name ("OptionsLabel");
994 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
995 HBox* h = manage (new HBox);
997 h->pack_start (*l, false, false);
998 h->pack_start (_clip_level_slider, true, true);
1000 _box->pack_start (*h, false, false);
1002 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1005 void parameter_changed (string const & p)
1007 if (p == "waveform-clip-level") {
1008 _clip_level_adjustment.set_value (_ui_config->get_waveform_clip_level());
1012 void set_state_from_config ()
1014 parameter_changed ("waveform-clip-level");
1019 void clip_level_changed ()
1021 _ui_config->set_waveform_clip_level (_clip_level_adjustment.get_value());
1022 /* XXX: should be triggered from the parameter changed signal */
1023 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1026 UIConfiguration* _ui_config;
1027 Adjustment _clip_level_adjustment;
1028 HScale _clip_level_slider;
1031 class BufferingOptions : public OptionEditorBox
1034 BufferingOptions (RCConfiguration* c)
1036 , _playback_adjustment (5, 1, 60, 1, 4)
1037 , _capture_adjustment (5, 1, 60, 1, 4)
1038 , _playback_slider (_playback_adjustment)
1039 , _capture_slider (_capture_adjustment)
1041 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1043 Label* l = manage (new Label (_("Playback (seconds of buffering):")));
1044 l->set_name ("OptionsLabel");
1046 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1047 HBox* h = manage (new HBox);
1049 h->pack_start (*l, false, false);
1050 h->pack_start (_playback_slider, true, true);
1052 _box->pack_start (*h, false, false);
1054 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1056 l = manage (new Label (_("Recording (seconds of buffering):")));
1057 l->set_name ("OptionsLabel");
1059 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1060 h = manage (new HBox);
1062 h->pack_start (*l, false, false);
1063 h->pack_start (_capture_slider, true, true);
1065 _box->pack_start (*h, false, false);
1067 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
1068 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
1071 void parameter_changed (string const & p)
1073 if (p == "playback-buffer-seconds") {
1074 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1075 } else if (p == "capture-buffer-seconds") {
1076 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1080 void set_state_from_config ()
1082 parameter_changed ("playback-buffer-seconds");
1083 parameter_changed ("capture-buffer-seconds");
1088 void playback_changed ()
1090 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
1093 void capture_changed ()
1095 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
1098 RCConfiguration* _rc_config;
1099 Adjustment _playback_adjustment;
1100 Adjustment _capture_adjustment;
1101 HScale _playback_slider;
1102 HScale _capture_slider;
1105 class ControlSurfacesOptions : public OptionEditorBox
1108 ControlSurfacesOptions (Gtk::Window& parent)
1110 , _ignore_view_change (0)
1112 _store = ListStore::create (_model);
1113 _view.set_model (_store);
1114 _view.append_column (_("Control Surface Protocol"), _model.name);
1115 _view.get_column(0)->set_resizable (true);
1116 _view.get_column(0)->set_expand (true);
1117 _view.append_column_editable (_("Enabled"), _model.enabled);
1118 _view.append_column_editable (_("Feedback"), _model.feedback);
1120 _box->pack_start (_view, false, false);
1122 Label* label = manage (new Label);
1123 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
1125 _box->pack_start (*label, false, false);
1128 ControlProtocolManager& m = ControlProtocolManager::instance ();
1129 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1130 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1132 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1133 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1136 void parameter_changed (std::string const &)
1141 void set_state_from_config ()
1145 ControlProtocolManager& m = ControlProtocolManager::instance ();
1146 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1148 if (!(*i)->mandatory) {
1149 TreeModel::Row r = *_store->append ();
1150 r[_model.name] = (*i)->name;
1151 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1152 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
1153 r[_model.protocol_info] = *i;
1160 void protocol_status_changed (ControlProtocolInfo* cpi) {
1162 TreeModel::Children rows = _store->children();
1164 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1165 string n = ((*x)[_model.name]);
1167 if ((*x)[_model.protocol_info] == cpi) {
1168 _ignore_view_change++;
1169 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1170 _ignore_view_change--;
1176 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1178 TreeModel::Row r = *i;
1180 if (_ignore_view_change) {
1184 ControlProtocolInfo* cpi = r[_model.protocol_info];
1189 bool const was_enabled = (cpi->protocol != 0);
1190 bool const is_enabled = r[_model.enabled];
1193 if (was_enabled != is_enabled) {
1196 ControlProtocolManager::instance().activate (*cpi);
1198 ControlProtocolManager::instance().deactivate (*cpi);
1202 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
1203 bool const is_feedback = r[_model.feedback];
1205 if (was_feedback != is_feedback && cpi->protocol) {
1206 cpi->protocol->set_feedback (is_feedback);
1210 void edit_clicked (GdkEventButton* ev)
1212 if (ev->type != GDK_2BUTTON_PRESS) {
1217 ControlProtocolInfo* cpi;
1220 row = *(_view.get_selection()->get_selected());
1221 if (!row[_model.enabled]) {
1224 cpi = row[_model.protocol_info];
1225 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1228 Box* box = (Box*) cpi->protocol->get_gui ();
1232 if (box->get_parent()) {
1233 static_cast<ArdourWindow*>(box->get_parent())->present();
1236 string title = row[_model.name];
1237 /* once created, the window is managed by the surface itself (as ->get_parent())
1238 * Surface's tear_down_gui() is called on session close, when de-activating
1239 * or re-initializing a surface.
1240 * tear_down_gui() hides an deletes the Window if it exists.
1242 ArdourWindow* win = new ArdourWindow (_parent, title);
1243 win->set_title ("Control Protocol Options");
1249 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1253 ControlSurfacesModelColumns ()
1258 add (protocol_info);
1261 TreeModelColumn<string> name;
1262 TreeModelColumn<bool> enabled;
1263 TreeModelColumn<bool> feedback;
1264 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1267 Glib::RefPtr<ListStore> _store;
1268 ControlSurfacesModelColumns _model;
1270 Gtk::Window& _parent;
1271 PBD::ScopedConnection protocol_status_connection;
1272 uint32_t _ignore_view_change;
1275 class VideoTimelineOptions : public OptionEditorBox
1278 VideoTimelineOptions (RCConfiguration* c)
1280 , _show_video_export_info_button (_("Show Video Export Info before export"))
1281 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1282 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1284 Table* t = manage (new Table (2, 6));
1285 t->set_spacings (4);
1287 t->attach (_video_advanced_setup_button, 0, 2, 0, 1);
1288 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1289 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1290 _("<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."));
1292 Label* l = manage (new Label (_("Video Server URL:")));
1293 l->set_alignment (0, 0.5);
1294 t->attach (*l, 0, 1, 1, 2, FILL);
1295 t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL);
1296 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1297 _("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"));
1299 l = manage (new Label (_("Video Folder:")));
1300 l->set_alignment (0, 0.5);
1301 t->attach (*l, 0, 1, 2, 3, FILL);
1302 t->attach (_video_server_docroot_entry, 1, 2, 2, 3);
1303 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1304 _("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."));
1306 /* small vspace y=3..4 */
1308 t->attach (_show_video_export_info_button, 0, 2, 4, 5);
1309 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1310 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1311 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1313 t->attach (_show_video_server_dialog_button, 0, 2, 5, 6);
1314 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1315 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1316 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1318 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1319 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1320 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1321 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1323 _box->pack_start (*t,true,true);
1326 void server_url_changed ()
1328 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1331 void server_docroot_changed ()
1333 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1336 void show_video_export_info_toggled ()
1338 bool const x = _show_video_export_info_button.get_active ();
1339 _rc_config->set_show_video_export_info (x);
1342 void show_video_server_dialog_toggled ()
1344 bool const x = _show_video_server_dialog_button.get_active ();
1345 _rc_config->set_show_video_server_dialog (x);
1348 void video_advanced_setup_toggled ()
1350 bool const x = _video_advanced_setup_button.get_active ();
1351 _rc_config->set_video_advanced_setup(x);
1354 void parameter_changed (string const & p)
1356 if (p == "video-server-url") {
1357 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1358 } else if (p == "video-server-docroot") {
1359 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1360 } else if (p == "show-video-export-info") {
1361 bool const x = _rc_config->get_show_video_export_info();
1362 _show_video_export_info_button.set_active (x);
1363 } else if (p == "show-video-server-dialog") {
1364 bool const x = _rc_config->get_show_video_server_dialog();
1365 _show_video_server_dialog_button.set_active (x);
1366 } else if (p == "video-advanced-setup") {
1367 bool const x = _rc_config->get_video_advanced_setup();
1368 _video_advanced_setup_button.set_active(x);
1369 _video_server_docroot_entry.set_sensitive(x);
1370 _video_server_url_entry.set_sensitive(x);
1374 void set_state_from_config ()
1376 parameter_changed ("video-server-url");
1377 parameter_changed ("video-server-docroot");
1378 parameter_changed ("video-monitor-setup-dialog");
1379 parameter_changed ("show-video-export-info");
1380 parameter_changed ("show-video-server-dialog");
1381 parameter_changed ("video-advanced-setup");
1385 RCConfiguration* _rc_config;
1386 Entry _video_server_url_entry;
1387 Entry _video_server_docroot_entry;
1388 CheckButton _show_video_export_info_button;
1389 CheckButton _show_video_server_dialog_button;
1390 CheckButton _video_advanced_setup_button;
1393 class PluginOptions : public OptionEditorBox
1396 PluginOptions (RCConfiguration* c, UIConfiguration* uic)
1399 , _display_plugin_scan_progress (_("Always Display Plugin Scan Progress"))
1400 , _discover_vst_on_start (_("Scan for [new] VST Plugins on Application Start"))
1401 , _discover_au_on_start (_("Scan for AudioUnit Plugins on Application Start"))
1402 , _timeout_adjustment (0, 0, 3000, 50, 50)
1403 , _timeout_slider (_timeout_adjustment)
1406 std::stringstream ss;
1407 Table* t = manage (new Table (2, 6));
1408 t->set_spacings (4);
1412 ss << "<b>" << _("General") << "</b>";
1413 l = manage (left_aligned_label (ss.str()));
1414 l->set_use_markup (true);
1415 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1416 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1418 b = manage (new Button (_("Scan for Plugins")));
1419 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1420 t->attach (*b, 0, 2, n, n+1, FILL); ++n;
1422 t->attach (_display_plugin_scan_progress, 0, 2, n, n+1); ++n;
1423 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1424 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1425 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
1427 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
1428 _timeout_slider.set_digits (0);
1429 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &PluginOptions::timeout_changed));
1431 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1432 _("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."));
1434 l = manage (left_aligned_label (_("Scan Time Out [deciseconds]")));;
1435 HBox* h = manage (new HBox);
1437 h->pack_start (*l, false, false);
1438 h->pack_start (_timeout_slider, true, true);
1439 t->attach (*h, 0, 2, n, n+1); ++n;
1442 ss << "<b>" << _("VST") << "</b>";
1443 l = manage (left_aligned_label (ss.str()));
1444 l->set_use_markup (true);
1445 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1446 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1448 b = manage (new Button (_("Clear VST Cache")));
1449 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_cache_clicked));
1450 t->attach (*b, 0, 1, n, n+1, FILL);
1452 b = manage (new Button (_("Clear VST Blacklist")));
1453 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_blacklist_clicked));
1454 t->attach (*b, 1, 2, n, n+1, FILL);
1457 t->attach (_discover_vst_on_start, 0, 2, n, n+1); ++n;
1458 _discover_vst_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_vst_on_start_toggled));
1459 Gtkmm2ext::UI::instance()->set_tip (_discover_vst_on_start,
1460 _("<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"));
1462 #ifdef LXVST_SUPPORT
1463 t->attach (*manage (left_aligned_label (_("Linux VST Path:"))), 0, 1, n, n+1);
1464 b = manage (new Button (_("Edit")));
1465 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_lxvst_path_clicked));
1466 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1469 #ifdef WINDOWS_VST_SUPPORT
1470 t->attach (*manage (left_aligned_label (_("Windows VST Path:"))), 0, 1, n, n+1);
1471 b = manage (new Button (_("Edit")));
1472 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_vst_path_clicked));
1473 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1477 #ifdef AUDIOUNIT_SUPPORT
1479 ss << "<b>" << _("Audio Unit") << "</b>";
1480 l = manage (left_aligned_label (ss.str()));
1481 l->set_use_markup (true);
1482 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1483 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1485 t->attach (_discover_au_on_start, 0, 2, n, n+1); ++n;
1486 _discover_au_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_au_on_start_toggled));
1487 Gtkmm2ext::UI::instance()->set_tip (_discover_au_on_start,
1488 _("<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."));
1491 b = manage (new Button (_("Clear AU Cache")));
1492 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_cache_clicked));
1493 t->attach (*b, 0, 1, n, n+1, FILL);
1495 b = manage (new Button (_("Clear AU Blacklist")));
1496 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_blacklist_clicked));
1497 t->attach (*b, 1, 2, n, n+1, FILL);
1501 _box->pack_start (*t,true,true);
1504 void parameter_changed (string const & p) {
1505 if (p == "show-plugin-scan-window") {
1506 bool const x = _ui_config->get_show_plugin_scan_window();
1507 _display_plugin_scan_progress.set_active (x);
1509 else if (p == "discover-vst-on-start") {
1510 bool const x = _rc_config->get_discover_vst_on_start();
1511 _discover_vst_on_start.set_active (x);
1513 else if (p == "vst-scan-timeout") {
1514 int const x = _rc_config->get_vst_scan_timeout();
1515 _timeout_adjustment.set_value (x);
1517 else if (p == "discover-audio-units") {
1518 bool const x = _rc_config->get_discover_audio_units();
1519 _discover_au_on_start.set_active (x);
1523 void set_state_from_config () {
1524 parameter_changed ("show-plugin-scan-window");
1525 parameter_changed ("discover-vst-on-start");
1526 parameter_changed ("vst-scan-timeout");
1527 parameter_changed ("discover-audio-units");
1531 RCConfiguration* _rc_config;
1532 UIConfiguration* _ui_config;
1533 CheckButton _display_plugin_scan_progress;
1534 CheckButton _discover_vst_on_start;
1535 CheckButton _discover_au_on_start;
1536 Adjustment _timeout_adjustment;
1537 HScale _timeout_slider;
1539 void display_plugin_scan_progress_toggled () {
1540 bool const x = _display_plugin_scan_progress.get_active();
1541 _ui_config->set_show_plugin_scan_window(x);
1544 void discover_vst_on_start_toggled () {
1545 bool const x = _discover_vst_on_start.get_active();
1546 _rc_config->set_discover_vst_on_start(x);
1549 void discover_au_on_start_toggled () {
1550 bool const x = _discover_au_on_start.get_active();
1551 _rc_config->set_discover_audio_units(x);
1554 void timeout_changed () {
1555 int x = floor(_timeout_adjustment.get_value());
1556 _rc_config->set_vst_scan_timeout(x);
1559 void clear_vst_cache_clicked () {
1560 PluginManager::instance().clear_vst_cache();
1563 void clear_vst_blacklist_clicked () {
1564 PluginManager::instance().clear_vst_blacklist();
1567 void clear_au_cache_clicked () {
1568 PluginManager::instance().clear_au_cache();
1571 void clear_au_blacklist_clicked () {
1572 PluginManager::instance().clear_au_blacklist();
1576 void edit_vst_path_clicked () {
1577 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1578 _("Set Windows VST Search Path"),
1579 _rc_config->get_plugin_path_vst(),
1580 PluginManager::instance().get_default_windows_vst_path()
1582 ResponseType r = (ResponseType) pd->run ();
1584 if (r == RESPONSE_ACCEPT) {
1585 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
1590 // todo consolidate with edit_vst_path_clicked..
1591 void edit_lxvst_path_clicked () {
1592 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1593 _("Set Linux VST Search Path"),
1594 _rc_config->get_plugin_path_lxvst(),
1595 PluginManager::instance().get_default_lxvst_path()
1597 ResponseType r = (ResponseType) pd->run ();
1599 if (r == RESPONSE_ACCEPT) {
1600 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
1605 void refresh_clicked () {
1606 PluginManager::instance().refresh();
1611 /** A class which allows control of visibility of some editor components usign
1612 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1613 * which has the correct members, but with null widget pointers. This
1614 * class allows the user to set visibility of the members, the details
1615 * of which are stored in a configuration variable which can be watched
1616 * by parts of the editor that actually contain the widgets whose visibility
1617 * is being controlled.
1620 class VisibilityOption : public Option
1623 /** @param name User-visible name for this group.
1624 * @param g `Dummy' VisibilityGroup (as described above).
1625 * @param get Method to get the value of the appropriate configuration variable.
1626 * @param set Method to set the value of the appropriate configuration variable.
1628 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1629 : Option (g->get_state_name(), name)
1631 , _visibility_group (g)
1635 /* Watch for changes made by the user to our members */
1636 _visibility_group->VisibilityChanged.connect_same_thread (
1637 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1641 void set_state_from_config ()
1643 /* Set our state from the current configuration */
1644 _visibility_group->set_state (_get ());
1647 void add_to_page (OptionEditorPage* p)
1649 _heading.add_to_page (p);
1650 add_widget_to_page (p, _visibility_group->list_view ());
1653 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1658 /* The user has changed something, so reflect this change
1659 in the RCConfiguration.
1661 _set (_visibility_group->get_state_value ());
1664 OptionEditorHeading _heading;
1665 VisibilityGroup* _visibility_group;
1666 sigc::slot<std::string> _get;
1667 sigc::slot<bool, std::string> _set;
1668 PBD::ScopedConnection _visibility_group_connection;
1673 RCOptionEditor::RCOptionEditor ()
1674 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1675 , _rc_config (Config)
1676 , _ui_config (ARDOUR_UI::config())
1677 , _mixer_strip_visibility ("mixer-element-visibility")
1681 uint32_t hwcpus = hardware_concurrency ();
1683 BoolComboOption* bco;
1686 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1688 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1690 _("Signal processing uses"),
1691 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1692 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1695 procs->add (-1, _("all but one processor"));
1696 procs->add (0, _("all available processors"));
1698 for (uint32_t i = 1; i <= hwcpus; ++i) {
1699 procs->add (i, string_compose (_("%1 processors"), i));
1702 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1704 add_option (_("Misc"), procs);
1707 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1709 add_option (_("Misc"), new UndoOptions (_rc_config));
1711 add_option (_("Misc"),
1713 "verify-remove-last-capture",
1714 _("Verify removal of last capture"),
1715 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1716 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1719 add_option (_("Misc"),
1721 "periodic-safety-backups",
1722 _("Make periodic backups of the session file"),
1723 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1724 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1727 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1729 add_option (_("Misc"),
1731 "only-copy-imported-files",
1732 _("Always copy imported files"),
1733 sigc::mem_fun (*_ui_config, &UIConfiguration::get_only_copy_imported_files),
1734 sigc::mem_fun (*_ui_config, &UIConfiguration::set_only_copy_imported_files)
1737 add_option (_("Misc"), new DirectoryOption (
1738 X_("default-session-parent-dir"),
1739 _("Default folder for new sessions:"),
1740 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1741 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1744 add_option (_("Misc"),
1745 new SpinOption<uint32_t> (
1746 "max-recent-sessions",
1747 _("Maximum number of recent sessions"),
1748 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1749 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1753 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1755 add_option (_("Misc"), new ClickOptions (_rc_config, this));
1757 add_option (_("Misc"),
1760 _("Click gain level"),
1761 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1762 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1765 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1767 add_option (_("Misc"),
1768 new SpinOption<double> (
1769 "automation-thinning-factor",
1770 _("Thinning factor (larger value => less data)"),
1771 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1772 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1776 add_option (_("Misc"),
1777 new SpinOption<double> (
1778 "automation-interval-msecs",
1779 _("Automation sampling interval (milliseconds)"),
1780 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1781 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1789 tsf = new BoolOption (
1790 "latched-record-enable",
1791 _("Keep record-enable engaged on stop"),
1792 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1793 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1795 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1796 add_option (_("Transport"), tsf);
1798 tsf = new BoolOption (
1800 _("Play loop is a transport mode"),
1801 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1802 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1804 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1805 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1806 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1807 add_option (_("Transport"), tsf);
1809 tsf = new BoolOption (
1810 "stop-recording-on-xrun",
1811 _("Stop recording when an xrun occurs"),
1812 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1813 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1815 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1816 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
1818 add_option (_("Transport"), tsf);
1820 tsf = new BoolOption (
1821 "create-xrun-marker",
1822 _("Create markers where xruns occur"),
1823 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
1824 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
1826 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1827 add_option (_("Transport"), tsf);
1829 tsf = new BoolOption (
1830 "stop-at-session-end",
1831 _("Stop at the end of the session"),
1832 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
1833 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
1835 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1836 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
1837 "when it reaches the current session end marker\n\n"
1838 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
1840 add_option (_("Transport"), tsf);
1842 tsf = new BoolOption (
1844 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
1845 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
1846 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
1848 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1849 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
1850 "preventing any need to do a transport locate at the end of the loop\n\n"
1851 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
1852 "which will often cause a small click or delay"), PROGRAM_NAME));
1853 add_option (_("Transport"), tsf);
1855 tsf = new BoolOption (
1856 "disable-disarm-during-roll",
1857 _("Disable per-track record disarm while rolling"),
1858 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
1859 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
1861 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"));
1862 add_option (_("Transport"), tsf);
1864 tsf = new BoolOption (
1866 _("12dB gain reduction during fast-forward and fast-rewind"),
1867 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
1868 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
1870 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
1871 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
1872 add_option (_("Transport"), tsf);
1874 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
1876 _sync_source = new ComboOption<SyncSource> (
1878 _("External timecode source"),
1879 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
1880 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
1883 add_option (_("Transport"), _sync_source);
1885 _sync_framerate = new BoolOption (
1886 "timecode-sync-frame-rate",
1887 _("Match session video frame rate to external timecode"),
1888 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
1889 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
1891 Gtkmm2ext::UI::instance()->set_tip
1892 (_sync_framerate->tip_widget(),
1893 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
1894 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
1895 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
1896 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
1897 "timecode standard and the session standard."), PROGRAM_NAME));
1899 add_option (_("Transport"), _sync_framerate);
1901 _sync_genlock = new BoolOption (
1902 "timecode-source-is-synced",
1903 _("Sync-lock timecode to clock (disable drift compensation)"),
1904 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
1905 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
1907 Gtkmm2ext::UI::instance()->set_tip
1908 (_sync_genlock->tip_widget(),
1909 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
1910 "Sync Lock indicates that the selected external timecode source shares clock-sync "
1911 "(Black & Burst, Wordclock, etc) with the audio interface. "
1912 "This option disables drift compensation. The transport speed is fixed at 1.0. "
1913 "Vari-speed LTC will be ignored and cause drift."
1915 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
1916 "timecode sources shares clock sync."
1920 add_option (_("Transport"), _sync_genlock);
1922 _sync_source_2997 = new BoolOption (
1923 "timecode-source-2997",
1924 _("Lock to 29.9700 fps instead of 30000/1001"),
1925 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
1926 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
1928 Gtkmm2ext::UI::instance()->set_tip
1929 (_sync_source_2997->tip_widget(),
1930 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
1931 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
1932 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
1933 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
1934 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
1935 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
1938 add_option (_("Transport"), _sync_source_2997);
1940 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
1942 _ltc_port = new ComboStringOption (
1944 _("LTC incoming port"),
1945 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
1946 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
1949 vector<string> physical_inputs;
1950 physical_inputs.push_back (_("None"));
1951 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
1952 _ltc_port->set_popdown_strings (physical_inputs);
1954 populate_sync_options ();
1956 add_option (_("Transport"), _ltc_port);
1958 // TODO; rather disable this button than not compile it..
1959 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
1961 add_option (_("Transport"),
1964 _("Enable LTC generator"),
1965 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
1966 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
1969 _ltc_send_continuously = new BoolOption (
1970 "ltc-send-continuously",
1971 _("Send LTC while stopped"),
1972 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
1973 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
1975 Gtkmm2ext::UI::instance()->set_tip
1976 (_ltc_send_continuously->tip_widget(),
1977 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
1978 add_option (_("Transport"), _ltc_send_continuously);
1980 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
1981 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
1982 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
1983 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
1985 Gtkmm2ext::UI::instance()->set_tip
1986 (_ltc_volume_slider->tip_widget(),
1987 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
1989 add_option (_("Transport"), _ltc_volume_slider);
1990 parameter_changed ("send-ltc");
1992 parameter_changed ("sync-source");
1996 add_option (S_("Editor"),
1998 "draggable-playhead",
1999 _("Allow dragging of playhead"),
2000 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_draggable_playhead),
2001 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_draggable_playhead)
2004 add_option (_("Editor"),
2006 "automation-follows-regions",
2007 _("Move relevant automation when audio regions are moved"),
2008 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2009 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2012 add_option (_("Editor"),
2014 "show-track-meters",
2015 _("Show meters on tracks in the editor"),
2016 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_track_meters),
2017 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_track_meters)
2020 add_option (_("Editor"),
2022 "show-editor-meter",
2023 _("Display master-meter in the toolbar"),
2024 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_editor_meter),
2025 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_editor_meter)
2028 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2029 "default-fade-shape",
2030 _("Default fade shape"),
2031 sigc::mem_fun (*_rc_config,
2032 &RCConfiguration::get_default_fade_shape),
2033 sigc::mem_fun (*_rc_config,
2034 &RCConfiguration::set_default_fade_shape)
2037 fadeshape->add (FadeLinear,
2038 _("Linear (for highly correlated material)"));
2039 fadeshape->add (FadeConstantPower, _("Constant power"));
2040 fadeshape->add (FadeSymmetric, _("Symmetric"));
2041 fadeshape->add (FadeSlow, _("Slow"));
2042 fadeshape->add (FadeFast, _("Fast"));
2044 add_option (_("Editor"), fadeshape);
2047 bco = new BoolComboOption (
2048 "use-overlap-equivalency",
2049 _("Regions in active edit groups are edited together"),
2050 _("whenever they overlap in time"),
2051 _("only if they have identical length, position and origin"),
2052 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2053 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2056 add_option (_("Editor"), bco);
2058 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2060 _("Layering model"),
2061 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2062 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2065 lm->add (LaterHigher, _("later is higher"));
2066 lm->add (Manual, _("manual layering"));
2067 add_option (_("Editor"), lm);
2069 add_option (_("Editor"),
2071 "rubberbanding-snaps-to-grid",
2072 _("Make rubberband selection rectangle snap to the grid"),
2073 sigc::mem_fun (*_ui_config, &UIConfiguration::get_rubberbanding_snaps_to_grid),
2074 sigc::mem_fun (*_ui_config, &UIConfiguration::set_rubberbanding_snaps_to_grid)
2077 add_option (_("Editor"),
2080 _("Show waveforms in regions"),
2081 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms),
2082 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms)
2085 add_option (_("Editor"),
2086 new BoolComboOption (
2087 "show-region-gain-envelopes",
2088 _("Show gain envelopes in audio regions"),
2090 _("only in Draw and Internal Edit modes"),
2091 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_region_gain),
2092 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_region_gain)
2095 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
2097 _("Waveform scale"),
2098 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_scale),
2099 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_scale)
2102 wfs->add (Linear, _("linear"));
2103 wfs->add (Logarithmic, _("logarithmic"));
2105 add_option (_("Editor"), wfs);
2107 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
2109 _("Waveform shape"),
2110 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_shape),
2111 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_shape)
2114 wfsh->add (Traditional, _("traditional"));
2115 wfsh->add (Rectified, _("rectified"));
2117 add_option (_("Editor"), wfsh);
2119 add_option (_("Editor"), new ClipLevelOptions (_ui_config));
2121 add_option (_("Editor"),
2123 "show-waveforms-while-recording",
2124 _("Show waveforms for audio while it is being recorded"),
2125 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms_while_recording),
2126 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms_while_recording)
2129 add_option (_("Editor"),
2132 _("Show zoom toolbar"),
2133 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_zoom_tools),
2134 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_zoom_tools)
2137 add_option (_("Editor"),
2139 "update-editor-during-summary-drag",
2140 _("Update editor window during drags of the summary"),
2141 sigc::mem_fun (*_ui_config, &UIConfiguration::get_update_editor_during_summary_drag),
2142 sigc::mem_fun (*_ui_config, &UIConfiguration::set_update_editor_during_summary_drag)
2145 bo = new BoolOption (
2147 _("Name new markers"),
2148 sigc::mem_fun (*_ui_config, &UIConfiguration::get_name_new_markers),
2149 sigc::mem_fun (*_ui_config, &UIConfiguration::set_name_new_markers)
2152 add_option (_("Editor"), bo);
2153 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."
2154 "\n\nYou can always rename markers by right-clicking on them"));
2156 add_option (_("Editor"),
2158 "autoscroll-editor",
2159 _("Auto-scroll editor window when dragging near its edges"),
2160 sigc::mem_fun (*_ui_config, &UIConfiguration::get_autoscroll_editor),
2161 sigc::mem_fun (*_ui_config, &UIConfiguration::set_autoscroll_editor)
2164 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2165 "region-selection-after-split",
2166 _("After splitting selected regions, select"),
2167 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2168 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2170 // TODO: decide which of these modes are really useful
2171 rsas->add(None, _("no regions"));
2172 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2173 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2174 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2175 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2176 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2177 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2178 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2180 add_option (_("Editor"), rsas);
2185 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2187 add_option (_("Audio"), new BufferingOptions (_rc_config));
2189 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2191 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2193 _("Record monitoring handled by"),
2194 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2195 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2198 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2199 mm->add (HardwareMonitoring, _("via Audio Driver"));
2202 string prog (PROGRAM_NAME);
2203 boost::algorithm::to_lower (prog);
2204 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2205 mm->add (ExternalMonitoring, _("audio hardware"));
2207 add_option (_("Audio"), mm);
2209 add_option (_("Audio"),
2211 "tape-machine-mode",
2212 _("Tape machine mode"),
2213 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2214 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2217 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
2219 add_option (_("Audio"),
2221 "auto-connect-standard-busses",
2222 _("Auto-connect master/monitor busses"),
2223 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2224 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2227 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2228 "input-auto-connect",
2229 _("Connect track inputs"),
2230 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2231 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2234 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2235 iac->add (ManualConnect, _("manually"));
2237 add_option (_("Audio"), iac);
2239 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2240 "output-auto-connect",
2241 _("Connect track and bus outputs"),
2242 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2243 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2246 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2247 oac->add (AutoConnectMaster, _("automatically to master bus"));
2248 oac->add (ManualConnect, _("manually"));
2250 add_option (_("Audio"), oac);
2252 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2254 add_option (_("Audio"),
2256 "denormal-protection",
2257 _("Use DC bias to protect against denormals"),
2258 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2259 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2262 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2264 _("Processor handling"),
2265 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2266 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2270 dm->add (DenormalNone, _("no processor handling"));
2274 if (fpu.has_flush_to_zero()) {
2276 dm->add (DenormalFTZ, _("use FlushToZero"));
2277 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2278 _rc_config->set_denormal_model(DenormalNone);
2281 if (fpu.has_denormals_are_zero()) {
2283 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2284 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2285 _rc_config->set_denormal_model(DenormalNone);
2288 if (fpu.has_flush_to_zero() && fpu.has_denormals_are_zero()) {
2290 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2291 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2292 _rc_config->set_denormal_model(DenormalNone);
2296 dm->set_sensitive(false);
2299 add_option (_("Audio"), dm);
2301 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
2303 add_option (_("Audio"),
2305 "plugins-stop-with-transport",
2306 _("Silence plugins when the transport is stopped"),
2307 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
2308 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
2311 add_option (_("Audio"),
2313 "new-plugins-active",
2314 _("Make new plugins active"),
2315 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
2316 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
2319 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2321 add_option (_("Audio"),
2323 "auto-analyse-audio",
2324 _("Enable automatic analysis of audio"),
2325 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2326 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2329 add_option (_("Audio"),
2331 "replicate-missing-region-channels",
2332 _("Replicate missing region channels"),
2333 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2334 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2339 add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
2341 add_option (_("Solo / mute"),
2344 _("Solo-in-place mute cut (dB)"),
2345 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2346 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2349 _solo_control_is_listen_control = new BoolOption (
2350 "solo-control-is-listen-control",
2351 _("Solo controls are Listen controls"),
2352 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2353 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2356 add_option (_("Solo / mute"), _solo_control_is_listen_control);
2358 _listen_position = new ComboOption<ListenPosition> (
2360 _("Listen Position"),
2361 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2362 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2365 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2366 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2368 add_option (_("Solo / mute"), _listen_position);
2370 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2372 _("PFL signals come from"),
2373 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2374 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2377 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2378 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2380 add_option (_("Solo / mute"), pp);
2382 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2384 _("AFL signals come from"),
2385 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2386 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2389 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2390 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2392 add_option (_("Solo / mute"), pa);
2394 parameter_changed ("use-monitor-bus");
2396 add_option (_("Solo / mute"),
2399 _("Exclusive solo"),
2400 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2401 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2404 add_option (_("Solo / mute"),
2407 _("Show solo muting"),
2408 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2409 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2412 add_option (_("Solo / mute"),
2414 "solo-mute-override",
2415 _("Soloing overrides muting"),
2416 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2417 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2420 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
2422 add_option (_("Solo / mute"),
2424 "mute-affects-pre-fader",
2425 _("Mute affects pre-fader sends"),
2426 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2427 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2430 add_option (_("Solo / mute"),
2432 "mute-affects-post-fader",
2433 _("Mute affects post-fader sends"),
2434 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2435 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2438 add_option (_("Solo / mute"),
2440 "mute-affects-control-outs",
2441 _("Mute affects control outputs"),
2442 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2443 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2446 add_option (_("Solo / mute"),
2448 "mute-affects-main-outs",
2449 _("Mute affects main outputs"),
2450 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2451 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2454 add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
2456 add_option (_("Solo / mute"),
2458 "link-send-and-route-panner",
2459 _("Link panners of Aux and External Sends with main panner by default"),
2460 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2461 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2464 add_option (_("MIDI"),
2465 new SpinOption<float> (
2467 _("MIDI read-ahead time (seconds)"),
2468 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2469 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2474 add_option (_("MIDI"),
2477 _("Send MIDI Clock"),
2478 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2479 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2482 add_option (_("MIDI"),
2485 _("Send MIDI Time Code"),
2486 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2487 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2490 add_option (_("MIDI"),
2491 new SpinOption<int> (
2492 "mtc-qf-speed-tolerance",
2493 _("Percentage either side of normal transport speed to transmit MTC"),
2494 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2495 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2499 add_option (_("MIDI"),
2502 _("Obey MIDI Machine Control commands"),
2503 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2504 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2507 add_option (_("MIDI"),
2510 _("Send MIDI Machine Control commands"),
2511 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2512 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2515 add_option (_("MIDI"),
2518 _("Send MIDI control feedback"),
2519 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2520 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2523 add_option (_("MIDI"),
2524 new SpinOption<uint8_t> (
2525 "mmc-receive-device-id",
2526 _("Inbound MMC device ID"),
2527 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2528 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2532 add_option (_("MIDI"),
2533 new SpinOption<uint8_t> (
2534 "mmc-send-device-id",
2535 _("Outbound MMC device ID"),
2536 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2537 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2541 add_option (_("MIDI"),
2542 new SpinOption<int32_t> (
2543 "initial-program-change",
2544 _("Initial program change"),
2545 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2546 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2550 add_option (_("MIDI"),
2552 "display-first-midi-bank-as-zero",
2553 _("Display first MIDI bank/program as 0"),
2554 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2555 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2558 add_option (_("MIDI"),
2560 "never-display-periodic-midi",
2561 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2562 sigc::mem_fun (*_ui_config, &UIConfiguration::get_never_display_periodic_midi),
2563 sigc::mem_fun (*_ui_config, &UIConfiguration::set_never_display_periodic_midi)
2566 add_option (_("MIDI"),
2569 _("Sound MIDI notes as they are selected"),
2570 sigc::mem_fun (*_ui_config, &UIConfiguration::get_sound_midi_notes),
2571 sigc::mem_fun (*_ui_config, &UIConfiguration::set_sound_midi_notes)
2574 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2576 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2577 "midi-audition-synth-uri",
2578 _("Midi Audition Synth (LV2)"),
2579 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2580 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2583 audition_synth->add(X_(""), _("None"));
2584 PluginInfoList all_plugs;
2585 PluginManager& manager (PluginManager::instance());
2587 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2589 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2590 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2591 if (!(*i)->is_instrument()) continue;
2592 if ((*i)->type != ARDOUR::LV2) continue;
2593 audition_synth->add((*i)->unique_id, (*i)->name);
2597 add_option (_("MIDI"), audition_synth);
2599 /* USER INTERACTION */
2602 #ifdef PLATFORM_WINDOWS
2605 getenv ("ARDOUR_BUNDLED")
2609 add_option (_("User interaction"),
2611 "enable-translation",
2612 string_compose (_("Use translations of %1 messages\n"
2613 " <i>(requires a restart of %1 to take effect)</i>\n"
2614 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2615 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2616 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2619 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2621 add_option (_("User interaction"), new KeyboardOptions);
2623 /* Control Surfaces */
2625 add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
2627 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2629 _("Control surface remote ID"),
2630 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2631 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2634 rm->add (UserOrdered, _("assigned by user"));
2635 rm->add (MixerOrdered, _("follows order of mixer"));
2637 add_option (_("Control Surfaces"), rm);
2639 /* VIDEO Timeline */
2640 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2642 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2643 /* Plugin options (currrently VST only) */
2644 add_option (_("Plugins"), new PluginOptions (_rc_config, _ui_config));
2649 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
2650 BoolOption* bgo = new BoolOption (
2652 _("Possibly improve slow graphical performance"),
2653 sigc::mem_fun (*_ui_config, &UIConfiguration::get_buggy_gradients),
2654 sigc::mem_fun (*_ui_config, &UIConfiguration::set_buggy_gradients)
2657 Gtkmm2ext::UI::instance()->set_tip (bgo->tip_widget(), string_compose (_("This requires restarting %1 before having an effect"), PROGRAM_NAME));
2658 add_option (S_("Preferences|GUI"), bgo);
2661 add_option (S_("Preferences|GUI"),
2664 _("Graphically indicate mouse pointer hovering over various widgets"),
2665 sigc::mem_fun (*_ui_config, &UIConfiguration::get_widget_prelight),
2666 sigc::mem_fun (*_ui_config, &UIConfiguration::set_widget_prelight)
2669 #ifdef TOOLTIPS_GOT_FIXED
2670 add_option (S_("Preferences|GUI"),
2673 _("Show tooltips if mouse hovers over a control"),
2674 sigc::mem_fun (*_ui_config, &UIConfiguration::get_use_tooltips),
2675 sigc::mem_fun (*_ui_config, &UIConfiguration::set_use_tooltips)
2679 add_option (S_("Preferences|GUI"),
2681 "show-name-highlight",
2682 _("Use name highlight bars in region displays (requires a restart)"),
2683 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_name_highlight),
2684 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_name_highlight)
2688 /* font scaling does nothing with GDK/Quartz */
2689 add_option (S_("Preferences|GUI"), new FontScalingOptions (_ui_config));
2692 add_option (S_("GUI"),
2694 "super-rapid-clock-update",
2695 _("update transport clock display at FPS instead of every 100ms"),
2696 sigc::mem_fun (*_ui_config, &UIConfiguration::get_super_rapid_clock_update),
2697 sigc::mem_fun (*_ui_config, &UIConfiguration::set_super_rapid_clock_update)
2701 /* Image cache size */
2703 Gtk::Adjustment *ics = manage (new Gtk::Adjustment(0, 1, 1024, 10)); /* 1 MB to 1GB in steps of 10MB */
2704 HSliderOption *sics = new HSliderOption("waveform-cache-size",
2705 _("Waveform image cache size (megabytes)"),
2707 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_waveform_cache_size),
2708 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_waveform_cache_size)
2710 sics->scale().set_digits (0);
2711 Gtkmm2ext::UI::instance()->set_tip
2712 (sics->tip_widget(),
2713 _("Larger values lead to using more memory to store images of waveforms, which can improve graphical performance."));
2714 add_option (S_("Preferences|GUI"), sics);
2716 /* Lock GUI timeout */
2718 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
2719 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2720 _("Lock timeout (seconds)"),
2722 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_lock_gui_after_seconds),
2723 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_lock_gui_after_seconds)
2725 slts->scale().set_digits (0);
2726 Gtkmm2ext::UI::instance()->set_tip
2727 (slts->tip_widget(),
2728 _("Lock GUI after this many idle seconds (zero to never lock)"));
2729 add_option (S_("Preferences|GUI"), slts);
2731 /* The names of these controls must be the same as those given in MixerStrip
2732 for the actual widgets being controlled.
2734 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
2735 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2736 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
2737 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
2738 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
2739 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2742 S_("Preferences|GUI"),
2743 new VisibilityOption (
2745 &_mixer_strip_visibility,
2746 sigc::mem_fun (*_ui_config, &UIConfiguration::get_mixer_strip_visibility),
2747 sigc::mem_fun (*_ui_config, &UIConfiguration::set_mixer_strip_visibility)
2751 add_option (S_("Preferences|GUI"),
2753 "default-narrow_ms",
2754 _("Use narrow strips in the mixer by default"),
2755 sigc::mem_fun (*_ui_config, &UIConfiguration::get_default_narrow_ms),
2756 sigc::mem_fun (*_ui_config, &UIConfiguration::set_default_narrow_ms)
2759 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2761 ComboOption<float>* mht = new ComboOption<float> (
2763 _("Peak hold time"),
2764 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_hold),
2765 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_hold)
2768 mht->add (MeterHoldOff, _("off"));
2769 mht->add (MeterHoldShort, _("short"));
2770 mht->add (MeterHoldMedium, _("medium"));
2771 mht->add (MeterHoldLong, _("long"));
2773 add_option (S_("Preferences|Metering"), mht);
2775 ComboOption<float>* mfo = new ComboOption<float> (
2778 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2779 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2782 mfo->add (METER_FALLOFF_OFF, _("off"));
2783 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2784 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2785 mfo->add (METER_FALLOFF_SLOWISH, _("slowish [12.0dB/sec] (DIN)"));
2786 mfo->add (METER_FALLOFF_MODERATE, _("moderate [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2787 mfo->add (METER_FALLOFF_MEDIUM, _("medium [20dB/sec]"));
2788 mfo->add (METER_FALLOFF_FAST, _("fast [32dB/sec]"));
2789 mfo->add (METER_FALLOFF_FASTER, _("faster [46dB/sec]"));
2790 mfo->add (METER_FALLOFF_FASTEST, _("fastest [70dB/sec]"));
2792 add_option (S_("Preferences|Metering"), mfo);
2794 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2795 "meter-line-up-level",
2796 _("Meter line-up level; 0dBu"),
2797 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_level),
2798 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_level)
2801 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2802 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2803 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2804 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2806 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."));
2808 add_option (S_("Preferences|Metering"), mlu);
2810 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2811 "meter-line-up-din",
2812 _("IEC1/DIN Meter line-up level; 0dBu"),
2813 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_din),
2814 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_din)
2817 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2818 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2819 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2820 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2822 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2824 add_option (S_("Preferences|Metering"), mld);
2826 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2827 "meter-vu-standard",
2828 _("VU Meter standard"),
2829 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_vu_standard),
2830 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_vu_standard)
2833 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2834 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2835 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2836 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2838 add_option (S_("Preferences|Metering"), mvu);
2840 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
2841 HSliderOption *mpks = new HSliderOption("meter-peak",
2842 _("Peak threshold [dBFS]"),
2844 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_peak),
2845 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_peak)
2848 Gtkmm2ext::UI::instance()->set_tip
2849 (mpks->tip_widget(),
2850 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
2852 add_option (S_("Preferences|Metering"), mpks);
2854 add_option (S_("Preferences|Metering"),
2857 _("LED meter style"),
2858 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_style_led),
2859 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_style_led)
2862 /* and now the theme manager */
2864 ThemeManager* tm = manage (new ThemeManager);
2865 add_page (_("Theme"), *tm);
2869 RCOptionEditor::parameter_changed (string const & p)
2871 OptionEditor::parameter_changed (p);
2873 if (p == "use-monitor-bus") {
2874 bool const s = Config->get_use_monitor_bus ();
2876 /* we can't use this if we don't have a monitor bus */
2877 Config->set_solo_control_is_listen_control (false);
2879 _solo_control_is_listen_control->set_sensitive (s);
2880 _listen_position->set_sensitive (s);
2881 } else if (p == "sync-source") {
2882 _sync_source->set_sensitive (true);
2884 _sync_source->set_sensitive (!_session->config.get_external_sync());
2886 switch(Config->get_sync_source()) {
2889 _sync_genlock->set_sensitive (true);
2890 _sync_framerate->set_sensitive (true);
2891 _sync_source_2997->set_sensitive (true);
2894 _sync_genlock->set_sensitive (false);
2895 _sync_framerate->set_sensitive (false);
2896 _sync_source_2997->set_sensitive (false);
2899 } else if (p == "send-ltc") {
2900 bool const s = Config->get_send_ltc ();
2901 _ltc_send_continuously->set_sensitive (s);
2902 _ltc_volume_slider->set_sensitive (s);
2906 void RCOptionEditor::ltc_generator_volume_changed () {
2907 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
2911 RCOptionEditor::populate_sync_options ()
2913 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
2915 _sync_source->clear ();
2917 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
2918 _sync_source->add (*i, sync_source_to_string (*i));
2921 if (sync_opts.empty()) {
2922 _sync_source->set_sensitive(false);
2924 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
2925 _rc_config->set_sync_source(sync_opts.front());