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 AutoReturnTargetOptions : public OptionEditorBox
74 AutoReturnTargetOptions (RCConfiguration* c, Gtk::Window* p)
76 , range_selection_button (_("Play Range Selection"))
77 , last_roll_button (_("Play from Last Roll"))
78 , loop_button (_("Play Loop"))
79 , region_selection_button (_("Play Region Selection"))
80 , toggle_button (_("Enable/Disable all options"))
82 _box->pack_start (range_selection_button, false, false);
83 range_selection_button.signal_toggled().connect (sigc::mem_fun (*this, &AutoReturnTargetOptions::range_selection_toggled));
85 _box->pack_start (loop_button, false, false);
86 loop_button.signal_toggled().connect (sigc::mem_fun (*this, &AutoReturnTargetOptions::loop_toggled));
88 _box->pack_start (region_selection_button, false, false);
89 region_selection_button.signal_toggled().connect (sigc::mem_fun (*this, &AutoReturnTargetOptions::region_selection_toggled));
91 _box->pack_start (last_roll_button, false, false);
92 last_roll_button.signal_toggled().connect (sigc::mem_fun (*this, &AutoReturnTargetOptions::last_roll_toggled));
94 HBox* hbox = manage (new HBox);
95 /* keep the toggle button small */
96 hbox->pack_start (toggle_button, false, false);
97 _box->pack_start (*hbox, false, false);
99 toggle_button.signal_clicked().connect (sigc::mem_fun (*this, &AutoReturnTargetOptions::toggle));
101 Gtkmm2ext::UI::instance()->set_tip (range_selection_button,
102 _("If enabled, playhead will always start from the beginning of the current range selection.\n\nIf disabled or no range selection, see the next choice in this list"));
103 Gtkmm2ext::UI::instance()->set_tip (loop_button,
104 _("If enabled, playhead will always start from the beginning of the loop range.\n\nIf disabled or no loop range, see the next choice in this list"));
105 Gtkmm2ext::UI::instance()->set_tip (region_selection_button,
106 _("If enabled, playhead will always start from the beginning of the first selected region.\n\nIf disabled or no region selection, see the next choice in this list"));
107 Gtkmm2ext::UI::instance()->set_tip (last_roll_button,
108 _("If enabled, playhead will always start from the last position where it was started.\n\nIf disabled it will start from wherever it is currently located"));
110 Gtkmm2ext::UI::instance()->set_tip (toggle_button,
111 _("Change status of all buttons above to all enabled or all disabled"));
114 void parameter_changed (string const & p)
116 if (p == "auto-return-target-list") {
117 AutoReturnTarget art = _rc_config->get_auto_return_target_list();
118 range_selection_button.set_active (art & RangeSelectionStart);
119 loop_button.set_active (art & Loop);
120 region_selection_button.set_active (art & RegionSelectionStart);
121 last_roll_button.set_active (art & LastLocate);
125 void set_state_from_config ()
127 parameter_changed ("auto-return-target-list");
132 void range_selection_toggled () {
133 AutoReturnTarget art = _rc_config->get_auto_return_target_list ();
134 if (range_selection_button.get_active ()) {
135 _rc_config->set_auto_return_target_list (AutoReturnTarget (art | RangeSelectionStart));
137 _rc_config->set_auto_return_target_list (AutoReturnTarget (art & ~RangeSelectionStart));
140 void last_roll_toggled () {
141 AutoReturnTarget art = _rc_config->get_auto_return_target_list ();
142 if (last_roll_button.get_active ()) {
143 _rc_config->set_auto_return_target_list (AutoReturnTarget (art | LastLocate));
145 _rc_config->set_auto_return_target_list (AutoReturnTarget (art & ~LastLocate));
148 void region_selection_toggled () {
149 AutoReturnTarget art = _rc_config->get_auto_return_target_list ();
150 if (region_selection_button.get_active ()) {
151 _rc_config->set_auto_return_target_list (AutoReturnTarget (art | RegionSelectionStart));
153 _rc_config->set_auto_return_target_list (AutoReturnTarget (art & ~RegionSelectionStart));
156 void loop_toggled () {
157 AutoReturnTarget art = _rc_config->get_auto_return_target_list ();
158 if (loop_button.get_active ()) {
159 _rc_config->set_auto_return_target_list (AutoReturnTarget (art | Loop));
161 _rc_config->set_auto_return_target_list (AutoReturnTarget (art & ~Loop));
166 AutoReturnTarget art = _rc_config->get_auto_return_target_list ();
168 _rc_config->set_auto_return_target_list (AutoReturnTarget (0));
170 _rc_config->set_auto_return_target_list (AutoReturnTarget (RangeSelectionStart|
171 RegionSelectionStart|
177 RCConfiguration* _rc_config;
179 Gtk::CheckButton range_selection_button;
180 Gtk::CheckButton last_roll_button;
181 Gtk::CheckButton loop_button;
182 Gtk::CheckButton region_selection_button;
183 Gtk::Button toggle_button;
186 class ClickOptions : public OptionEditorBox
189 ClickOptions (RCConfiguration* c, Gtk::Window* p)
192 Table* t = manage (new Table (2, 3));
195 Label* l = manage (left_aligned_label (_("Click audio file:")));
196 t->attach (*l, 0, 1, 0, 1, FILL);
197 t->attach (_click_path_entry, 1, 2, 0, 1, FILL);
198 Button* b = manage (new Button (_("Browse...")));
199 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
200 t->attach (*b, 2, 3, 0, 1, FILL);
202 l = manage (left_aligned_label (_("Click emphasis audio file:")));
203 t->attach (*l, 0, 1, 1, 2, FILL);
204 t->attach (_click_emphasis_path_entry, 1, 2, 1, 2, FILL);
205 b = manage (new Button (_("Browse...")));
206 b->signal_clicked().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
207 t->attach (*b, 2, 3, 1, 2, FILL);
209 _box->pack_start (*t, false, false);
211 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
212 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
215 void parameter_changed (string const & p)
217 if (p == "click-sound") {
218 _click_path_entry.set_text (_rc_config->get_click_sound());
219 } else if (p == "click-emphasis-sound") {
220 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
224 void set_state_from_config ()
226 parameter_changed ("click-sound");
227 parameter_changed ("click-emphasis-sound");
232 void click_browse_clicked ()
234 SoundFileChooser sfdb (_("Choose Click"));
239 if (sfdb.run () == RESPONSE_OK) {
240 click_chosen (sfdb.get_filename());
244 void click_chosen (string const & path)
246 _click_path_entry.set_text (path);
247 _rc_config->set_click_sound (path);
250 void click_changed ()
252 click_chosen (_click_path_entry.get_text ());
255 void click_emphasis_browse_clicked ()
257 SoundFileChooser sfdb (_("Choose Click Emphasis"));
262 if (sfdb.run () == RESPONSE_OK) {
263 click_emphasis_chosen (sfdb.get_filename());
267 void click_emphasis_chosen (string const & path)
269 _click_emphasis_path_entry.set_text (path);
270 _rc_config->set_click_emphasis_sound (path);
273 void click_emphasis_changed ()
275 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
278 RCConfiguration* _rc_config;
279 Entry _click_path_entry;
280 Entry _click_emphasis_path_entry;
283 class UndoOptions : public OptionEditorBox
286 UndoOptions (RCConfiguration* c) :
288 _limit_undo_button (_("Limit undo history to")),
289 _save_undo_button (_("Save undo history of"))
291 Table* t = new Table (2, 3);
294 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
295 _limit_undo_spin.set_range (0, 512);
296 _limit_undo_spin.set_increments (1, 10);
297 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
298 Label* l = manage (left_aligned_label (_("commands")));
299 t->attach (*l, 2, 3, 0, 1);
301 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
302 _save_undo_spin.set_range (0, 512);
303 _save_undo_spin.set_increments (1, 10);
304 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
305 l = manage (left_aligned_label (_("commands")));
306 t->attach (*l, 2, 3, 1, 2);
308 _box->pack_start (*t);
310 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
311 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
312 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
313 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
316 void parameter_changed (string const & p)
318 if (p == "history-depth") {
319 int32_t const d = _rc_config->get_history_depth();
320 _limit_undo_button.set_active (d != 0);
321 _limit_undo_spin.set_sensitive (d != 0);
322 _limit_undo_spin.set_value (d);
323 } else if (p == "save-history") {
324 bool const x = _rc_config->get_save_history ();
325 _save_undo_button.set_active (x);
326 _save_undo_spin.set_sensitive (x);
327 } else if (p == "save-history-depth") {
328 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
332 void set_state_from_config ()
334 parameter_changed ("save-history");
335 parameter_changed ("history-depth");
336 parameter_changed ("save-history-depth");
339 void limit_undo_toggled ()
341 bool const x = _limit_undo_button.get_active ();
342 _limit_undo_spin.set_sensitive (x);
343 int32_t const n = x ? 16 : 0;
344 _limit_undo_spin.set_value (n);
345 _rc_config->set_history_depth (n);
348 void limit_undo_changed ()
350 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
353 void save_undo_toggled ()
355 bool const x = _save_undo_button.get_active ();
356 _rc_config->set_save_history (x);
359 void save_undo_changed ()
361 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
365 RCConfiguration* _rc_config;
366 CheckButton _limit_undo_button;
367 SpinButton _limit_undo_spin;
368 CheckButton _save_undo_button;
369 SpinButton _save_undo_spin;
374 static const struct {
386 { "Key|Shift", GDK_SHIFT_MASK },
387 { "Command", GDK_META_MASK },
388 { "Control", GDK_CONTROL_MASK },
389 { "Option", GDK_MOD1_MASK },
390 { "Command-Shift", GDK_META_MASK|GDK_SHIFT_MASK },
391 { "Command-Option", GDK_MOD1_MASK|GDK_META_MASK },
392 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
393 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
394 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_META_MASK },
397 { "Key|Shift", GDK_SHIFT_MASK },
398 { "Control", GDK_CONTROL_MASK },
399 { "Alt", GDK_MOD1_MASK },
400 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
401 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
402 { "Shift-Alt", GDK_SHIFT_MASK|GDK_MOD1_MASK },
403 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
404 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
405 { "Mod2", GDK_MOD2_MASK },
406 { "Mod3", GDK_MOD3_MASK },
407 { "Windows", GDK_MOD4_MASK },
408 { "Mod5", GDK_MOD5_MASK },
414 class KeyboardOptions : public OptionEditorBox
418 _delete_button_adjustment (3, 1, 12),
419 _delete_button_spin (_delete_button_adjustment),
420 _edit_button_adjustment (3, 1, 5),
421 _edit_button_spin (_edit_button_adjustment),
422 _insert_note_button_adjustment (3, 1, 5),
423 _insert_note_button_spin (_insert_note_button_adjustment)
425 /* internationalize and prepare for use with combos */
428 for (int i = 0; modifiers[i].name; ++i) {
429 dumb.push_back (S_(modifiers[i].name));
432 set_popdown_strings (_edit_modifier_combo, dumb);
433 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
435 for (int x = 0; modifiers[x].name; ++x) {
436 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
437 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
442 Table* t = manage (new Table (5, 11));
448 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
449 l->set_name ("OptionsLabel");
453 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
454 strs.push_back (bf->first);
457 set_popdown_strings (_keyboard_layout_selector, strs);
458 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
459 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
461 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
462 t->attach (_keyboard_layout_selector, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
467 l = manage (left_aligned_label (_("When Clicking:")));
468 l->set_name ("OptionEditorHeading");
469 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
474 l = manage (left_aligned_label (_("Edit using:")));
475 l->set_name ("OptionsLabel");
477 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
478 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
480 l = manage (new Label (_("+ button")));
481 l->set_name ("OptionsLabel");
483 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
484 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
486 _edit_button_spin.set_name ("OptionsEntry");
487 _edit_button_adjustment.set_value (Keyboard::edit_button());
488 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
493 set_popdown_strings (_delete_modifier_combo, dumb);
494 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
496 for (int x = 0; modifiers[x].name; ++x) {
497 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
498 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
503 l = manage (left_aligned_label (_("Delete using:")));
504 l->set_name ("OptionsLabel");
506 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
507 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
509 l = manage (new Label (_("+ button")));
510 l->set_name ("OptionsLabel");
512 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
513 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
515 _delete_button_spin.set_name ("OptionsEntry");
516 _delete_button_adjustment.set_value (Keyboard::delete_button());
517 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
522 set_popdown_strings (_insert_note_modifier_combo, dumb);
523 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
525 for (int x = 0; modifiers[x].name; ++x) {
526 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
527 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
532 l = manage (left_aligned_label (_("Insert note using:")));
533 l->set_name ("OptionsLabel");
535 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
536 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
538 l = manage (new Label (_("+ button")));
539 l->set_name ("OptionsLabel");
541 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
542 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
544 _insert_note_button_spin.set_name ("OptionsEntry");
545 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
546 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
550 l = manage (left_aligned_label (_("When Beginning a Drag:")));
551 l->set_name ("OptionEditorHeading");
552 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
558 set_popdown_strings (_copy_modifier_combo, dumb);
559 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
561 for (int x = 0; modifiers[x].name; ++x) {
562 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
563 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
568 l = manage (left_aligned_label (_("Copy items using:")));
569 l->set_name ("OptionsLabel");
571 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
572 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
577 /* constraint modifier */
578 set_popdown_strings (_constraint_modifier_combo, dumb);
579 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
581 for (int x = 0; modifiers[x].name; ++x) {
582 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
583 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
588 l = manage (left_aligned_label (_("Constrain drag using:")));
589 l->set_name ("OptionsLabel");
591 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
592 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
596 l = manage (left_aligned_label (_("When Beginning a Trim:")));
597 l->set_name ("OptionEditorHeading");
598 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
604 set_popdown_strings (_trim_contents_combo, dumb);
605 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
607 for (int x = 0; modifiers[x].name; ++x) {
608 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
609 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
614 l = manage (left_aligned_label (_("Trim contents using:")));
615 l->set_name ("OptionsLabel");
617 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
618 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
624 set_popdown_strings (_trim_anchored_combo, dumb);
625 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
627 for (int x = 0; modifiers[x].name; ++x) {
628 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
629 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
634 l = manage (left_aligned_label (_("Anchored trim using:")));
635 l->set_name ("OptionsLabel");
637 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
639 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
644 /* jump trim disabled for now
645 set_popdown_strings (_trim_jump_combo, dumb);
646 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
648 for (int x = 0; modifiers[x].name; ++x) {
649 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
650 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
655 l = manage (left_aligned_label (_("Jump after trim using:")));
656 l->set_name ("OptionsLabel");
658 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
660 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
666 /* note resize relative */
667 set_popdown_strings (_note_size_relative_combo, dumb);
668 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
670 for (int x = 0; modifiers[x].name; ++x) {
671 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
672 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
677 l = manage (left_aligned_label (_("Resize notes relatively using:")));
678 l->set_name ("OptionsLabel");
680 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
682 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
686 l = manage (left_aligned_label (_("While Dragging:")));
687 l->set_name ("OptionEditorHeading");
688 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
694 set_popdown_strings (_snap_modifier_combo, dumb);
695 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
697 for (int x = 0; modifiers[x].name; ++x) {
698 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
699 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
704 l = manage (left_aligned_label (_("Ignore snap using:")));
705 l->set_name ("OptionsLabel");
707 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
708 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
714 set_popdown_strings (_snap_delta_combo, dumb);
715 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
717 for (int x = 0; modifiers[x].name; ++x) {
718 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
719 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
724 l = manage (left_aligned_label (_("Snap relatively using:")));
725 l->set_name ("OptionsLabel");
727 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
728 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
732 l = manage (left_aligned_label (_("While Trimming:")));
733 l->set_name ("OptionEditorHeading");
734 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
740 set_popdown_strings (_trim_overlap_combo, dumb);
741 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
743 for (int x = 0; modifiers[x].name; ++x) {
744 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
745 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
750 l = manage (left_aligned_label (_("Resize overlaped regions using:")));
751 l->set_name ("OptionsLabel");
753 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
754 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
758 l = manage (left_aligned_label (_("While Dragging Control Points:")));
759 l->set_name ("OptionEditorHeading");
760 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
766 set_popdown_strings (_fine_adjust_combo, dumb);
767 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
769 for (int x = 0; modifiers[x].name; ++x) {
770 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
771 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
776 l = manage (left_aligned_label (_("Fine adjust using:")));
777 l->set_name ("OptionsLabel");
779 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
780 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
786 set_popdown_strings (_push_points_combo, dumb);
787 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
789 for (int x = 0; modifiers[x].name; ++x) {
790 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
791 _push_points_combo.set_active_text (S_(modifiers[x].name));
796 l = manage (left_aligned_label (_("Push points using:")));
797 l->set_name ("OptionsLabel");
799 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
800 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
802 _box->pack_start (*t, false, false);
805 void parameter_changed (string const &)
807 /* XXX: these aren't really config options... */
810 void set_state_from_config ()
812 /* XXX: these aren't really config options... */
817 void bindings_changed ()
819 string const txt = _keyboard_layout_selector.get_active_text();
821 /* XXX: config...? for all this keyboard stuff */
823 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
824 if (txt == i->first) {
825 if (Keyboard::load_keybindings (i->second)) {
826 Keyboard::save_keybindings ();
832 void edit_modifier_chosen ()
834 string const txt = _edit_modifier_combo.get_active_text();
836 for (int i = 0; modifiers[i].name; ++i) {
837 if (txt == _(modifiers[i].name)) {
838 Keyboard::set_edit_modifier (modifiers[i].modifier);
844 void delete_modifier_chosen ()
846 string const txt = _delete_modifier_combo.get_active_text();
848 for (int i = 0; modifiers[i].name; ++i) {
849 if (txt == _(modifiers[i].name)) {
850 Keyboard::set_delete_modifier (modifiers[i].modifier);
856 void copy_modifier_chosen ()
858 string const txt = _copy_modifier_combo.get_active_text();
860 for (int i = 0; modifiers[i].name; ++i) {
861 if (txt == _(modifiers[i].name)) {
862 Keyboard::set_copy_modifier (modifiers[i].modifier);
868 void insert_note_modifier_chosen ()
870 string const txt = _insert_note_modifier_combo.get_active_text();
872 for (int i = 0; modifiers[i].name; ++i) {
873 if (txt == _(modifiers[i].name)) {
874 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
880 void snap_modifier_chosen ()
882 string const txt = _snap_modifier_combo.get_active_text();
884 for (int i = 0; modifiers[i].name; ++i) {
885 if (txt == _(modifiers[i].name)) {
886 Keyboard::set_snap_modifier (modifiers[i].modifier);
892 void snap_delta_modifier_chosen ()
894 string const txt = _snap_delta_combo.get_active_text();
896 for (int i = 0; modifiers[i].name; ++i) {
897 if (txt == _(modifiers[i].name)) {
898 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
904 void constraint_modifier_chosen ()
906 string const txt = _constraint_modifier_combo.get_active_text();
908 for (int i = 0; modifiers[i].name; ++i) {
909 if (txt == _(modifiers[i].name)) {
910 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
916 void trim_contents_modifier_chosen ()
918 string const txt = _trim_contents_combo.get_active_text();
920 for (int i = 0; modifiers[i].name; ++i) {
921 if (txt == _(modifiers[i].name)) {
922 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
928 void trim_overlap_modifier_chosen ()
930 string const txt = _trim_overlap_combo.get_active_text();
932 for (int i = 0; modifiers[i].name; ++i) {
933 if (txt == _(modifiers[i].name)) {
934 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
940 void trim_anchored_modifier_chosen ()
942 string const txt = _trim_anchored_combo.get_active_text();
944 for (int i = 0; modifiers[i].name; ++i) {
945 if (txt == _(modifiers[i].name)) {
946 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
952 void fine_adjust_modifier_chosen ()
954 string const txt = _fine_adjust_combo.get_active_text();
956 for (int i = 0; modifiers[i].name; ++i) {
957 if (txt == _(modifiers[i].name)) {
958 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
964 void push_points_modifier_chosen ()
966 string const txt = _push_points_combo.get_active_text();
968 for (int i = 0; modifiers[i].name; ++i) {
969 if (txt == _(modifiers[i].name)) {
970 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
976 void note_size_relative_modifier_chosen ()
978 string const txt = _note_size_relative_combo.get_active_text();
980 for (int i = 0; modifiers[i].name; ++i) {
981 if (txt == _(modifiers[i].name)) {
982 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
988 void delete_button_changed ()
990 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
993 void edit_button_changed ()
995 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
998 void insert_note_button_changed ()
1000 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
1003 ComboBoxText _keyboard_layout_selector;
1004 ComboBoxText _edit_modifier_combo;
1005 ComboBoxText _delete_modifier_combo;
1006 ComboBoxText _copy_modifier_combo;
1007 ComboBoxText _insert_note_modifier_combo;
1008 ComboBoxText _snap_modifier_combo;
1009 ComboBoxText _snap_delta_combo;
1010 ComboBoxText _constraint_modifier_combo;
1011 ComboBoxText _trim_contents_combo;
1012 ComboBoxText _trim_overlap_combo;
1013 ComboBoxText _trim_anchored_combo;
1014 ComboBoxText _trim_jump_combo;
1015 ComboBoxText _fine_adjust_combo;
1016 ComboBoxText _push_points_combo;
1017 ComboBoxText _note_size_relative_combo;
1018 Adjustment _delete_button_adjustment;
1019 SpinButton _delete_button_spin;
1020 Adjustment _edit_button_adjustment;
1021 SpinButton _edit_button_spin;
1022 Adjustment _insert_note_button_adjustment;
1023 SpinButton _insert_note_button_spin;
1027 class FontScalingOptions : public OptionEditorBox
1030 FontScalingOptions (UIConfiguration* uic) :
1032 _dpi_adjustment (100, 50, 250, 1, 5),
1033 _dpi_slider (_dpi_adjustment)
1035 _dpi_adjustment.set_value (_ui_config->get_font_scale() / 1024.);
1037 Label* l = manage (new Label (_("GUI and Font scaling:")));
1038 l->set_name ("OptionsLabel");
1040 const Glib::ustring dflt = _("Default");
1041 const Glib::ustring empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
1043 _dpi_slider.set_name("FontScaleSlider");
1044 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1045 _dpi_slider.set_draw_value(false);
1046 _dpi_slider.add_mark(50, Gtk::POS_TOP, empty);
1047 _dpi_slider.add_mark(60, Gtk::POS_TOP, empty);
1048 _dpi_slider.add_mark(70, Gtk::POS_TOP, empty);
1049 _dpi_slider.add_mark(80, Gtk::POS_TOP, empty);
1050 _dpi_slider.add_mark(90, Gtk::POS_TOP, empty);
1051 _dpi_slider.add_mark(100, Gtk::POS_TOP, dflt);
1052 _dpi_slider.add_mark(125, Gtk::POS_TOP, empty);
1053 _dpi_slider.add_mark(150, Gtk::POS_TOP, empty);
1054 _dpi_slider.add_mark(175, Gtk::POS_TOP, empty);
1055 _dpi_slider.add_mark(200, Gtk::POS_TOP, empty);
1056 _dpi_slider.add_mark(225, Gtk::POS_TOP, empty);
1057 _dpi_slider.add_mark(250, Gtk::POS_TOP, empty);
1059 HBox* h = manage (new HBox);
1061 h->pack_start (*l, false, false);
1062 h->pack_start (_dpi_slider, true, true);
1064 _box->pack_start (*h, false, false);
1066 set_note (_("Adjusting the scale require an application restart to re-layout."));
1068 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
1071 void parameter_changed (string const & p)
1073 if (p == "font-scale") {
1074 _dpi_adjustment.set_value (_ui_config->get_font_scale() / 1024.);
1078 void set_state_from_config ()
1080 parameter_changed ("font-scale");
1087 _ui_config->set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024.));
1088 /* XXX: should be triggered from the parameter changed signal */
1092 UIConfiguration* _ui_config;
1093 Adjustment _dpi_adjustment;
1097 class ClipLevelOptions : public OptionEditorBox
1100 ClipLevelOptions (UIConfiguration* c)
1102 , _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1103 , _clip_level_slider (_clip_level_adjustment)
1105 _clip_level_adjustment.set_value (_ui_config->get_waveform_clip_level ());
1107 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
1108 l->set_name ("OptionsLabel");
1110 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1111 HBox* h = manage (new HBox);
1113 h->pack_start (*l, false, false);
1114 h->pack_start (_clip_level_slider, true, true);
1116 _box->pack_start (*h, false, false);
1118 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1121 void parameter_changed (string const & p)
1123 if (p == "waveform-clip-level") {
1124 _clip_level_adjustment.set_value (_ui_config->get_waveform_clip_level());
1128 void set_state_from_config ()
1130 parameter_changed ("waveform-clip-level");
1135 void clip_level_changed ()
1137 _ui_config->set_waveform_clip_level (_clip_level_adjustment.get_value());
1138 /* XXX: should be triggered from the parameter changed signal */
1139 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1142 UIConfiguration* _ui_config;
1143 Adjustment _clip_level_adjustment;
1144 HScale _clip_level_slider;
1147 class BufferingOptions : public OptionEditorBox
1150 BufferingOptions (RCConfiguration* c)
1152 , _playback_adjustment (5, 1, 60, 1, 4)
1153 , _capture_adjustment (5, 1, 60, 1, 4)
1154 , _playback_slider (_playback_adjustment)
1155 , _capture_slider (_capture_adjustment)
1157 vector<string> presets;
1159 /* these must match the order of the enums for BufferingPreset */
1161 presets.push_back (_("Small sessions (4-16 tracks)"));
1162 presets.push_back (_("Medium sessions (16-64 tracks)"));
1163 presets.push_back (_("Large sessions (64+ tracks)"));
1164 presets.push_back (_("Custom (set by sliders below)"));
1166 set_popdown_strings (_buffering_presets_combo, presets);
1168 Label* l = manage (new Label (_("Preset:")));
1169 l->set_name ("OptionsLabel");
1170 HBox* h = manage (new HBox);
1171 h->set_spacing (12);
1172 h->pack_start (*l, false, false);
1173 h->pack_start (_buffering_presets_combo, true, true);
1174 _box->pack_start (*h, false, false);
1176 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1178 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1180 l = manage (new Label (_("Playback (seconds of buffering):")));
1181 l->set_name ("OptionsLabel");
1183 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1184 h = manage (new HBox);
1186 h->pack_start (*l, false, false);
1187 h->pack_start (_playback_slider, true, true);
1189 _box->pack_start (*h, false, false);
1191 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1193 l = manage (new Label (_("Recording (seconds of buffering):")));
1194 l->set_name ("OptionsLabel");
1196 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1197 h = manage (new HBox);
1199 h->pack_start (*l, false, false);
1200 h->pack_start (_capture_slider, true, true);
1202 _box->pack_start (*h, false, false);
1204 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
1205 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
1208 void parameter_changed (string const & p)
1210 if (p == "buffering-preset") {
1211 switch (_rc_config->get_buffering_preset()) {
1213 _playback_slider.set_sensitive (false);
1214 _capture_slider.set_sensitive (false);
1215 _buffering_presets_combo.set_active (0);
1218 _playback_slider.set_sensitive (false);
1219 _capture_slider.set_sensitive (false);
1220 _buffering_presets_combo.set_active (1);
1223 _playback_slider.set_sensitive (false);
1224 _capture_slider.set_sensitive (false);
1225 _buffering_presets_combo.set_active (2);
1228 _playback_slider.set_sensitive (true);
1229 _capture_slider.set_sensitive (true);
1230 _buffering_presets_combo.set_active (3);
1235 if (p == "playback-buffer-seconds") {
1236 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1237 } else if (p == "capture-buffer-seconds") {
1238 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1242 void set_state_from_config ()
1244 parameter_changed ("buffering-preset");
1245 parameter_changed ("playback-buffer-seconds");
1246 parameter_changed ("capture-buffer-seconds");
1251 void preset_changed ()
1253 int index = _buffering_presets_combo.get_active_row_number ();
1259 _rc_config->set_buffering_preset (Small);
1262 _rc_config->set_buffering_preset (Medium);
1265 _rc_config->set_buffering_preset (Large);
1268 _rc_config->set_buffering_preset (Custom);
1271 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1276 void playback_changed ()
1278 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
1281 void capture_changed ()
1283 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
1286 RCConfiguration* _rc_config;
1287 Adjustment _playback_adjustment;
1288 Adjustment _capture_adjustment;
1289 HScale _playback_slider;
1290 HScale _capture_slider;
1291 ComboBoxText _buffering_presets_combo;
1294 class ControlSurfacesOptions : public OptionEditorBox
1297 ControlSurfacesOptions (Gtk::Window& parent)
1299 , _ignore_view_change (0)
1301 _store = ListStore::create (_model);
1302 _view.set_model (_store);
1303 _view.append_column (_("Control Surface Protocol"), _model.name);
1304 _view.get_column(0)->set_resizable (true);
1305 _view.get_column(0)->set_expand (true);
1306 _view.append_column_editable (_("Enabled"), _model.enabled);
1307 _view.append_column_editable (_("Feedback"), _model.feedback);
1309 _box->pack_start (_view, false, false);
1311 Label* label = manage (new Label);
1312 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
1314 _box->pack_start (*label, false, false);
1317 ControlProtocolManager& m = ControlProtocolManager::instance ();
1318 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1319 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1321 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1322 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1325 void parameter_changed (std::string const &)
1330 void set_state_from_config ()
1334 ControlProtocolManager& m = ControlProtocolManager::instance ();
1335 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1337 if (!(*i)->mandatory) {
1338 TreeModel::Row r = *_store->append ();
1339 r[_model.name] = (*i)->name;
1340 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1341 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
1342 r[_model.protocol_info] = *i;
1349 void protocol_status_changed (ControlProtocolInfo* cpi) {
1351 TreeModel::Children rows = _store->children();
1353 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1354 string n = ((*x)[_model.name]);
1356 if ((*x)[_model.protocol_info] == cpi) {
1357 _ignore_view_change++;
1358 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1359 _ignore_view_change--;
1365 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1367 TreeModel::Row r = *i;
1369 if (_ignore_view_change) {
1373 ControlProtocolInfo* cpi = r[_model.protocol_info];
1378 bool const was_enabled = (cpi->protocol != 0);
1379 bool const is_enabled = r[_model.enabled];
1382 if (was_enabled != is_enabled) {
1385 ControlProtocolManager::instance().activate (*cpi);
1387 ControlProtocolManager::instance().deactivate (*cpi);
1391 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
1392 bool const is_feedback = r[_model.feedback];
1394 if (was_feedback != is_feedback && cpi->protocol) {
1395 cpi->protocol->set_feedback (is_feedback);
1399 void edit_clicked (GdkEventButton* ev)
1401 if (ev->type != GDK_2BUTTON_PRESS) {
1406 ControlProtocolInfo* cpi;
1409 row = *(_view.get_selection()->get_selected());
1410 if (!row[_model.enabled]) {
1413 cpi = row[_model.protocol_info];
1414 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1417 Box* box = (Box*) cpi->protocol->get_gui ();
1421 if (box->get_parent()) {
1422 static_cast<ArdourWindow*>(box->get_parent())->present();
1425 string title = row[_model.name];
1426 /* once created, the window is managed by the surface itself (as ->get_parent())
1427 * Surface's tear_down_gui() is called on session close, when de-activating
1428 * or re-initializing a surface.
1429 * tear_down_gui() hides an deletes the Window if it exists.
1431 ArdourWindow* win = new ArdourWindow (_parent, title);
1432 win->set_title ("Control Protocol Options");
1438 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1442 ControlSurfacesModelColumns ()
1447 add (protocol_info);
1450 TreeModelColumn<string> name;
1451 TreeModelColumn<bool> enabled;
1452 TreeModelColumn<bool> feedback;
1453 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1456 Glib::RefPtr<ListStore> _store;
1457 ControlSurfacesModelColumns _model;
1459 Gtk::Window& _parent;
1460 PBD::ScopedConnection protocol_status_connection;
1461 uint32_t _ignore_view_change;
1464 class VideoTimelineOptions : public OptionEditorBox
1467 VideoTimelineOptions (RCConfiguration* c)
1469 , _show_video_export_info_button (_("Show Video Export Info before export"))
1470 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1471 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1473 Table* t = manage (new Table (2, 6));
1474 t->set_spacings (4);
1476 t->attach (_video_advanced_setup_button, 0, 2, 0, 1);
1477 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1478 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1479 _("<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."));
1481 Label* l = manage (new Label (_("Video Server URL:")));
1482 l->set_alignment (0, 0.5);
1483 t->attach (*l, 0, 1, 1, 2, FILL);
1484 t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL);
1485 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1486 _("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"));
1488 l = manage (new Label (_("Video Folder:")));
1489 l->set_alignment (0, 0.5);
1490 t->attach (*l, 0, 1, 2, 3, FILL);
1491 t->attach (_video_server_docroot_entry, 1, 2, 2, 3);
1492 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1493 _("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."));
1495 /* small vspace y=3..4 */
1497 t->attach (_show_video_export_info_button, 0, 2, 4, 5);
1498 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1499 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1500 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1502 t->attach (_show_video_server_dialog_button, 0, 2, 5, 6);
1503 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1504 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1505 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1507 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1508 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1509 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1510 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1512 _box->pack_start (*t,true,true);
1515 void server_url_changed ()
1517 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1520 void server_docroot_changed ()
1522 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1525 void show_video_export_info_toggled ()
1527 bool const x = _show_video_export_info_button.get_active ();
1528 _rc_config->set_show_video_export_info (x);
1531 void show_video_server_dialog_toggled ()
1533 bool const x = _show_video_server_dialog_button.get_active ();
1534 _rc_config->set_show_video_server_dialog (x);
1537 void video_advanced_setup_toggled ()
1539 bool const x = _video_advanced_setup_button.get_active ();
1540 _rc_config->set_video_advanced_setup(x);
1543 void parameter_changed (string const & p)
1545 if (p == "video-server-url") {
1546 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1547 } else if (p == "video-server-docroot") {
1548 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1549 } else if (p == "show-video-export-info") {
1550 bool const x = _rc_config->get_show_video_export_info();
1551 _show_video_export_info_button.set_active (x);
1552 } else if (p == "show-video-server-dialog") {
1553 bool const x = _rc_config->get_show_video_server_dialog();
1554 _show_video_server_dialog_button.set_active (x);
1555 } else if (p == "video-advanced-setup") {
1556 bool const x = _rc_config->get_video_advanced_setup();
1557 _video_advanced_setup_button.set_active(x);
1558 _video_server_docroot_entry.set_sensitive(x);
1559 _video_server_url_entry.set_sensitive(x);
1563 void set_state_from_config ()
1565 parameter_changed ("video-server-url");
1566 parameter_changed ("video-server-docroot");
1567 parameter_changed ("video-monitor-setup-dialog");
1568 parameter_changed ("show-video-export-info");
1569 parameter_changed ("show-video-server-dialog");
1570 parameter_changed ("video-advanced-setup");
1574 RCConfiguration* _rc_config;
1575 Entry _video_server_url_entry;
1576 Entry _video_server_docroot_entry;
1577 CheckButton _show_video_export_info_button;
1578 CheckButton _show_video_server_dialog_button;
1579 CheckButton _video_advanced_setup_button;
1582 class PluginOptions : public OptionEditorBox
1585 PluginOptions (RCConfiguration* c, UIConfiguration* uic)
1588 , _display_plugin_scan_progress (_("Always Display Plugin Scan Progress"))
1589 , _discover_vst_on_start (_("Scan for [new] VST Plugins on Application Start"))
1590 , _discover_au_on_start (_("Scan for AudioUnit Plugins on Application Start"))
1591 , _verbose_plugin_scan (_("Verbose Plugin Scan"))
1592 , _timeout_adjustment (0, 0, 3000, 50, 50)
1593 , _timeout_slider (_timeout_adjustment)
1596 std::stringstream ss;
1597 Table* t = manage (new Table (2, 6));
1598 t->set_spacings (4);
1602 ss << "<b>" << _("General") << "</b>";
1603 l = manage (left_aligned_label (ss.str()));
1604 l->set_use_markup (true);
1605 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1606 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1608 b = manage (new Button (_("Scan for Plugins")));
1609 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1610 t->attach (*b, 0, 2, n, n+1, FILL); ++n;
1612 t->attach (_display_plugin_scan_progress, 0, 2, n, n+1); ++n;
1613 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1614 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1615 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
1617 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
1618 _timeout_slider.set_digits (0);
1619 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &PluginOptions::timeout_changed));
1621 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1622 _("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."));
1624 l = manage (left_aligned_label (_("Scan Time Out [deciseconds]")));;
1625 HBox* h = manage (new HBox);
1627 h->pack_start (*l, false, false);
1628 h->pack_start (_timeout_slider, true, true);
1629 t->attach (*h, 0, 2, n, n+1); ++n;
1632 ss << "<b>" << _("VST") << "</b>";
1633 l = manage (left_aligned_label (ss.str()));
1634 l->set_use_markup (true);
1635 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1636 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1638 b = manage (new Button (_("Clear VST Cache")));
1639 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_cache_clicked));
1640 t->attach (*b, 0, 1, n, n+1, FILL);
1642 b = manage (new Button (_("Clear VST Blacklist")));
1643 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_blacklist_clicked));
1644 t->attach (*b, 1, 2, n, n+1, FILL);
1647 t->attach (_discover_vst_on_start, 0, 2, n, n+1); ++n;
1648 _discover_vst_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_vst_on_start_toggled));
1649 Gtkmm2ext::UI::instance()->set_tip (_discover_vst_on_start,
1650 _("<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"));
1652 #ifdef LXVST_SUPPORT
1653 t->attach (*manage (left_aligned_label (_("Linux VST Path:"))), 0, 1, n, n+1);
1654 b = manage (new Button (_("Edit")));
1655 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_lxvst_path_clicked));
1656 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1659 #ifdef WINDOWS_VST_SUPPORT
1660 t->attach (*manage (left_aligned_label (_("Windows VST Path:"))), 0, 1, n, n+1);
1661 b = manage (new Button (_("Edit")));
1662 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_vst_path_clicked));
1663 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1665 // currently verbose logging is only implemented for Windows VST.
1666 t->attach (_verbose_plugin_scan, 0, 2, n, n+1); ++n;
1667 _verbose_plugin_scan.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::verbose_plugin_scan_toggled));
1668 Gtkmm2ext::UI::instance()->set_tip (_verbose_plugin_scan,
1669 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
1673 #ifdef AUDIOUNIT_SUPPORT
1675 ss << "<b>" << _("Audio Unit") << "</b>";
1676 l = manage (left_aligned_label (ss.str()));
1677 l->set_use_markup (true);
1678 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1679 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1681 t->attach (_discover_au_on_start, 0, 2, n, n+1); ++n;
1682 _discover_au_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_au_on_start_toggled));
1683 Gtkmm2ext::UI::instance()->set_tip (_discover_au_on_start,
1684 _("<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."));
1687 b = manage (new Button (_("Clear AU Cache")));
1688 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_cache_clicked));
1689 t->attach (*b, 0, 1, n, n+1, FILL);
1691 b = manage (new Button (_("Clear AU Blacklist")));
1692 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_blacklist_clicked));
1693 t->attach (*b, 1, 2, n, n+1, FILL);
1697 _box->pack_start (*t,true,true);
1700 void parameter_changed (string const & p) {
1701 if (p == "show-plugin-scan-window") {
1702 bool const x = _ui_config->get_show_plugin_scan_window();
1703 _display_plugin_scan_progress.set_active (x);
1705 else if (p == "discover-vst-on-start") {
1706 bool const x = _rc_config->get_discover_vst_on_start();
1707 _discover_vst_on_start.set_active (x);
1709 else if (p == "vst-scan-timeout") {
1710 int const x = _rc_config->get_vst_scan_timeout();
1711 _timeout_adjustment.set_value (x);
1713 else if (p == "discover-audio-units") {
1714 bool const x = _rc_config->get_discover_audio_units();
1715 _discover_au_on_start.set_active (x);
1717 else if (p == "verbose-plugin-scan") {
1718 bool const x = _rc_config->get_verbose_plugin_scan();
1719 _verbose_plugin_scan.set_active (x);
1723 void set_state_from_config () {
1724 parameter_changed ("show-plugin-scan-window");
1725 parameter_changed ("discover-vst-on-start");
1726 parameter_changed ("vst-scan-timeout");
1727 parameter_changed ("discover-audio-units");
1728 parameter_changed ("verbose-plugin-scan");
1732 RCConfiguration* _rc_config;
1733 UIConfiguration* _ui_config;
1734 CheckButton _display_plugin_scan_progress;
1735 CheckButton _discover_vst_on_start;
1736 CheckButton _discover_au_on_start;
1737 CheckButton _verbose_plugin_scan;
1738 Adjustment _timeout_adjustment;
1739 HScale _timeout_slider;
1741 void display_plugin_scan_progress_toggled () {
1742 bool const x = _display_plugin_scan_progress.get_active();
1743 _ui_config->set_show_plugin_scan_window(x);
1746 void discover_vst_on_start_toggled () {
1747 bool const x = _discover_vst_on_start.get_active();
1748 _rc_config->set_discover_vst_on_start(x);
1751 void discover_au_on_start_toggled () {
1752 bool const x = _discover_au_on_start.get_active();
1753 _rc_config->set_discover_audio_units(x);
1756 void verbose_plugin_scan_toggled () {
1757 bool const x = _verbose_plugin_scan.get_active();
1758 _rc_config->set_verbose_plugin_scan(x);
1761 void timeout_changed () {
1762 int x = floor(_timeout_adjustment.get_value());
1763 _rc_config->set_vst_scan_timeout(x);
1766 void clear_vst_cache_clicked () {
1767 PluginManager::instance().clear_vst_cache();
1770 void clear_vst_blacklist_clicked () {
1771 PluginManager::instance().clear_vst_blacklist();
1774 void clear_au_cache_clicked () {
1775 PluginManager::instance().clear_au_cache();
1778 void clear_au_blacklist_clicked () {
1779 PluginManager::instance().clear_au_blacklist();
1783 void edit_vst_path_clicked () {
1784 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1785 _("Set Windows VST Search Path"),
1786 _rc_config->get_plugin_path_vst(),
1787 PluginManager::instance().get_default_windows_vst_path()
1789 ResponseType r = (ResponseType) pd->run ();
1791 if (r == RESPONSE_ACCEPT) {
1792 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
1797 // todo consolidate with edit_vst_path_clicked..
1798 void edit_lxvst_path_clicked () {
1799 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1800 _("Set Linux VST Search Path"),
1801 _rc_config->get_plugin_path_lxvst(),
1802 PluginManager::instance().get_default_lxvst_path()
1804 ResponseType r = (ResponseType) pd->run ();
1806 if (r == RESPONSE_ACCEPT) {
1807 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
1812 void refresh_clicked () {
1813 PluginManager::instance().refresh();
1818 /** A class which allows control of visibility of some editor components usign
1819 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1820 * which has the correct members, but with null widget pointers. This
1821 * class allows the user to set visibility of the members, the details
1822 * of which are stored in a configuration variable which can be watched
1823 * by parts of the editor that actually contain the widgets whose visibility
1824 * is being controlled.
1827 class VisibilityOption : public Option
1830 /** @param name User-visible name for this group.
1831 * @param g `Dummy' VisibilityGroup (as described above).
1832 * @param get Method to get the value of the appropriate configuration variable.
1833 * @param set Method to set the value of the appropriate configuration variable.
1835 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1836 : Option (g->get_state_name(), name)
1838 , _visibility_group (g)
1842 /* Watch for changes made by the user to our members */
1843 _visibility_group->VisibilityChanged.connect_same_thread (
1844 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1848 void set_state_from_config ()
1850 /* Set our state from the current configuration */
1851 _visibility_group->set_state (_get ());
1854 void add_to_page (OptionEditorPage* p)
1856 _heading.add_to_page (p);
1857 add_widget_to_page (p, _visibility_group->list_view ());
1860 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1865 /* The user has changed something, so reflect this change
1866 in the RCConfiguration.
1868 _set (_visibility_group->get_state_value ());
1871 OptionEditorHeading _heading;
1872 VisibilityGroup* _visibility_group;
1873 sigc::slot<std::string> _get;
1874 sigc::slot<bool, std::string> _set;
1875 PBD::ScopedConnection _visibility_group_connection;
1880 RCOptionEditor::RCOptionEditor ()
1881 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1882 , _rc_config (Config)
1883 , _ui_config (ARDOUR_UI::config())
1884 , _mixer_strip_visibility ("mixer-element-visibility")
1888 uint32_t hwcpus = hardware_concurrency ();
1890 BoolComboOption* bco;
1893 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1895 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1897 _("Signal processing uses"),
1898 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1899 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1902 procs->add (-1, _("all but one processor"));
1903 procs->add (0, _("all available processors"));
1905 for (uint32_t i = 1; i <= hwcpus; ++i) {
1906 procs->add (i, string_compose (_("%1 processors"), i));
1909 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1911 add_option (_("Misc"), procs);
1914 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1916 add_option (_("Misc"), new UndoOptions (_rc_config));
1918 add_option (_("Misc"),
1920 "verify-remove-last-capture",
1921 _("Verify removal of last capture"),
1922 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1923 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1926 add_option (_("Misc"),
1928 "periodic-safety-backups",
1929 _("Make periodic backups of the session file"),
1930 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1931 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1934 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1936 add_option (_("Misc"),
1938 "only-copy-imported-files",
1939 _("Always copy imported files"),
1940 sigc::mem_fun (*_ui_config, &UIConfiguration::get_only_copy_imported_files),
1941 sigc::mem_fun (*_ui_config, &UIConfiguration::set_only_copy_imported_files)
1944 add_option (_("Misc"), new DirectoryOption (
1945 X_("default-session-parent-dir"),
1946 _("Default folder for new sessions:"),
1947 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1948 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1951 add_option (_("Misc"),
1952 new SpinOption<uint32_t> (
1953 "max-recent-sessions",
1954 _("Maximum number of recent sessions"),
1955 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1956 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1960 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1962 add_option (_("Misc"), new ClickOptions (_rc_config, this));
1964 add_option (_("Misc"),
1967 _("Click gain level"),
1968 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1969 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1972 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1974 add_option (_("Misc"),
1975 new SpinOption<double> (
1976 "automation-thinning-factor",
1977 _("Thinning factor (larger value => less data)"),
1978 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1979 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1983 add_option (_("Misc"),
1984 new SpinOption<double> (
1985 "automation-interval-msecs",
1986 _("Automation sampling interval (milliseconds)"),
1987 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1988 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1994 add_option (_("Transport"), new OptionEditorHeading (S_("Playhead Behaviour")));
1995 add_option (_("Transport"), new AutoReturnTargetOptions (_rc_config, this));
1996 add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options")));
2000 tsf = new BoolOption (
2001 "latched-record-enable",
2002 _("Keep record-enable engaged on stop"),
2003 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
2004 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
2006 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
2007 add_option (_("Transport"), tsf);
2009 tsf = new BoolOption (
2011 _("Play loop is a transport mode"),
2012 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
2013 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
2015 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2016 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
2017 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
2018 add_option (_("Transport"), tsf);
2020 tsf = new BoolOption (
2021 "stop-recording-on-xrun",
2022 _("Stop recording when an xrun occurs"),
2023 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
2024 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
2026 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2027 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
2029 add_option (_("Transport"), tsf);
2031 tsf = new BoolOption (
2032 "create-xrun-marker",
2033 _("Create markers where xruns occur"),
2034 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
2035 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
2037 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
2038 add_option (_("Transport"), tsf);
2040 tsf = new BoolOption (
2041 "stop-at-session-end",
2042 _("Stop at the end of the session"),
2043 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
2044 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
2046 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2047 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
2048 "when it reaches the current session end marker\n\n"
2049 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
2051 add_option (_("Transport"), tsf);
2053 tsf = new BoolOption (
2055 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
2056 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
2057 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
2059 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2060 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
2061 "preventing any need to do a transport locate at the end of the loop\n\n"
2062 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
2063 "which will often cause a small click or delay"), PROGRAM_NAME));
2064 add_option (_("Transport"), tsf);
2066 tsf = new BoolOption (
2067 "disable-disarm-during-roll",
2068 _("Disable per-track record disarm while rolling"),
2069 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
2070 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
2072 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"));
2073 add_option (_("Transport"), tsf);
2075 tsf = new BoolOption (
2077 _("12dB gain reduction during fast-forward and fast-rewind"),
2078 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
2079 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
2081 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
2082 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
2083 add_option (_("Transport"), tsf);
2085 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
2087 _sync_source = new ComboOption<SyncSource> (
2089 _("External timecode source"),
2090 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
2091 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
2094 add_option (_("Transport"), _sync_source);
2096 _sync_framerate = new BoolOption (
2097 "timecode-sync-frame-rate",
2098 _("Match session video frame rate to external timecode"),
2099 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
2100 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
2102 Gtkmm2ext::UI::instance()->set_tip
2103 (_sync_framerate->tip_widget(),
2104 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
2105 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
2106 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
2107 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
2108 "timecode standard and the session standard."), PROGRAM_NAME));
2110 add_option (_("Transport"), _sync_framerate);
2112 _sync_genlock = new BoolOption (
2113 "timecode-source-is-synced",
2114 _("Sync-lock timecode to clock (disable drift compensation)"),
2115 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
2116 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
2118 Gtkmm2ext::UI::instance()->set_tip
2119 (_sync_genlock->tip_widget(),
2120 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
2121 "Sync Lock indicates that the selected external timecode source shares clock-sync "
2122 "(Black & Burst, Wordclock, etc) with the audio interface. "
2123 "This option disables drift compensation. The transport speed is fixed at 1.0. "
2124 "Vari-speed LTC will be ignored and cause drift."
2126 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
2127 "timecode sources shares clock sync."
2131 add_option (_("Transport"), _sync_genlock);
2133 _sync_source_2997 = new BoolOption (
2134 "timecode-source-2997",
2135 _("Lock to 29.9700 fps instead of 30000/1001"),
2136 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
2137 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
2139 Gtkmm2ext::UI::instance()->set_tip
2140 (_sync_source_2997->tip_widget(),
2141 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
2142 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
2143 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
2144 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
2145 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
2146 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
2149 add_option (_("Transport"), _sync_source_2997);
2151 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
2153 _ltc_port = new ComboStringOption (
2155 _("LTC incoming port"),
2156 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
2157 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
2160 vector<string> physical_inputs;
2161 physical_inputs.push_back (_("None"));
2162 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
2163 _ltc_port->set_popdown_strings (physical_inputs);
2165 populate_sync_options ();
2167 add_option (_("Transport"), _ltc_port);
2169 // TODO; rather disable this button than not compile it..
2170 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
2172 add_option (_("Transport"),
2175 _("Enable LTC generator"),
2176 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
2177 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
2180 _ltc_send_continuously = new BoolOption (
2181 "ltc-send-continuously",
2182 _("Send LTC while stopped"),
2183 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
2184 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
2186 Gtkmm2ext::UI::instance()->set_tip
2187 (_ltc_send_continuously->tip_widget(),
2188 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
2189 add_option (_("Transport"), _ltc_send_continuously);
2191 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
2192 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
2193 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
2194 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
2196 Gtkmm2ext::UI::instance()->set_tip
2197 (_ltc_volume_slider->tip_widget(),
2198 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
2200 add_option (_("Transport"), _ltc_volume_slider);
2201 parameter_changed ("send-ltc");
2203 parameter_changed ("sync-source");
2207 add_option (S_("Editor"),
2209 "draggable-playhead",
2210 _("Allow dragging of playhead"),
2211 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_draggable_playhead),
2212 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_draggable_playhead)
2215 add_option (_("Editor"),
2217 "automation-follows-regions",
2218 _("Move relevant automation when audio regions are moved"),
2219 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2220 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2223 add_option (_("Editor"),
2225 "show-track-meters",
2226 _("Show meters on tracks in the editor"),
2227 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_track_meters),
2228 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_track_meters)
2231 add_option (_("Editor"),
2233 "show-editor-meter",
2234 _("Display master-meter in the toolbar"),
2235 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_editor_meter),
2236 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_editor_meter)
2239 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2240 "default-fade-shape",
2241 _("Default fade shape"),
2242 sigc::mem_fun (*_rc_config,
2243 &RCConfiguration::get_default_fade_shape),
2244 sigc::mem_fun (*_rc_config,
2245 &RCConfiguration::set_default_fade_shape)
2248 fadeshape->add (FadeLinear,
2249 _("Linear (for highly correlated material)"));
2250 fadeshape->add (FadeConstantPower, _("Constant power"));
2251 fadeshape->add (FadeSymmetric, _("Symmetric"));
2252 fadeshape->add (FadeSlow, _("Slow"));
2253 fadeshape->add (FadeFast, _("Fast"));
2255 add_option (_("Editor"), fadeshape);
2258 bco = new BoolComboOption (
2259 "use-overlap-equivalency",
2260 _("Regions in active edit groups are edited together"),
2261 _("whenever they overlap in time"),
2262 _("only if they have identical length, position and origin"),
2263 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2264 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2267 add_option (_("Editor"), bco);
2269 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2271 _("Layering model"),
2272 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2273 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2276 lm->add (LaterHigher, _("later is higher"));
2277 lm->add (Manual, _("manual layering"));
2278 add_option (_("Editor"), lm);
2280 add_option (_("Editor"),
2282 "rubberbanding-snaps-to-grid",
2283 _("Make rubberband selection rectangle snap to the grid"),
2284 sigc::mem_fun (*_ui_config, &UIConfiguration::get_rubberbanding_snaps_to_grid),
2285 sigc::mem_fun (*_ui_config, &UIConfiguration::set_rubberbanding_snaps_to_grid)
2288 add_option (_("Editor"),
2291 _("Show waveforms in regions"),
2292 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms),
2293 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms)
2296 add_option (_("Editor"),
2297 new BoolComboOption (
2298 "show-region-gain-envelopes",
2299 _("Show gain envelopes in audio regions"),
2301 _("only in Draw and Internal Edit modes"),
2302 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_region_gain),
2303 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_region_gain)
2306 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
2308 _("Waveform scale"),
2309 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_scale),
2310 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_scale)
2313 wfs->add (Linear, _("linear"));
2314 wfs->add (Logarithmic, _("logarithmic"));
2316 add_option (_("Editor"), wfs);
2318 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
2320 _("Waveform shape"),
2321 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_shape),
2322 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_shape)
2325 wfsh->add (Traditional, _("traditional"));
2326 wfsh->add (Rectified, _("rectified"));
2328 add_option (_("Editor"), wfsh);
2330 add_option (_("Editor"), new ClipLevelOptions (_ui_config));
2332 add_option (_("Editor"),
2334 "show-waveforms-while-recording",
2335 _("Show waveforms for audio while it is being recorded"),
2336 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms_while_recording),
2337 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms_while_recording)
2340 add_option (_("Editor"),
2343 _("Show zoom toolbar"),
2344 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_zoom_tools),
2345 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_zoom_tools)
2348 add_option (_("Editor"),
2350 "update-editor-during-summary-drag",
2351 _("Update editor window during drags of the summary"),
2352 sigc::mem_fun (*_ui_config, &UIConfiguration::get_update_editor_during_summary_drag),
2353 sigc::mem_fun (*_ui_config, &UIConfiguration::set_update_editor_during_summary_drag)
2356 bo = new BoolOption (
2358 _("Name new markers"),
2359 sigc::mem_fun (*_ui_config, &UIConfiguration::get_name_new_markers),
2360 sigc::mem_fun (*_ui_config, &UIConfiguration::set_name_new_markers)
2363 add_option (_("Editor"), bo);
2364 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."
2365 "\n\nYou can always rename markers by right-clicking on them"));
2367 add_option (_("Editor"),
2369 "autoscroll-editor",
2370 _("Auto-scroll editor window when dragging near its edges"),
2371 sigc::mem_fun (*_ui_config, &UIConfiguration::get_autoscroll_editor),
2372 sigc::mem_fun (*_ui_config, &UIConfiguration::set_autoscroll_editor)
2375 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2376 "region-selection-after-split",
2377 _("After splitting selected regions, select"),
2378 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2379 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2381 // TODO: decide which of these modes are really useful
2382 rsas->add(None, _("no regions"));
2383 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2384 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2385 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2386 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2387 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2388 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2389 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2391 add_option (_("Editor"), rsas);
2396 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2398 add_option (_("Audio"), new BufferingOptions (_rc_config));
2400 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2402 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2404 _("Record monitoring handled by"),
2405 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2406 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2409 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2410 mm->add (HardwareMonitoring, _("via Audio Driver"));
2413 string prog (PROGRAM_NAME);
2414 boost::algorithm::to_lower (prog);
2415 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2416 mm->add (ExternalMonitoring, _("audio hardware"));
2418 add_option (_("Audio"), mm);
2420 add_option (_("Audio"),
2422 "tape-machine-mode",
2423 _("Tape machine mode"),
2424 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2425 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2428 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
2430 add_option (_("Audio"),
2432 "auto-connect-standard-busses",
2433 _("Auto-connect master/monitor busses"),
2434 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2435 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2438 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2439 "input-auto-connect",
2440 _("Connect track inputs"),
2441 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2442 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2445 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2446 iac->add (ManualConnect, _("manually"));
2448 add_option (_("Audio"), iac);
2450 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2451 "output-auto-connect",
2452 _("Connect track and bus outputs"),
2453 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2454 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2457 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2458 oac->add (AutoConnectMaster, _("automatically to master bus"));
2459 oac->add (ManualConnect, _("manually"));
2461 add_option (_("Audio"), oac);
2463 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2465 add_option (_("Audio"),
2467 "denormal-protection",
2468 _("Use DC bias to protect against denormals"),
2469 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2470 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2473 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2475 _("Processor handling"),
2476 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2477 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2481 dm->add (DenormalNone, _("no processor handling"));
2483 FPU* fpu = FPU::instance();
2485 if (fpu->has_flush_to_zero()) {
2487 dm->add (DenormalFTZ, _("use FlushToZero"));
2488 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2489 _rc_config->set_denormal_model(DenormalNone);
2492 if (fpu->has_denormals_are_zero()) {
2494 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2495 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2496 _rc_config->set_denormal_model(DenormalNone);
2499 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2501 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2502 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2503 _rc_config->set_denormal_model(DenormalNone);
2507 dm->set_sensitive(false);
2510 add_option (_("Audio"), dm);
2512 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
2514 add_option (_("Audio"),
2516 "plugins-stop-with-transport",
2517 _("Silence plugins when the transport is stopped"),
2518 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
2519 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
2522 add_option (_("Audio"),
2524 "new-plugins-active",
2525 _("Make new plugins active"),
2526 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
2527 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
2530 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2532 add_option (_("Audio"),
2534 "auto-analyse-audio",
2535 _("Enable automatic analysis of audio"),
2536 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2537 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2540 add_option (_("Audio"),
2542 "replicate-missing-region-channels",
2543 _("Replicate missing region channels"),
2544 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2545 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2550 add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
2552 add_option (_("Solo / mute"),
2555 _("Solo-in-place mute cut (dB)"),
2556 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2557 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2560 _solo_control_is_listen_control = new BoolOption (
2561 "solo-control-is-listen-control",
2562 _("Solo controls are Listen controls"),
2563 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2564 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2567 add_option (_("Solo / mute"), _solo_control_is_listen_control);
2569 _listen_position = new ComboOption<ListenPosition> (
2571 _("Listen Position"),
2572 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2573 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2576 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2577 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2579 add_option (_("Solo / mute"), _listen_position);
2581 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2583 _("PFL signals come from"),
2584 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2585 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2588 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2589 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2591 add_option (_("Solo / mute"), pp);
2593 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2595 _("AFL signals come from"),
2596 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2597 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2600 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2601 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2603 add_option (_("Solo / mute"), pa);
2605 parameter_changed ("use-monitor-bus");
2607 add_option (_("Solo / mute"),
2610 _("Exclusive solo"),
2611 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2612 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2615 add_option (_("Solo / mute"),
2618 _("Show solo muting"),
2619 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2620 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2623 add_option (_("Solo / mute"),
2625 "solo-mute-override",
2626 _("Soloing overrides muting"),
2627 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2628 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2631 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
2633 add_option (_("Solo / mute"),
2635 "mute-affects-pre-fader",
2636 _("Mute affects pre-fader sends"),
2637 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2638 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2641 add_option (_("Solo / mute"),
2643 "mute-affects-post-fader",
2644 _("Mute affects post-fader sends"),
2645 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2646 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2649 add_option (_("Solo / mute"),
2651 "mute-affects-control-outs",
2652 _("Mute affects control outputs"),
2653 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2654 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2657 add_option (_("Solo / mute"),
2659 "mute-affects-main-outs",
2660 _("Mute affects main outputs"),
2661 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2662 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2665 add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
2667 add_option (_("Solo / mute"),
2669 "link-send-and-route-panner",
2670 _("Link panners of Aux and External Sends with main panner by default"),
2671 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2672 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2675 add_option (_("MIDI"),
2676 new SpinOption<float> (
2678 _("MIDI read-ahead time (seconds)"),
2679 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2680 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2685 add_option (_("MIDI"),
2688 _("Send MIDI Clock"),
2689 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2690 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2693 add_option (_("MIDI"),
2696 _("Send MIDI Time Code"),
2697 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2698 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2701 add_option (_("MIDI"),
2702 new SpinOption<int> (
2703 "mtc-qf-speed-tolerance",
2704 _("Percentage either side of normal transport speed to transmit MTC"),
2705 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2706 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2710 add_option (_("MIDI"),
2713 _("Obey MIDI Machine Control commands"),
2714 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2715 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2718 add_option (_("MIDI"),
2721 _("Send MIDI Machine Control commands"),
2722 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2723 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2726 add_option (_("MIDI"),
2729 _("Send MIDI control feedback"),
2730 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2731 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2734 add_option (_("MIDI"),
2735 new SpinOption<uint8_t> (
2736 "mmc-receive-device-id",
2737 _("Inbound MMC device ID"),
2738 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2739 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2743 add_option (_("MIDI"),
2744 new SpinOption<uint8_t> (
2745 "mmc-send-device-id",
2746 _("Outbound MMC device ID"),
2747 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2748 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2752 add_option (_("MIDI"),
2753 new SpinOption<int32_t> (
2754 "initial-program-change",
2755 _("Initial program change"),
2756 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2757 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2761 add_option (_("MIDI"),
2763 "display-first-midi-bank-as-zero",
2764 _("Display first MIDI bank/program as 0"),
2765 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2766 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2769 add_option (_("MIDI"),
2771 "never-display-periodic-midi",
2772 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2773 sigc::mem_fun (*_ui_config, &UIConfiguration::get_never_display_periodic_midi),
2774 sigc::mem_fun (*_ui_config, &UIConfiguration::set_never_display_periodic_midi)
2777 add_option (_("MIDI"),
2780 _("Sound MIDI notes as they are selected"),
2781 sigc::mem_fun (*_ui_config, &UIConfiguration::get_sound_midi_notes),
2782 sigc::mem_fun (*_ui_config, &UIConfiguration::set_sound_midi_notes)
2785 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2787 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2788 "midi-audition-synth-uri",
2789 _("Midi Audition Synth (LV2)"),
2790 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2791 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2794 audition_synth->add(X_(""), _("None"));
2795 PluginInfoList all_plugs;
2796 PluginManager& manager (PluginManager::instance());
2798 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2800 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2801 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2802 if (!(*i)->is_instrument()) continue;
2803 if ((*i)->type != ARDOUR::LV2) continue;
2804 audition_synth->add((*i)->unique_id, (*i)->name);
2808 add_option (_("MIDI"), audition_synth);
2810 /* USER INTERACTION */
2813 #ifdef PLATFORM_WINDOWS
2816 getenv ("ARDOUR_BUNDLED")
2820 add_option (_("User interaction"),
2822 "enable-translation",
2823 string_compose (_("Use translations of %1 messages\n"
2824 " <i>(requires a restart of %1 to take effect)</i>\n"
2825 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2826 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2827 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2830 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2832 add_option (_("User interaction"), new KeyboardOptions);
2834 /* Control Surfaces */
2836 add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
2838 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2840 _("Control surface remote ID"),
2841 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2842 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2845 rm->add (UserOrdered, _("assigned by user"));
2846 rm->add (MixerOrdered, _("follows order of mixer"));
2848 add_option (_("Control Surfaces"), rm);
2850 /* VIDEO Timeline */
2851 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2853 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2854 /* Plugin options (currrently VST only) */
2855 add_option (_("Plugins"), new PluginOptions (_rc_config, _ui_config));
2860 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
2861 BoolOption* bgo = new BoolOption (
2863 _("Possibly improve slow graphical performance"),
2864 sigc::mem_fun (*_ui_config, &UIConfiguration::get_buggy_gradients),
2865 sigc::mem_fun (*_ui_config, &UIConfiguration::set_buggy_gradients)
2868 Gtkmm2ext::UI::instance()->set_tip (bgo->tip_widget(), string_compose (_("This requires restarting %1 before having an effect"), PROGRAM_NAME));
2869 add_option (S_("Preferences|GUI"), bgo);
2872 add_option (S_("Preferences|GUI"),
2875 _("Graphically indicate mouse pointer hovering over various widgets"),
2876 sigc::mem_fun (*_ui_config, &UIConfiguration::get_widget_prelight),
2877 sigc::mem_fun (*_ui_config, &UIConfiguration::set_widget_prelight)
2880 #ifdef TOOLTIPS_GOT_FIXED
2881 add_option (S_("Preferences|GUI"),
2884 _("Show tooltips if mouse hovers over a control"),
2885 sigc::mem_fun (*_ui_config, &UIConfiguration::get_use_tooltips),
2886 sigc::mem_fun (*_ui_config, &UIConfiguration::set_use_tooltips)
2890 add_option (S_("Preferences|GUI"),
2892 "show-name-highlight",
2893 _("Use name highlight bars in region displays (requires a restart)"),
2894 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_name_highlight),
2895 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_name_highlight)
2899 /* font scaling does nothing with GDK/Quartz */
2900 add_option (S_("Preferences|GUI"), new FontScalingOptions (_ui_config));
2903 add_option (S_("GUI"),
2905 "super-rapid-clock-update",
2906 _("update transport clock display at FPS instead of every 100ms"),
2907 sigc::mem_fun (*_ui_config, &UIConfiguration::get_super_rapid_clock_update),
2908 sigc::mem_fun (*_ui_config, &UIConfiguration::set_super_rapid_clock_update)
2912 /* Image cache size */
2914 Gtk::Adjustment *ics = manage (new Gtk::Adjustment(0, 1, 1024, 10)); /* 1 MB to 1GB in steps of 10MB */
2915 HSliderOption *sics = new HSliderOption("waveform-cache-size",
2916 _("Waveform image cache size (megabytes)"),
2918 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_waveform_cache_size),
2919 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_waveform_cache_size)
2921 sics->scale().set_digits (0);
2922 Gtkmm2ext::UI::instance()->set_tip
2923 (sics->tip_widget(),
2924 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
2925 add_option (S_("Preferences|GUI"), sics);
2927 /* Lock GUI timeout */
2929 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
2930 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2931 _("Lock timeout (seconds)"),
2933 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_lock_gui_after_seconds),
2934 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_lock_gui_after_seconds)
2936 slts->scale().set_digits (0);
2937 Gtkmm2ext::UI::instance()->set_tip
2938 (slts->tip_widget(),
2939 _("Lock GUI after this many idle seconds (zero to never lock)"));
2940 add_option (S_("Preferences|GUI"), slts);
2942 /* The names of these controls must be the same as those given in MixerStrip
2943 for the actual widgets being controlled.
2945 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
2946 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2947 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
2948 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
2949 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
2950 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2953 S_("Preferences|GUI"),
2954 new VisibilityOption (
2956 &_mixer_strip_visibility,
2957 sigc::mem_fun (*_ui_config, &UIConfiguration::get_mixer_strip_visibility),
2958 sigc::mem_fun (*_ui_config, &UIConfiguration::set_mixer_strip_visibility)
2962 add_option (S_("Preferences|GUI"),
2964 "default-narrow_ms",
2965 _("Use narrow strips in the mixer by default"),
2966 sigc::mem_fun (*_ui_config, &UIConfiguration::get_default_narrow_ms),
2967 sigc::mem_fun (*_ui_config, &UIConfiguration::set_default_narrow_ms)
2970 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2972 ComboOption<float>* mht = new ComboOption<float> (
2974 _("Peak hold time"),
2975 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_hold),
2976 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_hold)
2979 mht->add (MeterHoldOff, _("off"));
2980 mht->add (MeterHoldShort, _("short"));
2981 mht->add (MeterHoldMedium, _("medium"));
2982 mht->add (MeterHoldLong, _("long"));
2984 add_option (S_("Preferences|Metering"), mht);
2986 ComboOption<float>* mfo = new ComboOption<float> (
2989 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2990 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2993 mfo->add (METER_FALLOFF_OFF, _("off"));
2994 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2995 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2996 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
2997 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2998 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
2999 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
3001 add_option (S_("Preferences|Metering"), mfo);
3003 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
3004 "meter-line-up-level",
3005 _("Meter line-up level; 0dBu"),
3006 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_level),
3007 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_level)
3010 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3011 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3012 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3013 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3015 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."));
3017 add_option (S_("Preferences|Metering"), mlu);
3019 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
3020 "meter-line-up-din",
3021 _("IEC1/DIN Meter line-up level; 0dBu"),
3022 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_din),
3023 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_din)
3026 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3027 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3028 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3029 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3031 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
3033 add_option (S_("Preferences|Metering"), mld);
3035 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
3036 "meter-vu-standard",
3037 _("VU Meter standard"),
3038 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_vu_standard),
3039 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_vu_standard)
3042 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
3043 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
3044 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
3045 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
3047 add_option (S_("Preferences|Metering"), mvu);
3049 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
3050 HSliderOption *mpks = new HSliderOption("meter-peak",
3051 _("Peak threshold [dBFS]"),
3053 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_peak),
3054 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_peak)
3058 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
3059 "meter-type-master",
3060 _("Default Meter Type for Master Bus"),
3061 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
3062 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3064 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3065 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3066 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3067 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3068 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3069 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3070 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3071 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3073 add_option (S_("Preferences|Metering"), mtm);
3076 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3078 _("Default Meter Type for Busses"),
3079 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3080 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3082 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3083 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3084 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3085 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3086 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3087 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3088 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3089 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3091 add_option (S_("Preferences|Metering"), mtb);
3093 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3095 _("Default Meter Type for Tracks"),
3096 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3097 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3099 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3100 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3102 add_option (S_("Preferences|Metering"), mtt);
3105 Gtkmm2ext::UI::instance()->set_tip
3106 (mpks->tip_widget(),
3107 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
3109 add_option (S_("Preferences|Metering"), mpks);
3111 add_option (S_("Preferences|Metering"),
3114 _("LED meter style"),
3115 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_style_led),
3116 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_style_led)
3119 /* and now the theme manager */
3121 ThemeManager* tm = manage (new ThemeManager);
3122 add_page (_("Theme"), *tm);
3126 RCOptionEditor::parameter_changed (string const & p)
3128 OptionEditor::parameter_changed (p);
3130 if (p == "use-monitor-bus") {
3131 bool const s = Config->get_use_monitor_bus ();
3133 /* we can't use this if we don't have a monitor bus */
3134 Config->set_solo_control_is_listen_control (false);
3136 _solo_control_is_listen_control->set_sensitive (s);
3137 _listen_position->set_sensitive (s);
3138 } else if (p == "sync-source") {
3139 _sync_source->set_sensitive (true);
3141 _sync_source->set_sensitive (!_session->config.get_external_sync());
3143 switch(Config->get_sync_source()) {
3146 _sync_genlock->set_sensitive (true);
3147 _sync_framerate->set_sensitive (true);
3148 _sync_source_2997->set_sensitive (true);
3151 _sync_genlock->set_sensitive (false);
3152 _sync_framerate->set_sensitive (false);
3153 _sync_source_2997->set_sensitive (false);
3156 } else if (p == "send-ltc") {
3157 bool const s = Config->get_send_ltc ();
3158 _ltc_send_continuously->set_sensitive (s);
3159 _ltc_volume_slider->set_sensitive (s);
3163 void RCOptionEditor::ltc_generator_volume_changed () {
3164 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
3168 RCOptionEditor::populate_sync_options ()
3170 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3172 _sync_source->clear ();
3174 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3175 _sync_source->add (*i, sync_source_to_string (*i));
3178 if (sync_opts.empty()) {
3179 _sync_source->set_sensitive(false);
3181 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3182 _rc_config->set_sync_source(sync_opts.front());