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 (3, 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 (_("Click audio file:")));
92 t->attach (*l, 0, 1, 1, 2, FILL);
93 t->attach (_click_path_entry, 1, 2, 1, 2, FILL);
94 _click_browse_button.signal_clicked ().connect (
95 sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
96 t->attach (_click_browse_button, 2, 3, 1, 2, FILL);
98 l = manage (left_aligned_label (_("Click emphasis audio file:")));
99 t->attach (*l, 0, 1, 2, 3, FILL);
100 t->attach (_click_emphasis_path_entry, 1, 2, 2, 3, FILL);
101 _click_emphasis_browse_button.signal_clicked ().connect (
102 sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
103 t->attach (_click_emphasis_browse_button, 2, 3, 2, 3, FILL);
105 _box->pack_start (*t, false, false);
107 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
108 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
110 if (_rc_config->get_click_sound ().empty() &&
111 _rc_config->get_click_emphasis_sound().empty()) {
112 _use_default_click_check_button.set_active (true);
115 _use_default_click_check_button.set_active (false);
119 void parameter_changed (string const & p)
121 if (p == "click-sound") {
122 _click_path_entry.set_text (_rc_config->get_click_sound());
123 } else if (p == "click-emphasis-sound") {
124 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
128 void set_state_from_config ()
130 parameter_changed ("click-sound");
131 parameter_changed ("click-emphasis-sound");
136 void click_browse_clicked ()
138 SoundFileChooser sfdb (_("Choose Click"));
143 if (sfdb.run () == RESPONSE_OK) {
144 click_chosen (sfdb.get_filename());
148 void click_chosen (string const & path)
150 _click_path_entry.set_text (path);
151 _rc_config->set_click_sound (path);
154 void click_changed ()
156 click_chosen (_click_path_entry.get_text ());
159 void click_emphasis_browse_clicked ()
161 SoundFileChooser sfdb (_("Choose Click Emphasis"));
166 if (sfdb.run () == RESPONSE_OK) {
167 click_emphasis_chosen (sfdb.get_filename());
171 void click_emphasis_chosen (string const & path)
173 _click_emphasis_path_entry.set_text (path);
174 _rc_config->set_click_emphasis_sound (path);
177 void click_emphasis_changed ()
179 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
182 void use_default_click_toggled ()
184 if (_use_default_click_check_button.get_active ()) {
185 _rc_config->set_click_sound ("");
186 _rc_config->set_click_emphasis_sound ("");
187 _click_path_entry.set_sensitive (false);
188 _click_emphasis_path_entry.set_sensitive (false);
189 _click_browse_button.set_sensitive (false);
190 _click_emphasis_browse_button.set_sensitive (false);
192 _click_path_entry.set_sensitive (true);
193 _click_emphasis_path_entry.set_sensitive (true);
194 _click_browse_button.set_sensitive (true);
195 _click_emphasis_browse_button.set_sensitive (true);
199 RCConfiguration* _rc_config;
200 CheckButton _use_default_click_check_button;
201 Entry _click_path_entry;
202 Entry _click_emphasis_path_entry;
203 Button _click_browse_button;
204 Button _click_emphasis_browse_button;
207 class UndoOptions : public OptionEditorBox
210 UndoOptions (RCConfiguration* c) :
212 _limit_undo_button (_("Limit undo history to")),
213 _save_undo_button (_("Save undo history of"))
215 Table* t = new Table (2, 3);
218 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
219 _limit_undo_spin.set_range (0, 512);
220 _limit_undo_spin.set_increments (1, 10);
221 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
222 Label* l = manage (left_aligned_label (_("commands")));
223 t->attach (*l, 2, 3, 0, 1);
225 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
226 _save_undo_spin.set_range (0, 512);
227 _save_undo_spin.set_increments (1, 10);
228 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
229 l = manage (left_aligned_label (_("commands")));
230 t->attach (*l, 2, 3, 1, 2);
232 _box->pack_start (*t);
234 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
235 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
236 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
237 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
240 void parameter_changed (string const & p)
242 if (p == "history-depth") {
243 int32_t const d = _rc_config->get_history_depth();
244 _limit_undo_button.set_active (d != 0);
245 _limit_undo_spin.set_sensitive (d != 0);
246 _limit_undo_spin.set_value (d);
247 } else if (p == "save-history") {
248 bool const x = _rc_config->get_save_history ();
249 _save_undo_button.set_active (x);
250 _save_undo_spin.set_sensitive (x);
251 } else if (p == "save-history-depth") {
252 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
256 void set_state_from_config ()
258 parameter_changed ("save-history");
259 parameter_changed ("history-depth");
260 parameter_changed ("save-history-depth");
263 void limit_undo_toggled ()
265 bool const x = _limit_undo_button.get_active ();
266 _limit_undo_spin.set_sensitive (x);
267 int32_t const n = x ? 16 : 0;
268 _limit_undo_spin.set_value (n);
269 _rc_config->set_history_depth (n);
272 void limit_undo_changed ()
274 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
277 void save_undo_toggled ()
279 bool const x = _save_undo_button.get_active ();
280 _rc_config->set_save_history (x);
283 void save_undo_changed ()
285 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
289 RCConfiguration* _rc_config;
290 CheckButton _limit_undo_button;
291 SpinButton _limit_undo_spin;
292 CheckButton _save_undo_button;
293 SpinButton _save_undo_spin;
298 static const struct {
310 { "Key|Shift", GDK_SHIFT_MASK },
311 { "Command", GDK_META_MASK },
312 { "Control", GDK_CONTROL_MASK },
313 { "Option", GDK_MOD1_MASK },
314 { "Command-Shift", GDK_META_MASK|GDK_SHIFT_MASK },
315 { "Command-Option", GDK_MOD1_MASK|GDK_META_MASK },
316 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
317 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
318 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_META_MASK },
321 { "Key|Shift", GDK_SHIFT_MASK },
322 { "Control", GDK_CONTROL_MASK },
323 { "Alt", GDK_MOD1_MASK },
324 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
325 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
326 { "Shift-Alt", GDK_SHIFT_MASK|GDK_MOD1_MASK },
327 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
328 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
329 { "Mod2", GDK_MOD2_MASK },
330 { "Mod3", GDK_MOD3_MASK },
331 { "Windows", GDK_MOD4_MASK },
332 { "Mod5", GDK_MOD5_MASK },
338 class KeyboardOptions : public OptionEditorBox
342 _delete_button_adjustment (3, 1, 12),
343 _delete_button_spin (_delete_button_adjustment),
344 _edit_button_adjustment (3, 1, 5),
345 _edit_button_spin (_edit_button_adjustment),
346 _insert_note_button_adjustment (3, 1, 5),
347 _insert_note_button_spin (_insert_note_button_adjustment)
349 /* internationalize and prepare for use with combos */
352 for (int i = 0; modifiers[i].name; ++i) {
353 dumb.push_back (S_(modifiers[i].name));
356 set_popdown_strings (_edit_modifier_combo, dumb);
357 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
359 for (int x = 0; modifiers[x].name; ++x) {
360 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
361 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
366 Table* t = manage (new Table (5, 11));
372 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
373 l->set_name ("OptionsLabel");
377 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
378 strs.push_back (bf->first);
381 set_popdown_strings (_keyboard_layout_selector, strs);
382 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
383 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
385 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
386 t->attach (_keyboard_layout_selector, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
391 l = manage (left_aligned_label (_("When Clicking:")));
392 l->set_name ("OptionEditorHeading");
393 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
398 l = manage (left_aligned_label (_("Edit using:")));
399 l->set_name ("OptionsLabel");
401 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
402 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
404 l = manage (new Label (_("+ button")));
405 l->set_name ("OptionsLabel");
407 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
408 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
410 _edit_button_spin.set_name ("OptionsEntry");
411 _edit_button_adjustment.set_value (Keyboard::edit_button());
412 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
417 set_popdown_strings (_delete_modifier_combo, dumb);
418 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
420 for (int x = 0; modifiers[x].name; ++x) {
421 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
422 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
427 l = manage (left_aligned_label (_("Delete using:")));
428 l->set_name ("OptionsLabel");
430 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
431 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
433 l = manage (new Label (_("+ button")));
434 l->set_name ("OptionsLabel");
436 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
437 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
439 _delete_button_spin.set_name ("OptionsEntry");
440 _delete_button_adjustment.set_value (Keyboard::delete_button());
441 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
446 set_popdown_strings (_insert_note_modifier_combo, dumb);
447 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
449 for (int x = 0; modifiers[x].name; ++x) {
450 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
451 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
456 l = manage (left_aligned_label (_("Insert note using:")));
457 l->set_name ("OptionsLabel");
459 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
460 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
462 l = manage (new Label (_("+ button")));
463 l->set_name ("OptionsLabel");
465 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
466 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
468 _insert_note_button_spin.set_name ("OptionsEntry");
469 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
470 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
474 l = manage (left_aligned_label (_("When Beginning a Drag:")));
475 l->set_name ("OptionEditorHeading");
476 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
482 set_popdown_strings (_copy_modifier_combo, dumb);
483 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
485 for (int x = 0; modifiers[x].name; ++x) {
486 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
487 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
492 l = manage (left_aligned_label (_("Copy items using:")));
493 l->set_name ("OptionsLabel");
495 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
496 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
501 /* constraint modifier */
502 set_popdown_strings (_constraint_modifier_combo, dumb);
503 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
505 for (int x = 0; modifiers[x].name; ++x) {
506 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
507 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
512 l = manage (left_aligned_label (_("Constrain drag using:")));
513 l->set_name ("OptionsLabel");
515 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
516 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
520 l = manage (left_aligned_label (_("When Beginning a Trim:")));
521 l->set_name ("OptionEditorHeading");
522 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
528 set_popdown_strings (_trim_contents_combo, dumb);
529 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
531 for (int x = 0; modifiers[x].name; ++x) {
532 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
533 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
538 l = manage (left_aligned_label (_("Trim contents using:")));
539 l->set_name ("OptionsLabel");
541 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
542 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
548 set_popdown_strings (_trim_anchored_combo, dumb);
549 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
551 for (int x = 0; modifiers[x].name; ++x) {
552 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
553 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
558 l = manage (left_aligned_label (_("Anchored trim using:")));
559 l->set_name ("OptionsLabel");
561 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
563 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
568 /* jump trim disabled for now
569 set_popdown_strings (_trim_jump_combo, dumb);
570 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
572 for (int x = 0; modifiers[x].name; ++x) {
573 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
574 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
579 l = manage (left_aligned_label (_("Jump after trim using:")));
580 l->set_name ("OptionsLabel");
582 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
584 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
590 /* note resize relative */
591 set_popdown_strings (_note_size_relative_combo, dumb);
592 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
594 for (int x = 0; modifiers[x].name; ++x) {
595 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
596 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
601 l = manage (left_aligned_label (_("Resize notes relatively using:")));
602 l->set_name ("OptionsLabel");
604 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
606 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
610 l = manage (left_aligned_label (_("While Dragging:")));
611 l->set_name ("OptionEditorHeading");
612 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
618 set_popdown_strings (_snap_modifier_combo, dumb);
619 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
621 for (int x = 0; modifiers[x].name; ++x) {
622 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
623 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
628 l = manage (left_aligned_label (_("Ignore snap using:")));
629 l->set_name ("OptionsLabel");
631 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
632 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
638 set_popdown_strings (_snap_delta_combo, dumb);
639 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
641 for (int x = 0; modifiers[x].name; ++x) {
642 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
643 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
648 l = manage (left_aligned_label (_("Snap relatively using:")));
649 l->set_name ("OptionsLabel");
651 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
652 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
656 l = manage (left_aligned_label (_("While Trimming:")));
657 l->set_name ("OptionEditorHeading");
658 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
664 set_popdown_strings (_trim_overlap_combo, dumb);
665 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
667 for (int x = 0; modifiers[x].name; ++x) {
668 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
669 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
674 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
675 l->set_name ("OptionsLabel");
677 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
678 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
682 l = manage (left_aligned_label (_("While Dragging Control Points:")));
683 l->set_name ("OptionEditorHeading");
684 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
690 set_popdown_strings (_fine_adjust_combo, dumb);
691 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
693 for (int x = 0; modifiers[x].name; ++x) {
694 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
695 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
700 l = manage (left_aligned_label (_("Fine adjust using:")));
701 l->set_name ("OptionsLabel");
703 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
704 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
710 set_popdown_strings (_push_points_combo, dumb);
711 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
713 for (int x = 0; modifiers[x].name; ++x) {
714 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
715 _push_points_combo.set_active_text (S_(modifiers[x].name));
720 l = manage (left_aligned_label (_("Push points using:")));
721 l->set_name ("OptionsLabel");
723 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
724 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
726 _box->pack_start (*t, false, false);
729 void parameter_changed (string const &)
731 /* XXX: these aren't really config options... */
734 void set_state_from_config ()
736 /* XXX: these aren't really config options... */
741 void bindings_changed ()
743 string const txt = _keyboard_layout_selector.get_active_text();
745 /* XXX: config...? for all this keyboard stuff */
747 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
748 if (txt == i->first) {
749 if (Keyboard::load_keybindings (i->second)) {
750 Keyboard::save_keybindings ();
756 void edit_modifier_chosen ()
758 string const txt = _edit_modifier_combo.get_active_text();
760 for (int i = 0; modifiers[i].name; ++i) {
761 if (txt == _(modifiers[i].name)) {
762 Keyboard::set_edit_modifier (modifiers[i].modifier);
768 void delete_modifier_chosen ()
770 string const txt = _delete_modifier_combo.get_active_text();
772 for (int i = 0; modifiers[i].name; ++i) {
773 if (txt == _(modifiers[i].name)) {
774 Keyboard::set_delete_modifier (modifiers[i].modifier);
780 void copy_modifier_chosen ()
782 string const txt = _copy_modifier_combo.get_active_text();
784 for (int i = 0; modifiers[i].name; ++i) {
785 if (txt == _(modifiers[i].name)) {
786 Keyboard::set_copy_modifier (modifiers[i].modifier);
792 void insert_note_modifier_chosen ()
794 string const txt = _insert_note_modifier_combo.get_active_text();
796 for (int i = 0; modifiers[i].name; ++i) {
797 if (txt == _(modifiers[i].name)) {
798 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
804 void snap_modifier_chosen ()
806 string const txt = _snap_modifier_combo.get_active_text();
808 for (int i = 0; modifiers[i].name; ++i) {
809 if (txt == _(modifiers[i].name)) {
810 Keyboard::set_snap_modifier (modifiers[i].modifier);
816 void snap_delta_modifier_chosen ()
818 string const txt = _snap_delta_combo.get_active_text();
820 for (int i = 0; modifiers[i].name; ++i) {
821 if (txt == _(modifiers[i].name)) {
822 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
828 void constraint_modifier_chosen ()
830 string const txt = _constraint_modifier_combo.get_active_text();
832 for (int i = 0; modifiers[i].name; ++i) {
833 if (txt == _(modifiers[i].name)) {
834 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
840 void trim_contents_modifier_chosen ()
842 string const txt = _trim_contents_combo.get_active_text();
844 for (int i = 0; modifiers[i].name; ++i) {
845 if (txt == _(modifiers[i].name)) {
846 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
852 void trim_overlap_modifier_chosen ()
854 string const txt = _trim_overlap_combo.get_active_text();
856 for (int i = 0; modifiers[i].name; ++i) {
857 if (txt == _(modifiers[i].name)) {
858 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
864 void trim_anchored_modifier_chosen ()
866 string const txt = _trim_anchored_combo.get_active_text();
868 for (int i = 0; modifiers[i].name; ++i) {
869 if (txt == _(modifiers[i].name)) {
870 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
876 void fine_adjust_modifier_chosen ()
878 string const txt = _fine_adjust_combo.get_active_text();
880 for (int i = 0; modifiers[i].name; ++i) {
881 if (txt == _(modifiers[i].name)) {
882 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
888 void push_points_modifier_chosen ()
890 string const txt = _push_points_combo.get_active_text();
892 for (int i = 0; modifiers[i].name; ++i) {
893 if (txt == _(modifiers[i].name)) {
894 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
900 void note_size_relative_modifier_chosen ()
902 string const txt = _note_size_relative_combo.get_active_text();
904 for (int i = 0; modifiers[i].name; ++i) {
905 if (txt == _(modifiers[i].name)) {
906 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
912 void delete_button_changed ()
914 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
917 void edit_button_changed ()
919 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
922 void insert_note_button_changed ()
924 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
927 ComboBoxText _keyboard_layout_selector;
928 ComboBoxText _edit_modifier_combo;
929 ComboBoxText _delete_modifier_combo;
930 ComboBoxText _copy_modifier_combo;
931 ComboBoxText _insert_note_modifier_combo;
932 ComboBoxText _snap_modifier_combo;
933 ComboBoxText _snap_delta_combo;
934 ComboBoxText _constraint_modifier_combo;
935 ComboBoxText _trim_contents_combo;
936 ComboBoxText _trim_overlap_combo;
937 ComboBoxText _trim_anchored_combo;
938 ComboBoxText _trim_jump_combo;
939 ComboBoxText _fine_adjust_combo;
940 ComboBoxText _push_points_combo;
941 ComboBoxText _note_size_relative_combo;
942 Adjustment _delete_button_adjustment;
943 SpinButton _delete_button_spin;
944 Adjustment _edit_button_adjustment;
945 SpinButton _edit_button_spin;
946 Adjustment _insert_note_button_adjustment;
947 SpinButton _insert_note_button_spin;
951 class FontScalingOptions : public OptionEditorBox
954 FontScalingOptions () :
955 _dpi_adjustment (100, 50, 250, 1, 5),
956 _dpi_slider (_dpi_adjustment)
958 _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.);
960 Label* l = manage (new Label (_("GUI and Font scaling:")));
961 l->set_name ("OptionsLabel");
963 const Glib::ustring dflt = _("Default");
964 const Glib::ustring empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
966 _dpi_slider.set_name("FontScaleSlider");
967 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
968 _dpi_slider.set_draw_value(false);
969 _dpi_slider.add_mark(50, Gtk::POS_TOP, empty);
970 _dpi_slider.add_mark(60, Gtk::POS_TOP, empty);
971 _dpi_slider.add_mark(70, Gtk::POS_TOP, empty);
972 _dpi_slider.add_mark(80, Gtk::POS_TOP, empty);
973 _dpi_slider.add_mark(90, Gtk::POS_TOP, empty);
974 _dpi_slider.add_mark(100, Gtk::POS_TOP, dflt);
975 _dpi_slider.add_mark(125, Gtk::POS_TOP, empty);
976 _dpi_slider.add_mark(150, Gtk::POS_TOP, empty);
977 _dpi_slider.add_mark(175, Gtk::POS_TOP, empty);
978 _dpi_slider.add_mark(200, Gtk::POS_TOP, empty);
979 _dpi_slider.add_mark(225, Gtk::POS_TOP, empty);
980 _dpi_slider.add_mark(250, Gtk::POS_TOP, empty);
982 HBox* h = manage (new HBox);
984 h->pack_start (*l, false, false);
985 h->pack_start (_dpi_slider, true, true);
987 _box->pack_start (*h, false, false);
989 set_note (_("Adjusting the scale require an application restart to re-layout."));
991 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
994 void parameter_changed (string const & p)
996 if (p == "font-scale") {
997 _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.);
1001 void set_state_from_config ()
1003 parameter_changed ("font-scale");
1010 UIConfiguration::instance().set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024.));
1011 /* XXX: should be triggered from the parameter changed signal */
1012 UIConfiguration::instance().reset_dpi ();
1015 Adjustment _dpi_adjustment;
1019 class ClipLevelOptions : public OptionEditorBox
1023 : _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1024 , _clip_level_slider (_clip_level_adjustment)
1026 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level ());
1028 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
1029 l->set_name ("OptionsLabel");
1031 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1032 HBox* h = manage (new HBox);
1034 h->pack_start (*l, false, false);
1035 h->pack_start (_clip_level_slider, true, true);
1037 _box->pack_start (*h, false, false);
1039 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1042 void parameter_changed (string const & p)
1044 if (p == "waveform-clip-level") {
1045 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level());
1049 void set_state_from_config ()
1051 parameter_changed ("waveform-clip-level");
1056 void clip_level_changed ()
1058 UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value());
1059 /* XXX: should be triggered from the parameter changed signal */
1060 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1063 Adjustment _clip_level_adjustment;
1064 HScale _clip_level_slider;
1067 class BufferingOptions : public OptionEditorBox
1070 BufferingOptions (RCConfiguration* c)
1072 , _playback_adjustment (5, 1, 60, 1, 4)
1073 , _capture_adjustment (5, 1, 60, 1, 4)
1074 , _playback_slider (_playback_adjustment)
1075 , _capture_slider (_capture_adjustment)
1077 vector<string> presets;
1079 /* these must match the order of the enums for BufferingPreset */
1081 presets.push_back (_("Small sessions (4-16 tracks)"));
1082 presets.push_back (_("Medium sessions (16-64 tracks)"));
1083 presets.push_back (_("Large sessions (64+ tracks)"));
1084 presets.push_back (_("Custom (set by sliders below)"));
1086 set_popdown_strings (_buffering_presets_combo, presets);
1088 Label* l = manage (new Label (_("Preset:")));
1089 l->set_name ("OptionsLabel");
1090 HBox* h = manage (new HBox);
1091 h->set_spacing (12);
1092 h->pack_start (*l, false, false);
1093 h->pack_start (_buffering_presets_combo, true, true);
1094 _box->pack_start (*h, false, false);
1096 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1098 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1100 l = manage (new Label (_("Playback (seconds of buffering):")));
1101 l->set_name ("OptionsLabel");
1103 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1104 h = manage (new HBox);
1106 h->pack_start (*l, false, false);
1107 h->pack_start (_playback_slider, true, true);
1109 _box->pack_start (*h, false, false);
1111 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1113 l = manage (new Label (_("Recording (seconds of buffering):")));
1114 l->set_name ("OptionsLabel");
1116 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1117 h = manage (new HBox);
1119 h->pack_start (*l, false, false);
1120 h->pack_start (_capture_slider, true, true);
1122 _box->pack_start (*h, false, false);
1124 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
1125 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
1128 void parameter_changed (string const & p)
1130 if (p == "buffering-preset") {
1131 switch (_rc_config->get_buffering_preset()) {
1133 _playback_slider.set_sensitive (false);
1134 _capture_slider.set_sensitive (false);
1135 _buffering_presets_combo.set_active (0);
1138 _playback_slider.set_sensitive (false);
1139 _capture_slider.set_sensitive (false);
1140 _buffering_presets_combo.set_active (1);
1143 _playback_slider.set_sensitive (false);
1144 _capture_slider.set_sensitive (false);
1145 _buffering_presets_combo.set_active (2);
1148 _playback_slider.set_sensitive (true);
1149 _capture_slider.set_sensitive (true);
1150 _buffering_presets_combo.set_active (3);
1155 if (p == "playback-buffer-seconds") {
1156 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1157 } else if (p == "capture-buffer-seconds") {
1158 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1162 void set_state_from_config ()
1164 parameter_changed ("buffering-preset");
1165 parameter_changed ("playback-buffer-seconds");
1166 parameter_changed ("capture-buffer-seconds");
1171 void preset_changed ()
1173 int index = _buffering_presets_combo.get_active_row_number ();
1179 _rc_config->set_buffering_preset (Small);
1182 _rc_config->set_buffering_preset (Medium);
1185 _rc_config->set_buffering_preset (Large);
1188 _rc_config->set_buffering_preset (Custom);
1191 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1196 void playback_changed ()
1198 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
1201 void capture_changed ()
1203 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
1206 RCConfiguration* _rc_config;
1207 Adjustment _playback_adjustment;
1208 Adjustment _capture_adjustment;
1209 HScale _playback_slider;
1210 HScale _capture_slider;
1211 ComboBoxText _buffering_presets_combo;
1214 class ControlSurfacesOptions : public OptionEditorBox
1217 ControlSurfacesOptions (Gtk::Window& parent)
1219 , _ignore_view_change (0)
1221 _store = ListStore::create (_model);
1222 _view.set_model (_store);
1223 _view.append_column (_("Control Surface Protocol"), _model.name);
1224 _view.get_column(0)->set_resizable (true);
1225 _view.get_column(0)->set_expand (true);
1226 _view.append_column_editable (_("Enabled"), _model.enabled);
1227 _view.append_column_editable (_("Feedback"), _model.feedback);
1229 _box->pack_start (_view, false, false);
1231 Label* label = manage (new Label);
1232 label->set_markup (string_compose (X_("<i>%1</i>"), _("Double-click on a name to edit settings for an enabled protocol")));
1234 _box->pack_start (*label, false, false);
1237 ControlProtocolManager& m = ControlProtocolManager::instance ();
1238 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1239 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1241 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1242 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1245 void parameter_changed (std::string const &)
1250 void set_state_from_config ()
1254 ControlProtocolManager& m = ControlProtocolManager::instance ();
1255 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1257 if (!(*i)->mandatory) {
1258 TreeModel::Row r = *_store->append ();
1259 r[_model.name] = (*i)->name;
1260 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1261 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
1262 r[_model.protocol_info] = *i;
1269 void protocol_status_changed (ControlProtocolInfo* cpi) {
1271 TreeModel::Children rows = _store->children();
1273 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1274 string n = ((*x)[_model.name]);
1276 if ((*x)[_model.protocol_info] == cpi) {
1277 _ignore_view_change++;
1278 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1279 _ignore_view_change--;
1285 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1287 TreeModel::Row r = *i;
1289 if (_ignore_view_change) {
1293 ControlProtocolInfo* cpi = r[_model.protocol_info];
1298 bool const was_enabled = (cpi->protocol != 0);
1299 bool const is_enabled = r[_model.enabled];
1302 if (was_enabled != is_enabled) {
1305 ControlProtocolManager::instance().activate (*cpi);
1307 ControlProtocolManager::instance().deactivate (*cpi);
1311 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
1312 bool const is_feedback = r[_model.feedback];
1314 if (was_feedback != is_feedback && cpi->protocol) {
1315 cpi->protocol->set_feedback (is_feedback);
1319 void edit_clicked (GdkEventButton* ev)
1321 if (ev->type != GDK_2BUTTON_PRESS) {
1326 ControlProtocolInfo* cpi;
1329 row = *(_view.get_selection()->get_selected());
1330 if (!row[_model.enabled]) {
1333 cpi = row[_model.protocol_info];
1334 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1337 Box* box = (Box*) cpi->protocol->get_gui ();
1341 if (box->get_parent()) {
1342 static_cast<ArdourWindow*>(box->get_parent())->present();
1345 string title = row[_model.name];
1346 /* once created, the window is managed by the surface itself (as ->get_parent())
1347 * Surface's tear_down_gui() is called on session close, when de-activating
1348 * or re-initializing a surface.
1349 * tear_down_gui() hides an deletes the Window if it exists.
1351 ArdourWindow* win = new ArdourWindow (_parent, title);
1352 win->set_title ("Control Protocol Options");
1358 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1362 ControlSurfacesModelColumns ()
1367 add (protocol_info);
1370 TreeModelColumn<string> name;
1371 TreeModelColumn<bool> enabled;
1372 TreeModelColumn<bool> feedback;
1373 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1376 Glib::RefPtr<ListStore> _store;
1377 ControlSurfacesModelColumns _model;
1379 Gtk::Window& _parent;
1380 PBD::ScopedConnection protocol_status_connection;
1381 uint32_t _ignore_view_change;
1384 class VideoTimelineOptions : public OptionEditorBox
1387 VideoTimelineOptions (RCConfiguration* c)
1389 , _show_video_export_info_button (_("Show Video Export Info before export"))
1390 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1391 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1393 Table* t = manage (new Table (2, 6));
1394 t->set_spacings (4);
1396 t->attach (_video_advanced_setup_button, 0, 2, 0, 1);
1397 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1398 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1399 _("<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."));
1401 Label* l = manage (new Label (_("Video Server URL:")));
1402 l->set_alignment (0, 0.5);
1403 t->attach (*l, 0, 1, 1, 2, FILL);
1404 t->attach (_video_server_url_entry, 1, 2, 1, 2, FILL);
1405 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1406 _("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"));
1408 l = manage (new Label (_("Video Folder:")));
1409 l->set_alignment (0, 0.5);
1410 t->attach (*l, 0, 1, 2, 3, FILL);
1411 t->attach (_video_server_docroot_entry, 1, 2, 2, 3);
1412 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1413 _("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."));
1415 /* small vspace y=3..4 */
1417 t->attach (_show_video_export_info_button, 0, 2, 4, 5);
1418 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1419 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1420 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1422 t->attach (_show_video_server_dialog_button, 0, 2, 5, 6);
1423 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1424 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1425 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1427 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1428 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1429 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1430 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1432 _box->pack_start (*t,true,true);
1435 void server_url_changed ()
1437 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1440 void server_docroot_changed ()
1442 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1445 void show_video_export_info_toggled ()
1447 bool const x = _show_video_export_info_button.get_active ();
1448 _rc_config->set_show_video_export_info (x);
1451 void show_video_server_dialog_toggled ()
1453 bool const x = _show_video_server_dialog_button.get_active ();
1454 _rc_config->set_show_video_server_dialog (x);
1457 void video_advanced_setup_toggled ()
1459 bool const x = _video_advanced_setup_button.get_active ();
1460 _rc_config->set_video_advanced_setup(x);
1463 void parameter_changed (string const & p)
1465 if (p == "video-server-url") {
1466 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1467 } else if (p == "video-server-docroot") {
1468 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1469 } else if (p == "show-video-export-info") {
1470 bool const x = _rc_config->get_show_video_export_info();
1471 _show_video_export_info_button.set_active (x);
1472 } else if (p == "show-video-server-dialog") {
1473 bool const x = _rc_config->get_show_video_server_dialog();
1474 _show_video_server_dialog_button.set_active (x);
1475 } else if (p == "video-advanced-setup") {
1476 bool const x = _rc_config->get_video_advanced_setup();
1477 _video_advanced_setup_button.set_active(x);
1478 _video_server_docroot_entry.set_sensitive(x);
1479 _video_server_url_entry.set_sensitive(x);
1483 void set_state_from_config ()
1485 parameter_changed ("video-server-url");
1486 parameter_changed ("video-server-docroot");
1487 parameter_changed ("video-monitor-setup-dialog");
1488 parameter_changed ("show-video-export-info");
1489 parameter_changed ("show-video-server-dialog");
1490 parameter_changed ("video-advanced-setup");
1494 RCConfiguration* _rc_config;
1495 Entry _video_server_url_entry;
1496 Entry _video_server_docroot_entry;
1497 CheckButton _show_video_export_info_button;
1498 CheckButton _show_video_server_dialog_button;
1499 CheckButton _video_advanced_setup_button;
1502 class PluginOptions : public OptionEditorBox
1505 PluginOptions (RCConfiguration* c)
1507 , _display_plugin_scan_progress (_("Always Display Plugin Scan Progress"))
1508 , _discover_vst_on_start (_("Scan for [new] VST Plugins on Application Start"))
1509 , _discover_au_on_start (_("Scan for AudioUnit Plugins on Application Start"))
1510 , _verbose_plugin_scan (_("Verbose Plugin Scan"))
1511 , _timeout_adjustment (0, 0, 3000, 50, 50)
1512 , _timeout_slider (_timeout_adjustment)
1515 std::stringstream ss;
1516 Table* t = manage (new Table (2, 6));
1517 t->set_spacings (4);
1521 ss << "<b>" << _("General") << "</b>";
1522 l = manage (left_aligned_label (ss.str()));
1523 l->set_use_markup (true);
1524 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1525 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1527 b = manage (new Button (_("Scan for Plugins")));
1528 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::refresh_clicked));
1529 t->attach (*b, 0, 2, n, n+1, FILL); ++n;
1531 t->attach (_display_plugin_scan_progress, 0, 2, n, n+1); ++n;
1532 _display_plugin_scan_progress.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::display_plugin_scan_progress_toggled));
1533 Gtkmm2ext::UI::instance()->set_tip (_display_plugin_scan_progress,
1534 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
1536 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
1537 _timeout_slider.set_digits (0);
1538 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &PluginOptions::timeout_changed));
1540 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1541 _("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."));
1543 l = manage (left_aligned_label (_("Scan Time Out [deciseconds]")));;
1544 HBox* h = manage (new HBox);
1546 h->pack_start (*l, false, false);
1547 h->pack_start (_timeout_slider, true, true);
1548 t->attach (*h, 0, 2, n, n+1); ++n;
1551 ss << "<b>" << _("VST") << "</b>";
1552 l = manage (left_aligned_label (ss.str()));
1553 l->set_use_markup (true);
1554 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1555 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1557 b = manage (new Button (_("Clear VST Cache")));
1558 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_cache_clicked));
1559 t->attach (*b, 0, 1, n, n+1, FILL);
1561 b = manage (new Button (_("Clear VST Blacklist")));
1562 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_vst_blacklist_clicked));
1563 t->attach (*b, 1, 2, n, n+1, FILL);
1566 t->attach (_discover_vst_on_start, 0, 2, n, n+1); ++n;
1567 _discover_vst_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_vst_on_start_toggled));
1568 Gtkmm2ext::UI::instance()->set_tip (_discover_vst_on_start,
1569 _("<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"));
1571 #ifdef LXVST_SUPPORT
1572 t->attach (*manage (right_aligned_label (_("Linux VST Path:"))), 0, 1, n, n+1);
1573 b = manage (new Button (_("Edit")));
1574 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_lxvst_path_clicked));
1575 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1578 #ifdef WINDOWS_VST_SUPPORT
1579 t->attach (*manage (right_aligned_label (_("Windows VST Path:"))), 0, 1, n, n+1);
1580 b = manage (new Button (_("Edit")));
1581 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::edit_vst_path_clicked));
1582 t->attach (*b, 1, 2, n, n+1, FILL); ++n;
1584 // currently verbose logging is only implemented for Windows VST.
1585 t->attach (_verbose_plugin_scan, 0, 2, n, n+1); ++n;
1586 _verbose_plugin_scan.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::verbose_plugin_scan_toggled));
1587 Gtkmm2ext::UI::instance()->set_tip (_verbose_plugin_scan,
1588 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
1592 #ifdef AUDIOUNIT_SUPPORT
1594 ss << "<b>" << _("Audio Unit") << "</b>";
1595 l = manage (left_aligned_label (ss.str()));
1596 l->set_use_markup (true);
1597 t->attach (*manage (new Label ("")), 0, 3, n, n+1, FILL | EXPAND); ++n;
1598 t->attach (*l, 0, 2, n, n+1, FILL | EXPAND); ++n;
1600 t->attach (_discover_au_on_start, 0, 2, n, n+1); ++n;
1601 _discover_au_on_start.signal_toggled().connect (sigc::mem_fun (*this, &PluginOptions::discover_au_on_start_toggled));
1602 Gtkmm2ext::UI::instance()->set_tip (_discover_au_on_start,
1603 _("<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."));
1606 b = manage (new Button (_("Clear AU Cache")));
1607 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_cache_clicked));
1608 t->attach (*b, 0, 1, n, n+1, FILL);
1610 b = manage (new Button (_("Clear AU Blacklist")));
1611 b->signal_clicked().connect (sigc::mem_fun (*this, &PluginOptions::clear_au_blacklist_clicked));
1612 t->attach (*b, 1, 2, n, n+1, FILL);
1616 _box->pack_start (*t,true,true);
1619 void parameter_changed (string const & p) {
1620 if (p == "show-plugin-scan-window") {
1621 bool const x = UIConfiguration::instance().get_show_plugin_scan_window();
1622 _display_plugin_scan_progress.set_active (x);
1624 else if (p == "discover-vst-on-start") {
1625 bool const x = _rc_config->get_discover_vst_on_start();
1626 _discover_vst_on_start.set_active (x);
1628 else if (p == "vst-scan-timeout") {
1629 int const x = _rc_config->get_vst_scan_timeout();
1630 _timeout_adjustment.set_value (x);
1632 else if (p == "discover-audio-units") {
1633 bool const x = _rc_config->get_discover_audio_units();
1634 _discover_au_on_start.set_active (x);
1636 else if (p == "verbose-plugin-scan") {
1637 bool const x = _rc_config->get_verbose_plugin_scan();
1638 _verbose_plugin_scan.set_active (x);
1642 void set_state_from_config () {
1643 parameter_changed ("show-plugin-scan-window");
1644 parameter_changed ("discover-vst-on-start");
1645 parameter_changed ("vst-scan-timeout");
1646 parameter_changed ("discover-audio-units");
1647 parameter_changed ("verbose-plugin-scan");
1651 RCConfiguration* _rc_config;
1652 CheckButton _display_plugin_scan_progress;
1653 CheckButton _discover_vst_on_start;
1654 CheckButton _discover_au_on_start;
1655 CheckButton _verbose_plugin_scan;
1656 Adjustment _timeout_adjustment;
1657 HScale _timeout_slider;
1659 void display_plugin_scan_progress_toggled () {
1660 bool const x = _display_plugin_scan_progress.get_active();
1661 UIConfiguration::instance().set_show_plugin_scan_window(x);
1664 void discover_vst_on_start_toggled () {
1665 bool const x = _discover_vst_on_start.get_active();
1666 _rc_config->set_discover_vst_on_start(x);
1669 void discover_au_on_start_toggled () {
1670 bool const x = _discover_au_on_start.get_active();
1671 _rc_config->set_discover_audio_units(x);
1674 void verbose_plugin_scan_toggled () {
1675 bool const x = _verbose_plugin_scan.get_active();
1676 _rc_config->set_verbose_plugin_scan(x);
1679 void timeout_changed () {
1680 int x = floor(_timeout_adjustment.get_value());
1681 _rc_config->set_vst_scan_timeout(x);
1684 void clear_vst_cache_clicked () {
1685 PluginManager::instance().clear_vst_cache();
1688 void clear_vst_blacklist_clicked () {
1689 PluginManager::instance().clear_vst_blacklist();
1692 void clear_au_cache_clicked () {
1693 PluginManager::instance().clear_au_cache();
1696 void clear_au_blacklist_clicked () {
1697 PluginManager::instance().clear_au_blacklist();
1701 void edit_vst_path_clicked () {
1702 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1703 _("Set Windows VST Search Path"),
1704 _rc_config->get_plugin_path_vst(),
1705 PluginManager::instance().get_default_windows_vst_path()
1707 ResponseType r = (ResponseType) pd->run ();
1709 if (r == RESPONSE_ACCEPT) {
1710 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
1715 // todo consolidate with edit_vst_path_clicked..
1716 void edit_lxvst_path_clicked () {
1717 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
1718 _("Set Linux VST Search Path"),
1719 _rc_config->get_plugin_path_lxvst(),
1720 PluginManager::instance().get_default_lxvst_path()
1722 ResponseType r = (ResponseType) pd->run ();
1724 if (r == RESPONSE_ACCEPT) {
1725 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
1730 void refresh_clicked () {
1731 PluginManager::instance().refresh();
1736 /** A class which allows control of visibility of some editor components usign
1737 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1738 * which has the correct members, but with null widget pointers. This
1739 * class allows the user to set visibility of the members, the details
1740 * of which are stored in a configuration variable which can be watched
1741 * by parts of the editor that actually contain the widgets whose visibility
1742 * is being controlled.
1745 class VisibilityOption : public Option
1748 /** @param name User-visible name for this group.
1749 * @param g `Dummy' VisibilityGroup (as described above).
1750 * @param get Method to get the value of the appropriate configuration variable.
1751 * @param set Method to set the value of the appropriate configuration variable.
1753 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1754 : Option (g->get_state_name(), name)
1756 , _visibility_group (g)
1760 /* Watch for changes made by the user to our members */
1761 _visibility_group->VisibilityChanged.connect_same_thread (
1762 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1766 void set_state_from_config ()
1768 /* Set our state from the current configuration */
1769 _visibility_group->set_state (_get ());
1772 void add_to_page (OptionEditorPage* p)
1774 _heading.add_to_page (p);
1775 add_widget_to_page (p, _visibility_group->list_view ());
1778 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1783 /* The user has changed something, so reflect this change
1784 in the RCConfiguration.
1786 _set (_visibility_group->get_state_value ());
1789 OptionEditorHeading _heading;
1790 VisibilityGroup* _visibility_group;
1791 sigc::slot<std::string> _get;
1792 sigc::slot<bool, std::string> _set;
1793 PBD::ScopedConnection _visibility_group_connection;
1798 RCOptionEditor::RCOptionEditor ()
1799 : OptionEditor (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1800 , _rc_config (Config)
1801 , _mixer_strip_visibility ("mixer-element-visibility")
1805 uint32_t hwcpus = hardware_concurrency ();
1807 BoolComboOption* bco;
1810 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1812 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1814 _("Signal processing uses"),
1815 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1816 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1819 procs->add (-1, _("all but one processor"));
1820 procs->add (0, _("all available processors"));
1822 for (uint32_t i = 1; i <= hwcpus; ++i) {
1823 procs->add (i, string_compose (_("%1 processors"), i));
1826 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1828 add_option (_("Misc"), procs);
1831 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1833 add_option (_("Misc"), new UndoOptions (_rc_config));
1835 add_option (_("Misc"),
1837 "verify-remove-last-capture",
1838 _("Verify removal of last capture"),
1839 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1840 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1843 add_option (_("Misc"),
1845 "periodic-safety-backups",
1846 _("Automatically save the session file at regular intervals"),
1847 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1848 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1851 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1853 add_option (_("Misc"),
1855 "only-copy-imported-files",
1856 _("Always copy imported files"),
1857 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
1858 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
1861 add_option (_("Misc"), new DirectoryOption (
1862 X_("default-session-parent-dir"),
1863 _("Default folder for new sessions:"),
1864 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1865 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1868 add_option (_("Misc"),
1869 new SpinOption<uint32_t> (
1870 "max-recent-sessions",
1871 _("Maximum number of recent sessions"),
1872 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1873 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1877 add_option (_("Misc"), new OptionEditorHeading (_("Click")));
1879 add_option (_("Misc"), new ClickOptions (_rc_config, this));
1881 add_option (_("Misc"),
1884 _("Click gain level"),
1885 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1886 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1889 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1891 add_option (_("Misc"),
1892 new SpinOption<double> (
1893 "automation-thinning-factor",
1894 _("Thinning factor (larger value => less data)"),
1895 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1896 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1900 add_option (_("Misc"),
1901 new SpinOption<double> (
1902 "automation-interval-msecs",
1903 _("Automation sampling interval (milliseconds)"),
1904 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1905 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1911 add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options")));
1915 tsf = new BoolOption (
1916 "latched-record-enable",
1917 _("Keep record-enable engaged on stop"),
1918 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1919 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1921 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1922 add_option (_("Transport"), tsf);
1924 tsf = new BoolOption (
1926 _("Play loop is a transport mode"),
1927 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1928 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1930 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1931 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1932 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1933 add_option (_("Transport"), tsf);
1935 tsf = new BoolOption (
1936 "stop-recording-on-xrun",
1937 _("Stop recording when an xrun occurs"),
1938 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1939 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1941 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1942 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
1944 add_option (_("Transport"), tsf);
1946 tsf = new BoolOption (
1947 "create-xrun-marker",
1948 _("Create markers where xruns occur"),
1949 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
1950 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
1952 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1953 add_option (_("Transport"), tsf);
1955 tsf = new BoolOption (
1956 "stop-at-session-end",
1957 _("Stop at the end of the session"),
1958 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
1959 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
1961 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1962 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
1963 "when it reaches the current session end marker\n\n"
1964 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
1966 add_option (_("Transport"), tsf);
1968 tsf = new BoolOption (
1970 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
1971 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
1972 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
1974 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1975 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
1976 "preventing any need to do a transport locate at the end of the loop\n\n"
1977 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
1978 "which will often cause a small click or delay"), PROGRAM_NAME));
1979 add_option (_("Transport"), tsf);
1981 tsf = new BoolOption (
1982 "disable-disarm-during-roll",
1983 _("Disable per-track record disarm while rolling"),
1984 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
1985 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
1987 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"));
1988 add_option (_("Transport"), tsf);
1990 tsf = new BoolOption (
1992 _("12dB gain reduction during fast-forward and fast-rewind"),
1993 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
1994 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
1996 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
1997 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
1998 add_option (_("Transport"), tsf);
2000 add_option (_("Transport"), new OptionEditorHeading (S_("Sync/Slave")));
2002 _sync_source = new ComboOption<SyncSource> (
2004 _("External timecode source"),
2005 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
2006 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
2009 add_option (_("Transport"), _sync_source);
2011 _sync_framerate = new BoolOption (
2012 "timecode-sync-frame-rate",
2013 _("Match session video frame rate to external timecode"),
2014 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
2015 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
2017 Gtkmm2ext::UI::instance()->set_tip
2018 (_sync_framerate->tip_widget(),
2019 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
2020 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
2021 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
2022 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
2023 "timecode standard and the session standard."), PROGRAM_NAME));
2025 add_option (_("Transport"), _sync_framerate);
2027 _sync_genlock = new BoolOption (
2028 "timecode-source-is-synced",
2029 _("Sync-lock timecode to clock (disable drift compensation)"),
2030 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
2031 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
2033 Gtkmm2ext::UI::instance()->set_tip
2034 (_sync_genlock->tip_widget(),
2035 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
2036 "Sync Lock indicates that the selected external timecode source shares clock-sync "
2037 "(Black & Burst, Wordclock, etc) with the audio interface. "
2038 "This option disables drift compensation. The transport speed is fixed at 1.0. "
2039 "Vari-speed LTC will be ignored and cause drift."
2041 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
2042 "timecode sources shares clock sync."
2046 add_option (_("Transport"), _sync_genlock);
2048 _sync_source_2997 = new BoolOption (
2049 "timecode-source-2997",
2050 _("Lock to 29.9700 fps instead of 30000/1001"),
2051 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
2052 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
2054 Gtkmm2ext::UI::instance()->set_tip
2055 (_sync_source_2997->tip_widget(),
2056 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
2057 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
2058 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
2059 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
2060 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
2061 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
2064 add_option (_("Transport"), _sync_source_2997);
2066 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Reader")));
2068 _ltc_port = new ComboStringOption (
2070 _("LTC incoming port"),
2071 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
2072 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
2075 vector<string> physical_inputs;
2076 physical_inputs.push_back (_("None"));
2077 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
2078 _ltc_port->set_popdown_strings (physical_inputs);
2080 populate_sync_options ();
2082 add_option (_("Transport"), _ltc_port);
2084 // TODO; rather disable this button than not compile it..
2085 add_option (_("Transport"), new OptionEditorHeading (S_("LTC Generator")));
2087 add_option (_("Transport"),
2090 _("Enable LTC generator"),
2091 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
2092 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
2095 _ltc_send_continuously = new BoolOption (
2096 "ltc-send-continuously",
2097 _("Send LTC while stopped"),
2098 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
2099 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
2101 Gtkmm2ext::UI::instance()->set_tip
2102 (_ltc_send_continuously->tip_widget(),
2103 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
2104 add_option (_("Transport"), _ltc_send_continuously);
2106 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
2107 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
2108 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
2109 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
2111 Gtkmm2ext::UI::instance()->set_tip
2112 (_ltc_volume_slider->tip_widget(),
2113 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
2115 add_option (_("Transport"), _ltc_volume_slider);
2116 parameter_changed ("send-ltc");
2118 parameter_changed ("sync-source");
2122 add_option (S_("Editor"),
2124 "draggable-playhead",
2125 _("Allow dragging of playhead"),
2126 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2127 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2130 add_option (_("Editor"),
2132 "automation-follows-regions",
2133 _("Move relevant automation when audio regions are moved"),
2134 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2135 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2138 add_option (_("Editor"),
2140 "show-track-meters",
2141 _("Show meters on tracks in the editor"),
2142 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
2143 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
2146 add_option (_("Editor"),
2148 "show-editor-meter",
2149 _("Display master-meter in the toolbar"),
2150 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
2151 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
2154 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2155 "default-fade-shape",
2156 _("Default fade shape"),
2157 sigc::mem_fun (*_rc_config,
2158 &RCConfiguration::get_default_fade_shape),
2159 sigc::mem_fun (*_rc_config,
2160 &RCConfiguration::set_default_fade_shape)
2163 fadeshape->add (FadeLinear,
2164 _("Linear (for highly correlated material)"));
2165 fadeshape->add (FadeConstantPower, _("Constant power"));
2166 fadeshape->add (FadeSymmetric, _("Symmetric"));
2167 fadeshape->add (FadeSlow, _("Slow"));
2168 fadeshape->add (FadeFast, _("Fast"));
2170 add_option (_("Editor"), fadeshape);
2173 bco = new BoolComboOption (
2174 "use-overlap-equivalency",
2175 _("Regions in active edit groups are edited together"),
2176 _("whenever they overlap in time"),
2177 _("only if they have identical length, position and origin"),
2178 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2179 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2182 add_option (_("Editor"), bco);
2184 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2186 _("Layering model"),
2187 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2188 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2191 lm->add (LaterHigher, _("later is higher"));
2192 lm->add (Manual, _("manual layering"));
2193 add_option (_("Editor"), lm);
2195 add_option (_("Editor"),
2197 "rubberbanding-snaps-to-grid",
2198 _("Make rubberband selection rectangle snap to the grid"),
2199 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2200 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2203 add_option (_("Editor"),
2206 _("Show waveforms in regions"),
2207 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
2208 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
2211 add_option (_("Editor"),
2212 new BoolComboOption (
2213 "show-region-gain-envelopes",
2214 _("Show gain envelopes in audio regions"),
2216 _("only in Draw and Internal Edit modes"),
2217 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2218 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2221 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
2223 _("Waveform scale"),
2224 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
2225 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
2228 wfs->add (Linear, _("linear"));
2229 wfs->add (Logarithmic, _("logarithmic"));
2231 add_option (_("Editor"), wfs);
2233 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
2235 _("Waveform shape"),
2236 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
2237 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
2240 wfsh->add (Traditional, _("traditional"));
2241 wfsh->add (Rectified, _("rectified"));
2243 add_option (_("Editor"), wfsh);
2245 add_option (_("Editor"), new ClipLevelOptions ());
2247 add_option (_("Editor"),
2249 "show-waveforms-while-recording",
2250 _("Show waveforms for audio while it is being recorded"),
2251 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
2252 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
2255 add_option (_("Editor"),
2258 _("Show zoom toolbar"),
2259 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_zoom_tools),
2260 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_zoom_tools)
2263 add_option (_("Editor"),
2265 "update-editor-during-summary-drag",
2266 _("Update editor window during drags of the summary"),
2267 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2268 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2271 bo = new BoolOption (
2273 _("Name new markers"),
2274 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2275 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2278 add_option (_("Editor"), bo);
2279 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."
2280 "\n\nYou can always rename markers by right-clicking on them"));
2282 add_option (_("Editor"),
2284 "autoscroll-editor",
2285 _("Auto-scroll editor window when dragging near its edges"),
2286 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2287 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2290 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2291 "region-selection-after-split",
2292 _("After splitting selected regions, select"),
2293 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2294 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2296 // TODO: decide which of these modes are really useful
2297 rsas->add(None, _("no regions"));
2298 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2299 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2300 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2301 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2302 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2303 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2304 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2306 add_option (_("Editor"), rsas);
2311 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2313 add_option (_("Audio"), new BufferingOptions (_rc_config));
2315 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2317 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2319 _("Record monitoring handled by"),
2320 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2321 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2324 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2325 mm->add (HardwareMonitoring, _("via Audio Driver"));
2328 string prog (PROGRAM_NAME);
2329 boost::algorithm::to_lower (prog);
2330 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2331 mm->add (ExternalMonitoring, _("audio hardware"));
2333 add_option (_("Audio"), mm);
2335 add_option (_("Audio"),
2337 "tape-machine-mode",
2338 _("Tape machine mode"),
2339 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2340 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2343 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
2345 add_option (_("Audio"),
2347 "auto-connect-standard-busses",
2348 _("Auto-connect master/monitor busses"),
2349 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2350 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2353 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2354 "input-auto-connect",
2355 _("Connect track inputs"),
2356 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2357 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2360 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2361 iac->add (ManualConnect, _("manually"));
2363 add_option (_("Audio"), iac);
2365 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2366 "output-auto-connect",
2367 _("Connect track and bus outputs"),
2368 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2369 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2372 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2373 oac->add (AutoConnectMaster, _("automatically to master bus"));
2374 oac->add (ManualConnect, _("manually"));
2376 add_option (_("Audio"), oac);
2378 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2380 add_option (_("Audio"),
2382 "denormal-protection",
2383 _("Use DC bias to protect against denormals"),
2384 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2385 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2388 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2390 _("Processor handling"),
2391 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2392 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2396 dm->add (DenormalNone, _("no processor handling"));
2398 FPU* fpu = FPU::instance();
2400 if (fpu->has_flush_to_zero()) {
2402 dm->add (DenormalFTZ, _("use FlushToZero"));
2403 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2404 _rc_config->set_denormal_model(DenormalNone);
2407 if (fpu->has_denormals_are_zero()) {
2409 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2410 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2411 _rc_config->set_denormal_model(DenormalNone);
2414 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2416 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2417 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2418 _rc_config->set_denormal_model(DenormalNone);
2422 dm->set_sensitive(false);
2425 add_option (_("Audio"), dm);
2427 add_option (_("Audio"), new OptionEditorHeading (_("Plugins")));
2429 add_option (_("Audio"),
2431 "plugins-stop-with-transport",
2432 _("Silence plugins when the transport is stopped"),
2433 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
2434 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
2437 add_option (_("Audio"),
2439 "new-plugins-active",
2440 _("Make new plugins active"),
2441 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
2442 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
2445 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2447 add_option (_("Audio"),
2449 "auto-analyse-audio",
2450 _("Enable automatic analysis of audio"),
2451 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2452 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2455 add_option (_("Audio"),
2457 "replicate-missing-region-channels",
2458 _("Replicate missing region channels"),
2459 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2460 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2465 add_option (_("Solo / mute"), new OptionEditorHeading (_("Solo")));
2467 add_option (_("Solo / mute"),
2470 _("Solo-in-place mute cut (dB)"),
2471 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2472 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2475 _solo_control_is_listen_control = new BoolOption (
2476 "solo-control-is-listen-control",
2477 _("Solo controls are Listen controls"),
2478 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2479 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2482 add_option (_("Solo / mute"), _solo_control_is_listen_control);
2484 _listen_position = new ComboOption<ListenPosition> (
2486 _("Listen Position"),
2487 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2488 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2491 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2492 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2494 add_option (_("Solo / mute"), _listen_position);
2496 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2498 _("PFL signals come from"),
2499 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2500 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2503 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2504 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2506 add_option (_("Solo / mute"), pp);
2508 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2510 _("AFL signals come from"),
2511 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2512 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2515 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2516 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2518 add_option (_("Solo / mute"), pa);
2520 parameter_changed ("use-monitor-bus");
2522 add_option (_("Solo / mute"),
2525 _("Exclusive solo"),
2526 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2527 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2530 add_option (_("Solo / mute"),
2533 _("Show solo muting"),
2534 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2535 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2538 add_option (_("Solo / mute"),
2540 "solo-mute-override",
2541 _("Soloing overrides muting"),
2542 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2543 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2546 add_option (_("Solo / mute"), new OptionEditorHeading (_("Default track / bus muting options")));
2548 add_option (_("Solo / mute"),
2550 "mute-affects-pre-fader",
2551 _("Mute affects pre-fader sends"),
2552 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2553 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2556 add_option (_("Solo / mute"),
2558 "mute-affects-post-fader",
2559 _("Mute affects post-fader sends"),
2560 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2561 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2564 add_option (_("Solo / mute"),
2566 "mute-affects-control-outs",
2567 _("Mute affects control outputs"),
2568 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2569 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2572 add_option (_("Solo / mute"),
2574 "mute-affects-main-outs",
2575 _("Mute affects main outputs"),
2576 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2577 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2580 add_option (_("Solo / mute"), new OptionEditorHeading (_("Send Routing")));
2582 add_option (_("Solo / mute"),
2584 "link-send-and-route-panner",
2585 _("Link panners of Aux and External Sends with main panner by default"),
2586 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2587 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2590 add_option (_("MIDI"),
2591 new SpinOption<float> (
2593 _("MIDI read-ahead time (seconds)"),
2594 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2595 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2600 add_option (_("MIDI"),
2603 _("Send MIDI Clock"),
2604 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2605 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2608 add_option (_("MIDI"),
2611 _("Send MIDI Time Code"),
2612 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2613 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2616 add_option (_("MIDI"),
2617 new SpinOption<int> (
2618 "mtc-qf-speed-tolerance",
2619 _("Percentage either side of normal transport speed to transmit MTC"),
2620 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2621 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2625 add_option (_("MIDI"),
2628 _("Obey MIDI Machine Control commands"),
2629 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2630 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2633 add_option (_("MIDI"),
2636 _("Send MIDI Machine Control commands"),
2637 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2638 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2641 add_option (_("MIDI"),
2644 _("Send MIDI control feedback"),
2645 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2646 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2649 add_option (_("MIDI"),
2650 new SpinOption<uint8_t> (
2651 "mmc-receive-device-id",
2652 _("Inbound MMC device ID"),
2653 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2654 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2658 add_option (_("MIDI"),
2659 new SpinOption<uint8_t> (
2660 "mmc-send-device-id",
2661 _("Outbound MMC device ID"),
2662 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2663 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2667 add_option (_("MIDI"),
2668 new SpinOption<int32_t> (
2669 "initial-program-change",
2670 _("Initial program change"),
2671 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2672 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2676 add_option (_("MIDI"),
2678 "display-first-midi-bank-as-zero",
2679 _("Display first MIDI bank/program as 0"),
2680 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2681 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2684 add_option (_("MIDI"),
2686 "never-display-periodic-midi",
2687 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2688 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
2689 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
2692 add_option (_("MIDI"),
2695 _("Sound MIDI notes as they are selected"),
2696 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2697 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2700 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2702 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2703 "midi-audition-synth-uri",
2704 _("Midi Audition Synth (LV2)"),
2705 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2706 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2709 audition_synth->add(X_(""), _("None"));
2710 PluginInfoList all_plugs;
2711 PluginManager& manager (PluginManager::instance());
2713 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2715 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2716 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2717 if (!(*i)->is_instrument()) continue;
2718 if ((*i)->type != ARDOUR::LV2) continue;
2719 audition_synth->add((*i)->unique_id, (*i)->name);
2723 add_option (_("MIDI"), audition_synth);
2725 /* USER INTERACTION */
2728 #ifdef PLATFORM_WINDOWS
2731 getenv ("ARDOUR_BUNDLED")
2735 add_option (_("User interaction"),
2737 "enable-translation",
2738 string_compose (_("Use translations of %1 messages\n"
2739 " <i>(requires a restart of %1 to take effect)</i>\n"
2740 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2741 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2742 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2745 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2747 add_option (_("User interaction"), new KeyboardOptions);
2749 /* Control Surfaces */
2751 add_option (_("Control Surfaces"), new ControlSurfacesOptions (*this));
2753 ComboOption<RemoteModel>* rm = new ComboOption<RemoteModel> (
2755 _("Control surface remote ID"),
2756 sigc::mem_fun (*_rc_config, &RCConfiguration::get_remote_model),
2757 sigc::mem_fun (*_rc_config, &RCConfiguration::set_remote_model)
2760 rm->add (UserOrdered, _("assigned by user"));
2761 rm->add (MixerOrdered, _("follows order of mixer"));
2763 add_option (_("Control Surfaces"), rm);
2765 /* VIDEO Timeline */
2766 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2768 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2769 /* Plugin options (currrently VST only) */
2770 add_option (_("Plugins"), new PluginOptions (_rc_config));
2775 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
2776 BoolOption* bgc = new BoolOption (
2777 "cairo-image-surface",
2778 _("Disable Graphics Hardware Acceleration (requires restart)"),
2779 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
2780 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
2783 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
2784 _("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));
2785 add_option (S_("Preferences|GUI"), bgc);
2788 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
2789 BoolOption* bgo = new BoolOption (
2791 _("Possibly improve slow graphical performance (requires restart)"),
2792 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
2793 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
2796 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));
2797 add_option (S_("Preferences|GUI"), bgo);
2800 add_option (S_("Preferences|GUI"),
2803 _("Graphically indicate mouse pointer hovering over various widgets"),
2804 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
2805 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
2808 #ifdef TOOLTIPS_GOT_FIXED
2809 add_option (S_("Preferences|GUI"),
2812 _("Show tooltips if mouse hovers over a control"),
2813 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
2814 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
2818 add_option (S_("Preferences|GUI"),
2820 "show-name-highlight",
2821 _("Use name highlight bars in region displays (requires a restart)"),
2822 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
2823 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
2827 /* font scaling does nothing with GDK/Quartz */
2828 add_option (S_("Preferences|GUI"), new FontScalingOptions ());
2831 add_option (S_("GUI"),
2833 "super-rapid-clock-update",
2834 _("update transport clock display at FPS instead of every 100ms"),
2835 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
2836 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
2840 /* Image cache size */
2842 Gtk::Adjustment *ics = manage (new Gtk::Adjustment(0, 1, 1024, 10)); /* 1 MB to 1GB in steps of 10MB */
2843 HSliderOption *sics = new HSliderOption("waveform-cache-size",
2844 _("Waveform image cache size (megabytes)"),
2846 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
2847 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size)
2849 sics->scale().set_digits (0);
2850 Gtkmm2ext::UI::instance()->set_tip
2851 (sics->tip_widget(),
2852 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
2853 add_option (S_("Preferences|GUI"), sics);
2855 /* Lock GUI timeout */
2857 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
2858 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
2859 _("Lock timeout (seconds)"),
2861 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
2862 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds)
2864 slts->scale().set_digits (0);
2865 Gtkmm2ext::UI::instance()->set_tip
2866 (slts->tip_widget(),
2867 _("Lock GUI after this many idle seconds (zero to never lock)"));
2868 add_option (S_("Preferences|GUI"), slts);
2870 /* The names of these controls must be the same as those given in MixerStrip
2871 for the actual widgets being controlled.
2873 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
2874 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
2875 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
2876 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
2877 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
2878 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
2881 S_("Preferences|GUI"),
2882 new VisibilityOption (
2884 &_mixer_strip_visibility,
2885 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
2886 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
2890 add_option (S_("Preferences|GUI"),
2892 "default-narrow_ms",
2893 _("Use narrow strips in the mixer by default"),
2894 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
2895 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
2898 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
2900 ComboOption<float>* mht = new ComboOption<float> (
2902 _("Peak hold time"),
2903 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
2904 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
2907 mht->add (MeterHoldOff, _("off"));
2908 mht->add (MeterHoldShort, _("short"));
2909 mht->add (MeterHoldMedium, _("medium"));
2910 mht->add (MeterHoldLong, _("long"));
2912 add_option (S_("Preferences|Metering"), mht);
2914 ComboOption<float>* mfo = new ComboOption<float> (
2917 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
2918 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
2921 mfo->add (METER_FALLOFF_OFF, _("off"));
2922 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
2923 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
2924 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
2925 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
2926 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
2927 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
2929 add_option (S_("Preferences|Metering"), mfo);
2931 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
2932 "meter-line-up-level",
2933 _("Meter line-up level; 0dBu"),
2934 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
2935 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
2938 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2939 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2940 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2941 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2943 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."));
2945 add_option (S_("Preferences|Metering"), mlu);
2947 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
2948 "meter-line-up-din",
2949 _("IEC1/DIN Meter line-up level; 0dBu"),
2950 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
2951 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
2954 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
2955 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
2956 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
2957 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
2959 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
2961 add_option (S_("Preferences|Metering"), mld);
2963 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
2964 "meter-vu-standard",
2965 _("VU Meter standard"),
2966 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
2967 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
2970 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
2971 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
2972 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
2973 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
2975 add_option (S_("Preferences|Metering"), mvu);
2977 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
2978 HSliderOption *mpks = new HSliderOption("meter-peak",
2979 _("Peak threshold [dBFS]"),
2981 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
2982 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak)
2986 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
2987 "meter-type-master",
2988 _("Default Meter Type for Master Bus"),
2989 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
2990 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
2992 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
2993 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
2994 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
2995 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
2996 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
2997 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
2998 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
2999 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3001 add_option (S_("Preferences|Metering"), mtm);
3004 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3006 _("Default Meter Type for Busses"),
3007 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3008 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3010 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3011 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3012 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3013 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3014 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3015 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3016 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3017 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3019 add_option (S_("Preferences|Metering"), mtb);
3021 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3023 _("Default Meter Type for Tracks"),
3024 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3025 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3027 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3028 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3030 add_option (S_("Preferences|Metering"), mtt);
3033 Gtkmm2ext::UI::instance()->set_tip
3034 (mpks->tip_widget(),
3035 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
3037 add_option (S_("Preferences|Metering"), mpks);
3039 add_option (S_("Preferences|Metering"),
3042 _("LED meter style"),
3043 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3044 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3047 /* and now the theme manager */
3049 ThemeManager* tm = manage (new ThemeManager);
3050 add_page (_("Theme"), *tm);
3054 RCOptionEditor::parameter_changed (string const & p)
3056 OptionEditor::parameter_changed (p);
3058 if (p == "use-monitor-bus") {
3059 bool const s = Config->get_use_monitor_bus ();
3061 /* we can't use this if we don't have a monitor bus */
3062 Config->set_solo_control_is_listen_control (false);
3064 _solo_control_is_listen_control->set_sensitive (s);
3065 _listen_position->set_sensitive (s);
3066 } else if (p == "sync-source") {
3067 _sync_source->set_sensitive (true);
3069 _sync_source->set_sensitive (!_session->config.get_external_sync());
3071 switch(Config->get_sync_source()) {
3074 _sync_genlock->set_sensitive (true);
3075 _sync_framerate->set_sensitive (true);
3076 _sync_source_2997->set_sensitive (true);
3079 _sync_genlock->set_sensitive (false);
3080 _sync_framerate->set_sensitive (false);
3081 _sync_source_2997->set_sensitive (false);
3084 } else if (p == "send-ltc") {
3085 bool const s = Config->get_send_ltc ();
3086 _ltc_send_continuously->set_sensitive (s);
3087 _ltc_volume_slider->set_sensitive (s);
3091 void RCOptionEditor::ltc_generator_volume_changed () {
3092 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
3096 RCOptionEditor::populate_sync_options ()
3098 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3100 _sync_source->clear ();
3102 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3103 _sync_source->add (*i, sync_source_to_string (*i));
3106 if (sync_opts.empty()) {
3107 _sync_source->set_sensitive(false);
3109 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3110 _rc_config->set_sync_source(sync_opts.front());