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>
40 #include <gtkmm2ext/window_title.h>
45 #include "ardour/audioengine.h"
46 #include "ardour/profile.h"
47 #include "ardour/dB.h"
48 #include "ardour/rc_configuration.h"
49 #include "ardour/control_protocol_manager.h"
50 #include "ardour/plugin_manager.h"
51 #include "control_protocol/control_protocol.h"
53 #include "canvas/wave_view.h"
55 #include "ardour_window.h"
56 #include "ardour_dialog.h"
57 #include "ardour_ui.h"
58 #include "color_theme_manager.h"
59 #include "gui_thread.h"
60 #include "meter_patterns.h"
61 #include "midi_tracer.h"
62 #include "rc_option_editor.h"
64 #include "midi_port_dialog.h"
67 #include "theme_manager.h"
68 #include "ui_config.h"
73 using namespace Gtkmm2ext;
75 using namespace ARDOUR;
76 using namespace ARDOUR_UI_UTILS;
78 class ClickOptions : public OptionEditorBox
81 ClickOptions (RCConfiguration* c)
83 , _click_browse_button (_("Browse..."))
84 , _click_emphasis_browse_button (_("Browse..."))
86 Table* t = manage (new Table (4, 3));
89 Label* l = manage (left_aligned_label (_("Emphasis on first beat:")));
90 t->attach (*l, 0, 1, 1, 2, FILL);
91 t->attach (_use_emphasis_on_click_check_button, 1, 2, 1, 2, FILL);
92 _use_emphasis_on_click_check_button.signal_toggled().connect (
93 sigc::mem_fun (*this, &ClickOptions::use_emphasis_on_click_toggled));
95 l = manage (left_aligned_label (_("Use default Click:")));
96 t->attach (*l, 0, 1, 0, 1, FILL);
97 t->attach (_use_default_click_check_button, 1, 2, 0, 1, FILL);
98 _use_default_click_check_button.signal_toggled().connect (
99 sigc::mem_fun (*this, &ClickOptions::use_default_click_toggled));
101 l = manage (left_aligned_label (_("Click audio file:")));
102 t->attach (*l, 0, 1, 2, 3, FILL);
103 t->attach (_click_path_entry, 1, 2, 2, 3, FILL);
104 _click_browse_button.signal_clicked ().connect (
105 sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
106 t->attach (_click_browse_button, 2, 3, 2, 3, FILL);
108 l = manage (left_aligned_label (_("Click emphasis audio file:")));
109 t->attach (*l, 0, 1, 3, 4, FILL);
110 t->attach (_click_emphasis_path_entry, 1, 2, 3, 4, FILL);
111 _click_emphasis_browse_button.signal_clicked ().connect (
112 sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
113 t->attach (_click_emphasis_browse_button, 2, 3, 3, 4, FILL);
115 _box->pack_start (*t, true, false);
117 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
118 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
120 if (_rc_config->get_click_sound ().empty() &&
121 _rc_config->get_click_emphasis_sound().empty()) {
122 _use_default_click_check_button.set_active (true);
123 _use_emphasis_on_click_check_button.set_active (true);
126 _use_default_click_check_button.set_active (false);
127 _use_emphasis_on_click_check_button.set_active (false);
131 void parameter_changed (string const & p)
133 if (p == "click-sound") {
134 _click_path_entry.set_text (_rc_config->get_click_sound());
135 } else if (p == "click-emphasis-sound") {
136 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
137 } else if (p == "use-click-emphasis") {
138 bool x = _rc_config->get_use_click_emphasis ();
139 _use_emphasis_on_click_check_button.set_active (x);
143 void set_state_from_config ()
145 parameter_changed ("click-sound");
146 parameter_changed ("click-emphasis-sound");
147 parameter_changed ("use-click-emphasis");
152 void click_browse_clicked ()
154 SoundFileChooser sfdb (_("Choose Click"));
159 if (sfdb.run () == RESPONSE_OK) {
160 click_chosen (sfdb.get_filename());
164 void click_chosen (string const & path)
166 _click_path_entry.set_text (path);
167 _rc_config->set_click_sound (path);
170 void click_changed ()
172 click_chosen (_click_path_entry.get_text ());
175 void click_emphasis_browse_clicked ()
177 SoundFileChooser sfdb (_("Choose Click Emphasis"));
182 if (sfdb.run () == RESPONSE_OK) {
183 click_emphasis_chosen (sfdb.get_filename());
187 void click_emphasis_chosen (string const & path)
189 _click_emphasis_path_entry.set_text (path);
190 _rc_config->set_click_emphasis_sound (path);
193 void click_emphasis_changed ()
195 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
198 void use_default_click_toggled ()
200 if (_use_default_click_check_button.get_active ()) {
201 _rc_config->set_click_sound ("");
202 _rc_config->set_click_emphasis_sound ("");
203 _click_path_entry.set_sensitive (false);
204 _click_emphasis_path_entry.set_sensitive (false);
205 _click_browse_button.set_sensitive (false);
206 _click_emphasis_browse_button.set_sensitive (false);
208 _click_path_entry.set_sensitive (true);
209 _click_emphasis_path_entry.set_sensitive (true);
210 _click_browse_button.set_sensitive (true);
211 _click_emphasis_browse_button.set_sensitive (true);
215 void use_emphasis_on_click_toggled ()
217 if (_use_emphasis_on_click_check_button.get_active ()) {
218 _rc_config->set_use_click_emphasis(true);
220 _rc_config->set_use_click_emphasis(false);
224 RCConfiguration* _rc_config;
225 CheckButton _use_default_click_check_button;
226 CheckButton _use_emphasis_on_click_check_button;
227 Entry _click_path_entry;
228 Entry _click_emphasis_path_entry;
229 Button _click_browse_button;
230 Button _click_emphasis_browse_button;
233 class UndoOptions : public OptionEditorBox
236 UndoOptions (RCConfiguration* c) :
238 _limit_undo_button (_("Limit undo history to")),
239 _save_undo_button (_("Save undo history of"))
241 Table* t = new Table (2, 3);
244 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
245 _limit_undo_spin.set_range (0, 512);
246 _limit_undo_spin.set_increments (1, 10);
247 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
248 Label* l = manage (left_aligned_label (_("commands")));
249 t->attach (*l, 2, 3, 0, 1);
251 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
252 _save_undo_spin.set_range (0, 512);
253 _save_undo_spin.set_increments (1, 10);
254 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
255 l = manage (left_aligned_label (_("commands")));
256 t->attach (*l, 2, 3, 1, 2);
258 _box->pack_start (*t);
260 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
261 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
262 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
263 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
266 void parameter_changed (string const & p)
268 if (p == "history-depth") {
269 int32_t const d = _rc_config->get_history_depth();
270 _limit_undo_button.set_active (d != 0);
271 _limit_undo_spin.set_sensitive (d != 0);
272 _limit_undo_spin.set_value (d);
273 } else if (p == "save-history") {
274 bool const x = _rc_config->get_save_history ();
275 _save_undo_button.set_active (x);
276 _save_undo_spin.set_sensitive (x);
277 } else if (p == "save-history-depth") {
278 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
282 void set_state_from_config ()
284 parameter_changed ("save-history");
285 parameter_changed ("history-depth");
286 parameter_changed ("save-history-depth");
289 void limit_undo_toggled ()
291 bool const x = _limit_undo_button.get_active ();
292 _limit_undo_spin.set_sensitive (x);
293 int32_t const n = x ? 16 : 0;
294 _limit_undo_spin.set_value (n);
295 _rc_config->set_history_depth (n);
298 void limit_undo_changed ()
300 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
303 void save_undo_toggled ()
305 bool const x = _save_undo_button.get_active ();
306 _rc_config->set_save_history (x);
309 void save_undo_changed ()
311 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
315 RCConfiguration* _rc_config;
316 CheckButton _limit_undo_button;
317 SpinButton _limit_undo_spin;
318 CheckButton _save_undo_button;
319 SpinButton _save_undo_spin;
324 static const struct {
336 { "Key|Shift", GDK_SHIFT_MASK },
337 { "Command", GDK_MOD2_MASK },
338 { "Control", GDK_CONTROL_MASK },
339 { "Option", GDK_MOD1_MASK },
340 { "Command-Shift", GDK_MOD2_MASK|GDK_SHIFT_MASK },
341 { "Command-Option", GDK_MOD2_MASK|GDK_MOD1_MASK },
342 { "Command-Option-Control", GDK_MOD2_MASK|GDK_MOD1_MASK|GDK_CONTROL_MASK },
343 { "Option-Control", GDK_MOD1_MASK|GDK_CONTROL_MASK },
344 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
345 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
346 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_MOD2_MASK },
349 { "Key|Shift", GDK_SHIFT_MASK },
350 { "Control", GDK_CONTROL_MASK },
351 { "Alt", GDK_MOD1_MASK },
352 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
353 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
354 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
355 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
356 { "Alt-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
357 { "Alt-Shift-Windows", GDK_MOD1_MASK|GDK_SHIFT_MASK|GDK_MOD4_MASK },
358 { "Mod2", GDK_MOD2_MASK },
359 { "Mod3", GDK_MOD3_MASK },
360 { "Windows", GDK_MOD4_MASK },
361 { "Mod5", GDK_MOD5_MASK },
367 class KeyboardOptions : public OptionEditorBox
371 _delete_button_adjustment (3, 1, 12),
372 _delete_button_spin (_delete_button_adjustment),
373 _edit_button_adjustment (3, 1, 5),
374 _edit_button_spin (_edit_button_adjustment),
375 _insert_note_button_adjustment (3, 1, 5),
376 _insert_note_button_spin (_insert_note_button_adjustment)
378 const std::string restart_msg = _("\nChanges to this setting will only persist after your project has been saved.");
379 /* internationalize and prepare for use with combos */
382 for (int i = 0; modifiers[i].name; ++i) {
383 dumb.push_back (S_(modifiers[i].name));
386 set_popdown_strings (_edit_modifier_combo, dumb);
387 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
388 Gtkmm2ext::UI::instance()->set_tip (_edit_modifier_combo,
389 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
390 for (int x = 0; modifiers[x].name; ++x) {
391 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
392 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
397 Table* t = manage (new Table (5, 11));
403 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
404 l->set_name ("OptionsLabel");
408 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
409 strs.push_back (bf->first);
412 set_popdown_strings (_keyboard_layout_selector, strs);
413 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
414 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
416 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
417 t->attach (_keyboard_layout_selector, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
422 l = manage (left_aligned_label (_("When Clicking:")));
423 l->set_name ("OptionEditorHeading");
424 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
429 l = manage (left_aligned_label (_("Edit using:")));
430 l->set_name ("OptionsLabel");
432 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
433 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
435 l = manage (new Label (_("+ button")));
436 l->set_name ("OptionsLabel");
438 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
439 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
441 _edit_button_spin.set_name ("OptionsEntry");
442 _edit_button_adjustment.set_value (Keyboard::edit_button());
443 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
448 set_popdown_strings (_delete_modifier_combo, dumb);
449 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
450 Gtkmm2ext::UI::instance()->set_tip (_delete_modifier_combo,
451 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
452 for (int x = 0; modifiers[x].name; ++x) {
453 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
454 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
459 l = manage (left_aligned_label (_("Delete using:")));
460 l->set_name ("OptionsLabel");
462 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
463 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
465 l = manage (new Label (_("+ button")));
466 l->set_name ("OptionsLabel");
468 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
469 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
471 _delete_button_spin.set_name ("OptionsEntry");
472 _delete_button_adjustment.set_value (Keyboard::delete_button());
473 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
478 set_popdown_strings (_insert_note_modifier_combo, dumb);
479 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
480 Gtkmm2ext::UI::instance()->set_tip (_insert_note_modifier_combo,
481 (string_compose (_("<b>Recommended Setting: %1 + button 1 (left mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
482 for (int x = 0; modifiers[x].name; ++x) {
483 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
484 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
489 l = manage (left_aligned_label (_("Insert note using:")));
490 l->set_name ("OptionsLabel");
492 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
493 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
495 l = manage (new Label (_("+ button")));
496 l->set_name ("OptionsLabel");
498 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
499 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
501 _insert_note_button_spin.set_name ("OptionsEntry");
502 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
503 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
507 l = manage (left_aligned_label (_("When Beginning a Drag:")));
508 l->set_name ("OptionEditorHeading");
509 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
515 set_popdown_strings (_copy_modifier_combo, dumb);
516 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
517 Gtkmm2ext::UI::instance()->set_tip (_copy_modifier_combo,
518 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
520 Keyboard::secondary_modifier_name (),
522 Keyboard::primary_modifier_name (),
525 for (int x = 0; modifiers[x].name; ++x) {
526 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
527 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
532 l = manage (left_aligned_label (_("Copy items using:")));
533 l->set_name ("OptionsLabel");
535 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
536 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
541 /* constraint modifier */
542 set_popdown_strings (_constraint_modifier_combo, dumb);
543 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
544 Gtkmm2ext::UI::instance()->set_tip (_constraint_modifier_combo,
545 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
547 Keyboard::primary_modifier_name (),
549 Keyboard::secondary_modifier_name (),
552 for (int x = 0; modifiers[x].name; ++x) {
553 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
554 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
559 l = manage (left_aligned_label (_("Constrain drag using:")));
560 l->set_name ("OptionsLabel");
562 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
563 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
567 l = manage (left_aligned_label (_("When Beginning a Trim:")));
568 l->set_name ("OptionEditorHeading");
569 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
575 set_popdown_strings (_trim_contents_combo, dumb);
576 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
577 Gtkmm2ext::UI::instance()->set_tip (_trim_contents_combo,
578 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
579 for (int x = 0; modifiers[x].name; ++x) {
580 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
581 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
586 l = manage (left_aligned_label (_("Trim contents using:")));
587 l->set_name ("OptionsLabel");
589 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
590 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
596 set_popdown_strings (_trim_anchored_combo, dumb);
597 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
598 Gtkmm2ext::UI::instance()->set_tip (_trim_anchored_combo,
599 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
600 for (int x = 0; modifiers[x].name; ++x) {
601 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
602 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
607 l = manage (left_aligned_label (_("Anchored trim using:")));
608 l->set_name ("OptionsLabel");
610 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
612 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
617 /* jump trim disabled for now
618 set_popdown_strings (_trim_jump_combo, dumb);
619 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
621 for (int x = 0; modifiers[x].name; ++x) {
622 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
623 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
628 l = manage (left_aligned_label (_("Jump after trim using:")));
629 l->set_name ("OptionsLabel");
631 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
633 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
639 /* note resize relative */
640 set_popdown_strings (_note_size_relative_combo, dumb);
641 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
642 Gtkmm2ext::UI::instance()->set_tip (_note_size_relative_combo,
643 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
644 for (int x = 0; modifiers[x].name; ++x) {
645 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
646 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
651 l = manage (left_aligned_label (_("Resize notes relatively using:")));
652 l->set_name ("OptionsLabel");
654 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
656 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
660 l = manage (left_aligned_label (_("While Dragging:")));
661 l->set_name ("OptionEditorHeading");
662 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
668 set_popdown_strings (_snap_modifier_combo, dumb);
669 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
671 std::string mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ());
673 std::string mod_str = Keyboard::secondary_modifier_name();
675 Gtkmm2ext::UI::instance()->set_tip (_snap_modifier_combo,
676 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
677 for (int x = 0; modifiers[x].name; ++x) {
678 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
679 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
684 l = manage (left_aligned_label (_("Ignore snap using:")));
685 l->set_name ("OptionsLabel");
687 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
688 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
694 set_popdown_strings (_snap_delta_combo, dumb);
695 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
697 mod_str = Keyboard::level4_modifier_name ();
699 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::level4_modifier_name ());
701 Gtkmm2ext::UI::instance()->set_tip (_snap_delta_combo,
702 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
703 for (int x = 0; modifiers[x].name; ++x) {
704 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
705 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
710 l = manage (left_aligned_label (_("Snap relatively using:")));
711 l->set_name ("OptionsLabel");
713 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
714 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
718 l = manage (left_aligned_label (_("While Trimming:")));
719 l->set_name ("OptionEditorHeading");
720 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
726 set_popdown_strings (_trim_overlap_combo, dumb);
727 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
729 Gtkmm2ext::UI::instance()->set_tip (_trim_overlap_combo,
730 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
731 for (int x = 0; modifiers[x].name; ++x) {
732 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
733 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
738 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
739 l->set_name ("OptionsLabel");
741 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
742 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
746 l = manage (left_aligned_label (_("While Dragging Control Points:")));
747 l->set_name ("OptionEditorHeading");
748 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
754 set_popdown_strings (_fine_adjust_combo, dumb);
755 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
757 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::tertiary_modifier_name ());
758 Gtkmm2ext::UI::instance()->set_tip (_fine_adjust_combo,
759 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
760 for (int x = 0; modifiers[x].name; ++x) {
761 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
762 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
767 l = manage (left_aligned_label (_("Fine adjust using:")));
768 l->set_name ("OptionsLabel");
770 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
771 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
777 set_popdown_strings (_push_points_combo, dumb);
778 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
780 Gtkmm2ext::UI::instance()->set_tip (_push_points_combo,
781 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
782 for (int x = 0; modifiers[x].name; ++x) {
783 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
784 _push_points_combo.set_active_text (S_(modifiers[x].name));
789 l = manage (left_aligned_label (_("Push points using:")));
790 l->set_name ("OptionsLabel");
792 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
793 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
795 _box->pack_start (*t, false, false);
798 void parameter_changed (string const &)
800 /* XXX: these aren't really config options... */
803 void set_state_from_config ()
805 /* XXX: these aren't really config options... */
810 void bindings_changed ()
812 string const txt = _keyboard_layout_selector.get_active_text();
814 /* XXX: config...? for all this keyboard stuff */
816 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
817 if (txt == i->first) {
818 if (Keyboard::load_keybindings (i->second)) {
819 Keyboard::save_keybindings ();
825 void edit_modifier_chosen ()
827 string const txt = _edit_modifier_combo.get_active_text();
829 for (int i = 0; modifiers[i].name; ++i) {
830 if (txt == S_(modifiers[i].name)) {
831 Keyboard::set_edit_modifier (modifiers[i].modifier);
837 void delete_modifier_chosen ()
839 string const txt = _delete_modifier_combo.get_active_text();
841 for (int i = 0; modifiers[i].name; ++i) {
842 if (txt == S_(modifiers[i].name)) {
843 Keyboard::set_delete_modifier (modifiers[i].modifier);
849 void copy_modifier_chosen ()
851 string const txt = _copy_modifier_combo.get_active_text();
853 for (int i = 0; modifiers[i].name; ++i) {
854 if (txt == S_(modifiers[i].name)) {
855 Keyboard::set_copy_modifier (modifiers[i].modifier);
861 void insert_note_modifier_chosen ()
863 string const txt = _insert_note_modifier_combo.get_active_text();
865 for (int i = 0; modifiers[i].name; ++i) {
866 if (txt == S_(modifiers[i].name)) {
867 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
873 void snap_modifier_chosen ()
875 string const txt = _snap_modifier_combo.get_active_text();
877 for (int i = 0; modifiers[i].name; ++i) {
878 if (txt == S_(modifiers[i].name)) {
879 Keyboard::set_snap_modifier (modifiers[i].modifier);
885 void snap_delta_modifier_chosen ()
887 string const txt = _snap_delta_combo.get_active_text();
889 for (int i = 0; modifiers[i].name; ++i) {
890 if (txt == S_(modifiers[i].name)) {
891 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
897 void constraint_modifier_chosen ()
899 string const txt = _constraint_modifier_combo.get_active_text();
901 for (int i = 0; modifiers[i].name; ++i) {
902 if (txt == S_(modifiers[i].name)) {
903 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
909 void trim_contents_modifier_chosen ()
911 string const txt = _trim_contents_combo.get_active_text();
913 for (int i = 0; modifiers[i].name; ++i) {
914 if (txt == S_(modifiers[i].name)) {
915 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
921 void trim_overlap_modifier_chosen ()
923 string const txt = _trim_overlap_combo.get_active_text();
925 for (int i = 0; modifiers[i].name; ++i) {
926 if (txt == S_(modifiers[i].name)) {
927 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
933 void trim_anchored_modifier_chosen ()
935 string const txt = _trim_anchored_combo.get_active_text();
937 for (int i = 0; modifiers[i].name; ++i) {
938 if (txt == S_(modifiers[i].name)) {
939 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
945 void fine_adjust_modifier_chosen ()
947 string const txt = _fine_adjust_combo.get_active_text();
949 for (int i = 0; modifiers[i].name; ++i) {
950 if (txt == S_(modifiers[i].name)) {
951 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
957 void push_points_modifier_chosen ()
959 string const txt = _push_points_combo.get_active_text();
961 for (int i = 0; modifiers[i].name; ++i) {
962 if (txt == S_(modifiers[i].name)) {
963 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
969 void note_size_relative_modifier_chosen ()
971 string const txt = _note_size_relative_combo.get_active_text();
973 for (int i = 0; modifiers[i].name; ++i) {
974 if (txt == S_(modifiers[i].name)) {
975 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
981 void delete_button_changed ()
983 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
986 void edit_button_changed ()
988 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
991 void insert_note_button_changed ()
993 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
996 ComboBoxText _keyboard_layout_selector;
997 ComboBoxText _edit_modifier_combo;
998 ComboBoxText _delete_modifier_combo;
999 ComboBoxText _copy_modifier_combo;
1000 ComboBoxText _insert_note_modifier_combo;
1001 ComboBoxText _snap_modifier_combo;
1002 ComboBoxText _snap_delta_combo;
1003 ComboBoxText _constraint_modifier_combo;
1004 ComboBoxText _trim_contents_combo;
1005 ComboBoxText _trim_overlap_combo;
1006 ComboBoxText _trim_anchored_combo;
1007 ComboBoxText _trim_jump_combo;
1008 ComboBoxText _fine_adjust_combo;
1009 ComboBoxText _push_points_combo;
1010 ComboBoxText _note_size_relative_combo;
1011 Adjustment _delete_button_adjustment;
1012 SpinButton _delete_button_spin;
1013 Adjustment _edit_button_adjustment;
1014 SpinButton _edit_button_spin;
1015 Adjustment _insert_note_button_adjustment;
1016 SpinButton _insert_note_button_spin;
1020 class FontScalingOptions : public OptionEditorBox
1023 FontScalingOptions () :
1024 _dpi_adjustment (100, 50, 250, 1, 5),
1025 _dpi_slider (_dpi_adjustment)
1027 _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.);
1029 Label* l = manage (new Label (_("GUI and Font scaling:")));
1030 l->set_name ("OptionsLabel");
1032 const std::string dflt = _("Default");
1033 const std::string empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
1035 _dpi_slider.set_name("FontScaleSlider");
1036 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1037 _dpi_slider.set_draw_value(false);
1038 _dpi_slider.add_mark(50, Gtk::POS_TOP, empty);
1039 _dpi_slider.add_mark(60, Gtk::POS_TOP, empty);
1040 _dpi_slider.add_mark(70, Gtk::POS_TOP, empty);
1041 _dpi_slider.add_mark(80, Gtk::POS_TOP, empty);
1042 _dpi_slider.add_mark(90, Gtk::POS_TOP, empty);
1043 _dpi_slider.add_mark(100, Gtk::POS_TOP, dflt);
1044 _dpi_slider.add_mark(125, Gtk::POS_TOP, empty);
1045 _dpi_slider.add_mark(150, Gtk::POS_TOP, empty);
1046 _dpi_slider.add_mark(175, Gtk::POS_TOP, empty);
1047 _dpi_slider.add_mark(200, Gtk::POS_TOP, empty);
1048 _dpi_slider.add_mark(225, Gtk::POS_TOP, empty);
1049 _dpi_slider.add_mark(250, Gtk::POS_TOP, empty);
1051 HBox* h = manage (new HBox);
1053 h->pack_start (*l, false, false);
1054 h->pack_start (_dpi_slider, true, true);
1056 _box->pack_start (*h, false, false);
1058 set_note (_("Adjusting the scale requires an application restart to re-layout."));
1060 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
1063 void parameter_changed (string const & p)
1065 if (p == "font-scale") {
1066 _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.);
1070 void set_state_from_config ()
1072 parameter_changed ("font-scale");
1079 UIConfiguration::instance().set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024.));
1080 /* XXX: should be triggered from the parameter changed signal */
1081 UIConfiguration::instance().reset_dpi ();
1084 Adjustment _dpi_adjustment;
1088 class VstTimeOutSliderOption : public OptionEditorBox
1091 VstTimeOutSliderOption (RCConfiguration* c)
1093 , _timeout_adjustment (0, 0, 3000, 50, 50)
1094 , _timeout_slider (_timeout_adjustment)
1096 _timeout_slider.set_digits (0);
1097 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &VstTimeOutSliderOption::timeout_changed));
1099 _timeout_slider.set_draw_value(false);
1100 _timeout_slider.add_mark( 0, Gtk::POS_TOP, _("\u221e")); // infinity
1101 _timeout_slider.add_mark( 300, Gtk::POS_TOP, _("30 sec"));
1102 _timeout_slider.add_mark( 600, Gtk::POS_TOP, _("1 min"));
1103 _timeout_slider.add_mark(1200, Gtk::POS_TOP, _("2 mins"));
1104 _timeout_slider.add_mark(1800, Gtk::POS_TOP, _("3 mins"));
1105 _timeout_slider.add_mark(2400, Gtk::POS_TOP, _("4 mins"));
1106 _timeout_slider.add_mark(3000, Gtk::POS_TOP, _("5 mins"));
1108 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1109 _("Specify the default timeout for plugin instantiation. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1111 Label* l = manage (left_aligned_label (_("Scan Time Out:")));
1112 HBox* h = manage (new HBox);
1114 h->pack_start (*l, false, false);
1115 h->pack_start (_timeout_slider, true, true);
1117 _box->pack_start (*h, false, false);
1120 void parameter_changed (string const & p)
1122 if (p == "vst-scan-timeout") {
1123 int const x = _rc_config->get_vst_scan_timeout();
1124 _timeout_adjustment.set_value (x);
1128 void set_state_from_config ()
1130 parameter_changed ("vst-scan-timeout");
1135 void timeout_changed ()
1137 int x = floor(_timeout_adjustment.get_value());
1138 _rc_config->set_vst_scan_timeout(x);
1141 RCConfiguration* _rc_config;
1142 Adjustment _timeout_adjustment;
1143 HScale _timeout_slider;
1150 class ClipLevelOptions : public OptionEditorBox
1154 : _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1155 , _clip_level_slider (_clip_level_adjustment)
1157 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level ());
1159 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
1160 l->set_name ("OptionsLabel");
1162 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1163 HBox* h = manage (new HBox);
1165 h->pack_start (*l, false, false);
1166 h->pack_start (_clip_level_slider, true, true);
1168 _box->pack_start (*h, false, false);
1170 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1173 void parameter_changed (string const & p)
1175 if (p == "waveform-clip-level") {
1176 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level());
1180 void set_state_from_config ()
1182 parameter_changed ("waveform-clip-level");
1187 void clip_level_changed ()
1189 UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value());
1190 /* XXX: should be triggered from the parameter changed signal */
1191 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1194 Adjustment _clip_level_adjustment;
1195 HScale _clip_level_slider;
1198 class BufferingOptions : public OptionEditorBox
1201 BufferingOptions (RCConfiguration* c)
1203 , _playback_adjustment (5, 1, 60, 1, 4)
1204 , _capture_adjustment (5, 1, 60, 1, 4)
1205 , _playback_slider (_playback_adjustment)
1206 , _capture_slider (_capture_adjustment)
1208 vector<string> presets;
1210 /* these must match the order of the enums for BufferingPreset */
1212 presets.push_back (_("Small sessions (4-16 tracks)"));
1213 presets.push_back (_("Medium sessions (16-64 tracks)"));
1214 presets.push_back (_("Large sessions (64+ tracks)"));
1215 presets.push_back (_("Custom (set by sliders below)"));
1217 set_popdown_strings (_buffering_presets_combo, presets);
1219 Label* l = manage (new Label (_("Preset:")));
1220 l->set_name ("OptionsLabel");
1221 HBox* h = manage (new HBox);
1222 h->set_spacing (12);
1223 h->pack_start (*l, false, false);
1224 h->pack_start (_buffering_presets_combo, true, true);
1225 _box->pack_start (*h, false, false);
1227 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1229 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1231 l = manage (new Label (_("Playback (seconds of buffering):")));
1232 l->set_name ("OptionsLabel");
1234 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1235 h = manage (new HBox);
1237 h->pack_start (*l, false, false);
1238 h->pack_start (_playback_slider, true, true);
1240 _box->pack_start (*h, false, false);
1242 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1244 l = manage (new Label (_("Recording (seconds of buffering):")));
1245 l->set_name ("OptionsLabel");
1247 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1248 h = manage (new HBox);
1250 h->pack_start (*l, false, false);
1251 h->pack_start (_capture_slider, true, true);
1253 _box->pack_start (*h, false, false);
1255 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
1256 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
1259 void parameter_changed (string const & p)
1261 if (p == "buffering-preset") {
1262 switch (_rc_config->get_buffering_preset()) {
1264 _playback_slider.set_sensitive (false);
1265 _capture_slider.set_sensitive (false);
1266 _buffering_presets_combo.set_active (0);
1269 _playback_slider.set_sensitive (false);
1270 _capture_slider.set_sensitive (false);
1271 _buffering_presets_combo.set_active (1);
1274 _playback_slider.set_sensitive (false);
1275 _capture_slider.set_sensitive (false);
1276 _buffering_presets_combo.set_active (2);
1279 _playback_slider.set_sensitive (true);
1280 _capture_slider.set_sensitive (true);
1281 _buffering_presets_combo.set_active (3);
1286 if (p == "playback-buffer-seconds") {
1287 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1288 } else if (p == "capture-buffer-seconds") {
1289 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1293 void set_state_from_config ()
1295 parameter_changed ("buffering-preset");
1296 parameter_changed ("playback-buffer-seconds");
1297 parameter_changed ("capture-buffer-seconds");
1302 void preset_changed ()
1304 int index = _buffering_presets_combo.get_active_row_number ();
1310 _rc_config->set_buffering_preset (Small);
1313 _rc_config->set_buffering_preset (Medium);
1316 _rc_config->set_buffering_preset (Large);
1319 _rc_config->set_buffering_preset (Custom);
1322 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1327 void playback_changed ()
1329 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
1332 void capture_changed ()
1334 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
1337 RCConfiguration* _rc_config;
1338 Adjustment _playback_adjustment;
1339 Adjustment _capture_adjustment;
1340 HScale _playback_slider;
1341 HScale _capture_slider;
1342 ComboBoxText _buffering_presets_combo;
1345 class ControlSurfacesOptions : public OptionEditorBox
1348 ControlSurfacesOptions ()
1349 : _ignore_view_change (0)
1351 _store = ListStore::create (_model);
1352 _view.set_model (_store);
1353 _view.append_column (_("Control Surface Protocol"), _model.name);
1354 _view.get_column(0)->set_resizable (true);
1355 _view.get_column(0)->set_expand (true);
1356 _view.append_column_editable (_("Enabled"), _model.enabled);
1357 _view.append_column_editable (_("Feedback"), _model.feedback);
1359 _box->pack_start (_view, false, false);
1361 Gtk::HBox* edit_box = manage (new Gtk::HBox);
1362 edit_box->set_spacing(3);
1363 _box->pack_start (*edit_box, false, false);
1366 Label* label = manage (new Label);
1367 label->set_text (_("Click to edit the settings for selected protocol ( it must be ENABLED first ):"));
1368 edit_box->pack_start (*label, false, false);
1371 edit_button = manage (new Button(_("Show Protocol Settings")));
1372 edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
1373 edit_box->pack_start (*edit_button, true, true);
1374 edit_button->set_sensitive (false);
1375 edit_button->show ();
1377 ControlProtocolManager& m = ControlProtocolManager::instance ();
1378 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1379 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1381 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1382 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1383 _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
1386 void parameter_changed (std::string const &)
1391 void set_state_from_config ()
1395 ControlProtocolManager& m = ControlProtocolManager::instance ();
1396 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1398 if (!(*i)->mandatory) {
1399 TreeModel::Row r = *_store->append ();
1400 r[_model.name] = (*i)->name;
1401 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1402 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
1403 r[_model.protocol_info] = *i;
1410 void protocol_status_changed (ControlProtocolInfo* cpi) {
1412 TreeModel::Children rows = _store->children();
1414 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1415 string n = ((*x)[_model.name]);
1417 if ((*x)[_model.protocol_info] == cpi) {
1418 _ignore_view_change++;
1419 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1420 _ignore_view_change--;
1426 void selection_changed ()
1428 //enable the Edit button when a row is selected for editing
1429 TreeModel::Row row = *(_view.get_selection()->get_selected());
1430 if (row && row[_model.enabled])
1431 edit_button->set_sensitive (true);
1433 edit_button->set_sensitive (false);
1436 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1438 TreeModel::Row r = *i;
1440 if (_ignore_view_change) {
1444 ControlProtocolInfo* cpi = r[_model.protocol_info];
1449 bool const was_enabled = (cpi->protocol != 0);
1450 bool const is_enabled = r[_model.enabled];
1453 if (was_enabled != is_enabled) {
1456 ControlProtocolManager::instance().activate (*cpi);
1458 ControlProtocolManager::instance().deactivate (*cpi);
1462 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
1463 bool const is_feedback = r[_model.feedback];
1465 if (was_feedback != is_feedback && cpi->protocol) {
1466 cpi->protocol->set_feedback (is_feedback);
1470 void edit_btn_clicked ()
1473 ControlProtocolInfo* cpi;
1476 row = *(_view.get_selection()->get_selected());
1477 if (!row[_model.enabled]) {
1480 cpi = row[_model.protocol_info];
1481 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1484 Box* box = (Box*) cpi->protocol->get_gui ();
1488 if (box->get_parent()) {
1489 static_cast<ArdourWindow*>(box->get_parent())->present();
1492 WindowTitle title (Glib::get_application_name());
1493 title += row[_model.name];
1494 title += _("Configuration");
1495 /* once created, the window is managed by the surface itself (as ->get_parent())
1496 * Surface's tear_down_gui() is called on session close, when de-activating
1497 * or re-initializing a surface.
1498 * tear_down_gui() hides an deletes the Window if it exists.
1500 ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string());
1501 win->set_title ("Control Protocol Options");
1507 void edit_clicked (GdkEventButton* ev)
1509 if (ev->type != GDK_2BUTTON_PRESS) {
1516 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1520 ControlSurfacesModelColumns ()
1525 add (protocol_info);
1528 TreeModelColumn<string> name;
1529 TreeModelColumn<bool> enabled;
1530 TreeModelColumn<bool> feedback;
1531 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1534 Glib::RefPtr<ListStore> _store;
1535 ControlSurfacesModelColumns _model;
1537 PBD::ScopedConnection protocol_status_connection;
1538 uint32_t _ignore_view_change;
1539 Gtk::Button* edit_button;
1542 class VideoTimelineOptions : public OptionEditorBox
1545 VideoTimelineOptions (RCConfiguration* c)
1547 , _show_video_export_info_button (_("Show Video Export Info before export"))
1548 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1549 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1550 , _xjadeo_browse_button (_("Browse..."))
1552 Table* t = manage (new Table (8, 4));
1553 t->set_spacings (4);
1555 std::stringstream s;
1556 s << "<b>" << _("Video Server") << "</b>";
1557 Label* l = manage (new Label (s.str()));
1558 l->set_use_markup (true);
1559 l->set_alignment (0, 0.5);
1560 t->attach (*l, 0, 4, 0, 1, EXPAND | FILL, FILL | EXPAND, 0, 8);
1562 t->attach (_video_advanced_setup_button, 1, 4, 1, 2);
1563 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1564 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1565 _("<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."));
1567 l = manage (new Label (_("Video Server URL:")));
1568 l->set_alignment (0, 0.5);
1569 t->attach (*l, 1, 2, 2, 3, FILL);
1570 t->attach (_video_server_url_entry, 2, 4, 2, 3, FILL);
1571 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1572 _("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"));
1574 l = manage (new Label (_("Video Folder:")));
1575 l->set_alignment (0, 0.5);
1576 t->attach (*l, 1, 2, 3, 4, FILL);
1577 t->attach (_video_server_docroot_entry, 2, 4, 3, 4);
1578 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1579 _("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."));
1581 t->attach (_show_video_export_info_button, 1, 4, 4, 5);
1582 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1583 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1584 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1586 t->attach (_show_video_server_dialog_button, 1, 4, 5, 6);
1587 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1588 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1589 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1591 s.str (std::string ());
1592 s << "<b>" << _("Video Monitor") << "</b>";
1593 l = manage (new Label (s.str()));
1594 l->set_use_markup (true);
1595 l->set_alignment (0, 0.5);
1596 t->attach (*l, 0, 4, 6, 7, EXPAND | FILL, FILL | EXPAND, 0, 8);
1598 l = manage (new Label (string_compose (_("Custom Path to Video Monitor (%1) - leave empty for default:"),
1601 #elif defined PLATFORM_WINDOWS
1607 l->set_alignment (0, 0.5);
1608 t->attach (*l, 1, 4, 7, 8, FILL);
1609 t->attach (_custom_xjadeo_path, 2, 3, 8, 9);
1610 Gtkmm2ext::UI::instance()->set_tip (_custom_xjadeo_path, _("Set a custom path to the Video Monitor Executable, changing this requires a restart."));
1611 t->attach (_xjadeo_browse_button, 3, 4, 8, 9, FILL);
1613 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1614 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1615 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1616 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1617 _custom_xjadeo_path.signal_changed().connect (sigc::mem_fun (*this, &VideoTimelineOptions::custom_xjadeo_path_changed));
1618 _xjadeo_browse_button.signal_clicked ().connect (sigc::mem_fun (*this, &VideoTimelineOptions::xjadeo_browse_clicked));
1620 // xjadeo-path is a UIConfig parameter
1621 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &VideoTimelineOptions::parameter_changed));
1623 _box->pack_start (*t,true,true);
1626 void server_url_changed ()
1628 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1631 void server_docroot_changed ()
1633 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1636 void show_video_export_info_toggled ()
1638 bool const x = _show_video_export_info_button.get_active ();
1639 _rc_config->set_show_video_export_info (x);
1642 void show_video_server_dialog_toggled ()
1644 bool const x = _show_video_server_dialog_button.get_active ();
1645 _rc_config->set_show_video_server_dialog (x);
1648 void video_advanced_setup_toggled ()
1650 bool const x = _video_advanced_setup_button.get_active ();
1651 _rc_config->set_video_advanced_setup(x);
1654 void custom_xjadeo_path_changed ()
1656 UIConfiguration::instance().set_xjadeo_binary (_custom_xjadeo_path.get_text());
1659 void xjadeo_browse_clicked ()
1661 Gtk::FileChooserDialog dialog(_("Set Video Monitor Executable"), Gtk::FILE_CHOOSER_ACTION_OPEN);
1662 dialog.set_filename (UIConfiguration::instance().get_xjadeo_binary());
1663 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1664 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1665 if (dialog.run () == Gtk::RESPONSE_OK) {
1666 const std::string& filename = dialog.get_filename();
1667 if (!filename.empty() && (
1669 Glib::file_test (filename + "/Contents/MacOS/xjadeo", Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) ||
1671 Glib::file_test (filename, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)
1673 UIConfiguration::instance().set_xjadeo_binary (filename);
1678 void parameter_changed (string const & p)
1680 if (p == "video-server-url") {
1681 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1682 } else if (p == "video-server-docroot") {
1683 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1684 } else if (p == "show-video-export-info") {
1685 bool const x = _rc_config->get_show_video_export_info();
1686 _show_video_export_info_button.set_active (x);
1687 } else if (p == "show-video-server-dialog") {
1688 bool const x = _rc_config->get_show_video_server_dialog();
1689 _show_video_server_dialog_button.set_active (x);
1690 } else if (p == "video-advanced-setup") {
1691 bool const x = _rc_config->get_video_advanced_setup();
1692 _video_advanced_setup_button.set_active(x);
1693 _video_server_docroot_entry.set_sensitive(x);
1694 _video_server_url_entry.set_sensitive(x);
1695 } else if (p == "xjadeo-binary") {
1696 _custom_xjadeo_path.set_text (UIConfiguration::instance().get_xjadeo_binary());
1700 void set_state_from_config ()
1702 parameter_changed ("video-server-url");
1703 parameter_changed ("video-server-docroot");
1704 parameter_changed ("video-monitor-setup-dialog");
1705 parameter_changed ("show-video-export-info");
1706 parameter_changed ("show-video-server-dialog");
1707 parameter_changed ("video-advanced-setup");
1708 parameter_changed ("xjadeo-binary");
1712 RCConfiguration* _rc_config;
1713 Entry _video_server_url_entry;
1714 Entry _video_server_docroot_entry;
1715 Entry _custom_xjadeo_path;
1716 CheckButton _show_video_export_info_button;
1717 CheckButton _show_video_server_dialog_button;
1718 CheckButton _video_advanced_setup_button;
1719 Button _xjadeo_browse_button;
1722 class ColumVisibilityOption : public Option
1725 ColumVisibilityOption (string id, string name, uint32_t n_col, sigc::slot<uint32_t> get, sigc::slot<bool, uint32_t> set)
1732 cb = (CheckButton**) malloc (sizeof (CheckButton*) * n_col);
1733 for (uint32_t i = 0; i < n_col; ++i) {
1734 CheckButton* col = manage (new CheckButton (string_compose (_("Column %1"), i + 1)));
1735 col->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &ColumVisibilityOption::column_toggled), i));
1736 _hbox.pack_start (*col);
1739 parameter_changed (id);
1742 ~ColumVisibilityOption () {
1746 Gtk::Widget& tip_widget() { return _hbox; }
1748 void set_state_from_config ()
1750 uint32_t c = _get();
1751 for (uint32_t i = 0; i < _n_col; ++i) {
1752 bool en = (c & (1<<i)) ? true : false;
1753 if (cb[i]->get_active () != en) {
1754 cb[i]->set_active (en);
1759 void add_to_page (OptionEditorPage* p)
1761 _heading.add_to_page (p);
1762 add_widget_to_page (p, &_hbox);
1766 void column_toggled (int b) {
1767 uint32_t c = _get();
1769 if (cb[b]->get_active ()) {
1780 OptionEditorHeading _heading;
1784 sigc::slot<uint32_t> _get;
1785 sigc::slot<bool, uint32_t> _set;
1789 /** A class which allows control of visibility of some editor components usign
1790 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1791 * which has the correct members, but with null widget pointers. This
1792 * class allows the user to set visibility of the members, the details
1793 * of which are stored in a configuration variable which can be watched
1794 * by parts of the editor that actually contain the widgets whose visibility
1795 * is being controlled.
1798 class VisibilityOption : public Option
1801 /** @param name User-visible name for this group.
1802 * @param g `Dummy' VisibilityGroup (as described above).
1803 * @param get Method to get the value of the appropriate configuration variable.
1804 * @param set Method to set the value of the appropriate configuration variable.
1806 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1807 : Option (g->get_state_name(), name)
1809 , _visibility_group (g)
1813 /* Watch for changes made by the user to our members */
1814 _visibility_group->VisibilityChanged.connect_same_thread (
1815 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1819 void set_state_from_config ()
1821 /* Set our state from the current configuration */
1822 _visibility_group->set_state (_get ());
1825 void add_to_page (OptionEditorPage* p)
1827 _heading.add_to_page (p);
1828 add_widget_to_page (p, _visibility_group->list_view ());
1831 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1836 /* The user has changed something, so reflect this change
1837 in the RCConfiguration.
1839 _set (_visibility_group->get_state_value ());
1842 OptionEditorHeading _heading;
1843 VisibilityGroup* _visibility_group;
1844 sigc::slot<std::string> _get;
1845 sigc::slot<bool, std::string> _set;
1846 PBD::ScopedConnection _visibility_group_connection;
1851 RCOptionEditor::RCOptionEditor ()
1852 : OptionEditorContainer (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1853 , Tabbable (*this, _("Preferences")) /* pack self-as-vbox into tabbable */
1854 , _rc_config (Config)
1855 , _mixer_strip_visibility ("mixer-element-visibility")
1857 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
1859 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
1860 (Gtk::StateType) here !!!
1862 Tabbable::set_state (*node, Stateful::loading_state_version);
1865 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed));
1869 uint32_t hwcpus = hardware_concurrency ();
1871 BoolComboOption* bco;
1874 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1876 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1878 _("Signal processing uses"),
1879 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1880 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1883 procs->add (-1, _("all but one processor"));
1884 procs->add (0, _("all available processors"));
1886 for (uint32_t i = 1; i <= hwcpus; ++i) {
1887 procs->add (i, string_compose (_("%1 processors"), i));
1890 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1892 add_option (_("Misc"), procs);
1895 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1897 add_option (_("Misc"), new UndoOptions (_rc_config));
1899 add_option (_("Misc"),
1901 "verify-remove-last-capture",
1902 _("Verify removal of last capture"),
1903 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1904 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1907 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1909 add_option (_("Misc"),
1911 "periodic-safety-backups",
1912 _("Make periodic backups of the session file"),
1913 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1914 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1917 add_option (_("Misc"),
1919 "only-copy-imported-files",
1920 _("Always copy imported files"),
1921 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
1922 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
1925 add_option (_("Misc"), new DirectoryOption (
1926 X_("default-session-parent-dir"),
1927 _("Default folder for new sessions:"),
1928 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1929 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1932 add_option (_("Misc"),
1933 new SpinOption<uint32_t> (
1934 "max-recent-sessions",
1935 _("Maximum number of recent sessions"),
1936 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1937 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1941 add_option (_("Misc/Click"), new OptionEditorHeading (_("Click")));
1943 add_option (_("Misc/Click"), new ClickOptions (_rc_config));
1945 add_option (_("Misc/Click"),
1948 _("Click gain level"),
1949 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1950 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1953 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1955 add_option (_("Misc"),
1956 new SpinOption<double> (
1957 "automation-thinning-factor",
1958 _("Thinning factor (larger value => less data)"),
1959 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1960 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1964 add_option (_("Misc"),
1965 new SpinOption<double> (
1966 "automation-interval-msecs",
1967 _("Automation sampling interval (milliseconds)"),
1968 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1969 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1975 add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options")));
1979 tsf = new BoolOption (
1980 "latched-record-enable",
1981 _("Keep record-enable engaged on stop"),
1982 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1983 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1985 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1986 add_option (_("Transport"), tsf);
1988 tsf = new BoolOption (
1990 _("Play loop is a transport mode"),
1991 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1992 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1994 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1995 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1996 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1997 add_option (_("Transport"), tsf);
1999 tsf = new BoolOption (
2000 "stop-recording-on-xrun",
2001 _("Stop recording when an xrun occurs"),
2002 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
2003 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
2005 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2006 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
2008 add_option (_("Transport"), tsf);
2010 tsf = new BoolOption (
2011 "create-xrun-marker",
2012 _("Create markers where xruns occur"),
2013 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
2014 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
2016 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
2017 add_option (_("Transport"), tsf);
2019 tsf = new BoolOption (
2020 "stop-at-session-end",
2021 _("Stop at the end of the session"),
2022 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
2023 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
2025 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2026 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
2027 "when it reaches the current session end marker\n\n"
2028 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
2030 add_option (_("Transport"), tsf);
2032 tsf = new BoolOption (
2034 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
2035 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
2036 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
2038 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2039 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
2040 "preventing any need to do a transport locate at the end of the loop\n\n"
2041 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
2042 "which will often cause a small click or delay"), PROGRAM_NAME));
2043 add_option (_("Transport"), tsf);
2045 tsf = new BoolOption (
2046 "disable-disarm-during-roll",
2047 _("Disable per-track record disarm while rolling"),
2048 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
2049 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
2051 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"));
2052 add_option (_("Transport"), tsf);
2054 tsf = new BoolOption (
2056 _("12dB gain reduction during fast-forward and fast-rewind"),
2057 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
2058 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
2060 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
2061 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
2062 add_option (_("Transport"), tsf);
2064 ComboOption<float>* psc = new ComboOption<float> (
2067 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
2068 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
2070 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
2071 (_("The amount of preroll (in seconds) to apply when <b>Play with Preroll</b> is initiated.\n\n"
2072 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
2073 psc->add (0.0, _("0 (no pre-roll)"));
2074 psc->add (0.1, _("0.1 second"));
2075 psc->add (0.25, _("0.25 second"));
2076 psc->add (0.5, _("0.5 second"));
2077 psc->add (1.0, _("1.0 second"));
2078 psc->add (2.0, _("2.0 seconds"));
2079 add_option (_("Transport"), psc);
2081 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("Synchronization and Slave Options")));
2083 _sync_source = new ComboOption<SyncSource> (
2085 _("External timecode source"),
2086 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
2087 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
2090 add_option (_("Transport/Sync"), _sync_source);
2092 _sync_framerate = new BoolOption (
2093 "timecode-sync-frame-rate",
2094 _("Match session video frame rate to external timecode"),
2095 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
2096 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
2098 Gtkmm2ext::UI::instance()->set_tip
2099 (_sync_framerate->tip_widget(),
2100 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
2101 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
2102 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
2103 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
2104 "timecode standard and the session standard."), PROGRAM_NAME));
2106 add_option (_("Transport/Sync"), _sync_framerate);
2108 _sync_genlock = new BoolOption (
2109 "timecode-source-is-synced",
2110 _("Sync-lock timecode to clock (disable drift compensation)"),
2111 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
2112 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
2114 Gtkmm2ext::UI::instance()->set_tip
2115 (_sync_genlock->tip_widget(),
2116 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
2117 "Sync Lock indicates that the selected external timecode source shares clock-sync "
2118 "(Black & Burst, Wordclock, etc) with the audio interface. "
2119 "This option disables drift compensation. The transport speed is fixed at 1.0. "
2120 "Vari-speed LTC will be ignored and cause drift."
2122 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
2123 "timecode sources shares clock sync."
2127 add_option (_("Transport/Sync"), _sync_genlock);
2129 _sync_source_2997 = new BoolOption (
2130 "timecode-source-2997",
2131 _("Lock to 29.9700 fps instead of 30000/1001"),
2132 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
2133 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
2135 Gtkmm2ext::UI::instance()->set_tip
2136 (_sync_source_2997->tip_widget(),
2137 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
2138 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
2139 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
2140 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
2141 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
2142 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
2145 add_option (_("Transport/Sync"), _sync_source_2997);
2147 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("LTC Reader")));
2149 _ltc_port = new ComboStringOption (
2151 _("LTC incoming port"),
2152 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
2153 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
2156 vector<string> physical_inputs;
2157 physical_inputs.push_back (_("None"));
2158 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
2159 _ltc_port->set_popdown_strings (physical_inputs);
2161 populate_sync_options ();
2162 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
2164 add_option (_("Transport/Sync"), _ltc_port);
2166 // TODO; rather disable this button than not compile it..
2167 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("LTC Generator")));
2169 add_option (_("Transport/Sync"),
2172 _("Enable LTC generator"),
2173 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
2174 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
2177 _ltc_send_continuously = new BoolOption (
2178 "ltc-send-continuously",
2179 _("Send LTC while stopped"),
2180 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
2181 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
2183 Gtkmm2ext::UI::instance()->set_tip
2184 (_ltc_send_continuously->tip_widget(),
2185 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
2186 add_option (_("Transport"), _ltc_send_continuously);
2188 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
2189 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
2190 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
2191 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
2193 Gtkmm2ext::UI::instance()->set_tip
2194 (_ltc_volume_slider->tip_widget(),
2195 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
2197 add_option (_("Transport/Sync"), _ltc_volume_slider);
2201 add_option (_("Editor"),
2203 "rubberbanding-snaps-to-grid",
2204 _("Make rubberband selection rectangle snap to the grid"),
2205 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2206 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2209 bo = new BoolOption (
2211 _("Name new markers"),
2212 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2213 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2215 add_option (_("Editor"), bo);
2216 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."
2217 "\n\nYou can always rename markers by right-clicking on them"));
2219 add_option (S_("Editor"),
2221 "draggable-playhead",
2222 _("Allow dragging of playhead"),
2223 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2224 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2227 add_option (_("Editor"),
2229 "show-editor-meter",
2230 _("Display master-meter in the toolbar"),
2231 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
2232 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
2235 if (!Profile->get_mixbus()) {
2236 add_option (_("Editor"),
2239 _("Show zoom toolbar (if torn off)"),
2240 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_zoom_tools),
2241 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_zoom_tools)
2244 add_option (_("Editor"),
2246 "use-mouse-position-as-zoom-focus-on-scroll",
2247 _("Always use mouse cursor position as zoom focus when zooming using mouse scroll wheel"),
2248 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2249 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2253 add_option (_("Editor"),
2255 "update-editor-during-summary-drag",
2256 _("Update editor window during drags of the summary"),
2257 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2258 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2261 add_option (_("Editor"),
2263 "autoscroll-editor",
2264 _("Auto-scroll editor window when dragging near its edges"),
2265 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2266 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2269 add_option (_("Editor"),
2270 new BoolComboOption (
2271 "show-region-gain-envelopes",
2272 _("Show gain envelopes in audio regions"),
2274 _("only in Draw and Internal Edit modes"),
2275 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2276 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2279 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2281 add_option (_("Editor"),
2283 "automation-follows-regions",
2284 _("Move relevant automation when audio regions are moved"),
2285 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2286 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2289 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2290 "default-fade-shape",
2291 _("Default fade shape"),
2292 sigc::mem_fun (*_rc_config,
2293 &RCConfiguration::get_default_fade_shape),
2294 sigc::mem_fun (*_rc_config,
2295 &RCConfiguration::set_default_fade_shape)
2298 fadeshape->add (FadeLinear,
2299 _("Linear (for highly correlated material)"));
2300 fadeshape->add (FadeConstantPower, _("Constant power"));
2301 fadeshape->add (FadeSymmetric, _("Symmetric"));
2302 fadeshape->add (FadeSlow, _("Slow"));
2303 fadeshape->add (FadeFast, _("Fast"));
2305 add_option (_("Editor"), fadeshape);
2308 bco = new BoolComboOption (
2309 "use-overlap-equivalency",
2310 _("Regions in active edit groups are edited together"),
2311 _("whenever they overlap in time"),
2312 _("only if they have identical length, position and origin"),
2313 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2314 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2317 add_option (_("Editor"), bco);
2319 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2321 _("Layering model"),
2322 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2323 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2326 lm->add (LaterHigher, _("later is higher"));
2327 lm->add (Manual, _("manual layering"));
2328 add_option (_("Editor"), lm);
2330 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2331 "region-selection-after-split",
2332 _("After splitting selected regions, select"),
2333 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2334 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2336 // TODO: decide which of these modes are really useful
2337 rsas->add(None, _("no regions"));
2338 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2339 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2340 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2341 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2342 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2343 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2344 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2346 add_option (_("Editor"), rsas);
2348 add_option (_("Editor/Waveforms"), new OptionEditorHeading (_("Waveforms")));
2350 if (!Profile->get_mixbus()) {
2351 add_option (_("Editor/Waveforms"),
2354 _("Show waveforms in regions"),
2355 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
2356 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
2360 add_option (_("Editor/Waveforms"),
2362 "show-waveforms-while-recording",
2363 _("Show waveforms for audio while it is being recorded"),
2364 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
2365 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
2368 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
2370 _("Waveform scale"),
2371 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
2372 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
2375 wfs->add (Linear, _("linear"));
2376 wfs->add (Logarithmic, _("logarithmic"));
2378 add_option (_("Editor/Waveforms"), wfs);
2380 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
2382 _("Waveform shape"),
2383 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
2384 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
2387 wfsh->add (Traditional, _("traditional"));
2388 wfsh->add (Rectified, _("rectified"));
2390 add_option (_("Editor/Waveforms"), wfsh);
2392 add_option (_("Editor/Waveforms"), new ClipLevelOptions ());
2397 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2399 add_option (_("Audio"), new BufferingOptions (_rc_config));
2401 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2403 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2405 _("Record monitoring handled by"),
2406 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2407 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2410 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2411 mm->add (HardwareMonitoring, _("via Audio Driver"));
2414 string prog (PROGRAM_NAME);
2415 boost::algorithm::to_lower (prog);
2416 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2417 mm->add (ExternalMonitoring, _("audio hardware"));
2419 add_option (_("Audio"), mm);
2421 add_option (_("Audio"),
2423 "tape-machine-mode",
2424 _("Tape machine mode"),
2425 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2426 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2429 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
2430 if (!Profile->get_mixbus()) {
2432 add_option (_("Audio"),
2434 "auto-connect-standard-busses",
2435 _("Auto-connect master/monitor busses"),
2436 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2437 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2440 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2441 "input-auto-connect",
2442 _("Connect track inputs"),
2443 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2444 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2447 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2448 iac->add (ManualConnect, _("manually"));
2450 add_option (_("Audio"), iac);
2452 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2453 "output-auto-connect",
2454 _("Connect track and bus outputs"),
2455 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2456 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2459 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2460 oac->add (AutoConnectMaster, _("automatically to master bus"));
2461 oac->add (ManualConnect, _("manually"));
2463 add_option (_("Audio"), oac);
2465 bo = new BoolOption (
2467 _("Use 'Strict-I/O' for new tracks or Busses"),
2468 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2469 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2472 add_option (_("Audio"), bo);
2473 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2474 _("With strict-i/o enabled, Effect Processors will not modify the number of channels on a track. The number of output channels will always match the number of input channels."));
2478 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2480 add_option (_("Audio"),
2482 "denormal-protection",
2483 _("Use DC bias to protect against denormals"),
2484 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2485 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2488 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2490 _("Processor handling"),
2491 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2492 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2496 dm->add (DenormalNone, _("no processor handling"));
2498 FPU* fpu = FPU::instance();
2500 if (fpu->has_flush_to_zero()) {
2502 dm->add (DenormalFTZ, _("use FlushToZero"));
2503 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2504 _rc_config->set_denormal_model(DenormalNone);
2507 if (fpu->has_denormals_are_zero()) {
2509 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2510 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2511 _rc_config->set_denormal_model(DenormalNone);
2514 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2516 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2517 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2518 _rc_config->set_denormal_model(DenormalNone);
2522 dm->set_sensitive(false);
2525 add_option (_("Audio"), dm);
2527 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2529 add_option (_("Audio"),
2531 "auto-analyse-audio",
2532 _("Enable automatic analysis of audio"),
2533 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2534 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2537 add_option (_("Audio"),
2539 "replicate-missing-region-channels",
2540 _("Replicate missing region channels"),
2541 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2542 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2547 add_option (_("Solo & mute"), new OptionEditorHeading (_("Solo")));
2549 _solo_control_is_listen_control = new BoolOption (
2550 "solo-control-is-listen-control",
2551 _("Solo controls are Listen controls"),
2552 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2553 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2556 add_option (_("Solo & mute"), _solo_control_is_listen_control);
2558 add_option (_("Solo & mute"),
2561 _("Exclusive solo"),
2562 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2563 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2566 add_option (_("Solo & mute"),
2569 _("Show solo muting"),
2570 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2571 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2574 add_option (_("Solo & mute"),
2576 "solo-mute-override",
2577 _("Soloing overrides muting"),
2578 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2579 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2582 add_option (_("Solo & mute"),
2585 _("Solo-in-place mute cut (dB)"),
2586 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2587 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2590 _listen_position = new ComboOption<ListenPosition> (
2592 _("Listen Position"),
2593 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2594 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2597 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2598 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2600 add_option (_("Solo & mute"), _listen_position);
2602 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2604 _("PFL signals come from"),
2605 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2606 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2609 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2610 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2612 add_option (_("Solo & mute"), pp);
2614 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2616 _("AFL signals come from"),
2617 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2618 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2621 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2622 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2624 add_option (_("Solo & mute"), pa);
2626 add_option (_("Solo & mute"), new OptionEditorHeading (_("Default track / bus muting options")));
2628 add_option (_("Solo & mute"),
2630 "mute-affects-pre-fader",
2631 _("Mute affects pre-fader sends"),
2632 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2633 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2636 add_option (_("Solo & mute"),
2638 "mute-affects-post-fader",
2639 _("Mute affects post-fader sends"),
2640 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2641 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2644 add_option (_("Solo & mute"),
2646 "mute-affects-control-outs",
2647 _("Mute affects control outputs"),
2648 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2649 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2652 add_option (_("Solo & mute"),
2654 "mute-affects-main-outs",
2655 _("Mute affects main outputs"),
2656 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2657 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2661 if (!ARDOUR::Profile->get_mixbus()) {
2662 add_option (_("Solo & mute"), new OptionEditorHeading (_("Send Routing")));
2663 add_option (_("Solo & mute"),
2665 "link-send-and-route-panner",
2666 _("Link panners of Aux and External Sends with main panner by default"),
2667 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2668 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2672 add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Preferences")));
2674 add_option (_("MIDI"),
2675 new SpinOption<float> (
2677 _("MIDI read-ahead time (seconds)"),
2678 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2679 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2684 add_option (_("MIDI"),
2685 new SpinOption<int32_t> (
2686 "initial-program-change",
2687 _("Initial program change"),
2688 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2689 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2693 add_option (_("MIDI"),
2695 "display-first-midi-bank-as-zero",
2696 _("Display first MIDI bank/program as 0"),
2697 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2698 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2701 add_option (_("MIDI"),
2703 "never-display-periodic-midi",
2704 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2705 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
2706 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
2709 add_option (_("MIDI"),
2712 _("Sound MIDI notes as they are selected in the editor"),
2713 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2714 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2717 add_option (_("MIDI"),
2720 _("Send MIDI control feedback"),
2721 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2722 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2725 add_option (_("MIDI/Sync"), new OptionEditorHeading (_("MIDI Clock")));
2727 add_option (_("MIDI/Sync"),
2730 _("Send MIDI Clock"),
2731 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2732 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2735 add_option (_("MIDI/Sync"), new OptionEditorHeading (_("MIDI Time Code (MTC)")));
2737 add_option (_("MIDI/Sync"),
2740 _("Send MIDI Time Code"),
2741 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2742 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2745 add_option (_("MIDI/Sync"),
2746 new SpinOption<int> (
2747 "mtc-qf-speed-tolerance",
2748 _("Percentage either side of normal transport speed to transmit MTC"),
2749 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2750 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2754 add_option (_("MIDI/Sync"), new OptionEditorHeading (_("Midi Machine Control (MMC)")));
2756 add_option (_("MIDI/Sync"),
2759 _("Obey MIDI Machine Control commands"),
2760 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2761 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2764 add_option (_("MIDI/Sync"),
2767 _("Send MIDI Machine Control commands"),
2768 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2769 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2772 add_option (_("MIDI/Sync"),
2773 new SpinOption<uint8_t> (
2774 "mmc-receive-device-id",
2775 _("Inbound MMC device ID"),
2776 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2777 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2781 add_option (_("MIDI/Sync"),
2782 new SpinOption<uint8_t> (
2783 "mmc-send-device-id",
2784 _("Outbound MMC device ID"),
2785 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2786 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2790 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2792 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2793 "midi-audition-synth-uri",
2794 _("Midi Audition Synth (LV2)"),
2795 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2796 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2799 audition_synth->add(X_(""), _("None"));
2800 PluginInfoList all_plugs;
2801 PluginManager& manager (PluginManager::instance());
2803 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2805 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2806 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2807 if (!(*i)->is_instrument()) continue;
2808 if ((*i)->type != ARDOUR::LV2) continue;
2809 audition_synth->add((*i)->unique_id, (*i)->name);
2813 add_option (_("MIDI"), audition_synth);
2815 /* USER INTERACTION */
2818 #ifdef PLATFORM_WINDOWS
2821 getenv ("ARDOUR_BUNDLED")
2825 add_option (_("User interaction"),
2827 "enable-translation",
2828 string_compose (_("Use translations of %1 messages\n"
2829 " <i>(requires a restart of %1 to take effect)</i>\n"
2830 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2831 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2832 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2835 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2837 add_option (_("User interaction"), new KeyboardOptions);
2839 /* Control Surfaces */
2841 add_option (_("Control Surfaces"), new ControlSurfacesOptions);
2843 /* VIDEO Timeline */
2844 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2846 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2847 add_option (_("Plugins"),
2848 new RcActionButton (_("Scan for Plugins"),
2849 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
2853 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
2855 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2856 bo = new BoolOption (
2857 "show-plugin-scan-window",
2858 _("Always Display Plugin Scan Progress"),
2859 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
2860 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
2862 add_option (_("Plugins"), bo);
2863 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2864 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
2867 bo = new BoolOption (
2868 "plugins-stop-with-transport",
2869 _("Silence plugins when the transport is stopped"),
2870 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
2871 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
2873 add_option (_("Plugins"), bo);
2874 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2875 _("<b>When enabled</b> plugins will be reset at transport stop. When disabled plugins will be left unchanged at transport stop.\n\nThis mostly affects plugins with a \"tail\" like Reverbs."));
2877 bo = new BoolOption (
2878 "new-plugins-active",
2879 _("Make new plugins active"),
2880 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
2881 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
2883 add_option (_("Plugins"), bo);
2884 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2885 _("<b>When enabled</b> plugins will be activated when they are added to tracks/busses. When disabled plugins will be left inactive when they are added to tracks/busses"));
2887 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
2888 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
2889 add_option (_("Plugins/VST"),
2890 new RcActionButton (_("Scan for Plugins"),
2891 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
2893 bo = new BoolOption (
2894 "discover-vst-on-start",
2895 _("Scan for [new] VST Plugins on Application Start"),
2896 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
2897 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
2899 add_option (_("Plugins/VST"), bo);
2900 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2901 _("<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"));
2903 #ifdef WINDOWS_VST_SUPPORT
2904 // currently verbose logging is only implemented for Windows VST.
2905 bo = new BoolOption (
2906 "verbose-plugin-scan",
2907 _("Verbose Plugin Scan"),
2908 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
2909 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
2911 add_option (_("Plugins/VST"), bo);
2912 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2913 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
2916 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
2918 add_option (_("Plugins/VST"),
2919 new RcActionButton (_("Clear"),
2920 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
2923 add_option (_("Plugins/VST"),
2924 new RcActionButton (_("Clear"),
2925 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
2926 _("VST Blacklist:")));
2929 #ifdef LXVST_SUPPORT
2930 add_option (_("Plugins/VST"),
2931 new RcActionButton (_("Edit"),
2932 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
2933 _("Linux VST Path:")));
2935 add_option (_("Plugins/VST"),
2936 new RcConfigDisplay (
2937 "plugin-path-lxvst",
2939 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
2943 #ifdef WINDOWS_VST_SUPPORT
2944 add_option (_("Plugins/VST"),
2945 new RcActionButton (_("Edit"),
2946 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
2947 _("Windows VST Path:")));
2948 add_option (_("Plugins"),
2949 new RcConfigDisplay (
2952 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
2956 #ifdef AUDIOUNIT_SUPPORT
2958 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
2959 add_option (_("Plugins/Audio Unit"),
2960 new RcActionButton (_("Scan for Plugins"),
2961 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
2963 bo = new BoolOption (
2964 "discover-audio-units",
2965 _("Scan for AudioUnit Plugins on Application Start"),
2966 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
2967 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
2969 add_option (_("Plugins"), bo);
2970 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2971 _("<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."));
2973 add_option (_("Plugins/Audio Unit"),
2974 new RcActionButton (_("Clear"),
2975 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
2978 add_option (_("Plugins/Audio Unit"),
2979 new RcActionButton (_("Clear"),
2980 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
2981 _("AU Blacklist:")));
2984 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
2985 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
2986 add_option (_("Plugins"),
2988 "open-gui-after-adding-plugin",
2989 _("Automatically open the plugin GUI when adding a new plugin"),
2990 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
2991 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
2994 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
2995 add_option (_("Plugins"),
2997 "show-inline-display-by-default",
2998 _("Show Plugin Inline Display on Mixerstrip by default"),
2999 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3000 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3003 _plugin_prefer_inline = new BoolOption (
3004 "prefer-inline-over-gui",
3005 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3006 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3007 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3009 add_option (_("Plugins"), _plugin_prefer_inline);
3012 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3014 bo = new BoolOption (
3015 "ask-replace-instrument",
3016 _("Ask to replace existing instrument plugin"),
3017 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3018 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3020 add_option (_("Plugins"), bo);
3022 bo = new BoolOption (
3023 "ask-setup_instrument",
3024 _("Interactively configure instrument plugins on insert"),
3025 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3026 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3028 add_option (_("Plugins"), bo);
3029 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3030 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3036 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3037 BoolOption* bgc = new BoolOption (
3038 "cairo-image-surface",
3039 _("Disable Graphics Hardware Acceleration (requires restart)"),
3040 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3041 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3044 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3045 _("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));
3046 add_option (S_("Preferences|GUI"), bgc);
3049 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3050 BoolOption* bgo = new BoolOption (
3052 _("Possibly improve slow graphical performance (requires restart)"),
3053 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3054 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3057 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));
3058 add_option (S_("Preferences|GUI"), bgo);
3061 add_option (S_("Preferences|GUI"),
3063 "use-wm-visibility",
3064 _("Use Window Manager/Desktop visibility information"),
3065 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3066 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3069 add_option (S_("Preferences|GUI"),
3072 _("Graphically indicate mouse pointer hovering over various widgets"),
3073 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3074 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3077 add_option (S_("Preferences|GUI"),
3080 _("Show tooltips if mouse hovers over a control"),
3081 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3082 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3085 add_option (S_("Preferences|GUI"),
3087 "show-name-highlight",
3088 _("Use name highlight bars in region displays (requires a restart)"),
3089 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3090 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3093 add_option (S_("Preferences|GUI"),
3095 "super-rapid-clock-update",
3096 _("Update transport clock display at FPS instead of every 100ms"),
3097 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3098 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3103 /* font scaling does nothing with GDK/Quartz */
3104 add_option (S_("Preferences|GUI"), new FontScalingOptions ());
3107 /* Image cache size */
3109 Gtk::Adjustment *ics = manage (new Gtk::Adjustment(0, 1, 1024, 10)); /* 1 MB to 1GB in steps of 10MB */
3110 HSliderOption *sics = new HSliderOption("waveform-cache-size",
3111 _("Waveform image cache size (megabytes)"),
3113 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
3114 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size)
3116 sics->scale().set_digits (0);
3117 Gtkmm2ext::UI::instance()->set_tip
3118 (sics->tip_widget(),
3119 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
3120 add_option (S_("Preferences|GUI"), sics);
3122 if (!ARDOUR::Profile->get_mixbus()) {
3123 /* Lock GUI timeout */
3125 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
3126 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
3127 _("Lock timeout (seconds)"),
3129 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
3130 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds)
3132 slts->scale().set_digits (0);
3133 Gtkmm2ext::UI::instance()->set_tip
3134 (slts->tip_widget(),
3135 _("Lock GUI after this many idle seconds (zero to never lock)"));
3136 add_option (S_("Preferences|GUI"), slts);
3139 /* The names of these controls must be the same as those given in MixerStrip
3140 for the actual widgets being controlled.
3142 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3143 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3144 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3145 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3146 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3147 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3148 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3151 S_("Preferences|GUI"),
3152 new VisibilityOption (
3154 &_mixer_strip_visibility,
3155 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3156 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3160 add_option (S_("Preferences|GUI"),
3162 "default-narrow_ms",
3163 _("Use narrow strips in the mixer by default"),
3164 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3165 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3168 add_option (S_("Preferences|GUI"),
3169 new ColumVisibilityOption (
3170 "action-table-columns", _("Action Script Button Visibility"), 3,
3171 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3172 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3176 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
3178 ComboOption<float>* mht = new ComboOption<float> (
3180 _("Peak hold time"),
3181 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
3182 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
3185 mht->add (MeterHoldOff, _("off"));
3186 mht->add (MeterHoldShort, _("short"));
3187 mht->add (MeterHoldMedium, _("medium"));
3188 mht->add (MeterHoldLong, _("long"));
3190 add_option (S_("Preferences|Metering"), mht);
3192 ComboOption<float>* mfo = new ComboOption<float> (
3195 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
3196 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
3199 mfo->add (METER_FALLOFF_OFF, _("off"));
3200 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
3201 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
3202 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
3203 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
3204 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
3205 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
3207 add_option (S_("Preferences|Metering"), mfo);
3209 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
3210 "meter-line-up-level",
3211 _("Meter line-up level; 0dBu"),
3212 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
3213 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
3216 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3217 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3218 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3219 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3221 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."));
3223 add_option (S_("Preferences|Metering"), mlu);
3225 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
3226 "meter-line-up-din",
3227 _("IEC1/DIN Meter line-up level; 0dBu"),
3228 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
3229 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
3232 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3233 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3234 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3235 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3237 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
3239 add_option (S_("Preferences|Metering"), mld);
3241 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
3242 "meter-vu-standard",
3243 _("VU Meter standard"),
3244 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
3245 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
3248 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
3249 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
3250 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
3251 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
3253 add_option (S_("Preferences|Metering"), mvu);
3255 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
3256 HSliderOption *mpks = new HSliderOption("meter-peak",
3257 _("Peak threshold [dBFS]"),
3259 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
3260 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak)
3264 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
3265 "meter-type-master",
3266 _("Default Meter Type for Master Bus"),
3267 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
3268 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3270 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3271 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3272 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3273 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3274 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3275 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3276 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3277 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3279 add_option (S_("Preferences|Metering"), mtm);
3282 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3284 _("Default Meter Type for Busses"),
3285 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3286 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3288 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3289 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3290 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3291 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3292 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3293 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3294 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3295 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3297 add_option (S_("Preferences|Metering"), mtb);
3299 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3301 _("Default Meter Type for Tracks"),
3302 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3303 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3305 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3306 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3308 add_option (S_("Preferences|Metering"), mtt);
3311 Gtkmm2ext::UI::instance()->set_tip
3312 (mpks->tip_widget(),
3313 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
3315 add_option (S_("Preferences|Metering"), mpks);
3317 add_option (S_("Preferences|Metering"),
3320 _("LED meter style"),
3321 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3322 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3325 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Editor Meters")));
3327 add_option (S_("Preferences|Metering"),
3329 "show-track-meters",
3330 _("Show meters on tracks in the editor"),
3331 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3332 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3335 add_option (S_("Preferences|Metering"),
3337 "editor-stereo-only-meters",
3338 _("Show at most stereo meters in the track-header"),
3339 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3340 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3343 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
3345 add_option (S_("Preferences|Metering"),
3347 "save-export-analysis-image",
3348 _("Save loudness analysis as image file"),
3349 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
3350 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
3353 /* and now the theme manager */
3355 ThemeManager* tm = manage (new ThemeManager);
3356 add_page (_("Theme"), *tm);
3358 add_option (_("Theme/Colors"), new ColorThemeManager);
3360 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3361 parameter_changed ("send-ltc");
3362 parameter_changed ("sync-source");
3363 parameter_changed ("use-monitor-bus");
3364 parameter_changed ("open-gui-after-adding-plugin");
3368 RCOptionEditor::parameter_changed (string const & p)
3370 OptionEditor::parameter_changed (p);
3372 if (p == "use-monitor-bus") {
3373 bool const s = Config->get_use_monitor_bus ();
3375 /* we can't use this if we don't have a monitor bus */
3376 Config->set_solo_control_is_listen_control (false);
3378 _solo_control_is_listen_control->set_sensitive (s);
3379 _listen_position->set_sensitive (s);
3380 } else if (p == "sync-source") {
3381 _sync_source->set_sensitive (true);
3383 _sync_source->set_sensitive (!_session->config.get_external_sync());
3385 switch(Config->get_sync_source()) {
3388 _sync_genlock->set_sensitive (true);
3389 _sync_framerate->set_sensitive (true);
3390 _sync_source_2997->set_sensitive (true);
3393 _sync_genlock->set_sensitive (false);
3394 _sync_framerate->set_sensitive (false);
3395 _sync_source_2997->set_sensitive (false);
3398 } else if (p == "send-ltc") {
3399 bool const s = Config->get_send_ltc ();
3400 _ltc_send_continuously->set_sensitive (s);
3401 _ltc_volume_slider->set_sensitive (s);
3402 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
3403 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3404 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
3409 void RCOptionEditor::ltc_generator_volume_changed () {
3410 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
3413 void RCOptionEditor::plugin_scan_refresh () {
3414 PluginManager::instance().refresh();
3417 void RCOptionEditor::clear_vst_cache () {
3418 PluginManager::instance().clear_vst_cache();
3421 void RCOptionEditor::clear_vst_blacklist () {
3422 PluginManager::instance().clear_vst_blacklist();
3425 void RCOptionEditor::clear_au_cache () {
3426 PluginManager::instance().clear_au_cache();
3429 void RCOptionEditor::clear_au_blacklist () {
3430 PluginManager::instance().clear_au_blacklist();
3433 void RCOptionEditor::edit_lxvst_path () {
3434 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
3435 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3436 *current_toplevel(), _("Set Linux VST Search Path"),
3437 _rc_config->get_plugin_path_lxvst(),
3438 PluginManager::instance().get_default_lxvst_path()
3440 ResponseType r = (ResponseType) pd->run ();
3442 if (r == RESPONSE_ACCEPT) {
3443 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
3448 void RCOptionEditor::edit_vst_path () {
3449 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3450 *current_toplevel(), _("Set Windows VST Search Path"),
3451 _rc_config->get_plugin_path_vst(),
3452 PluginManager::instance().get_default_windows_vst_path()
3454 ResponseType r = (ResponseType) pd->run ();
3456 if (r == RESPONSE_ACCEPT) {
3457 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
3464 RCOptionEditor::populate_sync_options ()
3466 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3468 _sync_source->clear ();
3470 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3471 _sync_source->add (*i, sync_source_to_string (*i));
3474 if (sync_opts.empty()) {
3475 _sync_source->set_sensitive(false);
3477 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3478 _rc_config->set_sync_source(sync_opts.front());
3482 parameter_changed ("sync-source");
3486 RCOptionEditor::use_own_window (bool and_fill_it)
3488 bool new_window = !own_window();
3490 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
3492 if (win && new_window) {
3493 win->set_name ("PreferencesWindow");
3494 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
3501 RCOptionEditor::get_state ()
3503 XMLNode* node = new XMLNode (X_("Preferences"));
3504 node->add_child_nocopy (Tabbable::get_state());