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 Gtkmm2ext::UI::instance()->set_tip (_constraint_modifier_combo,
547 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
549 Keyboard::primary_modifier_name (),
551 Keyboard::secondary_modifier_name (),
554 for (int x = 0; modifiers[x].name; ++x) {
555 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
556 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
561 l = manage (left_aligned_label (_("Constrain drag using:")));
562 l->set_name ("OptionsLabel");
564 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
565 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
571 set_popdown_strings (_push_points_combo, dumb);
572 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
574 Gtkmm2ext::UI::instance()->set_tip (_push_points_combo,
575 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
576 for (int x = 0; modifiers[x].name; ++x) {
577 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
578 _push_points_combo.set_active_text (S_(modifiers[x].name));
583 l = manage (left_aligned_label (_("Push points using:")));
584 l->set_name ("OptionsLabel");
586 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
587 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
591 l = manage (left_aligned_label (_("When Beginning a Trim:")));
592 l->set_name ("OptionEditorHeading");
593 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
599 set_popdown_strings (_trim_contents_combo, dumb);
600 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
601 Gtkmm2ext::UI::instance()->set_tip (_trim_contents_combo,
602 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
603 for (int x = 0; modifiers[x].name; ++x) {
604 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
605 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
610 l = manage (left_aligned_label (_("Trim contents using:")));
611 l->set_name ("OptionsLabel");
613 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
614 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
620 set_popdown_strings (_trim_anchored_combo, dumb);
621 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
622 Gtkmm2ext::UI::instance()->set_tip (_trim_anchored_combo,
623 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
624 for (int x = 0; modifiers[x].name; ++x) {
625 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
626 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
631 l = manage (left_aligned_label (_("Anchored trim using:")));
632 l->set_name ("OptionsLabel");
634 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
636 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
641 /* jump trim disabled for now
642 set_popdown_strings (_trim_jump_combo, dumb);
643 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
645 for (int x = 0; modifiers[x].name; ++x) {
646 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
647 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
652 l = manage (left_aligned_label (_("Jump after trim using:")));
653 l->set_name ("OptionsLabel");
655 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
657 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
663 /* note resize relative */
664 set_popdown_strings (_note_size_relative_combo, dumb);
665 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
666 Gtkmm2ext::UI::instance()->set_tip (_note_size_relative_combo,
667 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
668 for (int x = 0; modifiers[x].name; ++x) {
669 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
670 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
675 l = manage (left_aligned_label (_("Resize notes relatively using:")));
676 l->set_name ("OptionsLabel");
678 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
680 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
684 l = manage (left_aligned_label (_("While Dragging:")));
685 l->set_name ("OptionEditorHeading");
686 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
692 set_popdown_strings (_snap_modifier_combo, dumb);
693 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
695 std::string mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ());
697 std::string mod_str = Keyboard::secondary_modifier_name();
699 Gtkmm2ext::UI::instance()->set_tip (_snap_modifier_combo,
700 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
701 for (int x = 0; modifiers[x].name; ++x) {
702 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
703 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
708 l = manage (left_aligned_label (_("Ignore snap using:")));
709 l->set_name ("OptionsLabel");
711 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
712 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
718 set_popdown_strings (_snap_delta_combo, dumb);
719 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
721 mod_str = Keyboard::level4_modifier_name ();
723 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::level4_modifier_name ());
725 Gtkmm2ext::UI::instance()->set_tip (_snap_delta_combo,
726 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
727 for (int x = 0; modifiers[x].name; ++x) {
728 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
729 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
734 l = manage (left_aligned_label (_("Snap relatively using:")));
735 l->set_name ("OptionsLabel");
737 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
738 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
742 l = manage (left_aligned_label (_("While Trimming:")));
743 l->set_name ("OptionEditorHeading");
744 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
750 set_popdown_strings (_trim_overlap_combo, dumb);
751 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
753 Gtkmm2ext::UI::instance()->set_tip (_trim_overlap_combo,
754 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
755 for (int x = 0; modifiers[x].name; ++x) {
756 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
757 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
762 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
763 l->set_name ("OptionsLabel");
765 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
766 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
770 l = manage (left_aligned_label (_("While Dragging Control Points:")));
771 l->set_name ("OptionEditorHeading");
772 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
778 set_popdown_strings (_fine_adjust_combo, dumb);
779 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
781 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::tertiary_modifier_name ());
782 Gtkmm2ext::UI::instance()->set_tip (_fine_adjust_combo,
783 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
784 for (int x = 0; modifiers[x].name; ++x) {
785 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
786 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
791 l = manage (left_aligned_label (_("Fine adjust using:")));
792 l->set_name ("OptionsLabel");
794 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
795 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
797 _box->pack_start (*t, false, false);
800 void parameter_changed (string const &)
802 /* XXX: these aren't really config options... */
805 void set_state_from_config ()
807 /* XXX: these aren't really config options... */
812 void bindings_changed ()
814 string const txt = _keyboard_layout_selector.get_active_text();
816 /* XXX: config...? for all this keyboard stuff */
818 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
819 if (txt == i->first) {
820 if (Keyboard::load_keybindings (i->second)) {
821 Keyboard::save_keybindings ();
827 void edit_modifier_chosen ()
829 string const txt = _edit_modifier_combo.get_active_text();
831 for (int i = 0; modifiers[i].name; ++i) {
832 if (txt == S_(modifiers[i].name)) {
833 Keyboard::set_edit_modifier (modifiers[i].modifier);
839 void delete_modifier_chosen ()
841 string const txt = _delete_modifier_combo.get_active_text();
843 for (int i = 0; modifiers[i].name; ++i) {
844 if (txt == S_(modifiers[i].name)) {
845 Keyboard::set_delete_modifier (modifiers[i].modifier);
851 void copy_modifier_chosen ()
853 string const txt = _copy_modifier_combo.get_active_text();
855 for (int i = 0; modifiers[i].name; ++i) {
856 if (txt == S_(modifiers[i].name)) {
857 Keyboard::set_copy_modifier (modifiers[i].modifier);
863 void insert_note_modifier_chosen ()
865 string const txt = _insert_note_modifier_combo.get_active_text();
867 for (int i = 0; modifiers[i].name; ++i) {
868 if (txt == S_(modifiers[i].name)) {
869 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
875 void snap_modifier_chosen ()
877 string const txt = _snap_modifier_combo.get_active_text();
879 for (int i = 0; modifiers[i].name; ++i) {
880 if (txt == S_(modifiers[i].name)) {
881 Keyboard::set_snap_modifier (modifiers[i].modifier);
887 void snap_delta_modifier_chosen ()
889 string const txt = _snap_delta_combo.get_active_text();
891 for (int i = 0; modifiers[i].name; ++i) {
892 if (txt == S_(modifiers[i].name)) {
893 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
899 void constraint_modifier_chosen ()
901 string const txt = _constraint_modifier_combo.get_active_text();
903 for (int i = 0; modifiers[i].name; ++i) {
904 if (txt == S_(modifiers[i].name)) {
905 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
911 void trim_contents_modifier_chosen ()
913 string const txt = _trim_contents_combo.get_active_text();
915 for (int i = 0; modifiers[i].name; ++i) {
916 if (txt == S_(modifiers[i].name)) {
917 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
923 void trim_overlap_modifier_chosen ()
925 string const txt = _trim_overlap_combo.get_active_text();
927 for (int i = 0; modifiers[i].name; ++i) {
928 if (txt == S_(modifiers[i].name)) {
929 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
935 void trim_anchored_modifier_chosen ()
937 string const txt = _trim_anchored_combo.get_active_text();
939 for (int i = 0; modifiers[i].name; ++i) {
940 if (txt == S_(modifiers[i].name)) {
941 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
947 void fine_adjust_modifier_chosen ()
949 string const txt = _fine_adjust_combo.get_active_text();
951 for (int i = 0; modifiers[i].name; ++i) {
952 if (txt == S_(modifiers[i].name)) {
953 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
959 void push_points_modifier_chosen ()
961 string const txt = _push_points_combo.get_active_text();
963 for (int i = 0; modifiers[i].name; ++i) {
964 if (txt == S_(modifiers[i].name)) {
965 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
971 void note_size_relative_modifier_chosen ()
973 string const txt = _note_size_relative_combo.get_active_text();
975 for (int i = 0; modifiers[i].name; ++i) {
976 if (txt == S_(modifiers[i].name)) {
977 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
983 void delete_button_changed ()
985 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
988 void edit_button_changed ()
990 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
993 void insert_note_button_changed ()
995 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
998 ComboBoxText _keyboard_layout_selector;
999 ComboBoxText _edit_modifier_combo;
1000 ComboBoxText _delete_modifier_combo;
1001 ComboBoxText _copy_modifier_combo;
1002 ComboBoxText _insert_note_modifier_combo;
1003 ComboBoxText _snap_modifier_combo;
1004 ComboBoxText _snap_delta_combo;
1005 ComboBoxText _constraint_modifier_combo;
1006 ComboBoxText _trim_contents_combo;
1007 ComboBoxText _trim_overlap_combo;
1008 ComboBoxText _trim_anchored_combo;
1009 ComboBoxText _trim_jump_combo;
1010 ComboBoxText _fine_adjust_combo;
1011 ComboBoxText _push_points_combo;
1012 ComboBoxText _note_size_relative_combo;
1013 Adjustment _delete_button_adjustment;
1014 SpinButton _delete_button_spin;
1015 Adjustment _edit_button_adjustment;
1016 SpinButton _edit_button_spin;
1017 Adjustment _insert_note_button_adjustment;
1018 SpinButton _insert_note_button_spin;
1022 class FontScalingOptions : public OptionEditorBox
1025 FontScalingOptions () :
1026 _dpi_adjustment (100, 50, 250, 1, 5),
1027 _dpi_slider (_dpi_adjustment)
1029 _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.);
1031 Label* l = manage (new Label (_("GUI and Font scaling:")));
1032 l->set_name ("OptionsLabel");
1034 const std::string dflt = _("Default");
1035 const std::string empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
1037 _dpi_slider.set_name("FontScaleSlider");
1038 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1039 _dpi_slider.set_draw_value(false);
1040 _dpi_slider.add_mark(50, Gtk::POS_TOP, empty);
1041 _dpi_slider.add_mark(60, Gtk::POS_TOP, empty);
1042 _dpi_slider.add_mark(70, Gtk::POS_TOP, empty);
1043 _dpi_slider.add_mark(80, Gtk::POS_TOP, empty);
1044 _dpi_slider.add_mark(90, Gtk::POS_TOP, empty);
1045 _dpi_slider.add_mark(100, Gtk::POS_TOP, dflt);
1046 _dpi_slider.add_mark(125, Gtk::POS_TOP, empty);
1047 _dpi_slider.add_mark(150, Gtk::POS_TOP, empty);
1048 _dpi_slider.add_mark(175, Gtk::POS_TOP, empty);
1049 _dpi_slider.add_mark(200, Gtk::POS_TOP, empty);
1050 _dpi_slider.add_mark(225, Gtk::POS_TOP, empty);
1051 _dpi_slider.add_mark(250, Gtk::POS_TOP, empty);
1053 HBox* h = manage (new HBox);
1055 h->pack_start (*l, false, false);
1056 h->pack_start (_dpi_slider, true, true);
1058 _box->pack_start (*h, false, false);
1060 set_note (_("Adjusting the scale requires an application restart to re-layout."));
1062 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
1065 void parameter_changed (string const & p)
1067 if (p == "font-scale") {
1068 _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.);
1072 void set_state_from_config ()
1074 parameter_changed ("font-scale");
1081 UIConfiguration::instance().set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024.));
1082 /* XXX: should be triggered from the parameter changed signal */
1083 UIConfiguration::instance().reset_dpi ();
1086 Adjustment _dpi_adjustment;
1090 class VstTimeOutSliderOption : public OptionEditorBox
1093 VstTimeOutSliderOption (RCConfiguration* c)
1095 , _timeout_adjustment (0, 0, 3000, 50, 50)
1096 , _timeout_slider (_timeout_adjustment)
1098 _timeout_slider.set_digits (0);
1099 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &VstTimeOutSliderOption::timeout_changed));
1101 _timeout_slider.set_draw_value(false);
1102 _timeout_slider.add_mark( 0, Gtk::POS_TOP, _("\u221e")); // infinity
1103 _timeout_slider.add_mark( 300, Gtk::POS_TOP, _("30 sec"));
1104 _timeout_slider.add_mark( 600, Gtk::POS_TOP, _("1 min"));
1105 _timeout_slider.add_mark(1200, Gtk::POS_TOP, _("2 mins"));
1106 _timeout_slider.add_mark(1800, Gtk::POS_TOP, _("3 mins"));
1107 _timeout_slider.add_mark(2400, Gtk::POS_TOP, _("4 mins"));
1108 _timeout_slider.add_mark(3000, Gtk::POS_TOP, _("5 mins"));
1110 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1111 _("Specify the default timeout for plugin instantiation. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1113 Label* l = manage (left_aligned_label (_("Scan Time Out:")));
1114 HBox* h = manage (new HBox);
1116 h->pack_start (*l, false, false);
1117 h->pack_start (_timeout_slider, true, true);
1119 _box->pack_start (*h, false, false);
1122 void parameter_changed (string const & p)
1124 if (p == "vst-scan-timeout") {
1125 int const x = _rc_config->get_vst_scan_timeout();
1126 _timeout_adjustment.set_value (x);
1130 void set_state_from_config ()
1132 parameter_changed ("vst-scan-timeout");
1137 void timeout_changed ()
1139 int x = floor(_timeout_adjustment.get_value());
1140 _rc_config->set_vst_scan_timeout(x);
1143 RCConfiguration* _rc_config;
1144 Adjustment _timeout_adjustment;
1145 HScale _timeout_slider;
1152 class ClipLevelOptions : public OptionEditorBox
1156 : _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1157 , _clip_level_slider (_clip_level_adjustment)
1159 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level ());
1161 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
1162 l->set_name ("OptionsLabel");
1164 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1165 HBox* h = manage (new HBox);
1167 h->pack_start (*l, false, false);
1168 h->pack_start (_clip_level_slider, true, true);
1170 _box->pack_start (*h, false, false);
1172 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1175 void parameter_changed (string const & p)
1177 if (p == "waveform-clip-level") {
1178 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level());
1182 void set_state_from_config ()
1184 parameter_changed ("waveform-clip-level");
1189 void clip_level_changed ()
1191 UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value());
1192 /* XXX: should be triggered from the parameter changed signal */
1193 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1196 Adjustment _clip_level_adjustment;
1197 HScale _clip_level_slider;
1200 class BufferingOptions : public OptionEditorBox
1203 BufferingOptions (RCConfiguration* c)
1205 , _playback_adjustment (5, 1, 60, 1, 4)
1206 , _capture_adjustment (5, 1, 60, 1, 4)
1207 , _playback_slider (_playback_adjustment)
1208 , _capture_slider (_capture_adjustment)
1210 vector<string> presets;
1212 /* these must match the order of the enums for BufferingPreset */
1214 presets.push_back (_("Small sessions (4-16 tracks)"));
1215 presets.push_back (_("Medium sessions (16-64 tracks)"));
1216 presets.push_back (_("Large sessions (64+ tracks)"));
1217 presets.push_back (_("Custom (set by sliders below)"));
1219 set_popdown_strings (_buffering_presets_combo, presets);
1221 Label* l = manage (new Label (_("Preset:")));
1222 l->set_name ("OptionsLabel");
1223 HBox* h = manage (new HBox);
1224 h->set_spacing (12);
1225 h->pack_start (*l, false, false);
1226 h->pack_start (_buffering_presets_combo, true, true);
1227 _box->pack_start (*h, false, false);
1229 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1231 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1233 l = manage (new Label (_("Playback (seconds of buffering):")));
1234 l->set_name ("OptionsLabel");
1236 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1237 h = manage (new HBox);
1239 h->pack_start (*l, false, false);
1240 h->pack_start (_playback_slider, true, true);
1242 _box->pack_start (*h, false, false);
1244 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1246 l = manage (new Label (_("Recording (seconds of buffering):")));
1247 l->set_name ("OptionsLabel");
1249 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1250 h = manage (new HBox);
1252 h->pack_start (*l, false, false);
1253 h->pack_start (_capture_slider, true, true);
1255 _box->pack_start (*h, false, false);
1257 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
1258 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
1261 void parameter_changed (string const & p)
1263 if (p == "buffering-preset") {
1264 switch (_rc_config->get_buffering_preset()) {
1266 _playback_slider.set_sensitive (false);
1267 _capture_slider.set_sensitive (false);
1268 _buffering_presets_combo.set_active (0);
1271 _playback_slider.set_sensitive (false);
1272 _capture_slider.set_sensitive (false);
1273 _buffering_presets_combo.set_active (1);
1276 _playback_slider.set_sensitive (false);
1277 _capture_slider.set_sensitive (false);
1278 _buffering_presets_combo.set_active (2);
1281 _playback_slider.set_sensitive (true);
1282 _capture_slider.set_sensitive (true);
1283 _buffering_presets_combo.set_active (3);
1288 if (p == "playback-buffer-seconds") {
1289 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1290 } else if (p == "capture-buffer-seconds") {
1291 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1295 void set_state_from_config ()
1297 parameter_changed ("buffering-preset");
1298 parameter_changed ("playback-buffer-seconds");
1299 parameter_changed ("capture-buffer-seconds");
1304 void preset_changed ()
1306 int index = _buffering_presets_combo.get_active_row_number ();
1312 _rc_config->set_buffering_preset (Small);
1315 _rc_config->set_buffering_preset (Medium);
1318 _rc_config->set_buffering_preset (Large);
1321 _rc_config->set_buffering_preset (Custom);
1324 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1329 void playback_changed ()
1331 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
1334 void capture_changed ()
1336 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
1339 RCConfiguration* _rc_config;
1340 Adjustment _playback_adjustment;
1341 Adjustment _capture_adjustment;
1342 HScale _playback_slider;
1343 HScale _capture_slider;
1344 ComboBoxText _buffering_presets_combo;
1347 class ControlSurfacesOptions : public OptionEditorBox
1350 ControlSurfacesOptions ()
1351 : _ignore_view_change (0)
1353 _store = ListStore::create (_model);
1354 _view.set_model (_store);
1355 _view.append_column (_("Control Surface Protocol"), _model.name);
1356 _view.get_column(0)->set_resizable (true);
1357 _view.get_column(0)->set_expand (true);
1358 _view.append_column_editable (_("Enabled"), _model.enabled);
1359 _view.append_column_editable (_("Feedback"), _model.feedback);
1361 _box->pack_start (_view, false, false);
1363 Gtk::HBox* edit_box = manage (new Gtk::HBox);
1364 edit_box->set_spacing(3);
1365 _box->pack_start (*edit_box, false, false);
1368 Label* label = manage (new Label);
1369 label->set_text (_("Click to edit the settings for selected protocol ( it must be ENABLED first ):"));
1370 edit_box->pack_start (*label, false, false);
1373 edit_button = manage (new Button(_("Show Protocol Settings")));
1374 edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
1375 edit_box->pack_start (*edit_button, true, true);
1376 edit_button->set_sensitive (false);
1377 edit_button->show ();
1379 ControlProtocolManager& m = ControlProtocolManager::instance ();
1380 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1381 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1383 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1384 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1385 _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
1388 void parameter_changed (std::string const &)
1393 void set_state_from_config ()
1397 ControlProtocolManager& m = ControlProtocolManager::instance ();
1398 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1400 if (!(*i)->mandatory) {
1401 TreeModel::Row r = *_store->append ();
1402 r[_model.name] = (*i)->name;
1403 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1404 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
1405 r[_model.protocol_info] = *i;
1412 void protocol_status_changed (ControlProtocolInfo* cpi) {
1414 TreeModel::Children rows = _store->children();
1416 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1417 string n = ((*x)[_model.name]);
1419 if ((*x)[_model.protocol_info] == cpi) {
1420 _ignore_view_change++;
1421 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1422 _ignore_view_change--;
1428 void selection_changed ()
1430 //enable the Edit button when a row is selected for editing
1431 TreeModel::Row row = *(_view.get_selection()->get_selected());
1432 if (row && row[_model.enabled])
1433 edit_button->set_sensitive (true);
1435 edit_button->set_sensitive (false);
1438 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1440 TreeModel::Row r = *i;
1442 if (_ignore_view_change) {
1446 ControlProtocolInfo* cpi = r[_model.protocol_info];
1451 bool const was_enabled = (cpi->protocol != 0);
1452 bool const is_enabled = r[_model.enabled];
1455 if (was_enabled != is_enabled) {
1458 ControlProtocolManager::instance().activate (*cpi);
1460 ControlProtocolManager::instance().deactivate (*cpi);
1464 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
1465 bool const is_feedback = r[_model.feedback];
1467 if (was_feedback != is_feedback && cpi->protocol) {
1468 cpi->protocol->set_feedback (is_feedback);
1472 void edit_btn_clicked ()
1475 ControlProtocolInfo* cpi;
1478 row = *(_view.get_selection()->get_selected());
1479 if (!row[_model.enabled]) {
1482 cpi = row[_model.protocol_info];
1483 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1486 Box* box = (Box*) cpi->protocol->get_gui ();
1490 if (box->get_parent()) {
1491 static_cast<ArdourWindow*>(box->get_parent())->present();
1494 WindowTitle title (Glib::get_application_name());
1495 title += row[_model.name];
1496 title += _("Configuration");
1497 /* once created, the window is managed by the surface itself (as ->get_parent())
1498 * Surface's tear_down_gui() is called on session close, when de-activating
1499 * or re-initializing a surface.
1500 * tear_down_gui() hides an deletes the Window if it exists.
1502 ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string());
1503 win->set_title ("Control Protocol Options");
1509 void edit_clicked (GdkEventButton* ev)
1511 if (ev->type != GDK_2BUTTON_PRESS) {
1518 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1522 ControlSurfacesModelColumns ()
1527 add (protocol_info);
1530 TreeModelColumn<string> name;
1531 TreeModelColumn<bool> enabled;
1532 TreeModelColumn<bool> feedback;
1533 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1536 Glib::RefPtr<ListStore> _store;
1537 ControlSurfacesModelColumns _model;
1539 PBD::ScopedConnection protocol_status_connection;
1540 uint32_t _ignore_view_change;
1541 Gtk::Button* edit_button;
1544 class VideoTimelineOptions : public OptionEditorBox
1547 VideoTimelineOptions (RCConfiguration* c)
1549 , _show_video_export_info_button (_("Show Video Export Info before export"))
1550 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1551 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1552 , _xjadeo_browse_button (_("Browse..."))
1554 Table* t = manage (new Table (8, 4));
1555 t->set_spacings (4);
1557 std::stringstream s;
1558 s << "<b>" << _("Video Server") << "</b>";
1559 Label* l = manage (new Label (s.str()));
1560 l->set_use_markup (true);
1561 l->set_alignment (0, 0.5);
1562 t->attach (*l, 0, 4, 0, 1, EXPAND | FILL, FILL | EXPAND, 0, 8);
1564 t->attach (_video_advanced_setup_button, 1, 4, 1, 2);
1565 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1566 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1567 _("<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."));
1569 l = manage (new Label (_("Video Server URL:")));
1570 l->set_alignment (0, 0.5);
1571 t->attach (*l, 1, 2, 2, 3, FILL);
1572 t->attach (_video_server_url_entry, 2, 4, 2, 3, FILL);
1573 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1574 _("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"));
1576 l = manage (new Label (_("Video Folder:")));
1577 l->set_alignment (0, 0.5);
1578 t->attach (*l, 1, 2, 3, 4, FILL);
1579 t->attach (_video_server_docroot_entry, 2, 4, 3, 4);
1580 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1581 _("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."));
1583 t->attach (_show_video_export_info_button, 1, 4, 4, 5);
1584 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1585 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1586 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1588 t->attach (_show_video_server_dialog_button, 1, 4, 5, 6);
1589 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1590 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1591 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1593 s.str (std::string ());
1594 s << "<b>" << _("Video Monitor") << "</b>";
1595 l = manage (new Label (s.str()));
1596 l->set_use_markup (true);
1597 l->set_alignment (0, 0.5);
1598 t->attach (*l, 0, 4, 6, 7, EXPAND | FILL, FILL | EXPAND, 0, 8);
1600 l = manage (new Label (string_compose (_("Custom Path to Video Monitor (%1) - leave empty for default:"),
1603 #elif defined PLATFORM_WINDOWS
1609 l->set_alignment (0, 0.5);
1610 t->attach (*l, 1, 4, 7, 8, FILL);
1611 t->attach (_custom_xjadeo_path, 2, 3, 8, 9);
1612 Gtkmm2ext::UI::instance()->set_tip (_custom_xjadeo_path, _("Set a custom path to the Video Monitor Executable, changing this requires a restart."));
1613 t->attach (_xjadeo_browse_button, 3, 4, 8, 9, FILL);
1615 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1616 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1617 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1618 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1619 _custom_xjadeo_path.signal_changed().connect (sigc::mem_fun (*this, &VideoTimelineOptions::custom_xjadeo_path_changed));
1620 _xjadeo_browse_button.signal_clicked ().connect (sigc::mem_fun (*this, &VideoTimelineOptions::xjadeo_browse_clicked));
1622 // xjadeo-path is a UIConfig parameter
1623 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &VideoTimelineOptions::parameter_changed));
1625 _box->pack_start (*t,true,true);
1628 void server_url_changed ()
1630 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1633 void server_docroot_changed ()
1635 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1638 void show_video_export_info_toggled ()
1640 bool const x = _show_video_export_info_button.get_active ();
1641 _rc_config->set_show_video_export_info (x);
1644 void show_video_server_dialog_toggled ()
1646 bool const x = _show_video_server_dialog_button.get_active ();
1647 _rc_config->set_show_video_server_dialog (x);
1650 void video_advanced_setup_toggled ()
1652 bool const x = _video_advanced_setup_button.get_active ();
1653 _rc_config->set_video_advanced_setup(x);
1656 void custom_xjadeo_path_changed ()
1658 UIConfiguration::instance().set_xjadeo_binary (_custom_xjadeo_path.get_text());
1661 void xjadeo_browse_clicked ()
1663 Gtk::FileChooserDialog dialog(_("Set Video Monitor Executable"), Gtk::FILE_CHOOSER_ACTION_OPEN);
1664 dialog.set_filename (UIConfiguration::instance().get_xjadeo_binary());
1665 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1666 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1667 if (dialog.run () == Gtk::RESPONSE_OK) {
1668 const std::string& filename = dialog.get_filename();
1669 if (!filename.empty() && (
1671 Glib::file_test (filename + "/Contents/MacOS/xjadeo", Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) ||
1673 Glib::file_test (filename, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)
1675 UIConfiguration::instance().set_xjadeo_binary (filename);
1680 void parameter_changed (string const & p)
1682 if (p == "video-server-url") {
1683 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1684 } else if (p == "video-server-docroot") {
1685 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1686 } else if (p == "show-video-export-info") {
1687 bool const x = _rc_config->get_show_video_export_info();
1688 _show_video_export_info_button.set_active (x);
1689 } else if (p == "show-video-server-dialog") {
1690 bool const x = _rc_config->get_show_video_server_dialog();
1691 _show_video_server_dialog_button.set_active (x);
1692 } else if (p == "video-advanced-setup") {
1693 bool const x = _rc_config->get_video_advanced_setup();
1694 _video_advanced_setup_button.set_active(x);
1695 _video_server_docroot_entry.set_sensitive(x);
1696 _video_server_url_entry.set_sensitive(x);
1697 } else if (p == "xjadeo-binary") {
1698 _custom_xjadeo_path.set_text (UIConfiguration::instance().get_xjadeo_binary());
1702 void set_state_from_config ()
1704 parameter_changed ("video-server-url");
1705 parameter_changed ("video-server-docroot");
1706 parameter_changed ("video-monitor-setup-dialog");
1707 parameter_changed ("show-video-export-info");
1708 parameter_changed ("show-video-server-dialog");
1709 parameter_changed ("video-advanced-setup");
1710 parameter_changed ("xjadeo-binary");
1714 RCConfiguration* _rc_config;
1715 Entry _video_server_url_entry;
1716 Entry _video_server_docroot_entry;
1717 Entry _custom_xjadeo_path;
1718 CheckButton _show_video_export_info_button;
1719 CheckButton _show_video_server_dialog_button;
1720 CheckButton _video_advanced_setup_button;
1721 Button _xjadeo_browse_button;
1724 class ColumVisibilityOption : public Option
1727 ColumVisibilityOption (string id, string name, uint32_t n_col, sigc::slot<uint32_t> get, sigc::slot<bool, uint32_t> set)
1734 cb = (CheckButton**) malloc (sizeof (CheckButton*) * n_col);
1735 for (uint32_t i = 0; i < n_col; ++i) {
1736 CheckButton* col = manage (new CheckButton (string_compose (_("Column %1"), i + 1)));
1737 col->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &ColumVisibilityOption::column_toggled), i));
1738 _hbox.pack_start (*col);
1741 parameter_changed (id);
1744 ~ColumVisibilityOption () {
1748 Gtk::Widget& tip_widget() { return _hbox; }
1750 void set_state_from_config ()
1752 uint32_t c = _get();
1753 for (uint32_t i = 0; i < _n_col; ++i) {
1754 bool en = (c & (1<<i)) ? true : false;
1755 if (cb[i]->get_active () != en) {
1756 cb[i]->set_active (en);
1761 void add_to_page (OptionEditorPage* p)
1763 _heading.add_to_page (p);
1764 add_widget_to_page (p, &_hbox);
1768 void column_toggled (int b) {
1769 uint32_t c = _get();
1771 if (cb[b]->get_active ()) {
1782 OptionEditorHeading _heading;
1786 sigc::slot<uint32_t> _get;
1787 sigc::slot<bool, uint32_t> _set;
1791 /** A class which allows control of visibility of some editor components usign
1792 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1793 * which has the correct members, but with null widget pointers. This
1794 * class allows the user to set visibility of the members, the details
1795 * of which are stored in a configuration variable which can be watched
1796 * by parts of the editor that actually contain the widgets whose visibility
1797 * is being controlled.
1800 class VisibilityOption : public Option
1803 /** @param name User-visible name for this group.
1804 * @param g `Dummy' VisibilityGroup (as described above).
1805 * @param get Method to get the value of the appropriate configuration variable.
1806 * @param set Method to set the value of the appropriate configuration variable.
1808 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1809 : Option (g->get_state_name(), name)
1811 , _visibility_group (g)
1815 /* Watch for changes made by the user to our members */
1816 _visibility_group->VisibilityChanged.connect_same_thread (
1817 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1821 void set_state_from_config ()
1823 /* Set our state from the current configuration */
1824 _visibility_group->set_state (_get ());
1827 void add_to_page (OptionEditorPage* p)
1829 _heading.add_to_page (p);
1830 add_widget_to_page (p, _visibility_group->list_view ());
1833 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1838 /* The user has changed something, so reflect this change
1839 in the RCConfiguration.
1841 _set (_visibility_group->get_state_value ());
1844 OptionEditorHeading _heading;
1845 VisibilityGroup* _visibility_group;
1846 sigc::slot<std::string> _get;
1847 sigc::slot<bool, std::string> _set;
1848 PBD::ScopedConnection _visibility_group_connection;
1853 RCOptionEditor::RCOptionEditor ()
1854 : OptionEditorContainer (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1855 , Tabbable (*this, _("Preferences")) /* pack self-as-vbox into tabbable */
1856 , _rc_config (Config)
1857 , _mixer_strip_visibility ("mixer-element-visibility")
1859 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
1861 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
1862 (Gtk::StateType) here !!!
1864 Tabbable::set_state (*node, Stateful::loading_state_version);
1867 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed));
1871 uint32_t hwcpus = hardware_concurrency ();
1873 BoolComboOption* bco;
1876 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1878 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1880 _("Signal processing uses"),
1881 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1882 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1885 procs->add (-1, _("all but one processor"));
1886 procs->add (0, _("all available processors"));
1888 for (uint32_t i = 1; i <= hwcpus; ++i) {
1889 procs->add (i, string_compose (_("%1 processors"), i));
1892 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1894 add_option (_("Misc"), procs);
1897 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1899 add_option (_("Misc"), new UndoOptions (_rc_config));
1901 add_option (_("Misc"),
1903 "verify-remove-last-capture",
1904 _("Verify removal of last capture"),
1905 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1906 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1909 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1911 add_option (_("Misc"),
1913 "periodic-safety-backups",
1914 _("Make periodic backups of the session file"),
1915 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1916 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1919 add_option (_("Misc"),
1921 "only-copy-imported-files",
1922 _("Always copy imported files"),
1923 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
1924 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
1927 add_option (_("Misc"), new DirectoryOption (
1928 X_("default-session-parent-dir"),
1929 _("Default folder for new sessions:"),
1930 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1931 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1934 add_option (_("Misc"),
1935 new SpinOption<uint32_t> (
1936 "max-recent-sessions",
1937 _("Maximum number of recent sessions"),
1938 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1939 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1943 add_option (_("Misc/Click"), new OptionEditorHeading (_("Click")));
1945 add_option (_("Misc/Click"), new ClickOptions (_rc_config));
1947 add_option (_("Misc/Click"),
1950 _("Click gain level"),
1951 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1952 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1955 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1957 add_option (_("Misc"),
1958 new SpinOption<double> (
1959 "automation-thinning-factor",
1960 _("Thinning factor (larger value => less data)"),
1961 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1962 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1966 add_option (_("Misc"),
1967 new SpinOption<double> (
1968 "automation-interval-msecs",
1969 _("Automation sampling interval (milliseconds)"),
1970 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1971 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1977 add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options")));
1981 tsf = new BoolOption (
1982 "latched-record-enable",
1983 _("Keep record-enable engaged on stop"),
1984 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1985 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1987 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1988 add_option (_("Transport"), tsf);
1990 tsf = new BoolOption (
1992 _("Play loop is a transport mode"),
1993 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1994 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1996 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1997 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1998 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1999 add_option (_("Transport"), tsf);
2001 tsf = new BoolOption (
2002 "stop-recording-on-xrun",
2003 _("Stop recording when an xrun occurs"),
2004 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
2005 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
2007 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2008 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
2010 add_option (_("Transport"), tsf);
2012 tsf = new BoolOption (
2013 "create-xrun-marker",
2014 _("Create markers where xruns occur"),
2015 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
2016 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
2018 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
2019 add_option (_("Transport"), tsf);
2021 tsf = new BoolOption (
2022 "stop-at-session-end",
2023 _("Stop at the end of the session"),
2024 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
2025 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
2027 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2028 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
2029 "when it reaches the current session end marker\n\n"
2030 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
2032 add_option (_("Transport"), tsf);
2034 tsf = new BoolOption (
2036 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
2037 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
2038 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
2040 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2041 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
2042 "preventing any need to do a transport locate at the end of the loop\n\n"
2043 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
2044 "which will often cause a small click or delay"), PROGRAM_NAME));
2045 add_option (_("Transport"), tsf);
2047 tsf = new BoolOption (
2048 "disable-disarm-during-roll",
2049 _("Disable per-track record disarm while rolling"),
2050 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
2051 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
2053 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"));
2054 add_option (_("Transport"), tsf);
2056 tsf = new BoolOption (
2058 _("12dB gain reduction during fast-forward and fast-rewind"),
2059 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
2060 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
2062 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
2063 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
2064 add_option (_("Transport"), tsf);
2066 ComboOption<float>* psc = new ComboOption<float> (
2069 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
2070 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
2072 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
2073 (_("The amount of preroll (in seconds) to apply when <b>Play with Preroll</b> is initiated.\n\n"
2074 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
2075 psc->add (0.0, _("0 (no pre-roll)"));
2076 psc->add (0.1, _("0.1 second"));
2077 psc->add (0.25, _("0.25 second"));
2078 psc->add (0.5, _("0.5 second"));
2079 psc->add (1.0, _("1.0 second"));
2080 psc->add (2.0, _("2.0 seconds"));
2081 add_option (_("Transport"), psc);
2083 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("Synchronization and Slave Options")));
2085 _sync_source = new ComboOption<SyncSource> (
2087 _("External timecode source"),
2088 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
2089 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
2092 add_option (_("Transport/Sync"), _sync_source);
2094 _sync_framerate = new BoolOption (
2095 "timecode-sync-frame-rate",
2096 _("Match session video frame rate to external timecode"),
2097 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
2098 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
2100 Gtkmm2ext::UI::instance()->set_tip
2101 (_sync_framerate->tip_widget(),
2102 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
2103 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
2104 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
2105 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
2106 "timecode standard and the session standard."), PROGRAM_NAME));
2108 add_option (_("Transport/Sync"), _sync_framerate);
2110 _sync_genlock = new BoolOption (
2111 "timecode-source-is-synced",
2112 _("Sync-lock timecode to clock (disable drift compensation)"),
2113 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
2114 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
2116 Gtkmm2ext::UI::instance()->set_tip
2117 (_sync_genlock->tip_widget(),
2118 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
2119 "Sync Lock indicates that the selected external timecode source shares clock-sync "
2120 "(Black & Burst, Wordclock, etc) with the audio interface. "
2121 "This option disables drift compensation. The transport speed is fixed at 1.0. "
2122 "Vari-speed LTC will be ignored and cause drift."
2124 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
2125 "timecode sources shares clock sync."
2129 add_option (_("Transport/Sync"), _sync_genlock);
2131 _sync_source_2997 = new BoolOption (
2132 "timecode-source-2997",
2133 _("Lock to 29.9700 fps instead of 30000/1001"),
2134 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
2135 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
2137 Gtkmm2ext::UI::instance()->set_tip
2138 (_sync_source_2997->tip_widget(),
2139 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
2140 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
2141 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
2142 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
2143 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
2144 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
2147 add_option (_("Transport/Sync"), _sync_source_2997);
2149 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("LTC Reader")));
2151 _ltc_port = new ComboStringOption (
2153 _("LTC incoming port"),
2154 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
2155 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
2158 vector<string> physical_inputs;
2159 physical_inputs.push_back (_("None"));
2160 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
2161 _ltc_port->set_popdown_strings (physical_inputs);
2163 populate_sync_options ();
2164 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
2166 add_option (_("Transport/Sync"), _ltc_port);
2168 // TODO; rather disable this button than not compile it..
2169 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("LTC Generator")));
2171 add_option (_("Transport/Sync"),
2174 _("Enable LTC generator"),
2175 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
2176 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
2179 _ltc_send_continuously = new BoolOption (
2180 "ltc-send-continuously",
2181 _("Send LTC while stopped"),
2182 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
2183 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
2185 Gtkmm2ext::UI::instance()->set_tip
2186 (_ltc_send_continuously->tip_widget(),
2187 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
2188 add_option (_("Transport"), _ltc_send_continuously);
2190 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
2191 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
2192 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
2193 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
2195 Gtkmm2ext::UI::instance()->set_tip
2196 (_ltc_volume_slider->tip_widget(),
2197 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
2199 add_option (_("Transport/Sync"), _ltc_volume_slider);
2203 add_option (_("Editor"),
2205 "rubberbanding-snaps-to-grid",
2206 _("Make rubberband selection rectangle snap to the grid"),
2207 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2208 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2211 bo = new BoolOption (
2213 _("Name new markers"),
2214 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2215 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2217 add_option (_("Editor"), bo);
2218 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."
2219 "\n\nYou can always rename markers by right-clicking on them"));
2221 add_option (S_("Editor"),
2223 "draggable-playhead",
2224 _("Allow dragging of playhead"),
2225 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2226 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2229 add_option (_("Editor"),
2231 "show-editor-meter",
2232 _("Display master-meter in the toolbar"),
2233 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
2234 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
2237 if (!Profile->get_mixbus()) {
2238 add_option (_("Editor"),
2241 _("Show zoom toolbar (if torn off)"),
2242 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_zoom_tools),
2243 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_zoom_tools)
2246 add_option (_("Editor"),
2248 "use-mouse-position-as-zoom-focus-on-scroll",
2249 _("Always use mouse cursor position as zoom focus when zooming using mouse scroll wheel"),
2250 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2251 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2255 add_option (_("Editor"),
2257 "update-editor-during-summary-drag",
2258 _("Update editor window during drags of the summary"),
2259 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2260 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2263 add_option (_("Editor"),
2265 "autoscroll-editor",
2266 _("Auto-scroll editor window when dragging near its edges"),
2267 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2268 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2271 add_option (_("Editor"),
2272 new BoolComboOption (
2273 "show-region-gain-envelopes",
2274 _("Show gain envelopes in audio regions"),
2276 _("only in Draw and Internal Edit modes"),
2277 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2278 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2281 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2283 add_option (_("Editor"),
2285 "automation-follows-regions",
2286 _("Move relevant automation when audio regions are moved"),
2287 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2288 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2291 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2292 "default-fade-shape",
2293 _("Default fade shape"),
2294 sigc::mem_fun (*_rc_config,
2295 &RCConfiguration::get_default_fade_shape),
2296 sigc::mem_fun (*_rc_config,
2297 &RCConfiguration::set_default_fade_shape)
2300 fadeshape->add (FadeLinear,
2301 _("Linear (for highly correlated material)"));
2302 fadeshape->add (FadeConstantPower, _("Constant power"));
2303 fadeshape->add (FadeSymmetric, _("Symmetric"));
2304 fadeshape->add (FadeSlow, _("Slow"));
2305 fadeshape->add (FadeFast, _("Fast"));
2307 add_option (_("Editor"), fadeshape);
2310 bco = new BoolComboOption (
2311 "use-overlap-equivalency",
2312 _("Regions in active edit groups are edited together"),
2313 _("whenever they overlap in time"),
2314 _("only if they have identical length, position and origin"),
2315 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2316 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2319 add_option (_("Editor"), bco);
2321 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2323 _("Layering model"),
2324 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2325 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2328 lm->add (LaterHigher, _("later is higher"));
2329 lm->add (Manual, _("manual layering"));
2330 add_option (_("Editor"), lm);
2332 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2333 "region-selection-after-split",
2334 _("After splitting selected regions, select"),
2335 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2336 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2338 // TODO: decide which of these modes are really useful
2339 rsas->add(None, _("no regions"));
2340 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2341 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2342 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2343 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2344 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2345 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2346 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2348 add_option (_("Editor"), rsas);
2350 add_option (_("Editor/Waveforms"), new OptionEditorHeading (_("Waveforms")));
2352 if (!Profile->get_mixbus()) {
2353 add_option (_("Editor/Waveforms"),
2356 _("Show waveforms in regions"),
2357 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
2358 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
2362 add_option (_("Editor/Waveforms"),
2364 "show-waveforms-while-recording",
2365 _("Show waveforms for audio while it is being recorded"),
2366 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
2367 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
2370 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
2372 _("Waveform scale"),
2373 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
2374 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
2377 wfs->add (Linear, _("linear"));
2378 wfs->add (Logarithmic, _("logarithmic"));
2380 add_option (_("Editor/Waveforms"), wfs);
2382 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
2384 _("Waveform shape"),
2385 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
2386 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
2389 wfsh->add (Traditional, _("traditional"));
2390 wfsh->add (Rectified, _("rectified"));
2392 add_option (_("Editor/Waveforms"), wfsh);
2394 add_option (_("Editor/Waveforms"), new ClipLevelOptions ());
2399 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2401 add_option (_("Audio"), new BufferingOptions (_rc_config));
2403 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2405 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2407 _("Record monitoring handled by"),
2408 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2409 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2412 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2413 mm->add (HardwareMonitoring, _("via Audio Driver"));
2416 string prog (PROGRAM_NAME);
2417 boost::algorithm::to_lower (prog);
2418 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2419 mm->add (ExternalMonitoring, _("audio hardware"));
2421 add_option (_("Audio"), mm);
2423 add_option (_("Audio"),
2425 "tape-machine-mode",
2426 _("Tape machine mode"),
2427 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2428 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2431 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
2432 if (!Profile->get_mixbus()) {
2434 add_option (_("Audio"),
2436 "auto-connect-standard-busses",
2437 _("Auto-connect master/monitor busses"),
2438 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2439 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2442 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2443 "input-auto-connect",
2444 _("Connect track inputs"),
2445 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2446 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2449 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2450 iac->add (ManualConnect, _("manually"));
2452 add_option (_("Audio"), iac);
2454 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2455 "output-auto-connect",
2456 _("Connect track and bus outputs"),
2457 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2458 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2461 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2462 oac->add (AutoConnectMaster, _("automatically to master bus"));
2463 oac->add (ManualConnect, _("manually"));
2465 add_option (_("Audio"), oac);
2467 bo = new BoolOption (
2469 _("Use 'Strict-I/O' for new tracks or Busses"),
2470 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2471 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2474 add_option (_("Audio"), bo);
2475 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2476 _("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."));
2480 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2482 add_option (_("Audio"),
2484 "denormal-protection",
2485 _("Use DC bias to protect against denormals"),
2486 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2487 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2490 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2492 _("Processor handling"),
2493 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2494 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2498 dm->add (DenormalNone, _("no processor handling"));
2500 FPU* fpu = FPU::instance();
2502 if (fpu->has_flush_to_zero()) {
2504 dm->add (DenormalFTZ, _("use FlushToZero"));
2505 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2506 _rc_config->set_denormal_model(DenormalNone);
2509 if (fpu->has_denormals_are_zero()) {
2511 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2512 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2513 _rc_config->set_denormal_model(DenormalNone);
2516 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2518 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2519 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2520 _rc_config->set_denormal_model(DenormalNone);
2524 dm->set_sensitive(false);
2527 add_option (_("Audio"), dm);
2529 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2531 add_option (_("Audio"),
2533 "auto-analyse-audio",
2534 _("Enable automatic analysis of audio"),
2535 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2536 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2539 add_option (_("Audio"),
2541 "replicate-missing-region-channels",
2542 _("Replicate missing region channels"),
2543 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2544 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2549 add_option (_("Solo & mute"), new OptionEditorHeading (_("Solo")));
2551 _solo_control_is_listen_control = new BoolOption (
2552 "solo-control-is-listen-control",
2553 _("Solo controls are Listen controls"),
2554 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2555 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2558 add_option (_("Solo & mute"), _solo_control_is_listen_control);
2560 add_option (_("Solo & mute"),
2563 _("Exclusive solo"),
2564 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2565 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2568 add_option (_("Solo & mute"),
2571 _("Show solo muting"),
2572 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2573 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2576 add_option (_("Solo & mute"),
2578 "solo-mute-override",
2579 _("Soloing overrides muting"),
2580 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2581 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2584 add_option (_("Solo & mute"),
2587 _("Solo-in-place mute cut (dB)"),
2588 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2589 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2592 _listen_position = new ComboOption<ListenPosition> (
2594 _("Listen Position"),
2595 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2596 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2599 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2600 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2602 add_option (_("Solo & mute"), _listen_position);
2604 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2606 _("PFL signals come from"),
2607 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2608 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2611 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2612 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2614 add_option (_("Solo & mute"), pp);
2616 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2618 _("AFL signals come from"),
2619 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2620 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2623 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2624 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2626 add_option (_("Solo & mute"), pa);
2628 add_option (_("Solo & mute"), new OptionEditorHeading (_("Default track / bus muting options")));
2630 add_option (_("Solo & mute"),
2632 "mute-affects-pre-fader",
2633 _("Mute affects pre-fader sends"),
2634 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2635 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2638 add_option (_("Solo & mute"),
2640 "mute-affects-post-fader",
2641 _("Mute affects post-fader sends"),
2642 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2643 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2646 add_option (_("Solo & mute"),
2648 "mute-affects-control-outs",
2649 _("Mute affects control outputs"),
2650 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2651 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2654 add_option (_("Solo & mute"),
2656 "mute-affects-main-outs",
2657 _("Mute affects main outputs"),
2658 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2659 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2663 if (!ARDOUR::Profile->get_mixbus()) {
2664 add_option (_("Solo & mute"), new OptionEditorHeading (_("Send Routing")));
2665 add_option (_("Solo & mute"),
2667 "link-send-and-route-panner",
2668 _("Link panners of Aux and External Sends with main panner by default"),
2669 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2670 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2674 add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Preferences")));
2676 add_option (_("MIDI"),
2677 new SpinOption<float> (
2679 _("MIDI read-ahead time (seconds)"),
2680 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2681 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2686 add_option (_("MIDI"),
2687 new SpinOption<int32_t> (
2688 "initial-program-change",
2689 _("Initial program change"),
2690 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2691 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2695 add_option (_("MIDI"),
2697 "display-first-midi-bank-as-zero",
2698 _("Display first MIDI bank/program as 0"),
2699 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2700 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2703 add_option (_("MIDI"),
2705 "never-display-periodic-midi",
2706 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2707 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
2708 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
2711 add_option (_("MIDI"),
2714 _("Sound MIDI notes as they are selected in the editor"),
2715 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2716 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2719 add_option (_("MIDI"),
2722 _("Send MIDI control feedback"),
2723 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2724 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2727 add_option (_("MIDI/Sync"), new OptionEditorHeading (_("MIDI Clock")));
2729 add_option (_("MIDI/Sync"),
2732 _("Send MIDI Clock"),
2733 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2734 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2737 add_option (_("MIDI/Sync"), new OptionEditorHeading (_("MIDI Time Code (MTC)")));
2739 add_option (_("MIDI/Sync"),
2742 _("Send MIDI Time Code"),
2743 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2744 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2747 add_option (_("MIDI/Sync"),
2748 new SpinOption<int> (
2749 "mtc-qf-speed-tolerance",
2750 _("Percentage either side of normal transport speed to transmit MTC"),
2751 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2752 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2756 add_option (_("MIDI/Sync"), new OptionEditorHeading (_("Midi Machine Control (MMC)")));
2758 add_option (_("MIDI/Sync"),
2761 _("Obey MIDI Machine Control commands"),
2762 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2763 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2766 add_option (_("MIDI/Sync"),
2769 _("Send MIDI Machine Control commands"),
2770 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2771 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2774 add_option (_("MIDI/Sync"),
2775 new SpinOption<uint8_t> (
2776 "mmc-receive-device-id",
2777 _("Inbound MMC device ID"),
2778 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2779 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2783 add_option (_("MIDI/Sync"),
2784 new SpinOption<uint8_t> (
2785 "mmc-send-device-id",
2786 _("Outbound MMC device ID"),
2787 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2788 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2792 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2794 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2795 "midi-audition-synth-uri",
2796 _("Midi Audition Synth (LV2)"),
2797 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2798 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2801 audition_synth->add(X_(""), _("None"));
2802 PluginInfoList all_plugs;
2803 PluginManager& manager (PluginManager::instance());
2805 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2807 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2808 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2809 if (!(*i)->is_instrument()) continue;
2810 if ((*i)->type != ARDOUR::LV2) continue;
2811 audition_synth->add((*i)->unique_id, (*i)->name);
2815 add_option (_("MIDI"), audition_synth);
2817 /* USER INTERACTION */
2820 #ifdef PLATFORM_WINDOWS
2823 getenv ("ARDOUR_BUNDLED")
2827 add_option (_("User interaction"),
2829 "enable-translation",
2830 string_compose (_("Use translations of %1 messages\n"
2831 " <i>(requires a restart of %1 to take effect)</i>\n"
2832 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2833 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2834 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2837 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2839 add_option (_("User interaction"), new KeyboardOptions);
2841 /* Control Surfaces */
2843 add_option (_("Control Surfaces"), new ControlSurfacesOptions);
2845 /* VIDEO Timeline */
2846 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2848 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2849 add_option (_("Plugins"),
2850 new RcActionButton (_("Scan for Plugins"),
2851 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
2855 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
2857 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2858 bo = new BoolOption (
2859 "show-plugin-scan-window",
2860 _("Always Display Plugin Scan Progress"),
2861 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
2862 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
2864 add_option (_("Plugins"), bo);
2865 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2866 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
2869 bo = new BoolOption (
2870 "plugins-stop-with-transport",
2871 _("Silence plugins when the transport is stopped"),
2872 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
2873 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
2875 add_option (_("Plugins"), bo);
2876 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2877 _("<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."));
2879 bo = new BoolOption (
2880 "new-plugins-active",
2881 _("Make new plugins active"),
2882 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
2883 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
2885 add_option (_("Plugins"), bo);
2886 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2887 _("<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"));
2889 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
2890 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
2891 add_option (_("Plugins/VST"),
2892 new RcActionButton (_("Scan for Plugins"),
2893 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
2895 bo = new BoolOption (
2896 "discover-vst-on-start",
2897 _("Scan for [new] VST Plugins on Application Start"),
2898 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
2899 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
2901 add_option (_("Plugins/VST"), bo);
2902 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2903 _("<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"));
2905 #ifdef WINDOWS_VST_SUPPORT
2906 // currently verbose logging is only implemented for Windows VST.
2907 bo = new BoolOption (
2908 "verbose-plugin-scan",
2909 _("Verbose Plugin Scan"),
2910 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
2911 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
2913 add_option (_("Plugins/VST"), bo);
2914 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2915 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
2918 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
2920 add_option (_("Plugins/VST"),
2921 new RcActionButton (_("Clear"),
2922 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
2925 add_option (_("Plugins/VST"),
2926 new RcActionButton (_("Clear"),
2927 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
2928 _("VST Blacklist:")));
2931 #ifdef LXVST_SUPPORT
2932 add_option (_("Plugins/VST"),
2933 new RcActionButton (_("Edit"),
2934 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
2935 _("Linux VST Path:")));
2937 add_option (_("Plugins/VST"),
2938 new RcConfigDisplay (
2939 "plugin-path-lxvst",
2941 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
2945 #ifdef WINDOWS_VST_SUPPORT
2946 add_option (_("Plugins/VST"),
2947 new RcActionButton (_("Edit"),
2948 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
2949 _("Windows VST Path:")));
2950 add_option (_("Plugins"),
2951 new RcConfigDisplay (
2954 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
2958 #ifdef AUDIOUNIT_SUPPORT
2960 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
2961 add_option (_("Plugins/Audio Unit"),
2962 new RcActionButton (_("Scan for Plugins"),
2963 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
2965 bo = new BoolOption (
2966 "discover-audio-units",
2967 _("Scan for AudioUnit Plugins on Application Start"),
2968 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
2969 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
2971 add_option (_("Plugins"), bo);
2972 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2973 _("<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."));
2975 add_option (_("Plugins/Audio Unit"),
2976 new RcActionButton (_("Clear"),
2977 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
2980 add_option (_("Plugins/Audio Unit"),
2981 new RcActionButton (_("Clear"),
2982 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
2983 _("AU Blacklist:")));
2986 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
2987 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
2988 add_option (_("Plugins"),
2990 "open-gui-after-adding-plugin",
2991 _("Automatically open the plugin GUI when adding a new plugin"),
2992 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
2993 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
2996 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
2997 add_option (_("Plugins"),
2999 "show-inline-display-by-default",
3000 _("Show Plugin Inline Display on Mixerstrip by default"),
3001 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
3002 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3005 _plugin_prefer_inline = new BoolOption (
3006 "prefer-inline-over-gui",
3007 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3008 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3009 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3011 add_option (_("Plugins"), _plugin_prefer_inline);
3014 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3016 bo = new BoolOption (
3017 "ask-replace-instrument",
3018 _("Ask to replace existing instrument plugin"),
3019 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3020 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3022 add_option (_("Plugins"), bo);
3024 bo = new BoolOption (
3025 "ask-setup_instrument",
3026 _("Interactively configure instrument plugins on insert"),
3027 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3028 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3030 add_option (_("Plugins"), bo);
3031 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3032 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3038 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3039 BoolOption* bgc = new BoolOption (
3040 "cairo-image-surface",
3041 _("Disable Graphics Hardware Acceleration (requires restart)"),
3042 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3043 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3046 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3047 _("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));
3048 add_option (S_("Preferences|GUI"), bgc);
3051 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3052 BoolOption* bgo = new BoolOption (
3054 _("Possibly improve slow graphical performance (requires restart)"),
3055 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3056 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3059 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));
3060 add_option (S_("Preferences|GUI"), bgo);
3063 add_option (S_("Preferences|GUI"),
3065 "use-wm-visibility",
3066 _("Use Window Manager/Desktop visibility information"),
3067 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3068 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3071 add_option (S_("Preferences|GUI"),
3074 _("Graphically indicate mouse pointer hovering over various widgets"),
3075 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3076 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3079 add_option (S_("Preferences|GUI"),
3082 _("Show tooltips if mouse hovers over a control"),
3083 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3084 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3087 add_option (S_("Preferences|GUI"),
3089 "show-name-highlight",
3090 _("Use name highlight bars in region displays (requires a restart)"),
3091 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3092 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3095 add_option (S_("Preferences|GUI"),
3097 "super-rapid-clock-update",
3098 _("Update transport clock display at FPS instead of every 100ms"),
3099 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3100 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3105 /* font scaling does nothing with GDK/Quartz */
3106 add_option (S_("Preferences|GUI"), new FontScalingOptions ());
3109 /* Image cache size */
3111 Gtk::Adjustment *ics = manage (new Gtk::Adjustment(0, 1, 1024, 10)); /* 1 MB to 1GB in steps of 10MB */
3112 HSliderOption *sics = new HSliderOption("waveform-cache-size",
3113 _("Waveform image cache size (megabytes)"),
3115 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
3116 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size)
3118 sics->scale().set_digits (0);
3119 Gtkmm2ext::UI::instance()->set_tip
3120 (sics->tip_widget(),
3121 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
3122 add_option (S_("Preferences|GUI"), sics);
3124 if (!ARDOUR::Profile->get_mixbus()) {
3125 /* Lock GUI timeout */
3127 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
3128 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
3129 _("Lock timeout (seconds)"),
3131 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
3132 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds)
3134 slts->scale().set_digits (0);
3135 Gtkmm2ext::UI::instance()->set_tip
3136 (slts->tip_widget(),
3137 _("Lock GUI after this many idle seconds (zero to never lock)"));
3138 add_option (S_("Preferences|GUI"), slts);
3141 /* The names of these controls must be the same as those given in MixerStrip
3142 for the actual widgets being controlled.
3144 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3145 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3146 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3147 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3148 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3149 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3150 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3153 S_("Preferences|GUI"),
3154 new VisibilityOption (
3156 &_mixer_strip_visibility,
3157 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3158 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3162 add_option (S_("Preferences|GUI"),
3164 "default-narrow_ms",
3165 _("Use narrow strips in the mixer by default"),
3166 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3167 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3170 add_option (S_("Preferences|GUI"),
3171 new ColumVisibilityOption (
3172 "action-table-columns", _("Action Script Button Visibility"), 3,
3173 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3174 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3178 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
3180 ComboOption<float>* mht = new ComboOption<float> (
3182 _("Peak hold time"),
3183 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
3184 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
3187 mht->add (MeterHoldOff, _("off"));
3188 mht->add (MeterHoldShort, _("short"));
3189 mht->add (MeterHoldMedium, _("medium"));
3190 mht->add (MeterHoldLong, _("long"));
3192 add_option (S_("Preferences|Metering"), mht);
3194 ComboOption<float>* mfo = new ComboOption<float> (
3197 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
3198 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
3201 mfo->add (METER_FALLOFF_OFF, _("off"));
3202 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
3203 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
3204 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
3205 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
3206 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
3207 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
3209 add_option (S_("Preferences|Metering"), mfo);
3211 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
3212 "meter-line-up-level",
3213 _("Meter line-up level; 0dBu"),
3214 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
3215 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
3218 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3219 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3220 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3221 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3223 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."));
3225 add_option (S_("Preferences|Metering"), mlu);
3227 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
3228 "meter-line-up-din",
3229 _("IEC1/DIN Meter line-up level; 0dBu"),
3230 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
3231 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
3234 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3235 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3236 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3237 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3239 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
3241 add_option (S_("Preferences|Metering"), mld);
3243 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
3244 "meter-vu-standard",
3245 _("VU Meter standard"),
3246 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
3247 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
3250 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
3251 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
3252 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
3253 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
3255 add_option (S_("Preferences|Metering"), mvu);
3257 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
3258 HSliderOption *mpks = new HSliderOption("meter-peak",
3259 _("Peak threshold [dBFS]"),
3261 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
3262 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak)
3266 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
3267 "meter-type-master",
3268 _("Default Meter Type for Master Bus"),
3269 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
3270 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3272 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3273 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3274 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3275 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3276 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3277 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3278 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3279 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3281 add_option (S_("Preferences|Metering"), mtm);
3284 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3286 _("Default Meter Type for Busses"),
3287 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3288 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3290 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3291 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3292 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3293 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3294 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3295 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3296 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3297 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3299 add_option (S_("Preferences|Metering"), mtb);
3301 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3303 _("Default Meter Type for Tracks"),
3304 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3305 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3307 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3308 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3310 add_option (S_("Preferences|Metering"), mtt);
3313 Gtkmm2ext::UI::instance()->set_tip
3314 (mpks->tip_widget(),
3315 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
3317 add_option (S_("Preferences|Metering"), mpks);
3319 add_option (S_("Preferences|Metering"),
3322 _("LED meter style"),
3323 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3324 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3327 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Editor Meters")));
3329 add_option (S_("Preferences|Metering"),
3331 "show-track-meters",
3332 _("Show meters on tracks in the editor"),
3333 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3334 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3337 add_option (S_("Preferences|Metering"),
3339 "editor-stereo-only-meters",
3340 _("Show at most stereo meters in the track-header"),
3341 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3342 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3345 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
3347 add_option (S_("Preferences|Metering"),
3349 "save-export-analysis-image",
3350 _("Save loudness analysis as image file"),
3351 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
3352 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
3355 /* and now the theme manager */
3357 ThemeManager* tm = manage (new ThemeManager);
3358 add_page (_("Theme"), *tm);
3360 add_option (_("Theme/Colors"), new ColorThemeManager);
3362 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3363 parameter_changed ("send-ltc");
3364 parameter_changed ("sync-source");
3365 parameter_changed ("use-monitor-bus");
3366 parameter_changed ("open-gui-after-adding-plugin");
3370 RCOptionEditor::parameter_changed (string const & p)
3372 OptionEditor::parameter_changed (p);
3374 if (p == "use-monitor-bus") {
3375 bool const s = Config->get_use_monitor_bus ();
3377 /* we can't use this if we don't have a monitor bus */
3378 Config->set_solo_control_is_listen_control (false);
3380 _solo_control_is_listen_control->set_sensitive (s);
3381 _listen_position->set_sensitive (s);
3382 } else if (p == "sync-source") {
3383 _sync_source->set_sensitive (true);
3385 _sync_source->set_sensitive (!_session->config.get_external_sync());
3387 switch(Config->get_sync_source()) {
3390 _sync_genlock->set_sensitive (true);
3391 _sync_framerate->set_sensitive (true);
3392 _sync_source_2997->set_sensitive (true);
3395 _sync_genlock->set_sensitive (false);
3396 _sync_framerate->set_sensitive (false);
3397 _sync_source_2997->set_sensitive (false);
3400 } else if (p == "send-ltc") {
3401 bool const s = Config->get_send_ltc ();
3402 _ltc_send_continuously->set_sensitive (s);
3403 _ltc_volume_slider->set_sensitive (s);
3404 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
3405 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3406 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
3411 void RCOptionEditor::ltc_generator_volume_changed () {
3412 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
3415 void RCOptionEditor::plugin_scan_refresh () {
3416 PluginManager::instance().refresh();
3419 void RCOptionEditor::clear_vst_cache () {
3420 PluginManager::instance().clear_vst_cache();
3423 void RCOptionEditor::clear_vst_blacklist () {
3424 PluginManager::instance().clear_vst_blacklist();
3427 void RCOptionEditor::clear_au_cache () {
3428 PluginManager::instance().clear_au_cache();
3431 void RCOptionEditor::clear_au_blacklist () {
3432 PluginManager::instance().clear_au_blacklist();
3435 void RCOptionEditor::edit_lxvst_path () {
3436 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
3437 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3438 *current_toplevel(), _("Set Linux VST Search Path"),
3439 _rc_config->get_plugin_path_lxvst(),
3440 PluginManager::instance().get_default_lxvst_path()
3442 ResponseType r = (ResponseType) pd->run ();
3444 if (r == RESPONSE_ACCEPT) {
3445 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
3450 void RCOptionEditor::edit_vst_path () {
3451 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3452 *current_toplevel(), _("Set Windows VST Search Path"),
3453 _rc_config->get_plugin_path_vst(),
3454 PluginManager::instance().get_default_windows_vst_path()
3456 ResponseType r = (ResponseType) pd->run ();
3458 if (r == RESPONSE_ACCEPT) {
3459 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
3466 RCOptionEditor::populate_sync_options ()
3468 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3470 _sync_source->clear ();
3472 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3473 _sync_source->add (*i, sync_source_to_string (*i));
3476 if (sync_opts.empty()) {
3477 _sync_source->set_sensitive(false);
3479 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3480 _rc_config->set_sync_source(sync_opts.front());
3484 parameter_changed ("sync-source");
3488 RCOptionEditor::use_own_window (bool and_fill_it)
3490 bool new_window = !own_window();
3492 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
3494 if (win && new_window) {
3495 win->set_name ("PreferencesWindow");
3496 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
3503 RCOptionEditor::get_state ()
3505 XMLNode* node = new XMLNode (X_("Preferences"));
3506 node->add_child_nocopy (Tabbable::get_state());