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 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1159 Label* l = manage (new Label (_("Playback (seconds of buffering):")));
1160 l->set_name ("OptionsLabel");
1162 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1163 HBox* h = manage (new HBox);
1165 h->pack_start (*l, false, false);
1166 h->pack_start (_playback_slider, true, true);
1168 _box->pack_start (*h, false, false);
1170 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1172 l = manage (new Label (_("Recording (seconds of buffering):")));
1173 l->set_name ("OptionsLabel");
1175 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1176 h = manage (new HBox);
1178 h->pack_start (*l, false, false);
1179 h->pack_start (_capture_slider, true, true);
1181 _box->pack_start (*h, false, false);
1183 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
1184 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
1187 void parameter_changed (string const & p)
1189 if (p == "playback-buffer-seconds") {
1190 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1191 } else if (p == "capture-buffer-seconds") {
1192 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1196 void set_state_from_config ()
1198 parameter_changed ("playback-buffer-seconds");
1199 parameter_changed ("capture-buffer-seconds");
1204 void playback_changed ()
1206 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
1209 void capture_changed ()
1211 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
1214 RCConfiguration* _rc_config;
1215 Adjustment _playback_adjustment;
1216 Adjustment _capture_adjustment;
1217 HScale _playback_slider;
1218 HScale _capture_slider;
1221 class ControlSurfacesOptions : public OptionEditorBox
1224 ControlSurfacesOptions (Gtk::Window& parent)
1226 , _ignore_view_change (0)
1228 _store = ListStore::create (_model);
1229 _view.set_model (_store);
1230 _view.append_column (_("Control Surface Protocol"), _model.name);
1231 _view.get_column(0)->set_resizable (true);
1232 _view.get_column(0)->set_expand (true);
1233 _view.append_column_editable (_("Enabled"), _model.enabled);
1234 _view.append_column_editable (_("Feedback"), _model.feedback);
1236 _box->pack_start (_view, false, false);
1238 Label* label = manage (new Label);
1239 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
1241 _box->pack_start (*label, false, false);
1244 ControlProtocolManager& m = ControlProtocolManager::instance ();
1245 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1246 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1248 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1249 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1252 void parameter_changed (std::string const &)
1257 void set_state_from_config ()
1261 ControlProtocolManager& m = ControlProtocolManager::instance ();
1262 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1264 if (!(*i)->mandatory) {
1265 TreeModel::Row r = *_store->append ();
1266 r[_model.name] = (*i)->name;
1267 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1268 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
1269 r[_model.protocol_info] = *i;
1276 void protocol_status_changed (ControlProtocolInfo* cpi) {
1278 TreeModel::Children rows = _store->children();
1280 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1281 string n = ((*x)[_model.name]);
1283 if ((*x)[_model.protocol_info] == cpi) {
1284 _ignore_view_change++;
1285 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1286 _ignore_view_change--;
1292 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1294 TreeModel::Row r = *i;
1296 if (_ignore_view_change) {
1300 ControlProtocolInfo* cpi = r[_model.protocol_info];
1305 bool const was_enabled = (cpi->protocol != 0);
1306 bool const is_enabled = r[_model.enabled];
1309 if (was_enabled != is_enabled) {
1312 ControlProtocolManager::instance().activate (*cpi);
1314 ControlProtocolManager::instance().deactivate (*cpi);
1318 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
1319 bool const is_feedback = r[_model.feedback];
1321 if (was_feedback != is_feedback && cpi->protocol) {
1322 cpi->protocol->set_feedback (is_feedback);
1326 void edit_clicked (GdkEventButton* ev)
1328 if (ev->type != GDK_2BUTTON_PRESS) {
1333 ControlProtocolInfo* cpi;
1336 row = *(_view.get_selection()->get_selected());
1337 if (!row[_model.enabled]) {
1340 cpi = row[_model.protocol_info];
1341 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1344 Box* box = (Box*) cpi->protocol->get_gui ();
1348 if (box->get_parent()) {
1349 static_cast<ArdourWindow*>(box->get_parent())->present();
1352 string title = row[_model.name];
1353 /* once created, the window is managed by the surface itself (as ->get_parent())
1354 * Surface's tear_down_gui() is called on session close, when de-activating
1355 * or re-initializing a surface.
1356 * tear_down_gui() hides an deletes the Window if it exists.
1358 ArdourWindow* win = new ArdourWindow (_parent, title);
1359 win->set_title ("Control Protocol Options");
1365 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1369 ControlSurfacesModelColumns ()
1374 add (protocol_info);
1377 TreeModelColumn<string> name;
1378 TreeModelColumn<bool> enabled;
1379 TreeModelColumn<bool> feedback;
1380 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1383 Glib::RefPtr<ListStore> _store;
1384 ControlSurfacesModelColumns _model;
1386 Gtk::Window& _parent;
1387 PBD::ScopedConnection protocol_status_connection;
1388 uint32_t _ignore_view_change;
1391 class VideoTimelineOptions : public OptionEditorBox
1394 VideoTimelineOptions (RCConfiguration* c)
1396 , _show_video_export_info_button (_("Show Video Export Info before export"))
1397 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1398 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1400 Table* t = manage (new Table (2, 6));
1401 t->set_spacings (4);
1403 t->attach (_video_advanced_setup_button, 0, 2, 0, 1);
1404 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1405 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1406 _("<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."));
1408 Label* l = manage (new Label (_("Video Server URL:")));
1409 l->set_alignment (0, 0.5);
1410 t->attach (*l, 0, 1, 1, 2, FILL);
1411 t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL);
1412 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1413 _("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"));
1415 l = manage (new Label (_("Video Folder:")));
1416 l->set_alignment (0, 0.5);
1417 t->attach (*l, 0, 1, 2, 3, FILL);
1418 t->attach (_video_server_docroot_entry, 1, 2, 2, 3);
1419 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1420 _("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."));
1422 /* small vspace y=3..4 */
1424 t->attach (_show_video_export_info_button, 0, 2, 4, 5);
1425 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1426 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1427 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1429 t->attach (_show_video_server_dialog_button, 0, 2, 5, 6);
1430 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1431 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1432 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1434 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1435 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1436 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1437 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1439 _box->pack_start (*t,true,true);
1442 void server_url_changed ()
1444 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1447 void server_docroot_changed ()
1449 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1452 void show_video_export_info_toggled ()
1454 bool const x = _show_video_export_info_button.get_active ();
1455 _rc_config->set_show_video_export_info (x);
1458 void show_video_server_dialog_toggled ()
1460 bool const x = _show_video_server_dialog_button.get_active ();
1461 _rc_config->set_show_video_server_dialog (x);
1464 void video_advanced_setup_toggled ()
1466 bool const x = _video_advanced_setup_button.get_active ();
1467 _rc_config->set_video_advanced_setup(x);
1470 void parameter_changed (string const & p)
1472 if (p == "video-server-url") {
1473 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1474 } else if (p == "video-server-docroot") {
1475 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1476 } else if (p == "show-video-export-info") {
1477 bool const x = _rc_config->get_show_video_export_info();
1478 _show_video_export_info_button.set_active (x);
1479 } else if (p == "show-video-server-dialog") {
1480 bool const x = _rc_config->get_show_video_server_dialog();
1481 _show_video_server_dialog_button.set_active (x);
1482 } else if (p == "video-advanced-setup") {
1483 bool const x = _rc_config->get_video_advanced_setup();
1484 _video_advanced_setup_button.set_active(x);
1485 _video_server_docroot_entry.set_sensitive(x);
1486 _video_server_url_entry.set_sensitive(x);
1490 void set_state_from_config ()
1492 parameter_changed ("video-server-url");
1493 parameter_changed ("video-server-docroot");
1494 parameter_changed ("video-monitor-setup-dialog");
1495 parameter_changed ("show-video-export-info");
1496 parameter_changed ("show-video-server-dialog");
1497 parameter_changed ("video-advanced-setup");
1501 RCConfiguration* _rc_config;
1502 Entry _video_server_url_entry;
1503 Entry _video_server_docroot_entry;
1504 CheckButton _show_video_export_info_button;
1505 CheckButton _show_video_server_dialog_button;
1506 CheckButton _video_advanced_setup_button;
1509 class PluginOptions : public OptionEditorBox
1512 PluginOptions (RCConfiguration* c, UIConfiguration* uic)
1515 , _display_plugin_scan_progress (_("Always Display Plugin Scan Progress"))
1516 , _discover_vst_on_start (_("Scan for [new] VST Plugins on Application Start"))
1517 , _discover_au_on_start (_("Scan for AudioUnit Plugins on Application Start"))
1518 , _verbose_plugin_scan (_("Verbose Plugin Scan"))
1519 , _timeout_adjustment (0, 0, 3000, 50, 50)
1520 , _timeout_slider (_timeout_adjustment)
1523 std::stringstream ss;
1524 Table* t = manage (new Table (2, 6));
1525 t->set_spacings (4);
1529 ss << "<b>" << _("General") << "</b>";
1530 l = manage (left_aligned_label (ss.str()));
1531 l->set_use_markup (true);
1532 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1533 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1535 b = manage (new Button (_("Scan for Plugins")));
1536 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1537 t->attach (*b, 0, 2, n, n+1, FILL); ++n;
1539 t->attach (_display_plugin_scan_progress, 0, 2, n, n+1); ++n;
1540 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1541 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1542 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
1544 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
1545 _timeout_slider.set_digits (0);
1546 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &PluginOptions::timeout_changed));
1548 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1549 _("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."));
1551 l = manage (left_aligned_label (_("Scan Time Out [deciseconds]")));;
1552 HBox* h = manage (new HBox);
1554 h->pack_start (*l, false, false);
1555 h->pack_start (_timeout_slider, true, true);
1556 t->attach (*h, 0, 2, n, n+1); ++n;
1559 ss << "<b>" << _("VST") << "</b>";
1560 l = manage (left_aligned_label (ss.str()));
1561 l->set_use_markup (true);
1562 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1563 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1565 b = manage (new Button (_("Clear VST Cache")));
1566 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_cache_clicked));
1567 t->attach (*b, 0, 1, n, n+1, FILL);
1569 b = manage (new Button (_("Clear VST Blacklist")));
1570 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_blacklist_clicked));
1571 t->attach (*b, 1, 2, n, n+1, FILL);
1574 t->attach (_discover_vst_on_start, 0, 2, n, n+1); ++n;
1575 _discover_vst_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_vst_on_start_toggled));
1576 Gtkmm2ext::UI::instance()->set_tip (_discover_vst_on_start,
1577 _("<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"));
1579 #ifdef LXVST_SUPPORT
1580 t->attach (*manage (left_aligned_label (_("Linux VST Path:"))), 0, 1, n, n+1);
1581 b = manage (new Button (_("Edit")));
1582 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_lxvst_path_clicked));
1583 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1586 #ifdef WINDOWS_VST_SUPPORT
1587 t->attach (*manage (left_aligned_label (_("Windows VST Path:"))), 0, 1, n, n+1);
1588 b = manage (new Button (_("Edit")));
1589 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_vst_path_clicked));
1590 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1592 // currently verbose logging is only implemented for Windows VST.
1593 t->attach (_verbose_plugin_scan, 0, 2, n, n+1); ++n;
1594 _verbose_plugin_scan.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::verbose_plugin_scan_toggled));
1595 Gtkmm2ext::UI::instance()->set_tip (_verbose_plugin_scan,
1596 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
1600 #ifdef AUDIOUNIT_SUPPORT
1602 ss << "<b>" << _("Audio Unit") << "</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 t->attach (_discover_au_on_start, 0, 2, n, n+1); ++n;
1609 _discover_au_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_au_on_start_toggled));
1610 Gtkmm2ext::UI::instance()->set_tip (_discover_au_on_start,
1611 _("<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."));
1614 b = manage (new Button (_("Clear AU Cache")));
1615 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_cache_clicked));
1616 t->attach (*b, 0, 1, n, n+1, FILL);
1618 b = manage (new Button (_("Clear AU Blacklist")));
1619 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_blacklist_clicked));
1620 t->attach (*b, 1, 2, n, n+1, FILL);
1624 _box->pack_start (*t,true,true);
1627 void parameter_changed (string const & p) {
1628 if (p == "show-plugin-scan-window") {
1629 bool const x = _ui_config->get_show_plugin_scan_window();
1630 _display_plugin_scan_progress.set_active (x);
1632 else if (p == "discover-vst-on-start") {
1633 bool const x = _rc_config->get_discover_vst_on_start();
1634 _discover_vst_on_start.set_active (x);
1636 else if (p == "vst-scan-timeout") {
1637 int const x = _rc_config->get_vst_scan_timeout();
1638 _timeout_adjustment.set_value (x);
1640 else if (p == "discover-audio-units") {
1641 bool const x = _rc_config->get_discover_audio_units();
1642 _discover_au_on_start.set_active (x);
1644 else if (p == "verbose-plugin-scan") {
1645 bool const x = _rc_config->get_verbose_plugin_scan();
1646 _verbose_plugin_scan.set_active (x);
1650 void set_state_from_config () {
1651 parameter_changed ("show-plugin-scan-window");
1652 parameter_changed ("discover-vst-on-start");
1653 parameter_changed ("vst-scan-timeout");
1654 parameter_changed ("discover-audio-units");
1655 parameter_changed ("verbose-plugin-scan");
1659 RCConfiguration* _rc_config;
1660 UIConfiguration* _ui_config;
1661 CheckButton _display_plugin_scan_progress;
1662 CheckButton _discover_vst_on_start;
1663 CheckButton _discover_au_on_start;
1664 CheckButton _verbose_plugin_scan;
1665 Adjustment _timeout_adjustment;
1666 HScale _timeout_slider;
1668 void display_plugin_scan_progress_toggled () {
1669 bool const x = _display_plugin_scan_progress.get_active();
1670 _ui_config->set_show_plugin_scan_window(x);
1673 void discover_vst_on_start_toggled () {
1674 bool const x = _discover_vst_on_start.get_active();
1675 _rc_config->set_discover_vst_on_start(x);
1678 void discover_au_on_start_toggled () {
1679 bool const x = _discover_au_on_start.get_active();
1680 _rc_config->set_discover_audio_units(x);
1683 void verbose_plugin_scan_toggled () {
1684 bool const x = _verbose_plugin_scan.get_active();
1685 _rc_config->set_verbose_plugin_scan(x);
1688 void timeout_changed () {
1689 int x = floor(_timeout_adjustment.get_value());
1690 _rc_config->set_vst_scan_timeout(x);
1693 void clear_vst_cache_clicked () {
1694 PluginManager::instance().clear_vst_cache();
1697 void clear_vst_blacklist_clicked () {
1698 PluginManager::instance().clear_vst_blacklist();
1701 void clear_au_cache_clicked () {
1702 PluginManager::instance().clear_au_cache();
1705 void clear_au_blacklist_clicked () {
1706 PluginManager::instance().clear_au_blacklist();
1710 void edit_vst_path_clicked () {
1711 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1712 _("Set Windows VST Search Path"),
1713 _rc_config->get_plugin_path_vst(),
1714 PluginManager::instance().get_default_windows_vst_path()
1716 ResponseType r = (ResponseType) pd->run ();
1718 if (r == RESPONSE_ACCEPT) {
1719 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
1724 // todo consolidate with edit_vst_path_clicked..
1725 void edit_lxvst_path_clicked () {
1726 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1727 _("Set Linux VST Search Path"),
1728 _rc_config->get_plugin_path_lxvst(),
1729 PluginManager::instance().get_default_lxvst_path()
1731 ResponseType r = (ResponseType) pd->run ();
1733 if (r == RESPONSE_ACCEPT) {
1734 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
1739 void refresh_clicked () {
1740 PluginManager::instance().refresh();
1745 /** A class which allows control of visibility of some editor components usign
1746 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1747 * which has the correct members, but with null widget pointers. This
1748 * class allows the user to set visibility of the members, the details
1749 * of which are stored in a configuration variable which can be watched
1750 * by parts of the editor that actually contain the widgets whose visibility
1751 * is being controlled.
1754 class VisibilityOption : public Option
1757 /** @param name User-visible name for this group.
1758 * @param g `Dummy' VisibilityGroup (as described above).
1759 * @param get Method to get the value of the appropriate configuration variable.
1760 * @param set Method to set the value of the appropriate configuration variable.
1762 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1763 : Option (g->get_state_name(), name)
1765 , _visibility_group (g)
1769 /* Watch for changes made by the user to our members */
1770 _visibility_group->VisibilityChanged.connect_same_thread (
1771 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1775 void set_state_from_config ()
1777 /* Set our state from the current configuration */
1778 _visibility_group->set_state (_get ());
1781 void add_to_page (OptionEditorPage* p)
1783 _heading.add_to_page (p);
1784 add_widget_to_page (p, _visibility_group->list_view ());
1787 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1792 /* The user has changed something, so reflect this change
1793 in the RCConfiguration.
1795 _set (_visibility_group->get_state_value ());
1798 OptionEditorHeading _heading;
1799 VisibilityGroup* _visibility_group;
1800 sigc::slot<std::string> _get;
1801 sigc::slot<bool, std::string> _set;
1802 PBD::ScopedConnection _visibility_group_connection;
1807 RCOptionEditor::RCOptionEditor ()
1808 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1809 , _rc_config (Config)
1810 , _ui_config (ARDOUR_UI::config())
1811 , _mixer_strip_visibility ("mixer-element-visibility")
1815 uint32_t hwcpus = hardware_concurrency ();
1817 BoolComboOption* bco;
1820 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1822 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1824 _("Signal processing uses"),
1825 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1826 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1829 procs->add (-1, _("all but one processor"));
1830 procs->add (0, _("all available processors"));
1832 for (uint32_t i = 1; i <= hwcpus; ++i) {
1833 procs->add (i, string_compose (_("%1 processors"), i));
1836 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1838 add_option (_("Misc"), procs);
1841 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1843 add_option (_("Misc"), new UndoOptions (_rc_config));
1845 add_option (_("Misc"),
1847 "verify-remove-last-capture",
1848 _("Verify removal of last capture"),
1849 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1850 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1853 add_option (_("Misc"),
1855 "periodic-safety-backups",
1856 _("Make periodic backups of the session file"),
1857 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1858 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1861 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1863 add_option (_("Misc"),
1865 "only-copy-imported-files",
1866 _("Always copy imported files"),
1867 sigc::mem_fun (*_ui_config, &UIConfiguration::get_only_copy_imported_files),
1868 sigc::mem_fun (*_ui_config, &UIConfiguration::set_only_copy_imported_files)
1871 add_option (_("Misc"), new DirectoryOption (
1872 X_("default-session-parent-dir"),
1873 _("Default folder for new sessions:"),
1874 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1875 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1878 add_option (_("Misc"),
1879 new SpinOption<uint32_t> (
1880 "max-recent-sessions",
1881 _("Maximum number of recent sessions"),
1882 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1883 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1887 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1889 add_option (_("Misc"), new ClickOptions (_rc_config, this));
1891 add_option (_("Misc"),
1894 _("Click gain level"),
1895 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1896 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1899 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1901 add_option (_("Misc"),
1902 new SpinOption<double> (
1903 "automation-thinning-factor",
1904 _("Thinning factor (larger value => less data)"),
1905 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1906 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1910 add_option (_("Misc"),
1911 new SpinOption<double> (
1912 "automation-interval-msecs",
1913 _("Automation sampling interval (milliseconds)"),
1914 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1915 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1921 add_option (_("Transport"), new OptionEditorHeading (S_("Playhead Behaviour")));
1922 add_option (_("Transport"), new AutoReturnTargetOptions (_rc_config, this));
1923 add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options")));
1927 tsf = new BoolOption (
1928 "latched-record-enable",
1929 _("Keep record-enable engaged on stop"),
1930 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1931 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1933 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1934 add_option (_("Transport"), tsf);
1936 tsf = new BoolOption (
1938 _("Play loop is a transport mode"),
1939 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1940 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1942 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1943 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1944 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1945 add_option (_("Transport"), tsf);
1947 tsf = new BoolOption (
1948 "stop-recording-on-xrun",
1949 _("Stop recording when an xrun occurs"),
1950 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1951 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1953 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1954 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
1956 add_option (_("Transport"), tsf);
1958 tsf = new BoolOption (
1959 "create-xrun-marker",
1960 _("Create markers where xruns occur"),
1961 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
1962 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
1964 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1965 add_option (_("Transport"), tsf);
1967 tsf = new BoolOption (
1968 "stop-at-session-end",
1969 _("Stop at the end of the session"),
1970 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
1971 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
1973 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1974 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
1975 "when it reaches the current session end marker\n\n"
1976 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
1978 add_option (_("Transport"), tsf);
1980 tsf = new BoolOption (
1982 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
1983 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
1984 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
1986 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1987 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
1988 "preventing any need to do a transport locate at the end of the loop\n\n"
1989 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
1990 "which will often cause a small click or delay"), PROGRAM_NAME));
1991 add_option (_("Transport"), tsf);
1993 tsf = new BoolOption (
1994 "disable-disarm-during-roll",
1995 _("Disable per-track record disarm while rolling"),
1996 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
1997 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
1999 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"));
2000 add_option (_("Transport"), tsf);
2002 tsf = new BoolOption (
2004 _("12dB gain reduction during fast-forward and fast-rewind"),
2005 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
2006 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
2008 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
2009 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
2010 add_option (_("Transport"), tsf);
2012 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
2014 _sync_source = new ComboOption<SyncSource> (
2016 _("External timecode source"),
2017 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
2018 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
2021 add_option (_("Transport"), _sync_source);
2023 _sync_framerate = new BoolOption (
2024 "timecode-sync-frame-rate",
2025 _("Match session video frame rate to external timecode"),
2026 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
2027 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
2029 Gtkmm2ext::UI::instance()->set_tip
2030 (_sync_framerate->tip_widget(),
2031 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
2032 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
2033 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
2034 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
2035 "timecode standard and the session standard."), PROGRAM_NAME));
2037 add_option (_("Transport"), _sync_framerate);
2039 _sync_genlock = new BoolOption (
2040 "timecode-source-is-synced",
2041 _("Sync-lock timecode to clock (disable drift compensation)"),
2042 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
2043 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
2045 Gtkmm2ext::UI::instance()->set_tip
2046 (_sync_genlock->tip_widget(),
2047 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
2048 "Sync Lock indicates that the selected external timecode source shares clock-sync "
2049 "(Black & Burst, Wordclock, etc) with the audio interface. "
2050 "This option disables drift compensation. The transport speed is fixed at 1.0. "
2051 "Vari-speed LTC will be ignored and cause drift."
2053 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
2054 "timecode sources shares clock sync."
2058 add_option (_("Transport"), _sync_genlock);
2060 _sync_source_2997 = new BoolOption (
2061 "timecode-source-2997",
2062 _("Lock to 29.9700 fps instead of 30000/1001"),
2063 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
2064 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
2066 Gtkmm2ext::UI::instance()->set_tip
2067 (_sync_source_2997->tip_widget(),
2068 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
2069 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
2070 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
2071 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
2072 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
2073 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
2076 add_option (_("Transport"), _sync_source_2997);
2078 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
2080 _ltc_port = new ComboStringOption (
2082 _("LTC incoming port"),
2083 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
2084 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
2087 vector<string> physical_inputs;
2088 physical_inputs.push_back (_("None"));
2089 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
2090 _ltc_port->set_popdown_strings (physical_inputs);
2092 populate_sync_options ();
2094 add_option (_("Transport"), _ltc_port);
2096 // TODO; rather disable this button than not compile it..
2097 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
2099 add_option (_("Transport"),
2102 _("Enable LTC generator"),
2103 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
2104 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
2107 _ltc_send_continuously = new BoolOption (
2108 "ltc-send-continuously",
2109 _("Send LTC while stopped"),
2110 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
2111 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
2113 Gtkmm2ext::UI::instance()->set_tip
2114 (_ltc_send_continuously->tip_widget(),
2115 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
2116 add_option (_("Transport"), _ltc_send_continuously);
2118 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
2119 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
2120 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
2121 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
2123 Gtkmm2ext::UI::instance()->set_tip
2124 (_ltc_volume_slider->tip_widget(),
2125 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
2127 add_option (_("Transport"), _ltc_volume_slider);
2128 parameter_changed ("send-ltc");
2130 parameter_changed ("sync-source");
2134 add_option (S_("Editor"),
2136 "draggable-playhead",
2137 _("Allow dragging of playhead"),
2138 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_draggable_playhead),
2139 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_draggable_playhead)
2142 add_option (_("Editor"),
2144 "automation-follows-regions",
2145 _("Move relevant automation when audio regions are moved"),
2146 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2147 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2150 add_option (_("Editor"),
2152 "show-track-meters",
2153 _("Show meters on tracks in the editor"),
2154 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_track_meters),
2155 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_track_meters)
2158 add_option (_("Editor"),
2160 "show-editor-meter",
2161 _("Display master-meter in the toolbar"),
2162 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_editor_meter),
2163 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_editor_meter)
2166 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2167 "default-fade-shape",
2168 _("Default fade shape"),
2169 sigc::mem_fun (*_rc_config,
2170 &RCConfiguration::get_default_fade_shape),
2171 sigc::mem_fun (*_rc_config,
2172 &RCConfiguration::set_default_fade_shape)
2175 fadeshape->add (FadeLinear,
2176 _("Linear (for highly correlated material)"));
2177 fadeshape->add (FadeConstantPower, _("Constant power"));
2178 fadeshape->add (FadeSymmetric, _("Symmetric"));
2179 fadeshape->add (FadeSlow, _("Slow"));
2180 fadeshape->add (FadeFast, _("Fast"));
2182 add_option (_("Editor"), fadeshape);
2185 bco = new BoolComboOption (
2186 "use-overlap-equivalency",
2187 _("Regions in active edit groups are edited together"),
2188 _("whenever they overlap in time"),
2189 _("only if they have identical length, position and origin"),
2190 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2191 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2194 add_option (_("Editor"), bco);
2196 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2198 _("Layering model"),
2199 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2200 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2203 lm->add (LaterHigher, _("later is higher"));
2204 lm->add (Manual, _("manual layering"));
2205 add_option (_("Editor"), lm);
2207 add_option (_("Editor"),
2209 "rubberbanding-snaps-to-grid",
2210 _("Make rubberband selection rectangle snap to the grid"),
2211 sigc::mem_fun (*_ui_config, &UIConfiguration::get_rubberbanding_snaps_to_grid),
2212 sigc::mem_fun (*_ui_config, &UIConfiguration::set_rubberbanding_snaps_to_grid)
2215 add_option (_("Editor"),
2218 _("Show waveforms in regions"),
2219 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms),
2220 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms)
2223 add_option (_("Editor"),
2224 new BoolComboOption (
2225 "show-region-gain-envelopes",
2226 _("Show gain envelopes in audio regions"),
2228 _("only in Draw and Internal Edit modes"),
2229 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_region_gain),
2230 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_region_gain)
2233 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
2235 _("Waveform scale"),
2236 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_scale),
2237 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_scale)
2240 wfs->add (Linear, _("linear"));
2241 wfs->add (Logarithmic, _("logarithmic"));
2243 add_option (_("Editor"), wfs);
2245 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
2247 _("Waveform shape"),
2248 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_shape),
2249 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_shape)
2252 wfsh->add (Traditional, _("traditional"));
2253 wfsh->add (Rectified, _("rectified"));
2255 add_option (_("Editor"), wfsh);
2257 add_option (_("Editor"), new ClipLevelOptions (_ui_config));
2259 add_option (_("Editor"),
2261 "show-waveforms-while-recording",
2262 _("Show waveforms for audio while it is being recorded"),
2263 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms_while_recording),
2264 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms_while_recording)
2267 add_option (_("Editor"),
2270 _("Show zoom toolbar"),
2271 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_zoom_tools),
2272 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_zoom_tools)
2275 add_option (_("Editor"),
2277 "update-editor-during-summary-drag",
2278 _("Update editor window during drags of the summary"),
2279 sigc::mem_fun (*_ui_config, &UIConfiguration::get_update_editor_during_summary_drag),
2280 sigc::mem_fun (*_ui_config, &UIConfiguration::set_update_editor_during_summary_drag)
2283 bo = new BoolOption (
2285 _("Name new markers"),
2286 sigc::mem_fun (*_ui_config, &UIConfiguration::get_name_new_markers),
2287 sigc::mem_fun (*_ui_config, &UIConfiguration::set_name_new_markers)
2290 add_option (_("Editor"), bo);
2291 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."
2292 "\n\nYou can always rename markers by right-clicking on them"));
2294 add_option (_("Editor"),
2296 "autoscroll-editor",
2297 _("Auto-scroll editor window when dragging near its edges"),
2298 sigc::mem_fun (*_ui_config, &UIConfiguration::get_autoscroll_editor),
2299 sigc::mem_fun (*_ui_config, &UIConfiguration::set_autoscroll_editor)
2302 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2303 "region-selection-after-split",
2304 _("After splitting selected regions, select"),
2305 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2306 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2308 // TODO: decide which of these modes are really useful
2309 rsas->add(None, _("no regions"));
2310 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2311 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2312 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2313 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2314 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2315 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2316 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2318 add_option (_("Editor"), rsas);
2323 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2325 add_option (_("Audio"), new BufferingOptions (_rc_config));
2327 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2329 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2331 _("Record monitoring handled by"),
2332 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2333 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2336 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2337 mm->add (HardwareMonitoring, _("via Audio Driver"));
2340 string prog (PROGRAM_NAME);
2341 boost::algorithm::to_lower (prog);
2342 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2343 mm->add (ExternalMonitoring, _("audio hardware"));
2345 add_option (_("Audio"), mm);
2347 add_option (_("Audio"),
2349 "tape-machine-mode",
2350 _("Tape machine mode"),
2351 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2352 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2355 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
2357 add_option (_("Audio"),
2359 "auto-connect-standard-busses",
2360 _("Auto-connect master/monitor busses"),
2361 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2362 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2365 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2366 "input-auto-connect",
2367 _("Connect track inputs"),
2368 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2369 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2372 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2373 iac->add (ManualConnect, _("manually"));
2375 add_option (_("Audio"), iac);
2377 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2378 "output-auto-connect",
2379 _("Connect track and bus outputs"),
2380 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2381 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2384 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2385 oac->add (AutoConnectMaster, _("automatically to master bus"));
2386 oac->add (ManualConnect, _("manually"));
2388 add_option (_("Audio"), oac);
2390 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2392 add_option (_("Audio"),
2394 "denormal-protection",
2395 _("Use DC bias to protect against denormals"),
2396 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2397 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2400 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2402 _("Processor handling"),
2403 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2404 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2408 dm->add (DenormalNone, _("no processor handling"));
2410 FPU* fpu = FPU::instance();
2412 if (fpu->has_flush_to_zero()) {
2414 dm->add (DenormalFTZ, _("use FlushToZero"));
2415 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2416 _rc_config->set_denormal_model(DenormalNone);
2419 if (fpu->has_denormals_are_zero()) {
2421 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2422 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2423 _rc_config->set_denormal_model(DenormalNone);
2426 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2428 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2429 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2430 _rc_config->set_denormal_model(DenormalNone);
2434 dm->set_sensitive(false);
2437 add_option (_("Audio"), dm);
2439 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
2441 add_option (_("Audio"),
2443 "plugins-stop-with-transport",
2444 _("Silence plugins when the transport is stopped"),
2445 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
2446 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
2449 add_option (_("Audio"),
2451 "new-plugins-active",
2452 _("Make new plugins active"),
2453 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
2454 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
2457 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2459 add_option (_("Audio"),
2461 "auto-analyse-audio",
2462 _("Enable automatic analysis of audio"),
2463 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2464 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2467 add_option (_("Audio"),
2469 "replicate-missing-region-channels",
2470 _("Replicate missing region channels"),
2471 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2472 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2477 add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
2479 add_option (_("Solo / mute"),
2482 _("Solo-in-place mute cut (dB)"),
2483 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2484 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2487 _solo_control_is_listen_control = new BoolOption (
2488 "solo-control-is-listen-control",
2489 _("Solo controls are Listen controls"),
2490 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2491 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2494 add_option (_("Solo / mute"), _solo_control_is_listen_control);
2496 _listen_position = new ComboOption<ListenPosition> (
2498 _("Listen Position"),
2499 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2500 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2503 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2504 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2506 add_option (_("Solo / mute"), _listen_position);
2508 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2510 _("PFL signals come from"),
2511 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2512 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2515 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2516 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2518 add_option (_("Solo / mute"), pp);
2520 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2522 _("AFL signals come from"),
2523 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2524 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2527 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2528 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2530 add_option (_("Solo / mute"), pa);
2532 parameter_changed ("use-monitor-bus");
2534 add_option (_("Solo / mute"),
2537 _("Exclusive solo"),
2538 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2539 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2542 add_option (_("Solo / mute"),
2545 _("Show solo muting"),
2546 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2547 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2550 add_option (_("Solo / mute"),
2552 "solo-mute-override",
2553 _("Soloing overrides muting"),
2554 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2555 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2558 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
2560 add_option (_("Solo / mute"),
2562 "mute-affects-pre-fader",
2563 _("Mute affects pre-fader sends"),
2564 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2565 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2568 add_option (_("Solo / mute"),
2570 "mute-affects-post-fader",
2571 _("Mute affects post-fader sends"),
2572 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2573 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2576 add_option (_("Solo / mute"),
2578 "mute-affects-control-outs",
2579 _("Mute affects control outputs"),
2580 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2581 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2584 add_option (_("Solo / mute"),
2586 "mute-affects-main-outs",
2587 _("Mute affects main outputs"),
2588 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2589 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2592 add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
2594 add_option (_("Solo / mute"),
2596 "link-send-and-route-panner",
2597 _("Link panners of Aux and External Sends with main panner by default"),
2598 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2599 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2602 add_option (_("MIDI"),
2603 new SpinOption<float> (
2605 _("MIDI read-ahead time (seconds)"),
2606 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2607 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2612 add_option (_("MIDI"),
2615 _("Send MIDI Clock"),
2616 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2617 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2620 add_option (_("MIDI"),
2623 _("Send MIDI Time Code"),
2624 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2625 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2628 add_option (_("MIDI"),
2629 new SpinOption<int> (
2630 "mtc-qf-speed-tolerance",
2631 _("Percentage either side of normal transport speed to transmit MTC"),
2632 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2633 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2637 add_option (_("MIDI"),
2640 _("Obey MIDI Machine Control commands"),
2641 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2642 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2645 add_option (_("MIDI"),
2648 _("Send MIDI Machine Control commands"),
2649 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2650 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2653 add_option (_("MIDI"),
2656 _("Send MIDI control feedback"),
2657 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2658 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2661 add_option (_("MIDI"),
2662 new SpinOption<uint8_t> (
2663 "mmc-receive-device-id",
2664 _("Inbound MMC device ID"),
2665 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2666 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2670 add_option (_("MIDI"),
2671 new SpinOption<uint8_t> (
2672 "mmc-send-device-id",
2673 _("Outbound MMC device ID"),
2674 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2675 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2679 add_option (_("MIDI"),
2680 new SpinOption<int32_t> (
2681 "initial-program-change",
2682 _("Initial program change"),
2683 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2684 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2688 add_option (_("MIDI"),
2690 "display-first-midi-bank-as-zero",
2691 _("Display first MIDI bank/program as 0"),
2692 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2693 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2696 add_option (_("MIDI"),
2698 "never-display-periodic-midi",
2699 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2700 sigc::mem_fun (*_ui_config, &UIConfiguration::get_never_display_periodic_midi),
2701 sigc::mem_fun (*_ui_config, &UIConfiguration::set_never_display_periodic_midi)
2704 add_option (_("MIDI"),
2707 _("Sound MIDI notes as they are selected"),
2708 sigc::mem_fun (*_ui_config, &UIConfiguration::get_sound_midi_notes),
2709 sigc::mem_fun (*_ui_config, &UIConfiguration::set_sound_midi_notes)
2712 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2714 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2715 "midi-audition-synth-uri",
2716 _("Midi Audition Synth (LV2)"),
2717 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2718 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2721 audition_synth->add(X_(""), _("None"));
2722 PluginInfoList all_plugs;
2723 PluginManager& manager (PluginManager::instance());
2725 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2727 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2728 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2729 if (!(*i)->is_instrument()) continue;
2730 if ((*i)->type != ARDOUR::LV2) continue;
2731 audition_synth->add((*i)->unique_id, (*i)->name);
2735 add_option (_("MIDI"), audition_synth);
2737 /* USER INTERACTION */
2740 #ifdef PLATFORM_WINDOWS
2743 getenv ("ARDOUR_BUNDLED")
2747 add_option (_("User interaction"),
2749 "enable-translation",
2750 string_compose (_("Use translations of %1 messages\n"
2751 " <i>(requires a restart of %1 to take effect)</i>\n"
2752 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2753 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2754 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2757 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2759 add_option (_("User interaction"), new KeyboardOptions);
2761 /* Control Surfaces */
2763 add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
2765 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2767 _("Control surface remote ID"),
2768 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2769 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2772 rm->add (UserOrdered, _("assigned by user"));
2773 rm->add (MixerOrdered, _("follows order of mixer"));
2775 add_option (_("Control Surfaces"), rm);
2777 /* VIDEO Timeline */
2778 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2780 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2781 /* Plugin options (currrently VST only) */
2782 add_option (_("Plugins"), new PluginOptions (_rc_config, _ui_config));
2787 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
2788 BoolOption* bgo = new BoolOption (
2790 _("Possibly improve slow graphical performance"),
2791 sigc::mem_fun (*_ui_config, &UIConfiguration::get_buggy_gradients),
2792 sigc::mem_fun (*_ui_config, &UIConfiguration::set_buggy_gradients)
2795 Gtkmm2ext::UI::instance()->set_tip (bgo->tip_widget(), string_compose (_("This requires restarting %1 before having an effect"), PROGRAM_NAME));
2796 add_option (S_("Preferences|GUI"), bgo);
2799 add_option (S_("Preferences|GUI"),
2802 _("Graphically indicate mouse pointer hovering over various widgets"),
2803 sigc::mem_fun (*_ui_config, &UIConfiguration::get_widget_prelight),
2804 sigc::mem_fun (*_ui_config, &UIConfiguration::set_widget_prelight)
2807 #ifdef TOOLTIPS_GOT_FIXED
2808 add_option (S_("Preferences|GUI"),
2811 _("Show tooltips if mouse hovers over a control"),
2812 sigc::mem_fun (*_ui_config, &UIConfiguration::get_use_tooltips),
2813 sigc::mem_fun (*_ui_config, &UIConfiguration::set_use_tooltips)
2817 add_option (S_("Preferences|GUI"),
2819 "show-name-highlight",
2820 _("Use name highlight bars in region displays (requires a restart)"),
2821 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_name_highlight),
2822 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_name_highlight)
2826 /* font scaling does nothing with GDK/Quartz */
2827 add_option (S_("Preferences|GUI"), new FontScalingOptions (_ui_config));
2830 add_option (S_("GUI"),
2832 "super-rapid-clock-update",
2833 _("update transport clock display at FPS instead of every 100ms"),
2834 sigc::mem_fun (*_ui_config, &UIConfiguration::get_super_rapid_clock_update),
2835 sigc::mem_fun (*_ui_config, &UIConfiguration::set_super_rapid_clock_update)
2839 /* Image cache size */
2841 Gtk::Adjustment *ics = manage (new Gtk::Adjustment(0, 1, 1024, 10)); /* 1 MB to 1GB in steps of 10MB */
2842 HSliderOption *sics = new HSliderOption("waveform-cache-size",
2843 _("Waveform image cache size (megabytes)"),
2845 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_waveform_cache_size),
2846 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_waveform_cache_size)
2848 sics->scale().set_digits (0);
2849 Gtkmm2ext::UI::instance()->set_tip
2850 (sics->tip_widget(),
2851 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
2852 add_option (S_("Preferences|GUI"), sics);
2854 /* Lock GUI timeout */
2856 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
2857 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2858 _("Lock timeout (seconds)"),
2860 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_lock_gui_after_seconds),
2861 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_lock_gui_after_seconds)
2863 slts->scale().set_digits (0);
2864 Gtkmm2ext::UI::instance()->set_tip
2865 (slts->tip_widget(),
2866 _("Lock GUI after this many idle seconds (zero to never lock)"));
2867 add_option (S_("Preferences|GUI"), slts);
2869 /* The names of these controls must be the same as those given in MixerStrip
2870 for the actual widgets being controlled.
2872 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
2873 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2874 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
2875 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
2876 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
2877 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2880 S_("Preferences|GUI"),
2881 new VisibilityOption (
2883 &_mixer_strip_visibility,
2884 sigc::mem_fun (*_ui_config, &UIConfiguration::get_mixer_strip_visibility),
2885 sigc::mem_fun (*_ui_config, &UIConfiguration::set_mixer_strip_visibility)
2889 add_option (S_("Preferences|GUI"),
2891 "default-narrow_ms",
2892 _("Use narrow strips in the mixer by default"),
2893 sigc::mem_fun (*_ui_config, &UIConfiguration::get_default_narrow_ms),
2894 sigc::mem_fun (*_ui_config, &UIConfiguration::set_default_narrow_ms)
2897 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2899 ComboOption<float>* mht = new ComboOption<float> (
2901 _("Peak hold time"),
2902 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_hold),
2903 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_hold)
2906 mht->add (MeterHoldOff, _("off"));
2907 mht->add (MeterHoldShort, _("short"));
2908 mht->add (MeterHoldMedium, _("medium"));
2909 mht->add (MeterHoldLong, _("long"));
2911 add_option (S_("Preferences|Metering"), mht);
2913 ComboOption<float>* mfo = new ComboOption<float> (
2916 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2917 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2920 mfo->add (METER_FALLOFF_OFF, _("off"));
2921 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2922 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2923 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
2924 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2925 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
2926 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
2928 add_option (S_("Preferences|Metering"), mfo);
2930 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2931 "meter-line-up-level",
2932 _("Meter line-up level; 0dBu"),
2933 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_level),
2934 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_level)
2937 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2938 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2939 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2940 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2942 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."));
2944 add_option (S_("Preferences|Metering"), mlu);
2946 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2947 "meter-line-up-din",
2948 _("IEC1/DIN Meter line-up level; 0dBu"),
2949 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_din),
2950 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_din)
2953 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2954 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2955 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2956 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2958 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2960 add_option (S_("Preferences|Metering"), mld);
2962 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2963 "meter-vu-standard",
2964 _("VU Meter standard"),
2965 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_vu_standard),
2966 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_vu_standard)
2969 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2970 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2971 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2972 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2974 add_option (S_("Preferences|Metering"), mvu);
2976 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
2977 HSliderOption *mpks = new HSliderOption("meter-peak",
2978 _("Peak threshold [dBFS]"),
2980 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_peak),
2981 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_peak)
2985 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
2986 "meter-type-master",
2987 _("Default Meter Type for Master Bus"),
2988 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
2989 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
2991 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2992 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2993 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2994 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2995 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2996 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2997 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2998 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3000 add_option (S_("Preferences|Metering"), mtm);
3003 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3005 _("Default Meter Type for Busses"),
3006 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3007 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3009 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3010 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3011 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3012 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3013 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3014 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3015 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3016 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3018 add_option (S_("Preferences|Metering"), mtb);
3020 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3022 _("Default Meter Type for Tracks"),
3023 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3024 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3026 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3027 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3029 add_option (S_("Preferences|Metering"), mtt);
3032 Gtkmm2ext::UI::instance()->set_tip
3033 (mpks->tip_widget(),
3034 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
3036 add_option (S_("Preferences|Metering"), mpks);
3038 add_option (S_("Preferences|Metering"),
3041 _("LED meter style"),
3042 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_style_led),
3043 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_style_led)
3046 /* and now the theme manager */
3048 ThemeManager* tm = manage (new ThemeManager);
3049 add_page (_("Theme"), *tm);
3053 RCOptionEditor::parameter_changed (string const & p)
3055 OptionEditor::parameter_changed (p);
3057 if (p == "use-monitor-bus") {
3058 bool const s = Config->get_use_monitor_bus ();
3060 /* we can't use this if we don't have a monitor bus */
3061 Config->set_solo_control_is_listen_control (false);
3063 _solo_control_is_listen_control->set_sensitive (s);
3064 _listen_position->set_sensitive (s);
3065 } else if (p == "sync-source") {
3066 _sync_source->set_sensitive (true);
3068 _sync_source->set_sensitive (!_session->config.get_external_sync());
3070 switch(Config->get_sync_source()) {
3073 _sync_genlock->set_sensitive (true);
3074 _sync_framerate->set_sensitive (true);
3075 _sync_source_2997->set_sensitive (true);
3078 _sync_genlock->set_sensitive (false);
3079 _sync_framerate->set_sensitive (false);
3080 _sync_source_2997->set_sensitive (false);
3083 } else if (p == "send-ltc") {
3084 bool const s = Config->get_send_ltc ();
3085 _ltc_send_continuously->set_sensitive (s);
3086 _ltc_volume_slider->set_sensitive (s);
3090 void RCOptionEditor::ltc_generator_volume_changed () {
3091 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
3095 RCOptionEditor::populate_sync_options ()
3097 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3099 _sync_source->clear ();
3101 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3102 _sync_source->add (*i, sync_source_to_string (*i));
3105 if (sync_opts.empty()) {
3106 _sync_source->set_sensitive(false);
3108 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3109 _rc_config->set_sync_source(sync_opts.front());