2 Copyright (C) 2001-2011 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "gtk2ardour-config.h"
24 #if !defined USE_CAIRO_IMAGE_SURFACE && !defined NDEBUG
25 #define OPTIONAL_CAIRO_IMAGE_SURFACE
28 #include <cairo/cairo.h>
30 #include <boost/algorithm/string.hpp>
32 #include <gtkmm/liststore.h>
33 #include <gtkmm/stock.h>
34 #include <gtkmm/scale.h>
36 #include <gtkmm2ext/utils.h>
37 #include <gtkmm2ext/slider_controller.h>
38 #include <gtkmm2ext/gtk_ui.h>
39 #include <gtkmm2ext/paths_dialog.h>
44 #include "ardour/audioengine.h"
45 #include "ardour/dB.h"
46 #include "ardour/rc_configuration.h"
47 #include "ardour/control_protocol_manager.h"
48 #include "ardour/plugin_manager.h"
49 #include "control_protocol/control_protocol.h"
51 #include "canvas/wave_view.h"
53 #include "ardour_window.h"
54 #include "ardour_dialog.h"
55 #include "gui_thread.h"
56 #include "meter_patterns.h"
57 #include "midi_tracer.h"
58 #include "rc_option_editor.h"
60 #include "midi_port_dialog.h"
63 #include "theme_manager.h"
64 #include "ui_config.h"
69 using namespace Gtkmm2ext;
71 using namespace ARDOUR;
72 using namespace ARDOUR_UI_UTILS;
74 class ClickOptions : public OptionEditorBox
77 ClickOptions (RCConfiguration* c, Gtk::Window* p)
79 , _click_browse_button (_("Browse..."))
80 , _click_emphasis_browse_button (_("Browse..."))
82 Table* t = manage (new Table (4, 3));
85 Label* l = manage (left_aligned_label (_("Use default Click:")));
86 t->attach (*l, 0, 1, 0, 1, FILL);
87 t->attach (_use_default_click_check_button, 1, 2, 0, 1, FILL);
88 _use_default_click_check_button.signal_toggled().connect (
89 sigc::mem_fun (*this, &ClickOptions::use_default_click_toggled));
91 l = manage (left_aligned_label (_("Emphasis on first beat:")));
92 t->attach (*l, 0, 1, 1, 2, FILL);
93 t->attach (_use_emphasis_on_click_check_button, 1, 2, 1, 2, FILL);
94 _use_emphasis_on_click_check_button.signal_toggled().connect (
95 sigc::mem_fun (*this, &ClickOptions::use_emphasis_on_click_toggled));
97 l = manage (left_aligned_label (_("Click audio file:")));
98 t->attach (*l, 0, 1, 2, 3, FILL);
99 t->attach (_click_path_entry, 1, 2, 2, 3, FILL);
100 _click_browse_button.signal_clicked ().connect (
101 sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
102 t->attach (_click_browse_button, 2, 3, 2, 3, FILL);
104 l = manage (left_aligned_label (_("Click emphasis audio file:")));
105 t->attach (*l, 0, 1, 3, 4, FILL);
106 t->attach (_click_emphasis_path_entry, 1, 2, 3, 4, FILL);
107 _click_emphasis_browse_button.signal_clicked ().connect (
108 sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
109 t->attach (_click_emphasis_browse_button, 2, 3, 3, 4, FILL);
111 _box->pack_start (*t, false, false);
113 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
114 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
116 if (_rc_config->get_click_sound ().empty() &&
117 _rc_config->get_click_emphasis_sound().empty()) {
118 _use_default_click_check_button.set_active (true);
119 _use_emphasis_on_click_check_button.set_active (true);
122 _use_default_click_check_button.set_active (false);
123 _use_emphasis_on_click_check_button.set_active (false);
127 void parameter_changed (string const & p)
129 if (p == "click-sound") {
130 _click_path_entry.set_text (_rc_config->get_click_sound());
131 } else if (p == "click-emphasis-sound") {
132 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
133 } else if (p == "use-click-emphasis") {
134 bool x = _rc_config->get_use_click_emphasis ();
135 _use_emphasis_on_click_check_button.set_active (x);
139 void set_state_from_config ()
141 parameter_changed ("click-sound");
142 parameter_changed ("click-emphasis-sound");
143 parameter_changed ("use-click-emphasis");
148 void click_browse_clicked ()
150 SoundFileChooser sfdb (_("Choose Click"));
155 if (sfdb.run () == RESPONSE_OK) {
156 click_chosen (sfdb.get_filename());
160 void click_chosen (string const & path)
162 _click_path_entry.set_text (path);
163 _rc_config->set_click_sound (path);
166 void click_changed ()
168 click_chosen (_click_path_entry.get_text ());
171 void click_emphasis_browse_clicked ()
173 SoundFileChooser sfdb (_("Choose Click Emphasis"));
178 if (sfdb.run () == RESPONSE_OK) {
179 click_emphasis_chosen (sfdb.get_filename());
183 void click_emphasis_chosen (string const & path)
185 _click_emphasis_path_entry.set_text (path);
186 _rc_config->set_click_emphasis_sound (path);
189 void click_emphasis_changed ()
191 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
194 void use_default_click_toggled ()
196 if (_use_default_click_check_button.get_active ()) {
197 _rc_config->set_click_sound ("");
198 _rc_config->set_click_emphasis_sound ("");
199 _click_path_entry.set_sensitive (false);
200 _click_emphasis_path_entry.set_sensitive (false);
201 _click_browse_button.set_sensitive (false);
202 _click_emphasis_browse_button.set_sensitive (false);
204 _click_path_entry.set_sensitive (true);
205 _click_emphasis_path_entry.set_sensitive (true);
206 _click_browse_button.set_sensitive (true);
207 _click_emphasis_browse_button.set_sensitive (true);
211 void use_emphasis_on_click_toggled ()
213 if (_use_emphasis_on_click_check_button.get_active ()) {
214 _rc_config->set_use_click_emphasis(true);
216 _rc_config->set_use_click_emphasis(false);
220 RCConfiguration* _rc_config;
221 CheckButton _use_default_click_check_button;
222 CheckButton _use_emphasis_on_click_check_button;
223 Entry _click_path_entry;
224 Entry _click_emphasis_path_entry;
225 Button _click_browse_button;
226 Button _click_emphasis_browse_button;
229 class UndoOptions : public OptionEditorBox
232 UndoOptions (RCConfiguration* c) :
234 _limit_undo_button (_("Limit undo history to")),
235 _save_undo_button (_("Save undo history of"))
237 Table* t = new Table (2, 3);
240 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
241 _limit_undo_spin.set_range (0, 512);
242 _limit_undo_spin.set_increments (1, 10);
243 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
244 Label* l = manage (left_aligned_label (_("commands")));
245 t->attach (*l, 2, 3, 0, 1);
247 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
248 _save_undo_spin.set_range (0, 512);
249 _save_undo_spin.set_increments (1, 10);
250 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
251 l = manage (left_aligned_label (_("commands")));
252 t->attach (*l, 2, 3, 1, 2);
254 _box->pack_start (*t);
256 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
257 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
258 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
259 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
262 void parameter_changed (string const & p)
264 if (p == "history-depth") {
265 int32_t const d = _rc_config->get_history_depth();
266 _limit_undo_button.set_active (d != 0);
267 _limit_undo_spin.set_sensitive (d != 0);
268 _limit_undo_spin.set_value (d);
269 } else if (p == "save-history") {
270 bool const x = _rc_config->get_save_history ();
271 _save_undo_button.set_active (x);
272 _save_undo_spin.set_sensitive (x);
273 } else if (p == "save-history-depth") {
274 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
278 void set_state_from_config ()
280 parameter_changed ("save-history");
281 parameter_changed ("history-depth");
282 parameter_changed ("save-history-depth");
285 void limit_undo_toggled ()
287 bool const x = _limit_undo_button.get_active ();
288 _limit_undo_spin.set_sensitive (x);
289 int32_t const n = x ? 16 : 0;
290 _limit_undo_spin.set_value (n);
291 _rc_config->set_history_depth (n);
294 void limit_undo_changed ()
296 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
299 void save_undo_toggled ()
301 bool const x = _save_undo_button.get_active ();
302 _rc_config->set_save_history (x);
305 void save_undo_changed ()
307 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
311 RCConfiguration* _rc_config;
312 CheckButton _limit_undo_button;
313 SpinButton _limit_undo_spin;
314 CheckButton _save_undo_button;
315 SpinButton _save_undo_spin;
320 static const struct {
332 { "Key|Shift", GDK_SHIFT_MASK },
333 { "Command", GDK_META_MASK },
334 { "Control", GDK_CONTROL_MASK },
335 { "Option", GDK_MOD1_MASK },
336 { "Command-Shift", GDK_META_MASK|GDK_SHIFT_MASK },
337 { "Command-Option", GDK_MOD1_MASK|GDK_META_MASK },
338 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
339 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
340 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_META_MASK },
343 { "Key|Shift", GDK_SHIFT_MASK },
344 { "Control", GDK_CONTROL_MASK },
345 { "Alt", GDK_MOD1_MASK },
346 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
347 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
348 { "Shift-Alt", GDK_SHIFT_MASK|GDK_MOD1_MASK },
349 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
350 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
351 { "Mod2", GDK_MOD2_MASK },
352 { "Mod3", GDK_MOD3_MASK },
353 { "Windows", GDK_MOD4_MASK },
354 { "Mod5", GDK_MOD5_MASK },
360 class KeyboardOptions : public OptionEditorBox
364 _delete_button_adjustment (3, 1, 12),
365 _delete_button_spin (_delete_button_adjustment),
366 _edit_button_adjustment (3, 1, 5),
367 _edit_button_spin (_edit_button_adjustment),
368 _insert_note_button_adjustment (3, 1, 5),
369 _insert_note_button_spin (_insert_note_button_adjustment)
371 /* internationalize and prepare for use with combos */
374 for (int i = 0; modifiers[i].name; ++i) {
375 dumb.push_back (S_(modifiers[i].name));
378 set_popdown_strings (_edit_modifier_combo, dumb);
379 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
381 for (int x = 0; modifiers[x].name; ++x) {
382 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
383 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
388 Table* t = manage (new Table (5, 11));
394 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
395 l->set_name ("OptionsLabel");
399 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
400 strs.push_back (bf->first);
403 set_popdown_strings (_keyboard_layout_selector, strs);
404 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
405 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
407 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
408 t->attach (_keyboard_layout_selector, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
413 l = manage (left_aligned_label (_("When Clicking:")));
414 l->set_name ("OptionEditorHeading");
415 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
420 l = manage (left_aligned_label (_("Edit using:")));
421 l->set_name ("OptionsLabel");
423 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
424 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
426 l = manage (new Label (_("+ button")));
427 l->set_name ("OptionsLabel");
429 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
430 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
432 _edit_button_spin.set_name ("OptionsEntry");
433 _edit_button_adjustment.set_value (Keyboard::edit_button());
434 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
439 set_popdown_strings (_delete_modifier_combo, dumb);
440 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
442 for (int x = 0; modifiers[x].name; ++x) {
443 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
444 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
449 l = manage (left_aligned_label (_("Delete using:")));
450 l->set_name ("OptionsLabel");
452 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
453 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
455 l = manage (new Label (_("+ button")));
456 l->set_name ("OptionsLabel");
458 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
459 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
461 _delete_button_spin.set_name ("OptionsEntry");
462 _delete_button_adjustment.set_value (Keyboard::delete_button());
463 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
468 set_popdown_strings (_insert_note_modifier_combo, dumb);
469 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
471 for (int x = 0; modifiers[x].name; ++x) {
472 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
473 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
478 l = manage (left_aligned_label (_("Insert note using:")));
479 l->set_name ("OptionsLabel");
481 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
482 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
484 l = manage (new Label (_("+ button")));
485 l->set_name ("OptionsLabel");
487 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
488 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
490 _insert_note_button_spin.set_name ("OptionsEntry");
491 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
492 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
496 l = manage (left_aligned_label (_("When Beginning a Drag:")));
497 l->set_name ("OptionEditorHeading");
498 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
504 set_popdown_strings (_copy_modifier_combo, dumb);
505 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
507 for (int x = 0; modifiers[x].name; ++x) {
508 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
509 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
514 l = manage (left_aligned_label (_("Copy items using:")));
515 l->set_name ("OptionsLabel");
517 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
518 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
523 /* constraint modifier */
524 set_popdown_strings (_constraint_modifier_combo, dumb);
525 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
527 for (int x = 0; modifiers[x].name; ++x) {
528 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
529 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
534 l = manage (left_aligned_label (_("Constrain drag using:")));
535 l->set_name ("OptionsLabel");
537 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
538 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
542 l = manage (left_aligned_label (_("When Beginning a Trim:")));
543 l->set_name ("OptionEditorHeading");
544 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
550 set_popdown_strings (_trim_contents_combo, dumb);
551 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
553 for (int x = 0; modifiers[x].name; ++x) {
554 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
555 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
560 l = manage (left_aligned_label (_("Trim contents using:")));
561 l->set_name ("OptionsLabel");
563 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
564 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
570 set_popdown_strings (_trim_anchored_combo, dumb);
571 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
573 for (int x = 0; modifiers[x].name; ++x) {
574 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
575 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
580 l = manage (left_aligned_label (_("Anchored trim using:")));
581 l->set_name ("OptionsLabel");
583 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
585 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
590 /* jump trim disabled for now
591 set_popdown_strings (_trim_jump_combo, dumb);
592 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
594 for (int x = 0; modifiers[x].name; ++x) {
595 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
596 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
601 l = manage (left_aligned_label (_("Jump after trim using:")));
602 l->set_name ("OptionsLabel");
604 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
606 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
612 /* note resize relative */
613 set_popdown_strings (_note_size_relative_combo, dumb);
614 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
616 for (int x = 0; modifiers[x].name; ++x) {
617 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
618 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
623 l = manage (left_aligned_label (_("Resize notes relatively using:")));
624 l->set_name ("OptionsLabel");
626 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
628 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
632 l = manage (left_aligned_label (_("While Dragging:")));
633 l->set_name ("OptionEditorHeading");
634 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
640 set_popdown_strings (_snap_modifier_combo, dumb);
641 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
643 for (int x = 0; modifiers[x].name; ++x) {
644 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
645 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
650 l = manage (left_aligned_label (_("Ignore snap using:")));
651 l->set_name ("OptionsLabel");
653 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
654 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
660 set_popdown_strings (_snap_delta_combo, dumb);
661 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
663 for (int x = 0; modifiers[x].name; ++x) {
664 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
665 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
670 l = manage (left_aligned_label (_("Snap relatively using:")));
671 l->set_name ("OptionsLabel");
673 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
674 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
678 l = manage (left_aligned_label (_("While Trimming:")));
679 l->set_name ("OptionEditorHeading");
680 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
686 set_popdown_strings (_trim_overlap_combo, dumb);
687 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
689 for (int x = 0; modifiers[x].name; ++x) {
690 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
691 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
696 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
697 l->set_name ("OptionsLabel");
699 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
700 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
704 l = manage (left_aligned_label (_("While Dragging Control Points:")));
705 l->set_name ("OptionEditorHeading");
706 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
712 set_popdown_strings (_fine_adjust_combo, dumb);
713 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
715 for (int x = 0; modifiers[x].name; ++x) {
716 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
717 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
722 l = manage (left_aligned_label (_("Fine adjust using:")));
723 l->set_name ("OptionsLabel");
725 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
726 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
732 set_popdown_strings (_push_points_combo, dumb);
733 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
735 for (int x = 0; modifiers[x].name; ++x) {
736 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
737 _push_points_combo.set_active_text (S_(modifiers[x].name));
742 l = manage (left_aligned_label (_("Push points using:")));
743 l->set_name ("OptionsLabel");
745 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
746 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
748 _box->pack_start (*t, false, false);
751 void parameter_changed (string const &)
753 /* XXX: these aren't really config options... */
756 void set_state_from_config ()
758 /* XXX: these aren't really config options... */
763 void bindings_changed ()
765 string const txt = _keyboard_layout_selector.get_active_text();
767 /* XXX: config...? for all this keyboard stuff */
769 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
770 if (txt == i->first) {
771 if (Keyboard::load_keybindings (i->second)) {
772 Keyboard::save_keybindings ();
778 void edit_modifier_chosen ()
780 string const txt = _edit_modifier_combo.get_active_text();
782 for (int i = 0; modifiers[i].name; ++i) {
783 if (txt == _(modifiers[i].name)) {
784 Keyboard::set_edit_modifier (modifiers[i].modifier);
790 void delete_modifier_chosen ()
792 string const txt = _delete_modifier_combo.get_active_text();
794 for (int i = 0; modifiers[i].name; ++i) {
795 if (txt == _(modifiers[i].name)) {
796 Keyboard::set_delete_modifier (modifiers[i].modifier);
802 void copy_modifier_chosen ()
804 string const txt = _copy_modifier_combo.get_active_text();
806 for (int i = 0; modifiers[i].name; ++i) {
807 if (txt == _(modifiers[i].name)) {
808 Keyboard::set_copy_modifier (modifiers[i].modifier);
814 void insert_note_modifier_chosen ()
816 string const txt = _insert_note_modifier_combo.get_active_text();
818 for (int i = 0; modifiers[i].name; ++i) {
819 if (txt == _(modifiers[i].name)) {
820 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
826 void snap_modifier_chosen ()
828 string const txt = _snap_modifier_combo.get_active_text();
830 for (int i = 0; modifiers[i].name; ++i) {
831 if (txt == _(modifiers[i].name)) {
832 Keyboard::set_snap_modifier (modifiers[i].modifier);
838 void snap_delta_modifier_chosen ()
840 string const txt = _snap_delta_combo.get_active_text();
842 for (int i = 0; modifiers[i].name; ++i) {
843 if (txt == _(modifiers[i].name)) {
844 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
850 void constraint_modifier_chosen ()
852 string const txt = _constraint_modifier_combo.get_active_text();
854 for (int i = 0; modifiers[i].name; ++i) {
855 if (txt == _(modifiers[i].name)) {
856 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
862 void trim_contents_modifier_chosen ()
864 string const txt = _trim_contents_combo.get_active_text();
866 for (int i = 0; modifiers[i].name; ++i) {
867 if (txt == _(modifiers[i].name)) {
868 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
874 void trim_overlap_modifier_chosen ()
876 string const txt = _trim_overlap_combo.get_active_text();
878 for (int i = 0; modifiers[i].name; ++i) {
879 if (txt == _(modifiers[i].name)) {
880 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
886 void trim_anchored_modifier_chosen ()
888 string const txt = _trim_anchored_combo.get_active_text();
890 for (int i = 0; modifiers[i].name; ++i) {
891 if (txt == _(modifiers[i].name)) {
892 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
898 void fine_adjust_modifier_chosen ()
900 string const txt = _fine_adjust_combo.get_active_text();
902 for (int i = 0; modifiers[i].name; ++i) {
903 if (txt == _(modifiers[i].name)) {
904 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
910 void push_points_modifier_chosen ()
912 string const txt = _push_points_combo.get_active_text();
914 for (int i = 0; modifiers[i].name; ++i) {
915 if (txt == _(modifiers[i].name)) {
916 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
922 void note_size_relative_modifier_chosen ()
924 string const txt = _note_size_relative_combo.get_active_text();
926 for (int i = 0; modifiers[i].name; ++i) {
927 if (txt == _(modifiers[i].name)) {
928 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
934 void delete_button_changed ()
936 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
939 void edit_button_changed ()
941 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
944 void insert_note_button_changed ()
946 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
949 ComboBoxText _keyboard_layout_selector;
950 ComboBoxText _edit_modifier_combo;
951 ComboBoxText _delete_modifier_combo;
952 ComboBoxText _copy_modifier_combo;
953 ComboBoxText _insert_note_modifier_combo;
954 ComboBoxText _snap_modifier_combo;
955 ComboBoxText _snap_delta_combo;
956 ComboBoxText _constraint_modifier_combo;
957 ComboBoxText _trim_contents_combo;
958 ComboBoxText _trim_overlap_combo;
959 ComboBoxText _trim_anchored_combo;
960 ComboBoxText _trim_jump_combo;
961 ComboBoxText _fine_adjust_combo;
962 ComboBoxText _push_points_combo;
963 ComboBoxText _note_size_relative_combo;
964 Adjustment _delete_button_adjustment;
965 SpinButton _delete_button_spin;
966 Adjustment _edit_button_adjustment;
967 SpinButton _edit_button_spin;
968 Adjustment _insert_note_button_adjustment;
969 SpinButton _insert_note_button_spin;
973 class FontScalingOptions : public OptionEditorBox
976 FontScalingOptions () :
977 _dpi_adjustment (100, 50, 250, 1, 5),
978 _dpi_slider (_dpi_adjustment)
980 _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.);
982 Label* l = manage (new Label (_("GUI and Font scaling:")));
983 l->set_name ("OptionsLabel");
985 const Glib::ustring dflt = _("Default");
986 const Glib::ustring empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
988 _dpi_slider.set_name("FontScaleSlider");
989 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
990 _dpi_slider.set_draw_value(false);
991 _dpi_slider.add_mark(50, Gtk::POS_TOP, empty);
992 _dpi_slider.add_mark(60, Gtk::POS_TOP, empty);
993 _dpi_slider.add_mark(70, Gtk::POS_TOP, empty);
994 _dpi_slider.add_mark(80, Gtk::POS_TOP, empty);
995 _dpi_slider.add_mark(90, Gtk::POS_TOP, empty);
996 _dpi_slider.add_mark(100, Gtk::POS_TOP, dflt);
997 _dpi_slider.add_mark(125, Gtk::POS_TOP, empty);
998 _dpi_slider.add_mark(150, Gtk::POS_TOP, empty);
999 _dpi_slider.add_mark(175, Gtk::POS_TOP, empty);
1000 _dpi_slider.add_mark(200, Gtk::POS_TOP, empty);
1001 _dpi_slider.add_mark(225, Gtk::POS_TOP, empty);
1002 _dpi_slider.add_mark(250, Gtk::POS_TOP, empty);
1004 HBox* h = manage (new HBox);
1006 h->pack_start (*l, false, false);
1007 h->pack_start (_dpi_slider, true, true);
1009 _box->pack_start (*h, false, false);
1011 set_note (_("Adjusting the scale require an application restart to re-layout."));
1013 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
1016 void parameter_changed (string const & p)
1018 if (p == "font-scale") {
1019 _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.);
1023 void set_state_from_config ()
1025 parameter_changed ("font-scale");
1032 UIConfiguration::instance().set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024.));
1033 /* XXX: should be triggered from the parameter changed signal */
1034 UIConfiguration::instance().reset_dpi ();
1037 Adjustment _dpi_adjustment;
1041 class ClipLevelOptions : public OptionEditorBox
1045 : _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1046 , _clip_level_slider (_clip_level_adjustment)
1048 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level ());
1050 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
1051 l->set_name ("OptionsLabel");
1053 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1054 HBox* h = manage (new HBox);
1056 h->pack_start (*l, false, false);
1057 h->pack_start (_clip_level_slider, true, true);
1059 _box->pack_start (*h, false, false);
1061 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1064 void parameter_changed (string const & p)
1066 if (p == "waveform-clip-level") {
1067 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level());
1071 void set_state_from_config ()
1073 parameter_changed ("waveform-clip-level");
1078 void clip_level_changed ()
1080 UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value());
1081 /* XXX: should be triggered from the parameter changed signal */
1082 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1085 Adjustment _clip_level_adjustment;
1086 HScale _clip_level_slider;
1089 class BufferingOptions : public OptionEditorBox
1092 BufferingOptions (RCConfiguration* c)
1094 , _playback_adjustment (5, 1, 60, 1, 4)
1095 , _capture_adjustment (5, 1, 60, 1, 4)
1096 , _playback_slider (_playback_adjustment)
1097 , _capture_slider (_capture_adjustment)
1099 vector<string> presets;
1101 /* these must match the order of the enums for BufferingPreset */
1103 presets.push_back (_("Small sessions (4-16 tracks)"));
1104 presets.push_back (_("Medium sessions (16-64 tracks)"));
1105 presets.push_back (_("Large sessions (64+ tracks)"));
1106 presets.push_back (_("Custom (set by sliders below)"));
1108 set_popdown_strings (_buffering_presets_combo, presets);
1110 Label* l = manage (new Label (_("Preset:")));
1111 l->set_name ("OptionsLabel");
1112 HBox* h = manage (new HBox);
1113 h->set_spacing (12);
1114 h->pack_start (*l, false, false);
1115 h->pack_start (_buffering_presets_combo, true, true);
1116 _box->pack_start (*h, false, false);
1118 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1120 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1122 l = manage (new Label (_("Playback (seconds of buffering):")));
1123 l->set_name ("OptionsLabel");
1125 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1126 h = manage (new HBox);
1128 h->pack_start (*l, false, false);
1129 h->pack_start (_playback_slider, true, true);
1131 _box->pack_start (*h, false, false);
1133 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1135 l = manage (new Label (_("Recording (seconds of buffering):")));
1136 l->set_name ("OptionsLabel");
1138 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1139 h = manage (new HBox);
1141 h->pack_start (*l, false, false);
1142 h->pack_start (_capture_slider, true, true);
1144 _box->pack_start (*h, false, false);
1146 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
1147 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
1150 void parameter_changed (string const & p)
1152 if (p == "buffering-preset") {
1153 switch (_rc_config->get_buffering_preset()) {
1155 _playback_slider.set_sensitive (false);
1156 _capture_slider.set_sensitive (false);
1157 _buffering_presets_combo.set_active (0);
1160 _playback_slider.set_sensitive (false);
1161 _capture_slider.set_sensitive (false);
1162 _buffering_presets_combo.set_active (1);
1165 _playback_slider.set_sensitive (false);
1166 _capture_slider.set_sensitive (false);
1167 _buffering_presets_combo.set_active (2);
1170 _playback_slider.set_sensitive (true);
1171 _capture_slider.set_sensitive (true);
1172 _buffering_presets_combo.set_active (3);
1177 if (p == "playback-buffer-seconds") {
1178 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1179 } else if (p == "capture-buffer-seconds") {
1180 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1184 void set_state_from_config ()
1186 parameter_changed ("buffering-preset");
1187 parameter_changed ("playback-buffer-seconds");
1188 parameter_changed ("capture-buffer-seconds");
1193 void preset_changed ()
1195 int index = _buffering_presets_combo.get_active_row_number ();
1201 _rc_config->set_buffering_preset (Small);
1204 _rc_config->set_buffering_preset (Medium);
1207 _rc_config->set_buffering_preset (Large);
1210 _rc_config->set_buffering_preset (Custom);
1213 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1218 void playback_changed ()
1220 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
1223 void capture_changed ()
1225 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
1228 RCConfiguration* _rc_config;
1229 Adjustment _playback_adjustment;
1230 Adjustment _capture_adjustment;
1231 HScale _playback_slider;
1232 HScale _capture_slider;
1233 ComboBoxText _buffering_presets_combo;
1236 class ControlSurfacesOptions : public OptionEditorBox
1239 ControlSurfacesOptions (Gtk::Window& parent)
1241 , _ignore_view_change (0)
1243 _store = ListStore::create (_model);
1244 _view.set_model (_store);
1245 _view.append_column (_("Control Surface Protocol"), _model.name);
1246 _view.get_column(0)->set_resizable (true);
1247 _view.get_column(0)->set_expand (true);
1248 _view.append_column_editable (_("Enabled"), _model.enabled);
1249 _view.append_column_editable (_("Feedback"), _model.feedback);
1251 _box->pack_start (_view, false, false);
1253 Label* label = manage (new Label);
1254 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
1256 _box->pack_start (*label, false, false);
1259 ControlProtocolManager& m = ControlProtocolManager::instance ();
1260 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1261 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1263 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1264 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1267 void parameter_changed (std::string const &)
1272 void set_state_from_config ()
1276 ControlProtocolManager& m = ControlProtocolManager::instance ();
1277 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1279 if (!(*i)->mandatory) {
1280 TreeModel::Row r = *_store->append ();
1281 r[_model.name] = (*i)->name;
1282 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1283 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
1284 r[_model.protocol_info] = *i;
1291 void protocol_status_changed (ControlProtocolInfo* cpi) {
1293 TreeModel::Children rows = _store->children();
1295 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1296 string n = ((*x)[_model.name]);
1298 if ((*x)[_model.protocol_info] == cpi) {
1299 _ignore_view_change++;
1300 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1301 _ignore_view_change--;
1307 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1309 TreeModel::Row r = *i;
1311 if (_ignore_view_change) {
1315 ControlProtocolInfo* cpi = r[_model.protocol_info];
1320 bool const was_enabled = (cpi->protocol != 0);
1321 bool const is_enabled = r[_model.enabled];
1324 if (was_enabled != is_enabled) {
1327 ControlProtocolManager::instance().activate (*cpi);
1329 ControlProtocolManager::instance().deactivate (*cpi);
1333 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
1334 bool const is_feedback = r[_model.feedback];
1336 if (was_feedback != is_feedback && cpi->protocol) {
1337 cpi->protocol->set_feedback (is_feedback);
1341 void edit_clicked (GdkEventButton* ev)
1343 if (ev->type != GDK_2BUTTON_PRESS) {
1348 ControlProtocolInfo* cpi;
1351 row = *(_view.get_selection()->get_selected());
1352 if (!row[_model.enabled]) {
1355 cpi = row[_model.protocol_info];
1356 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1359 Box* box = (Box*) cpi->protocol->get_gui ();
1363 if (box->get_parent()) {
1364 static_cast<ArdourWindow*>(box->get_parent())->present();
1367 string title = row[_model.name];
1368 /* once created, the window is managed by the surface itself (as ->get_parent())
1369 * Surface's tear_down_gui() is called on session close, when de-activating
1370 * or re-initializing a surface.
1371 * tear_down_gui() hides an deletes the Window if it exists.
1373 ArdourWindow* win = new ArdourWindow (_parent, title);
1374 win->set_title ("Control Protocol Options");
1380 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1384 ControlSurfacesModelColumns ()
1389 add (protocol_info);
1392 TreeModelColumn<string> name;
1393 TreeModelColumn<bool> enabled;
1394 TreeModelColumn<bool> feedback;
1395 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1398 Glib::RefPtr<ListStore> _store;
1399 ControlSurfacesModelColumns _model;
1401 Gtk::Window& _parent;
1402 PBD::ScopedConnection protocol_status_connection;
1403 uint32_t _ignore_view_change;
1406 class VideoTimelineOptions : public OptionEditorBox
1409 VideoTimelineOptions (RCConfiguration* c)
1411 , _show_video_export_info_button (_("Show Video Export Info before export"))
1412 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1413 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1415 Table* t = manage (new Table (2, 6));
1416 t->set_spacings (4);
1418 t->attach (_video_advanced_setup_button, 0, 2, 0, 1);
1419 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1420 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1421 _("<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."));
1423 Label* l = manage (new Label (_("Video Server URL:")));
1424 l->set_alignment (0, 0.5);
1425 t->attach (*l, 0, 1, 1, 2, FILL);
1426 t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL);
1427 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1428 _("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"));
1430 l = manage (new Label (_("Video Folder:")));
1431 l->set_alignment (0, 0.5);
1432 t->attach (*l, 0, 1, 2, 3, FILL);
1433 t->attach (_video_server_docroot_entry, 1, 2, 2, 3);
1434 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1435 _("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."));
1437 /* small vspace y=3..4 */
1439 t->attach (_show_video_export_info_button, 0, 2, 4, 5);
1440 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1441 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1442 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1444 t->attach (_show_video_server_dialog_button, 0, 2, 5, 6);
1445 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1446 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1447 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1449 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1450 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1451 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1452 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1454 _box->pack_start (*t,true,true);
1457 void server_url_changed ()
1459 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1462 void server_docroot_changed ()
1464 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1467 void show_video_export_info_toggled ()
1469 bool const x = _show_video_export_info_button.get_active ();
1470 _rc_config->set_show_video_export_info (x);
1473 void show_video_server_dialog_toggled ()
1475 bool const x = _show_video_server_dialog_button.get_active ();
1476 _rc_config->set_show_video_server_dialog (x);
1479 void video_advanced_setup_toggled ()
1481 bool const x = _video_advanced_setup_button.get_active ();
1482 _rc_config->set_video_advanced_setup(x);
1485 void parameter_changed (string const & p)
1487 if (p == "video-server-url") {
1488 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1489 } else if (p == "video-server-docroot") {
1490 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1491 } else if (p == "show-video-export-info") {
1492 bool const x = _rc_config->get_show_video_export_info();
1493 _show_video_export_info_button.set_active (x);
1494 } else if (p == "show-video-server-dialog") {
1495 bool const x = _rc_config->get_show_video_server_dialog();
1496 _show_video_server_dialog_button.set_active (x);
1497 } else if (p == "video-advanced-setup") {
1498 bool const x = _rc_config->get_video_advanced_setup();
1499 _video_advanced_setup_button.set_active(x);
1500 _video_server_docroot_entry.set_sensitive(x);
1501 _video_server_url_entry.set_sensitive(x);
1505 void set_state_from_config ()
1507 parameter_changed ("video-server-url");
1508 parameter_changed ("video-server-docroot");
1509 parameter_changed ("video-monitor-setup-dialog");
1510 parameter_changed ("show-video-export-info");
1511 parameter_changed ("show-video-server-dialog");
1512 parameter_changed ("video-advanced-setup");
1516 RCConfiguration* _rc_config;
1517 Entry _video_server_url_entry;
1518 Entry _video_server_docroot_entry;
1519 CheckButton _show_video_export_info_button;
1520 CheckButton _show_video_server_dialog_button;
1521 CheckButton _video_advanced_setup_button;
1524 class PluginOptions : public OptionEditorBox
1527 PluginOptions (RCConfiguration* c)
1529 , _display_plugin_scan_progress (_("Always Display Plugin Scan Progress"))
1530 , _discover_vst_on_start (_("Scan for [new] VST Plugins on Application Start"))
1531 , _discover_au_on_start (_("Scan for AudioUnit Plugins on Application Start"))
1532 , _verbose_plugin_scan (_("Verbose Plugin Scan"))
1533 , _timeout_adjustment (0, 0, 3000, 50, 50)
1534 , _timeout_slider (_timeout_adjustment)
1537 std::stringstream ss;
1538 Table* t = manage (new Table (2, 6));
1539 t->set_spacings (4);
1543 ss << "<b>" << _("General") << "</b>";
1544 l = manage (left_aligned_label (ss.str()));
1545 l->set_use_markup (true);
1546 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1547 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1549 b = manage (new Button (_("Scan for Plugins")));
1550 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1551 t->attach (*b, 0, 2, n, n+1, FILL); ++n;
1553 t->attach (_display_plugin_scan_progress, 0, 2, n, n+1); ++n;
1554 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1555 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1556 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
1558 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
1559 _timeout_slider.set_digits (0);
1560 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &PluginOptions::timeout_changed));
1562 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1563 _("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."));
1565 l = manage (left_aligned_label (_("Scan Time Out [deciseconds]")));;
1566 HBox* h = manage (new HBox);
1568 h->pack_start (*l, false, false);
1569 h->pack_start (_timeout_slider, true, true);
1570 t->attach (*h, 0, 2, n, n+1); ++n;
1573 ss << "<b>" << _("VST") << "</b>";
1574 l = manage (left_aligned_label (ss.str()));
1575 l->set_use_markup (true);
1576 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1577 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1579 b = manage (new Button (_("Clear VST Cache")));
1580 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_cache_clicked));
1581 t->attach (*b, 0, 1, n, n+1, FILL);
1583 b = manage (new Button (_("Clear VST Blacklist")));
1584 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_blacklist_clicked));
1585 t->attach (*b, 1, 2, n, n+1, FILL);
1588 t->attach (_discover_vst_on_start, 0, 2, n, n+1); ++n;
1589 _discover_vst_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_vst_on_start_toggled));
1590 Gtkmm2ext::UI::instance()->set_tip (_discover_vst_on_start,
1591 _("<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"));
1593 #ifdef LXVST_SUPPORT
1594 t->attach (*manage (right_aligned_label (_("Linux VST Path:"))), 0, 1, n, n+1);
1595 b = manage (new Button (_("Edit")));
1596 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_lxvst_path_clicked));
1597 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1600 #ifdef WINDOWS_VST_SUPPORT
1601 t->attach (*manage (right_aligned_label (_("Windows VST Path:"))), 0, 1, n, n+1);
1602 b = manage (new Button (_("Edit")));
1603 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_vst_path_clicked));
1604 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1606 // currently verbose logging is only implemented for Windows VST.
1607 t->attach (_verbose_plugin_scan, 0, 2, n, n+1); ++n;
1608 _verbose_plugin_scan.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::verbose_plugin_scan_toggled));
1609 Gtkmm2ext::UI::instance()->set_tip (_verbose_plugin_scan,
1610 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
1614 #ifdef AUDIOUNIT_SUPPORT
1616 ss << "<b>" << _("Audio Unit") << "</b>";
1617 l = manage (left_aligned_label (ss.str()));
1618 l->set_use_markup (true);
1619 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1620 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1622 t->attach (_discover_au_on_start, 0, 2, n, n+1); ++n;
1623 _discover_au_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_au_on_start_toggled));
1624 Gtkmm2ext::UI::instance()->set_tip (_discover_au_on_start,
1625 _("<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."));
1628 b = manage (new Button (_("Clear AU Cache")));
1629 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_cache_clicked));
1630 t->attach (*b, 0, 1, n, n+1, FILL);
1632 b = manage (new Button (_("Clear AU Blacklist")));
1633 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_blacklist_clicked));
1634 t->attach (*b, 1, 2, n, n+1, FILL);
1638 _box->pack_start (*t,true,true);
1641 void parameter_changed (string const & p) {
1642 if (p == "show-plugin-scan-window") {
1643 bool const x = UIConfiguration::instance().get_show_plugin_scan_window();
1644 _display_plugin_scan_progress.set_active (x);
1646 else if (p == "discover-vst-on-start") {
1647 bool const x = _rc_config->get_discover_vst_on_start();
1648 _discover_vst_on_start.set_active (x);
1650 else if (p == "vst-scan-timeout") {
1651 int const x = _rc_config->get_vst_scan_timeout();
1652 _timeout_adjustment.set_value (x);
1654 else if (p == "discover-audio-units") {
1655 bool const x = _rc_config->get_discover_audio_units();
1656 _discover_au_on_start.set_active (x);
1658 else if (p == "verbose-plugin-scan") {
1659 bool const x = _rc_config->get_verbose_plugin_scan();
1660 _verbose_plugin_scan.set_active (x);
1664 void set_state_from_config () {
1665 parameter_changed ("show-plugin-scan-window");
1666 parameter_changed ("discover-vst-on-start");
1667 parameter_changed ("vst-scan-timeout");
1668 parameter_changed ("discover-audio-units");
1669 parameter_changed ("verbose-plugin-scan");
1673 RCConfiguration* _rc_config;
1674 CheckButton _display_plugin_scan_progress;
1675 CheckButton _discover_vst_on_start;
1676 CheckButton _discover_au_on_start;
1677 CheckButton _verbose_plugin_scan;
1678 Adjustment _timeout_adjustment;
1679 HScale _timeout_slider;
1681 void display_plugin_scan_progress_toggled () {
1682 bool const x = _display_plugin_scan_progress.get_active();
1683 UIConfiguration::instance().set_show_plugin_scan_window(x);
1686 void discover_vst_on_start_toggled () {
1687 bool const x = _discover_vst_on_start.get_active();
1688 _rc_config->set_discover_vst_on_start(x);
1691 void discover_au_on_start_toggled () {
1692 bool const x = _discover_au_on_start.get_active();
1693 _rc_config->set_discover_audio_units(x);
1696 void verbose_plugin_scan_toggled () {
1697 bool const x = _verbose_plugin_scan.get_active();
1698 _rc_config->set_verbose_plugin_scan(x);
1701 void timeout_changed () {
1702 int x = floor(_timeout_adjustment.get_value());
1703 _rc_config->set_vst_scan_timeout(x);
1706 void clear_vst_cache_clicked () {
1707 PluginManager::instance().clear_vst_cache();
1710 void clear_vst_blacklist_clicked () {
1711 PluginManager::instance().clear_vst_blacklist();
1714 void clear_au_cache_clicked () {
1715 PluginManager::instance().clear_au_cache();
1718 void clear_au_blacklist_clicked () {
1719 PluginManager::instance().clear_au_blacklist();
1723 void edit_vst_path_clicked () {
1724 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1725 _("Set Windows VST Search Path"),
1726 _rc_config->get_plugin_path_vst(),
1727 PluginManager::instance().get_default_windows_vst_path()
1729 ResponseType r = (ResponseType) pd->run ();
1731 if (r == RESPONSE_ACCEPT) {
1732 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
1737 // todo consolidate with edit_vst_path_clicked..
1738 void edit_lxvst_path_clicked () {
1739 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1740 _("Set Linux VST Search Path"),
1741 _rc_config->get_plugin_path_lxvst(),
1742 PluginManager::instance().get_default_lxvst_path()
1744 ResponseType r = (ResponseType) pd->run ();
1746 if (r == RESPONSE_ACCEPT) {
1747 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
1752 void refresh_clicked () {
1753 PluginManager::instance().refresh();
1758 /** A class which allows control of visibility of some editor components usign
1759 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1760 * which has the correct members, but with null widget pointers. This
1761 * class allows the user to set visibility of the members, the details
1762 * of which are stored in a configuration variable which can be watched
1763 * by parts of the editor that actually contain the widgets whose visibility
1764 * is being controlled.
1767 class VisibilityOption : public Option
1770 /** @param name User-visible name for this group.
1771 * @param g `Dummy' VisibilityGroup (as described above).
1772 * @param get Method to get the value of the appropriate configuration variable.
1773 * @param set Method to set the value of the appropriate configuration variable.
1775 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1776 : Option (g->get_state_name(), name)
1778 , _visibility_group (g)
1782 /* Watch for changes made by the user to our members */
1783 _visibility_group->VisibilityChanged.connect_same_thread (
1784 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1788 void set_state_from_config ()
1790 /* Set our state from the current configuration */
1791 _visibility_group->set_state (_get ());
1794 void add_to_page (OptionEditorPage* p)
1796 _heading.add_to_page (p);
1797 add_widget_to_page (p, _visibility_group->list_view ());
1800 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1805 /* The user has changed something, so reflect this change
1806 in the RCConfiguration.
1808 _set (_visibility_group->get_state_value ());
1811 OptionEditorHeading _heading;
1812 VisibilityGroup* _visibility_group;
1813 sigc::slot<std::string> _get;
1814 sigc::slot<bool, std::string> _set;
1815 PBD::ScopedConnection _visibility_group_connection;
1820 RCOptionEditor::RCOptionEditor ()
1821 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1822 , _rc_config (Config)
1823 , _mixer_strip_visibility ("mixer-element-visibility")
1827 uint32_t hwcpus = hardware_concurrency ();
1829 BoolComboOption* bco;
1832 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1834 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1836 _("Signal processing uses"),
1837 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1838 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1841 procs->add (-1, _("all but one processor"));
1842 procs->add (0, _("all available processors"));
1844 for (uint32_t i = 1; i <= hwcpus; ++i) {
1845 procs->add (i, string_compose (_("%1 processors"), i));
1848 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1850 add_option (_("Misc"), procs);
1853 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1855 add_option (_("Misc"), new UndoOptions (_rc_config));
1857 add_option (_("Misc"),
1859 "verify-remove-last-capture",
1860 _("Verify removal of last capture"),
1861 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1862 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1865 add_option (_("Misc"),
1867 "periodic-safety-backups",
1868 _("Make periodic backups of the session file"),
1869 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1870 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1873 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1875 add_option (_("Misc"),
1877 "only-copy-imported-files",
1878 _("Always copy imported files"),
1879 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
1880 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
1883 add_option (_("Misc"), new DirectoryOption (
1884 X_("default-session-parent-dir"),
1885 _("Default folder for new sessions:"),
1886 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1887 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1890 add_option (_("Misc"),
1891 new SpinOption<uint32_t> (
1892 "max-recent-sessions",
1893 _("Maximum number of recent sessions"),
1894 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1895 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1899 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1901 add_option (_("Misc"), new ClickOptions (_rc_config, this));
1903 add_option (_("Misc"),
1906 _("Click gain level"),
1907 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1908 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1911 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1913 add_option (_("Misc"),
1914 new SpinOption<double> (
1915 "automation-thinning-factor",
1916 _("Thinning factor (larger value => less data)"),
1917 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1918 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1922 add_option (_("Misc"),
1923 new SpinOption<double> (
1924 "automation-interval-msecs",
1925 _("Automation sampling interval (milliseconds)"),
1926 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1927 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1933 add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options")));
1937 tsf = new BoolOption (
1938 "latched-record-enable",
1939 _("Keep record-enable engaged on stop"),
1940 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1941 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1943 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1944 add_option (_("Transport"), tsf);
1946 tsf = new BoolOption (
1948 _("Play loop is a transport mode"),
1949 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1950 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1952 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1953 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1954 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1955 add_option (_("Transport"), tsf);
1957 tsf = new BoolOption (
1958 "stop-recording-on-xrun",
1959 _("Stop recording when an xrun occurs"),
1960 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1961 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1963 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1964 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
1966 add_option (_("Transport"), tsf);
1968 tsf = new BoolOption (
1969 "create-xrun-marker",
1970 _("Create markers where xruns occur"),
1971 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
1972 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
1974 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1975 add_option (_("Transport"), tsf);
1977 tsf = new BoolOption (
1978 "stop-at-session-end",
1979 _("Stop at the end of the session"),
1980 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
1981 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
1983 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1984 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
1985 "when it reaches the current session end marker\n\n"
1986 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
1988 add_option (_("Transport"), tsf);
1990 tsf = new BoolOption (
1992 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
1993 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
1994 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
1996 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1997 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
1998 "preventing any need to do a transport locate at the end of the loop\n\n"
1999 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
2000 "which will often cause a small click or delay"), PROGRAM_NAME));
2001 add_option (_("Transport"), tsf);
2003 tsf = new BoolOption (
2004 "disable-disarm-during-roll",
2005 _("Disable per-track record disarm while rolling"),
2006 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
2007 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
2009 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"));
2010 add_option (_("Transport"), tsf);
2012 tsf = new BoolOption (
2014 _("12dB gain reduction during fast-forward and fast-rewind"),
2015 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
2016 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
2018 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
2019 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
2020 add_option (_("Transport"), tsf);
2022 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
2024 _sync_source = new ComboOption<SyncSource> (
2026 _("External timecode source"),
2027 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
2028 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
2031 add_option (_("Transport"), _sync_source);
2033 _sync_framerate = new BoolOption (
2034 "timecode-sync-frame-rate",
2035 _("Match session video frame rate to external timecode"),
2036 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
2037 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
2039 Gtkmm2ext::UI::instance()->set_tip
2040 (_sync_framerate->tip_widget(),
2041 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
2042 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
2043 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
2044 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
2045 "timecode standard and the session standard."), PROGRAM_NAME));
2047 add_option (_("Transport"), _sync_framerate);
2049 _sync_genlock = new BoolOption (
2050 "timecode-source-is-synced",
2051 _("Sync-lock timecode to clock (disable drift compensation)"),
2052 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
2053 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
2055 Gtkmm2ext::UI::instance()->set_tip
2056 (_sync_genlock->tip_widget(),
2057 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
2058 "Sync Lock indicates that the selected external timecode source shares clock-sync "
2059 "(Black & Burst, Wordclock, etc) with the audio interface. "
2060 "This option disables drift compensation. The transport speed is fixed at 1.0. "
2061 "Vari-speed LTC will be ignored and cause drift."
2063 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
2064 "timecode sources shares clock sync."
2068 add_option (_("Transport"), _sync_genlock);
2070 _sync_source_2997 = new BoolOption (
2071 "timecode-source-2997",
2072 _("Lock to 29.9700 fps instead of 30000/1001"),
2073 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
2074 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
2076 Gtkmm2ext::UI::instance()->set_tip
2077 (_sync_source_2997->tip_widget(),
2078 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
2079 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
2080 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
2081 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
2082 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
2083 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
2086 add_option (_("Transport"), _sync_source_2997);
2088 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
2090 _ltc_port = new ComboStringOption (
2092 _("LTC incoming port"),
2093 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
2094 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
2097 vector<string> physical_inputs;
2098 physical_inputs.push_back (_("None"));
2099 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
2100 _ltc_port->set_popdown_strings (physical_inputs);
2102 populate_sync_options ();
2104 add_option (_("Transport"), _ltc_port);
2106 // TODO; rather disable this button than not compile it..
2107 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
2109 add_option (_("Transport"),
2112 _("Enable LTC generator"),
2113 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
2114 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
2117 _ltc_send_continuously = new BoolOption (
2118 "ltc-send-continuously",
2119 _("Send LTC while stopped"),
2120 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
2121 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
2123 Gtkmm2ext::UI::instance()->set_tip
2124 (_ltc_send_continuously->tip_widget(),
2125 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
2126 add_option (_("Transport"), _ltc_send_continuously);
2128 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
2129 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
2130 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
2131 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
2133 Gtkmm2ext::UI::instance()->set_tip
2134 (_ltc_volume_slider->tip_widget(),
2135 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
2137 add_option (_("Transport"), _ltc_volume_slider);
2138 parameter_changed ("send-ltc");
2140 parameter_changed ("sync-source");
2144 add_option (S_("Editor"),
2146 "draggable-playhead",
2147 _("Allow dragging of playhead"),
2148 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2149 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2152 add_option (_("Editor"),
2154 "automation-follows-regions",
2155 _("Move relevant automation when audio regions are moved"),
2156 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2157 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2160 add_option (_("Editor"),
2162 "show-track-meters",
2163 _("Show meters on tracks in the editor"),
2164 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
2165 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
2168 add_option (_("Editor"),
2170 "show-editor-meter",
2171 _("Display master-meter in the toolbar"),
2172 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
2173 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
2176 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2177 "default-fade-shape",
2178 _("Default fade shape"),
2179 sigc::mem_fun (*_rc_config,
2180 &RCConfiguration::get_default_fade_shape),
2181 sigc::mem_fun (*_rc_config,
2182 &RCConfiguration::set_default_fade_shape)
2185 fadeshape->add (FadeLinear,
2186 _("Linear (for highly correlated material)"));
2187 fadeshape->add (FadeConstantPower, _("Constant power"));
2188 fadeshape->add (FadeSymmetric, _("Symmetric"));
2189 fadeshape->add (FadeSlow, _("Slow"));
2190 fadeshape->add (FadeFast, _("Fast"));
2192 add_option (_("Editor"), fadeshape);
2195 bco = new BoolComboOption (
2196 "use-overlap-equivalency",
2197 _("Regions in active edit groups are edited together"),
2198 _("whenever they overlap in time"),
2199 _("only if they have identical length, position and origin"),
2200 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2201 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2204 add_option (_("Editor"), bco);
2206 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2208 _("Layering model"),
2209 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2210 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2213 lm->add (LaterHigher, _("later is higher"));
2214 lm->add (Manual, _("manual layering"));
2215 add_option (_("Editor"), lm);
2217 add_option (_("Editor"),
2219 "rubberbanding-snaps-to-grid",
2220 _("Make rubberband selection rectangle snap to the grid"),
2221 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2222 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2225 add_option (_("Editor"),
2228 _("Show waveforms in regions"),
2229 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
2230 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
2233 add_option (_("Editor"),
2234 new BoolComboOption (
2235 "show-region-gain-envelopes",
2236 _("Show gain envelopes in audio regions"),
2238 _("only in Draw and Internal Edit modes"),
2239 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2240 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2243 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
2245 _("Waveform scale"),
2246 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
2247 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
2250 wfs->add (Linear, _("linear"));
2251 wfs->add (Logarithmic, _("logarithmic"));
2253 add_option (_("Editor"), wfs);
2255 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
2257 _("Waveform shape"),
2258 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
2259 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
2262 wfsh->add (Traditional, _("traditional"));
2263 wfsh->add (Rectified, _("rectified"));
2265 add_option (_("Editor"), wfsh);
2267 add_option (_("Editor"), new ClipLevelOptions ());
2269 add_option (_("Editor"),
2271 "show-waveforms-while-recording",
2272 _("Show waveforms for audio while it is being recorded"),
2273 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
2274 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
2277 add_option (_("Editor"),
2280 _("Show zoom toolbar"),
2281 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_zoom_tools),
2282 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_zoom_tools)
2285 add_option (_("Editor"),
2287 "update-editor-during-summary-drag",
2288 _("Update editor window during drags of the summary"),
2289 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2290 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2293 bo = new BoolOption (
2295 _("Name new markers"),
2296 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2297 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2300 add_option (_("Editor"), bo);
2301 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."
2302 "\n\nYou can always rename markers by right-clicking on them"));
2304 add_option (_("Editor"),
2306 "autoscroll-editor",
2307 _("Auto-scroll editor window when dragging near its edges"),
2308 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2309 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2312 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2313 "region-selection-after-split",
2314 _("After splitting selected regions, select"),
2315 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2316 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2318 // TODO: decide which of these modes are really useful
2319 rsas->add(None, _("no regions"));
2320 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2321 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2322 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2323 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2324 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2325 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2326 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2328 add_option (_("Editor"), rsas);
2333 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2335 add_option (_("Audio"), new BufferingOptions (_rc_config));
2337 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2339 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2341 _("Record monitoring handled by"),
2342 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2343 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2346 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2347 mm->add (HardwareMonitoring, _("via Audio Driver"));
2350 string prog (PROGRAM_NAME);
2351 boost::algorithm::to_lower (prog);
2352 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2353 mm->add (ExternalMonitoring, _("audio hardware"));
2355 add_option (_("Audio"), mm);
2357 add_option (_("Audio"),
2359 "tape-machine-mode",
2360 _("Tape machine mode"),
2361 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2362 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2365 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
2367 add_option (_("Audio"),
2369 "auto-connect-standard-busses",
2370 _("Auto-connect master/monitor busses"),
2371 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2372 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2375 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2376 "input-auto-connect",
2377 _("Connect track inputs"),
2378 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2379 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2382 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2383 iac->add (ManualConnect, _("manually"));
2385 add_option (_("Audio"), iac);
2387 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2388 "output-auto-connect",
2389 _("Connect track and bus outputs"),
2390 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2391 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2394 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2395 oac->add (AutoConnectMaster, _("automatically to master bus"));
2396 oac->add (ManualConnect, _("manually"));
2398 add_option (_("Audio"), oac);
2400 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2402 add_option (_("Audio"),
2404 "denormal-protection",
2405 _("Use DC bias to protect against denormals"),
2406 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2407 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2410 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2412 _("Processor handling"),
2413 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2414 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2418 dm->add (DenormalNone, _("no processor handling"));
2420 FPU* fpu = FPU::instance();
2422 if (fpu->has_flush_to_zero()) {
2424 dm->add (DenormalFTZ, _("use FlushToZero"));
2425 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2426 _rc_config->set_denormal_model(DenormalNone);
2429 if (fpu->has_denormals_are_zero()) {
2431 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2432 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2433 _rc_config->set_denormal_model(DenormalNone);
2436 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2438 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2439 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2440 _rc_config->set_denormal_model(DenormalNone);
2444 dm->set_sensitive(false);
2447 add_option (_("Audio"), dm);
2449 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
2451 add_option (_("Audio"),
2453 "plugins-stop-with-transport",
2454 _("Silence plugins when the transport is stopped"),
2455 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
2456 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
2459 add_option (_("Audio"),
2461 "new-plugins-active",
2462 _("Make new plugins active"),
2463 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
2464 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
2467 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2469 add_option (_("Audio"),
2471 "auto-analyse-audio",
2472 _("Enable automatic analysis of audio"),
2473 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2474 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2477 add_option (_("Audio"),
2479 "replicate-missing-region-channels",
2480 _("Replicate missing region channels"),
2481 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2482 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2487 add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
2489 add_option (_("Solo / mute"),
2492 _("Solo-in-place mute cut (dB)"),
2493 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2494 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2497 _solo_control_is_listen_control = new BoolOption (
2498 "solo-control-is-listen-control",
2499 _("Solo controls are Listen controls"),
2500 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2501 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2504 add_option (_("Solo / mute"), _solo_control_is_listen_control);
2506 _listen_position = new ComboOption<ListenPosition> (
2508 _("Listen Position"),
2509 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2510 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2513 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2514 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2516 add_option (_("Solo / mute"), _listen_position);
2518 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2520 _("PFL signals come from"),
2521 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2522 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2525 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2526 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2528 add_option (_("Solo / mute"), pp);
2530 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2532 _("AFL signals come from"),
2533 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2534 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2537 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2538 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2540 add_option (_("Solo / mute"), pa);
2542 parameter_changed ("use-monitor-bus");
2544 add_option (_("Solo / mute"),
2547 _("Exclusive solo"),
2548 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2549 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2552 add_option (_("Solo / mute"),
2555 _("Show solo muting"),
2556 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2557 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2560 add_option (_("Solo / mute"),
2562 "solo-mute-override",
2563 _("Soloing overrides muting"),
2564 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2565 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2568 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
2570 add_option (_("Solo / mute"),
2572 "mute-affects-pre-fader",
2573 _("Mute affects pre-fader sends"),
2574 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2575 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2578 add_option (_("Solo / mute"),
2580 "mute-affects-post-fader",
2581 _("Mute affects post-fader sends"),
2582 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2583 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2586 add_option (_("Solo / mute"),
2588 "mute-affects-control-outs",
2589 _("Mute affects control outputs"),
2590 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2591 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2594 add_option (_("Solo / mute"),
2596 "mute-affects-main-outs",
2597 _("Mute affects main outputs"),
2598 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2599 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2602 add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
2604 add_option (_("Solo / mute"),
2606 "link-send-and-route-panner",
2607 _("Link panners of Aux and External Sends with main panner by default"),
2608 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2609 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2612 add_option (_("MIDI"),
2613 new SpinOption<float> (
2615 _("MIDI read-ahead time (seconds)"),
2616 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2617 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2622 add_option (_("MIDI"),
2625 _("Send MIDI Clock"),
2626 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2627 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2630 add_option (_("MIDI"),
2633 _("Send MIDI Time Code"),
2634 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2635 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2638 add_option (_("MIDI"),
2639 new SpinOption<int> (
2640 "mtc-qf-speed-tolerance",
2641 _("Percentage either side of normal transport speed to transmit MTC"),
2642 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2643 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2647 add_option (_("MIDI"),
2650 _("Obey MIDI Machine Control commands"),
2651 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2652 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2655 add_option (_("MIDI"),
2658 _("Send MIDI Machine Control commands"),
2659 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2660 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2663 add_option (_("MIDI"),
2666 _("Send MIDI control feedback"),
2667 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2668 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2671 add_option (_("MIDI"),
2672 new SpinOption<uint8_t> (
2673 "mmc-receive-device-id",
2674 _("Inbound MMC device ID"),
2675 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2676 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2680 add_option (_("MIDI"),
2681 new SpinOption<uint8_t> (
2682 "mmc-send-device-id",
2683 _("Outbound MMC device ID"),
2684 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2685 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2689 add_option (_("MIDI"),
2690 new SpinOption<int32_t> (
2691 "initial-program-change",
2692 _("Initial program change"),
2693 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2694 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2698 add_option (_("MIDI"),
2700 "display-first-midi-bank-as-zero",
2701 _("Display first MIDI bank/program as 0"),
2702 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2703 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2706 add_option (_("MIDI"),
2708 "never-display-periodic-midi",
2709 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2710 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
2711 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
2714 add_option (_("MIDI"),
2717 _("Sound MIDI notes as they are selected"),
2718 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2719 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2722 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2724 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2725 "midi-audition-synth-uri",
2726 _("Midi Audition Synth (LV2)"),
2727 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2728 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2731 audition_synth->add(X_(""), _("None"));
2732 PluginInfoList all_plugs;
2733 PluginManager& manager (PluginManager::instance());
2735 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2737 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2738 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2739 if (!(*i)->is_instrument()) continue;
2740 if ((*i)->type != ARDOUR::LV2) continue;
2741 audition_synth->add((*i)->unique_id, (*i)->name);
2745 add_option (_("MIDI"), audition_synth);
2747 /* USER INTERACTION */
2750 #ifdef PLATFORM_WINDOWS
2753 getenv ("ARDOUR_BUNDLED")
2757 add_option (_("User interaction"),
2759 "enable-translation",
2760 string_compose (_("Use translations of %1 messages\n"
2761 " <i>(requires a restart of %1 to take effect)</i>\n"
2762 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2763 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2764 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2767 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2769 add_option (_("User interaction"), new KeyboardOptions);
2771 /* Control Surfaces */
2773 add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
2775 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2777 _("Control surface remote ID"),
2778 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2779 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2782 rm->add (UserOrdered, _("assigned by user"));
2783 rm->add (MixerOrdered, _("follows order of mixer"));
2785 add_option (_("Control Surfaces"), rm);
2787 /* VIDEO Timeline */
2788 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2790 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2791 /* Plugin options (currrently VST only) */
2792 add_option (_("Plugins"), new PluginOptions (_rc_config));
2797 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
2798 BoolOption* bgc = new BoolOption (
2799 "cairo-image-surface",
2800 _("Disable Graphics Hardware Acceleration (requires restart)"),
2801 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
2802 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
2805 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
2806 _("Render large parts of the application user-interface in software, instead of using 2D-graphics acceleration.\nThis requires restarting %1 before having an effect"), PROGRAM_NAME));
2807 add_option (S_("Preferences|GUI"), bgc);
2810 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
2811 BoolOption* bgo = new BoolOption (
2813 _("Possibly improve slow graphical performance (requires restart)"),
2814 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
2815 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
2818 Gtkmm2ext::UI::instance()->set_tip (bgo->tip_widget(), string_compose (_("Disables hardware gradient rendering on buggy video drivers (\"buggy gradients patch\").\nThis requires restarting %1 before having an effect"), PROGRAM_NAME));
2819 add_option (S_("Preferences|GUI"), bgo);
2822 add_option (S_("Preferences|GUI"),
2825 _("Graphically indicate mouse pointer hovering over various widgets"),
2826 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
2827 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
2830 #ifdef TOOLTIPS_GOT_FIXED
2831 add_option (S_("Preferences|GUI"),
2834 _("Show tooltips if mouse hovers over a control"),
2835 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
2836 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
2840 add_option (S_("Preferences|GUI"),
2842 "show-name-highlight",
2843 _("Use name highlight bars in region displays (requires a restart)"),
2844 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
2845 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
2849 /* font scaling does nothing with GDK/Quartz */
2850 add_option (S_("Preferences|GUI"), new FontScalingOptions ());
2853 add_option (S_("GUI"),
2855 "super-rapid-clock-update",
2856 _("update transport clock display at FPS instead of every 100ms"),
2857 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
2858 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
2862 /* Image cache size */
2864 Gtk::Adjustment *ics = manage (new Gtk::Adjustment(0, 1, 1024, 10)); /* 1 MB to 1GB in steps of 10MB */
2865 HSliderOption *sics = new HSliderOption("waveform-cache-size",
2866 _("Waveform image cache size (megabytes)"),
2868 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
2869 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size)
2871 sics->scale().set_digits (0);
2872 Gtkmm2ext::UI::instance()->set_tip
2873 (sics->tip_widget(),
2874 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
2875 add_option (S_("Preferences|GUI"), sics);
2877 /* Lock GUI timeout */
2879 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
2880 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2881 _("Lock timeout (seconds)"),
2883 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
2884 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds)
2886 slts->scale().set_digits (0);
2887 Gtkmm2ext::UI::instance()->set_tip
2888 (slts->tip_widget(),
2889 _("Lock GUI after this many idle seconds (zero to never lock)"));
2890 add_option (S_("Preferences|GUI"), slts);
2892 /* The names of these controls must be the same as those given in MixerStrip
2893 for the actual widgets being controlled.
2895 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
2896 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2897 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
2898 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
2899 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
2900 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2903 S_("Preferences|GUI"),
2904 new VisibilityOption (
2906 &_mixer_strip_visibility,
2907 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
2908 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
2912 add_option (S_("Preferences|GUI"),
2914 "default-narrow_ms",
2915 _("Use narrow strips in the mixer by default"),
2916 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
2917 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
2920 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2922 ComboOption<float>* mht = new ComboOption<float> (
2924 _("Peak hold time"),
2925 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
2926 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
2929 mht->add (MeterHoldOff, _("off"));
2930 mht->add (MeterHoldShort, _("short"));
2931 mht->add (MeterHoldMedium, _("medium"));
2932 mht->add (MeterHoldLong, _("long"));
2934 add_option (S_("Preferences|Metering"), mht);
2936 ComboOption<float>* mfo = new ComboOption<float> (
2939 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2940 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2943 mfo->add (METER_FALLOFF_OFF, _("off"));
2944 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2945 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2946 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
2947 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2948 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
2949 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
2951 add_option (S_("Preferences|Metering"), mfo);
2953 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2954 "meter-line-up-level",
2955 _("Meter line-up level; 0dBu"),
2956 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
2957 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
2960 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2961 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2962 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2963 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2965 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."));
2967 add_option (S_("Preferences|Metering"), mlu);
2969 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2970 "meter-line-up-din",
2971 _("IEC1/DIN Meter line-up level; 0dBu"),
2972 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
2973 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
2976 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2977 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2978 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2979 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2981 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2983 add_option (S_("Preferences|Metering"), mld);
2985 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2986 "meter-vu-standard",
2987 _("VU Meter standard"),
2988 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
2989 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
2992 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2993 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2994 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2995 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2997 add_option (S_("Preferences|Metering"), mvu);
2999 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
3000 HSliderOption *mpks = new HSliderOption("meter-peak",
3001 _("Peak threshold [dBFS]"),
3003 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
3004 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak)
3008 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
3009 "meter-type-master",
3010 _("Default Meter Type for Master Bus"),
3011 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
3012 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3014 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3015 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3016 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3017 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3018 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3019 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3020 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3021 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3023 add_option (S_("Preferences|Metering"), mtm);
3026 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3028 _("Default Meter Type for Busses"),
3029 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3030 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3032 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3033 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3034 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3035 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3036 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3037 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3038 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3039 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3041 add_option (S_("Preferences|Metering"), mtb);
3043 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3045 _("Default Meter Type for Tracks"),
3046 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3047 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3049 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3050 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3052 add_option (S_("Preferences|Metering"), mtt);
3055 Gtkmm2ext::UI::instance()->set_tip
3056 (mpks->tip_widget(),
3057 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
3059 add_option (S_("Preferences|Metering"), mpks);
3061 add_option (S_("Preferences|Metering"),
3064 _("LED meter style"),
3065 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3066 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3069 /* and now the theme manager */
3071 ThemeManager* tm = manage (new ThemeManager);
3072 add_page (_("Theme"), *tm);
3076 RCOptionEditor::parameter_changed (string const & p)
3078 OptionEditor::parameter_changed (p);
3080 if (p == "use-monitor-bus") {
3081 bool const s = Config->get_use_monitor_bus ();
3083 /* we can't use this if we don't have a monitor bus */
3084 Config->set_solo_control_is_listen_control (false);
3086 _solo_control_is_listen_control->set_sensitive (s);
3087 _listen_position->set_sensitive (s);
3088 } else if (p == "sync-source") {
3089 _sync_source->set_sensitive (true);
3091 _sync_source->set_sensitive (!_session->config.get_external_sync());
3093 switch(Config->get_sync_source()) {
3096 _sync_genlock->set_sensitive (true);
3097 _sync_framerate->set_sensitive (true);
3098 _sync_source_2997->set_sensitive (true);
3101 _sync_genlock->set_sensitive (false);
3102 _sync_framerate->set_sensitive (false);
3103 _sync_source_2997->set_sensitive (false);
3106 } else if (p == "send-ltc") {
3107 bool const s = Config->get_send_ltc ();
3108 _ltc_send_continuously->set_sensitive (s);
3109 _ltc_volume_slider->set_sensitive (s);
3113 void RCOptionEditor::ltc_generator_volume_changed () {
3114 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
3118 RCOptionEditor::populate_sync_options ()
3120 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3122 _sync_source->clear ();
3124 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3125 _sync_source->add (*i, sync_source_to_string (*i));
3128 if (sync_opts.empty()) {
3129 _sync_source->set_sensitive(false);
3131 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3132 _rc_config->set_sync_source(sync_opts.front());