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-Control", GDK_MOD2_MASK|GDK_CONTROL_MASK },
343 { "Command-Option-Control", GDK_MOD2_MASK|GDK_MOD1_MASK|GDK_CONTROL_MASK },
344 { "Option-Control", GDK_MOD1_MASK|GDK_CONTROL_MASK },
345 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
346 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
347 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_MOD2_MASK },
350 { "Key|Shift", GDK_SHIFT_MASK },
351 { "Control", GDK_CONTROL_MASK },
352 { "Alt", GDK_MOD1_MASK },
353 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
354 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
355 { "Control-Windows", GDK_CONTROL_MASK|GDK_MOD4_MASK },
356 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
357 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
358 { "Alt-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
359 { "Alt-Shift-Windows", GDK_MOD1_MASK|GDK_SHIFT_MASK|GDK_MOD4_MASK },
360 { "Mod2", GDK_MOD2_MASK },
361 { "Mod3", GDK_MOD3_MASK },
362 { "Windows", GDK_MOD4_MASK },
363 { "Mod5", GDK_MOD5_MASK },
369 class KeyboardOptions : public OptionEditorBox
373 _delete_button_adjustment (3, 1, 12),
374 _delete_button_spin (_delete_button_adjustment),
375 _edit_button_adjustment (3, 1, 5),
376 _edit_button_spin (_edit_button_adjustment),
377 _insert_note_button_adjustment (3, 1, 5),
378 _insert_note_button_spin (_insert_note_button_adjustment)
380 const std::string restart_msg = _("\nChanges to this setting will only persist after your project has been saved.");
381 /* internationalize and prepare for use with combos */
384 for (int i = 0; modifiers[i].name; ++i) {
385 dumb.push_back (S_(modifiers[i].name));
388 set_popdown_strings (_edit_modifier_combo, dumb);
389 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
390 Gtkmm2ext::UI::instance()->set_tip (_edit_modifier_combo,
391 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
392 for (int x = 0; modifiers[x].name; ++x) {
393 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
394 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
399 Table* t = manage (new Table (5, 11));
405 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
406 l->set_name ("OptionsLabel");
410 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
411 strs.push_back (bf->first);
414 set_popdown_strings (_keyboard_layout_selector, strs);
415 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
416 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
418 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
419 t->attach (_keyboard_layout_selector, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
424 l = manage (left_aligned_label (_("When Clicking:")));
425 l->set_name ("OptionEditorHeading");
426 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
431 l = manage (left_aligned_label (_("Edit using:")));
432 l->set_name ("OptionsLabel");
434 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
435 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
437 l = manage (new Label (_("+ button")));
438 l->set_name ("OptionsLabel");
440 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
441 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
443 _edit_button_spin.set_name ("OptionsEntry");
444 _edit_button_adjustment.set_value (Keyboard::edit_button());
445 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
450 set_popdown_strings (_delete_modifier_combo, dumb);
451 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
452 Gtkmm2ext::UI::instance()->set_tip (_delete_modifier_combo,
453 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
454 for (int x = 0; modifiers[x].name; ++x) {
455 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
456 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
461 l = manage (left_aligned_label (_("Delete using:")));
462 l->set_name ("OptionsLabel");
464 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
465 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
467 l = manage (new Label (_("+ button")));
468 l->set_name ("OptionsLabel");
470 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
471 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
473 _delete_button_spin.set_name ("OptionsEntry");
474 _delete_button_adjustment.set_value (Keyboard::delete_button());
475 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
480 set_popdown_strings (_insert_note_modifier_combo, dumb);
481 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
482 Gtkmm2ext::UI::instance()->set_tip (_insert_note_modifier_combo,
483 (string_compose (_("<b>Recommended Setting: %1 + button 1 (left mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
484 for (int x = 0; modifiers[x].name; ++x) {
485 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
486 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
491 l = manage (left_aligned_label (_("Insert note using:")));
492 l->set_name ("OptionsLabel");
494 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
495 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
497 l = manage (new Label (_("+ button")));
498 l->set_name ("OptionsLabel");
500 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
501 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
503 _insert_note_button_spin.set_name ("OptionsEntry");
504 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
505 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
509 l = manage (left_aligned_label (_("When Beginning a Drag:")));
510 l->set_name ("OptionEditorHeading");
511 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
517 set_popdown_strings (_copy_modifier_combo, dumb);
518 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
519 Gtkmm2ext::UI::instance()->set_tip (_copy_modifier_combo,
520 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
522 Keyboard::secondary_modifier_name (),
524 Keyboard::primary_modifier_name (),
527 for (int x = 0; modifiers[x].name; ++x) {
528 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
529 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
534 l = manage (left_aligned_label (_("Copy items using:")));
535 l->set_name ("OptionsLabel");
537 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
538 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
543 /* constraint modifier */
544 set_popdown_strings (_constraint_modifier_combo, dumb);
545 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
546 std::string mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ());
547 Gtkmm2ext::UI::instance()->set_tip (_constraint_modifier_combo,
548 (string_compose (_("At the beginning of a drag, applies vertical constraint (mostly)."
549 " Holding down after grabbing an object but before the first move constrains the"
550 " drag to the direction of the first movement. <b>Recommended Setting: %1</b>%2"),
552 Keyboard::primary_modifier_name (),
554 Keyboard::tertiary_modifier_name (),
557 for (int x = 0; modifiers[x].name; ++x) {
558 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
559 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
564 l = manage (left_aligned_label (_("Constrain drag using:")));
565 l->set_name ("OptionsLabel");
567 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
568 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
574 set_popdown_strings (_push_points_combo, dumb);
575 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
577 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ());
578 Gtkmm2ext::UI::instance()->set_tip (_push_points_combo,
579 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
580 for (int x = 0; modifiers[x].name; ++x) {
581 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
582 _push_points_combo.set_active_text (S_(modifiers[x].name));
587 l = manage (left_aligned_label (_("Push points using:")));
588 l->set_name ("OptionsLabel");
590 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
591 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
595 l = manage (left_aligned_label (_("When Beginning a Trim:")));
596 l->set_name ("OptionEditorHeading");
597 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
603 set_popdown_strings (_trim_contents_combo, dumb);
604 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
605 Gtkmm2ext::UI::instance()->set_tip (_trim_contents_combo,
606 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
607 for (int x = 0; modifiers[x].name; ++x) {
608 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
609 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
614 l = manage (left_aligned_label (_("Trim contents using:")));
615 l->set_name ("OptionsLabel");
617 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
618 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
624 set_popdown_strings (_trim_anchored_combo, dumb);
625 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
627 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::tertiary_modifier_name ());
628 Gtkmm2ext::UI::instance()->set_tip (_trim_anchored_combo,
629 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
630 for (int x = 0; modifiers[x].name; ++x) {
631 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
632 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
637 l = manage (left_aligned_label (_("Anchored trim using:")));
638 l->set_name ("OptionsLabel");
640 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
642 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
647 /* jump trim disabled for now
648 set_popdown_strings (_trim_jump_combo, dumb);
649 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
651 for (int x = 0; modifiers[x].name; ++x) {
652 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
653 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
658 l = manage (left_aligned_label (_("Jump after trim using:")));
659 l->set_name ("OptionsLabel");
661 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
663 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
669 /* note resize relative */
670 set_popdown_strings (_note_size_relative_combo, dumb);
671 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
672 Gtkmm2ext::UI::instance()->set_tip (_note_size_relative_combo,
673 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
674 for (int x = 0; modifiers[x].name; ++x) {
675 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
676 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
681 l = manage (left_aligned_label (_("Resize notes relatively using:")));
682 l->set_name ("OptionsLabel");
684 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
686 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
690 l = manage (left_aligned_label (_("While Dragging:")));
691 l->set_name ("OptionEditorHeading");
692 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
698 set_popdown_strings (_snap_modifier_combo, dumb);
699 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
701 mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ());
703 mod_str = Keyboard::secondary_modifier_name();
705 Gtkmm2ext::UI::instance()->set_tip (_snap_modifier_combo,
706 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
707 for (int x = 0; modifiers[x].name; ++x) {
708 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
709 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
714 l = manage (left_aligned_label (_("Ignore snap using:")));
715 l->set_name ("OptionsLabel");
717 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
718 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
724 set_popdown_strings (_snap_delta_combo, dumb);
725 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
727 mod_str = Keyboard::level4_modifier_name ();
729 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::level4_modifier_name ());
731 Gtkmm2ext::UI::instance()->set_tip (_snap_delta_combo,
732 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
733 for (int x = 0; modifiers[x].name; ++x) {
734 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
735 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
740 l = manage (left_aligned_label (_("Snap relatively using:")));
741 l->set_name ("OptionsLabel");
743 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
744 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
748 l = manage (left_aligned_label (_("While Trimming:")));
749 l->set_name ("OptionEditorHeading");
750 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
756 set_popdown_strings (_trim_overlap_combo, dumb);
757 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
759 Gtkmm2ext::UI::instance()->set_tip (_trim_overlap_combo,
760 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
761 for (int x = 0; modifiers[x].name; ++x) {
762 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
763 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
768 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
769 l->set_name ("OptionsLabel");
771 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
772 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
776 l = manage (left_aligned_label (_("While Dragging Control Points:")));
777 l->set_name ("OptionEditorHeading");
778 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
784 set_popdown_strings (_fine_adjust_combo, dumb);
785 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
787 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::secondary_modifier_name ());
788 Gtkmm2ext::UI::instance()->set_tip (_fine_adjust_combo,
789 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
790 for (int x = 0; modifiers[x].name; ++x) {
791 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
792 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
797 l = manage (left_aligned_label (_("Fine adjust using:")));
798 l->set_name ("OptionsLabel");
800 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
801 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
803 _box->pack_start (*t, false, false);
806 void parameter_changed (string const &)
808 /* XXX: these aren't really config options... */
811 void set_state_from_config ()
813 /* XXX: these aren't really config options... */
818 void bindings_changed ()
820 string const txt = _keyboard_layout_selector.get_active_text();
822 /* XXX: config...? for all this keyboard stuff */
824 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
825 if (txt == i->first) {
826 if (Keyboard::load_keybindings (i->second)) {
827 Keyboard::save_keybindings ();
833 void edit_modifier_chosen ()
835 string const txt = _edit_modifier_combo.get_active_text();
837 for (int i = 0; modifiers[i].name; ++i) {
838 if (txt == S_(modifiers[i].name)) {
839 Keyboard::set_edit_modifier (modifiers[i].modifier);
845 void delete_modifier_chosen ()
847 string const txt = _delete_modifier_combo.get_active_text();
849 for (int i = 0; modifiers[i].name; ++i) {
850 if (txt == S_(modifiers[i].name)) {
851 Keyboard::set_delete_modifier (modifiers[i].modifier);
857 void copy_modifier_chosen ()
859 string const txt = _copy_modifier_combo.get_active_text();
861 for (int i = 0; modifiers[i].name; ++i) {
862 if (txt == S_(modifiers[i].name)) {
863 Keyboard::set_copy_modifier (modifiers[i].modifier);
869 void insert_note_modifier_chosen ()
871 string const txt = _insert_note_modifier_combo.get_active_text();
873 for (int i = 0; modifiers[i].name; ++i) {
874 if (txt == S_(modifiers[i].name)) {
875 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
881 void snap_modifier_chosen ()
883 string const txt = _snap_modifier_combo.get_active_text();
885 for (int i = 0; modifiers[i].name; ++i) {
886 if (txt == S_(modifiers[i].name)) {
887 Keyboard::set_snap_modifier (modifiers[i].modifier);
893 void snap_delta_modifier_chosen ()
895 string const txt = _snap_delta_combo.get_active_text();
897 for (int i = 0; modifiers[i].name; ++i) {
898 if (txt == S_(modifiers[i].name)) {
899 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
905 void constraint_modifier_chosen ()
907 string const txt = _constraint_modifier_combo.get_active_text();
909 for (int i = 0; modifiers[i].name; ++i) {
910 if (txt == S_(modifiers[i].name)) {
911 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
917 void trim_contents_modifier_chosen ()
919 string const txt = _trim_contents_combo.get_active_text();
921 for (int i = 0; modifiers[i].name; ++i) {
922 if (txt == S_(modifiers[i].name)) {
923 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
929 void trim_overlap_modifier_chosen ()
931 string const txt = _trim_overlap_combo.get_active_text();
933 for (int i = 0; modifiers[i].name; ++i) {
934 if (txt == S_(modifiers[i].name)) {
935 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
941 void trim_anchored_modifier_chosen ()
943 string const txt = _trim_anchored_combo.get_active_text();
945 for (int i = 0; modifiers[i].name; ++i) {
946 if (txt == S_(modifiers[i].name)) {
947 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
953 void fine_adjust_modifier_chosen ()
955 string const txt = _fine_adjust_combo.get_active_text();
957 for (int i = 0; modifiers[i].name; ++i) {
958 if (txt == S_(modifiers[i].name)) {
959 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
965 void push_points_modifier_chosen ()
967 string const txt = _push_points_combo.get_active_text();
969 for (int i = 0; modifiers[i].name; ++i) {
970 if (txt == S_(modifiers[i].name)) {
971 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
977 void note_size_relative_modifier_chosen ()
979 string const txt = _note_size_relative_combo.get_active_text();
981 for (int i = 0; modifiers[i].name; ++i) {
982 if (txt == S_(modifiers[i].name)) {
983 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
989 void delete_button_changed ()
991 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
994 void edit_button_changed ()
996 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
999 void insert_note_button_changed ()
1001 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
1004 ComboBoxText _keyboard_layout_selector;
1005 ComboBoxText _edit_modifier_combo;
1006 ComboBoxText _delete_modifier_combo;
1007 ComboBoxText _copy_modifier_combo;
1008 ComboBoxText _insert_note_modifier_combo;
1009 ComboBoxText _snap_modifier_combo;
1010 ComboBoxText _snap_delta_combo;
1011 ComboBoxText _constraint_modifier_combo;
1012 ComboBoxText _trim_contents_combo;
1013 ComboBoxText _trim_overlap_combo;
1014 ComboBoxText _trim_anchored_combo;
1015 ComboBoxText _trim_jump_combo;
1016 ComboBoxText _fine_adjust_combo;
1017 ComboBoxText _push_points_combo;
1018 ComboBoxText _note_size_relative_combo;
1019 Adjustment _delete_button_adjustment;
1020 SpinButton _delete_button_spin;
1021 Adjustment _edit_button_adjustment;
1022 SpinButton _edit_button_spin;
1023 Adjustment _insert_note_button_adjustment;
1024 SpinButton _insert_note_button_spin;
1028 class FontScalingOptions : public OptionEditorBox
1031 FontScalingOptions () :
1032 _dpi_adjustment (100, 50, 250, 1, 5),
1033 _dpi_slider (_dpi_adjustment)
1035 _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.);
1037 Label* l = manage (new Label (_("GUI and Font scaling:")));
1038 l->set_name ("OptionsLabel");
1040 const std::string dflt = _("Default");
1041 const std::string empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
1043 _dpi_slider.set_name("FontScaleSlider");
1044 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1045 _dpi_slider.set_draw_value(false);
1046 _dpi_slider.add_mark(50, Gtk::POS_TOP, empty);
1047 _dpi_slider.add_mark(60, Gtk::POS_TOP, empty);
1048 _dpi_slider.add_mark(70, Gtk::POS_TOP, empty);
1049 _dpi_slider.add_mark(80, Gtk::POS_TOP, empty);
1050 _dpi_slider.add_mark(90, Gtk::POS_TOP, empty);
1051 _dpi_slider.add_mark(100, Gtk::POS_TOP, dflt);
1052 _dpi_slider.add_mark(125, Gtk::POS_TOP, empty);
1053 _dpi_slider.add_mark(150, Gtk::POS_TOP, empty);
1054 _dpi_slider.add_mark(175, Gtk::POS_TOP, empty);
1055 _dpi_slider.add_mark(200, Gtk::POS_TOP, empty);
1056 _dpi_slider.add_mark(225, Gtk::POS_TOP, empty);
1057 _dpi_slider.add_mark(250, Gtk::POS_TOP, empty);
1059 HBox* h = manage (new HBox);
1061 h->pack_start (*l, false, false);
1062 h->pack_start (_dpi_slider, true, true);
1064 _box->pack_start (*h, false, false);
1066 set_note (_("Adjusting the scale requires an application restart to re-layout."));
1068 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
1071 void parameter_changed (string const & p)
1073 if (p == "font-scale") {
1074 _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.);
1078 void set_state_from_config ()
1080 parameter_changed ("font-scale");
1087 UIConfiguration::instance().set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024.));
1088 /* XXX: should be triggered from the parameter changed signal */
1089 UIConfiguration::instance().reset_dpi ();
1092 Adjustment _dpi_adjustment;
1096 class VstTimeOutSliderOption : public OptionEditorBox
1099 VstTimeOutSliderOption (RCConfiguration* c)
1101 , _timeout_adjustment (0, 0, 3000, 50, 50)
1102 , _timeout_slider (_timeout_adjustment)
1104 _timeout_slider.set_digits (0);
1105 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &VstTimeOutSliderOption::timeout_changed));
1107 _timeout_slider.set_draw_value(false);
1108 _timeout_slider.add_mark( 0, Gtk::POS_TOP, _("\u221e")); // infinity
1109 _timeout_slider.add_mark( 300, Gtk::POS_TOP, _("30 sec"));
1110 _timeout_slider.add_mark( 600, Gtk::POS_TOP, _("1 min"));
1111 _timeout_slider.add_mark(1200, Gtk::POS_TOP, _("2 mins"));
1112 _timeout_slider.add_mark(1800, Gtk::POS_TOP, _("3 mins"));
1113 _timeout_slider.add_mark(2400, Gtk::POS_TOP, _("4 mins"));
1114 _timeout_slider.add_mark(3000, Gtk::POS_TOP, _("5 mins"));
1116 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1117 _("Specify the default timeout for plugin instantiation. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1119 Label* l = manage (left_aligned_label (_("Scan Time Out:")));
1120 HBox* h = manage (new HBox);
1122 h->pack_start (*l, false, false);
1123 h->pack_start (_timeout_slider, true, true);
1125 _box->pack_start (*h, false, false);
1128 void parameter_changed (string const & p)
1130 if (p == "vst-scan-timeout") {
1131 int const x = _rc_config->get_vst_scan_timeout();
1132 _timeout_adjustment.set_value (x);
1136 void set_state_from_config ()
1138 parameter_changed ("vst-scan-timeout");
1143 void timeout_changed ()
1145 int x = floor(_timeout_adjustment.get_value());
1146 _rc_config->set_vst_scan_timeout(x);
1149 RCConfiguration* _rc_config;
1150 Adjustment _timeout_adjustment;
1151 HScale _timeout_slider;
1158 class ClipLevelOptions : public OptionEditorBox
1162 : _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1163 , _clip_level_slider (_clip_level_adjustment)
1165 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level ());
1167 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
1168 l->set_name ("OptionsLabel");
1170 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1171 HBox* h = manage (new HBox);
1173 h->pack_start (*l, false, false);
1174 h->pack_start (_clip_level_slider, true, true);
1176 _box->pack_start (*h, false, false);
1178 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1181 void parameter_changed (string const & p)
1183 if (p == "waveform-clip-level") {
1184 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level());
1188 void set_state_from_config ()
1190 parameter_changed ("waveform-clip-level");
1195 void clip_level_changed ()
1197 UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value());
1198 /* XXX: should be triggered from the parameter changed signal */
1199 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1202 Adjustment _clip_level_adjustment;
1203 HScale _clip_level_slider;
1206 class BufferingOptions : public OptionEditorBox
1209 BufferingOptions (RCConfiguration* c)
1211 , _playback_adjustment (5, 1, 60, 1, 4)
1212 , _capture_adjustment (5, 1, 60, 1, 4)
1213 , _playback_slider (_playback_adjustment)
1214 , _capture_slider (_capture_adjustment)
1216 vector<string> presets;
1218 /* these must match the order of the enums for BufferingPreset */
1220 presets.push_back (_("Small sessions (4-16 tracks)"));
1221 presets.push_back (_("Medium sessions (16-64 tracks)"));
1222 presets.push_back (_("Large sessions (64+ tracks)"));
1223 presets.push_back (_("Custom (set by sliders below)"));
1225 set_popdown_strings (_buffering_presets_combo, presets);
1227 Label* l = manage (new Label (_("Preset:")));
1228 l->set_name ("OptionsLabel");
1229 HBox* h = manage (new HBox);
1230 h->set_spacing (12);
1231 h->pack_start (*l, false, false);
1232 h->pack_start (_buffering_presets_combo, true, true);
1233 _box->pack_start (*h, false, false);
1235 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1237 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1239 l = manage (new Label (_("Playback (seconds of buffering):")));
1240 l->set_name ("OptionsLabel");
1242 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1243 h = manage (new HBox);
1245 h->pack_start (*l, false, false);
1246 h->pack_start (_playback_slider, true, true);
1248 _box->pack_start (*h, false, false);
1250 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1252 l = manage (new Label (_("Recording (seconds of buffering):")));
1253 l->set_name ("OptionsLabel");
1255 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1256 h = manage (new HBox);
1258 h->pack_start (*l, false, false);
1259 h->pack_start (_capture_slider, true, true);
1261 _box->pack_start (*h, false, false);
1263 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
1264 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
1267 void parameter_changed (string const & p)
1269 if (p == "buffering-preset") {
1270 switch (_rc_config->get_buffering_preset()) {
1272 _playback_slider.set_sensitive (false);
1273 _capture_slider.set_sensitive (false);
1274 _buffering_presets_combo.set_active (0);
1277 _playback_slider.set_sensitive (false);
1278 _capture_slider.set_sensitive (false);
1279 _buffering_presets_combo.set_active (1);
1282 _playback_slider.set_sensitive (false);
1283 _capture_slider.set_sensitive (false);
1284 _buffering_presets_combo.set_active (2);
1287 _playback_slider.set_sensitive (true);
1288 _capture_slider.set_sensitive (true);
1289 _buffering_presets_combo.set_active (3);
1294 if (p == "playback-buffer-seconds") {
1295 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1296 } else if (p == "capture-buffer-seconds") {
1297 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1301 void set_state_from_config ()
1303 parameter_changed ("buffering-preset");
1304 parameter_changed ("playback-buffer-seconds");
1305 parameter_changed ("capture-buffer-seconds");
1310 void preset_changed ()
1312 int index = _buffering_presets_combo.get_active_row_number ();
1318 _rc_config->set_buffering_preset (Small);
1321 _rc_config->set_buffering_preset (Medium);
1324 _rc_config->set_buffering_preset (Large);
1327 _rc_config->set_buffering_preset (Custom);
1330 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1335 void playback_changed ()
1337 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
1340 void capture_changed ()
1342 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
1345 RCConfiguration* _rc_config;
1346 Adjustment _playback_adjustment;
1347 Adjustment _capture_adjustment;
1348 HScale _playback_slider;
1349 HScale _capture_slider;
1350 ComboBoxText _buffering_presets_combo;
1353 class ControlSurfacesOptions : public OptionEditorBox
1356 ControlSurfacesOptions ()
1357 : _ignore_view_change (0)
1359 _store = ListStore::create (_model);
1360 _view.set_model (_store);
1361 _view.append_column (_("Control Surface Protocol"), _model.name);
1362 _view.get_column(0)->set_resizable (true);
1363 _view.get_column(0)->set_expand (true);
1364 _view.append_column_editable (_("Enabled"), _model.enabled);
1365 _view.append_column_editable (_("Feedback"), _model.feedback);
1367 _box->pack_start (_view, false, false);
1369 Gtk::HBox* edit_box = manage (new Gtk::HBox);
1370 edit_box->set_spacing(3);
1371 _box->pack_start (*edit_box, false, false);
1374 Label* label = manage (new Label);
1375 label->set_text (_("Click to edit the settings for selected protocol ( it must be ENABLED first ):"));
1376 edit_box->pack_start (*label, false, false);
1379 edit_button = manage (new Button(_("Show Protocol Settings")));
1380 edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
1381 edit_box->pack_start (*edit_button, true, true);
1382 edit_button->set_sensitive (false);
1383 edit_button->show ();
1385 ControlProtocolManager& m = ControlProtocolManager::instance ();
1386 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1387 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1389 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1390 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1391 _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
1394 void parameter_changed (std::string const &)
1399 void set_state_from_config ()
1403 ControlProtocolManager& m = ControlProtocolManager::instance ();
1404 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1406 if (!(*i)->mandatory) {
1407 TreeModel::Row r = *_store->append ();
1408 r[_model.name] = (*i)->name;
1409 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1410 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
1411 r[_model.protocol_info] = *i;
1418 void protocol_status_changed (ControlProtocolInfo* cpi) {
1420 TreeModel::Children rows = _store->children();
1422 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1423 string n = ((*x)[_model.name]);
1425 if ((*x)[_model.protocol_info] == cpi) {
1426 _ignore_view_change++;
1427 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1428 _ignore_view_change--;
1434 void selection_changed ()
1436 //enable the Edit button when a row is selected for editing
1437 TreeModel::Row row = *(_view.get_selection()->get_selected());
1438 if (row && row[_model.enabled])
1439 edit_button->set_sensitive (true);
1441 edit_button->set_sensitive (false);
1444 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1446 TreeModel::Row r = *i;
1448 if (_ignore_view_change) {
1452 ControlProtocolInfo* cpi = r[_model.protocol_info];
1457 bool const was_enabled = (cpi->protocol != 0);
1458 bool const is_enabled = r[_model.enabled];
1461 if (was_enabled != is_enabled) {
1464 ControlProtocolManager::instance().activate (*cpi);
1466 ControlProtocolManager::instance().deactivate (*cpi);
1470 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
1471 bool const is_feedback = r[_model.feedback];
1473 if (was_feedback != is_feedback && cpi->protocol) {
1474 cpi->protocol->set_feedback (is_feedback);
1478 void edit_btn_clicked ()
1481 ControlProtocolInfo* cpi;
1484 row = *(_view.get_selection()->get_selected());
1485 if (!row[_model.enabled]) {
1488 cpi = row[_model.protocol_info];
1489 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1492 Box* box = (Box*) cpi->protocol->get_gui ();
1496 if (box->get_parent()) {
1497 static_cast<ArdourWindow*>(box->get_parent())->present();
1500 WindowTitle title (Glib::get_application_name());
1501 title += row[_model.name];
1502 title += _("Configuration");
1503 /* once created, the window is managed by the surface itself (as ->get_parent())
1504 * Surface's tear_down_gui() is called on session close, when de-activating
1505 * or re-initializing a surface.
1506 * tear_down_gui() hides an deletes the Window if it exists.
1508 ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string());
1509 win->set_title ("Control Protocol Options");
1515 void edit_clicked (GdkEventButton* ev)
1517 if (ev->type != GDK_2BUTTON_PRESS) {
1524 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1528 ControlSurfacesModelColumns ()
1533 add (protocol_info);
1536 TreeModelColumn<string> name;
1537 TreeModelColumn<bool> enabled;
1538 TreeModelColumn<bool> feedback;
1539 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1542 Glib::RefPtr<ListStore> _store;
1543 ControlSurfacesModelColumns _model;
1545 PBD::ScopedConnection protocol_status_connection;
1546 uint32_t _ignore_view_change;
1547 Gtk::Button* edit_button;
1550 class VideoTimelineOptions : public OptionEditorBox
1553 VideoTimelineOptions (RCConfiguration* c)
1555 , _show_video_export_info_button (_("Show Video Export Info before export"))
1556 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1557 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1558 , _xjadeo_browse_button (_("Browse..."))
1560 Table* t = manage (new Table (8, 4));
1561 t->set_spacings (4);
1563 std::stringstream s;
1564 s << "<b>" << _("Video Server") << "</b>";
1565 Label* l = manage (new Label (s.str()));
1566 l->set_use_markup (true);
1567 l->set_alignment (0, 0.5);
1568 t->attach (*l, 0, 4, 0, 1, EXPAND | FILL, FILL | EXPAND, 0, 8);
1570 t->attach (_video_advanced_setup_button, 1, 4, 1, 2);
1571 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1572 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1573 _("<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."));
1575 l = manage (new Label (_("Video Server URL:")));
1576 l->set_alignment (0, 0.5);
1577 t->attach (*l, 1, 2, 2, 3, FILL);
1578 t->attach (_video_server_url_entry, 2, 4, 2, 3, FILL);
1579 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1580 _("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"));
1582 l = manage (new Label (_("Video Folder:")));
1583 l->set_alignment (0, 0.5);
1584 t->attach (*l, 1, 2, 3, 4, FILL);
1585 t->attach (_video_server_docroot_entry, 2, 4, 3, 4);
1586 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1587 _("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."));
1589 t->attach (_show_video_export_info_button, 1, 4, 4, 5);
1590 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1591 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1592 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1594 t->attach (_show_video_server_dialog_button, 1, 4, 5, 6);
1595 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1596 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1597 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1599 s.str (std::string ());
1600 s << "<b>" << _("Video Monitor") << "</b>";
1601 l = manage (new Label (s.str()));
1602 l->set_use_markup (true);
1603 l->set_alignment (0, 0.5);
1604 t->attach (*l, 0, 4, 6, 7, EXPAND | FILL, FILL | EXPAND, 0, 8);
1606 l = manage (new Label (string_compose (_("Custom Path to Video Monitor (%1) - leave empty for default:"),
1609 #elif defined PLATFORM_WINDOWS
1615 l->set_alignment (0, 0.5);
1616 t->attach (*l, 1, 4, 7, 8, FILL);
1617 t->attach (_custom_xjadeo_path, 2, 3, 8, 9);
1618 Gtkmm2ext::UI::instance()->set_tip (_custom_xjadeo_path, _("Set a custom path to the Video Monitor Executable, changing this requires a restart."));
1619 t->attach (_xjadeo_browse_button, 3, 4, 8, 9, FILL);
1621 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1622 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1623 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1624 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1625 _custom_xjadeo_path.signal_changed().connect (sigc::mem_fun (*this, &VideoTimelineOptions::custom_xjadeo_path_changed));
1626 _xjadeo_browse_button.signal_clicked ().connect (sigc::mem_fun (*this, &VideoTimelineOptions::xjadeo_browse_clicked));
1628 // xjadeo-path is a UIConfig parameter
1629 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &VideoTimelineOptions::parameter_changed));
1631 _box->pack_start (*t,true,true);
1634 void server_url_changed ()
1636 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1639 void server_docroot_changed ()
1641 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1644 void show_video_export_info_toggled ()
1646 bool const x = _show_video_export_info_button.get_active ();
1647 _rc_config->set_show_video_export_info (x);
1650 void show_video_server_dialog_toggled ()
1652 bool const x = _show_video_server_dialog_button.get_active ();
1653 _rc_config->set_show_video_server_dialog (x);
1656 void video_advanced_setup_toggled ()
1658 bool const x = _video_advanced_setup_button.get_active ();
1659 _rc_config->set_video_advanced_setup(x);
1662 void custom_xjadeo_path_changed ()
1664 UIConfiguration::instance().set_xjadeo_binary (_custom_xjadeo_path.get_text());
1667 void xjadeo_browse_clicked ()
1669 Gtk::FileChooserDialog dialog(_("Set Video Monitor Executable"), Gtk::FILE_CHOOSER_ACTION_OPEN);
1670 dialog.set_filename (UIConfiguration::instance().get_xjadeo_binary());
1671 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1672 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1673 if (dialog.run () == Gtk::RESPONSE_OK) {
1674 const std::string& filename = dialog.get_filename();
1675 if (!filename.empty() && (
1677 Glib::file_test (filename + "/Contents/MacOS/xjadeo", Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) ||
1679 Glib::file_test (filename, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)
1681 UIConfiguration::instance().set_xjadeo_binary (filename);
1686 void parameter_changed (string const & p)
1688 if (p == "video-server-url") {
1689 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1690 } else if (p == "video-server-docroot") {
1691 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1692 } else if (p == "show-video-export-info") {
1693 bool const x = _rc_config->get_show_video_export_info();
1694 _show_video_export_info_button.set_active (x);
1695 } else if (p == "show-video-server-dialog") {
1696 bool const x = _rc_config->get_show_video_server_dialog();
1697 _show_video_server_dialog_button.set_active (x);
1698 } else if (p == "video-advanced-setup") {
1699 bool const x = _rc_config->get_video_advanced_setup();
1700 _video_advanced_setup_button.set_active(x);
1701 _video_server_docroot_entry.set_sensitive(x);
1702 _video_server_url_entry.set_sensitive(x);
1703 } else if (p == "xjadeo-binary") {
1704 _custom_xjadeo_path.set_text (UIConfiguration::instance().get_xjadeo_binary());
1708 void set_state_from_config ()
1710 parameter_changed ("video-server-url");
1711 parameter_changed ("video-server-docroot");
1712 parameter_changed ("video-monitor-setup-dialog");
1713 parameter_changed ("show-video-export-info");
1714 parameter_changed ("show-video-server-dialog");
1715 parameter_changed ("video-advanced-setup");
1716 parameter_changed ("xjadeo-binary");
1720 RCConfiguration* _rc_config;
1721 Entry _video_server_url_entry;
1722 Entry _video_server_docroot_entry;
1723 Entry _custom_xjadeo_path;
1724 CheckButton _show_video_export_info_button;
1725 CheckButton _show_video_server_dialog_button;
1726 CheckButton _video_advanced_setup_button;
1727 Button _xjadeo_browse_button;
1730 class ColumVisibilityOption : public Option
1733 ColumVisibilityOption (string id, string name, uint32_t n_col, sigc::slot<uint32_t> get, sigc::slot<bool, uint32_t> set)
1740 cb = (CheckButton**) malloc (sizeof (CheckButton*) * n_col);
1741 for (uint32_t i = 0; i < n_col; ++i) {
1742 CheckButton* col = manage (new CheckButton (string_compose (_("Column %1"), i + 1)));
1743 col->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &ColumVisibilityOption::column_toggled), i));
1744 _hbox.pack_start (*col);
1747 parameter_changed (id);
1750 ~ColumVisibilityOption () {
1754 Gtk::Widget& tip_widget() { return _hbox; }
1756 void set_state_from_config ()
1758 uint32_t c = _get();
1759 for (uint32_t i = 0; i < _n_col; ++i) {
1760 bool en = (c & (1<<i)) ? true : false;
1761 if (cb[i]->get_active () != en) {
1762 cb[i]->set_active (en);
1767 void add_to_page (OptionEditorPage* p)
1769 _heading.add_to_page (p);
1770 add_widget_to_page (p, &_hbox);
1774 void column_toggled (int b) {
1775 uint32_t c = _get();
1777 if (cb[b]->get_active ()) {
1788 OptionEditorHeading _heading;
1792 sigc::slot<uint32_t> _get;
1793 sigc::slot<bool, uint32_t> _set;
1797 /** A class which allows control of visibility of some editor components usign
1798 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1799 * which has the correct members, but with null widget pointers. This
1800 * class allows the user to set visibility of the members, the details
1801 * of which are stored in a configuration variable which can be watched
1802 * by parts of the editor that actually contain the widgets whose visibility
1803 * is being controlled.
1806 class VisibilityOption : public Option
1809 /** @param name User-visible name for this group.
1810 * @param g `Dummy' VisibilityGroup (as described above).
1811 * @param get Method to get the value of the appropriate configuration variable.
1812 * @param set Method to set the value of the appropriate configuration variable.
1814 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1815 : Option (g->get_state_name(), name)
1817 , _visibility_group (g)
1821 /* Watch for changes made by the user to our members */
1822 _visibility_group->VisibilityChanged.connect_same_thread (
1823 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1827 void set_state_from_config ()
1829 /* Set our state from the current configuration */
1830 _visibility_group->set_state (_get ());
1833 void add_to_page (OptionEditorPage* p)
1835 _heading.add_to_page (p);
1836 add_widget_to_page (p, _visibility_group->list_view ());
1839 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1844 /* The user has changed something, so reflect this change
1845 in the RCConfiguration.
1847 _set (_visibility_group->get_state_value ());
1850 OptionEditorHeading _heading;
1851 VisibilityGroup* _visibility_group;
1852 sigc::slot<std::string> _get;
1853 sigc::slot<bool, std::string> _set;
1854 PBD::ScopedConnection _visibility_group_connection;
1859 RCOptionEditor::RCOptionEditor ()
1860 : OptionEditorContainer (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1861 , Tabbable (*this, _("Preferences")) /* pack self-as-vbox into tabbable */
1862 , _rc_config (Config)
1863 , _mixer_strip_visibility ("mixer-element-visibility")
1865 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
1867 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
1868 (Gtk::StateType) here !!!
1870 Tabbable::set_state (*node, Stateful::loading_state_version);
1873 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed));
1877 uint32_t hwcpus = hardware_concurrency ();
1879 BoolComboOption* bco;
1882 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1884 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1886 _("Signal processing uses"),
1887 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1888 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1891 procs->add (-1, _("all but one processor"));
1892 procs->add (0, _("all available processors"));
1894 for (uint32_t i = 1; i <= hwcpus; ++i) {
1895 procs->add (i, string_compose (_("%1 processors"), i));
1898 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1900 add_option (_("Misc"), procs);
1903 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1905 add_option (_("Misc"), new UndoOptions (_rc_config));
1907 add_option (_("Misc"),
1909 "verify-remove-last-capture",
1910 _("Verify removal of last capture"),
1911 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1912 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1915 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1917 add_option (_("Misc"),
1919 "periodic-safety-backups",
1920 _("Make periodic backups of the session file"),
1921 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1922 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1925 add_option (_("Misc"),
1927 "only-copy-imported-files",
1928 _("Always copy imported files"),
1929 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
1930 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
1933 add_option (_("Misc"), new DirectoryOption (
1934 X_("default-session-parent-dir"),
1935 _("Default folder for new sessions:"),
1936 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1937 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1940 add_option (_("Misc"),
1941 new SpinOption<uint32_t> (
1942 "max-recent-sessions",
1943 _("Maximum number of recent sessions"),
1944 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1945 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1949 add_option (_("Misc/Click"), new OptionEditorHeading (_("Click")));
1951 add_option (_("Misc/Click"), new ClickOptions (_rc_config));
1953 add_option (_("Misc/Click"),
1956 _("Click gain level"),
1957 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1958 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1961 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1963 add_option (_("Misc"),
1964 new SpinOption<double> (
1965 "automation-thinning-factor",
1966 _("Thinning factor (larger value => less data)"),
1967 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1968 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1972 add_option (_("Misc"),
1973 new SpinOption<double> (
1974 "automation-interval-msecs",
1975 _("Automation sampling interval (milliseconds)"),
1976 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1977 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1983 add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options")));
1987 tsf = new BoolOption (
1988 "latched-record-enable",
1989 _("Keep record-enable engaged on stop"),
1990 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1991 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1993 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1994 add_option (_("Transport"), tsf);
1996 tsf = new BoolOption (
1998 _("Play loop is a transport mode"),
1999 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
2000 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
2002 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2003 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
2004 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
2005 add_option (_("Transport"), tsf);
2007 tsf = new BoolOption (
2008 "stop-recording-on-xrun",
2009 _("Stop recording when an xrun occurs"),
2010 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
2011 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
2013 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2014 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
2016 add_option (_("Transport"), tsf);
2018 tsf = new BoolOption (
2019 "create-xrun-marker",
2020 _("Create markers where xruns occur"),
2021 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
2022 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
2024 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
2025 add_option (_("Transport"), tsf);
2027 tsf = new BoolOption (
2028 "stop-at-session-end",
2029 _("Stop at the end of the session"),
2030 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
2031 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
2033 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2034 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
2035 "when it reaches the current session end marker\n\n"
2036 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
2038 add_option (_("Transport"), tsf);
2040 tsf = new BoolOption (
2042 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
2043 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
2044 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
2046 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2047 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
2048 "preventing any need to do a transport locate at the end of the loop\n\n"
2049 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
2050 "which will often cause a small click or delay"), PROGRAM_NAME));
2051 add_option (_("Transport"), tsf);
2053 tsf = new BoolOption (
2054 "disable-disarm-during-roll",
2055 _("Disable per-track record disarm while rolling"),
2056 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
2057 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
2059 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"));
2060 add_option (_("Transport"), tsf);
2062 tsf = new BoolOption (
2064 _("12dB gain reduction during fast-forward and fast-rewind"),
2065 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
2066 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
2068 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
2069 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
2070 add_option (_("Transport"), tsf);
2072 ComboOption<float>* psc = new ComboOption<float> (
2075 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
2076 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
2078 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
2079 (_("The amount of preroll (in seconds) to apply when <b>Play with Preroll</b> is initiated.\n\n"
2080 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
2081 psc->add (0.0, _("0 (no pre-roll)"));
2082 psc->add (0.1, _("0.1 second"));
2083 psc->add (0.25, _("0.25 second"));
2084 psc->add (0.5, _("0.5 second"));
2085 psc->add (1.0, _("1.0 second"));
2086 psc->add (2.0, _("2.0 seconds"));
2087 add_option (_("Transport"), psc);
2089 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("Synchronization and Slave Options")));
2091 _sync_source = new ComboOption<SyncSource> (
2093 _("External timecode source"),
2094 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
2095 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
2098 add_option (_("Transport/Sync"), _sync_source);
2100 _sync_framerate = new BoolOption (
2101 "timecode-sync-frame-rate",
2102 _("Match session video frame rate to external timecode"),
2103 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
2104 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
2106 Gtkmm2ext::UI::instance()->set_tip
2107 (_sync_framerate->tip_widget(),
2108 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
2109 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
2110 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
2111 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
2112 "timecode standard and the session standard."), PROGRAM_NAME));
2114 add_option (_("Transport/Sync"), _sync_framerate);
2116 _sync_genlock = new BoolOption (
2117 "timecode-source-is-synced",
2118 _("Sync-lock timecode to clock (disable drift compensation)"),
2119 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
2120 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
2122 Gtkmm2ext::UI::instance()->set_tip
2123 (_sync_genlock->tip_widget(),
2124 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
2125 "Sync Lock indicates that the selected external timecode source shares clock-sync "
2126 "(Black & Burst, Wordclock, etc) with the audio interface. "
2127 "This option disables drift compensation. The transport speed is fixed at 1.0. "
2128 "Vari-speed LTC will be ignored and cause drift."
2130 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
2131 "timecode sources shares clock sync."
2135 add_option (_("Transport/Sync"), _sync_genlock);
2137 _sync_source_2997 = new BoolOption (
2138 "timecode-source-2997",
2139 _("Lock to 29.9700 fps instead of 30000/1001"),
2140 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
2141 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
2143 Gtkmm2ext::UI::instance()->set_tip
2144 (_sync_source_2997->tip_widget(),
2145 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
2146 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
2147 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
2148 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
2149 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
2150 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
2153 add_option (_("Transport/Sync"), _sync_source_2997);
2155 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("LTC Reader")));
2157 _ltc_port = new ComboStringOption (
2159 _("LTC incoming port"),
2160 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
2161 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
2164 vector<string> physical_inputs;
2165 physical_inputs.push_back (_("None"));
2166 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
2167 _ltc_port->set_popdown_strings (physical_inputs);
2169 populate_sync_options ();
2170 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
2172 add_option (_("Transport/Sync"), _ltc_port);
2174 // TODO; rather disable this button than not compile it..
2175 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("LTC Generator")));
2177 add_option (_("Transport/Sync"),
2180 _("Enable LTC generator"),
2181 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
2182 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
2185 _ltc_send_continuously = new BoolOption (
2186 "ltc-send-continuously",
2187 _("Send LTC while stopped"),
2188 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
2189 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
2191 Gtkmm2ext::UI::instance()->set_tip
2192 (_ltc_send_continuously->tip_widget(),
2193 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
2194 add_option (_("Transport"), _ltc_send_continuously);
2196 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
2197 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
2198 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
2199 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
2201 Gtkmm2ext::UI::instance()->set_tip
2202 (_ltc_volume_slider->tip_widget(),
2203 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
2205 add_option (_("Transport/Sync"), _ltc_volume_slider);
2209 add_option (_("Editor"),
2211 "rubberbanding-snaps-to-grid",
2212 _("Make rubberband selection rectangle snap to the grid"),
2213 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2214 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2217 bo = new BoolOption (
2219 _("Name new markers"),
2220 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2221 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2223 add_option (_("Editor"), bo);
2224 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."
2225 "\n\nYou can always rename markers by right-clicking on them"));
2227 add_option (S_("Editor"),
2229 "draggable-playhead",
2230 _("Allow dragging of playhead"),
2231 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2232 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2235 add_option (_("Editor"),
2237 "show-editor-meter",
2238 _("Display master-meter in the toolbar"),
2239 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
2240 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
2243 if (!Profile->get_mixbus()) {
2244 add_option (_("Editor"),
2247 _("Show zoom toolbar (if torn off)"),
2248 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_zoom_tools),
2249 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_zoom_tools)
2252 add_option (_("Editor"),
2254 "use-mouse-position-as-zoom-focus-on-scroll",
2255 _("Always use mouse cursor position as zoom focus when zooming using mouse scroll wheel"),
2256 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2257 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2261 add_option (_("Editor"),
2263 "update-editor-during-summary-drag",
2264 _("Update editor window during drags of the summary"),
2265 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2266 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2269 add_option (_("Editor"),
2271 "autoscroll-editor",
2272 _("Auto-scroll editor window when dragging near its edges"),
2273 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2274 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2277 add_option (_("Editor"),
2278 new BoolComboOption (
2279 "show-region-gain-envelopes",
2280 _("Show gain envelopes in audio regions"),
2282 _("only in Draw and Internal Edit modes"),
2283 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2284 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2287 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2289 add_option (_("Editor"),
2291 "automation-follows-regions",
2292 _("Move relevant automation when audio regions are moved"),
2293 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2294 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2297 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2298 "default-fade-shape",
2299 _("Default fade shape"),
2300 sigc::mem_fun (*_rc_config,
2301 &RCConfiguration::get_default_fade_shape),
2302 sigc::mem_fun (*_rc_config,
2303 &RCConfiguration::set_default_fade_shape)
2306 fadeshape->add (FadeLinear,
2307 _("Linear (for highly correlated material)"));
2308 fadeshape->add (FadeConstantPower, _("Constant power"));
2309 fadeshape->add (FadeSymmetric, _("Symmetric"));
2310 fadeshape->add (FadeSlow, _("Slow"));
2311 fadeshape->add (FadeFast, _("Fast"));
2313 add_option (_("Editor"), fadeshape);
2316 bco = new BoolComboOption (
2317 "use-overlap-equivalency",
2318 _("Regions in active edit groups are edited together"),
2319 _("whenever they overlap in time"),
2320 _("only if they have identical length, position and origin"),
2321 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2322 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2325 add_option (_("Editor"), bco);
2327 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2329 _("Layering model"),
2330 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2331 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2334 lm->add (LaterHigher, _("later is higher"));
2335 lm->add (Manual, _("manual layering"));
2336 add_option (_("Editor"), lm);
2338 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2339 "region-selection-after-split",
2340 _("After splitting selected regions, select"),
2341 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2342 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2344 // TODO: decide which of these modes are really useful
2345 rsas->add(None, _("no regions"));
2346 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2347 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2348 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2349 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2350 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2351 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2352 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2354 add_option (_("Editor"), rsas);
2356 add_option (_("Editor/Waveforms"), new OptionEditorHeading (_("Waveforms")));
2358 if (!Profile->get_mixbus()) {
2359 add_option (_("Editor/Waveforms"),
2362 _("Show waveforms in regions"),
2363 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
2364 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
2368 add_option (_("Editor/Waveforms"),
2370 "show-waveforms-while-recording",
2371 _("Show waveforms for audio while it is being recorded"),
2372 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
2373 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
2376 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
2378 _("Waveform scale"),
2379 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
2380 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
2383 wfs->add (Linear, _("linear"));
2384 wfs->add (Logarithmic, _("logarithmic"));
2386 add_option (_("Editor/Waveforms"), wfs);
2388 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
2390 _("Waveform shape"),
2391 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
2392 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
2395 wfsh->add (Traditional, _("traditional"));
2396 wfsh->add (Rectified, _("rectified"));
2398 add_option (_("Editor/Waveforms"), wfsh);
2400 add_option (_("Editor/Waveforms"), new ClipLevelOptions ());
2405 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2407 add_option (_("Audio"), new BufferingOptions (_rc_config));
2409 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2411 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2413 _("Record monitoring handled by"),
2414 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2415 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2418 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2419 mm->add (HardwareMonitoring, _("via Audio Driver"));
2422 string prog (PROGRAM_NAME);
2423 boost::algorithm::to_lower (prog);
2424 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2425 mm->add (ExternalMonitoring, _("audio hardware"));
2427 add_option (_("Audio"), mm);
2429 add_option (_("Audio"),
2431 "tape-machine-mode",
2432 _("Tape machine mode"),
2433 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2434 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2437 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
2438 if (!Profile->get_mixbus()) {
2440 add_option (_("Audio"),
2442 "auto-connect-standard-busses",
2443 _("Auto-connect master/monitor busses"),
2444 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2445 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2448 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2449 "input-auto-connect",
2450 _("Connect track inputs"),
2451 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2452 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2455 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2456 iac->add (ManualConnect, _("manually"));
2458 add_option (_("Audio"), iac);
2460 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2461 "output-auto-connect",
2462 _("Connect track and bus outputs"),
2463 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2464 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2467 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2468 oac->add (AutoConnectMaster, _("automatically to master bus"));
2469 oac->add (ManualConnect, _("manually"));
2471 add_option (_("Audio"), oac);
2473 bo = new BoolOption (
2475 _("Use 'Strict-I/O' for new tracks or Busses"),
2476 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2477 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2480 add_option (_("Audio"), bo);
2481 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2482 _("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."));
2486 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2488 add_option (_("Audio"),
2490 "denormal-protection",
2491 _("Use DC bias to protect against denormals"),
2492 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2493 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2496 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2498 _("Processor handling"),
2499 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2500 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2504 dm->add (DenormalNone, _("no processor handling"));
2506 FPU* fpu = FPU::instance();
2508 if (fpu->has_flush_to_zero()) {
2510 dm->add (DenormalFTZ, _("use FlushToZero"));
2511 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2512 _rc_config->set_denormal_model(DenormalNone);
2515 if (fpu->has_denormals_are_zero()) {
2517 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2518 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2519 _rc_config->set_denormal_model(DenormalNone);
2522 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2524 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2525 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2526 _rc_config->set_denormal_model(DenormalNone);
2530 dm->set_sensitive(false);
2533 add_option (_("Audio"), dm);
2535 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2537 add_option (_("Audio"),
2539 "auto-analyse-audio",
2540 _("Enable automatic analysis of audio"),
2541 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2542 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2545 add_option (_("Audio"),
2547 "replicate-missing-region-channels",
2548 _("Replicate missing region channels"),
2549 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2550 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2555 add_option (_("Solo & mute"), new OptionEditorHeading (_("Solo")));
2557 _solo_control_is_listen_control = new BoolOption (
2558 "solo-control-is-listen-control",
2559 _("Solo controls are Listen controls"),
2560 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2561 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2564 add_option (_("Solo & mute"), _solo_control_is_listen_control);
2566 add_option (_("Solo & mute"),
2569 _("Exclusive solo"),
2570 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2571 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2574 add_option (_("Solo & mute"),
2577 _("Show solo muting"),
2578 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2579 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2582 add_option (_("Solo & mute"),
2584 "solo-mute-override",
2585 _("Soloing overrides muting"),
2586 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2587 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2590 add_option (_("Solo & mute"),
2593 _("Solo-in-place mute cut (dB)"),
2594 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2595 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2598 _listen_position = new ComboOption<ListenPosition> (
2600 _("Listen Position"),
2601 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2602 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2605 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2606 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2608 add_option (_("Solo & mute"), _listen_position);
2610 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2612 _("PFL signals come from"),
2613 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2614 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2617 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2618 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2620 add_option (_("Solo & mute"), pp);
2622 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2624 _("AFL signals come from"),
2625 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2626 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2629 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2630 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2632 add_option (_("Solo & mute"), pa);
2634 add_option (_("Solo & mute"), new OptionEditorHeading (_("Default track / bus muting options")));
2636 add_option (_("Solo & mute"),
2638 "mute-affects-pre-fader",
2639 _("Mute affects pre-fader sends"),
2640 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2641 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2644 add_option (_("Solo & mute"),
2646 "mute-affects-post-fader",
2647 _("Mute affects post-fader sends"),
2648 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2649 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2652 add_option (_("Solo & mute"),
2654 "mute-affects-control-outs",
2655 _("Mute affects control outputs"),
2656 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2657 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2660 add_option (_("Solo & mute"),
2662 "mute-affects-main-outs",
2663 _("Mute affects main outputs"),
2664 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2665 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2669 if (!ARDOUR::Profile->get_mixbus()) {
2670 add_option (_("Solo & mute"), new OptionEditorHeading (_("Send Routing")));
2671 add_option (_("Solo & mute"),
2673 "link-send-and-route-panner",
2674 _("Link panners of Aux and External Sends with main panner by default"),
2675 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2676 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2680 add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Preferences")));
2682 add_option (_("MIDI"),
2683 new SpinOption<float> (
2685 _("MIDI read-ahead time (seconds)"),
2686 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2687 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2692 add_option (_("MIDI"),
2693 new SpinOption<int32_t> (
2694 "initial-program-change",
2695 _("Initial program change"),
2696 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2697 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2701 add_option (_("MIDI"),
2703 "display-first-midi-bank-as-zero",
2704 _("Display first MIDI bank/program as 0"),
2705 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2706 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2709 add_option (_("MIDI"),
2711 "never-display-periodic-midi",
2712 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2713 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
2714 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
2717 add_option (_("MIDI"),
2720 _("Sound MIDI notes as they are selected in the editor"),
2721 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2722 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2725 add_option (_("MIDI"),
2728 _("Send MIDI control feedback"),
2729 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2730 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2733 add_option (_("MIDI/Sync"), new OptionEditorHeading (_("MIDI Clock")));
2735 add_option (_("MIDI/Sync"),
2738 _("Send MIDI Clock"),
2739 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2740 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2743 add_option (_("MIDI/Sync"), new OptionEditorHeading (_("MIDI Time Code (MTC)")));
2745 add_option (_("MIDI/Sync"),
2748 _("Send MIDI Time Code"),
2749 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2750 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2753 add_option (_("MIDI/Sync"),
2754 new SpinOption<int> (
2755 "mtc-qf-speed-tolerance",
2756 _("Percentage either side of normal transport speed to transmit MTC"),
2757 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2758 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2762 add_option (_("MIDI/Sync"), new OptionEditorHeading (_("Midi Machine Control (MMC)")));
2764 add_option (_("MIDI/Sync"),
2767 _("Obey MIDI Machine Control commands"),
2768 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2769 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2772 add_option (_("MIDI/Sync"),
2775 _("Send MIDI Machine Control commands"),
2776 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2777 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2780 add_option (_("MIDI/Sync"),
2781 new SpinOption<uint8_t> (
2782 "mmc-receive-device-id",
2783 _("Inbound MMC device ID"),
2784 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2785 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2789 add_option (_("MIDI/Sync"),
2790 new SpinOption<uint8_t> (
2791 "mmc-send-device-id",
2792 _("Outbound MMC device ID"),
2793 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2794 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2798 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2800 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2801 "midi-audition-synth-uri",
2802 _("Midi Audition Synth (LV2)"),
2803 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2804 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2807 audition_synth->add(X_(""), _("None"));
2808 PluginInfoList all_plugs;
2809 PluginManager& manager (PluginManager::instance());
2811 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2813 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2814 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2815 if (!(*i)->is_instrument()) continue;
2816 if ((*i)->type != ARDOUR::LV2) continue;
2817 audition_synth->add((*i)->unique_id, (*i)->name);
2821 add_option (_("MIDI"), audition_synth);
2823 /* USER INTERACTION */
2826 #ifdef PLATFORM_WINDOWS
2829 getenv ("ARDOUR_BUNDLED")
2833 add_option (_("User interaction"),
2835 "enable-translation",
2836 string_compose (_("Use translations of %1 messages\n"
2837 " <i>(requires a restart of %1 to take effect)</i>\n"
2838 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2839 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2840 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2843 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2845 add_option (_("User interaction"), new KeyboardOptions);
2847 /* Control Surfaces */
2849 add_option (_("Control Surfaces"), new ControlSurfacesOptions);
2851 /* VIDEO Timeline */
2852 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2854 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2855 add_option (_("Plugins"),
2856 new RcActionButton (_("Scan for Plugins"),
2857 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
2861 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
2863 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2864 bo = new BoolOption (
2865 "show-plugin-scan-window",
2866 _("Always Display Plugin Scan Progress"),
2867 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
2868 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
2870 add_option (_("Plugins"), bo);
2871 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2872 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
2875 bo = new BoolOption (
2876 "plugins-stop-with-transport",
2877 _("Silence plugins when the transport is stopped"),
2878 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
2879 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
2881 add_option (_("Plugins"), bo);
2882 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2883 _("<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."));
2885 bo = new BoolOption (
2886 "new-plugins-active",
2887 _("Make new plugins active"),
2888 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
2889 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
2891 add_option (_("Plugins"), bo);
2892 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2893 _("<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"));
2895 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
2896 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
2897 add_option (_("Plugins/VST"),
2898 new RcActionButton (_("Scan for Plugins"),
2899 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
2901 bo = new BoolOption (
2902 "discover-vst-on-start",
2903 _("Scan for [new] VST Plugins on Application Start"),
2904 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
2905 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
2907 add_option (_("Plugins/VST"), bo);
2908 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2909 _("<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"));
2911 #ifdef WINDOWS_VST_SUPPORT
2912 // currently verbose logging is only implemented for Windows VST.
2913 bo = new BoolOption (
2914 "verbose-plugin-scan",
2915 _("Verbose Plugin Scan"),
2916 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
2917 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
2919 add_option (_("Plugins/VST"), bo);
2920 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2921 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
2924 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
2926 add_option (_("Plugins/VST"),
2927 new RcActionButton (_("Clear"),
2928 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
2931 add_option (_("Plugins/VST"),
2932 new RcActionButton (_("Clear"),
2933 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
2934 _("VST Blacklist:")));
2937 #ifdef LXVST_SUPPORT
2938 add_option (_("Plugins/VST"),
2939 new RcActionButton (_("Edit"),
2940 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
2941 _("Linux VST Path:")));
2943 add_option (_("Plugins/VST"),
2944 new RcConfigDisplay (
2945 "plugin-path-lxvst",
2947 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
2951 #ifdef WINDOWS_VST_SUPPORT
2952 add_option (_("Plugins/VST"),
2953 new RcActionButton (_("Edit"),
2954 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
2955 _("Windows VST Path:")));
2956 add_option (_("Plugins"),
2957 new RcConfigDisplay (
2960 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
2964 #ifdef AUDIOUNIT_SUPPORT
2966 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
2967 add_option (_("Plugins/Audio Unit"),
2968 new RcActionButton (_("Scan for Plugins"),
2969 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
2971 bo = new BoolOption (
2972 "discover-audio-units",
2973 _("Scan for AudioUnit Plugins on Application Start"),
2974 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
2975 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
2977 add_option (_("Plugins"), bo);
2978 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2979 _("<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."));
2981 add_option (_("Plugins/Audio Unit"),
2982 new RcActionButton (_("Clear"),
2983 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
2986 add_option (_("Plugins/Audio Unit"),
2987 new RcActionButton (_("Clear"),
2988 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
2989 _("AU Blacklist:")));
2992 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
2993 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
2994 add_option (_("Plugins"),
2996 "open-gui-after-adding-plugin",
2997 _("Automatically open the plugin GUI when adding a new plugin"),
2998 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
2999 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
3002 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3003 add_option (_("Plugins"),
3005 "show-inline-display-by-default",
3006 _("Show Plugin Inline Display on Mixerstrip by default"),
3007 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3008 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3011 _plugin_prefer_inline = new BoolOption (
3012 "prefer-inline-over-gui",
3013 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3014 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3015 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3017 add_option (_("Plugins"), _plugin_prefer_inline);
3020 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3022 bo = new BoolOption (
3023 "ask-replace-instrument",
3024 _("Ask to replace existing instrument plugin"),
3025 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3026 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3028 add_option (_("Plugins"), bo);
3030 bo = new BoolOption (
3031 "ask-setup_instrument",
3032 _("Interactively configure instrument plugins on insert"),
3033 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3034 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3036 add_option (_("Plugins"), bo);
3037 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3038 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3044 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3045 BoolOption* bgc = new BoolOption (
3046 "cairo-image-surface",
3047 _("Disable Graphics Hardware Acceleration (requires restart)"),
3048 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3049 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3052 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3053 _("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));
3054 add_option (S_("Preferences|GUI"), bgc);
3057 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3058 BoolOption* bgo = new BoolOption (
3060 _("Possibly improve slow graphical performance (requires restart)"),
3061 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3062 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3065 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));
3066 add_option (S_("Preferences|GUI"), bgo);
3069 add_option (S_("Preferences|GUI"),
3071 "use-wm-visibility",
3072 _("Use Window Manager/Desktop visibility information"),
3073 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3074 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3077 add_option (S_("Preferences|GUI"),
3080 _("Graphically indicate mouse pointer hovering over various widgets"),
3081 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3082 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3085 add_option (S_("Preferences|GUI"),
3088 _("Show tooltips if mouse hovers over a control"),
3089 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3090 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3093 add_option (S_("Preferences|GUI"),
3095 "show-name-highlight",
3096 _("Use name highlight bars in region displays (requires a restart)"),
3097 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3098 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3101 add_option (S_("Preferences|GUI"),
3103 "super-rapid-clock-update",
3104 _("Update transport clock display at FPS instead of every 100ms"),
3105 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3106 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3111 /* font scaling does nothing with GDK/Quartz */
3112 add_option (S_("Preferences|GUI"), new FontScalingOptions ());
3115 /* Image cache size */
3117 Gtk::Adjustment *ics = manage (new Gtk::Adjustment(0, 1, 1024, 10)); /* 1 MB to 1GB in steps of 10MB */
3118 HSliderOption *sics = new HSliderOption("waveform-cache-size",
3119 _("Waveform image cache size (megabytes)"),
3121 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
3122 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size)
3124 sics->scale().set_digits (0);
3125 Gtkmm2ext::UI::instance()->set_tip
3126 (sics->tip_widget(),
3127 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
3128 add_option (S_("Preferences|GUI"), sics);
3130 if (!ARDOUR::Profile->get_mixbus()) {
3131 /* Lock GUI timeout */
3133 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
3134 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
3135 _("Lock timeout (seconds)"),
3137 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
3138 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds)
3140 slts->scale().set_digits (0);
3141 Gtkmm2ext::UI::instance()->set_tip
3142 (slts->tip_widget(),
3143 _("Lock GUI after this many idle seconds (zero to never lock)"));
3144 add_option (S_("Preferences|GUI"), slts);
3147 /* The names of these controls must be the same as those given in MixerStrip
3148 for the actual widgets being controlled.
3150 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3151 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3152 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3153 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3154 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3155 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3156 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3159 S_("Preferences|GUI"),
3160 new VisibilityOption (
3162 &_mixer_strip_visibility,
3163 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3164 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3168 add_option (S_("Preferences|GUI"),
3170 "default-narrow_ms",
3171 _("Use narrow strips in the mixer by default"),
3172 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3173 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3176 add_option (S_("Preferences|GUI"),
3177 new ColumVisibilityOption (
3178 "action-table-columns", _("Action Script Button Visibility"), 3,
3179 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3180 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3184 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
3186 ComboOption<float>* mht = new ComboOption<float> (
3188 _("Peak hold time"),
3189 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
3190 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
3193 mht->add (MeterHoldOff, _("off"));
3194 mht->add (MeterHoldShort, _("short"));
3195 mht->add (MeterHoldMedium, _("medium"));
3196 mht->add (MeterHoldLong, _("long"));
3198 add_option (S_("Preferences|Metering"), mht);
3200 ComboOption<float>* mfo = new ComboOption<float> (
3203 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
3204 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
3207 mfo->add (METER_FALLOFF_OFF, _("off"));
3208 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
3209 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
3210 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
3211 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
3212 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
3213 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
3215 add_option (S_("Preferences|Metering"), mfo);
3217 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
3218 "meter-line-up-level",
3219 _("Meter line-up level; 0dBu"),
3220 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
3221 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
3224 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3225 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3226 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3227 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3229 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."));
3231 add_option (S_("Preferences|Metering"), mlu);
3233 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
3234 "meter-line-up-din",
3235 _("IEC1/DIN Meter line-up level; 0dBu"),
3236 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
3237 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
3240 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3241 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3242 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3243 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3245 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
3247 add_option (S_("Preferences|Metering"), mld);
3249 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
3250 "meter-vu-standard",
3251 _("VU Meter standard"),
3252 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
3253 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
3256 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
3257 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
3258 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
3259 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
3261 add_option (S_("Preferences|Metering"), mvu);
3263 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
3264 HSliderOption *mpks = new HSliderOption("meter-peak",
3265 _("Peak threshold [dBFS]"),
3267 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
3268 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak)
3272 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
3273 "meter-type-master",
3274 _("Default Meter Type for Master Bus"),
3275 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
3276 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3278 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3279 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3280 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3281 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3282 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3283 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3284 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3285 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3287 add_option (S_("Preferences|Metering"), mtm);
3290 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3292 _("Default Meter Type for Busses"),
3293 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3294 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3296 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3297 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3298 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3299 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3300 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3301 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3302 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3303 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3305 add_option (S_("Preferences|Metering"), mtb);
3307 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3309 _("Default Meter Type for Tracks"),
3310 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3311 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3313 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3314 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3316 add_option (S_("Preferences|Metering"), mtt);
3319 Gtkmm2ext::UI::instance()->set_tip
3320 (mpks->tip_widget(),
3321 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
3323 add_option (S_("Preferences|Metering"), mpks);
3325 add_option (S_("Preferences|Metering"),
3328 _("LED meter style"),
3329 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3330 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3333 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Editor Meters")));
3335 add_option (S_("Preferences|Metering"),
3337 "show-track-meters",
3338 _("Show meters on tracks in the editor"),
3339 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3340 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3343 add_option (S_("Preferences|Metering"),
3345 "editor-stereo-only-meters",
3346 _("Show at most stereo meters in the track-header"),
3347 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3348 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3351 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
3353 add_option (S_("Preferences|Metering"),
3355 "save-export-analysis-image",
3356 _("Save loudness analysis as image file"),
3357 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
3358 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
3361 /* and now the theme manager */
3363 ThemeManager* tm = manage (new ThemeManager);
3364 add_page (_("Theme"), *tm);
3366 add_option (_("Theme/Colors"), new ColorThemeManager);
3368 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3369 parameter_changed ("send-ltc");
3370 parameter_changed ("sync-source");
3371 parameter_changed ("use-monitor-bus");
3372 parameter_changed ("open-gui-after-adding-plugin");
3376 RCOptionEditor::parameter_changed (string const & p)
3378 OptionEditor::parameter_changed (p);
3380 if (p == "use-monitor-bus") {
3381 bool const s = Config->get_use_monitor_bus ();
3383 /* we can't use this if we don't have a monitor bus */
3384 Config->set_solo_control_is_listen_control (false);
3386 _solo_control_is_listen_control->set_sensitive (s);
3387 _listen_position->set_sensitive (s);
3388 } else if (p == "sync-source") {
3389 _sync_source->set_sensitive (true);
3391 _sync_source->set_sensitive (!_session->config.get_external_sync());
3393 switch(Config->get_sync_source()) {
3396 _sync_genlock->set_sensitive (true);
3397 _sync_framerate->set_sensitive (true);
3398 _sync_source_2997->set_sensitive (true);
3401 _sync_genlock->set_sensitive (false);
3402 _sync_framerate->set_sensitive (false);
3403 _sync_source_2997->set_sensitive (false);
3406 } else if (p == "send-ltc") {
3407 bool const s = Config->get_send_ltc ();
3408 _ltc_send_continuously->set_sensitive (s);
3409 _ltc_volume_slider->set_sensitive (s);
3410 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
3411 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3412 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
3417 void RCOptionEditor::ltc_generator_volume_changed () {
3418 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
3421 void RCOptionEditor::plugin_scan_refresh () {
3422 PluginManager::instance().refresh();
3425 void RCOptionEditor::clear_vst_cache () {
3426 PluginManager::instance().clear_vst_cache();
3429 void RCOptionEditor::clear_vst_blacklist () {
3430 PluginManager::instance().clear_vst_blacklist();
3433 void RCOptionEditor::clear_au_cache () {
3434 PluginManager::instance().clear_au_cache();
3437 void RCOptionEditor::clear_au_blacklist () {
3438 PluginManager::instance().clear_au_blacklist();
3441 void RCOptionEditor::edit_lxvst_path () {
3442 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
3443 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3444 *current_toplevel(), _("Set Linux VST Search Path"),
3445 _rc_config->get_plugin_path_lxvst(),
3446 PluginManager::instance().get_default_lxvst_path()
3448 ResponseType r = (ResponseType) pd->run ();
3450 if (r == RESPONSE_ACCEPT) {
3451 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
3456 void RCOptionEditor::edit_vst_path () {
3457 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3458 *current_toplevel(), _("Set Windows VST Search Path"),
3459 _rc_config->get_plugin_path_vst(),
3460 PluginManager::instance().get_default_windows_vst_path()
3462 ResponseType r = (ResponseType) pd->run ();
3464 if (r == RESPONSE_ACCEPT) {
3465 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
3472 RCOptionEditor::populate_sync_options ()
3474 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3476 _sync_source->clear ();
3478 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3479 _sync_source->add (*i, sync_source_to_string (*i));
3482 if (sync_opts.empty()) {
3483 _sync_source->set_sensitive(false);
3485 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3486 _rc_config->set_sync_source(sync_opts.front());
3490 parameter_changed ("sync-source");
3494 RCOptionEditor::use_own_window (bool and_fill_it)
3496 bool new_window = !own_window();
3498 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
3500 if (win && new_window) {
3501 win->set_name ("PreferencesWindow");
3502 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
3509 RCOptionEditor::get_state ()
3511 XMLNode* node = new XMLNode (X_("Preferences"));
3512 node->add_child_nocopy (Tabbable::get_state());