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 == _(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 == _(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 == _(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 == _(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 == _(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 == _(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 == _(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 == _(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 == _(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 == _(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 == _(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 == _(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 == _(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")
1858 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed));
1862 uint32_t hwcpus = hardware_concurrency ();
1864 BoolComboOption* bco;
1867 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1869 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1871 _("Signal processing uses"),
1872 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1873 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1876 procs->add (-1, _("all but one processor"));
1877 procs->add (0, _("all available processors"));
1879 for (uint32_t i = 1; i <= hwcpus; ++i) {
1880 procs->add (i, string_compose (_("%1 processors"), i));
1883 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1885 add_option (_("Misc"), procs);
1888 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1890 add_option (_("Misc"), new UndoOptions (_rc_config));
1892 add_option (_("Misc"),
1894 "verify-remove-last-capture",
1895 _("Verify removal of last capture"),
1896 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1897 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1900 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1902 add_option (_("Misc"),
1904 "periodic-safety-backups",
1905 _("Make periodic backups of the session file"),
1906 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1907 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1910 add_option (_("Misc"),
1912 "only-copy-imported-files",
1913 _("Always copy imported files"),
1914 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
1915 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
1918 add_option (_("Misc"), new DirectoryOption (
1919 X_("default-session-parent-dir"),
1920 _("Default folder for new sessions:"),
1921 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1922 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1925 add_option (_("Misc"),
1926 new SpinOption<uint32_t> (
1927 "max-recent-sessions",
1928 _("Maximum number of recent sessions"),
1929 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1930 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1934 add_option (_("Misc/Click"), new OptionEditorHeading (_("Click")));
1936 add_option (_("Misc/Click"), new ClickOptions (_rc_config));
1938 add_option (_("Misc/Click"),
1941 _("Click gain level"),
1942 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1943 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1946 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1948 add_option (_("Misc"),
1949 new SpinOption<double> (
1950 "automation-thinning-factor",
1951 _("Thinning factor (larger value => less data)"),
1952 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1953 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1957 add_option (_("Misc"),
1958 new SpinOption<double> (
1959 "automation-interval-msecs",
1960 _("Automation sampling interval (milliseconds)"),
1961 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1962 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1968 add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options")));
1972 tsf = new BoolOption (
1973 "latched-record-enable",
1974 _("Keep record-enable engaged on stop"),
1975 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1976 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1978 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1979 add_option (_("Transport"), tsf);
1981 tsf = new BoolOption (
1983 _("Play loop is a transport mode"),
1984 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1985 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1987 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1988 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1989 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1990 add_option (_("Transport"), tsf);
1992 tsf = new BoolOption (
1993 "stop-recording-on-xrun",
1994 _("Stop recording when an xrun occurs"),
1995 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
1996 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
1998 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1999 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
2001 add_option (_("Transport"), tsf);
2003 tsf = new BoolOption (
2004 "create-xrun-marker",
2005 _("Create markers where xruns occur"),
2006 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
2007 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
2009 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
2010 add_option (_("Transport"), tsf);
2012 tsf = new BoolOption (
2013 "stop-at-session-end",
2014 _("Stop at the end of the session"),
2015 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
2016 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
2018 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2019 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
2020 "when it reaches the current session end marker\n\n"
2021 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
2023 add_option (_("Transport"), tsf);
2025 tsf = new BoolOption (
2027 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
2028 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
2029 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
2031 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2032 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
2033 "preventing any need to do a transport locate at the end of the loop\n\n"
2034 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
2035 "which will often cause a small click or delay"), PROGRAM_NAME));
2036 add_option (_("Transport"), tsf);
2038 tsf = new BoolOption (
2039 "disable-disarm-during-roll",
2040 _("Disable per-track record disarm while rolling"),
2041 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
2042 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
2044 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"));
2045 add_option (_("Transport"), tsf);
2047 tsf = new BoolOption (
2049 _("12dB gain reduction during fast-forward and fast-rewind"),
2050 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
2051 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
2053 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
2054 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
2055 add_option (_("Transport"), tsf);
2057 ComboOption<float>* psc = new ComboOption<float> (
2060 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
2061 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
2063 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
2064 (_("The amount of preroll (in seconds) to apply when <b>Play with Preroll</b> is initiated.\n\n"
2065 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
2066 psc->add (0.0, _("0 (no pre-roll)"));
2067 psc->add (0.1, _("0.1 second"));
2068 psc->add (0.25, _("0.25 second"));
2069 psc->add (0.5, _("0.5 second"));
2070 psc->add (1.0, _("1.0 second"));
2071 psc->add (2.0, _("2.0 seconds"));
2072 add_option (_("Transport"), psc);
2074 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("Synchronization and Slave Options")));
2076 _sync_source = new ComboOption<SyncSource> (
2078 _("External timecode source"),
2079 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
2080 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
2083 add_option (_("Transport/Sync"), _sync_source);
2085 _sync_framerate = new BoolOption (
2086 "timecode-sync-frame-rate",
2087 _("Match session video frame rate to external timecode"),
2088 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
2089 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
2091 Gtkmm2ext::UI::instance()->set_tip
2092 (_sync_framerate->tip_widget(),
2093 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
2094 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
2095 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
2096 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
2097 "timecode standard and the session standard."), PROGRAM_NAME));
2099 add_option (_("Transport/Sync"), _sync_framerate);
2101 _sync_genlock = new BoolOption (
2102 "timecode-source-is-synced",
2103 _("Sync-lock timecode to clock (disable drift compensation)"),
2104 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
2105 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
2107 Gtkmm2ext::UI::instance()->set_tip
2108 (_sync_genlock->tip_widget(),
2109 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
2110 "Sync Lock indicates that the selected external timecode source shares clock-sync "
2111 "(Black & Burst, Wordclock, etc) with the audio interface. "
2112 "This option disables drift compensation. The transport speed is fixed at 1.0. "
2113 "Vari-speed LTC will be ignored and cause drift."
2115 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
2116 "timecode sources shares clock sync."
2120 add_option (_("Transport/Sync"), _sync_genlock);
2122 _sync_source_2997 = new BoolOption (
2123 "timecode-source-2997",
2124 _("Lock to 29.9700 fps instead of 30000/1001"),
2125 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
2126 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
2128 Gtkmm2ext::UI::instance()->set_tip
2129 (_sync_source_2997->tip_widget(),
2130 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
2131 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
2132 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
2133 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
2134 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
2135 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
2138 add_option (_("Transport/Sync"), _sync_source_2997);
2140 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("LTC Reader")));
2142 _ltc_port = new ComboStringOption (
2144 _("LTC incoming port"),
2145 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
2146 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
2149 vector<string> physical_inputs;
2150 physical_inputs.push_back (_("None"));
2151 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
2152 _ltc_port->set_popdown_strings (physical_inputs);
2154 populate_sync_options ();
2155 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
2157 add_option (_("Transport/Sync"), _ltc_port);
2159 // TODO; rather disable this button than not compile it..
2160 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("LTC Generator")));
2162 add_option (_("Transport/Sync"),
2165 _("Enable LTC generator"),
2166 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
2167 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
2170 _ltc_send_continuously = new BoolOption (
2171 "ltc-send-continuously",
2172 _("Send LTC while stopped"),
2173 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
2174 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
2176 Gtkmm2ext::UI::instance()->set_tip
2177 (_ltc_send_continuously->tip_widget(),
2178 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
2179 add_option (_("Transport"), _ltc_send_continuously);
2181 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
2182 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
2183 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
2184 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
2186 Gtkmm2ext::UI::instance()->set_tip
2187 (_ltc_volume_slider->tip_widget(),
2188 _("Specify the Peak Volume of the generated LTC signal in dbFS. A good value is 0dBu ^= -18dbFS in an EBU calibrated system"));
2190 add_option (_("Transport/Sync"), _ltc_volume_slider);
2194 add_option (_("Editor"),
2196 "rubberbanding-snaps-to-grid",
2197 _("Make rubberband selection rectangle snap to the grid"),
2198 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2199 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2202 bo = new BoolOption (
2204 _("Name new markers"),
2205 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2206 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2208 add_option (_("Editor"), bo);
2209 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."
2210 "\n\nYou can always rename markers by right-clicking on them"));
2212 add_option (S_("Editor"),
2214 "draggable-playhead",
2215 _("Allow dragging of playhead"),
2216 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2217 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2220 add_option (_("Editor"),
2222 "show-editor-meter",
2223 _("Display master-meter in the toolbar"),
2224 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
2225 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
2228 if (!Profile->get_mixbus()) {
2229 add_option (_("Editor"),
2232 _("Show zoom toolbar (if torn off)"),
2233 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_zoom_tools),
2234 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_zoom_tools)
2237 add_option (_("Editor"),
2239 "use-mouse-position-as-zoom-focus-on-scroll",
2240 _("Always use mouse cursor position as zoom focus when zooming using mouse scroll wheel"),
2241 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2242 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2246 add_option (_("Editor"),
2248 "update-editor-during-summary-drag",
2249 _("Update editor window during drags of the summary"),
2250 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2251 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2254 add_option (_("Editor"),
2256 "autoscroll-editor",
2257 _("Auto-scroll editor window when dragging near its edges"),
2258 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2259 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2262 add_option (_("Editor"),
2263 new BoolComboOption (
2264 "show-region-gain-envelopes",
2265 _("Show gain envelopes in audio regions"),
2267 _("only in Draw and Internal Edit modes"),
2268 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2269 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2272 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2274 add_option (_("Editor"),
2276 "automation-follows-regions",
2277 _("Move relevant automation when audio regions are moved"),
2278 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2279 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2282 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2283 "default-fade-shape",
2284 _("Default fade shape"),
2285 sigc::mem_fun (*_rc_config,
2286 &RCConfiguration::get_default_fade_shape),
2287 sigc::mem_fun (*_rc_config,
2288 &RCConfiguration::set_default_fade_shape)
2291 fadeshape->add (FadeLinear,
2292 _("Linear (for highly correlated material)"));
2293 fadeshape->add (FadeConstantPower, _("Constant power"));
2294 fadeshape->add (FadeSymmetric, _("Symmetric"));
2295 fadeshape->add (FadeSlow, _("Slow"));
2296 fadeshape->add (FadeFast, _("Fast"));
2298 add_option (_("Editor"), fadeshape);
2301 bco = new BoolComboOption (
2302 "use-overlap-equivalency",
2303 _("Regions in active edit groups are edited together"),
2304 _("whenever they overlap in time"),
2305 _("only if they have identical length, position and origin"),
2306 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2307 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2310 add_option (_("Editor"), bco);
2312 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2314 _("Layering model"),
2315 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2316 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2319 lm->add (LaterHigher, _("later is higher"));
2320 lm->add (Manual, _("manual layering"));
2321 add_option (_("Editor"), lm);
2323 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2324 "region-selection-after-split",
2325 _("After splitting selected regions, select"),
2326 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2327 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2329 // TODO: decide which of these modes are really useful
2330 rsas->add(None, _("no regions"));
2331 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2332 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2333 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2334 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2335 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2336 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2337 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2339 add_option (_("Editor"), rsas);
2341 add_option (_("Editor/Waveforms"), new OptionEditorHeading (_("Waveforms")));
2343 if (!Profile->get_mixbus()) {
2344 add_option (_("Editor/Waveforms"),
2347 _("Show waveforms in regions"),
2348 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
2349 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
2353 add_option (_("Editor/Waveforms"),
2355 "show-waveforms-while-recording",
2356 _("Show waveforms for audio while it is being recorded"),
2357 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
2358 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
2361 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
2363 _("Waveform scale"),
2364 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
2365 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
2368 wfs->add (Linear, _("linear"));
2369 wfs->add (Logarithmic, _("logarithmic"));
2371 add_option (_("Editor/Waveforms"), wfs);
2373 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
2375 _("Waveform shape"),
2376 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
2377 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
2380 wfsh->add (Traditional, _("traditional"));
2381 wfsh->add (Rectified, _("rectified"));
2383 add_option (_("Editor/Waveforms"), wfsh);
2385 add_option (_("Editor/Waveforms"), new ClipLevelOptions ());
2390 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2392 add_option (_("Audio"), new BufferingOptions (_rc_config));
2394 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2396 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2398 _("Record monitoring handled by"),
2399 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2400 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2403 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2404 mm->add (HardwareMonitoring, _("via Audio Driver"));
2407 string prog (PROGRAM_NAME);
2408 boost::algorithm::to_lower (prog);
2409 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2410 mm->add (ExternalMonitoring, _("audio hardware"));
2412 add_option (_("Audio"), mm);
2414 add_option (_("Audio"),
2416 "tape-machine-mode",
2417 _("Tape machine mode"),
2418 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2419 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2422 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
2423 if (!Profile->get_mixbus()) {
2425 add_option (_("Audio"),
2427 "auto-connect-standard-busses",
2428 _("Auto-connect master/monitor busses"),
2429 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2430 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2433 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2434 "input-auto-connect",
2435 _("Connect track inputs"),
2436 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2437 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2440 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2441 iac->add (ManualConnect, _("manually"));
2443 add_option (_("Audio"), iac);
2445 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2446 "output-auto-connect",
2447 _("Connect track and bus outputs"),
2448 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2449 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2452 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2453 oac->add (AutoConnectMaster, _("automatically to master bus"));
2454 oac->add (ManualConnect, _("manually"));
2456 add_option (_("Audio"), oac);
2458 bo = new BoolOption (
2460 _("Use 'Strict-I/O' for new tracks or Busses"),
2461 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2462 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2465 add_option (_("Audio"), bo);
2466 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2467 _("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."));
2471 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2473 add_option (_("Audio"),
2475 "denormal-protection",
2476 _("Use DC bias to protect against denormals"),
2477 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2478 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2481 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2483 _("Processor handling"),
2484 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2485 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2489 dm->add (DenormalNone, _("no processor handling"));
2491 FPU* fpu = FPU::instance();
2493 if (fpu->has_flush_to_zero()) {
2495 dm->add (DenormalFTZ, _("use FlushToZero"));
2496 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2497 _rc_config->set_denormal_model(DenormalNone);
2500 if (fpu->has_denormals_are_zero()) {
2502 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2503 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2504 _rc_config->set_denormal_model(DenormalNone);
2507 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2509 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2510 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2511 _rc_config->set_denormal_model(DenormalNone);
2515 dm->set_sensitive(false);
2518 add_option (_("Audio"), dm);
2520 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2522 add_option (_("Audio"),
2524 "auto-analyse-audio",
2525 _("Enable automatic analysis of audio"),
2526 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2527 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2530 add_option (_("Audio"),
2532 "replicate-missing-region-channels",
2533 _("Replicate missing region channels"),
2534 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2535 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2540 add_option (_("Solo & mute"), new OptionEditorHeading (_("Solo")));
2542 _solo_control_is_listen_control = new BoolOption (
2543 "solo-control-is-listen-control",
2544 _("Solo controls are Listen controls"),
2545 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2546 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2549 add_option (_("Solo & mute"), _solo_control_is_listen_control);
2551 add_option (_("Solo & mute"),
2554 _("Exclusive solo"),
2555 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2556 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2559 add_option (_("Solo & mute"),
2562 _("Show solo muting"),
2563 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2564 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2567 add_option (_("Solo & mute"),
2569 "solo-mute-override",
2570 _("Soloing overrides muting"),
2571 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2572 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2575 add_option (_("Solo & mute"),
2578 _("Solo-in-place mute cut (dB)"),
2579 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2580 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2583 _listen_position = new ComboOption<ListenPosition> (
2585 _("Listen Position"),
2586 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2587 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2590 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2591 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2593 add_option (_("Solo & mute"), _listen_position);
2595 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2597 _("PFL signals come from"),
2598 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2599 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2602 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2603 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2605 add_option (_("Solo & mute"), pp);
2607 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2609 _("AFL signals come from"),
2610 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2611 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2614 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2615 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2617 add_option (_("Solo & mute"), pa);
2619 add_option (_("Solo & mute"), new OptionEditorHeading (_("Default track / bus muting options")));
2621 add_option (_("Solo & mute"),
2623 "mute-affects-pre-fader",
2624 _("Mute affects pre-fader sends"),
2625 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2626 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2629 add_option (_("Solo & mute"),
2631 "mute-affects-post-fader",
2632 _("Mute affects post-fader sends"),
2633 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2634 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2637 add_option (_("Solo & mute"),
2639 "mute-affects-control-outs",
2640 _("Mute affects control outputs"),
2641 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2642 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2645 add_option (_("Solo & mute"),
2647 "mute-affects-main-outs",
2648 _("Mute affects main outputs"),
2649 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2650 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2654 if (!ARDOUR::Profile->get_mixbus()) {
2655 add_option (_("Solo & mute"), new OptionEditorHeading (_("Send Routing")));
2656 add_option (_("Solo & mute"),
2658 "link-send-and-route-panner",
2659 _("Link panners of Aux and External Sends with main panner by default"),
2660 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2661 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2665 add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Preferences")));
2667 add_option (_("MIDI"),
2668 new SpinOption<float> (
2670 _("MIDI read-ahead time (seconds)"),
2671 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2672 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2677 add_option (_("MIDI"),
2678 new SpinOption<int32_t> (
2679 "initial-program-change",
2680 _("Initial program change"),
2681 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2682 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2686 add_option (_("MIDI"),
2688 "display-first-midi-bank-as-zero",
2689 _("Display first MIDI bank/program as 0"),
2690 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2691 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2694 add_option (_("MIDI"),
2696 "never-display-periodic-midi",
2697 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2698 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
2699 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
2702 add_option (_("MIDI"),
2705 _("Sound MIDI notes as they are selected in the editor"),
2706 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2707 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2710 add_option (_("MIDI"),
2713 _("Send MIDI control feedback"),
2714 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2715 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2718 add_option (_("MIDI/Sync"), new OptionEditorHeading (_("MIDI Clock")));
2720 add_option (_("MIDI/Sync"),
2723 _("Send MIDI Clock"),
2724 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2725 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2728 add_option (_("MIDI/Sync"), new OptionEditorHeading (_("MIDI Time Code (MTC)")));
2730 add_option (_("MIDI/Sync"),
2733 _("Send MIDI Time Code"),
2734 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2735 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2738 add_option (_("MIDI/Sync"),
2739 new SpinOption<int> (
2740 "mtc-qf-speed-tolerance",
2741 _("Percentage either side of normal transport speed to transmit MTC"),
2742 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2743 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2747 add_option (_("MIDI/Sync"), new OptionEditorHeading (_("Midi Machine Control (MMC)")));
2749 add_option (_("MIDI/Sync"),
2752 _("Obey MIDI Machine Control commands"),
2753 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2754 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2757 add_option (_("MIDI/Sync"),
2760 _("Send MIDI Machine Control commands"),
2761 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2762 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2765 add_option (_("MIDI/Sync"),
2766 new SpinOption<uint8_t> (
2767 "mmc-receive-device-id",
2768 _("Inbound MMC device ID"),
2769 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2770 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2774 add_option (_("MIDI/Sync"),
2775 new SpinOption<uint8_t> (
2776 "mmc-send-device-id",
2777 _("Outbound MMC device ID"),
2778 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2779 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2783 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2785 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2786 "midi-audition-synth-uri",
2787 _("Midi Audition Synth (LV2)"),
2788 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2789 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2792 audition_synth->add(X_(""), _("None"));
2793 PluginInfoList all_plugs;
2794 PluginManager& manager (PluginManager::instance());
2796 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2798 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2799 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2800 if (!(*i)->is_instrument()) continue;
2801 if ((*i)->type != ARDOUR::LV2) continue;
2802 audition_synth->add((*i)->unique_id, (*i)->name);
2806 add_option (_("MIDI"), audition_synth);
2808 /* USER INTERACTION */
2811 #ifdef PLATFORM_WINDOWS
2814 getenv ("ARDOUR_BUNDLED")
2818 add_option (_("User interaction"),
2820 "enable-translation",
2821 string_compose (_("Use translations of %1 messages\n"
2822 " <i>(requires a restart of %1 to take effect)</i>\n"
2823 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2824 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2825 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2828 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2830 add_option (_("User interaction"), new KeyboardOptions);
2832 /* Control Surfaces */
2834 add_option (_("Control Surfaces"), new ControlSurfacesOptions);
2836 /* VIDEO Timeline */
2837 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2839 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2840 add_option (_("Plugins"),
2841 new RcActionButton (_("Scan for Plugins"),
2842 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
2846 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
2848 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2849 bo = new BoolOption (
2850 "show-plugin-scan-window",
2851 _("Always Display Plugin Scan Progress"),
2852 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
2853 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
2855 add_option (_("Plugins"), bo);
2856 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2857 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
2860 bo = new BoolOption (
2861 "plugins-stop-with-transport",
2862 _("Silence plugins when the transport is stopped"),
2863 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
2864 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
2866 add_option (_("Plugins"), bo);
2867 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2868 _("<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."));
2870 bo = new BoolOption (
2871 "new-plugins-active",
2872 _("Make new plugins active"),
2873 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
2874 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
2876 add_option (_("Plugins"), bo);
2877 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2878 _("<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"));
2880 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
2881 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
2883 bo = new BoolOption (
2884 "discover-vst-on-start",
2885 _("Scan for [new] VST Plugins on Application Start"),
2886 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
2887 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
2889 add_option (_("Plugins/VST"), bo);
2890 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2891 _("<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"));
2893 #ifdef WINDOWS_VST_SUPPORT
2894 // currently verbose logging is only implemented for Windows VST.
2895 bo = new BoolOption (
2896 "verbose-plugin-scan",
2897 _("Verbose Plugin Scan"),
2898 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
2899 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
2901 add_option (_("Plugins/VST"), bo);
2902 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2903 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
2906 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
2908 add_option (_("Plugins/VST"),
2909 new RcActionButton (_("Clear"),
2910 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
2913 add_option (_("Plugins/VST"),
2914 new RcActionButton (_("Clear"),
2915 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
2916 _("VST Blacklist:")));
2919 #ifdef LXVST_SUPPORT
2920 add_option (_("Plugins/VST"),
2921 new RcActionButton (_("Edit"),
2922 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
2923 _("Linux VST Path:")));
2925 add_option (_("Plugins/VST"),
2926 new RcConfigDisplay (
2927 "plugin-path-lxvst",
2929 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
2933 #ifdef WINDOWS_VST_SUPPORT
2934 add_option (_("Plugins/VST"),
2935 new RcActionButton (_("Edit"),
2936 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
2937 _("Windows VST Path:")));
2938 add_option (_("Plugins"),
2939 new RcConfigDisplay (
2942 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
2946 #ifdef AUDIOUNIT_SUPPORT
2947 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
2949 bo = new BoolOption (
2950 "discover-audio-units",
2951 _("Scan for AudioUnit Plugins on Application Start"),
2952 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
2953 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
2955 add_option (_("Plugins"), bo);
2956 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2957 _("<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."));
2959 add_option (_("Plugins/Audio Unit"),
2960 new RcActionButton (_("Clear"),
2961 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
2964 add_option (_("Plugins/Audio Unit"),
2965 new RcActionButton (_("Clear"),
2966 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
2967 _("AU Blacklist:")));
2970 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
2971 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
2972 add_option (_("Plugins"),
2974 "open-gui-after-adding-plugin",
2975 _("Automatically open the plugin GUI when adding a new plugin"),
2976 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
2977 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
2980 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
2981 add_option (_("Plugins"),
2983 "show-inline-display-by-default",
2984 _("Show Plugin Inline Display on Mixerstrip by default"),
2985 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
2986 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
2989 _plugin_prefer_inline = new BoolOption (
2990 "prefer-inline-over-gui",
2991 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
2992 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
2993 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
2995 add_option (_("Plugins"), _plugin_prefer_inline);
2998 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3000 bo = new BoolOption (
3001 "ask-replace-instrument",
3002 _("Ask to replace existing instrument plugin"),
3003 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3004 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3006 add_option (_("Plugins"), bo);
3008 bo = new BoolOption (
3009 "ask-setup_instrument",
3010 _("Interactively configure instrument plugins on insert"),
3011 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3012 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3014 add_option (_("Plugins"), bo);
3015 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3016 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3022 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3023 BoolOption* bgc = new BoolOption (
3024 "cairo-image-surface",
3025 _("Disable Graphics Hardware Acceleration (requires restart)"),
3026 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3027 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3030 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3031 _("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));
3032 add_option (S_("Preferences|GUI"), bgc);
3035 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3036 BoolOption* bgo = new BoolOption (
3038 _("Possibly improve slow graphical performance (requires restart)"),
3039 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3040 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3043 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));
3044 add_option (S_("Preferences|GUI"), bgo);
3047 add_option (S_("Preferences|GUI"),
3049 "use-wm-visibility",
3050 _("Use Window Manager/Desktop visibility information"),
3051 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3052 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3055 add_option (S_("Preferences|GUI"),
3058 _("Graphically indicate mouse pointer hovering over various widgets"),
3059 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3060 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3063 add_option (S_("Preferences|GUI"),
3066 _("Show tooltips if mouse hovers over a control"),
3067 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3068 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3071 add_option (S_("Preferences|GUI"),
3073 "show-name-highlight",
3074 _("Use name highlight bars in region displays (requires a restart)"),
3075 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3076 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3079 add_option (S_("Preferences|GUI"),
3081 "super-rapid-clock-update",
3082 _("Update transport clock display at FPS instead of every 100ms"),
3083 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3084 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3089 /* font scaling does nothing with GDK/Quartz */
3090 add_option (S_("Preferences|GUI"), new FontScalingOptions ());
3093 /* Image cache size */
3095 Gtk::Adjustment *ics = manage (new Gtk::Adjustment(0, 1, 1024, 10)); /* 1 MB to 1GB in steps of 10MB */
3096 HSliderOption *sics = new HSliderOption("waveform-cache-size",
3097 _("Waveform image cache size (megabytes)"),
3099 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
3100 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size)
3102 sics->scale().set_digits (0);
3103 Gtkmm2ext::UI::instance()->set_tip
3104 (sics->tip_widget(),
3105 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
3106 add_option (S_("Preferences|GUI"), sics);
3108 if (!ARDOUR::Profile->get_mixbus()) {
3109 /* Lock GUI timeout */
3111 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
3112 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
3113 _("Lock timeout (seconds)"),
3115 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
3116 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds)
3118 slts->scale().set_digits (0);
3119 Gtkmm2ext::UI::instance()->set_tip
3120 (slts->tip_widget(),
3121 _("Lock GUI after this many idle seconds (zero to never lock)"));
3122 add_option (S_("Preferences|GUI"), slts);
3125 /* The names of these controls must be the same as those given in MixerStrip
3126 for the actual widgets being controlled.
3128 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3129 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3130 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3131 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3132 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3133 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3134 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3137 S_("Preferences|GUI"),
3138 new VisibilityOption (
3140 &_mixer_strip_visibility,
3141 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3142 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3146 add_option (S_("Preferences|GUI"),
3148 "default-narrow_ms",
3149 _("Use narrow strips in the mixer by default"),
3150 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3151 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3154 add_option (S_("Preferences|GUI"),
3155 new ColumVisibilityOption (
3156 "action-table-columns", _("Action Script Button Visibility"), 3,
3157 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3158 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3162 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
3164 ComboOption<float>* mht = new ComboOption<float> (
3166 _("Peak hold time"),
3167 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
3168 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
3171 mht->add (MeterHoldOff, _("off"));
3172 mht->add (MeterHoldShort, _("short"));
3173 mht->add (MeterHoldMedium, _("medium"));
3174 mht->add (MeterHoldLong, _("long"));
3176 add_option (S_("Preferences|Metering"), mht);
3178 ComboOption<float>* mfo = new ComboOption<float> (
3181 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
3182 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
3185 mfo->add (METER_FALLOFF_OFF, _("off"));
3186 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
3187 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
3188 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
3189 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
3190 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
3191 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
3193 add_option (S_("Preferences|Metering"), mfo);
3195 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
3196 "meter-line-up-level",
3197 _("Meter line-up level; 0dBu"),
3198 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
3199 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
3202 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3203 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3204 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3205 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3207 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."));
3209 add_option (S_("Preferences|Metering"), mlu);
3211 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
3212 "meter-line-up-din",
3213 _("IEC1/DIN Meter line-up level; 0dBu"),
3214 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
3215 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
3218 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3219 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3220 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3221 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3223 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
3225 add_option (S_("Preferences|Metering"), mld);
3227 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
3228 "meter-vu-standard",
3229 _("VU Meter standard"),
3230 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
3231 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
3234 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
3235 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
3236 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
3237 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
3239 add_option (S_("Preferences|Metering"), mvu);
3241 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
3242 HSliderOption *mpks = new HSliderOption("meter-peak",
3243 _("Peak threshold [dBFS]"),
3245 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
3246 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak)
3250 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
3251 "meter-type-master",
3252 _("Default Meter Type for Master Bus"),
3253 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
3254 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3256 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3257 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3258 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3259 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3260 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3261 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3262 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3263 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3265 add_option (S_("Preferences|Metering"), mtm);
3268 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3270 _("Default Meter Type for Busses"),
3271 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3272 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3274 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3275 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3276 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3277 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3278 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3279 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3280 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3281 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3283 add_option (S_("Preferences|Metering"), mtb);
3285 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3287 _("Default Meter Type for Tracks"),
3288 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3289 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3291 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3292 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3294 add_option (S_("Preferences|Metering"), mtt);
3297 Gtkmm2ext::UI::instance()->set_tip
3298 (mpks->tip_widget(),
3299 _("Specify the audio signal level in dbFS at and above which the meter-peak indicator will flash red."));
3301 add_option (S_("Preferences|Metering"), mpks);
3303 add_option (S_("Preferences|Metering"),
3306 _("LED meter style"),
3307 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3308 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3311 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Editor Meters")));
3313 add_option (S_("Preferences|Metering"),
3315 "show-track-meters",
3316 _("Show meters on tracks in the editor"),
3317 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3318 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3321 add_option (S_("Preferences|Metering"),
3323 "editor-stereo-only-meters",
3324 _("Show at most stereo meters in the track-header"),
3325 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3326 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3329 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
3331 add_option (S_("Preferences|Metering"),
3333 "save-export-analysis-image",
3334 _("Save loudness analysis as image file"),
3335 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
3336 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
3339 /* and now the theme manager */
3341 ThemeManager* tm = manage (new ThemeManager);
3342 add_page (_("Theme"), *tm);
3344 add_option (_("Theme/Colors"), new ColorThemeManager);
3346 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3347 parameter_changed ("send-ltc");
3348 parameter_changed ("sync-source");
3349 parameter_changed ("use-monitor-bus");
3350 parameter_changed ("open-gui-after-adding-plugin");
3354 RCOptionEditor::parameter_changed (string const & p)
3356 OptionEditor::parameter_changed (p);
3358 if (p == "use-monitor-bus") {
3359 bool const s = Config->get_use_monitor_bus ();
3361 /* we can't use this if we don't have a monitor bus */
3362 Config->set_solo_control_is_listen_control (false);
3364 _solo_control_is_listen_control->set_sensitive (s);
3365 _listen_position->set_sensitive (s);
3366 } else if (p == "sync-source") {
3367 _sync_source->set_sensitive (true);
3369 _sync_source->set_sensitive (!_session->config.get_external_sync());
3371 switch(Config->get_sync_source()) {
3374 _sync_genlock->set_sensitive (true);
3375 _sync_framerate->set_sensitive (true);
3376 _sync_source_2997->set_sensitive (true);
3379 _sync_genlock->set_sensitive (false);
3380 _sync_framerate->set_sensitive (false);
3381 _sync_source_2997->set_sensitive (false);
3384 } else if (p == "send-ltc") {
3385 bool const s = Config->get_send_ltc ();
3386 _ltc_send_continuously->set_sensitive (s);
3387 _ltc_volume_slider->set_sensitive (s);
3388 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
3390 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
3395 void RCOptionEditor::ltc_generator_volume_changed () {
3396 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
3399 void RCOptionEditor::plugin_scan_refresh () {
3400 PluginManager::instance().refresh();
3403 void RCOptionEditor::clear_vst_cache () {
3404 PluginManager::instance().clear_vst_cache();
3407 void RCOptionEditor::clear_vst_blacklist () {
3408 PluginManager::instance().clear_vst_blacklist();
3411 void RCOptionEditor::clear_au_cache () {
3412 PluginManager::instance().clear_au_cache();
3415 void RCOptionEditor::clear_au_blacklist () {
3416 PluginManager::instance().clear_au_blacklist();
3419 void RCOptionEditor::edit_lxvst_path () {
3420 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
3421 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3422 *current_toplevel(), _("Set Linux VST Search Path"),
3423 _rc_config->get_plugin_path_lxvst(),
3424 PluginManager::instance().get_default_lxvst_path()
3426 ResponseType r = (ResponseType) pd->run ();
3428 if (r == RESPONSE_ACCEPT) {
3429 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
3434 void RCOptionEditor::edit_vst_path () {
3435 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3436 *current_toplevel(), _("Set Windows VST Search Path"),
3437 _rc_config->get_plugin_path_vst(),
3438 PluginManager::instance().get_default_windows_vst_path()
3440 ResponseType r = (ResponseType) pd->run ();
3442 if (r == RESPONSE_ACCEPT) {
3443 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
3450 RCOptionEditor::populate_sync_options ()
3452 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3454 _sync_source->clear ();
3456 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3457 _sync_source->add (*i, sync_source_to_string (*i));
3460 if (sync_opts.empty()) {
3461 _sync_source->set_sensitive(false);
3463 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3464 _rc_config->set_sync_source(sync_opts.front());
3468 parameter_changed ("sync-source");
3472 RCOptionEditor::use_own_window (bool and_fill_it)
3474 bool new_window = !own_window();
3476 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
3478 if (win && new_window) {
3479 win->set_name ("PreferencesWindow");
3480 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);