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 "meter_patterns.h"
54 #include "midi_tracer.h"
55 #include "rc_option_editor.h"
57 #include "midi_port_dialog.h"
60 #include "theme_manager.h"
61 #include "ui_config.h"
66 using namespace Gtkmm2ext;
68 using namespace ARDOUR;
69 using namespace ARDOUR_UI_UTILS;
71 class ClickOptions : public OptionEditorBox
74 ClickOptions (RCConfiguration* c, Gtk::Window* p)
77 Table* t = manage (new Table (2, 3));
80 Label* l = manage (left_aligned_label (_("Click audio file:")));
81 t->attach (*l, 0, 1, 0, 1, FILL);
82 t->attach (_click_path_entry, 1, 2, 0, 1, FILL);
83 Button* b = manage (new Button (_("Browse...")));
84 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
85 t->attach (*b, 2, 3, 0, 1, FILL);
87 l = manage (left_aligned_label (_("Click emphasis audio file:")));
88 t->attach (*l, 0, 1, 1, 2, FILL);
89 t->attach (_click_emphasis_path_entry, 1, 2, 1, 2, FILL);
90 b = manage (new Button (_("Browse...")));
91 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
92 t->attach (*b, 2, 3, 1, 2, FILL);
94 _box->pack_start (*t, false, false);
96 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
97 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
100 void parameter_changed (string const & p)
102 if (p == "click-sound") {
103 _click_path_entry.set_text (_rc_config->get_click_sound());
104 } else if (p == "click-emphasis-sound") {
105 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
109 void set_state_from_config ()
111 parameter_changed ("click-sound");
112 parameter_changed ("click-emphasis-sound");
117 void click_browse_clicked ()
119 SoundFileChooser sfdb (_("Choose Click"));
124 if (sfdb.run () == RESPONSE_OK) {
125 click_chosen (sfdb.get_filename());
129 void click_chosen (string const & path)
131 _click_path_entry.set_text (path);
132 _rc_config->set_click_sound (path);
135 void click_changed ()
137 click_chosen (_click_path_entry.get_text ());
140 void click_emphasis_browse_clicked ()
142 SoundFileChooser sfdb (_("Choose Click Emphasis"));
147 if (sfdb.run () == RESPONSE_OK) {
148 click_emphasis_chosen (sfdb.get_filename());
152 void click_emphasis_chosen (string const & path)
154 _click_emphasis_path_entry.set_text (path);
155 _rc_config->set_click_emphasis_sound (path);
158 void click_emphasis_changed ()
160 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
163 RCConfiguration* _rc_config;
164 Entry _click_path_entry;
165 Entry _click_emphasis_path_entry;
168 class UndoOptions : public OptionEditorBox
171 UndoOptions (RCConfiguration* c) :
173 _limit_undo_button (_("Limit undo history to")),
174 _save_undo_button (_("Save undo history of"))
176 Table* t = new Table (2, 3);
179 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
180 _limit_undo_spin.set_range (0, 512);
181 _limit_undo_spin.set_increments (1, 10);
182 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
183 Label* l = manage (left_aligned_label (_("commands")));
184 t->attach (*l, 2, 3, 0, 1);
186 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
187 _save_undo_spin.set_range (0, 512);
188 _save_undo_spin.set_increments (1, 10);
189 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
190 l = manage (left_aligned_label (_("commands")));
191 t->attach (*l, 2, 3, 1, 2);
193 _box->pack_start (*t);
195 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
196 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
197 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
198 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
201 void parameter_changed (string const & p)
203 if (p == "history-depth") {
204 int32_t const d = _rc_config->get_history_depth();
205 _limit_undo_button.set_active (d != 0);
206 _limit_undo_spin.set_sensitive (d != 0);
207 _limit_undo_spin.set_value (d);
208 } else if (p == "save-history") {
209 bool const x = _rc_config->get_save_history ();
210 _save_undo_button.set_active (x);
211 _save_undo_spin.set_sensitive (x);
212 } else if (p == "save-history-depth") {
213 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
217 void set_state_from_config ()
219 parameter_changed ("save-history");
220 parameter_changed ("history-depth");
221 parameter_changed ("save-history-depth");
224 void limit_undo_toggled ()
226 bool const x = _limit_undo_button.get_active ();
227 _limit_undo_spin.set_sensitive (x);
228 int32_t const n = x ? 16 : 0;
229 _limit_undo_spin.set_value (n);
230 _rc_config->set_history_depth (n);
233 void limit_undo_changed ()
235 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
238 void save_undo_toggled ()
240 bool const x = _save_undo_button.get_active ();
241 _rc_config->set_save_history (x);
244 void save_undo_changed ()
246 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
250 RCConfiguration* _rc_config;
251 CheckButton _limit_undo_button;
252 SpinButton _limit_undo_spin;
253 CheckButton _save_undo_button;
254 SpinButton _save_undo_spin;
259 static const struct {
271 { "Key|Shift", GDK_SHIFT_MASK },
272 { "Command", GDK_META_MASK },
273 { "Control", GDK_CONTROL_MASK },
274 { "Option", GDK_MOD1_MASK },
275 { "Command-Shift", GDK_META_MASK|GDK_SHIFT_MASK },
276 { "Command-Option", GDK_MOD1_MASK|GDK_META_MASK },
277 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
278 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
279 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_META_MASK },
282 { "Key|Shift", GDK_SHIFT_MASK },
283 { "Control", GDK_CONTROL_MASK },
284 { "Alt", GDK_MOD1_MASK },
285 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
286 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
287 { "Shift-Alt", GDK_SHIFT_MASK|GDK_MOD1_MASK },
288 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
289 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
290 { "Mod2", GDK_MOD2_MASK },
291 { "Mod3", GDK_MOD3_MASK },
292 { "Windows", GDK_MOD4_MASK },
293 { "Mod5", GDK_MOD5_MASK },
299 class KeyboardOptions : public OptionEditorBox
303 _delete_button_adjustment (3, 1, 12),
304 _delete_button_spin (_delete_button_adjustment),
305 _edit_button_adjustment (3, 1, 5),
306 _edit_button_spin (_edit_button_adjustment),
307 _insert_note_button_adjustment (3, 1, 5),
308 _insert_note_button_spin (_insert_note_button_adjustment)
310 /* internationalize and prepare for use with combos */
313 for (int i = 0; modifiers[i].name; ++i) {
314 dumb.push_back (S_(modifiers[i].name));
317 set_popdown_strings (_edit_modifier_combo, dumb);
318 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
320 for (int x = 0; modifiers[x].name; ++x) {
321 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
322 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
327 Table* t = manage (new Table (5, 11));
333 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
334 l->set_name ("OptionsLabel");
338 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
339 strs.push_back (bf->first);
342 set_popdown_strings (_keyboard_layout_selector, strs);
343 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
344 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
346 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
347 t->attach (_keyboard_layout_selector, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
352 l = manage (left_aligned_label (_("When Clicking:")));
353 l->set_name ("OptionEditorHeading");
354 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
359 l = manage (left_aligned_label (_("Edit using:")));
360 l->set_name ("OptionsLabel");
362 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
363 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
365 l = manage (new Label (_("+ button")));
366 l->set_name ("OptionsLabel");
368 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
369 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
371 _edit_button_spin.set_name ("OptionsEntry");
372 _edit_button_adjustment.set_value (Keyboard::edit_button());
373 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
378 set_popdown_strings (_delete_modifier_combo, dumb);
379 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
381 for (int x = 0; modifiers[x].name; ++x) {
382 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
383 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
388 l = manage (left_aligned_label (_("Delete using:")));
389 l->set_name ("OptionsLabel");
391 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
392 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
394 l = manage (new Label (_("+ button")));
395 l->set_name ("OptionsLabel");
397 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
398 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
400 _delete_button_spin.set_name ("OptionsEntry");
401 _delete_button_adjustment.set_value (Keyboard::delete_button());
402 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
407 set_popdown_strings (_insert_note_modifier_combo, dumb);
408 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
410 for (int x = 0; modifiers[x].name; ++x) {
411 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
412 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
417 l = manage (left_aligned_label (_("Insert note using:")));
418 l->set_name ("OptionsLabel");
420 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
421 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
423 l = manage (new Label (_("+ button")));
424 l->set_name ("OptionsLabel");
426 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
427 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
429 _insert_note_button_spin.set_name ("OptionsEntry");
430 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
431 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
435 l = manage (left_aligned_label (_("When Beginning a Drag:")));
436 l->set_name ("OptionEditorHeading");
437 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
443 set_popdown_strings (_copy_modifier_combo, dumb);
444 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
446 for (int x = 0; modifiers[x].name; ++x) {
447 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
448 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
453 l = manage (left_aligned_label (_("Copy items using:")));
454 l->set_name ("OptionsLabel");
456 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
457 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
462 /* constraint modifier */
463 set_popdown_strings (_constraint_modifier_combo, dumb);
464 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
466 for (int x = 0; modifiers[x].name; ++x) {
467 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
468 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
473 l = manage (left_aligned_label (_("Constrain drag using:")));
474 l->set_name ("OptionsLabel");
476 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
477 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
481 l = manage (left_aligned_label (_("When Beginning a Trim:")));
482 l->set_name ("OptionEditorHeading");
483 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
489 set_popdown_strings (_trim_contents_combo, dumb);
490 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
492 for (int x = 0; modifiers[x].name; ++x) {
493 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
494 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
499 l = manage (left_aligned_label (_("Trim contents using:")));
500 l->set_name ("OptionsLabel");
502 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
503 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
509 set_popdown_strings (_trim_anchored_combo, dumb);
510 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
512 for (int x = 0; modifiers[x].name; ++x) {
513 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
514 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
519 l = manage (left_aligned_label (_("Anchored trim using:")));
520 l->set_name ("OptionsLabel");
522 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
524 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
529 /* jump trim disabled for now
530 set_popdown_strings (_trim_jump_combo, dumb);
531 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
533 for (int x = 0; modifiers[x].name; ++x) {
534 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
535 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
540 l = manage (left_aligned_label (_("Jump after trim using:")));
541 l->set_name ("OptionsLabel");
543 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
545 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
551 /* note resize relative */
552 set_popdown_strings (_note_size_relative_combo, dumb);
553 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
555 for (int x = 0; modifiers[x].name; ++x) {
556 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
557 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
562 l = manage (left_aligned_label (_("Resize notes relatively using:")));
563 l->set_name ("OptionsLabel");
565 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
567 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
571 l = manage (left_aligned_label (_("While Dragging:")));
572 l->set_name ("OptionEditorHeading");
573 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
579 set_popdown_strings (_snap_modifier_combo, dumb);
580 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
582 for (int x = 0; modifiers[x].name; ++x) {
583 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
584 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
589 l = manage (left_aligned_label (_("Ignore snap using:")));
590 l->set_name ("OptionsLabel");
592 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
593 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
599 set_popdown_strings (_snap_delta_combo, dumb);
600 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
602 for (int x = 0; modifiers[x].name; ++x) {
603 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
604 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
609 l = manage (left_aligned_label (_("Snap relatively using:")));
610 l->set_name ("OptionsLabel");
612 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
613 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
617 l = manage (left_aligned_label (_("While Trimming:")));
618 l->set_name ("OptionEditorHeading");
619 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
625 set_popdown_strings (_trim_overlap_combo, dumb);
626 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
628 for (int x = 0; modifiers[x].name; ++x) {
629 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
630 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
635 l = manage (left_aligned_label (_("Resize overlaped regions using:")));
636 l->set_name ("OptionsLabel");
638 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
639 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
643 l = manage (left_aligned_label (_("While Dragging Control Points:")));
644 l->set_name ("OptionEditorHeading");
645 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
651 set_popdown_strings (_fine_adjust_combo, dumb);
652 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
654 for (int x = 0; modifiers[x].name; ++x) {
655 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
656 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
661 l = manage (left_aligned_label (_("Fine adjust using:")));
662 l->set_name ("OptionsLabel");
664 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
665 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
671 set_popdown_strings (_push_points_combo, dumb);
672 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
674 for (int x = 0; modifiers[x].name; ++x) {
675 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
676 _push_points_combo.set_active_text (S_(modifiers[x].name));
681 l = manage (left_aligned_label (_("Push points using:")));
682 l->set_name ("OptionsLabel");
684 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
685 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
687 _box->pack_start (*t, false, false);
690 void parameter_changed (string const &)
692 /* XXX: these aren't really config options... */
695 void set_state_from_config ()
697 /* XXX: these aren't really config options... */
702 void bindings_changed ()
704 string const txt = _keyboard_layout_selector.get_active_text();
706 /* XXX: config...? for all this keyboard stuff */
708 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
709 if (txt == i->first) {
710 if (Keyboard::load_keybindings (i->second)) {
711 Keyboard::save_keybindings ();
717 void edit_modifier_chosen ()
719 string const txt = _edit_modifier_combo.get_active_text();
721 for (int i = 0; modifiers[i].name; ++i) {
722 if (txt == _(modifiers[i].name)) {
723 Keyboard::set_edit_modifier (modifiers[i].modifier);
729 void delete_modifier_chosen ()
731 string const txt = _delete_modifier_combo.get_active_text();
733 for (int i = 0; modifiers[i].name; ++i) {
734 if (txt == _(modifiers[i].name)) {
735 Keyboard::set_delete_modifier (modifiers[i].modifier);
741 void copy_modifier_chosen ()
743 string const txt = _copy_modifier_combo.get_active_text();
745 for (int i = 0; modifiers[i].name; ++i) {
746 if (txt == _(modifiers[i].name)) {
747 Keyboard::set_copy_modifier (modifiers[i].modifier);
753 void insert_note_modifier_chosen ()
755 string const txt = _insert_note_modifier_combo.get_active_text();
757 for (int i = 0; modifiers[i].name; ++i) {
758 if (txt == _(modifiers[i].name)) {
759 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
765 void snap_modifier_chosen ()
767 string const txt = _snap_modifier_combo.get_active_text();
769 for (int i = 0; modifiers[i].name; ++i) {
770 if (txt == _(modifiers[i].name)) {
771 Keyboard::set_snap_modifier (modifiers[i].modifier);
777 void snap_delta_modifier_chosen ()
779 string const txt = _snap_delta_combo.get_active_text();
781 for (int i = 0; modifiers[i].name; ++i) {
782 if (txt == _(modifiers[i].name)) {
783 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
789 void constraint_modifier_chosen ()
791 string const txt = _constraint_modifier_combo.get_active_text();
793 for (int i = 0; modifiers[i].name; ++i) {
794 if (txt == _(modifiers[i].name)) {
795 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
801 void trim_contents_modifier_chosen ()
803 string const txt = _trim_contents_combo.get_active_text();
805 for (int i = 0; modifiers[i].name; ++i) {
806 if (txt == _(modifiers[i].name)) {
807 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
813 void trim_overlap_modifier_chosen ()
815 string const txt = _trim_overlap_combo.get_active_text();
817 for (int i = 0; modifiers[i].name; ++i) {
818 if (txt == _(modifiers[i].name)) {
819 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
825 void trim_anchored_modifier_chosen ()
827 string const txt = _trim_anchored_combo.get_active_text();
829 for (int i = 0; modifiers[i].name; ++i) {
830 if (txt == _(modifiers[i].name)) {
831 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
837 void fine_adjust_modifier_chosen ()
839 string const txt = _fine_adjust_combo.get_active_text();
841 for (int i = 0; modifiers[i].name; ++i) {
842 if (txt == _(modifiers[i].name)) {
843 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
849 void push_points_modifier_chosen ()
851 string const txt = _push_points_combo.get_active_text();
853 for (int i = 0; modifiers[i].name; ++i) {
854 if (txt == _(modifiers[i].name)) {
855 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
861 void note_size_relative_modifier_chosen ()
863 string const txt = _note_size_relative_combo.get_active_text();
865 for (int i = 0; modifiers[i].name; ++i) {
866 if (txt == _(modifiers[i].name)) {
867 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
873 void delete_button_changed ()
875 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
878 void edit_button_changed ()
880 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
883 void insert_note_button_changed ()
885 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
888 ComboBoxText _keyboard_layout_selector;
889 ComboBoxText _edit_modifier_combo;
890 ComboBoxText _delete_modifier_combo;
891 ComboBoxText _copy_modifier_combo;
892 ComboBoxText _insert_note_modifier_combo;
893 ComboBoxText _snap_modifier_combo;
894 ComboBoxText _snap_delta_combo;
895 ComboBoxText _constraint_modifier_combo;
896 ComboBoxText _trim_contents_combo;
897 ComboBoxText _trim_overlap_combo;
898 ComboBoxText _trim_anchored_combo;
899 ComboBoxText _trim_jump_combo;
900 ComboBoxText _fine_adjust_combo;
901 ComboBoxText _push_points_combo;
902 ComboBoxText _note_size_relative_combo;
903 Adjustment _delete_button_adjustment;
904 SpinButton _delete_button_spin;
905 Adjustment _edit_button_adjustment;
906 SpinButton _edit_button_spin;
907 Adjustment _insert_note_button_adjustment;
908 SpinButton _insert_note_button_spin;
912 class FontScalingOptions : public OptionEditorBox
915 FontScalingOptions (UIConfiguration* uic) :
917 _dpi_adjustment (100, 50, 250, 1, 5),
918 _dpi_slider (_dpi_adjustment)
920 _dpi_adjustment.set_value (_ui_config->get_font_scale() / 1024.);
922 Label* l = manage (new Label (_("GUI and Font scaling:")));
923 l->set_name ("OptionsLabel");
925 const Glib::ustring dflt = _("Default");
926 const Glib::ustring empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
928 _dpi_slider.set_name("FontScaleSlider");
929 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
930 _dpi_slider.set_draw_value(false);
931 _dpi_slider.add_mark(50, Gtk::POS_TOP, empty);
932 _dpi_slider.add_mark(60, Gtk::POS_TOP, empty);
933 _dpi_slider.add_mark(70, Gtk::POS_TOP, empty);
934 _dpi_slider.add_mark(80, Gtk::POS_TOP, empty);
935 _dpi_slider.add_mark(90, Gtk::POS_TOP, empty);
936 _dpi_slider.add_mark(100, Gtk::POS_TOP, dflt);
937 _dpi_slider.add_mark(125, Gtk::POS_TOP, empty);
938 _dpi_slider.add_mark(150, Gtk::POS_TOP, empty);
939 _dpi_slider.add_mark(175, Gtk::POS_TOP, empty);
940 _dpi_slider.add_mark(200, Gtk::POS_TOP, empty);
941 _dpi_slider.add_mark(225, Gtk::POS_TOP, empty);
942 _dpi_slider.add_mark(250, Gtk::POS_TOP, empty);
944 HBox* h = manage (new HBox);
946 h->pack_start (*l, false, false);
947 h->pack_start (_dpi_slider, true, true);
949 _box->pack_start (*h, false, false);
951 set_note (_("Adjusting the scale require an application restart to re-layout."));
953 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
956 void parameter_changed (string const & p)
958 if (p == "font-scale") {
959 _dpi_adjustment.set_value (_ui_config->get_font_scale() / 1024.);
963 void set_state_from_config ()
965 parameter_changed ("font-scale");
972 _ui_config->set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024.));
973 /* XXX: should be triggered from the parameter changed signal */
977 UIConfiguration* _ui_config;
978 Adjustment _dpi_adjustment;
982 class ClipLevelOptions : public OptionEditorBox
985 ClipLevelOptions (UIConfiguration* c)
987 , _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
988 , _clip_level_slider (_clip_level_adjustment)
990 _clip_level_adjustment.set_value (_ui_config->get_waveform_clip_level ());
992 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
993 l->set_name ("OptionsLabel");
995 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
996 HBox* h = manage (new HBox);
998 h->pack_start (*l, false, false);
999 h->pack_start (_clip_level_slider, true, true);
1001 _box->pack_start (*h, false, false);
1003 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1006 void parameter_changed (string const & p)
1008 if (p == "waveform-clip-level") {
1009 _clip_level_adjustment.set_value (_ui_config->get_waveform_clip_level());
1013 void set_state_from_config ()
1015 parameter_changed ("waveform-clip-level");
1020 void clip_level_changed ()
1022 _ui_config->set_waveform_clip_level (_clip_level_adjustment.get_value());
1023 /* XXX: should be triggered from the parameter changed signal */
1024 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1027 UIConfiguration* _ui_config;
1028 Adjustment _clip_level_adjustment;
1029 HScale _clip_level_slider;
1032 class BufferingOptions : public OptionEditorBox
1035 BufferingOptions (RCConfiguration* c)
1037 , _playback_adjustment (5, 1, 60, 1, 4)
1038 , _capture_adjustment (5, 1, 60, 1, 4)
1039 , _playback_slider (_playback_adjustment)
1040 , _capture_slider (_capture_adjustment)
1042 vector<string> presets;
1044 /* these must match the order of the enums for BufferingPreset */
1046 presets.push_back (_("Small sessions (4-16 tracks)"));
1047 presets.push_back (_("Medium sessions (16-64 tracks)"));
1048 presets.push_back (_("Large sessions (64+ tracks)"));
1049 presets.push_back (_("Custom (set by sliders below)"));
1051 set_popdown_strings (_buffering_presets_combo, presets);
1053 Label* l = manage (new Label (_("Preset:")));
1054 l->set_name ("OptionsLabel");
1055 HBox* h = manage (new HBox);
1056 h->set_spacing (12);
1057 h->pack_start (*l, false, false);
1058 h->pack_start (_buffering_presets_combo, true, true);
1059 _box->pack_start (*h, false, false);
1061 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1063 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1065 l = manage (new Label (_("Playback (seconds of buffering):")));
1066 l->set_name ("OptionsLabel");
1068 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1069 h = manage (new HBox);
1071 h->pack_start (*l, false, false);
1072 h->pack_start (_playback_slider, true, true);
1074 _box->pack_start (*h, false, false);
1076 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1078 l = manage (new Label (_("Recording (seconds of buffering):")));
1079 l->set_name ("OptionsLabel");
1081 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1082 h = manage (new HBox);
1084 h->pack_start (*l, false, false);
1085 h->pack_start (_capture_slider, true, true);
1087 _box->pack_start (*h, false, false);
1089 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
1090 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
1093 void parameter_changed (string const & p)
1095 if (p == "buffering-preset") {
1096 switch (_rc_config->get_buffering_preset()) {
1098 _playback_slider.set_sensitive (false);
1099 _capture_slider.set_sensitive (false);
1100 _buffering_presets_combo.set_active (0);
1103 _playback_slider.set_sensitive (false);
1104 _capture_slider.set_sensitive (false);
1105 _buffering_presets_combo.set_active (1);
1108 _playback_slider.set_sensitive (false);
1109 _capture_slider.set_sensitive (false);
1110 _buffering_presets_combo.set_active (2);
1113 _playback_slider.set_sensitive (true);
1114 _capture_slider.set_sensitive (true);
1115 _buffering_presets_combo.set_active (3);
1120 if (p == "playback-buffer-seconds") {
1121 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1122 } else if (p == "capture-buffer-seconds") {
1123 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1127 void set_state_from_config ()
1129 parameter_changed ("buffering-preset");
1130 parameter_changed ("playback-buffer-seconds");
1131 parameter_changed ("capture-buffer-seconds");
1136 void preset_changed ()
1138 int index = _buffering_presets_combo.get_active_row_number ();
1144 _rc_config->set_buffering_preset (Small);
1147 _rc_config->set_buffering_preset (Medium);
1150 _rc_config->set_buffering_preset (Large);
1153 _rc_config->set_buffering_preset (Custom);
1156 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1161 void playback_changed ()
1163 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
1166 void capture_changed ()
1168 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
1171 RCConfiguration* _rc_config;
1172 Adjustment _playback_adjustment;
1173 Adjustment _capture_adjustment;
1174 HScale _playback_slider;
1175 HScale _capture_slider;
1176 ComboBoxText _buffering_presets_combo;
1179 class ControlSurfacesOptions : public OptionEditorBox
1182 ControlSurfacesOptions (Gtk::Window& parent)
1184 , _ignore_view_change (0)
1186 _store = ListStore::create (_model);
1187 _view.set_model (_store);
1188 _view.append_column (_("Control Surface Protocol"), _model.name);
1189 _view.get_column(0)->set_resizable (true);
1190 _view.get_column(0)->set_expand (true);
1191 _view.append_column_editable (_("Enabled"), _model.enabled);
1192 _view.append_column_editable (_("Feedback"), _model.feedback);
1194 _box->pack_start (_view, false, false);
1196 Label* label = manage (new Label);
1197 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
1199 _box->pack_start (*label, false, false);
1202 ControlProtocolManager& m = ControlProtocolManager::instance ();
1203 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1204 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1206 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1207 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1210 void parameter_changed (std::string const &)
1215 void set_state_from_config ()
1219 ControlProtocolManager& m = ControlProtocolManager::instance ();
1220 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1222 if (!(*i)->mandatory) {
1223 TreeModel::Row r = *_store->append ();
1224 r[_model.name] = (*i)->name;
1225 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1226 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
1227 r[_model.protocol_info] = *i;
1234 void protocol_status_changed (ControlProtocolInfo* cpi) {
1236 TreeModel::Children rows = _store->children();
1238 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1239 string n = ((*x)[_model.name]);
1241 if ((*x)[_model.protocol_info] == cpi) {
1242 _ignore_view_change++;
1243 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1244 _ignore_view_change--;
1250 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1252 TreeModel::Row r = *i;
1254 if (_ignore_view_change) {
1258 ControlProtocolInfo* cpi = r[_model.protocol_info];
1263 bool const was_enabled = (cpi->protocol != 0);
1264 bool const is_enabled = r[_model.enabled];
1267 if (was_enabled != is_enabled) {
1270 ControlProtocolManager::instance().activate (*cpi);
1272 ControlProtocolManager::instance().deactivate (*cpi);
1276 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
1277 bool const is_feedback = r[_model.feedback];
1279 if (was_feedback != is_feedback && cpi->protocol) {
1280 cpi->protocol->set_feedback (is_feedback);
1284 void edit_clicked (GdkEventButton* ev)
1286 if (ev->type != GDK_2BUTTON_PRESS) {
1291 ControlProtocolInfo* cpi;
1294 row = *(_view.get_selection()->get_selected());
1295 if (!row[_model.enabled]) {
1298 cpi = row[_model.protocol_info];
1299 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1302 Box* box = (Box*) cpi->protocol->get_gui ();
1306 if (box->get_parent()) {
1307 static_cast<ArdourWindow*>(box->get_parent())->present();
1310 string title = row[_model.name];
1311 /* once created, the window is managed by the surface itself (as ->get_parent())
1312 * Surface's tear_down_gui() is called on session close, when de-activating
1313 * or re-initializing a surface.
1314 * tear_down_gui() hides an deletes the Window if it exists.
1316 ArdourWindow* win = new ArdourWindow (_parent, title);
1317 win->set_title ("Control Protocol Options");
1323 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1327 ControlSurfacesModelColumns ()
1332 add (protocol_info);
1335 TreeModelColumn<string> name;
1336 TreeModelColumn<bool> enabled;
1337 TreeModelColumn<bool> feedback;
1338 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1341 Glib::RefPtr<ListStore> _store;
1342 ControlSurfacesModelColumns _model;
1344 Gtk::Window& _parent;
1345 PBD::ScopedConnection protocol_status_connection;
1346 uint32_t _ignore_view_change;
1349 class VideoTimelineOptions : public OptionEditorBox
1352 VideoTimelineOptions (RCConfiguration* c)
1354 , _show_video_export_info_button (_("Show Video Export Info before export"))
1355 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1356 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1358 Table* t = manage (new Table (2, 6));
1359 t->set_spacings (4);
1361 t->attach (_video_advanced_setup_button, 0, 2, 0, 1);
1362 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1363 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1364 _("<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."));
1366 Label* l = manage (new Label (_("Video Server URL:")));
1367 l->set_alignment (0, 0.5);
1368 t->attach (*l, 0, 1, 1, 2, FILL);
1369 t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL);
1370 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1371 _("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"));
1373 l = manage (new Label (_("Video Folder:")));
1374 l->set_alignment (0, 0.5);
1375 t->attach (*l, 0, 1, 2, 3, FILL);
1376 t->attach (_video_server_docroot_entry, 1, 2, 2, 3);
1377 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1378 _("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."));
1380 /* small vspace y=3..4 */
1382 t->attach (_show_video_export_info_button, 0, 2, 4, 5);
1383 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1384 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1385 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1387 t->attach (_show_video_server_dialog_button, 0, 2, 5, 6);
1388 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1389 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1390 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1392 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1393 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1394 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1395 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1397 _box->pack_start (*t,true,true);
1400 void server_url_changed ()
1402 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1405 void server_docroot_changed ()
1407 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1410 void show_video_export_info_toggled ()
1412 bool const x = _show_video_export_info_button.get_active ();
1413 _rc_config->set_show_video_export_info (x);
1416 void show_video_server_dialog_toggled ()
1418 bool const x = _show_video_server_dialog_button.get_active ();
1419 _rc_config->set_show_video_server_dialog (x);
1422 void video_advanced_setup_toggled ()
1424 bool const x = _video_advanced_setup_button.get_active ();
1425 _rc_config->set_video_advanced_setup(x);
1428 void parameter_changed (string const & p)
1430 if (p == "video-server-url") {
1431 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1432 } else if (p == "video-server-docroot") {
1433 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1434 } else if (p == "show-video-export-info") {
1435 bool const x = _rc_config->get_show_video_export_info();
1436 _show_video_export_info_button.set_active (x);
1437 } else if (p == "show-video-server-dialog") {
1438 bool const x = _rc_config->get_show_video_server_dialog();
1439 _show_video_server_dialog_button.set_active (x);
1440 } else if (p == "video-advanced-setup") {
1441 bool const x = _rc_config->get_video_advanced_setup();
1442 _video_advanced_setup_button.set_active(x);
1443 _video_server_docroot_entry.set_sensitive(x);
1444 _video_server_url_entry.set_sensitive(x);
1448 void set_state_from_config ()
1450 parameter_changed ("video-server-url");
1451 parameter_changed ("video-server-docroot");
1452 parameter_changed ("video-monitor-setup-dialog");
1453 parameter_changed ("show-video-export-info");
1454 parameter_changed ("show-video-server-dialog");
1455 parameter_changed ("video-advanced-setup");
1459 RCConfiguration* _rc_config;
1460 Entry _video_server_url_entry;
1461 Entry _video_server_docroot_entry;
1462 CheckButton _show_video_export_info_button;
1463 CheckButton _show_video_server_dialog_button;
1464 CheckButton _video_advanced_setup_button;
1467 class PluginOptions : public OptionEditorBox
1470 PluginOptions (RCConfiguration* c, UIConfiguration* uic)
1473 , _display_plugin_scan_progress (_("Always Display Plugin Scan Progress"))
1474 , _discover_vst_on_start (_("Scan for [new] VST Plugins on Application Start"))
1475 , _discover_au_on_start (_("Scan for AudioUnit Plugins on Application Start"))
1476 , _verbose_plugin_scan (_("Verbose Plugin Scan"))
1477 , _timeout_adjustment (0, 0, 3000, 50, 50)
1478 , _timeout_slider (_timeout_adjustment)
1481 std::stringstream ss;
1482 Table* t = manage (new Table (2, 6));
1483 t->set_spacings (4);
1487 ss << "<b>" << _("General") << "</b>";
1488 l = manage (left_aligned_label (ss.str()));
1489 l->set_use_markup (true);
1490 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1491 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1493 b = manage (new Button (_("Scan for Plugins")));
1494 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1495 t->attach (*b, 0, 2, n, n+1, FILL); ++n;
1497 t->attach (_display_plugin_scan_progress, 0, 2, n, n+1); ++n;
1498 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1499 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1500 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
1502 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
1503 _timeout_slider.set_digits (0);
1504 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &PluginOptions::timeout_changed));
1506 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1507 _("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."));
1509 l = manage (left_aligned_label (_("Scan Time Out [deciseconds]")));;
1510 HBox* h = manage (new HBox);
1512 h->pack_start (*l, false, false);
1513 h->pack_start (_timeout_slider, true, true);
1514 t->attach (*h, 0, 2, n, n+1); ++n;
1517 ss << "<b>" << _("VST") << "</b>";
1518 l = manage (left_aligned_label (ss.str()));
1519 l->set_use_markup (true);
1520 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1521 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1523 b = manage (new Button (_("Clear VST Cache")));
1524 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_cache_clicked));
1525 t->attach (*b, 0, 1, n, n+1, FILL);
1527 b = manage (new Button (_("Clear VST Blacklist")));
1528 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_blacklist_clicked));
1529 t->attach (*b, 1, 2, n, n+1, FILL);
1532 t->attach (_discover_vst_on_start, 0, 2, n, n+1); ++n;
1533 _discover_vst_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_vst_on_start_toggled));
1534 Gtkmm2ext::UI::instance()->set_tip (_discover_vst_on_start,
1535 _("<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"));
1537 #ifdef LXVST_SUPPORT
1538 t->attach (*manage (left_aligned_label (_("Linux VST Path:"))), 0, 1, n, n+1);
1539 b = manage (new Button (_("Edit")));
1540 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_lxvst_path_clicked));
1541 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1544 #ifdef WINDOWS_VST_SUPPORT
1545 t->attach (*manage (left_aligned_label (_("Windows VST Path:"))), 0, 1, n, n+1);
1546 b = manage (new Button (_("Edit")));
1547 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_vst_path_clicked));
1548 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1550 // currently verbose logging is only implemented for Windows VST.
1551 t->attach (_verbose_plugin_scan, 0, 2, n, n+1); ++n;
1552 _verbose_plugin_scan.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::verbose_plugin_scan_toggled));
1553 Gtkmm2ext::UI::instance()->set_tip (_verbose_plugin_scan,
1554 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
1558 #ifdef AUDIOUNIT_SUPPORT
1560 ss << "<b>" << _("Audio Unit") << "</b>";
1561 l = manage (left_aligned_label (ss.str()));
1562 l->set_use_markup (true);
1563 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1564 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1566 t->attach (_discover_au_on_start, 0, 2, n, n+1); ++n;
1567 _discover_au_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_au_on_start_toggled));
1568 Gtkmm2ext::UI::instance()->set_tip (_discover_au_on_start,
1569 _("<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."));
1572 b = manage (new Button (_("Clear AU Cache")));
1573 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_cache_clicked));
1574 t->attach (*b, 0, 1, n, n+1, FILL);
1576 b = manage (new Button (_("Clear AU Blacklist")));
1577 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_blacklist_clicked));
1578 t->attach (*b, 1, 2, n, n+1, FILL);
1582 _box->pack_start (*t,true,true);
1585 void parameter_changed (string const & p) {
1586 if (p == "show-plugin-scan-window") {
1587 bool const x = _ui_config->get_show_plugin_scan_window();
1588 _display_plugin_scan_progress.set_active (x);
1590 else if (p == "discover-vst-on-start") {
1591 bool const x = _rc_config->get_discover_vst_on_start();
1592 _discover_vst_on_start.set_active (x);
1594 else if (p == "vst-scan-timeout") {
1595 int const x = _rc_config->get_vst_scan_timeout();
1596 _timeout_adjustment.set_value (x);
1598 else if (p == "discover-audio-units") {
1599 bool const x = _rc_config->get_discover_audio_units();
1600 _discover_au_on_start.set_active (x);
1602 else if (p == "verbose-plugin-scan") {
1603 bool const x = _rc_config->get_verbose_plugin_scan();
1604 _verbose_plugin_scan.set_active (x);
1608 void set_state_from_config () {
1609 parameter_changed ("show-plugin-scan-window");
1610 parameter_changed ("discover-vst-on-start");
1611 parameter_changed ("vst-scan-timeout");
1612 parameter_changed ("discover-audio-units");
1613 parameter_changed ("verbose-plugin-scan");
1617 RCConfiguration* _rc_config;
1618 UIConfiguration* _ui_config;
1619 CheckButton _display_plugin_scan_progress;
1620 CheckButton _discover_vst_on_start;
1621 CheckButton _discover_au_on_start;
1622 CheckButton _verbose_plugin_scan;
1623 Adjustment _timeout_adjustment;
1624 HScale _timeout_slider;
1626 void display_plugin_scan_progress_toggled () {
1627 bool const x = _display_plugin_scan_progress.get_active();
1628 _ui_config->set_show_plugin_scan_window(x);
1631 void discover_vst_on_start_toggled () {
1632 bool const x = _discover_vst_on_start.get_active();
1633 _rc_config->set_discover_vst_on_start(x);
1636 void discover_au_on_start_toggled () {
1637 bool const x = _discover_au_on_start.get_active();
1638 _rc_config->set_discover_audio_units(x);
1641 void verbose_plugin_scan_toggled () {
1642 bool const x = _verbose_plugin_scan.get_active();
1643 _rc_config->set_verbose_plugin_scan(x);
1646 void timeout_changed () {
1647 int x = floor(_timeout_adjustment.get_value());
1648 _rc_config->set_vst_scan_timeout(x);
1651 void clear_vst_cache_clicked () {
1652 PluginManager::instance().clear_vst_cache();
1655 void clear_vst_blacklist_clicked () {
1656 PluginManager::instance().clear_vst_blacklist();
1659 void clear_au_cache_clicked () {
1660 PluginManager::instance().clear_au_cache();
1663 void clear_au_blacklist_clicked () {
1664 PluginManager::instance().clear_au_blacklist();
1668 void edit_vst_path_clicked () {
1669 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1670 _("Set Windows VST Search Path"),
1671 _rc_config->get_plugin_path_vst(),
1672 PluginManager::instance().get_default_windows_vst_path()
1674 ResponseType r = (ResponseType) pd->run ();
1676 if (r == RESPONSE_ACCEPT) {
1677 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
1682 // todo consolidate with edit_vst_path_clicked..
1683 void edit_lxvst_path_clicked () {
1684 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1685 _("Set Linux VST Search Path"),
1686 _rc_config->get_plugin_path_lxvst(),
1687 PluginManager::instance().get_default_lxvst_path()
1689 ResponseType r = (ResponseType) pd->run ();
1691 if (r == RESPONSE_ACCEPT) {
1692 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
1697 void refresh_clicked () {
1698 PluginManager::instance().refresh();
1703 /** A class which allows control of visibility of some editor components usign
1704 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1705 * which has the correct members, but with null widget pointers. This
1706 * class allows the user to set visibility of the members, the details
1707 * of which are stored in a configuration variable which can be watched
1708 * by parts of the editor that actually contain the widgets whose visibility
1709 * is being controlled.
1712 class VisibilityOption : public Option
1715 /** @param name User-visible name for this group.
1716 * @param g `Dummy' VisibilityGroup (as described above).
1717 * @param get Method to get the value of the appropriate configuration variable.
1718 * @param set Method to set the value of the appropriate configuration variable.
1720 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1721 : Option (g->get_state_name(), name)
1723 , _visibility_group (g)
1727 /* Watch for changes made by the user to our members */
1728 _visibility_group->VisibilityChanged.connect_same_thread (
1729 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1733 void set_state_from_config ()
1735 /* Set our state from the current configuration */
1736 _visibility_group->set_state (_get ());
1739 void add_to_page (OptionEditorPage* p)
1741 _heading.add_to_page (p);
1742 add_widget_to_page (p, _visibility_group->list_view ());
1745 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1750 /* The user has changed something, so reflect this change
1751 in the RCConfiguration.
1753 _set (_visibility_group->get_state_value ());
1756 OptionEditorHeading _heading;
1757 VisibilityGroup* _visibility_group;
1758 sigc::slot<std::string> _get;
1759 sigc::slot<bool, std::string> _set;
1760 PBD::ScopedConnection _visibility_group_connection;
1765 RCOptionEditor::RCOptionEditor ()
1766 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1767 , _rc_config (Config)
1768 , _ui_config (ARDOUR_UI::config())
1769 , _mixer_strip_visibility ("mixer-element-visibility")
1773 uint32_t hwcpus = hardware_concurrency ();
1775 BoolComboOption* bco;
1778 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1780 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1782 _("Signal processing uses"),
1783 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1784 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1787 procs->add (-1, _("all but one processor"));
1788 procs->add (0, _("all available processors"));
1790 for (uint32_t i = 1; i <= hwcpus; ++i) {
1791 procs->add (i, string_compose (_("%1 processors"), i));
1794 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1796 add_option (_("Misc"), procs);
1799 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1801 add_option (_("Misc"), new UndoOptions (_rc_config));
1803 add_option (_("Misc"),
1805 "verify-remove-last-capture",
1806 _("Verify removal of last capture"),
1807 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1808 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1811 add_option (_("Misc"),
1813 "periodic-safety-backups",
1814 _("Make periodic backups of the session file"),
1815 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1816 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1819 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1821 add_option (_("Misc"),
1823 "only-copy-imported-files",
1824 _("Always copy imported files"),
1825 sigc::mem_fun (*_ui_config, &UIConfiguration::get_only_copy_imported_files),
1826 sigc::mem_fun (*_ui_config, &UIConfiguration::set_only_copy_imported_files)
1829 add_option (_("Misc"), new DirectoryOption (
1830 X_("default-session-parent-dir"),
1831 _("Default folder for new sessions:"),
1832 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1833 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1836 add_option (_("Misc"),
1837 new SpinOption<uint32_t> (
1838 "max-recent-sessions",
1839 _("Maximum number of recent sessions"),
1840 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1841 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1845 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1847 add_option (_("Misc"), new ClickOptions (_rc_config, this));
1849 add_option (_("Misc"),
1852 _("Click gain level"),
1853 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1854 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1857 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1859 add_option (_("Misc"),
1860 new SpinOption<double> (
1861 "automation-thinning-factor",
1862 _("Thinning factor (larger value => less data)"),
1863 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1864 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1868 add_option (_("Misc"),
1869 new SpinOption<double> (
1870 "automation-interval-msecs",
1871 _("Automation sampling interval (milliseconds)"),
1872 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1873 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1879 add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options")));
1883 tsf = new BoolOption (
1884 "latched-record-enable",
1885 _("Keep record-enable engaged on stop"),
1886 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1887 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1889 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1890 add_option (_("Transport"), tsf);
1892 tsf = new BoolOption (
1894 _("Play loop is a transport mode"),
1895 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1896 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1898 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1899 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1900 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1901 add_option (_("Transport"), tsf);
1903 tsf = new BoolOption (
1904 "stop-recording-on-xrun",
1905 _("Stop recording when an xrun occurs"),
1906 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1907 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1909 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1910 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
1912 add_option (_("Transport"), tsf);
1914 tsf = new BoolOption (
1915 "create-xrun-marker",
1916 _("Create markers where xruns occur"),
1917 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
1918 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
1920 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1921 add_option (_("Transport"), tsf);
1923 tsf = new BoolOption (
1924 "stop-at-session-end",
1925 _("Stop at the end of the session"),
1926 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
1927 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
1929 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1930 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
1931 "when it reaches the current session end marker\n\n"
1932 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
1934 add_option (_("Transport"), tsf);
1936 tsf = new BoolOption (
1938 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
1939 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
1940 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
1942 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1943 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
1944 "preventing any need to do a transport locate at the end of the loop\n\n"
1945 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
1946 "which will often cause a small click or delay"), PROGRAM_NAME));
1947 add_option (_("Transport"), tsf);
1949 tsf = new BoolOption (
1950 "disable-disarm-during-roll",
1951 _("Disable per-track record disarm while rolling"),
1952 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
1953 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
1955 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"));
1956 add_option (_("Transport"), tsf);
1958 tsf = new BoolOption (
1960 _("12dB gain reduction during fast-forward and fast-rewind"),
1961 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
1962 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
1964 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
1965 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
1966 add_option (_("Transport"), tsf);
1968 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
1970 _sync_source = new ComboOption<SyncSource> (
1972 _("External timecode source"),
1973 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
1974 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
1977 add_option (_("Transport"), _sync_source);
1979 _sync_framerate = new BoolOption (
1980 "timecode-sync-frame-rate",
1981 _("Match session video frame rate to external timecode"),
1982 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
1983 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
1985 Gtkmm2ext::UI::instance()->set_tip
1986 (_sync_framerate->tip_widget(),
1987 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
1988 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
1989 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
1990 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
1991 "timecode standard and the session standard."), PROGRAM_NAME));
1993 add_option (_("Transport"), _sync_framerate);
1995 _sync_genlock = new BoolOption (
1996 "timecode-source-is-synced",
1997 _("Sync-lock timecode to clock (disable drift compensation)"),
1998 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
1999 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
2001 Gtkmm2ext::UI::instance()->set_tip
2002 (_sync_genlock->tip_widget(),
2003 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
2004 "Sync Lock indicates that the selected external timecode source shares clock-sync "
2005 "(Black & Burst, Wordclock, etc) with the audio interface. "
2006 "This option disables drift compensation. The transport speed is fixed at 1.0. "
2007 "Vari-speed LTC will be ignored and cause drift."
2009 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
2010 "timecode sources shares clock sync."
2014 add_option (_("Transport"), _sync_genlock);
2016 _sync_source_2997 = new BoolOption (
2017 "timecode-source-2997",
2018 _("Lock to 29.9700 fps instead of 30000/1001"),
2019 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
2020 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
2022 Gtkmm2ext::UI::instance()->set_tip
2023 (_sync_source_2997->tip_widget(),
2024 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
2025 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
2026 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
2027 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
2028 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
2029 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
2032 add_option (_("Transport"), _sync_source_2997);
2034 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
2036 _ltc_port = new ComboStringOption (
2038 _("LTC incoming port"),
2039 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
2040 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
2043 vector<string> physical_inputs;
2044 physical_inputs.push_back (_("None"));
2045 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
2046 _ltc_port->set_popdown_strings (physical_inputs);
2048 populate_sync_options ();
2050 add_option (_("Transport"), _ltc_port);
2052 // TODO; rather disable this button than not compile it..
2053 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
2055 add_option (_("Transport"),
2058 _("Enable LTC generator"),
2059 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
2060 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
2063 _ltc_send_continuously = new BoolOption (
2064 "ltc-send-continuously",
2065 _("Send LTC while stopped"),
2066 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
2067 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
2069 Gtkmm2ext::UI::instance()->set_tip
2070 (_ltc_send_continuously->tip_widget(),
2071 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
2072 add_option (_("Transport"), _ltc_send_continuously);
2074 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
2075 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
2076 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
2077 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
2079 Gtkmm2ext::UI::instance()->set_tip
2080 (_ltc_volume_slider->tip_widget(),
2081 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
2083 add_option (_("Transport"), _ltc_volume_slider);
2084 parameter_changed ("send-ltc");
2086 parameter_changed ("sync-source");
2090 add_option (S_("Editor"),
2092 "draggable-playhead",
2093 _("Allow dragging of playhead"),
2094 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_draggable_playhead),
2095 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_draggable_playhead)
2098 add_option (_("Editor"),
2100 "automation-follows-regions",
2101 _("Move relevant automation when audio regions are moved"),
2102 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2103 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2106 add_option (_("Editor"),
2108 "show-track-meters",
2109 _("Show meters on tracks in the editor"),
2110 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_track_meters),
2111 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_track_meters)
2114 add_option (_("Editor"),
2116 "show-editor-meter",
2117 _("Display master-meter in the toolbar"),
2118 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_editor_meter),
2119 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_editor_meter)
2122 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2123 "default-fade-shape",
2124 _("Default fade shape"),
2125 sigc::mem_fun (*_rc_config,
2126 &RCConfiguration::get_default_fade_shape),
2127 sigc::mem_fun (*_rc_config,
2128 &RCConfiguration::set_default_fade_shape)
2131 fadeshape->add (FadeLinear,
2132 _("Linear (for highly correlated material)"));
2133 fadeshape->add (FadeConstantPower, _("Constant power"));
2134 fadeshape->add (FadeSymmetric, _("Symmetric"));
2135 fadeshape->add (FadeSlow, _("Slow"));
2136 fadeshape->add (FadeFast, _("Fast"));
2138 add_option (_("Editor"), fadeshape);
2141 bco = new BoolComboOption (
2142 "use-overlap-equivalency",
2143 _("Regions in active edit groups are edited together"),
2144 _("whenever they overlap in time"),
2145 _("only if they have identical length, position and origin"),
2146 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2147 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2150 add_option (_("Editor"), bco);
2152 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2154 _("Layering model"),
2155 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2156 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2159 lm->add (LaterHigher, _("later is higher"));
2160 lm->add (Manual, _("manual layering"));
2161 add_option (_("Editor"), lm);
2163 add_option (_("Editor"),
2165 "rubberbanding-snaps-to-grid",
2166 _("Make rubberband selection rectangle snap to the grid"),
2167 sigc::mem_fun (*_ui_config, &UIConfiguration::get_rubberbanding_snaps_to_grid),
2168 sigc::mem_fun (*_ui_config, &UIConfiguration::set_rubberbanding_snaps_to_grid)
2171 add_option (_("Editor"),
2174 _("Show waveforms in regions"),
2175 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms),
2176 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms)
2179 add_option (_("Editor"),
2180 new BoolComboOption (
2181 "show-region-gain-envelopes",
2182 _("Show gain envelopes in audio regions"),
2184 _("only in Draw and Internal Edit modes"),
2185 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_region_gain),
2186 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_region_gain)
2189 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
2191 _("Waveform scale"),
2192 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_scale),
2193 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_scale)
2196 wfs->add (Linear, _("linear"));
2197 wfs->add (Logarithmic, _("logarithmic"));
2199 add_option (_("Editor"), wfs);
2201 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
2203 _("Waveform shape"),
2204 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_shape),
2205 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_shape)
2208 wfsh->add (Traditional, _("traditional"));
2209 wfsh->add (Rectified, _("rectified"));
2211 add_option (_("Editor"), wfsh);
2213 add_option (_("Editor"), new ClipLevelOptions (_ui_config));
2215 add_option (_("Editor"),
2217 "show-waveforms-while-recording",
2218 _("Show waveforms for audio while it is being recorded"),
2219 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms_while_recording),
2220 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms_while_recording)
2223 add_option (_("Editor"),
2226 _("Show zoom toolbar"),
2227 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_zoom_tools),
2228 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_zoom_tools)
2231 add_option (_("Editor"),
2233 "update-editor-during-summary-drag",
2234 _("Update editor window during drags of the summary"),
2235 sigc::mem_fun (*_ui_config, &UIConfiguration::get_update_editor_during_summary_drag),
2236 sigc::mem_fun (*_ui_config, &UIConfiguration::set_update_editor_during_summary_drag)
2239 bo = new BoolOption (
2241 _("Name new markers"),
2242 sigc::mem_fun (*_ui_config, &UIConfiguration::get_name_new_markers),
2243 sigc::mem_fun (*_ui_config, &UIConfiguration::set_name_new_markers)
2246 add_option (_("Editor"), bo);
2247 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."
2248 "\n\nYou can always rename markers by right-clicking on them"));
2250 add_option (_("Editor"),
2252 "autoscroll-editor",
2253 _("Auto-scroll editor window when dragging near its edges"),
2254 sigc::mem_fun (*_ui_config, &UIConfiguration::get_autoscroll_editor),
2255 sigc::mem_fun (*_ui_config, &UIConfiguration::set_autoscroll_editor)
2258 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2259 "region-selection-after-split",
2260 _("After splitting selected regions, select"),
2261 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2262 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2264 // TODO: decide which of these modes are really useful
2265 rsas->add(None, _("no regions"));
2266 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2267 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2268 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2269 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2270 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2271 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2272 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2274 add_option (_("Editor"), rsas);
2279 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2281 add_option (_("Audio"), new BufferingOptions (_rc_config));
2283 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2285 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2287 _("Record monitoring handled by"),
2288 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2289 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2292 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2293 mm->add (HardwareMonitoring, _("via Audio Driver"));
2296 string prog (PROGRAM_NAME);
2297 boost::algorithm::to_lower (prog);
2298 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2299 mm->add (ExternalMonitoring, _("audio hardware"));
2301 add_option (_("Audio"), mm);
2303 add_option (_("Audio"),
2305 "tape-machine-mode",
2306 _("Tape machine mode"),
2307 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2308 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2311 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
2313 add_option (_("Audio"),
2315 "auto-connect-standard-busses",
2316 _("Auto-connect master/monitor busses"),
2317 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2318 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2321 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2322 "input-auto-connect",
2323 _("Connect track inputs"),
2324 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2325 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2328 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2329 iac->add (ManualConnect, _("manually"));
2331 add_option (_("Audio"), iac);
2333 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2334 "output-auto-connect",
2335 _("Connect track and bus outputs"),
2336 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2337 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2340 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2341 oac->add (AutoConnectMaster, _("automatically to master bus"));
2342 oac->add (ManualConnect, _("manually"));
2344 add_option (_("Audio"), oac);
2346 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2348 add_option (_("Audio"),
2350 "denormal-protection",
2351 _("Use DC bias to protect against denormals"),
2352 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2353 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2356 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2358 _("Processor handling"),
2359 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2360 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2364 dm->add (DenormalNone, _("no processor handling"));
2366 FPU* fpu = FPU::instance();
2368 if (fpu->has_flush_to_zero()) {
2370 dm->add (DenormalFTZ, _("use FlushToZero"));
2371 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2372 _rc_config->set_denormal_model(DenormalNone);
2375 if (fpu->has_denormals_are_zero()) {
2377 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2378 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2379 _rc_config->set_denormal_model(DenormalNone);
2382 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2384 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2385 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2386 _rc_config->set_denormal_model(DenormalNone);
2390 dm->set_sensitive(false);
2393 add_option (_("Audio"), dm);
2395 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
2397 add_option (_("Audio"),
2399 "plugins-stop-with-transport",
2400 _("Silence plugins when the transport is stopped"),
2401 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
2402 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
2405 add_option (_("Audio"),
2407 "new-plugins-active",
2408 _("Make new plugins active"),
2409 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
2410 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
2413 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2415 add_option (_("Audio"),
2417 "auto-analyse-audio",
2418 _("Enable automatic analysis of audio"),
2419 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2420 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2423 add_option (_("Audio"),
2425 "replicate-missing-region-channels",
2426 _("Replicate missing region channels"),
2427 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2428 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2433 add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
2435 add_option (_("Solo / mute"),
2438 _("Solo-in-place mute cut (dB)"),
2439 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2440 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2443 _solo_control_is_listen_control = new BoolOption (
2444 "solo-control-is-listen-control",
2445 _("Solo controls are Listen controls"),
2446 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2447 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2450 add_option (_("Solo / mute"), _solo_control_is_listen_control);
2452 _listen_position = new ComboOption<ListenPosition> (
2454 _("Listen Position"),
2455 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2456 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2459 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2460 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2462 add_option (_("Solo / mute"), _listen_position);
2464 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2466 _("PFL signals come from"),
2467 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2468 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2471 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2472 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2474 add_option (_("Solo / mute"), pp);
2476 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2478 _("AFL signals come from"),
2479 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2480 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2483 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2484 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2486 add_option (_("Solo / mute"), pa);
2488 parameter_changed ("use-monitor-bus");
2490 add_option (_("Solo / mute"),
2493 _("Exclusive solo"),
2494 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2495 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2498 add_option (_("Solo / mute"),
2501 _("Show solo muting"),
2502 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2503 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2506 add_option (_("Solo / mute"),
2508 "solo-mute-override",
2509 _("Soloing overrides muting"),
2510 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2511 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2514 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
2516 add_option (_("Solo / mute"),
2518 "mute-affects-pre-fader",
2519 _("Mute affects pre-fader sends"),
2520 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2521 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2524 add_option (_("Solo / mute"),
2526 "mute-affects-post-fader",
2527 _("Mute affects post-fader sends"),
2528 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2529 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2532 add_option (_("Solo / mute"),
2534 "mute-affects-control-outs",
2535 _("Mute affects control outputs"),
2536 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2537 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2540 add_option (_("Solo / mute"),
2542 "mute-affects-main-outs",
2543 _("Mute affects main outputs"),
2544 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2545 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2548 add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
2550 add_option (_("Solo / mute"),
2552 "link-send-and-route-panner",
2553 _("Link panners of Aux and External Sends with main panner by default"),
2554 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2555 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2558 add_option (_("MIDI"),
2559 new SpinOption<float> (
2561 _("MIDI read-ahead time (seconds)"),
2562 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2563 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2568 add_option (_("MIDI"),
2571 _("Send MIDI Clock"),
2572 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2573 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2576 add_option (_("MIDI"),
2579 _("Send MIDI Time Code"),
2580 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2581 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2584 add_option (_("MIDI"),
2585 new SpinOption<int> (
2586 "mtc-qf-speed-tolerance",
2587 _("Percentage either side of normal transport speed to transmit MTC"),
2588 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2589 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2593 add_option (_("MIDI"),
2596 _("Obey MIDI Machine Control commands"),
2597 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2598 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2601 add_option (_("MIDI"),
2604 _("Send MIDI Machine Control commands"),
2605 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2606 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2609 add_option (_("MIDI"),
2612 _("Send MIDI control feedback"),
2613 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2614 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2617 add_option (_("MIDI"),
2618 new SpinOption<uint8_t> (
2619 "mmc-receive-device-id",
2620 _("Inbound MMC device ID"),
2621 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2622 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2626 add_option (_("MIDI"),
2627 new SpinOption<uint8_t> (
2628 "mmc-send-device-id",
2629 _("Outbound MMC device ID"),
2630 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2631 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2635 add_option (_("MIDI"),
2636 new SpinOption<int32_t> (
2637 "initial-program-change",
2638 _("Initial program change"),
2639 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2640 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2644 add_option (_("MIDI"),
2646 "display-first-midi-bank-as-zero",
2647 _("Display first MIDI bank/program as 0"),
2648 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2649 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2652 add_option (_("MIDI"),
2654 "never-display-periodic-midi",
2655 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2656 sigc::mem_fun (*_ui_config, &UIConfiguration::get_never_display_periodic_midi),
2657 sigc::mem_fun (*_ui_config, &UIConfiguration::set_never_display_periodic_midi)
2660 add_option (_("MIDI"),
2663 _("Sound MIDI notes as they are selected"),
2664 sigc::mem_fun (*_ui_config, &UIConfiguration::get_sound_midi_notes),
2665 sigc::mem_fun (*_ui_config, &UIConfiguration::set_sound_midi_notes)
2668 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2670 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2671 "midi-audition-synth-uri",
2672 _("Midi Audition Synth (LV2)"),
2673 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2674 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2677 audition_synth->add(X_(""), _("None"));
2678 PluginInfoList all_plugs;
2679 PluginManager& manager (PluginManager::instance());
2681 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2683 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2684 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2685 if (!(*i)->is_instrument()) continue;
2686 if ((*i)->type != ARDOUR::LV2) continue;
2687 audition_synth->add((*i)->unique_id, (*i)->name);
2691 add_option (_("MIDI"), audition_synth);
2693 /* USER INTERACTION */
2696 #ifdef PLATFORM_WINDOWS
2699 getenv ("ARDOUR_BUNDLED")
2703 add_option (_("User interaction"),
2705 "enable-translation",
2706 string_compose (_("Use translations of %1 messages\n"
2707 " <i>(requires a restart of %1 to take effect)</i>\n"
2708 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2709 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2710 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2713 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2715 add_option (_("User interaction"), new KeyboardOptions);
2717 /* Control Surfaces */
2719 add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
2721 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2723 _("Control surface remote ID"),
2724 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2725 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2728 rm->add (UserOrdered, _("assigned by user"));
2729 rm->add (MixerOrdered, _("follows order of mixer"));
2731 add_option (_("Control Surfaces"), rm);
2733 /* VIDEO Timeline */
2734 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2736 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2737 /* Plugin options (currrently VST only) */
2738 add_option (_("Plugins"), new PluginOptions (_rc_config, _ui_config));
2743 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
2744 BoolOption* bgo = new BoolOption (
2746 _("Possibly improve slow graphical performance"),
2747 sigc::mem_fun (*_ui_config, &UIConfiguration::get_buggy_gradients),
2748 sigc::mem_fun (*_ui_config, &UIConfiguration::set_buggy_gradients)
2751 Gtkmm2ext::UI::instance()->set_tip (bgo->tip_widget(), string_compose (_("This requires restarting %1 before having an effect"), PROGRAM_NAME));
2752 add_option (S_("Preferences|GUI"), bgo);
2755 add_option (S_("Preferences|GUI"),
2758 _("Graphically indicate mouse pointer hovering over various widgets"),
2759 sigc::mem_fun (*_ui_config, &UIConfiguration::get_widget_prelight),
2760 sigc::mem_fun (*_ui_config, &UIConfiguration::set_widget_prelight)
2763 #ifdef TOOLTIPS_GOT_FIXED
2764 add_option (S_("Preferences|GUI"),
2767 _("Show tooltips if mouse hovers over a control"),
2768 sigc::mem_fun (*_ui_config, &UIConfiguration::get_use_tooltips),
2769 sigc::mem_fun (*_ui_config, &UIConfiguration::set_use_tooltips)
2773 add_option (S_("Preferences|GUI"),
2775 "show-name-highlight",
2776 _("Use name highlight bars in region displays (requires a restart)"),
2777 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_name_highlight),
2778 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_name_highlight)
2782 /* font scaling does nothing with GDK/Quartz */
2783 add_option (S_("Preferences|GUI"), new FontScalingOptions (_ui_config));
2786 add_option (S_("GUI"),
2788 "super-rapid-clock-update",
2789 _("update transport clock display at FPS instead of every 100ms"),
2790 sigc::mem_fun (*_ui_config, &UIConfiguration::get_super_rapid_clock_update),
2791 sigc::mem_fun (*_ui_config, &UIConfiguration::set_super_rapid_clock_update)
2795 /* Image cache size */
2797 Gtk::Adjustment *ics = manage (new Gtk::Adjustment(0, 1, 1024, 10)); /* 1 MB to 1GB in steps of 10MB */
2798 HSliderOption *sics = new HSliderOption("waveform-cache-size",
2799 _("Waveform image cache size (megabytes)"),
2801 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_waveform_cache_size),
2802 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_waveform_cache_size)
2804 sics->scale().set_digits (0);
2805 Gtkmm2ext::UI::instance()->set_tip
2806 (sics->tip_widget(),
2807 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
2808 add_option (S_("Preferences|GUI"), sics);
2810 /* Lock GUI timeout */
2812 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
2813 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2814 _("Lock timeout (seconds)"),
2816 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_lock_gui_after_seconds),
2817 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_lock_gui_after_seconds)
2819 slts->scale().set_digits (0);
2820 Gtkmm2ext::UI::instance()->set_tip
2821 (slts->tip_widget(),
2822 _("Lock GUI after this many idle seconds (zero to never lock)"));
2823 add_option (S_("Preferences|GUI"), slts);
2825 /* The names of these controls must be the same as those given in MixerStrip
2826 for the actual widgets being controlled.
2828 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
2829 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2830 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
2831 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
2832 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
2833 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2836 S_("Preferences|GUI"),
2837 new VisibilityOption (
2839 &_mixer_strip_visibility,
2840 sigc::mem_fun (*_ui_config, &UIConfiguration::get_mixer_strip_visibility),
2841 sigc::mem_fun (*_ui_config, &UIConfiguration::set_mixer_strip_visibility)
2845 add_option (S_("Preferences|GUI"),
2847 "default-narrow_ms",
2848 _("Use narrow strips in the mixer by default"),
2849 sigc::mem_fun (*_ui_config, &UIConfiguration::get_default_narrow_ms),
2850 sigc::mem_fun (*_ui_config, &UIConfiguration::set_default_narrow_ms)
2853 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2855 ComboOption<float>* mht = new ComboOption<float> (
2857 _("Peak hold time"),
2858 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_hold),
2859 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_hold)
2862 mht->add (MeterHoldOff, _("off"));
2863 mht->add (MeterHoldShort, _("short"));
2864 mht->add (MeterHoldMedium, _("medium"));
2865 mht->add (MeterHoldLong, _("long"));
2867 add_option (S_("Preferences|Metering"), mht);
2869 ComboOption<float>* mfo = new ComboOption<float> (
2872 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2873 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2876 mfo->add (METER_FALLOFF_OFF, _("off"));
2877 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2878 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2879 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
2880 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2881 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
2882 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
2884 add_option (S_("Preferences|Metering"), mfo);
2886 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2887 "meter-line-up-level",
2888 _("Meter line-up level; 0dBu"),
2889 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_level),
2890 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_level)
2893 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2894 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2895 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2896 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2898 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."));
2900 add_option (S_("Preferences|Metering"), mlu);
2902 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2903 "meter-line-up-din",
2904 _("IEC1/DIN Meter line-up level; 0dBu"),
2905 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_din),
2906 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_din)
2909 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2910 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2911 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2912 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2914 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2916 add_option (S_("Preferences|Metering"), mld);
2918 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2919 "meter-vu-standard",
2920 _("VU Meter standard"),
2921 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_vu_standard),
2922 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_vu_standard)
2925 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2926 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2927 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2928 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2930 add_option (S_("Preferences|Metering"), mvu);
2932 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
2933 HSliderOption *mpks = new HSliderOption("meter-peak",
2934 _("Peak threshold [dBFS]"),
2936 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_peak),
2937 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_peak)
2941 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
2942 "meter-type-master",
2943 _("Default Meter Type for Master Bus"),
2944 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
2945 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
2947 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2948 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2949 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2950 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2951 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2952 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2953 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2954 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
2956 add_option (S_("Preferences|Metering"), mtm);
2959 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
2961 _("Default Meter Type for Busses"),
2962 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
2963 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
2965 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2966 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2967 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2968 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2969 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2970 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2971 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2972 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
2974 add_option (S_("Preferences|Metering"), mtb);
2976 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
2978 _("Default Meter Type for Tracks"),
2979 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
2980 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
2982 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2983 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
2985 add_option (S_("Preferences|Metering"), mtt);
2988 Gtkmm2ext::UI::instance()->set_tip
2989 (mpks->tip_widget(),
2990 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
2992 add_option (S_("Preferences|Metering"), mpks);
2994 add_option (S_("Preferences|Metering"),
2997 _("LED meter style"),
2998 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_style_led),
2999 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_style_led)
3002 /* and now the theme manager */
3004 ThemeManager* tm = manage (new ThemeManager);
3005 add_page (_("Theme"), *tm);
3009 RCOptionEditor::parameter_changed (string const & p)
3011 OptionEditor::parameter_changed (p);
3013 if (p == "use-monitor-bus") {
3014 bool const s = Config->get_use_monitor_bus ();
3016 /* we can't use this if we don't have a monitor bus */
3017 Config->set_solo_control_is_listen_control (false);
3019 _solo_control_is_listen_control->set_sensitive (s);
3020 _listen_position->set_sensitive (s);
3021 } else if (p == "sync-source") {
3022 _sync_source->set_sensitive (true);
3024 _sync_source->set_sensitive (!_session->config.get_external_sync());
3026 switch(Config->get_sync_source()) {
3029 _sync_genlock->set_sensitive (true);
3030 _sync_framerate->set_sensitive (true);
3031 _sync_source_2997->set_sensitive (true);
3034 _sync_genlock->set_sensitive (false);
3035 _sync_framerate->set_sensitive (false);
3036 _sync_source_2997->set_sensitive (false);
3039 } else if (p == "send-ltc") {
3040 bool const s = Config->get_send_ltc ();
3041 _ltc_send_continuously->set_sensitive (s);
3042 _ltc_volume_slider->set_sensitive (s);
3046 void RCOptionEditor::ltc_generator_volume_changed () {
3047 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
3051 RCOptionEditor::populate_sync_options ()
3053 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3055 _sync_source->clear ();
3057 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3058 _sync_source->add (*i, sync_source_to_string (*i));
3061 if (sync_opts.empty()) {
3062 _sync_source->set_sensitive(false);
3064 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3065 _rc_config->set_sync_source(sync_opts.front());