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 #if !defined USE_CAIRO_IMAGE_SURFACE && !defined NDEBUG
25 #define OPTIONAL_CAIRO_IMAGE_SURFACE
28 #include <cairo/cairo.h>
30 #include <boost/algorithm/string.hpp>
32 #include <gtkmm/liststore.h>
33 #include <gtkmm/stock.h>
34 #include <gtkmm/scale.h>
36 #include <gtkmm2ext/utils.h>
37 #include <gtkmm2ext/slider_controller.h>
38 #include <gtkmm2ext/gtk_ui.h>
39 #include <gtkmm2ext/paths_dialog.h>
44 #include "ardour/audioengine.h"
45 #include "ardour/dB.h"
46 #include "ardour/rc_configuration.h"
47 #include "ardour/control_protocol_manager.h"
48 #include "ardour/plugin_manager.h"
49 #include "control_protocol/control_protocol.h"
51 #include "canvas/wave_view.h"
53 #include "ardour_ui.h"
54 #include "ardour_window.h"
55 #include "ardour_dialog.h"
56 #include "gui_thread.h"
57 #include "meter_patterns.h"
58 #include "midi_tracer.h"
59 #include "rc_option_editor.h"
61 #include "midi_port_dialog.h"
64 #include "theme_manager.h"
65 #include "ui_config.h"
70 using namespace Gtkmm2ext;
72 using namespace ARDOUR;
73 using namespace ARDOUR_UI_UTILS;
75 class ClickOptions : public OptionEditorBox
78 ClickOptions (RCConfiguration* c, Gtk::Window* p)
80 , _click_browse_button (_("Browse..."))
81 , _click_emphasis_browse_button (_("Browse..."))
83 Table* t = manage (new Table (3, 3));
86 Label* l = manage (left_aligned_label (_("Use default Click:")));
87 t->attach (*l, 0, 1, 0, 1, FILL);
88 t->attach (_use_default_click_check_button, 1, 2, 0, 1, FILL);
89 _use_default_click_check_button.signal_toggled().connect (
90 sigc::mem_fun (*this, &ClickOptions::use_default_click_toggled));
92 l = manage (left_aligned_label (_("Click audio file:")));
93 t->attach (*l, 0, 1, 1, 2, FILL);
94 t->attach (_click_path_entry, 1, 2, 1, 2, FILL);
95 _click_browse_button.signal_clicked ().connect (
96 sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
97 t->attach (_click_browse_button, 2, 3, 1, 2, FILL);
99 l = manage (left_aligned_label (_("Click emphasis audio file:")));
100 t->attach (*l, 0, 1, 2, 3, FILL);
101 t->attach (_click_emphasis_path_entry, 1, 2, 2, 3, FILL);
102 _click_emphasis_browse_button.signal_clicked ().connect (
103 sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
104 t->attach (_click_emphasis_browse_button, 2, 3, 2, 3, FILL);
106 _box->pack_start (*t, false, false);
108 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
109 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
111 if (_rc_config->get_click_sound ().empty() &&
112 _rc_config->get_click_emphasis_sound().empty()) {
113 _use_default_click_check_button.set_active (true);
116 _use_default_click_check_button.set_active (false);
120 void parameter_changed (string const & p)
122 if (p == "click-sound") {
123 _click_path_entry.set_text (_rc_config->get_click_sound());
124 } else if (p == "click-emphasis-sound") {
125 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
129 void set_state_from_config ()
131 parameter_changed ("click-sound");
132 parameter_changed ("click-emphasis-sound");
137 void click_browse_clicked ()
139 SoundFileChooser sfdb (_("Choose Click"));
144 if (sfdb.run () == RESPONSE_OK) {
145 click_chosen (sfdb.get_filename());
149 void click_chosen (string const & path)
151 _click_path_entry.set_text (path);
152 _rc_config->set_click_sound (path);
155 void click_changed ()
157 click_chosen (_click_path_entry.get_text ());
160 void click_emphasis_browse_clicked ()
162 SoundFileChooser sfdb (_("Choose Click Emphasis"));
167 if (sfdb.run () == RESPONSE_OK) {
168 click_emphasis_chosen (sfdb.get_filename());
172 void click_emphasis_chosen (string const & path)
174 _click_emphasis_path_entry.set_text (path);
175 _rc_config->set_click_emphasis_sound (path);
178 void click_emphasis_changed ()
180 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
183 void use_default_click_toggled ()
185 if (_use_default_click_check_button.get_active ()) {
186 _rc_config->set_click_sound ("");
187 _rc_config->set_click_emphasis_sound ("");
188 _click_path_entry.set_sensitive (false);
189 _click_emphasis_path_entry.set_sensitive (false);
190 _click_browse_button.set_sensitive (false);
191 _click_emphasis_browse_button.set_sensitive (false);
193 _click_path_entry.set_sensitive (true);
194 _click_emphasis_path_entry.set_sensitive (true);
195 _click_browse_button.set_sensitive (true);
196 _click_emphasis_browse_button.set_sensitive (true);
200 RCConfiguration* _rc_config;
201 CheckButton _use_default_click_check_button;
202 Entry _click_path_entry;
203 Entry _click_emphasis_path_entry;
204 Button _click_browse_button;
205 Button _click_emphasis_browse_button;
208 class UndoOptions : public OptionEditorBox
211 UndoOptions (RCConfiguration* c) :
213 _limit_undo_button (_("Limit undo history to")),
214 _save_undo_button (_("Save undo history of"))
216 Table* t = new Table (2, 3);
219 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
220 _limit_undo_spin.set_range (0, 512);
221 _limit_undo_spin.set_increments (1, 10);
222 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
223 Label* l = manage (left_aligned_label (_("commands")));
224 t->attach (*l, 2, 3, 0, 1);
226 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
227 _save_undo_spin.set_range (0, 512);
228 _save_undo_spin.set_increments (1, 10);
229 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
230 l = manage (left_aligned_label (_("commands")));
231 t->attach (*l, 2, 3, 1, 2);
233 _box->pack_start (*t);
235 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
236 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
237 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
238 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
241 void parameter_changed (string const & p)
243 if (p == "history-depth") {
244 int32_t const d = _rc_config->get_history_depth();
245 _limit_undo_button.set_active (d != 0);
246 _limit_undo_spin.set_sensitive (d != 0);
247 _limit_undo_spin.set_value (d);
248 } else if (p == "save-history") {
249 bool const x = _rc_config->get_save_history ();
250 _save_undo_button.set_active (x);
251 _save_undo_spin.set_sensitive (x);
252 } else if (p == "save-history-depth") {
253 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
257 void set_state_from_config ()
259 parameter_changed ("save-history");
260 parameter_changed ("history-depth");
261 parameter_changed ("save-history-depth");
264 void limit_undo_toggled ()
266 bool const x = _limit_undo_button.get_active ();
267 _limit_undo_spin.set_sensitive (x);
268 int32_t const n = x ? 16 : 0;
269 _limit_undo_spin.set_value (n);
270 _rc_config->set_history_depth (n);
273 void limit_undo_changed ()
275 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
278 void save_undo_toggled ()
280 bool const x = _save_undo_button.get_active ();
281 _rc_config->set_save_history (x);
284 void save_undo_changed ()
286 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
290 RCConfiguration* _rc_config;
291 CheckButton _limit_undo_button;
292 SpinButton _limit_undo_spin;
293 CheckButton _save_undo_button;
294 SpinButton _save_undo_spin;
299 static const struct {
311 { "Key|Shift", GDK_SHIFT_MASK },
312 { "Command", GDK_META_MASK },
313 { "Control", GDK_CONTROL_MASK },
314 { "Option", GDK_MOD1_MASK },
315 { "Command-Shift", GDK_META_MASK|GDK_SHIFT_MASK },
316 { "Command-Option", GDK_MOD1_MASK|GDK_META_MASK },
317 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
318 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
319 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_META_MASK },
322 { "Key|Shift", GDK_SHIFT_MASK },
323 { "Control", GDK_CONTROL_MASK },
324 { "Alt", GDK_MOD1_MASK },
325 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
326 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
327 { "Shift-Alt", GDK_SHIFT_MASK|GDK_MOD1_MASK },
328 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
329 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
330 { "Mod2", GDK_MOD2_MASK },
331 { "Mod3", GDK_MOD3_MASK },
332 { "Windows", GDK_MOD4_MASK },
333 { "Mod5", GDK_MOD5_MASK },
339 class KeyboardOptions : public OptionEditorBox
343 _delete_button_adjustment (3, 1, 12),
344 _delete_button_spin (_delete_button_adjustment),
345 _edit_button_adjustment (3, 1, 5),
346 _edit_button_spin (_edit_button_adjustment),
347 _insert_note_button_adjustment (3, 1, 5),
348 _insert_note_button_spin (_insert_note_button_adjustment)
350 /* internationalize and prepare for use with combos */
353 for (int i = 0; modifiers[i].name; ++i) {
354 dumb.push_back (S_(modifiers[i].name));
357 set_popdown_strings (_edit_modifier_combo, dumb);
358 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
360 for (int x = 0; modifiers[x].name; ++x) {
361 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
362 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
367 Table* t = manage (new Table (5, 11));
373 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
374 l->set_name ("OptionsLabel");
378 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
379 strs.push_back (bf->first);
382 set_popdown_strings (_keyboard_layout_selector, strs);
383 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
384 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
386 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
387 t->attach (_keyboard_layout_selector, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
392 l = manage (left_aligned_label (_("When Clicking:")));
393 l->set_name ("OptionEditorHeading");
394 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
399 l = manage (left_aligned_label (_("Edit using:")));
400 l->set_name ("OptionsLabel");
402 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
403 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
405 l = manage (new Label (_("+ button")));
406 l->set_name ("OptionsLabel");
408 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
409 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
411 _edit_button_spin.set_name ("OptionsEntry");
412 _edit_button_adjustment.set_value (Keyboard::edit_button());
413 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
418 set_popdown_strings (_delete_modifier_combo, dumb);
419 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
421 for (int x = 0; modifiers[x].name; ++x) {
422 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
423 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
428 l = manage (left_aligned_label (_("Delete using:")));
429 l->set_name ("OptionsLabel");
431 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
432 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
434 l = manage (new Label (_("+ button")));
435 l->set_name ("OptionsLabel");
437 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
438 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
440 _delete_button_spin.set_name ("OptionsEntry");
441 _delete_button_adjustment.set_value (Keyboard::delete_button());
442 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
447 set_popdown_strings (_insert_note_modifier_combo, dumb);
448 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
450 for (int x = 0; modifiers[x].name; ++x) {
451 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
452 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
457 l = manage (left_aligned_label (_("Insert note using:")));
458 l->set_name ("OptionsLabel");
460 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
461 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
463 l = manage (new Label (_("+ button")));
464 l->set_name ("OptionsLabel");
466 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
467 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
469 _insert_note_button_spin.set_name ("OptionsEntry");
470 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
471 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
475 l = manage (left_aligned_label (_("When Beginning a Drag:")));
476 l->set_name ("OptionEditorHeading");
477 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
483 set_popdown_strings (_copy_modifier_combo, dumb);
484 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
486 for (int x = 0; modifiers[x].name; ++x) {
487 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
488 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
493 l = manage (left_aligned_label (_("Copy items using:")));
494 l->set_name ("OptionsLabel");
496 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
497 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
502 /* constraint modifier */
503 set_popdown_strings (_constraint_modifier_combo, dumb);
504 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
506 for (int x = 0; modifiers[x].name; ++x) {
507 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
508 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
513 l = manage (left_aligned_label (_("Constrain drag using:")));
514 l->set_name ("OptionsLabel");
516 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
517 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
521 l = manage (left_aligned_label (_("When Beginning a Trim:")));
522 l->set_name ("OptionEditorHeading");
523 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
529 set_popdown_strings (_trim_contents_combo, dumb);
530 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
532 for (int x = 0; modifiers[x].name; ++x) {
533 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
534 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
539 l = manage (left_aligned_label (_("Trim contents using:")));
540 l->set_name ("OptionsLabel");
542 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
543 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
549 set_popdown_strings (_trim_anchored_combo, dumb);
550 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
552 for (int x = 0; modifiers[x].name; ++x) {
553 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
554 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
559 l = manage (left_aligned_label (_("Anchored trim using:")));
560 l->set_name ("OptionsLabel");
562 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
564 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
569 /* jump trim disabled for now
570 set_popdown_strings (_trim_jump_combo, dumb);
571 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
573 for (int x = 0; modifiers[x].name; ++x) {
574 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
575 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
580 l = manage (left_aligned_label (_("Jump after trim using:")));
581 l->set_name ("OptionsLabel");
583 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
585 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
591 /* note resize relative */
592 set_popdown_strings (_note_size_relative_combo, dumb);
593 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
595 for (int x = 0; modifiers[x].name; ++x) {
596 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
597 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
602 l = manage (left_aligned_label (_("Resize notes relatively using:")));
603 l->set_name ("OptionsLabel");
605 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
607 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
611 l = manage (left_aligned_label (_("While Dragging:")));
612 l->set_name ("OptionEditorHeading");
613 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
619 set_popdown_strings (_snap_modifier_combo, dumb);
620 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
622 for (int x = 0; modifiers[x].name; ++x) {
623 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
624 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
629 l = manage (left_aligned_label (_("Ignore snap using:")));
630 l->set_name ("OptionsLabel");
632 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
633 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
639 set_popdown_strings (_snap_delta_combo, dumb);
640 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
642 for (int x = 0; modifiers[x].name; ++x) {
643 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
644 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
649 l = manage (left_aligned_label (_("Snap relatively using:")));
650 l->set_name ("OptionsLabel");
652 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
653 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
657 l = manage (left_aligned_label (_("While Trimming:")));
658 l->set_name ("OptionEditorHeading");
659 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
665 set_popdown_strings (_trim_overlap_combo, dumb);
666 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
668 for (int x = 0; modifiers[x].name; ++x) {
669 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
670 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
675 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
676 l->set_name ("OptionsLabel");
678 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
679 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
683 l = manage (left_aligned_label (_("While Dragging Control Points:")));
684 l->set_name ("OptionEditorHeading");
685 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
691 set_popdown_strings (_fine_adjust_combo, dumb);
692 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
694 for (int x = 0; modifiers[x].name; ++x) {
695 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
696 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
701 l = manage (left_aligned_label (_("Fine adjust using:")));
702 l->set_name ("OptionsLabel");
704 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
705 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
711 set_popdown_strings (_push_points_combo, dumb);
712 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
714 for (int x = 0; modifiers[x].name; ++x) {
715 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
716 _push_points_combo.set_active_text (S_(modifiers[x].name));
721 l = manage (left_aligned_label (_("Push points using:")));
722 l->set_name ("OptionsLabel");
724 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
725 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
727 _box->pack_start (*t, false, false);
730 void parameter_changed (string const &)
732 /* XXX: these aren't really config options... */
735 void set_state_from_config ()
737 /* XXX: these aren't really config options... */
742 void bindings_changed ()
744 string const txt = _keyboard_layout_selector.get_active_text();
746 /* XXX: config...? for all this keyboard stuff */
748 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
749 if (txt == i->first) {
750 if (Keyboard::load_keybindings (i->second)) {
751 Keyboard::save_keybindings ();
757 void edit_modifier_chosen ()
759 string const txt = _edit_modifier_combo.get_active_text();
761 for (int i = 0; modifiers[i].name; ++i) {
762 if (txt == _(modifiers[i].name)) {
763 Keyboard::set_edit_modifier (modifiers[i].modifier);
769 void delete_modifier_chosen ()
771 string const txt = _delete_modifier_combo.get_active_text();
773 for (int i = 0; modifiers[i].name; ++i) {
774 if (txt == _(modifiers[i].name)) {
775 Keyboard::set_delete_modifier (modifiers[i].modifier);
781 void copy_modifier_chosen ()
783 string const txt = _copy_modifier_combo.get_active_text();
785 for (int i = 0; modifiers[i].name; ++i) {
786 if (txt == _(modifiers[i].name)) {
787 Keyboard::set_copy_modifier (modifiers[i].modifier);
793 void insert_note_modifier_chosen ()
795 string const txt = _insert_note_modifier_combo.get_active_text();
797 for (int i = 0; modifiers[i].name; ++i) {
798 if (txt == _(modifiers[i].name)) {
799 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
805 void snap_modifier_chosen ()
807 string const txt = _snap_modifier_combo.get_active_text();
809 for (int i = 0; modifiers[i].name; ++i) {
810 if (txt == _(modifiers[i].name)) {
811 Keyboard::set_snap_modifier (modifiers[i].modifier);
817 void snap_delta_modifier_chosen ()
819 string const txt = _snap_delta_combo.get_active_text();
821 for (int i = 0; modifiers[i].name; ++i) {
822 if (txt == _(modifiers[i].name)) {
823 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
829 void constraint_modifier_chosen ()
831 string const txt = _constraint_modifier_combo.get_active_text();
833 for (int i = 0; modifiers[i].name; ++i) {
834 if (txt == _(modifiers[i].name)) {
835 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
841 void trim_contents_modifier_chosen ()
843 string const txt = _trim_contents_combo.get_active_text();
845 for (int i = 0; modifiers[i].name; ++i) {
846 if (txt == _(modifiers[i].name)) {
847 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
853 void trim_overlap_modifier_chosen ()
855 string const txt = _trim_overlap_combo.get_active_text();
857 for (int i = 0; modifiers[i].name; ++i) {
858 if (txt == _(modifiers[i].name)) {
859 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
865 void trim_anchored_modifier_chosen ()
867 string const txt = _trim_anchored_combo.get_active_text();
869 for (int i = 0; modifiers[i].name; ++i) {
870 if (txt == _(modifiers[i].name)) {
871 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
877 void fine_adjust_modifier_chosen ()
879 string const txt = _fine_adjust_combo.get_active_text();
881 for (int i = 0; modifiers[i].name; ++i) {
882 if (txt == _(modifiers[i].name)) {
883 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
889 void push_points_modifier_chosen ()
891 string const txt = _push_points_combo.get_active_text();
893 for (int i = 0; modifiers[i].name; ++i) {
894 if (txt == _(modifiers[i].name)) {
895 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
901 void note_size_relative_modifier_chosen ()
903 string const txt = _note_size_relative_combo.get_active_text();
905 for (int i = 0; modifiers[i].name; ++i) {
906 if (txt == _(modifiers[i].name)) {
907 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
913 void delete_button_changed ()
915 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
918 void edit_button_changed ()
920 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
923 void insert_note_button_changed ()
925 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
928 ComboBoxText _keyboard_layout_selector;
929 ComboBoxText _edit_modifier_combo;
930 ComboBoxText _delete_modifier_combo;
931 ComboBoxText _copy_modifier_combo;
932 ComboBoxText _insert_note_modifier_combo;
933 ComboBoxText _snap_modifier_combo;
934 ComboBoxText _snap_delta_combo;
935 ComboBoxText _constraint_modifier_combo;
936 ComboBoxText _trim_contents_combo;
937 ComboBoxText _trim_overlap_combo;
938 ComboBoxText _trim_anchored_combo;
939 ComboBoxText _trim_jump_combo;
940 ComboBoxText _fine_adjust_combo;
941 ComboBoxText _push_points_combo;
942 ComboBoxText _note_size_relative_combo;
943 Adjustment _delete_button_adjustment;
944 SpinButton _delete_button_spin;
945 Adjustment _edit_button_adjustment;
946 SpinButton _edit_button_spin;
947 Adjustment _insert_note_button_adjustment;
948 SpinButton _insert_note_button_spin;
952 class FontScalingOptions : public OptionEditorBox
955 FontScalingOptions (UIConfiguration* uic) :
957 _dpi_adjustment (100, 50, 250, 1, 5),
958 _dpi_slider (_dpi_adjustment)
960 _dpi_adjustment.set_value (_ui_config->get_font_scale() / 1024.);
962 Label* l = manage (new Label (_("GUI and Font scaling:")));
963 l->set_name ("OptionsLabel");
965 const Glib::ustring dflt = _("Default");
966 const Glib::ustring empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
968 _dpi_slider.set_name("FontScaleSlider");
969 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
970 _dpi_slider.set_draw_value(false);
971 _dpi_slider.add_mark(50, Gtk::POS_TOP, empty);
972 _dpi_slider.add_mark(60, Gtk::POS_TOP, empty);
973 _dpi_slider.add_mark(70, Gtk::POS_TOP, empty);
974 _dpi_slider.add_mark(80, Gtk::POS_TOP, empty);
975 _dpi_slider.add_mark(90, Gtk::POS_TOP, empty);
976 _dpi_slider.add_mark(100, Gtk::POS_TOP, dflt);
977 _dpi_slider.add_mark(125, Gtk::POS_TOP, empty);
978 _dpi_slider.add_mark(150, Gtk::POS_TOP, empty);
979 _dpi_slider.add_mark(175, Gtk::POS_TOP, empty);
980 _dpi_slider.add_mark(200, Gtk::POS_TOP, empty);
981 _dpi_slider.add_mark(225, Gtk::POS_TOP, empty);
982 _dpi_slider.add_mark(250, Gtk::POS_TOP, empty);
984 HBox* h = manage (new HBox);
986 h->pack_start (*l, false, false);
987 h->pack_start (_dpi_slider, true, true);
989 _box->pack_start (*h, false, false);
991 set_note (_("Adjusting the scale require an application restart to re-layout."));
993 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
996 void parameter_changed (string const & p)
998 if (p == "font-scale") {
999 _dpi_adjustment.set_value (_ui_config->get_font_scale() / 1024.);
1003 void set_state_from_config ()
1005 parameter_changed ("font-scale");
1012 _ui_config->set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024.));
1013 /* XXX: should be triggered from the parameter changed signal */
1017 UIConfiguration* _ui_config;
1018 Adjustment _dpi_adjustment;
1022 class ClipLevelOptions : public OptionEditorBox
1025 ClipLevelOptions (UIConfiguration* c)
1027 , _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1028 , _clip_level_slider (_clip_level_adjustment)
1030 _clip_level_adjustment.set_value (_ui_config->get_waveform_clip_level ());
1032 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
1033 l->set_name ("OptionsLabel");
1035 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1036 HBox* h = manage (new HBox);
1038 h->pack_start (*l, false, false);
1039 h->pack_start (_clip_level_slider, true, true);
1041 _box->pack_start (*h, false, false);
1043 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1046 void parameter_changed (string const & p)
1048 if (p == "waveform-clip-level") {
1049 _clip_level_adjustment.set_value (_ui_config->get_waveform_clip_level());
1053 void set_state_from_config ()
1055 parameter_changed ("waveform-clip-level");
1060 void clip_level_changed ()
1062 _ui_config->set_waveform_clip_level (_clip_level_adjustment.get_value());
1063 /* XXX: should be triggered from the parameter changed signal */
1064 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1067 UIConfiguration* _ui_config;
1068 Adjustment _clip_level_adjustment;
1069 HScale _clip_level_slider;
1072 class BufferingOptions : public OptionEditorBox
1075 BufferingOptions (RCConfiguration* c)
1077 , _playback_adjustment (5, 1, 60, 1, 4)
1078 , _capture_adjustment (5, 1, 60, 1, 4)
1079 , _playback_slider (_playback_adjustment)
1080 , _capture_slider (_capture_adjustment)
1082 vector<string> presets;
1084 /* these must match the order of the enums for BufferingPreset */
1086 presets.push_back (_("Small sessions (4-16 tracks)"));
1087 presets.push_back (_("Medium sessions (16-64 tracks)"));
1088 presets.push_back (_("Large sessions (64+ tracks)"));
1089 presets.push_back (_("Custom (set by sliders below)"));
1091 set_popdown_strings (_buffering_presets_combo, presets);
1093 Label* l = manage (new Label (_("Preset:")));
1094 l->set_name ("OptionsLabel");
1095 HBox* h = manage (new HBox);
1096 h->set_spacing (12);
1097 h->pack_start (*l, false, false);
1098 h->pack_start (_buffering_presets_combo, true, true);
1099 _box->pack_start (*h, false, false);
1101 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1103 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1105 l = manage (new Label (_("Playback (seconds of buffering):")));
1106 l->set_name ("OptionsLabel");
1108 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1109 h = manage (new HBox);
1111 h->pack_start (*l, false, false);
1112 h->pack_start (_playback_slider, true, true);
1114 _box->pack_start (*h, false, false);
1116 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1118 l = manage (new Label (_("Recording (seconds of buffering):")));
1119 l->set_name ("OptionsLabel");
1121 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1122 h = manage (new HBox);
1124 h->pack_start (*l, false, false);
1125 h->pack_start (_capture_slider, true, true);
1127 _box->pack_start (*h, false, false);
1129 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
1130 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
1133 void parameter_changed (string const & p)
1135 if (p == "buffering-preset") {
1136 switch (_rc_config->get_buffering_preset()) {
1138 _playback_slider.set_sensitive (false);
1139 _capture_slider.set_sensitive (false);
1140 _buffering_presets_combo.set_active (0);
1143 _playback_slider.set_sensitive (false);
1144 _capture_slider.set_sensitive (false);
1145 _buffering_presets_combo.set_active (1);
1148 _playback_slider.set_sensitive (false);
1149 _capture_slider.set_sensitive (false);
1150 _buffering_presets_combo.set_active (2);
1153 _playback_slider.set_sensitive (true);
1154 _capture_slider.set_sensitive (true);
1155 _buffering_presets_combo.set_active (3);
1160 if (p == "playback-buffer-seconds") {
1161 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1162 } else if (p == "capture-buffer-seconds") {
1163 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1167 void set_state_from_config ()
1169 parameter_changed ("buffering-preset");
1170 parameter_changed ("playback-buffer-seconds");
1171 parameter_changed ("capture-buffer-seconds");
1176 void preset_changed ()
1178 int index = _buffering_presets_combo.get_active_row_number ();
1184 _rc_config->set_buffering_preset (Small);
1187 _rc_config->set_buffering_preset (Medium);
1190 _rc_config->set_buffering_preset (Large);
1193 _rc_config->set_buffering_preset (Custom);
1196 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1201 void playback_changed ()
1203 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
1206 void capture_changed ()
1208 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
1211 RCConfiguration* _rc_config;
1212 Adjustment _playback_adjustment;
1213 Adjustment _capture_adjustment;
1214 HScale _playback_slider;
1215 HScale _capture_slider;
1216 ComboBoxText _buffering_presets_combo;
1219 class ControlSurfacesOptions : public OptionEditorBox
1222 ControlSurfacesOptions (Gtk::Window& parent)
1224 , _ignore_view_change (0)
1226 _store = ListStore::create (_model);
1227 _view.set_model (_store);
1228 _view.append_column (_("Control Surface Protocol"), _model.name);
1229 _view.get_column(0)->set_resizable (true);
1230 _view.get_column(0)->set_expand (true);
1231 _view.append_column_editable (_("Enabled"), _model.enabled);
1232 _view.append_column_editable (_("Feedback"), _model.feedback);
1234 _box->pack_start (_view, false, false);
1236 Label* label = manage (new Label);
1237 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
1239 _box->pack_start (*label, false, false);
1242 ControlProtocolManager& m = ControlProtocolManager::instance ();
1243 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1244 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1246 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1247 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1250 void parameter_changed (std::string const &)
1255 void set_state_from_config ()
1259 ControlProtocolManager& m = ControlProtocolManager::instance ();
1260 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1262 if (!(*i)->mandatory) {
1263 TreeModel::Row r = *_store->append ();
1264 r[_model.name] = (*i)->name;
1265 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1266 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
1267 r[_model.protocol_info] = *i;
1274 void protocol_status_changed (ControlProtocolInfo* cpi) {
1276 TreeModel::Children rows = _store->children();
1278 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1279 string n = ((*x)[_model.name]);
1281 if ((*x)[_model.protocol_info] == cpi) {
1282 _ignore_view_change++;
1283 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1284 _ignore_view_change--;
1290 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1292 TreeModel::Row r = *i;
1294 if (_ignore_view_change) {
1298 ControlProtocolInfo* cpi = r[_model.protocol_info];
1303 bool const was_enabled = (cpi->protocol != 0);
1304 bool const is_enabled = r[_model.enabled];
1307 if (was_enabled != is_enabled) {
1310 ControlProtocolManager::instance().activate (*cpi);
1312 ControlProtocolManager::instance().deactivate (*cpi);
1316 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
1317 bool const is_feedback = r[_model.feedback];
1319 if (was_feedback != is_feedback && cpi->protocol) {
1320 cpi->protocol->set_feedback (is_feedback);
1324 void edit_clicked (GdkEventButton* ev)
1326 if (ev->type != GDK_2BUTTON_PRESS) {
1331 ControlProtocolInfo* cpi;
1334 row = *(_view.get_selection()->get_selected());
1335 if (!row[_model.enabled]) {
1338 cpi = row[_model.protocol_info];
1339 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1342 Box* box = (Box*) cpi->protocol->get_gui ();
1346 if (box->get_parent()) {
1347 static_cast<ArdourWindow*>(box->get_parent())->present();
1350 string title = row[_model.name];
1351 /* once created, the window is managed by the surface itself (as ->get_parent())
1352 * Surface's tear_down_gui() is called on session close, when de-activating
1353 * or re-initializing a surface.
1354 * tear_down_gui() hides an deletes the Window if it exists.
1356 ArdourWindow* win = new ArdourWindow (_parent, title);
1357 win->set_title ("Control Protocol Options");
1363 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1367 ControlSurfacesModelColumns ()
1372 add (protocol_info);
1375 TreeModelColumn<string> name;
1376 TreeModelColumn<bool> enabled;
1377 TreeModelColumn<bool> feedback;
1378 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1381 Glib::RefPtr<ListStore> _store;
1382 ControlSurfacesModelColumns _model;
1384 Gtk::Window& _parent;
1385 PBD::ScopedConnection protocol_status_connection;
1386 uint32_t _ignore_view_change;
1389 class VideoTimelineOptions : public OptionEditorBox
1392 VideoTimelineOptions (RCConfiguration* c)
1394 , _show_video_export_info_button (_("Show Video Export Info before export"))
1395 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1396 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1398 Table* t = manage (new Table (2, 6));
1399 t->set_spacings (4);
1401 t->attach (_video_advanced_setup_button, 0, 2, 0, 1);
1402 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1403 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1404 _("<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."));
1406 Label* l = manage (new Label (_("Video Server URL:")));
1407 l->set_alignment (0, 0.5);
1408 t->attach (*l, 0, 1, 1, 2, FILL);
1409 t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL);
1410 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1411 _("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"));
1413 l = manage (new Label (_("Video Folder:")));
1414 l->set_alignment (0, 0.5);
1415 t->attach (*l, 0, 1, 2, 3, FILL);
1416 t->attach (_video_server_docroot_entry, 1, 2, 2, 3);
1417 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1418 _("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."));
1420 /* small vspace y=3..4 */
1422 t->attach (_show_video_export_info_button, 0, 2, 4, 5);
1423 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1424 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1425 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1427 t->attach (_show_video_server_dialog_button, 0, 2, 5, 6);
1428 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1429 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1430 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1432 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1433 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1434 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1435 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1437 _box->pack_start (*t,true,true);
1440 void server_url_changed ()
1442 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1445 void server_docroot_changed ()
1447 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1450 void show_video_export_info_toggled ()
1452 bool const x = _show_video_export_info_button.get_active ();
1453 _rc_config->set_show_video_export_info (x);
1456 void show_video_server_dialog_toggled ()
1458 bool const x = _show_video_server_dialog_button.get_active ();
1459 _rc_config->set_show_video_server_dialog (x);
1462 void video_advanced_setup_toggled ()
1464 bool const x = _video_advanced_setup_button.get_active ();
1465 _rc_config->set_video_advanced_setup(x);
1468 void parameter_changed (string const & p)
1470 if (p == "video-server-url") {
1471 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1472 } else if (p == "video-server-docroot") {
1473 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1474 } else if (p == "show-video-export-info") {
1475 bool const x = _rc_config->get_show_video_export_info();
1476 _show_video_export_info_button.set_active (x);
1477 } else if (p == "show-video-server-dialog") {
1478 bool const x = _rc_config->get_show_video_server_dialog();
1479 _show_video_server_dialog_button.set_active (x);
1480 } else if (p == "video-advanced-setup") {
1481 bool const x = _rc_config->get_video_advanced_setup();
1482 _video_advanced_setup_button.set_active(x);
1483 _video_server_docroot_entry.set_sensitive(x);
1484 _video_server_url_entry.set_sensitive(x);
1488 void set_state_from_config ()
1490 parameter_changed ("video-server-url");
1491 parameter_changed ("video-server-docroot");
1492 parameter_changed ("video-monitor-setup-dialog");
1493 parameter_changed ("show-video-export-info");
1494 parameter_changed ("show-video-server-dialog");
1495 parameter_changed ("video-advanced-setup");
1499 RCConfiguration* _rc_config;
1500 Entry _video_server_url_entry;
1501 Entry _video_server_docroot_entry;
1502 CheckButton _show_video_export_info_button;
1503 CheckButton _show_video_server_dialog_button;
1504 CheckButton _video_advanced_setup_button;
1507 class PluginOptions : public OptionEditorBox
1510 PluginOptions (RCConfiguration* c, UIConfiguration* uic)
1513 , _display_plugin_scan_progress (_("Always Display Plugin Scan Progress"))
1514 , _discover_vst_on_start (_("Scan for [new] VST Plugins on Application Start"))
1515 , _discover_au_on_start (_("Scan for AudioUnit Plugins on Application Start"))
1516 , _verbose_plugin_scan (_("Verbose Plugin Scan"))
1517 , _timeout_adjustment (0, 0, 3000, 50, 50)
1518 , _timeout_slider (_timeout_adjustment)
1521 std::stringstream ss;
1522 Table* t = manage (new Table (2, 6));
1523 t->set_spacings (4);
1527 ss << "<b>" << _("General") << "</b>";
1528 l = manage (left_aligned_label (ss.str()));
1529 l->set_use_markup (true);
1530 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1531 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1533 b = manage (new Button (_("Scan for Plugins")));
1534 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1535 t->attach (*b, 0, 2, n, n+1, FILL); ++n;
1537 t->attach (_display_plugin_scan_progress, 0, 2, n, n+1); ++n;
1538 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1539 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1540 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
1542 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
1543 _timeout_slider.set_digits (0);
1544 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &PluginOptions::timeout_changed));
1546 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1547 _("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."));
1549 l = manage (left_aligned_label (_("Scan Time Out [deciseconds]")));;
1550 HBox* h = manage (new HBox);
1552 h->pack_start (*l, false, false);
1553 h->pack_start (_timeout_slider, true, true);
1554 t->attach (*h, 0, 2, n, n+1); ++n;
1557 ss << "<b>" << _("VST") << "</b>";
1558 l = manage (left_aligned_label (ss.str()));
1559 l->set_use_markup (true);
1560 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1561 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1563 b = manage (new Button (_("Clear VST Cache")));
1564 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_cache_clicked));
1565 t->attach (*b, 0, 1, n, n+1, FILL);
1567 b = manage (new Button (_("Clear VST Blacklist")));
1568 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_blacklist_clicked));
1569 t->attach (*b, 1, 2, n, n+1, FILL);
1572 t->attach (_discover_vst_on_start, 0, 2, n, n+1); ++n;
1573 _discover_vst_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_vst_on_start_toggled));
1574 Gtkmm2ext::UI::instance()->set_tip (_discover_vst_on_start,
1575 _("<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"));
1577 #ifdef LXVST_SUPPORT
1578 t->attach (*manage (left_aligned_label (_("Linux VST Path:"))), 0, 1, n, n+1);
1579 b = manage (new Button (_("Edit")));
1580 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_lxvst_path_clicked));
1581 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1584 #ifdef WINDOWS_VST_SUPPORT
1585 t->attach (*manage (left_aligned_label (_("Windows VST Path:"))), 0, 1, n, n+1);
1586 b = manage (new Button (_("Edit")));
1587 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_vst_path_clicked));
1588 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1590 // currently verbose logging is only implemented for Windows VST.
1591 t->attach (_verbose_plugin_scan, 0, 2, n, n+1); ++n;
1592 _verbose_plugin_scan.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::verbose_plugin_scan_toggled));
1593 Gtkmm2ext::UI::instance()->set_tip (_verbose_plugin_scan,
1594 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
1598 #ifdef AUDIOUNIT_SUPPORT
1600 ss << "<b>" << _("Audio Unit") << "</b>";
1601 l = manage (left_aligned_label (ss.str()));
1602 l->set_use_markup (true);
1603 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1604 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1606 t->attach (_discover_au_on_start, 0, 2, n, n+1); ++n;
1607 _discover_au_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_au_on_start_toggled));
1608 Gtkmm2ext::UI::instance()->set_tip (_discover_au_on_start,
1609 _("<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."));
1612 b = manage (new Button (_("Clear AU Cache")));
1613 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_cache_clicked));
1614 t->attach (*b, 0, 1, n, n+1, FILL);
1616 b = manage (new Button (_("Clear AU Blacklist")));
1617 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_blacklist_clicked));
1618 t->attach (*b, 1, 2, n, n+1, FILL);
1622 _box->pack_start (*t,true,true);
1625 void parameter_changed (string const & p) {
1626 if (p == "show-plugin-scan-window") {
1627 bool const x = _ui_config->get_show_plugin_scan_window();
1628 _display_plugin_scan_progress.set_active (x);
1630 else if (p == "discover-vst-on-start") {
1631 bool const x = _rc_config->get_discover_vst_on_start();
1632 _discover_vst_on_start.set_active (x);
1634 else if (p == "vst-scan-timeout") {
1635 int const x = _rc_config->get_vst_scan_timeout();
1636 _timeout_adjustment.set_value (x);
1638 else if (p == "discover-audio-units") {
1639 bool const x = _rc_config->get_discover_audio_units();
1640 _discover_au_on_start.set_active (x);
1642 else if (p == "verbose-plugin-scan") {
1643 bool const x = _rc_config->get_verbose_plugin_scan();
1644 _verbose_plugin_scan.set_active (x);
1648 void set_state_from_config () {
1649 parameter_changed ("show-plugin-scan-window");
1650 parameter_changed ("discover-vst-on-start");
1651 parameter_changed ("vst-scan-timeout");
1652 parameter_changed ("discover-audio-units");
1653 parameter_changed ("verbose-plugin-scan");
1657 RCConfiguration* _rc_config;
1658 UIConfiguration* _ui_config;
1659 CheckButton _display_plugin_scan_progress;
1660 CheckButton _discover_vst_on_start;
1661 CheckButton _discover_au_on_start;
1662 CheckButton _verbose_plugin_scan;
1663 Adjustment _timeout_adjustment;
1664 HScale _timeout_slider;
1666 void display_plugin_scan_progress_toggled () {
1667 bool const x = _display_plugin_scan_progress.get_active();
1668 _ui_config->set_show_plugin_scan_window(x);
1671 void discover_vst_on_start_toggled () {
1672 bool const x = _discover_vst_on_start.get_active();
1673 _rc_config->set_discover_vst_on_start(x);
1676 void discover_au_on_start_toggled () {
1677 bool const x = _discover_au_on_start.get_active();
1678 _rc_config->set_discover_audio_units(x);
1681 void verbose_plugin_scan_toggled () {
1682 bool const x = _verbose_plugin_scan.get_active();
1683 _rc_config->set_verbose_plugin_scan(x);
1686 void timeout_changed () {
1687 int x = floor(_timeout_adjustment.get_value());
1688 _rc_config->set_vst_scan_timeout(x);
1691 void clear_vst_cache_clicked () {
1692 PluginManager::instance().clear_vst_cache();
1695 void clear_vst_blacklist_clicked () {
1696 PluginManager::instance().clear_vst_blacklist();
1699 void clear_au_cache_clicked () {
1700 PluginManager::instance().clear_au_cache();
1703 void clear_au_blacklist_clicked () {
1704 PluginManager::instance().clear_au_blacklist();
1708 void edit_vst_path_clicked () {
1709 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1710 _("Set Windows VST Search Path"),
1711 _rc_config->get_plugin_path_vst(),
1712 PluginManager::instance().get_default_windows_vst_path()
1714 ResponseType r = (ResponseType) pd->run ();
1716 if (r == RESPONSE_ACCEPT) {
1717 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
1722 // todo consolidate with edit_vst_path_clicked..
1723 void edit_lxvst_path_clicked () {
1724 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1725 _("Set Linux VST Search Path"),
1726 _rc_config->get_plugin_path_lxvst(),
1727 PluginManager::instance().get_default_lxvst_path()
1729 ResponseType r = (ResponseType) pd->run ();
1731 if (r == RESPONSE_ACCEPT) {
1732 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
1737 void refresh_clicked () {
1738 PluginManager::instance().refresh();
1743 /** A class which allows control of visibility of some editor components usign
1744 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1745 * which has the correct members, but with null widget pointers. This
1746 * class allows the user to set visibility of the members, the details
1747 * of which are stored in a configuration variable which can be watched
1748 * by parts of the editor that actually contain the widgets whose visibility
1749 * is being controlled.
1752 class VisibilityOption : public Option
1755 /** @param name User-visible name for this group.
1756 * @param g `Dummy' VisibilityGroup (as described above).
1757 * @param get Method to get the value of the appropriate configuration variable.
1758 * @param set Method to set the value of the appropriate configuration variable.
1760 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1761 : Option (g->get_state_name(), name)
1763 , _visibility_group (g)
1767 /* Watch for changes made by the user to our members */
1768 _visibility_group->VisibilityChanged.connect_same_thread (
1769 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1773 void set_state_from_config ()
1775 /* Set our state from the current configuration */
1776 _visibility_group->set_state (_get ());
1779 void add_to_page (OptionEditorPage* p)
1781 _heading.add_to_page (p);
1782 add_widget_to_page (p, _visibility_group->list_view ());
1785 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1790 /* The user has changed something, so reflect this change
1791 in the RCConfiguration.
1793 _set (_visibility_group->get_state_value ());
1796 OptionEditorHeading _heading;
1797 VisibilityGroup* _visibility_group;
1798 sigc::slot<std::string> _get;
1799 sigc::slot<bool, std::string> _set;
1800 PBD::ScopedConnection _visibility_group_connection;
1805 RCOptionEditor::RCOptionEditor ()
1806 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1807 , _rc_config (Config)
1808 , _ui_config (ARDOUR_UI::config())
1809 , _mixer_strip_visibility ("mixer-element-visibility")
1813 uint32_t hwcpus = hardware_concurrency ();
1815 BoolComboOption* bco;
1818 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1820 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1822 _("Signal processing uses"),
1823 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1824 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1827 procs->add (-1, _("all but one processor"));
1828 procs->add (0, _("all available processors"));
1830 for (uint32_t i = 1; i <= hwcpus; ++i) {
1831 procs->add (i, string_compose (_("%1 processors"), i));
1834 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1836 add_option (_("Misc"), procs);
1839 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1841 add_option (_("Misc"), new UndoOptions (_rc_config));
1843 add_option (_("Misc"),
1845 "verify-remove-last-capture",
1846 _("Verify removal of last capture"),
1847 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1848 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1851 add_option (_("Misc"),
1853 "periodic-safety-backups",
1854 _("Make periodic backups of the session file"),
1855 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1856 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1859 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1861 add_option (_("Misc"),
1863 "only-copy-imported-files",
1864 _("Always copy imported files"),
1865 sigc::mem_fun (*_ui_config, &UIConfiguration::get_only_copy_imported_files),
1866 sigc::mem_fun (*_ui_config, &UIConfiguration::set_only_copy_imported_files)
1869 add_option (_("Misc"), new DirectoryOption (
1870 X_("default-session-parent-dir"),
1871 _("Default folder for new sessions:"),
1872 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1873 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1876 add_option (_("Misc"),
1877 new SpinOption<uint32_t> (
1878 "max-recent-sessions",
1879 _("Maximum number of recent sessions"),
1880 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1881 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1885 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1887 add_option (_("Misc"), new ClickOptions (_rc_config, this));
1889 add_option (_("Misc"),
1892 _("Click gain level"),
1893 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1894 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1897 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1899 add_option (_("Misc"),
1900 new SpinOption<double> (
1901 "automation-thinning-factor",
1902 _("Thinning factor (larger value => less data)"),
1903 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1904 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1908 add_option (_("Misc"),
1909 new SpinOption<double> (
1910 "automation-interval-msecs",
1911 _("Automation sampling interval (milliseconds)"),
1912 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1913 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1919 add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options")));
1923 tsf = new BoolOption (
1924 "latched-record-enable",
1925 _("Keep record-enable engaged on stop"),
1926 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1927 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1929 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1930 add_option (_("Transport"), tsf);
1932 tsf = new BoolOption (
1934 _("Play loop is a transport mode"),
1935 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1936 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1938 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1939 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1940 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1941 add_option (_("Transport"), tsf);
1943 tsf = new BoolOption (
1944 "stop-recording-on-xrun",
1945 _("Stop recording when an xrun occurs"),
1946 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1947 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1949 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1950 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
1952 add_option (_("Transport"), tsf);
1954 tsf = new BoolOption (
1955 "create-xrun-marker",
1956 _("Create markers where xruns occur"),
1957 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
1958 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
1960 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1961 add_option (_("Transport"), tsf);
1963 tsf = new BoolOption (
1964 "stop-at-session-end",
1965 _("Stop at the end of the session"),
1966 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
1967 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
1969 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1970 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
1971 "when it reaches the current session end marker\n\n"
1972 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
1974 add_option (_("Transport"), tsf);
1976 tsf = new BoolOption (
1978 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
1979 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
1980 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
1982 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1983 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
1984 "preventing any need to do a transport locate at the end of the loop\n\n"
1985 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
1986 "which will often cause a small click or delay"), PROGRAM_NAME));
1987 add_option (_("Transport"), tsf);
1989 tsf = new BoolOption (
1990 "disable-disarm-during-roll",
1991 _("Disable per-track record disarm while rolling"),
1992 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
1993 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
1995 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"));
1996 add_option (_("Transport"), tsf);
1998 tsf = new BoolOption (
2000 _("12dB gain reduction during fast-forward and fast-rewind"),
2001 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
2002 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
2004 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
2005 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
2006 add_option (_("Transport"), tsf);
2008 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
2010 _sync_source = new ComboOption<SyncSource> (
2012 _("External timecode source"),
2013 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
2014 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
2017 add_option (_("Transport"), _sync_source);
2019 _sync_framerate = new BoolOption (
2020 "timecode-sync-frame-rate",
2021 _("Match session video frame rate to external timecode"),
2022 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
2023 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
2025 Gtkmm2ext::UI::instance()->set_tip
2026 (_sync_framerate->tip_widget(),
2027 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
2028 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
2029 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
2030 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
2031 "timecode standard and the session standard."), PROGRAM_NAME));
2033 add_option (_("Transport"), _sync_framerate);
2035 _sync_genlock = new BoolOption (
2036 "timecode-source-is-synced",
2037 _("Sync-lock timecode to clock (disable drift compensation)"),
2038 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
2039 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
2041 Gtkmm2ext::UI::instance()->set_tip
2042 (_sync_genlock->tip_widget(),
2043 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
2044 "Sync Lock indicates that the selected external timecode source shares clock-sync "
2045 "(Black & Burst, Wordclock, etc) with the audio interface. "
2046 "This option disables drift compensation. The transport speed is fixed at 1.0. "
2047 "Vari-speed LTC will be ignored and cause drift."
2049 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
2050 "timecode sources shares clock sync."
2054 add_option (_("Transport"), _sync_genlock);
2056 _sync_source_2997 = new BoolOption (
2057 "timecode-source-2997",
2058 _("Lock to 29.9700 fps instead of 30000/1001"),
2059 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
2060 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
2062 Gtkmm2ext::UI::instance()->set_tip
2063 (_sync_source_2997->tip_widget(),
2064 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
2065 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
2066 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
2067 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
2068 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
2069 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
2072 add_option (_("Transport"), _sync_source_2997);
2074 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
2076 _ltc_port = new ComboStringOption (
2078 _("LTC incoming port"),
2079 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
2080 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
2083 vector<string> physical_inputs;
2084 physical_inputs.push_back (_("None"));
2085 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
2086 _ltc_port->set_popdown_strings (physical_inputs);
2088 populate_sync_options ();
2090 add_option (_("Transport"), _ltc_port);
2092 // TODO; rather disable this button than not compile it..
2093 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
2095 add_option (_("Transport"),
2098 _("Enable LTC generator"),
2099 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
2100 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
2103 _ltc_send_continuously = new BoolOption (
2104 "ltc-send-continuously",
2105 _("Send LTC while stopped"),
2106 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
2107 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
2109 Gtkmm2ext::UI::instance()->set_tip
2110 (_ltc_send_continuously->tip_widget(),
2111 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
2112 add_option (_("Transport"), _ltc_send_continuously);
2114 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
2115 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
2116 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
2117 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
2119 Gtkmm2ext::UI::instance()->set_tip
2120 (_ltc_volume_slider->tip_widget(),
2121 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
2123 add_option (_("Transport"), _ltc_volume_slider);
2124 parameter_changed ("send-ltc");
2126 parameter_changed ("sync-source");
2130 add_option (S_("Editor"),
2132 "draggable-playhead",
2133 _("Allow dragging of playhead"),
2134 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_draggable_playhead),
2135 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_draggable_playhead)
2138 add_option (_("Editor"),
2140 "automation-follows-regions",
2141 _("Move relevant automation when audio regions are moved"),
2142 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2143 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2146 add_option (_("Editor"),
2148 "show-track-meters",
2149 _("Show meters on tracks in the editor"),
2150 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_track_meters),
2151 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_track_meters)
2154 add_option (_("Editor"),
2156 "show-editor-meter",
2157 _("Display master-meter in the toolbar"),
2158 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_editor_meter),
2159 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_editor_meter)
2162 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2163 "default-fade-shape",
2164 _("Default fade shape"),
2165 sigc::mem_fun (*_rc_config,
2166 &RCConfiguration::get_default_fade_shape),
2167 sigc::mem_fun (*_rc_config,
2168 &RCConfiguration::set_default_fade_shape)
2171 fadeshape->add (FadeLinear,
2172 _("Linear (for highly correlated material)"));
2173 fadeshape->add (FadeConstantPower, _("Constant power"));
2174 fadeshape->add (FadeSymmetric, _("Symmetric"));
2175 fadeshape->add (FadeSlow, _("Slow"));
2176 fadeshape->add (FadeFast, _("Fast"));
2178 add_option (_("Editor"), fadeshape);
2181 bco = new BoolComboOption (
2182 "use-overlap-equivalency",
2183 _("Regions in active edit groups are edited together"),
2184 _("whenever they overlap in time"),
2185 _("only if they have identical length, position and origin"),
2186 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2187 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2190 add_option (_("Editor"), bco);
2192 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2194 _("Layering model"),
2195 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2196 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2199 lm->add (LaterHigher, _("later is higher"));
2200 lm->add (Manual, _("manual layering"));
2201 add_option (_("Editor"), lm);
2203 add_option (_("Editor"),
2205 "rubberbanding-snaps-to-grid",
2206 _("Make rubberband selection rectangle snap to the grid"),
2207 sigc::mem_fun (*_ui_config, &UIConfiguration::get_rubberbanding_snaps_to_grid),
2208 sigc::mem_fun (*_ui_config, &UIConfiguration::set_rubberbanding_snaps_to_grid)
2211 add_option (_("Editor"),
2214 _("Show waveforms in regions"),
2215 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms),
2216 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms)
2219 add_option (_("Editor"),
2220 new BoolComboOption (
2221 "show-region-gain-envelopes",
2222 _("Show gain envelopes in audio regions"),
2224 _("only in Draw and Internal Edit modes"),
2225 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_region_gain),
2226 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_region_gain)
2229 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
2231 _("Waveform scale"),
2232 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_scale),
2233 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_scale)
2236 wfs->add (Linear, _("linear"));
2237 wfs->add (Logarithmic, _("logarithmic"));
2239 add_option (_("Editor"), wfs);
2241 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
2243 _("Waveform shape"),
2244 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_shape),
2245 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_shape)
2248 wfsh->add (Traditional, _("traditional"));
2249 wfsh->add (Rectified, _("rectified"));
2251 add_option (_("Editor"), wfsh);
2253 add_option (_("Editor"), new ClipLevelOptions (_ui_config));
2255 add_option (_("Editor"),
2257 "show-waveforms-while-recording",
2258 _("Show waveforms for audio while it is being recorded"),
2259 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms_while_recording),
2260 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms_while_recording)
2263 add_option (_("Editor"),
2266 _("Show zoom toolbar"),
2267 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_zoom_tools),
2268 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_zoom_tools)
2271 add_option (_("Editor"),
2273 "update-editor-during-summary-drag",
2274 _("Update editor window during drags of the summary"),
2275 sigc::mem_fun (*_ui_config, &UIConfiguration::get_update_editor_during_summary_drag),
2276 sigc::mem_fun (*_ui_config, &UIConfiguration::set_update_editor_during_summary_drag)
2279 bo = new BoolOption (
2281 _("Name new markers"),
2282 sigc::mem_fun (*_ui_config, &UIConfiguration::get_name_new_markers),
2283 sigc::mem_fun (*_ui_config, &UIConfiguration::set_name_new_markers)
2286 add_option (_("Editor"), bo);
2287 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."
2288 "\n\nYou can always rename markers by right-clicking on them"));
2290 add_option (_("Editor"),
2292 "autoscroll-editor",
2293 _("Auto-scroll editor window when dragging near its edges"),
2294 sigc::mem_fun (*_ui_config, &UIConfiguration::get_autoscroll_editor),
2295 sigc::mem_fun (*_ui_config, &UIConfiguration::set_autoscroll_editor)
2298 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2299 "region-selection-after-split",
2300 _("After splitting selected regions, select"),
2301 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2302 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2304 // TODO: decide which of these modes are really useful
2305 rsas->add(None, _("no regions"));
2306 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2307 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2308 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2309 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2310 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2311 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2312 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2314 add_option (_("Editor"), rsas);
2319 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2321 add_option (_("Audio"), new BufferingOptions (_rc_config));
2323 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2325 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2327 _("Record monitoring handled by"),
2328 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2329 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2332 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2333 mm->add (HardwareMonitoring, _("via Audio Driver"));
2336 string prog (PROGRAM_NAME);
2337 boost::algorithm::to_lower (prog);
2338 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2339 mm->add (ExternalMonitoring, _("audio hardware"));
2341 add_option (_("Audio"), mm);
2343 add_option (_("Audio"),
2345 "tape-machine-mode",
2346 _("Tape machine mode"),
2347 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2348 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2351 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
2353 add_option (_("Audio"),
2355 "auto-connect-standard-busses",
2356 _("Auto-connect master/monitor busses"),
2357 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2358 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2361 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2362 "input-auto-connect",
2363 _("Connect track inputs"),
2364 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2365 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2368 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2369 iac->add (ManualConnect, _("manually"));
2371 add_option (_("Audio"), iac);
2373 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2374 "output-auto-connect",
2375 _("Connect track and bus outputs"),
2376 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2377 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2380 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2381 oac->add (AutoConnectMaster, _("automatically to master bus"));
2382 oac->add (ManualConnect, _("manually"));
2384 add_option (_("Audio"), oac);
2386 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2388 add_option (_("Audio"),
2390 "denormal-protection",
2391 _("Use DC bias to protect against denormals"),
2392 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2393 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2396 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2398 _("Processor handling"),
2399 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2400 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2404 dm->add (DenormalNone, _("no processor handling"));
2406 FPU* fpu = FPU::instance();
2408 if (fpu->has_flush_to_zero()) {
2410 dm->add (DenormalFTZ, _("use FlushToZero"));
2411 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2412 _rc_config->set_denormal_model(DenormalNone);
2415 if (fpu->has_denormals_are_zero()) {
2417 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2418 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2419 _rc_config->set_denormal_model(DenormalNone);
2422 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2424 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2425 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2426 _rc_config->set_denormal_model(DenormalNone);
2430 dm->set_sensitive(false);
2433 add_option (_("Audio"), dm);
2435 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
2437 add_option (_("Audio"),
2439 "plugins-stop-with-transport",
2440 _("Silence plugins when the transport is stopped"),
2441 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
2442 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
2445 add_option (_("Audio"),
2447 "new-plugins-active",
2448 _("Make new plugins active"),
2449 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
2450 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
2453 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2455 add_option (_("Audio"),
2457 "auto-analyse-audio",
2458 _("Enable automatic analysis of audio"),
2459 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2460 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2463 add_option (_("Audio"),
2465 "replicate-missing-region-channels",
2466 _("Replicate missing region channels"),
2467 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2468 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2473 add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
2475 add_option (_("Solo / mute"),
2478 _("Solo-in-place mute cut (dB)"),
2479 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2480 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2483 _solo_control_is_listen_control = new BoolOption (
2484 "solo-control-is-listen-control",
2485 _("Solo controls are Listen controls"),
2486 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2487 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2490 add_option (_("Solo / mute"), _solo_control_is_listen_control);
2492 _listen_position = new ComboOption<ListenPosition> (
2494 _("Listen Position"),
2495 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2496 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2499 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2500 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2502 add_option (_("Solo / mute"), _listen_position);
2504 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2506 _("PFL signals come from"),
2507 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2508 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2511 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2512 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2514 add_option (_("Solo / mute"), pp);
2516 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2518 _("AFL signals come from"),
2519 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2520 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2523 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2524 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2526 add_option (_("Solo / mute"), pa);
2528 parameter_changed ("use-monitor-bus");
2530 add_option (_("Solo / mute"),
2533 _("Exclusive solo"),
2534 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2535 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2538 add_option (_("Solo / mute"),
2541 _("Show solo muting"),
2542 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2543 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2546 add_option (_("Solo / mute"),
2548 "solo-mute-override",
2549 _("Soloing overrides muting"),
2550 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2551 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2554 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
2556 add_option (_("Solo / mute"),
2558 "mute-affects-pre-fader",
2559 _("Mute affects pre-fader sends"),
2560 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2561 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2564 add_option (_("Solo / mute"),
2566 "mute-affects-post-fader",
2567 _("Mute affects post-fader sends"),
2568 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2569 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2572 add_option (_("Solo / mute"),
2574 "mute-affects-control-outs",
2575 _("Mute affects control outputs"),
2576 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2577 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2580 add_option (_("Solo / mute"),
2582 "mute-affects-main-outs",
2583 _("Mute affects main outputs"),
2584 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2585 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2588 add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
2590 add_option (_("Solo / mute"),
2592 "link-send-and-route-panner",
2593 _("Link panners of Aux and External Sends with main panner by default"),
2594 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2595 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2598 add_option (_("MIDI"),
2599 new SpinOption<float> (
2601 _("MIDI read-ahead time (seconds)"),
2602 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2603 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2608 add_option (_("MIDI"),
2611 _("Send MIDI Clock"),
2612 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2613 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2616 add_option (_("MIDI"),
2619 _("Send MIDI Time Code"),
2620 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2621 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2624 add_option (_("MIDI"),
2625 new SpinOption<int> (
2626 "mtc-qf-speed-tolerance",
2627 _("Percentage either side of normal transport speed to transmit MTC"),
2628 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2629 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2633 add_option (_("MIDI"),
2636 _("Obey MIDI Machine Control commands"),
2637 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2638 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2641 add_option (_("MIDI"),
2644 _("Send MIDI Machine Control commands"),
2645 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2646 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2649 add_option (_("MIDI"),
2652 _("Send MIDI control feedback"),
2653 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2654 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2657 add_option (_("MIDI"),
2658 new SpinOption<uint8_t> (
2659 "mmc-receive-device-id",
2660 _("Inbound MMC device ID"),
2661 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2662 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2666 add_option (_("MIDI"),
2667 new SpinOption<uint8_t> (
2668 "mmc-send-device-id",
2669 _("Outbound MMC device ID"),
2670 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2671 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2675 add_option (_("MIDI"),
2676 new SpinOption<int32_t> (
2677 "initial-program-change",
2678 _("Initial program change"),
2679 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2680 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2684 add_option (_("MIDI"),
2686 "display-first-midi-bank-as-zero",
2687 _("Display first MIDI bank/program as 0"),
2688 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2689 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2692 add_option (_("MIDI"),
2694 "never-display-periodic-midi",
2695 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2696 sigc::mem_fun (*_ui_config, &UIConfiguration::get_never_display_periodic_midi),
2697 sigc::mem_fun (*_ui_config, &UIConfiguration::set_never_display_periodic_midi)
2700 add_option (_("MIDI"),
2703 _("Sound MIDI notes as they are selected"),
2704 sigc::mem_fun (*_ui_config, &UIConfiguration::get_sound_midi_notes),
2705 sigc::mem_fun (*_ui_config, &UIConfiguration::set_sound_midi_notes)
2708 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2710 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2711 "midi-audition-synth-uri",
2712 _("Midi Audition Synth (LV2)"),
2713 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2714 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2717 audition_synth->add(X_(""), _("None"));
2718 PluginInfoList all_plugs;
2719 PluginManager& manager (PluginManager::instance());
2721 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2723 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2724 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2725 if (!(*i)->is_instrument()) continue;
2726 if ((*i)->type != ARDOUR::LV2) continue;
2727 audition_synth->add((*i)->unique_id, (*i)->name);
2731 add_option (_("MIDI"), audition_synth);
2733 /* USER INTERACTION */
2736 #ifdef PLATFORM_WINDOWS
2739 getenv ("ARDOUR_BUNDLED")
2743 add_option (_("User interaction"),
2745 "enable-translation",
2746 string_compose (_("Use translations of %1 messages\n"
2747 " <i>(requires a restart of %1 to take effect)</i>\n"
2748 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2749 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2750 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2753 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2755 add_option (_("User interaction"), new KeyboardOptions);
2757 /* Control Surfaces */
2759 add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
2761 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2763 _("Control surface remote ID"),
2764 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2765 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2768 rm->add (UserOrdered, _("assigned by user"));
2769 rm->add (MixerOrdered, _("follows order of mixer"));
2771 add_option (_("Control Surfaces"), rm);
2773 /* VIDEO Timeline */
2774 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2776 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2777 /* Plugin options (currrently VST only) */
2778 add_option (_("Plugins"), new PluginOptions (_rc_config, _ui_config));
2783 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
2784 BoolOption* bgc = new BoolOption (
2785 "cairo-image-surface",
2786 _("Disable Graphics Hardware Acceleration (requires restart)"),
2787 sigc::mem_fun (*_ui_config, &UIConfiguration::get_cairo_image_surface),
2788 sigc::mem_fun (*_ui_config, &UIConfiguration::set_cairo_image_surface)
2791 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
2792 _("Render large parts of the application user-interface in software, instead of using 2D-graphics acceleration.\nThis requires restarting %1 before having an effect"), PROGRAM_NAME));
2793 add_option (S_("Preferences|GUI"), bgc);
2796 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
2797 BoolOption* bgo = new BoolOption (
2799 _("Possibly improve slow graphical performance (requires restart)"),
2800 sigc::mem_fun (*_ui_config, &UIConfiguration::get_buggy_gradients),
2801 sigc::mem_fun (*_ui_config, &UIConfiguration::set_buggy_gradients)
2804 Gtkmm2ext::UI::instance()->set_tip (bgo->tip_widget(), string_compose (_("Disables hardware gradient rendering on buggy video drivers (\"buggy gradients patch\").\nThis requires restarting %1 before having an effect"), PROGRAM_NAME));
2805 add_option (S_("Preferences|GUI"), bgo);
2808 add_option (S_("Preferences|GUI"),
2811 _("Graphically indicate mouse pointer hovering over various widgets"),
2812 sigc::mem_fun (*_ui_config, &UIConfiguration::get_widget_prelight),
2813 sigc::mem_fun (*_ui_config, &UIConfiguration::set_widget_prelight)
2816 #ifdef TOOLTIPS_GOT_FIXED
2817 add_option (S_("Preferences|GUI"),
2820 _("Show tooltips if mouse hovers over a control"),
2821 sigc::mem_fun (*_ui_config, &UIConfiguration::get_use_tooltips),
2822 sigc::mem_fun (*_ui_config, &UIConfiguration::set_use_tooltips)
2826 add_option (S_("Preferences|GUI"),
2828 "show-name-highlight",
2829 _("Use name highlight bars in region displays (requires a restart)"),
2830 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_name_highlight),
2831 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_name_highlight)
2835 /* font scaling does nothing with GDK/Quartz */
2836 add_option (S_("Preferences|GUI"), new FontScalingOptions (_ui_config));
2839 add_option (S_("GUI"),
2841 "super-rapid-clock-update",
2842 _("update transport clock display at FPS instead of every 100ms"),
2843 sigc::mem_fun (*_ui_config, &UIConfiguration::get_super_rapid_clock_update),
2844 sigc::mem_fun (*_ui_config, &UIConfiguration::set_super_rapid_clock_update)
2848 /* Image cache size */
2850 Gtk::Adjustment *ics = manage (new Gtk::Adjustment(0, 1, 1024, 10)); /* 1 MB to 1GB in steps of 10MB */
2851 HSliderOption *sics = new HSliderOption("waveform-cache-size",
2852 _("Waveform image cache size (megabytes)"),
2854 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_waveform_cache_size),
2855 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_waveform_cache_size)
2857 sics->scale().set_digits (0);
2858 Gtkmm2ext::UI::instance()->set_tip
2859 (sics->tip_widget(),
2860 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
2861 add_option (S_("Preferences|GUI"), sics);
2863 /* Lock GUI timeout */
2865 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
2866 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2867 _("Lock timeout (seconds)"),
2869 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_lock_gui_after_seconds),
2870 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_lock_gui_after_seconds)
2872 slts->scale().set_digits (0);
2873 Gtkmm2ext::UI::instance()->set_tip
2874 (slts->tip_widget(),
2875 _("Lock GUI after this many idle seconds (zero to never lock)"));
2876 add_option (S_("Preferences|GUI"), slts);
2878 /* The names of these controls must be the same as those given in MixerStrip
2879 for the actual widgets being controlled.
2881 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
2882 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2883 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
2884 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
2885 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
2886 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2889 S_("Preferences|GUI"),
2890 new VisibilityOption (
2892 &_mixer_strip_visibility,
2893 sigc::mem_fun (*_ui_config, &UIConfiguration::get_mixer_strip_visibility),
2894 sigc::mem_fun (*_ui_config, &UIConfiguration::set_mixer_strip_visibility)
2898 add_option (S_("Preferences|GUI"),
2900 "default-narrow_ms",
2901 _("Use narrow strips in the mixer by default"),
2902 sigc::mem_fun (*_ui_config, &UIConfiguration::get_default_narrow_ms),
2903 sigc::mem_fun (*_ui_config, &UIConfiguration::set_default_narrow_ms)
2906 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2908 ComboOption<float>* mht = new ComboOption<float> (
2910 _("Peak hold time"),
2911 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_hold),
2912 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_hold)
2915 mht->add (MeterHoldOff, _("off"));
2916 mht->add (MeterHoldShort, _("short"));
2917 mht->add (MeterHoldMedium, _("medium"));
2918 mht->add (MeterHoldLong, _("long"));
2920 add_option (S_("Preferences|Metering"), mht);
2922 ComboOption<float>* mfo = new ComboOption<float> (
2925 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2926 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2929 mfo->add (METER_FALLOFF_OFF, _("off"));
2930 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2931 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2932 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
2933 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2934 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
2935 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
2937 add_option (S_("Preferences|Metering"), mfo);
2939 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2940 "meter-line-up-level",
2941 _("Meter line-up level; 0dBu"),
2942 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_level),
2943 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_level)
2946 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2947 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2948 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2949 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2951 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."));
2953 add_option (S_("Preferences|Metering"), mlu);
2955 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2956 "meter-line-up-din",
2957 _("IEC1/DIN Meter line-up level; 0dBu"),
2958 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_din),
2959 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_din)
2962 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2963 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2964 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2965 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2967 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2969 add_option (S_("Preferences|Metering"), mld);
2971 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2972 "meter-vu-standard",
2973 _("VU Meter standard"),
2974 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_vu_standard),
2975 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_vu_standard)
2978 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2979 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2980 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2981 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2983 add_option (S_("Preferences|Metering"), mvu);
2985 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
2986 HSliderOption *mpks = new HSliderOption("meter-peak",
2987 _("Peak threshold [dBFS]"),
2989 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_peak),
2990 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_peak)
2994 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
2995 "meter-type-master",
2996 _("Default Meter Type for Master Bus"),
2997 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
2998 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3000 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3001 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3002 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3003 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3004 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3005 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3006 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3007 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3009 add_option (S_("Preferences|Metering"), mtm);
3012 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3014 _("Default Meter Type for Busses"),
3015 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3016 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3018 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3019 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3020 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3021 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3022 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3023 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3024 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3025 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3027 add_option (S_("Preferences|Metering"), mtb);
3029 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3031 _("Default Meter Type for Tracks"),
3032 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3033 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3035 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3036 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3038 add_option (S_("Preferences|Metering"), mtt);
3041 Gtkmm2ext::UI::instance()->set_tip
3042 (mpks->tip_widget(),
3043 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
3045 add_option (S_("Preferences|Metering"), mpks);
3047 add_option (S_("Preferences|Metering"),
3050 _("LED meter style"),
3051 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_style_led),
3052 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_style_led)
3055 /* and now the theme manager */
3057 ThemeManager* tm = manage (new ThemeManager);
3058 add_page (_("Theme"), *tm);
3062 RCOptionEditor::parameter_changed (string const & p)
3064 OptionEditor::parameter_changed (p);
3066 if (p == "use-monitor-bus") {
3067 bool const s = Config->get_use_monitor_bus ();
3069 /* we can't use this if we don't have a monitor bus */
3070 Config->set_solo_control_is_listen_control (false);
3072 _solo_control_is_listen_control->set_sensitive (s);
3073 _listen_position->set_sensitive (s);
3074 } else if (p == "sync-source") {
3075 _sync_source->set_sensitive (true);
3077 _sync_source->set_sensitive (!_session->config.get_external_sync());
3079 switch(Config->get_sync_source()) {
3082 _sync_genlock->set_sensitive (true);
3083 _sync_framerate->set_sensitive (true);
3084 _sync_source_2997->set_sensitive (true);
3087 _sync_genlock->set_sensitive (false);
3088 _sync_framerate->set_sensitive (false);
3089 _sync_source_2997->set_sensitive (false);
3092 } else if (p == "send-ltc") {
3093 bool const s = Config->get_send_ltc ();
3094 _ltc_send_continuously->set_sensitive (s);
3095 _ltc_volume_slider->set_sensitive (s);
3099 void RCOptionEditor::ltc_generator_volume_changed () {
3100 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
3104 RCOptionEditor::populate_sync_options ()
3106 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3108 _sync_source->clear ();
3110 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3111 _sync_source->add (*i, sync_source_to_string (*i));
3114 if (sync_opts.empty()) {
3115 _sync_source->set_sensitive(false);
3117 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3118 _rc_config->set_sync_source(sync_opts.front());