2 Copyright (C) 2001-2011 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "gtk2ardour-config.h"
24 #include <cairo/cairo.h>
26 #include <boost/algorithm/string.hpp>
28 #include <gtkmm/liststore.h>
29 #include <gtkmm/stock.h>
30 #include <gtkmm/scale.h>
32 #include <gtkmm2ext/utils.h>
33 #include <gtkmm2ext/slider_controller.h>
34 #include <gtkmm2ext/gtk_ui.h>
35 #include <gtkmm2ext/paths_dialog.h>
40 #include "ardour/audioengine.h"
41 #include "ardour/dB.h"
42 #include "ardour/rc_configuration.h"
43 #include "ardour/control_protocol_manager.h"
44 #include "ardour/plugin_manager.h"
45 #include "control_protocol/control_protocol.h"
47 #include "canvas/wave_view.h"
49 #include "ardour_ui.h"
50 #include "ardour_window.h"
51 #include "ardour_dialog.h"
52 #include "gui_thread.h"
53 #include "meter_patterns.h"
54 #include "midi_tracer.h"
55 #include "rc_option_editor.h"
57 #include "midi_port_dialog.h"
60 #include "theme_manager.h"
61 #include "ui_config.h"
66 using namespace Gtkmm2ext;
68 using namespace ARDOUR;
69 using namespace ARDOUR_UI_UTILS;
71 class ClickOptions : public OptionEditorBox
74 ClickOptions (RCConfiguration* c, Gtk::Window* p)
76 , _click_browse_button (_("Browse..."))
77 , _click_emphasis_browse_button (_("Browse..."))
79 Table* t = manage (new Table (3, 3));
82 Label* l = manage (left_aligned_label (_("Use default Click:")));
83 t->attach (*l, 0, 1, 0, 1, FILL);
84 t->attach (_use_default_click_check_button, 1, 2, 0, 1, FILL);
85 _use_default_click_check_button.signal_toggled().connect (
86 sigc::mem_fun (*this, &ClickOptions::use_default_click_toggled));
88 l = manage (left_aligned_label (_("Click audio file:")));
89 t->attach (*l, 0, 1, 1, 2, FILL);
90 t->attach (_click_path_entry, 1, 2, 1, 2, FILL);
91 _click_browse_button.signal_clicked ().connect (
92 sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
93 t->attach (_click_browse_button, 2, 3, 1, 2, FILL);
95 l = manage (left_aligned_label (_("Click emphasis audio file:")));
96 t->attach (*l, 0, 1, 2, 3, FILL);
97 t->attach (_click_emphasis_path_entry, 1, 2, 2, 3, FILL);
98 _click_emphasis_browse_button.signal_clicked ().connect (
99 sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
100 t->attach (_click_emphasis_browse_button, 2, 3, 2, 3, FILL);
102 _box->pack_start (*t, false, false);
104 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
105 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
107 if (_rc_config->get_click_sound ().empty() &&
108 _rc_config->get_click_emphasis_sound().empty()) {
109 _use_default_click_check_button.set_active (true);
112 _use_default_click_check_button.set_active (false);
116 void parameter_changed (string const & p)
118 if (p == "click-sound") {
119 _click_path_entry.set_text (_rc_config->get_click_sound());
120 } else if (p == "click-emphasis-sound") {
121 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
125 void set_state_from_config ()
127 parameter_changed ("click-sound");
128 parameter_changed ("click-emphasis-sound");
133 void click_browse_clicked ()
135 SoundFileChooser sfdb (_("Choose Click"));
140 if (sfdb.run () == RESPONSE_OK) {
141 click_chosen (sfdb.get_filename());
145 void click_chosen (string const & path)
147 _click_path_entry.set_text (path);
148 _rc_config->set_click_sound (path);
151 void click_changed ()
153 click_chosen (_click_path_entry.get_text ());
156 void click_emphasis_browse_clicked ()
158 SoundFileChooser sfdb (_("Choose Click Emphasis"));
163 if (sfdb.run () == RESPONSE_OK) {
164 click_emphasis_chosen (sfdb.get_filename());
168 void click_emphasis_chosen (string const & path)
170 _click_emphasis_path_entry.set_text (path);
171 _rc_config->set_click_emphasis_sound (path);
174 void click_emphasis_changed ()
176 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
179 void use_default_click_toggled ()
181 if (_use_default_click_check_button.get_active ()) {
182 _rc_config->set_click_sound ("");
183 _rc_config->set_click_emphasis_sound ("");
184 _click_path_entry.set_sensitive (false);
185 _click_emphasis_path_entry.set_sensitive (false);
186 _click_browse_button.set_sensitive (false);
187 _click_emphasis_browse_button.set_sensitive (false);
189 _click_path_entry.set_sensitive (true);
190 _click_emphasis_path_entry.set_sensitive (true);
191 _click_browse_button.set_sensitive (true);
192 _click_emphasis_browse_button.set_sensitive (true);
196 RCConfiguration* _rc_config;
197 CheckButton _use_default_click_check_button;
198 Entry _click_path_entry;
199 Entry _click_emphasis_path_entry;
200 Button _click_browse_button;
201 Button _click_emphasis_browse_button;
204 class UndoOptions : public OptionEditorBox
207 UndoOptions (RCConfiguration* c) :
209 _limit_undo_button (_("Limit undo history to")),
210 _save_undo_button (_("Save undo history of"))
212 Table* t = new Table (2, 3);
215 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
216 _limit_undo_spin.set_range (0, 512);
217 _limit_undo_spin.set_increments (1, 10);
218 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
219 Label* l = manage (left_aligned_label (_("commands")));
220 t->attach (*l, 2, 3, 0, 1);
222 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
223 _save_undo_spin.set_range (0, 512);
224 _save_undo_spin.set_increments (1, 10);
225 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
226 l = manage (left_aligned_label (_("commands")));
227 t->attach (*l, 2, 3, 1, 2);
229 _box->pack_start (*t);
231 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
232 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
233 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
234 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
237 void parameter_changed (string const & p)
239 if (p == "history-depth") {
240 int32_t const d = _rc_config->get_history_depth();
241 _limit_undo_button.set_active (d != 0);
242 _limit_undo_spin.set_sensitive (d != 0);
243 _limit_undo_spin.set_value (d);
244 } else if (p == "save-history") {
245 bool const x = _rc_config->get_save_history ();
246 _save_undo_button.set_active (x);
247 _save_undo_spin.set_sensitive (x);
248 } else if (p == "save-history-depth") {
249 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
253 void set_state_from_config ()
255 parameter_changed ("save-history");
256 parameter_changed ("history-depth");
257 parameter_changed ("save-history-depth");
260 void limit_undo_toggled ()
262 bool const x = _limit_undo_button.get_active ();
263 _limit_undo_spin.set_sensitive (x);
264 int32_t const n = x ? 16 : 0;
265 _limit_undo_spin.set_value (n);
266 _rc_config->set_history_depth (n);
269 void limit_undo_changed ()
271 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
274 void save_undo_toggled ()
276 bool const x = _save_undo_button.get_active ();
277 _rc_config->set_save_history (x);
280 void save_undo_changed ()
282 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
286 RCConfiguration* _rc_config;
287 CheckButton _limit_undo_button;
288 SpinButton _limit_undo_spin;
289 CheckButton _save_undo_button;
290 SpinButton _save_undo_spin;
295 static const struct {
307 { "Key|Shift", GDK_SHIFT_MASK },
308 { "Command", GDK_META_MASK },
309 { "Control", GDK_CONTROL_MASK },
310 { "Option", GDK_MOD1_MASK },
311 { "Command-Shift", GDK_META_MASK|GDK_SHIFT_MASK },
312 { "Command-Option", GDK_MOD1_MASK|GDK_META_MASK },
313 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
314 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
315 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_META_MASK },
318 { "Key|Shift", GDK_SHIFT_MASK },
319 { "Control", GDK_CONTROL_MASK },
320 { "Alt", GDK_MOD1_MASK },
321 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
322 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
323 { "Shift-Alt", GDK_SHIFT_MASK|GDK_MOD1_MASK },
324 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
325 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
326 { "Mod2", GDK_MOD2_MASK },
327 { "Mod3", GDK_MOD3_MASK },
328 { "Windows", GDK_MOD4_MASK },
329 { "Mod5", GDK_MOD5_MASK },
335 class KeyboardOptions : public OptionEditorBox
339 _delete_button_adjustment (3, 1, 12),
340 _delete_button_spin (_delete_button_adjustment),
341 _edit_button_adjustment (3, 1, 5),
342 _edit_button_spin (_edit_button_adjustment),
343 _insert_note_button_adjustment (3, 1, 5),
344 _insert_note_button_spin (_insert_note_button_adjustment)
346 /* internationalize and prepare for use with combos */
349 for (int i = 0; modifiers[i].name; ++i) {
350 dumb.push_back (S_(modifiers[i].name));
353 set_popdown_strings (_edit_modifier_combo, dumb);
354 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
356 for (int x = 0; modifiers[x].name; ++x) {
357 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
358 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
363 Table* t = manage (new Table (5, 11));
369 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
370 l->set_name ("OptionsLabel");
374 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
375 strs.push_back (bf->first);
378 set_popdown_strings (_keyboard_layout_selector, strs);
379 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
380 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
382 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
383 t->attach (_keyboard_layout_selector, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
388 l = manage (left_aligned_label (_("When Clicking:")));
389 l->set_name ("OptionEditorHeading");
390 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
395 l = manage (left_aligned_label (_("Edit using:")));
396 l->set_name ("OptionsLabel");
398 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
399 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
401 l = manage (new Label (_("+ button")));
402 l->set_name ("OptionsLabel");
404 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
405 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
407 _edit_button_spin.set_name ("OptionsEntry");
408 _edit_button_adjustment.set_value (Keyboard::edit_button());
409 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
414 set_popdown_strings (_delete_modifier_combo, dumb);
415 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
417 for (int x = 0; modifiers[x].name; ++x) {
418 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
419 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
424 l = manage (left_aligned_label (_("Delete using:")));
425 l->set_name ("OptionsLabel");
427 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
428 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
430 l = manage (new Label (_("+ button")));
431 l->set_name ("OptionsLabel");
433 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
434 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
436 _delete_button_spin.set_name ("OptionsEntry");
437 _delete_button_adjustment.set_value (Keyboard::delete_button());
438 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
443 set_popdown_strings (_insert_note_modifier_combo, dumb);
444 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
446 for (int x = 0; modifiers[x].name; ++x) {
447 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
448 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
453 l = manage (left_aligned_label (_("Insert note using:")));
454 l->set_name ("OptionsLabel");
456 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
457 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
459 l = manage (new Label (_("+ button")));
460 l->set_name ("OptionsLabel");
462 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
463 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
465 _insert_note_button_spin.set_name ("OptionsEntry");
466 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
467 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
471 l = manage (left_aligned_label (_("When Beginning a Drag:")));
472 l->set_name ("OptionEditorHeading");
473 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
479 set_popdown_strings (_copy_modifier_combo, dumb);
480 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
482 for (int x = 0; modifiers[x].name; ++x) {
483 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
484 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
489 l = manage (left_aligned_label (_("Copy items using:")));
490 l->set_name ("OptionsLabel");
492 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
493 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
498 /* constraint modifier */
499 set_popdown_strings (_constraint_modifier_combo, dumb);
500 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
502 for (int x = 0; modifiers[x].name; ++x) {
503 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
504 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
509 l = manage (left_aligned_label (_("Constrain drag using:")));
510 l->set_name ("OptionsLabel");
512 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
513 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
517 l = manage (left_aligned_label (_("When Beginning a Trim:")));
518 l->set_name ("OptionEditorHeading");
519 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
525 set_popdown_strings (_trim_contents_combo, dumb);
526 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
528 for (int x = 0; modifiers[x].name; ++x) {
529 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
530 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
535 l = manage (left_aligned_label (_("Trim contents using:")));
536 l->set_name ("OptionsLabel");
538 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
539 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
545 set_popdown_strings (_trim_anchored_combo, dumb);
546 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
548 for (int x = 0; modifiers[x].name; ++x) {
549 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
550 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
555 l = manage (left_aligned_label (_("Anchored trim using:")));
556 l->set_name ("OptionsLabel");
558 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
560 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
565 /* jump trim disabled for now
566 set_popdown_strings (_trim_jump_combo, dumb);
567 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
569 for (int x = 0; modifiers[x].name; ++x) {
570 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
571 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
576 l = manage (left_aligned_label (_("Jump after trim using:")));
577 l->set_name ("OptionsLabel");
579 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
581 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
587 /* note resize relative */
588 set_popdown_strings (_note_size_relative_combo, dumb);
589 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
591 for (int x = 0; modifiers[x].name; ++x) {
592 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
593 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
598 l = manage (left_aligned_label (_("Resize notes relatively using:")));
599 l->set_name ("OptionsLabel");
601 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
603 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
607 l = manage (left_aligned_label (_("While Dragging:")));
608 l->set_name ("OptionEditorHeading");
609 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
615 set_popdown_strings (_snap_modifier_combo, dumb);
616 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
618 for (int x = 0; modifiers[x].name; ++x) {
619 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
620 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
625 l = manage (left_aligned_label (_("Ignore snap using:")));
626 l->set_name ("OptionsLabel");
628 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
629 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
635 set_popdown_strings (_snap_delta_combo, dumb);
636 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
638 for (int x = 0; modifiers[x].name; ++x) {
639 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
640 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
645 l = manage (left_aligned_label (_("Snap relatively using:")));
646 l->set_name ("OptionsLabel");
648 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
649 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
653 l = manage (left_aligned_label (_("While Trimming:")));
654 l->set_name ("OptionEditorHeading");
655 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
661 set_popdown_strings (_trim_overlap_combo, dumb);
662 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
664 for (int x = 0; modifiers[x].name; ++x) {
665 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
666 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
671 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
672 l->set_name ("OptionsLabel");
674 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
675 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
679 l = manage (left_aligned_label (_("While Dragging Control Points:")));
680 l->set_name ("OptionEditorHeading");
681 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
687 set_popdown_strings (_fine_adjust_combo, dumb);
688 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
690 for (int x = 0; modifiers[x].name; ++x) {
691 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
692 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
697 l = manage (left_aligned_label (_("Fine adjust using:")));
698 l->set_name ("OptionsLabel");
700 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
701 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
707 set_popdown_strings (_push_points_combo, dumb);
708 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
710 for (int x = 0; modifiers[x].name; ++x) {
711 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
712 _push_points_combo.set_active_text (S_(modifiers[x].name));
717 l = manage (left_aligned_label (_("Push points using:")));
718 l->set_name ("OptionsLabel");
720 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
721 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
723 _box->pack_start (*t, false, false);
726 void parameter_changed (string const &)
728 /* XXX: these aren't really config options... */
731 void set_state_from_config ()
733 /* XXX: these aren't really config options... */
738 void bindings_changed ()
740 string const txt = _keyboard_layout_selector.get_active_text();
742 /* XXX: config...? for all this keyboard stuff */
744 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
745 if (txt == i->first) {
746 if (Keyboard::load_keybindings (i->second)) {
747 Keyboard::save_keybindings ();
753 void edit_modifier_chosen ()
755 string const txt = _edit_modifier_combo.get_active_text();
757 for (int i = 0; modifiers[i].name; ++i) {
758 if (txt == _(modifiers[i].name)) {
759 Keyboard::set_edit_modifier (modifiers[i].modifier);
765 void delete_modifier_chosen ()
767 string const txt = _delete_modifier_combo.get_active_text();
769 for (int i = 0; modifiers[i].name; ++i) {
770 if (txt == _(modifiers[i].name)) {
771 Keyboard::set_delete_modifier (modifiers[i].modifier);
777 void copy_modifier_chosen ()
779 string const txt = _copy_modifier_combo.get_active_text();
781 for (int i = 0; modifiers[i].name; ++i) {
782 if (txt == _(modifiers[i].name)) {
783 Keyboard::set_copy_modifier (modifiers[i].modifier);
789 void insert_note_modifier_chosen ()
791 string const txt = _insert_note_modifier_combo.get_active_text();
793 for (int i = 0; modifiers[i].name; ++i) {
794 if (txt == _(modifiers[i].name)) {
795 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
801 void snap_modifier_chosen ()
803 string const txt = _snap_modifier_combo.get_active_text();
805 for (int i = 0; modifiers[i].name; ++i) {
806 if (txt == _(modifiers[i].name)) {
807 Keyboard::set_snap_modifier (modifiers[i].modifier);
813 void snap_delta_modifier_chosen ()
815 string const txt = _snap_delta_combo.get_active_text();
817 for (int i = 0; modifiers[i].name; ++i) {
818 if (txt == _(modifiers[i].name)) {
819 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
825 void constraint_modifier_chosen ()
827 string const txt = _constraint_modifier_combo.get_active_text();
829 for (int i = 0; modifiers[i].name; ++i) {
830 if (txt == _(modifiers[i].name)) {
831 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
837 void trim_contents_modifier_chosen ()
839 string const txt = _trim_contents_combo.get_active_text();
841 for (int i = 0; modifiers[i].name; ++i) {
842 if (txt == _(modifiers[i].name)) {
843 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
849 void trim_overlap_modifier_chosen ()
851 string const txt = _trim_overlap_combo.get_active_text();
853 for (int i = 0; modifiers[i].name; ++i) {
854 if (txt == _(modifiers[i].name)) {
855 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
861 void trim_anchored_modifier_chosen ()
863 string const txt = _trim_anchored_combo.get_active_text();
865 for (int i = 0; modifiers[i].name; ++i) {
866 if (txt == _(modifiers[i].name)) {
867 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
873 void fine_adjust_modifier_chosen ()
875 string const txt = _fine_adjust_combo.get_active_text();
877 for (int i = 0; modifiers[i].name; ++i) {
878 if (txt == _(modifiers[i].name)) {
879 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
885 void push_points_modifier_chosen ()
887 string const txt = _push_points_combo.get_active_text();
889 for (int i = 0; modifiers[i].name; ++i) {
890 if (txt == _(modifiers[i].name)) {
891 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
897 void note_size_relative_modifier_chosen ()
899 string const txt = _note_size_relative_combo.get_active_text();
901 for (int i = 0; modifiers[i].name; ++i) {
902 if (txt == _(modifiers[i].name)) {
903 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
909 void delete_button_changed ()
911 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
914 void edit_button_changed ()
916 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
919 void insert_note_button_changed ()
921 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
924 ComboBoxText _keyboard_layout_selector;
925 ComboBoxText _edit_modifier_combo;
926 ComboBoxText _delete_modifier_combo;
927 ComboBoxText _copy_modifier_combo;
928 ComboBoxText _insert_note_modifier_combo;
929 ComboBoxText _snap_modifier_combo;
930 ComboBoxText _snap_delta_combo;
931 ComboBoxText _constraint_modifier_combo;
932 ComboBoxText _trim_contents_combo;
933 ComboBoxText _trim_overlap_combo;
934 ComboBoxText _trim_anchored_combo;
935 ComboBoxText _trim_jump_combo;
936 ComboBoxText _fine_adjust_combo;
937 ComboBoxText _push_points_combo;
938 ComboBoxText _note_size_relative_combo;
939 Adjustment _delete_button_adjustment;
940 SpinButton _delete_button_spin;
941 Adjustment _edit_button_adjustment;
942 SpinButton _edit_button_spin;
943 Adjustment _insert_note_button_adjustment;
944 SpinButton _insert_note_button_spin;
948 class FontScalingOptions : public OptionEditorBox
951 FontScalingOptions (UIConfiguration* uic) :
953 _dpi_adjustment (100, 50, 250, 1, 5),
954 _dpi_slider (_dpi_adjustment)
956 _dpi_adjustment.set_value (_ui_config->get_font_scale() / 1024.);
958 Label* l = manage (new Label (_("GUI and Font scaling:")));
959 l->set_name ("OptionsLabel");
961 const Glib::ustring dflt = _("Default");
962 const Glib::ustring empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
964 _dpi_slider.set_name("FontScaleSlider");
965 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
966 _dpi_slider.set_draw_value(false);
967 _dpi_slider.add_mark(50, Gtk::POS_TOP, empty);
968 _dpi_slider.add_mark(60, Gtk::POS_TOP, empty);
969 _dpi_slider.add_mark(70, Gtk::POS_TOP, empty);
970 _dpi_slider.add_mark(80, Gtk::POS_TOP, empty);
971 _dpi_slider.add_mark(90, Gtk::POS_TOP, empty);
972 _dpi_slider.add_mark(100, Gtk::POS_TOP, dflt);
973 _dpi_slider.add_mark(125, Gtk::POS_TOP, empty);
974 _dpi_slider.add_mark(150, Gtk::POS_TOP, empty);
975 _dpi_slider.add_mark(175, Gtk::POS_TOP, empty);
976 _dpi_slider.add_mark(200, Gtk::POS_TOP, empty);
977 _dpi_slider.add_mark(225, Gtk::POS_TOP, empty);
978 _dpi_slider.add_mark(250, Gtk::POS_TOP, empty);
980 HBox* h = manage (new HBox);
982 h->pack_start (*l, false, false);
983 h->pack_start (_dpi_slider, true, true);
985 _box->pack_start (*h, false, false);
987 set_note (_("Adjusting the scale require an application restart to re-layout."));
989 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
992 void parameter_changed (string const & p)
994 if (p == "font-scale") {
995 _dpi_adjustment.set_value (_ui_config->get_font_scale() / 1024.);
999 void set_state_from_config ()
1001 parameter_changed ("font-scale");
1008 _ui_config->set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024.));
1009 /* XXX: should be triggered from the parameter changed signal */
1013 UIConfiguration* _ui_config;
1014 Adjustment _dpi_adjustment;
1018 class ClipLevelOptions : public OptionEditorBox
1021 ClipLevelOptions (UIConfiguration* c)
1023 , _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1024 , _clip_level_slider (_clip_level_adjustment)
1026 _clip_level_adjustment.set_value (_ui_config->get_waveform_clip_level ());
1028 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
1029 l->set_name ("OptionsLabel");
1031 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1032 HBox* h = manage (new HBox);
1034 h->pack_start (*l, false, false);
1035 h->pack_start (_clip_level_slider, true, true);
1037 _box->pack_start (*h, false, false);
1039 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1042 void parameter_changed (string const & p)
1044 if (p == "waveform-clip-level") {
1045 _clip_level_adjustment.set_value (_ui_config->get_waveform_clip_level());
1049 void set_state_from_config ()
1051 parameter_changed ("waveform-clip-level");
1056 void clip_level_changed ()
1058 _ui_config->set_waveform_clip_level (_clip_level_adjustment.get_value());
1059 /* XXX: should be triggered from the parameter changed signal */
1060 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1063 UIConfiguration* _ui_config;
1064 Adjustment _clip_level_adjustment;
1065 HScale _clip_level_slider;
1068 class BufferingOptions : public OptionEditorBox
1071 BufferingOptions (RCConfiguration* c)
1073 , _playback_adjustment (5, 1, 60, 1, 4)
1074 , _capture_adjustment (5, 1, 60, 1, 4)
1075 , _playback_slider (_playback_adjustment)
1076 , _capture_slider (_capture_adjustment)
1078 vector<string> presets;
1080 /* these must match the order of the enums for BufferingPreset */
1082 presets.push_back (_("Small sessions (4-16 tracks)"));
1083 presets.push_back (_("Medium sessions (16-64 tracks)"));
1084 presets.push_back (_("Large sessions (64+ tracks)"));
1085 presets.push_back (_("Custom (set by sliders below)"));
1087 set_popdown_strings (_buffering_presets_combo, presets);
1089 Label* l = manage (new Label (_("Preset:")));
1090 l->set_name ("OptionsLabel");
1091 HBox* h = manage (new HBox);
1092 h->set_spacing (12);
1093 h->pack_start (*l, false, false);
1094 h->pack_start (_buffering_presets_combo, true, true);
1095 _box->pack_start (*h, false, false);
1097 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1099 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1101 l = manage (new Label (_("Playback (seconds of buffering):")));
1102 l->set_name ("OptionsLabel");
1104 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1105 h = manage (new HBox);
1107 h->pack_start (*l, false, false);
1108 h->pack_start (_playback_slider, true, true);
1110 _box->pack_start (*h, false, false);
1112 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1114 l = manage (new Label (_("Recording (seconds of buffering):")));
1115 l->set_name ("OptionsLabel");
1117 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1118 h = manage (new HBox);
1120 h->pack_start (*l, false, false);
1121 h->pack_start (_capture_slider, true, true);
1123 _box->pack_start (*h, false, false);
1125 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
1126 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
1129 void parameter_changed (string const & p)
1131 if (p == "buffering-preset") {
1132 switch (_rc_config->get_buffering_preset()) {
1134 _playback_slider.set_sensitive (false);
1135 _capture_slider.set_sensitive (false);
1136 _buffering_presets_combo.set_active (0);
1139 _playback_slider.set_sensitive (false);
1140 _capture_slider.set_sensitive (false);
1141 _buffering_presets_combo.set_active (1);
1144 _playback_slider.set_sensitive (false);
1145 _capture_slider.set_sensitive (false);
1146 _buffering_presets_combo.set_active (2);
1149 _playback_slider.set_sensitive (true);
1150 _capture_slider.set_sensitive (true);
1151 _buffering_presets_combo.set_active (3);
1156 if (p == "playback-buffer-seconds") {
1157 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1158 } else if (p == "capture-buffer-seconds") {
1159 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1163 void set_state_from_config ()
1165 parameter_changed ("buffering-preset");
1166 parameter_changed ("playback-buffer-seconds");
1167 parameter_changed ("capture-buffer-seconds");
1172 void preset_changed ()
1174 int index = _buffering_presets_combo.get_active_row_number ();
1180 _rc_config->set_buffering_preset (Small);
1183 _rc_config->set_buffering_preset (Medium);
1186 _rc_config->set_buffering_preset (Large);
1189 _rc_config->set_buffering_preset (Custom);
1192 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1197 void playback_changed ()
1199 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
1202 void capture_changed ()
1204 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
1207 RCConfiguration* _rc_config;
1208 Adjustment _playback_adjustment;
1209 Adjustment _capture_adjustment;
1210 HScale _playback_slider;
1211 HScale _capture_slider;
1212 ComboBoxText _buffering_presets_combo;
1215 class ControlSurfacesOptions : public OptionEditorBox
1218 ControlSurfacesOptions (Gtk::Window& parent)
1220 , _ignore_view_change (0)
1222 _store = ListStore::create (_model);
1223 _view.set_model (_store);
1224 _view.append_column (_("Control Surface Protocol"), _model.name);
1225 _view.get_column(0)->set_resizable (true);
1226 _view.get_column(0)->set_expand (true);
1227 _view.append_column_editable (_("Enabled"), _model.enabled);
1228 _view.append_column_editable (_("Feedback"), _model.feedback);
1230 _box->pack_start (_view, false, false);
1232 Label* label = manage (new Label);
1233 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
1235 _box->pack_start (*label, false, false);
1238 ControlProtocolManager& m = ControlProtocolManager::instance ();
1239 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1240 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1242 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1243 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1246 void parameter_changed (std::string const &)
1251 void set_state_from_config ()
1255 ControlProtocolManager& m = ControlProtocolManager::instance ();
1256 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1258 if (!(*i)->mandatory) {
1259 TreeModel::Row r = *_store->append ();
1260 r[_model.name] = (*i)->name;
1261 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1262 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
1263 r[_model.protocol_info] = *i;
1270 void protocol_status_changed (ControlProtocolInfo* cpi) {
1272 TreeModel::Children rows = _store->children();
1274 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1275 string n = ((*x)[_model.name]);
1277 if ((*x)[_model.protocol_info] == cpi) {
1278 _ignore_view_change++;
1279 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1280 _ignore_view_change--;
1286 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1288 TreeModel::Row r = *i;
1290 if (_ignore_view_change) {
1294 ControlProtocolInfo* cpi = r[_model.protocol_info];
1299 bool const was_enabled = (cpi->protocol != 0);
1300 bool const is_enabled = r[_model.enabled];
1303 if (was_enabled != is_enabled) {
1306 ControlProtocolManager::instance().activate (*cpi);
1308 ControlProtocolManager::instance().deactivate (*cpi);
1312 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
1313 bool const is_feedback = r[_model.feedback];
1315 if (was_feedback != is_feedback && cpi->protocol) {
1316 cpi->protocol->set_feedback (is_feedback);
1320 void edit_clicked (GdkEventButton* ev)
1322 if (ev->type != GDK_2BUTTON_PRESS) {
1327 ControlProtocolInfo* cpi;
1330 row = *(_view.get_selection()->get_selected());
1331 if (!row[_model.enabled]) {
1334 cpi = row[_model.protocol_info];
1335 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1338 Box* box = (Box*) cpi->protocol->get_gui ();
1342 if (box->get_parent()) {
1343 static_cast<ArdourWindow*>(box->get_parent())->present();
1346 string title = row[_model.name];
1347 /* once created, the window is managed by the surface itself (as ->get_parent())
1348 * Surface's tear_down_gui() is called on session close, when de-activating
1349 * or re-initializing a surface.
1350 * tear_down_gui() hides an deletes the Window if it exists.
1352 ArdourWindow* win = new ArdourWindow (_parent, title);
1353 win->set_title ("Control Protocol Options");
1359 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1363 ControlSurfacesModelColumns ()
1368 add (protocol_info);
1371 TreeModelColumn<string> name;
1372 TreeModelColumn<bool> enabled;
1373 TreeModelColumn<bool> feedback;
1374 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1377 Glib::RefPtr<ListStore> _store;
1378 ControlSurfacesModelColumns _model;
1380 Gtk::Window& _parent;
1381 PBD::ScopedConnection protocol_status_connection;
1382 uint32_t _ignore_view_change;
1385 class VideoTimelineOptions : public OptionEditorBox
1388 VideoTimelineOptions (RCConfiguration* c)
1390 , _show_video_export_info_button (_("Show Video Export Info before export"))
1391 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1392 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1394 Table* t = manage (new Table (2, 6));
1395 t->set_spacings (4);
1397 t->attach (_video_advanced_setup_button, 0, 2, 0, 1);
1398 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1399 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1400 _("<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."));
1402 Label* l = manage (new Label (_("Video Server URL:")));
1403 l->set_alignment (0, 0.5);
1404 t->attach (*l, 0, 1, 1, 2, FILL);
1405 t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL);
1406 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1407 _("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"));
1409 l = manage (new Label (_("Video Folder:")));
1410 l->set_alignment (0, 0.5);
1411 t->attach (*l, 0, 1, 2, 3, FILL);
1412 t->attach (_video_server_docroot_entry, 1, 2, 2, 3);
1413 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1414 _("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."));
1416 /* small vspace y=3..4 */
1418 t->attach (_show_video_export_info_button, 0, 2, 4, 5);
1419 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1420 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1421 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1423 t->attach (_show_video_server_dialog_button, 0, 2, 5, 6);
1424 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1425 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1426 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1428 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1429 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1430 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1431 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1433 _box->pack_start (*t,true,true);
1436 void server_url_changed ()
1438 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1441 void server_docroot_changed ()
1443 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1446 void show_video_export_info_toggled ()
1448 bool const x = _show_video_export_info_button.get_active ();
1449 _rc_config->set_show_video_export_info (x);
1452 void show_video_server_dialog_toggled ()
1454 bool const x = _show_video_server_dialog_button.get_active ();
1455 _rc_config->set_show_video_server_dialog (x);
1458 void video_advanced_setup_toggled ()
1460 bool const x = _video_advanced_setup_button.get_active ();
1461 _rc_config->set_video_advanced_setup(x);
1464 void parameter_changed (string const & p)
1466 if (p == "video-server-url") {
1467 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1468 } else if (p == "video-server-docroot") {
1469 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1470 } else if (p == "show-video-export-info") {
1471 bool const x = _rc_config->get_show_video_export_info();
1472 _show_video_export_info_button.set_active (x);
1473 } else if (p == "show-video-server-dialog") {
1474 bool const x = _rc_config->get_show_video_server_dialog();
1475 _show_video_server_dialog_button.set_active (x);
1476 } else if (p == "video-advanced-setup") {
1477 bool const x = _rc_config->get_video_advanced_setup();
1478 _video_advanced_setup_button.set_active(x);
1479 _video_server_docroot_entry.set_sensitive(x);
1480 _video_server_url_entry.set_sensitive(x);
1484 void set_state_from_config ()
1486 parameter_changed ("video-server-url");
1487 parameter_changed ("video-server-docroot");
1488 parameter_changed ("video-monitor-setup-dialog");
1489 parameter_changed ("show-video-export-info");
1490 parameter_changed ("show-video-server-dialog");
1491 parameter_changed ("video-advanced-setup");
1495 RCConfiguration* _rc_config;
1496 Entry _video_server_url_entry;
1497 Entry _video_server_docroot_entry;
1498 CheckButton _show_video_export_info_button;
1499 CheckButton _show_video_server_dialog_button;
1500 CheckButton _video_advanced_setup_button;
1503 class PluginOptions : public OptionEditorBox
1506 PluginOptions (RCConfiguration* c, UIConfiguration* uic)
1509 , _display_plugin_scan_progress (_("Always Display Plugin Scan Progress"))
1510 , _discover_vst_on_start (_("Scan for [new] VST Plugins on Application Start"))
1511 , _discover_au_on_start (_("Scan for AudioUnit Plugins on Application Start"))
1512 , _verbose_plugin_scan (_("Verbose Plugin Scan"))
1513 , _timeout_adjustment (0, 0, 3000, 50, 50)
1514 , _timeout_slider (_timeout_adjustment)
1517 std::stringstream ss;
1518 Table* t = manage (new Table (2, 6));
1519 t->set_spacings (4);
1523 ss << "<b>" << _("General") << "</b>";
1524 l = manage (left_aligned_label (ss.str()));
1525 l->set_use_markup (true);
1526 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1527 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1529 b = manage (new Button (_("Scan for Plugins")));
1530 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1531 t->attach (*b, 0, 2, n, n+1, FILL); ++n;
1533 t->attach (_display_plugin_scan_progress, 0, 2, n, n+1); ++n;
1534 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1535 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1536 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
1538 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
1539 _timeout_slider.set_digits (0);
1540 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &PluginOptions::timeout_changed));
1542 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1543 _("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."));
1545 l = manage (left_aligned_label (_("Scan Time Out [deciseconds]")));;
1546 HBox* h = manage (new HBox);
1548 h->pack_start (*l, false, false);
1549 h->pack_start (_timeout_slider, true, true);
1550 t->attach (*h, 0, 2, n, n+1); ++n;
1553 ss << "<b>" << _("VST") << "</b>";
1554 l = manage (left_aligned_label (ss.str()));
1555 l->set_use_markup (true);
1556 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1557 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1559 b = manage (new Button (_("Clear VST Cache")));
1560 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_cache_clicked));
1561 t->attach (*b, 0, 1, n, n+1, FILL);
1563 b = manage (new Button (_("Clear VST Blacklist")));
1564 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_blacklist_clicked));
1565 t->attach (*b, 1, 2, n, n+1, FILL);
1568 t->attach (_discover_vst_on_start, 0, 2, n, n+1); ++n;
1569 _discover_vst_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_vst_on_start_toggled));
1570 Gtkmm2ext::UI::instance()->set_tip (_discover_vst_on_start,
1571 _("<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"));
1573 #ifdef LXVST_SUPPORT
1574 t->attach (*manage (left_aligned_label (_("Linux VST Path:"))), 0, 1, n, n+1);
1575 b = manage (new Button (_("Edit")));
1576 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_lxvst_path_clicked));
1577 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1580 #ifdef WINDOWS_VST_SUPPORT
1581 t->attach (*manage (left_aligned_label (_("Windows VST Path:"))), 0, 1, n, n+1);
1582 b = manage (new Button (_("Edit")));
1583 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_vst_path_clicked));
1584 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1586 // currently verbose logging is only implemented for Windows VST.
1587 t->attach (_verbose_plugin_scan, 0, 2, n, n+1); ++n;
1588 _verbose_plugin_scan.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::verbose_plugin_scan_toggled));
1589 Gtkmm2ext::UI::instance()->set_tip (_verbose_plugin_scan,
1590 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
1594 #ifdef AUDIOUNIT_SUPPORT
1596 ss << "<b>" << _("Audio Unit") << "</b>";
1597 l = manage (left_aligned_label (ss.str()));
1598 l->set_use_markup (true);
1599 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1600 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1602 t->attach (_discover_au_on_start, 0, 2, n, n+1); ++n;
1603 _discover_au_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_au_on_start_toggled));
1604 Gtkmm2ext::UI::instance()->set_tip (_discover_au_on_start,
1605 _("<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."));
1608 b = manage (new Button (_("Clear AU Cache")));
1609 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_cache_clicked));
1610 t->attach (*b, 0, 1, n, n+1, FILL);
1612 b = manage (new Button (_("Clear AU Blacklist")));
1613 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_blacklist_clicked));
1614 t->attach (*b, 1, 2, n, n+1, FILL);
1618 _box->pack_start (*t,true,true);
1621 void parameter_changed (string const & p) {
1622 if (p == "show-plugin-scan-window") {
1623 bool const x = _ui_config->get_show_plugin_scan_window();
1624 _display_plugin_scan_progress.set_active (x);
1626 else if (p == "discover-vst-on-start") {
1627 bool const x = _rc_config->get_discover_vst_on_start();
1628 _discover_vst_on_start.set_active (x);
1630 else if (p == "vst-scan-timeout") {
1631 int const x = _rc_config->get_vst_scan_timeout();
1632 _timeout_adjustment.set_value (x);
1634 else if (p == "discover-audio-units") {
1635 bool const x = _rc_config->get_discover_audio_units();
1636 _discover_au_on_start.set_active (x);
1638 else if (p == "verbose-plugin-scan") {
1639 bool const x = _rc_config->get_verbose_plugin_scan();
1640 _verbose_plugin_scan.set_active (x);
1644 void set_state_from_config () {
1645 parameter_changed ("show-plugin-scan-window");
1646 parameter_changed ("discover-vst-on-start");
1647 parameter_changed ("vst-scan-timeout");
1648 parameter_changed ("discover-audio-units");
1649 parameter_changed ("verbose-plugin-scan");
1653 RCConfiguration* _rc_config;
1654 UIConfiguration* _ui_config;
1655 CheckButton _display_plugin_scan_progress;
1656 CheckButton _discover_vst_on_start;
1657 CheckButton _discover_au_on_start;
1658 CheckButton _verbose_plugin_scan;
1659 Adjustment _timeout_adjustment;
1660 HScale _timeout_slider;
1662 void display_plugin_scan_progress_toggled () {
1663 bool const x = _display_plugin_scan_progress.get_active();
1664 _ui_config->set_show_plugin_scan_window(x);
1667 void discover_vst_on_start_toggled () {
1668 bool const x = _discover_vst_on_start.get_active();
1669 _rc_config->set_discover_vst_on_start(x);
1672 void discover_au_on_start_toggled () {
1673 bool const x = _discover_au_on_start.get_active();
1674 _rc_config->set_discover_audio_units(x);
1677 void verbose_plugin_scan_toggled () {
1678 bool const x = _verbose_plugin_scan.get_active();
1679 _rc_config->set_verbose_plugin_scan(x);
1682 void timeout_changed () {
1683 int x = floor(_timeout_adjustment.get_value());
1684 _rc_config->set_vst_scan_timeout(x);
1687 void clear_vst_cache_clicked () {
1688 PluginManager::instance().clear_vst_cache();
1691 void clear_vst_blacklist_clicked () {
1692 PluginManager::instance().clear_vst_blacklist();
1695 void clear_au_cache_clicked () {
1696 PluginManager::instance().clear_au_cache();
1699 void clear_au_blacklist_clicked () {
1700 PluginManager::instance().clear_au_blacklist();
1704 void edit_vst_path_clicked () {
1705 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1706 _("Set Windows VST Search Path"),
1707 _rc_config->get_plugin_path_vst(),
1708 PluginManager::instance().get_default_windows_vst_path()
1710 ResponseType r = (ResponseType) pd->run ();
1712 if (r == RESPONSE_ACCEPT) {
1713 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
1718 // todo consolidate with edit_vst_path_clicked..
1719 void edit_lxvst_path_clicked () {
1720 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1721 _("Set Linux VST Search Path"),
1722 _rc_config->get_plugin_path_lxvst(),
1723 PluginManager::instance().get_default_lxvst_path()
1725 ResponseType r = (ResponseType) pd->run ();
1727 if (r == RESPONSE_ACCEPT) {
1728 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
1733 void refresh_clicked () {
1734 PluginManager::instance().refresh();
1739 /** A class which allows control of visibility of some editor components usign
1740 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1741 * which has the correct members, but with null widget pointers. This
1742 * class allows the user to set visibility of the members, the details
1743 * of which are stored in a configuration variable which can be watched
1744 * by parts of the editor that actually contain the widgets whose visibility
1745 * is being controlled.
1748 class VisibilityOption : public Option
1751 /** @param name User-visible name for this group.
1752 * @param g `Dummy' VisibilityGroup (as described above).
1753 * @param get Method to get the value of the appropriate configuration variable.
1754 * @param set Method to set the value of the appropriate configuration variable.
1756 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1757 : Option (g->get_state_name(), name)
1759 , _visibility_group (g)
1763 /* Watch for changes made by the user to our members */
1764 _visibility_group->VisibilityChanged.connect_same_thread (
1765 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1769 void set_state_from_config ()
1771 /* Set our state from the current configuration */
1772 _visibility_group->set_state (_get ());
1775 void add_to_page (OptionEditorPage* p)
1777 _heading.add_to_page (p);
1778 add_widget_to_page (p, _visibility_group->list_view ());
1781 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1786 /* The user has changed something, so reflect this change
1787 in the RCConfiguration.
1789 _set (_visibility_group->get_state_value ());
1792 OptionEditorHeading _heading;
1793 VisibilityGroup* _visibility_group;
1794 sigc::slot<std::string> _get;
1795 sigc::slot<bool, std::string> _set;
1796 PBD::ScopedConnection _visibility_group_connection;
1801 RCOptionEditor::RCOptionEditor ()
1802 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1803 , _rc_config (Config)
1804 , _ui_config (ARDOUR_UI::config())
1805 , _mixer_strip_visibility ("mixer-element-visibility")
1809 uint32_t hwcpus = hardware_concurrency ();
1811 BoolComboOption* bco;
1814 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1816 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1818 _("Signal processing uses"),
1819 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1820 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1823 procs->add (-1, _("all but one processor"));
1824 procs->add (0, _("all available processors"));
1826 for (uint32_t i = 1; i <= hwcpus; ++i) {
1827 procs->add (i, string_compose (_("%1 processors"), i));
1830 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1832 add_option (_("Misc"), procs);
1835 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1837 add_option (_("Misc"), new UndoOptions (_rc_config));
1839 add_option (_("Misc"),
1841 "verify-remove-last-capture",
1842 _("Verify removal of last capture"),
1843 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1844 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1847 add_option (_("Misc"),
1849 "periodic-safety-backups",
1850 _("Make periodic backups of the session file"),
1851 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1852 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1855 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1857 add_option (_("Misc"),
1859 "only-copy-imported-files",
1860 _("Always copy imported files"),
1861 sigc::mem_fun (*_ui_config, &UIConfiguration::get_only_copy_imported_files),
1862 sigc::mem_fun (*_ui_config, &UIConfiguration::set_only_copy_imported_files)
1865 add_option (_("Misc"), new DirectoryOption (
1866 X_("default-session-parent-dir"),
1867 _("Default folder for new sessions:"),
1868 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1869 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1872 add_option (_("Misc"),
1873 new SpinOption<uint32_t> (
1874 "max-recent-sessions",
1875 _("Maximum number of recent sessions"),
1876 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1877 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1881 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1883 add_option (_("Misc"), new ClickOptions (_rc_config, this));
1885 add_option (_("Misc"),
1888 _("Click gain level"),
1889 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1890 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1893 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1895 add_option (_("Misc"),
1896 new SpinOption<double> (
1897 "automation-thinning-factor",
1898 _("Thinning factor (larger value => less data)"),
1899 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1900 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1904 add_option (_("Misc"),
1905 new SpinOption<double> (
1906 "automation-interval-msecs",
1907 _("Automation sampling interval (milliseconds)"),
1908 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1909 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1915 add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options")));
1919 tsf = new BoolOption (
1920 "latched-record-enable",
1921 _("Keep record-enable engaged on stop"),
1922 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1923 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1925 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1926 add_option (_("Transport"), tsf);
1928 tsf = new BoolOption (
1930 _("Play loop is a transport mode"),
1931 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1932 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1934 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1935 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1936 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1937 add_option (_("Transport"), tsf);
1939 tsf = new BoolOption (
1940 "stop-recording-on-xrun",
1941 _("Stop recording when an xrun occurs"),
1942 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1943 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1945 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1946 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
1948 add_option (_("Transport"), tsf);
1950 tsf = new BoolOption (
1951 "create-xrun-marker",
1952 _("Create markers where xruns occur"),
1953 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
1954 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
1956 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1957 add_option (_("Transport"), tsf);
1959 tsf = new BoolOption (
1960 "stop-at-session-end",
1961 _("Stop at the end of the session"),
1962 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
1963 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
1965 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1966 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
1967 "when it reaches the current session end marker\n\n"
1968 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
1970 add_option (_("Transport"), tsf);
1972 tsf = new BoolOption (
1974 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
1975 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
1976 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
1978 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1979 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
1980 "preventing any need to do a transport locate at the end of the loop\n\n"
1981 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
1982 "which will often cause a small click or delay"), PROGRAM_NAME));
1983 add_option (_("Transport"), tsf);
1985 tsf = new BoolOption (
1986 "disable-disarm-during-roll",
1987 _("Disable per-track record disarm while rolling"),
1988 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
1989 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
1991 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"));
1992 add_option (_("Transport"), tsf);
1994 tsf = new BoolOption (
1996 _("12dB gain reduction during fast-forward and fast-rewind"),
1997 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
1998 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
2000 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
2001 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
2002 add_option (_("Transport"), tsf);
2004 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
2006 _sync_source = new ComboOption<SyncSource> (
2008 _("External timecode source"),
2009 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
2010 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
2013 add_option (_("Transport"), _sync_source);
2015 _sync_framerate = new BoolOption (
2016 "timecode-sync-frame-rate",
2017 _("Match session video frame rate to external timecode"),
2018 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
2019 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
2021 Gtkmm2ext::UI::instance()->set_tip
2022 (_sync_framerate->tip_widget(),
2023 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
2024 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
2025 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
2026 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
2027 "timecode standard and the session standard."), PROGRAM_NAME));
2029 add_option (_("Transport"), _sync_framerate);
2031 _sync_genlock = new BoolOption (
2032 "timecode-source-is-synced",
2033 _("Sync-lock timecode to clock (disable drift compensation)"),
2034 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
2035 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
2037 Gtkmm2ext::UI::instance()->set_tip
2038 (_sync_genlock->tip_widget(),
2039 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
2040 "Sync Lock indicates that the selected external timecode source shares clock-sync "
2041 "(Black & Burst, Wordclock, etc) with the audio interface. "
2042 "This option disables drift compensation. The transport speed is fixed at 1.0. "
2043 "Vari-speed LTC will be ignored and cause drift."
2045 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
2046 "timecode sources shares clock sync."
2050 add_option (_("Transport"), _sync_genlock);
2052 _sync_source_2997 = new BoolOption (
2053 "timecode-source-2997",
2054 _("Lock to 29.9700 fps instead of 30000/1001"),
2055 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
2056 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
2058 Gtkmm2ext::UI::instance()->set_tip
2059 (_sync_source_2997->tip_widget(),
2060 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
2061 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
2062 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
2063 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
2064 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
2065 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
2068 add_option (_("Transport"), _sync_source_2997);
2070 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
2072 _ltc_port = new ComboStringOption (
2074 _("LTC incoming port"),
2075 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
2076 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
2079 vector<string> physical_inputs;
2080 physical_inputs.push_back (_("None"));
2081 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
2082 _ltc_port->set_popdown_strings (physical_inputs);
2084 populate_sync_options ();
2086 add_option (_("Transport"), _ltc_port);
2088 // TODO; rather disable this button than not compile it..
2089 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
2091 add_option (_("Transport"),
2094 _("Enable LTC generator"),
2095 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
2096 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
2099 _ltc_send_continuously = new BoolOption (
2100 "ltc-send-continuously",
2101 _("Send LTC while stopped"),
2102 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
2103 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
2105 Gtkmm2ext::UI::instance()->set_tip
2106 (_ltc_send_continuously->tip_widget(),
2107 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
2108 add_option (_("Transport"), _ltc_send_continuously);
2110 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
2111 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
2112 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
2113 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
2115 Gtkmm2ext::UI::instance()->set_tip
2116 (_ltc_volume_slider->tip_widget(),
2117 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
2119 add_option (_("Transport"), _ltc_volume_slider);
2120 parameter_changed ("send-ltc");
2122 parameter_changed ("sync-source");
2126 add_option (S_("Editor"),
2128 "draggable-playhead",
2129 _("Allow dragging of playhead"),
2130 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_draggable_playhead),
2131 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_draggable_playhead)
2134 add_option (_("Editor"),
2136 "automation-follows-regions",
2137 _("Move relevant automation when audio regions are moved"),
2138 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2139 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2142 add_option (_("Editor"),
2144 "show-track-meters",
2145 _("Show meters on tracks in the editor"),
2146 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_track_meters),
2147 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_track_meters)
2150 add_option (_("Editor"),
2152 "show-editor-meter",
2153 _("Display master-meter in the toolbar"),
2154 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_editor_meter),
2155 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_editor_meter)
2158 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2159 "default-fade-shape",
2160 _("Default fade shape"),
2161 sigc::mem_fun (*_rc_config,
2162 &RCConfiguration::get_default_fade_shape),
2163 sigc::mem_fun (*_rc_config,
2164 &RCConfiguration::set_default_fade_shape)
2167 fadeshape->add (FadeLinear,
2168 _("Linear (for highly correlated material)"));
2169 fadeshape->add (FadeConstantPower, _("Constant power"));
2170 fadeshape->add (FadeSymmetric, _("Symmetric"));
2171 fadeshape->add (FadeSlow, _("Slow"));
2172 fadeshape->add (FadeFast, _("Fast"));
2174 add_option (_("Editor"), fadeshape);
2177 bco = new BoolComboOption (
2178 "use-overlap-equivalency",
2179 _("Regions in active edit groups are edited together"),
2180 _("whenever they overlap in time"),
2181 _("only if they have identical length, position and origin"),
2182 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2183 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2186 add_option (_("Editor"), bco);
2188 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2190 _("Layering model"),
2191 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2192 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2195 lm->add (LaterHigher, _("later is higher"));
2196 lm->add (Manual, _("manual layering"));
2197 add_option (_("Editor"), lm);
2199 add_option (_("Editor"),
2201 "rubberbanding-snaps-to-grid",
2202 _("Make rubberband selection rectangle snap to the grid"),
2203 sigc::mem_fun (*_ui_config, &UIConfiguration::get_rubberbanding_snaps_to_grid),
2204 sigc::mem_fun (*_ui_config, &UIConfiguration::set_rubberbanding_snaps_to_grid)
2207 add_option (_("Editor"),
2210 _("Show waveforms in regions"),
2211 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms),
2212 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms)
2215 add_option (_("Editor"),
2216 new BoolComboOption (
2217 "show-region-gain-envelopes",
2218 _("Show gain envelopes in audio regions"),
2220 _("only in Draw and Internal Edit modes"),
2221 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_region_gain),
2222 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_region_gain)
2225 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
2227 _("Waveform scale"),
2228 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_scale),
2229 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_scale)
2232 wfs->add (Linear, _("linear"));
2233 wfs->add (Logarithmic, _("logarithmic"));
2235 add_option (_("Editor"), wfs);
2237 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
2239 _("Waveform shape"),
2240 sigc::mem_fun (*_ui_config, &UIConfiguration::get_waveform_shape),
2241 sigc::mem_fun (*_ui_config, &UIConfiguration::set_waveform_shape)
2244 wfsh->add (Traditional, _("traditional"));
2245 wfsh->add (Rectified, _("rectified"));
2247 add_option (_("Editor"), wfsh);
2249 add_option (_("Editor"), new ClipLevelOptions (_ui_config));
2251 add_option (_("Editor"),
2253 "show-waveforms-while-recording",
2254 _("Show waveforms for audio while it is being recorded"),
2255 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_waveforms_while_recording),
2256 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_waveforms_while_recording)
2259 add_option (_("Editor"),
2262 _("Show zoom toolbar"),
2263 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_zoom_tools),
2264 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_zoom_tools)
2267 add_option (_("Editor"),
2269 "update-editor-during-summary-drag",
2270 _("Update editor window during drags of the summary"),
2271 sigc::mem_fun (*_ui_config, &UIConfiguration::get_update_editor_during_summary_drag),
2272 sigc::mem_fun (*_ui_config, &UIConfiguration::set_update_editor_during_summary_drag)
2275 bo = new BoolOption (
2277 _("Name new markers"),
2278 sigc::mem_fun (*_ui_config, &UIConfiguration::get_name_new_markers),
2279 sigc::mem_fun (*_ui_config, &UIConfiguration::set_name_new_markers)
2282 add_option (_("Editor"), bo);
2283 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."
2284 "\n\nYou can always rename markers by right-clicking on them"));
2286 add_option (_("Editor"),
2288 "autoscroll-editor",
2289 _("Auto-scroll editor window when dragging near its edges"),
2290 sigc::mem_fun (*_ui_config, &UIConfiguration::get_autoscroll_editor),
2291 sigc::mem_fun (*_ui_config, &UIConfiguration::set_autoscroll_editor)
2294 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2295 "region-selection-after-split",
2296 _("After splitting selected regions, select"),
2297 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2298 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2300 // TODO: decide which of these modes are really useful
2301 rsas->add(None, _("no regions"));
2302 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2303 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2304 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2305 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2306 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2307 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2308 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2310 add_option (_("Editor"), rsas);
2315 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2317 add_option (_("Audio"), new BufferingOptions (_rc_config));
2319 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2321 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2323 _("Record monitoring handled by"),
2324 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2325 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2328 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2329 mm->add (HardwareMonitoring, _("via Audio Driver"));
2332 string prog (PROGRAM_NAME);
2333 boost::algorithm::to_lower (prog);
2334 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2335 mm->add (ExternalMonitoring, _("audio hardware"));
2337 add_option (_("Audio"), mm);
2339 add_option (_("Audio"),
2341 "tape-machine-mode",
2342 _("Tape machine mode"),
2343 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2344 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2347 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
2349 add_option (_("Audio"),
2351 "auto-connect-standard-busses",
2352 _("Auto-connect master/monitor busses"),
2353 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2354 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2357 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2358 "input-auto-connect",
2359 _("Connect track inputs"),
2360 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2361 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2364 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2365 iac->add (ManualConnect, _("manually"));
2367 add_option (_("Audio"), iac);
2369 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2370 "output-auto-connect",
2371 _("Connect track and bus outputs"),
2372 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2373 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2376 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2377 oac->add (AutoConnectMaster, _("automatically to master bus"));
2378 oac->add (ManualConnect, _("manually"));
2380 add_option (_("Audio"), oac);
2382 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2384 add_option (_("Audio"),
2386 "denormal-protection",
2387 _("Use DC bias to protect against denormals"),
2388 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2389 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2392 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2394 _("Processor handling"),
2395 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2396 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2400 dm->add (DenormalNone, _("no processor handling"));
2402 FPU* fpu = FPU::instance();
2404 if (fpu->has_flush_to_zero()) {
2406 dm->add (DenormalFTZ, _("use FlushToZero"));
2407 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2408 _rc_config->set_denormal_model(DenormalNone);
2411 if (fpu->has_denormals_are_zero()) {
2413 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2414 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2415 _rc_config->set_denormal_model(DenormalNone);
2418 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2420 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2421 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2422 _rc_config->set_denormal_model(DenormalNone);
2426 dm->set_sensitive(false);
2429 add_option (_("Audio"), dm);
2431 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
2433 add_option (_("Audio"),
2435 "plugins-stop-with-transport",
2436 _("Silence plugins when the transport is stopped"),
2437 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
2438 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
2441 add_option (_("Audio"),
2443 "new-plugins-active",
2444 _("Make new plugins active"),
2445 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
2446 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
2449 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2451 add_option (_("Audio"),
2453 "auto-analyse-audio",
2454 _("Enable automatic analysis of audio"),
2455 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2456 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2459 add_option (_("Audio"),
2461 "replicate-missing-region-channels",
2462 _("Replicate missing region channels"),
2463 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2464 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2469 add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
2471 add_option (_("Solo / mute"),
2474 _("Solo-in-place mute cut (dB)"),
2475 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2476 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2479 _solo_control_is_listen_control = new BoolOption (
2480 "solo-control-is-listen-control",
2481 _("Solo controls are Listen controls"),
2482 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2483 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2486 add_option (_("Solo / mute"), _solo_control_is_listen_control);
2488 _listen_position = new ComboOption<ListenPosition> (
2490 _("Listen Position"),
2491 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2492 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2495 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2496 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2498 add_option (_("Solo / mute"), _listen_position);
2500 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2502 _("PFL signals come from"),
2503 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2504 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2507 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2508 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2510 add_option (_("Solo / mute"), pp);
2512 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2514 _("AFL signals come from"),
2515 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2516 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2519 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2520 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2522 add_option (_("Solo / mute"), pa);
2524 parameter_changed ("use-monitor-bus");
2526 add_option (_("Solo / mute"),
2529 _("Exclusive solo"),
2530 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2531 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2534 add_option (_("Solo / mute"),
2537 _("Show solo muting"),
2538 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2539 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2542 add_option (_("Solo / mute"),
2544 "solo-mute-override",
2545 _("Soloing overrides muting"),
2546 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2547 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2550 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
2552 add_option (_("Solo / mute"),
2554 "mute-affects-pre-fader",
2555 _("Mute affects pre-fader sends"),
2556 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2557 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2560 add_option (_("Solo / mute"),
2562 "mute-affects-post-fader",
2563 _("Mute affects post-fader sends"),
2564 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2565 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2568 add_option (_("Solo / mute"),
2570 "mute-affects-control-outs",
2571 _("Mute affects control outputs"),
2572 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2573 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2576 add_option (_("Solo / mute"),
2578 "mute-affects-main-outs",
2579 _("Mute affects main outputs"),
2580 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2581 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2584 add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
2586 add_option (_("Solo / mute"),
2588 "link-send-and-route-panner",
2589 _("Link panners of Aux and External Sends with main panner by default"),
2590 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2591 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2594 add_option (_("MIDI"),
2595 new SpinOption<float> (
2597 _("MIDI read-ahead time (seconds)"),
2598 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2599 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2604 add_option (_("MIDI"),
2607 _("Send MIDI Clock"),
2608 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2609 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2612 add_option (_("MIDI"),
2615 _("Send MIDI Time Code"),
2616 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2617 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2620 add_option (_("MIDI"),
2621 new SpinOption<int> (
2622 "mtc-qf-speed-tolerance",
2623 _("Percentage either side of normal transport speed to transmit MTC"),
2624 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2625 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2629 add_option (_("MIDI"),
2632 _("Obey MIDI Machine Control commands"),
2633 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2634 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2637 add_option (_("MIDI"),
2640 _("Send MIDI Machine Control commands"),
2641 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2642 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2645 add_option (_("MIDI"),
2648 _("Send MIDI control feedback"),
2649 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2650 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2653 add_option (_("MIDI"),
2654 new SpinOption<uint8_t> (
2655 "mmc-receive-device-id",
2656 _("Inbound MMC device ID"),
2657 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2658 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2662 add_option (_("MIDI"),
2663 new SpinOption<uint8_t> (
2664 "mmc-send-device-id",
2665 _("Outbound MMC device ID"),
2666 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2667 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2671 add_option (_("MIDI"),
2672 new SpinOption<int32_t> (
2673 "initial-program-change",
2674 _("Initial program change"),
2675 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2676 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2680 add_option (_("MIDI"),
2682 "display-first-midi-bank-as-zero",
2683 _("Display first MIDI bank/program as 0"),
2684 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2685 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2688 add_option (_("MIDI"),
2690 "never-display-periodic-midi",
2691 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2692 sigc::mem_fun (*_ui_config, &UIConfiguration::get_never_display_periodic_midi),
2693 sigc::mem_fun (*_ui_config, &UIConfiguration::set_never_display_periodic_midi)
2696 add_option (_("MIDI"),
2699 _("Sound MIDI notes as they are selected"),
2700 sigc::mem_fun (*_ui_config, &UIConfiguration::get_sound_midi_notes),
2701 sigc::mem_fun (*_ui_config, &UIConfiguration::set_sound_midi_notes)
2704 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2706 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2707 "midi-audition-synth-uri",
2708 _("Midi Audition Synth (LV2)"),
2709 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2710 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2713 audition_synth->add(X_(""), _("None"));
2714 PluginInfoList all_plugs;
2715 PluginManager& manager (PluginManager::instance());
2717 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2719 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2720 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2721 if (!(*i)->is_instrument()) continue;
2722 if ((*i)->type != ARDOUR::LV2) continue;
2723 audition_synth->add((*i)->unique_id, (*i)->name);
2727 add_option (_("MIDI"), audition_synth);
2729 /* USER INTERACTION */
2732 #ifdef PLATFORM_WINDOWS
2735 getenv ("ARDOUR_BUNDLED")
2739 add_option (_("User interaction"),
2741 "enable-translation",
2742 string_compose (_("Use translations of %1 messages\n"
2743 " <i>(requires a restart of %1 to take effect)</i>\n"
2744 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2745 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2746 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2749 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2751 add_option (_("User interaction"), new KeyboardOptions);
2753 /* Control Surfaces */
2755 add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
2757 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2759 _("Control surface remote ID"),
2760 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2761 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2764 rm->add (UserOrdered, _("assigned by user"));
2765 rm->add (MixerOrdered, _("follows order of mixer"));
2767 add_option (_("Control Surfaces"), rm);
2769 /* VIDEO Timeline */
2770 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2772 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2773 /* Plugin options (currrently VST only) */
2774 add_option (_("Plugins"), new PluginOptions (_rc_config, _ui_config));
2779 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
2780 BoolOption* bgo = new BoolOption (
2782 _("Possibly improve slow graphical performance"),
2783 sigc::mem_fun (*_ui_config, &UIConfiguration::get_buggy_gradients),
2784 sigc::mem_fun (*_ui_config, &UIConfiguration::set_buggy_gradients)
2787 Gtkmm2ext::UI::instance()->set_tip (bgo->tip_widget(), string_compose (_("This requires restarting %1 before having an effect"), PROGRAM_NAME));
2788 add_option (S_("Preferences|GUI"), bgo);
2791 add_option (S_("Preferences|GUI"),
2794 _("Graphically indicate mouse pointer hovering over various widgets"),
2795 sigc::mem_fun (*_ui_config, &UIConfiguration::get_widget_prelight),
2796 sigc::mem_fun (*_ui_config, &UIConfiguration::set_widget_prelight)
2799 #ifdef TOOLTIPS_GOT_FIXED
2800 add_option (S_("Preferences|GUI"),
2803 _("Show tooltips if mouse hovers over a control"),
2804 sigc::mem_fun (*_ui_config, &UIConfiguration::get_use_tooltips),
2805 sigc::mem_fun (*_ui_config, &UIConfiguration::set_use_tooltips)
2809 add_option (S_("Preferences|GUI"),
2811 "show-name-highlight",
2812 _("Use name highlight bars in region displays (requires a restart)"),
2813 sigc::mem_fun (*_ui_config, &UIConfiguration::get_show_name_highlight),
2814 sigc::mem_fun (*_ui_config, &UIConfiguration::set_show_name_highlight)
2818 /* font scaling does nothing with GDK/Quartz */
2819 add_option (S_("Preferences|GUI"), new FontScalingOptions (_ui_config));
2822 add_option (S_("GUI"),
2824 "super-rapid-clock-update",
2825 _("update transport clock display at FPS instead of every 100ms"),
2826 sigc::mem_fun (*_ui_config, &UIConfiguration::get_super_rapid_clock_update),
2827 sigc::mem_fun (*_ui_config, &UIConfiguration::set_super_rapid_clock_update)
2831 /* Image cache size */
2833 Gtk::Adjustment *ics = manage (new Gtk::Adjustment(0, 1, 1024, 10)); /* 1 MB to 1GB in steps of 10MB */
2834 HSliderOption *sics = new HSliderOption("waveform-cache-size",
2835 _("Waveform image cache size (megabytes)"),
2837 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_waveform_cache_size),
2838 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_waveform_cache_size)
2840 sics->scale().set_digits (0);
2841 Gtkmm2ext::UI::instance()->set_tip
2842 (sics->tip_widget(),
2843 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
2844 add_option (S_("Preferences|GUI"), sics);
2846 /* Lock GUI timeout */
2848 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
2849 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2850 _("Lock timeout (seconds)"),
2852 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::get_lock_gui_after_seconds),
2853 sigc::mem_fun (*ARDOUR_UI::config(), &UIConfiguration::set_lock_gui_after_seconds)
2855 slts->scale().set_digits (0);
2856 Gtkmm2ext::UI::instance()->set_tip
2857 (slts->tip_widget(),
2858 _("Lock GUI after this many idle seconds (zero to never lock)"));
2859 add_option (S_("Preferences|GUI"), slts);
2861 /* The names of these controls must be the same as those given in MixerStrip
2862 for the actual widgets being controlled.
2864 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
2865 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2866 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
2867 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
2868 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
2869 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2872 S_("Preferences|GUI"),
2873 new VisibilityOption (
2875 &_mixer_strip_visibility,
2876 sigc::mem_fun (*_ui_config, &UIConfiguration::get_mixer_strip_visibility),
2877 sigc::mem_fun (*_ui_config, &UIConfiguration::set_mixer_strip_visibility)
2881 add_option (S_("Preferences|GUI"),
2883 "default-narrow_ms",
2884 _("Use narrow strips in the mixer by default"),
2885 sigc::mem_fun (*_ui_config, &UIConfiguration::get_default_narrow_ms),
2886 sigc::mem_fun (*_ui_config, &UIConfiguration::set_default_narrow_ms)
2889 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2891 ComboOption<float>* mht = new ComboOption<float> (
2893 _("Peak hold time"),
2894 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_hold),
2895 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_hold)
2898 mht->add (MeterHoldOff, _("off"));
2899 mht->add (MeterHoldShort, _("short"));
2900 mht->add (MeterHoldMedium, _("medium"));
2901 mht->add (MeterHoldLong, _("long"));
2903 add_option (S_("Preferences|Metering"), mht);
2905 ComboOption<float>* mfo = new ComboOption<float> (
2908 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2909 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2912 mfo->add (METER_FALLOFF_OFF, _("off"));
2913 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2914 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2915 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
2916 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2917 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
2918 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
2920 add_option (S_("Preferences|Metering"), mfo);
2922 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2923 "meter-line-up-level",
2924 _("Meter line-up level; 0dBu"),
2925 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_level),
2926 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_level)
2929 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2930 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2931 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2932 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2934 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."));
2936 add_option (S_("Preferences|Metering"), mlu);
2938 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2939 "meter-line-up-din",
2940 _("IEC1/DIN Meter line-up level; 0dBu"),
2941 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_line_up_din),
2942 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_line_up_din)
2945 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2946 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2947 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2948 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2950 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2952 add_option (S_("Preferences|Metering"), mld);
2954 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2955 "meter-vu-standard",
2956 _("VU Meter standard"),
2957 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_vu_standard),
2958 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_vu_standard)
2961 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2962 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2963 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2964 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2966 add_option (S_("Preferences|Metering"), mvu);
2968 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
2969 HSliderOption *mpks = new HSliderOption("meter-peak",
2970 _("Peak threshold [dBFS]"),
2972 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_peak),
2973 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_peak)
2977 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
2978 "meter-type-master",
2979 _("Default Meter Type for Master Bus"),
2980 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
2981 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
2983 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2984 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2985 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2986 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2987 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2988 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2989 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2990 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
2992 add_option (S_("Preferences|Metering"), mtm);
2995 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
2997 _("Default Meter Type for Busses"),
2998 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
2999 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3001 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3002 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3003 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3004 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3005 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3006 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3007 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3008 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3010 add_option (S_("Preferences|Metering"), mtb);
3012 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3014 _("Default Meter Type for Tracks"),
3015 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3016 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3018 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3019 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3021 add_option (S_("Preferences|Metering"), mtt);
3024 Gtkmm2ext::UI::instance()->set_tip
3025 (mpks->tip_widget(),
3026 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
3028 add_option (S_("Preferences|Metering"), mpks);
3030 add_option (S_("Preferences|Metering"),
3033 _("LED meter style"),
3034 sigc::mem_fun (*_ui_config, &UIConfiguration::get_meter_style_led),
3035 sigc::mem_fun (*_ui_config, &UIConfiguration::set_meter_style_led)
3038 /* and now the theme manager */
3040 ThemeManager* tm = manage (new ThemeManager);
3041 add_page (_("Theme"), *tm);
3045 RCOptionEditor::parameter_changed (string const & p)
3047 OptionEditor::parameter_changed (p);
3049 if (p == "use-monitor-bus") {
3050 bool const s = Config->get_use_monitor_bus ();
3052 /* we can't use this if we don't have a monitor bus */
3053 Config->set_solo_control_is_listen_control (false);
3055 _solo_control_is_listen_control->set_sensitive (s);
3056 _listen_position->set_sensitive (s);
3057 } else if (p == "sync-source") {
3058 _sync_source->set_sensitive (true);
3060 _sync_source->set_sensitive (!_session->config.get_external_sync());
3062 switch(Config->get_sync_source()) {
3065 _sync_genlock->set_sensitive (true);
3066 _sync_framerate->set_sensitive (true);
3067 _sync_source_2997->set_sensitive (true);
3070 _sync_genlock->set_sensitive (false);
3071 _sync_framerate->set_sensitive (false);
3072 _sync_source_2997->set_sensitive (false);
3075 } else if (p == "send-ltc") {
3076 bool const s = Config->get_send_ltc ();
3077 _ltc_send_continuously->set_sensitive (s);
3078 _ltc_volume_slider->set_sensitive (s);
3082 void RCOptionEditor::ltc_generator_volume_changed () {
3083 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
3087 RCOptionEditor::populate_sync_options ()
3089 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3091 _sync_source->clear ();
3093 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3094 _sync_source->add (*i, sync_source_to_string (*i));
3097 if (sync_opts.empty()) {
3098 _sync_source->set_sensitive(false);
3100 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3101 _rc_config->set_sync_source(sync_opts.front());