2 Copyright (C) 2001-2011 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "gtk2ardour-config.h"
24 #if !defined USE_CAIRO_IMAGE_SURFACE && !defined NDEBUG
25 #define OPTIONAL_CAIRO_IMAGE_SURFACE
28 #include <cairo/cairo.h>
30 #include <boost/algorithm/string.hpp>
32 #include <gtkmm/liststore.h>
33 #include <gtkmm/stock.h>
34 #include <gtkmm/scale.h>
36 #include <gtkmm2ext/utils.h>
37 #include <gtkmm2ext/slider_controller.h>
38 #include <gtkmm2ext/gtk_ui.h>
39 #include <gtkmm2ext/paths_dialog.h>
40 #include <gtkmm2ext/window_title.h>
45 #include "ardour/audioengine.h"
46 #include "ardour/profile.h"
47 #include "ardour/dB.h"
48 #include "ardour/rc_configuration.h"
49 #include "ardour/control_protocol_manager.h"
50 #include "ardour/plugin_manager.h"
51 #include "control_protocol/control_protocol.h"
53 #include "canvas/wave_view.h"
55 #include "ardour_window.h"
56 #include "ardour_dialog.h"
57 #include "ardour_ui.h"
58 #include "color_theme_manager.h"
59 #include "gui_thread.h"
60 #include "meter_patterns.h"
61 #include "midi_tracer.h"
62 #include "rc_option_editor.h"
64 #include "midi_port_dialog.h"
67 #include "theme_manager.h"
68 #include "ui_config.h"
73 using namespace Gtkmm2ext;
75 using namespace ARDOUR;
76 using namespace ARDOUR_UI_UTILS;
78 class ClickOptions : public OptionEditorBox
81 ClickOptions (RCConfiguration* c)
83 , _click_browse_button (_("Browse..."))
84 , _click_emphasis_browse_button (_("Browse..."))
86 Table* t = manage (new Table (4, 3));
89 Label* l = manage (left_aligned_label (_("Emphasis on first beat:")));
90 t->attach (*l, 0, 1, 1, 2, FILL);
91 t->attach (_use_emphasis_on_click_check_button, 1, 2, 1, 2, FILL);
92 _use_emphasis_on_click_check_button.signal_toggled().connect (
93 sigc::mem_fun (*this, &ClickOptions::use_emphasis_on_click_toggled));
95 l = manage (left_aligned_label (_("Use default Click:")));
96 t->attach (*l, 0, 1, 0, 1, FILL);
97 t->attach (_use_default_click_check_button, 1, 2, 0, 1, FILL);
98 _use_default_click_check_button.signal_toggled().connect (
99 sigc::mem_fun (*this, &ClickOptions::use_default_click_toggled));
101 l = manage (left_aligned_label (_("Click audio file:")));
102 t->attach (*l, 0, 1, 2, 3, FILL);
103 t->attach (_click_path_entry, 1, 2, 2, 3, FILL);
104 _click_browse_button.signal_clicked ().connect (
105 sigc::mem_fun (*this, &ClickOptions::click_browse_clicked));
106 t->attach (_click_browse_button, 2, 3, 2, 3, FILL);
108 l = manage (left_aligned_label (_("Click emphasis audio file:")));
109 t->attach (*l, 0, 1, 3, 4, FILL);
110 t->attach (_click_emphasis_path_entry, 1, 2, 3, 4, FILL);
111 _click_emphasis_browse_button.signal_clicked ().connect (
112 sigc::mem_fun (*this, &ClickOptions::click_emphasis_browse_clicked));
113 t->attach (_click_emphasis_browse_button, 2, 3, 3, 4, FILL);
115 _box->pack_start (*t, true, false);
117 _click_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_changed));
118 _click_emphasis_path_entry.signal_activate().connect (sigc::mem_fun (*this, &ClickOptions::click_emphasis_changed));
120 if (_rc_config->get_click_sound ().empty() &&
121 _rc_config->get_click_emphasis_sound().empty()) {
122 _use_default_click_check_button.set_active (true);
123 _use_emphasis_on_click_check_button.set_active (true);
126 _use_default_click_check_button.set_active (false);
127 _use_emphasis_on_click_check_button.set_active (false);
131 void parameter_changed (string const & p)
133 if (p == "click-sound") {
134 _click_path_entry.set_text (_rc_config->get_click_sound());
135 } else if (p == "click-emphasis-sound") {
136 _click_emphasis_path_entry.set_text (_rc_config->get_click_emphasis_sound());
137 } else if (p == "use-click-emphasis") {
138 bool x = _rc_config->get_use_click_emphasis ();
139 _use_emphasis_on_click_check_button.set_active (x);
143 void set_state_from_config ()
145 parameter_changed ("click-sound");
146 parameter_changed ("click-emphasis-sound");
147 parameter_changed ("use-click-emphasis");
152 void click_browse_clicked ()
154 SoundFileChooser sfdb (_("Choose Click"));
159 if (sfdb.run () == RESPONSE_OK) {
160 click_chosen (sfdb.get_filename());
164 void click_chosen (string const & path)
166 _click_path_entry.set_text (path);
167 _rc_config->set_click_sound (path);
170 void click_changed ()
172 click_chosen (_click_path_entry.get_text ());
175 void click_emphasis_browse_clicked ()
177 SoundFileChooser sfdb (_("Choose Click Emphasis"));
182 if (sfdb.run () == RESPONSE_OK) {
183 click_emphasis_chosen (sfdb.get_filename());
187 void click_emphasis_chosen (string const & path)
189 _click_emphasis_path_entry.set_text (path);
190 _rc_config->set_click_emphasis_sound (path);
193 void click_emphasis_changed ()
195 click_emphasis_chosen (_click_emphasis_path_entry.get_text ());
198 void use_default_click_toggled ()
200 if (_use_default_click_check_button.get_active ()) {
201 _rc_config->set_click_sound ("");
202 _rc_config->set_click_emphasis_sound ("");
203 _click_path_entry.set_sensitive (false);
204 _click_emphasis_path_entry.set_sensitive (false);
205 _click_browse_button.set_sensitive (false);
206 _click_emphasis_browse_button.set_sensitive (false);
208 _click_path_entry.set_sensitive (true);
209 _click_emphasis_path_entry.set_sensitive (true);
210 _click_browse_button.set_sensitive (true);
211 _click_emphasis_browse_button.set_sensitive (true);
215 void use_emphasis_on_click_toggled ()
217 if (_use_emphasis_on_click_check_button.get_active ()) {
218 _rc_config->set_use_click_emphasis(true);
220 _rc_config->set_use_click_emphasis(false);
224 RCConfiguration* _rc_config;
225 CheckButton _use_default_click_check_button;
226 CheckButton _use_emphasis_on_click_check_button;
227 Entry _click_path_entry;
228 Entry _click_emphasis_path_entry;
229 Button _click_browse_button;
230 Button _click_emphasis_browse_button;
233 class UndoOptions : public OptionEditorBox
236 UndoOptions (RCConfiguration* c) :
238 _limit_undo_button (_("Limit undo history to")),
239 _save_undo_button (_("Save undo history of"))
241 Table* t = new Table (2, 3);
244 t->attach (_limit_undo_button, 0, 1, 0, 1, FILL);
245 _limit_undo_spin.set_range (0, 512);
246 _limit_undo_spin.set_increments (1, 10);
247 t->attach (_limit_undo_spin, 1, 2, 0, 1, FILL | EXPAND);
248 Label* l = manage (left_aligned_label (_("commands")));
249 t->attach (*l, 2, 3, 0, 1);
251 t->attach (_save_undo_button, 0, 1, 1, 2, FILL);
252 _save_undo_spin.set_range (0, 512);
253 _save_undo_spin.set_increments (1, 10);
254 t->attach (_save_undo_spin, 1, 2, 1, 2, FILL | EXPAND);
255 l = manage (left_aligned_label (_("commands")));
256 t->attach (*l, 2, 3, 1, 2);
258 _box->pack_start (*t);
260 _limit_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_toggled));
261 _limit_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::limit_undo_changed));
262 _save_undo_button.signal_toggled().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_toggled));
263 _save_undo_spin.signal_value_changed().connect (sigc::mem_fun (*this, &UndoOptions::save_undo_changed));
266 void parameter_changed (string const & p)
268 if (p == "history-depth") {
269 int32_t const d = _rc_config->get_history_depth();
270 _limit_undo_button.set_active (d != 0);
271 _limit_undo_spin.set_sensitive (d != 0);
272 _limit_undo_spin.set_value (d);
273 } else if (p == "save-history") {
274 bool const x = _rc_config->get_save_history ();
275 _save_undo_button.set_active (x);
276 _save_undo_spin.set_sensitive (x);
277 } else if (p == "save-history-depth") {
278 _save_undo_spin.set_value (_rc_config->get_saved_history_depth());
282 void set_state_from_config ()
284 parameter_changed ("save-history");
285 parameter_changed ("history-depth");
286 parameter_changed ("save-history-depth");
289 void limit_undo_toggled ()
291 bool const x = _limit_undo_button.get_active ();
292 _limit_undo_spin.set_sensitive (x);
293 int32_t const n = x ? 16 : 0;
294 _limit_undo_spin.set_value (n);
295 _rc_config->set_history_depth (n);
298 void limit_undo_changed ()
300 _rc_config->set_history_depth (_limit_undo_spin.get_value_as_int ());
303 void save_undo_toggled ()
305 bool const x = _save_undo_button.get_active ();
306 _rc_config->set_save_history (x);
309 void save_undo_changed ()
311 _rc_config->set_saved_history_depth (_save_undo_spin.get_value_as_int ());
315 RCConfiguration* _rc_config;
316 CheckButton _limit_undo_button;
317 SpinButton _limit_undo_spin;
318 CheckButton _save_undo_button;
319 SpinButton _save_undo_spin;
324 static const struct {
336 { "Key|Shift", GDK_SHIFT_MASK },
337 { "Command", GDK_MOD2_MASK },
338 { "Control", GDK_CONTROL_MASK },
339 { "Option", GDK_MOD1_MASK },
340 { "Command-Shift", GDK_MOD2_MASK|GDK_SHIFT_MASK },
341 { "Command-Option", GDK_MOD2_MASK|GDK_MOD1_MASK },
342 { "Command-Control", GDK_MOD2_MASK|GDK_CONTROL_MASK },
343 { "Command-Option-Control", GDK_MOD2_MASK|GDK_MOD1_MASK|GDK_CONTROL_MASK },
344 { "Option-Control", GDK_MOD1_MASK|GDK_CONTROL_MASK },
345 { "Option-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
346 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
347 { "Shift-Command-Option", GDK_MOD5_MASK|GDK_SHIFT_MASK|GDK_MOD2_MASK },
350 { "Key|Shift", GDK_SHIFT_MASK },
351 { "Control", GDK_CONTROL_MASK },
352 { "Alt", GDK_MOD1_MASK },
353 { "Control-Shift", GDK_CONTROL_MASK|GDK_SHIFT_MASK },
354 { "Control-Alt", GDK_CONTROL_MASK|GDK_MOD1_MASK },
355 { "Control-Windows", GDK_CONTROL_MASK|GDK_MOD4_MASK },
356 { "Control-Shift-Alt", GDK_CONTROL_MASK|GDK_SHIFT_MASK|GDK_MOD1_MASK },
357 { "Alt-Windows", GDK_MOD1_MASK|GDK_MOD4_MASK },
358 { "Alt-Shift", GDK_MOD1_MASK|GDK_SHIFT_MASK },
359 { "Alt-Shift-Windows", GDK_MOD1_MASK|GDK_SHIFT_MASK|GDK_MOD4_MASK },
360 { "Mod2", GDK_MOD2_MASK },
361 { "Mod3", GDK_MOD3_MASK },
362 { "Windows", GDK_MOD4_MASK },
363 { "Mod5", GDK_MOD5_MASK },
369 class KeyboardOptions : public OptionEditorBox
373 _delete_button_adjustment (3, 1, 12),
374 _delete_button_spin (_delete_button_adjustment),
375 _edit_button_adjustment (3, 1, 5),
376 _edit_button_spin (_edit_button_adjustment),
377 _insert_note_button_adjustment (3, 1, 5),
378 _insert_note_button_spin (_insert_note_button_adjustment)
380 const std::string restart_msg = _("\nChanges to this setting will only persist after your project has been saved.");
381 /* internationalize and prepare for use with combos */
384 for (int i = 0; modifiers[i].name; ++i) {
385 dumb.push_back (S_(modifiers[i].name));
388 set_popdown_strings (_edit_modifier_combo, dumb);
389 _edit_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_modifier_chosen));
390 Gtkmm2ext::UI::instance()->set_tip (_edit_modifier_combo,
391 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
392 for (int x = 0; modifiers[x].name; ++x) {
393 if (modifiers[x].modifier == Keyboard::edit_modifier ()) {
394 _edit_modifier_combo.set_active_text (S_(modifiers[x].name));
399 Table* t = manage (new Table (5, 11));
405 Label* l = manage (left_aligned_label (_("Select Keyboard layout:")));
406 l->set_name ("OptionsLabel");
410 for (map<string,string>::iterator bf = Keyboard::binding_files.begin(); bf != Keyboard::binding_files.end(); ++bf) {
411 strs.push_back (bf->first);
414 set_popdown_strings (_keyboard_layout_selector, strs);
415 _keyboard_layout_selector.set_active_text (Keyboard::current_binding_name());
416 _keyboard_layout_selector.signal_changed().connect (sigc::mem_fun (*this, &KeyboardOptions::bindings_changed));
418 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
419 t->attach (_keyboard_layout_selector, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
424 l = manage (left_aligned_label (_("When Clicking:")));
425 l->set_name ("OptionEditorHeading");
426 t->attach (*l, col, col + 2, row, row + 1, FILL | EXPAND, FILL);
431 l = manage (left_aligned_label (_("Edit using:")));
432 l->set_name ("OptionsLabel");
434 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
435 t->attach (_edit_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
437 l = manage (new Label (_("+ button")));
438 l->set_name ("OptionsLabel");
440 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
441 t->attach (_edit_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
443 _edit_button_spin.set_name ("OptionsEntry");
444 _edit_button_adjustment.set_value (Keyboard::edit_button());
445 _edit_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::edit_button_changed));
450 set_popdown_strings (_delete_modifier_combo, dumb);
451 _delete_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_modifier_chosen));
452 Gtkmm2ext::UI::instance()->set_tip (_delete_modifier_combo,
453 (string_compose (_("<b>Recommended Setting: %1 + button 3 (right mouse button)</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
454 for (int x = 0; modifiers[x].name; ++x) {
455 if (modifiers[x].modifier == Keyboard::delete_modifier ()) {
456 _delete_modifier_combo.set_active_text (S_(modifiers[x].name));
461 l = manage (left_aligned_label (_("Delete using:")));
462 l->set_name ("OptionsLabel");
464 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
465 t->attach (_delete_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
467 l = manage (new Label (_("+ button")));
468 l->set_name ("OptionsLabel");
470 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
471 t->attach (_delete_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
473 _delete_button_spin.set_name ("OptionsEntry");
474 _delete_button_adjustment.set_value (Keyboard::delete_button());
475 _delete_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::delete_button_changed));
480 set_popdown_strings (_insert_note_modifier_combo, dumb);
481 _insert_note_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_modifier_chosen));
482 Gtkmm2ext::UI::instance()->set_tip (_insert_note_modifier_combo,
483 (string_compose (_("<b>Recommended Setting: %1 + button 1 (left mouse button)</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
484 for (int x = 0; modifiers[x].name; ++x) {
485 if (modifiers[x].modifier == Keyboard::insert_note_modifier ()) {
486 _insert_note_modifier_combo.set_active_text (S_(modifiers[x].name));
491 l = manage (left_aligned_label (_("Insert note using:")));
492 l->set_name ("OptionsLabel");
494 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
495 t->attach (_insert_note_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
497 l = manage (new Label (_("+ button")));
498 l->set_name ("OptionsLabel");
500 t->attach (*l, col + 3, col + 4, row, row + 1, FILL | EXPAND, FILL);
501 t->attach (_insert_note_button_spin, col + 4, col + 5, row, row + 1, FILL | EXPAND, FILL);
503 _insert_note_button_spin.set_name ("OptionsEntry");
504 _insert_note_button_adjustment.set_value (Keyboard::insert_note_button());
505 _insert_note_button_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::insert_note_button_changed));
509 l = manage (left_aligned_label (_("When Beginning a Drag:")));
510 l->set_name ("OptionEditorHeading");
511 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
517 set_popdown_strings (_copy_modifier_combo, dumb);
518 _copy_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::copy_modifier_chosen));
519 Gtkmm2ext::UI::instance()->set_tip (_copy_modifier_combo,
520 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
522 Keyboard::secondary_modifier_name (),
524 Keyboard::primary_modifier_name (),
527 for (int x = 0; modifiers[x].name; ++x) {
528 if (modifiers[x].modifier == (guint) Keyboard::CopyModifier) {
529 _copy_modifier_combo.set_active_text (S_(modifiers[x].name));
534 l = manage (left_aligned_label (_("Copy items using:")));
535 l->set_name ("OptionsLabel");
537 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
538 t->attach (_copy_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
543 /* constraint modifier */
544 set_popdown_strings (_constraint_modifier_combo, dumb);
545 _constraint_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::constraint_modifier_chosen));
546 std::string mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ());
547 Gtkmm2ext::UI::instance()->set_tip (_constraint_modifier_combo,
548 (string_compose (_("<b>Recommended Setting: %1</b>%2"),
550 Keyboard::primary_modifier_name (),
552 Keyboard::tertiary_modifier_name (),
555 for (int x = 0; modifiers[x].name; ++x) {
556 if (modifiers[x].modifier == (guint) ArdourKeyboard::constraint_modifier ()) {
557 _constraint_modifier_combo.set_active_text (S_(modifiers[x].name));
562 l = manage (left_aligned_label (_("Constrain drag using:")));
563 l->set_name ("OptionsLabel");
565 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
566 t->attach (_constraint_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
572 set_popdown_strings (_push_points_combo, dumb);
573 _push_points_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::push_points_modifier_chosen));
575 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::level4_modifier_name ());
576 Gtkmm2ext::UI::instance()->set_tip (_push_points_combo,
577 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
578 for (int x = 0; modifiers[x].name; ++x) {
579 if (modifiers[x].modifier == (guint) ArdourKeyboard::push_points_modifier ()) {
580 _push_points_combo.set_active_text (S_(modifiers[x].name));
585 l = manage (left_aligned_label (_("Push points using:")));
586 l->set_name ("OptionsLabel");
588 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
589 t->attach (_push_points_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
593 l = manage (left_aligned_label (_("When Beginning a Trim:")));
594 l->set_name ("OptionEditorHeading");
595 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
601 set_popdown_strings (_trim_contents_combo, dumb);
602 _trim_contents_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_contents_modifier_chosen));
603 Gtkmm2ext::UI::instance()->set_tip (_trim_contents_combo,
604 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::primary_modifier_name (), restart_msg)));
605 for (int x = 0; modifiers[x].name; ++x) {
606 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_contents_modifier ()) {
607 _trim_contents_combo.set_active_text (S_(modifiers[x].name));
612 l = manage (left_aligned_label (_("Trim contents using:")));
613 l->set_name ("OptionsLabel");
615 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
616 t->attach (_trim_contents_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
622 set_popdown_strings (_trim_anchored_combo, dumb);
623 _trim_anchored_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_anchored_modifier_chosen));
625 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::tertiary_modifier_name ());
626 Gtkmm2ext::UI::instance()->set_tip (_trim_anchored_combo,
627 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
628 for (int x = 0; modifiers[x].name; ++x) {
629 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_anchored_modifier ()) {
630 _trim_anchored_combo.set_active_text (S_(modifiers[x].name));
635 l = manage (left_aligned_label (_("Anchored trim using:")));
636 l->set_name ("OptionsLabel");
638 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
640 t->attach (_trim_anchored_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
645 /* jump trim disabled for now
646 set_popdown_strings (_trim_jump_combo, dumb);
647 _trim_jump_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_jump_modifier_chosen));
649 for (int x = 0; modifiers[x].name; ++x) {
650 if (modifiers[x].modifier == (guint) Keyboard::trim_jump_modifier ()) {
651 _trim_jump_combo.set_active_text (S_(modifiers[x].name));
656 l = manage (left_aligned_label (_("Jump after trim using:")));
657 l->set_name ("OptionsLabel");
659 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
661 t->attach (_trim_jump_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
667 /* note resize relative */
668 set_popdown_strings (_note_size_relative_combo, dumb);
669 _note_size_relative_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::note_size_relative_modifier_chosen));
670 Gtkmm2ext::UI::instance()->set_tip (_note_size_relative_combo,
671 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
672 for (int x = 0; modifiers[x].name; ++x) {
673 if (modifiers[x].modifier == (guint) ArdourKeyboard::note_size_relative_modifier ()) {
674 _note_size_relative_combo.set_active_text (S_(modifiers[x].name));
679 l = manage (left_aligned_label (_("Resize notes relatively using:")));
680 l->set_name ("OptionsLabel");
682 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
684 t->attach (_note_size_relative_combo, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
688 l = manage (left_aligned_label (_("While Dragging:")));
689 l->set_name ("OptionEditorHeading");
690 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
696 set_popdown_strings (_snap_modifier_combo, dumb);
697 _snap_modifier_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_modifier_chosen));
699 mod_str = string_compose (X_("%1-%2"), Keyboard::level4_modifier_name (), Keyboard::tertiary_modifier_name ());
701 mod_str = Keyboard::secondary_modifier_name();
703 Gtkmm2ext::UI::instance()->set_tip (_snap_modifier_combo,
704 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
705 for (int x = 0; modifiers[x].name; ++x) {
706 if (modifiers[x].modifier == (guint) Keyboard::snap_modifier ()) {
707 _snap_modifier_combo.set_active_text (S_(modifiers[x].name));
712 l = manage (left_aligned_label (_("Ignore snap using:")));
713 l->set_name ("OptionsLabel");
715 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
716 t->attach (_snap_modifier_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
722 set_popdown_strings (_snap_delta_combo, dumb);
723 _snap_delta_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::snap_delta_modifier_chosen));
725 mod_str = Keyboard::level4_modifier_name ();
727 mod_str = string_compose (X_("%1-%2"), Keyboard::secondary_modifier_name (), Keyboard::level4_modifier_name ());
729 Gtkmm2ext::UI::instance()->set_tip (_snap_delta_combo,
730 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
731 for (int x = 0; modifiers[x].name; ++x) {
732 if (modifiers[x].modifier == (guint) Keyboard::snap_delta_modifier ()) {
733 _snap_delta_combo.set_active_text (S_(modifiers[x].name));
738 l = manage (left_aligned_label (_("Snap relatively using:")));
739 l->set_name ("OptionsLabel");
741 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
742 t->attach (_snap_delta_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
746 l = manage (left_aligned_label (_("While Trimming:")));
747 l->set_name ("OptionEditorHeading");
748 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
754 set_popdown_strings (_trim_overlap_combo, dumb);
755 _trim_overlap_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::trim_overlap_modifier_chosen));
757 Gtkmm2ext::UI::instance()->set_tip (_trim_overlap_combo,
758 (string_compose (_("<b>Recommended Setting: %1</b>%2"), Keyboard::tertiary_modifier_name (), restart_msg)));
759 for (int x = 0; modifiers[x].name; ++x) {
760 if (modifiers[x].modifier == (guint) ArdourKeyboard::trim_overlap_modifier ()) {
761 _trim_overlap_combo.set_active_text (S_(modifiers[x].name));
766 l = manage (left_aligned_label (_("Resize overlapped regions using:")));
767 l->set_name ("OptionsLabel");
769 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
770 t->attach (_trim_overlap_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
774 l = manage (left_aligned_label (_("While Dragging Control Points:")));
775 l->set_name ("OptionEditorHeading");
776 t->attach (*l, 0, 2, row, row + 1, FILL | EXPAND, FILL);
782 set_popdown_strings (_fine_adjust_combo, dumb);
783 _fine_adjust_combo.signal_changed().connect (sigc::mem_fun(*this, &KeyboardOptions::fine_adjust_modifier_chosen));
785 mod_str = string_compose (X_("%1-%2"), Keyboard::primary_modifier_name (), Keyboard::secondary_modifier_name ());
786 Gtkmm2ext::UI::instance()->set_tip (_fine_adjust_combo,
787 (string_compose (_("<b>Recommended Setting: %1</b>%2"), mod_str, restart_msg)));
788 for (int x = 0; modifiers[x].name; ++x) {
789 if (modifiers[x].modifier == (guint) ArdourKeyboard::fine_adjust_modifier ()) {
790 _fine_adjust_combo.set_active_text (S_(modifiers[x].name));
795 l = manage (left_aligned_label (_("Fine adjust using:")));
796 l->set_name ("OptionsLabel");
798 t->attach (*l, col, col + 1, row, row + 1, FILL | EXPAND, FILL);
799 t->attach (_fine_adjust_combo, col + 1, col + 2, row, row + 1, FILL | EXPAND, FILL);
801 _box->pack_start (*t, false, false);
804 void parameter_changed (string const &)
806 /* XXX: these aren't really config options... */
809 void set_state_from_config ()
811 /* XXX: these aren't really config options... */
816 void bindings_changed ()
818 string const txt = _keyboard_layout_selector.get_active_text();
820 /* XXX: config...? for all this keyboard stuff */
822 for (map<string,string>::iterator i = Keyboard::binding_files.begin(); i != Keyboard::binding_files.end(); ++i) {
823 if (txt == i->first) {
824 if (Keyboard::load_keybindings (i->second)) {
825 Keyboard::save_keybindings ();
831 void edit_modifier_chosen ()
833 string const txt = _edit_modifier_combo.get_active_text();
835 for (int i = 0; modifiers[i].name; ++i) {
836 if (txt == S_(modifiers[i].name)) {
837 Keyboard::set_edit_modifier (modifiers[i].modifier);
843 void delete_modifier_chosen ()
845 string const txt = _delete_modifier_combo.get_active_text();
847 for (int i = 0; modifiers[i].name; ++i) {
848 if (txt == S_(modifiers[i].name)) {
849 Keyboard::set_delete_modifier (modifiers[i].modifier);
855 void copy_modifier_chosen ()
857 string const txt = _copy_modifier_combo.get_active_text();
859 for (int i = 0; modifiers[i].name; ++i) {
860 if (txt == S_(modifiers[i].name)) {
861 Keyboard::set_copy_modifier (modifiers[i].modifier);
867 void insert_note_modifier_chosen ()
869 string const txt = _insert_note_modifier_combo.get_active_text();
871 for (int i = 0; modifiers[i].name; ++i) {
872 if (txt == S_(modifiers[i].name)) {
873 Keyboard::set_insert_note_modifier (modifiers[i].modifier);
879 void snap_modifier_chosen ()
881 string const txt = _snap_modifier_combo.get_active_text();
883 for (int i = 0; modifiers[i].name; ++i) {
884 if (txt == S_(modifiers[i].name)) {
885 Keyboard::set_snap_modifier (modifiers[i].modifier);
891 void snap_delta_modifier_chosen ()
893 string const txt = _snap_delta_combo.get_active_text();
895 for (int i = 0; modifiers[i].name; ++i) {
896 if (txt == S_(modifiers[i].name)) {
897 Keyboard::set_snap_delta_modifier (modifiers[i].modifier);
903 void constraint_modifier_chosen ()
905 string const txt = _constraint_modifier_combo.get_active_text();
907 for (int i = 0; modifiers[i].name; ++i) {
908 if (txt == S_(modifiers[i].name)) {
909 ArdourKeyboard::set_constraint_modifier (modifiers[i].modifier);
915 void trim_contents_modifier_chosen ()
917 string const txt = _trim_contents_combo.get_active_text();
919 for (int i = 0; modifiers[i].name; ++i) {
920 if (txt == S_(modifiers[i].name)) {
921 ArdourKeyboard::set_trim_contents_modifier (modifiers[i].modifier);
927 void trim_overlap_modifier_chosen ()
929 string const txt = _trim_overlap_combo.get_active_text();
931 for (int i = 0; modifiers[i].name; ++i) {
932 if (txt == S_(modifiers[i].name)) {
933 ArdourKeyboard::set_trim_overlap_modifier (modifiers[i].modifier);
939 void trim_anchored_modifier_chosen ()
941 string const txt = _trim_anchored_combo.get_active_text();
943 for (int i = 0; modifiers[i].name; ++i) {
944 if (txt == S_(modifiers[i].name)) {
945 ArdourKeyboard::set_trim_anchored_modifier (modifiers[i].modifier);
951 void fine_adjust_modifier_chosen ()
953 string const txt = _fine_adjust_combo.get_active_text();
955 for (int i = 0; modifiers[i].name; ++i) {
956 if (txt == S_(modifiers[i].name)) {
957 ArdourKeyboard::set_fine_adjust_modifier (modifiers[i].modifier);
963 void push_points_modifier_chosen ()
965 string const txt = _push_points_combo.get_active_text();
967 for (int i = 0; modifiers[i].name; ++i) {
968 if (txt == S_(modifiers[i].name)) {
969 ArdourKeyboard::set_push_points_modifier (modifiers[i].modifier);
975 void note_size_relative_modifier_chosen ()
977 string const txt = _note_size_relative_combo.get_active_text();
979 for (int i = 0; modifiers[i].name; ++i) {
980 if (txt == S_(modifiers[i].name)) {
981 ArdourKeyboard::set_note_size_relative_modifier (modifiers[i].modifier);
987 void delete_button_changed ()
989 Keyboard::set_delete_button (_delete_button_spin.get_value_as_int());
992 void edit_button_changed ()
994 Keyboard::set_edit_button (_edit_button_spin.get_value_as_int());
997 void insert_note_button_changed ()
999 Keyboard::set_insert_note_button (_insert_note_button_spin.get_value_as_int());
1002 ComboBoxText _keyboard_layout_selector;
1003 ComboBoxText _edit_modifier_combo;
1004 ComboBoxText _delete_modifier_combo;
1005 ComboBoxText _copy_modifier_combo;
1006 ComboBoxText _insert_note_modifier_combo;
1007 ComboBoxText _snap_modifier_combo;
1008 ComboBoxText _snap_delta_combo;
1009 ComboBoxText _constraint_modifier_combo;
1010 ComboBoxText _trim_contents_combo;
1011 ComboBoxText _trim_overlap_combo;
1012 ComboBoxText _trim_anchored_combo;
1013 ComboBoxText _trim_jump_combo;
1014 ComboBoxText _fine_adjust_combo;
1015 ComboBoxText _push_points_combo;
1016 ComboBoxText _note_size_relative_combo;
1017 Adjustment _delete_button_adjustment;
1018 SpinButton _delete_button_spin;
1019 Adjustment _edit_button_adjustment;
1020 SpinButton _edit_button_spin;
1021 Adjustment _insert_note_button_adjustment;
1022 SpinButton _insert_note_button_spin;
1026 class FontScalingOptions : public OptionEditorBox
1029 FontScalingOptions () :
1030 _dpi_adjustment (100, 50, 250, 1, 5),
1031 _dpi_slider (_dpi_adjustment)
1033 _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.);
1035 Label* l = manage (new Label (_("GUI and Font scaling:")));
1036 l->set_name ("OptionsLabel");
1038 const std::string dflt = _("Default");
1039 const std::string empty = X_(""); // despite gtk-doc saying so, NULL does not work as reference
1041 _dpi_slider.set_name("FontScaleSlider");
1042 _dpi_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1043 _dpi_slider.set_draw_value(false);
1044 _dpi_slider.add_mark(50, Gtk::POS_TOP, empty);
1045 _dpi_slider.add_mark(60, Gtk::POS_TOP, empty);
1046 _dpi_slider.add_mark(70, Gtk::POS_TOP, empty);
1047 _dpi_slider.add_mark(80, Gtk::POS_TOP, empty);
1048 _dpi_slider.add_mark(90, Gtk::POS_TOP, empty);
1049 _dpi_slider.add_mark(100, Gtk::POS_TOP, dflt);
1050 _dpi_slider.add_mark(125, Gtk::POS_TOP, empty);
1051 _dpi_slider.add_mark(150, Gtk::POS_TOP, empty);
1052 _dpi_slider.add_mark(175, Gtk::POS_TOP, empty);
1053 _dpi_slider.add_mark(200, Gtk::POS_TOP, empty);
1054 _dpi_slider.add_mark(225, Gtk::POS_TOP, empty);
1055 _dpi_slider.add_mark(250, Gtk::POS_TOP, empty);
1057 HBox* h = manage (new HBox);
1059 h->pack_start (*l, false, false);
1060 h->pack_start (_dpi_slider, true, true);
1062 _box->pack_start (*h, false, false);
1064 set_note (_("Adjusting the scale requires an application restart to re-layout."));
1066 _dpi_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &FontScalingOptions::dpi_changed));
1069 void parameter_changed (string const & p)
1071 if (p == "font-scale") {
1072 _dpi_adjustment.set_value (UIConfiguration::instance().get_font_scale() / 1024.);
1076 void set_state_from_config ()
1078 parameter_changed ("font-scale");
1085 UIConfiguration::instance().set_font_scale ((long) floor (_dpi_adjustment.get_value() * 1024.));
1086 /* XXX: should be triggered from the parameter changed signal */
1087 UIConfiguration::instance().reset_dpi ();
1090 Adjustment _dpi_adjustment;
1094 class VstTimeOutSliderOption : public OptionEditorBox
1097 VstTimeOutSliderOption (RCConfiguration* c)
1099 , _timeout_adjustment (0, 0, 3000, 50, 50)
1100 , _timeout_slider (_timeout_adjustment)
1102 _timeout_slider.set_digits (0);
1103 _timeout_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &VstTimeOutSliderOption::timeout_changed));
1105 _timeout_slider.set_draw_value(false);
1106 _timeout_slider.add_mark( 0, Gtk::POS_TOP, _("\u221e")); // infinity
1107 _timeout_slider.add_mark( 300, Gtk::POS_TOP, _("30 sec"));
1108 _timeout_slider.add_mark( 600, Gtk::POS_TOP, _("1 min"));
1109 _timeout_slider.add_mark(1200, Gtk::POS_TOP, _("2 mins"));
1110 _timeout_slider.add_mark(1800, Gtk::POS_TOP, _("3 mins"));
1111 _timeout_slider.add_mark(2400, Gtk::POS_TOP, _("4 mins"));
1112 _timeout_slider.add_mark(3000, Gtk::POS_TOP, _("5 mins"));
1114 Gtkmm2ext::UI::instance()->set_tip(_timeout_slider,
1115 _("Specify the default timeout for plugin instantiation. Plugins that require more time to load will be blacklisted. A value of 0 disables the timeout."));
1117 Label* l = manage (left_aligned_label (_("Scan Time Out:")));
1118 HBox* h = manage (new HBox);
1120 h->pack_start (*l, false, false);
1121 h->pack_start (_timeout_slider, true, true);
1123 _box->pack_start (*h, false, false);
1126 void parameter_changed (string const & p)
1128 if (p == "vst-scan-timeout") {
1129 int const x = _rc_config->get_vst_scan_timeout();
1130 _timeout_adjustment.set_value (x);
1134 void set_state_from_config ()
1136 parameter_changed ("vst-scan-timeout");
1141 void timeout_changed ()
1143 int x = floor(_timeout_adjustment.get_value());
1144 _rc_config->set_vst_scan_timeout(x);
1147 RCConfiguration* _rc_config;
1148 Adjustment _timeout_adjustment;
1149 HScale _timeout_slider;
1156 class ClipLevelOptions : public OptionEditorBox
1160 : _clip_level_adjustment (-.5, -50.0, 0.0, 0.1, 1.0) /* units of dB */
1161 , _clip_level_slider (_clip_level_adjustment)
1163 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level ());
1165 Label* l = manage (new Label (_("Waveform Clip Level (dBFS):")));
1166 l->set_name ("OptionsLabel");
1168 _clip_level_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1169 HBox* h = manage (new HBox);
1171 h->pack_start (*l, false, false);
1172 h->pack_start (_clip_level_slider, true, true);
1174 _box->pack_start (*h, false, false);
1176 _clip_level_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &ClipLevelOptions::clip_level_changed));
1179 void parameter_changed (string const & p)
1181 if (p == "waveform-clip-level") {
1182 _clip_level_adjustment.set_value (UIConfiguration::instance().get_waveform_clip_level());
1186 void set_state_from_config ()
1188 parameter_changed ("waveform-clip-level");
1193 void clip_level_changed ()
1195 UIConfiguration::instance().set_waveform_clip_level (_clip_level_adjustment.get_value());
1196 /* XXX: should be triggered from the parameter changed signal */
1197 ArdourCanvas::WaveView::set_clip_level (_clip_level_adjustment.get_value());
1200 Adjustment _clip_level_adjustment;
1201 HScale _clip_level_slider;
1204 class BufferingOptions : public OptionEditorBox
1207 BufferingOptions (RCConfiguration* c)
1209 , _playback_adjustment (5, 1, 60, 1, 4)
1210 , _capture_adjustment (5, 1, 60, 1, 4)
1211 , _playback_slider (_playback_adjustment)
1212 , _capture_slider (_capture_adjustment)
1214 vector<string> presets;
1216 /* these must match the order of the enums for BufferingPreset */
1218 presets.push_back (_("Small sessions (4-16 tracks)"));
1219 presets.push_back (_("Medium sessions (16-64 tracks)"));
1220 presets.push_back (_("Large sessions (64+ tracks)"));
1221 presets.push_back (_("Custom (set by sliders below)"));
1223 set_popdown_strings (_buffering_presets_combo, presets);
1225 Label* l = manage (new Label (_("Preset:")));
1226 l->set_name ("OptionsLabel");
1227 HBox* h = manage (new HBox);
1228 h->set_spacing (12);
1229 h->pack_start (*l, false, false);
1230 h->pack_start (_buffering_presets_combo, true, true);
1231 _box->pack_start (*h, false, false);
1233 _buffering_presets_combo.signal_changed().connect (sigc::mem_fun (*this, &BufferingOptions::preset_changed));
1235 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1237 l = manage (new Label (_("Playback (seconds of buffering):")));
1238 l->set_name ("OptionsLabel");
1240 _playback_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1241 h = manage (new HBox);
1243 h->pack_start (*l, false, false);
1244 h->pack_start (_playback_slider, true, true);
1246 _box->pack_start (*h, false, false);
1248 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1250 l = manage (new Label (_("Recording (seconds of buffering):")));
1251 l->set_name ("OptionsLabel");
1253 _capture_slider.set_update_policy (UPDATE_DISCONTINUOUS);
1254 h = manage (new HBox);
1256 h->pack_start (*l, false, false);
1257 h->pack_start (_capture_slider, true, true);
1259 _box->pack_start (*h, false, false);
1261 _capture_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::capture_changed));
1262 _playback_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &BufferingOptions::playback_changed));
1265 void parameter_changed (string const & p)
1267 if (p == "buffering-preset") {
1268 switch (_rc_config->get_buffering_preset()) {
1270 _playback_slider.set_sensitive (false);
1271 _capture_slider.set_sensitive (false);
1272 _buffering_presets_combo.set_active (0);
1275 _playback_slider.set_sensitive (false);
1276 _capture_slider.set_sensitive (false);
1277 _buffering_presets_combo.set_active (1);
1280 _playback_slider.set_sensitive (false);
1281 _capture_slider.set_sensitive (false);
1282 _buffering_presets_combo.set_active (2);
1285 _playback_slider.set_sensitive (true);
1286 _capture_slider.set_sensitive (true);
1287 _buffering_presets_combo.set_active (3);
1292 if (p == "playback-buffer-seconds") {
1293 _playback_adjustment.set_value (_rc_config->get_audio_playback_buffer_seconds());
1294 } else if (p == "capture-buffer-seconds") {
1295 _capture_adjustment.set_value (_rc_config->get_audio_capture_buffer_seconds());
1299 void set_state_from_config ()
1301 parameter_changed ("buffering-preset");
1302 parameter_changed ("playback-buffer-seconds");
1303 parameter_changed ("capture-buffer-seconds");
1308 void preset_changed ()
1310 int index = _buffering_presets_combo.get_active_row_number ();
1316 _rc_config->set_buffering_preset (Small);
1319 _rc_config->set_buffering_preset (Medium);
1322 _rc_config->set_buffering_preset (Large);
1325 _rc_config->set_buffering_preset (Custom);
1328 error << string_compose (_("programming error: unknown buffering preset string, index = %1"), index) << endmsg;
1333 void playback_changed ()
1335 _rc_config->set_audio_playback_buffer_seconds ((long) _playback_adjustment.get_value());
1338 void capture_changed ()
1340 _rc_config->set_audio_capture_buffer_seconds ((long) _capture_adjustment.get_value());
1343 RCConfiguration* _rc_config;
1344 Adjustment _playback_adjustment;
1345 Adjustment _capture_adjustment;
1346 HScale _playback_slider;
1347 HScale _capture_slider;
1348 ComboBoxText _buffering_presets_combo;
1351 class ControlSurfacesOptions : public OptionEditorBox
1354 ControlSurfacesOptions ()
1355 : _ignore_view_change (0)
1357 _store = ListStore::create (_model);
1358 _view.set_model (_store);
1359 _view.append_column (_("Control Surface Protocol"), _model.name);
1360 _view.get_column(0)->set_resizable (true);
1361 _view.get_column(0)->set_expand (true);
1362 _view.append_column_editable (_("Enabled"), _model.enabled);
1363 _view.append_column_editable (_("Feedback"), _model.feedback);
1365 _box->pack_start (_view, false, false);
1367 Gtk::HBox* edit_box = manage (new Gtk::HBox);
1368 edit_box->set_spacing(3);
1369 _box->pack_start (*edit_box, false, false);
1372 Label* label = manage (new Label);
1373 label->set_text (_("Click to edit the settings for selected protocol ( it must be ENABLED first ):"));
1374 edit_box->pack_start (*label, false, false);
1377 edit_button = manage (new Button(_("Show Protocol Settings")));
1378 edit_button->signal_clicked().connect (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_btn_clicked));
1379 edit_box->pack_start (*edit_button, true, true);
1380 edit_button->set_sensitive (false);
1381 edit_button->show ();
1383 ControlProtocolManager& m = ControlProtocolManager::instance ();
1384 m.ProtocolStatusChange.connect (protocol_status_connection, MISSING_INVALIDATOR,
1385 boost::bind (&ControlSurfacesOptions::protocol_status_changed, this, _1), gui_context());
1387 _store->signal_row_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::view_changed));
1388 _view.signal_button_press_event().connect_notify (sigc::mem_fun(*this, &ControlSurfacesOptions::edit_clicked));
1389 _view.get_selection()->signal_changed().connect (sigc::mem_fun (*this, &ControlSurfacesOptions::selection_changed));
1392 void parameter_changed (std::string const &)
1397 void set_state_from_config ()
1401 ControlProtocolManager& m = ControlProtocolManager::instance ();
1402 for (list<ControlProtocolInfo*>::iterator i = m.control_protocol_info.begin(); i != m.control_protocol_info.end(); ++i) {
1404 if (!(*i)->mandatory) {
1405 TreeModel::Row r = *_store->append ();
1406 r[_model.name] = (*i)->name;
1407 r[_model.enabled] = ((*i)->protocol || (*i)->requested);
1408 r[_model.feedback] = ((*i)->protocol && (*i)->protocol->get_feedback ());
1409 r[_model.protocol_info] = *i;
1416 void protocol_status_changed (ControlProtocolInfo* cpi) {
1418 TreeModel::Children rows = _store->children();
1420 for (TreeModel::Children::iterator x = rows.begin(); x != rows.end(); ++x) {
1421 string n = ((*x)[_model.name]);
1423 if ((*x)[_model.protocol_info] == cpi) {
1424 _ignore_view_change++;
1425 (*x)[_model.enabled] = (cpi->protocol || cpi->requested);
1426 _ignore_view_change--;
1432 void selection_changed ()
1434 //enable the Edit button when a row is selected for editing
1435 TreeModel::Row row = *(_view.get_selection()->get_selected());
1436 if (row && row[_model.enabled])
1437 edit_button->set_sensitive (true);
1439 edit_button->set_sensitive (false);
1442 void view_changed (TreeModel::Path const &, TreeModel::iterator const & i)
1444 TreeModel::Row r = *i;
1446 if (_ignore_view_change) {
1450 ControlProtocolInfo* cpi = r[_model.protocol_info];
1455 bool const was_enabled = (cpi->protocol != 0);
1456 bool const is_enabled = r[_model.enabled];
1459 if (was_enabled != is_enabled) {
1462 ControlProtocolManager::instance().activate (*cpi);
1464 ControlProtocolManager::instance().deactivate (*cpi);
1468 bool const was_feedback = (cpi->protocol && cpi->protocol->get_feedback ());
1469 bool const is_feedback = r[_model.feedback];
1471 if (was_feedback != is_feedback && cpi->protocol) {
1472 cpi->protocol->set_feedback (is_feedback);
1476 void edit_btn_clicked ()
1479 ControlProtocolInfo* cpi;
1482 row = *(_view.get_selection()->get_selected());
1483 if (!row[_model.enabled]) {
1486 cpi = row[_model.protocol_info];
1487 if (!cpi || !cpi->protocol || !cpi->protocol->has_editor ()) {
1490 Box* box = (Box*) cpi->protocol->get_gui ();
1494 if (box->get_parent()) {
1495 static_cast<ArdourWindow*>(box->get_parent())->present();
1498 WindowTitle title (Glib::get_application_name());
1499 title += row[_model.name];
1500 title += _("Configuration");
1501 /* once created, the window is managed by the surface itself (as ->get_parent())
1502 * Surface's tear_down_gui() is called on session close, when de-activating
1503 * or re-initializing a surface.
1504 * tear_down_gui() hides an deletes the Window if it exists.
1506 ArdourWindow* win = new ArdourWindow (*((Gtk::Window*) _view.get_toplevel()), title.get_string());
1507 win->set_title ("Control Protocol Options");
1513 void edit_clicked (GdkEventButton* ev)
1515 if (ev->type != GDK_2BUTTON_PRESS) {
1522 class ControlSurfacesModelColumns : public TreeModelColumnRecord
1526 ControlSurfacesModelColumns ()
1531 add (protocol_info);
1534 TreeModelColumn<string> name;
1535 TreeModelColumn<bool> enabled;
1536 TreeModelColumn<bool> feedback;
1537 TreeModelColumn<ControlProtocolInfo*> protocol_info;
1540 Glib::RefPtr<ListStore> _store;
1541 ControlSurfacesModelColumns _model;
1543 PBD::ScopedConnection protocol_status_connection;
1544 uint32_t _ignore_view_change;
1545 Gtk::Button* edit_button;
1548 class VideoTimelineOptions : public OptionEditorBox
1551 VideoTimelineOptions (RCConfiguration* c)
1553 , _show_video_export_info_button (_("Show Video Export Info before export"))
1554 , _show_video_server_dialog_button (_("Show Video Server Startup Dialog"))
1555 , _video_advanced_setup_button (_("Advanced Setup (remote video server)"))
1556 , _xjadeo_browse_button (_("Browse..."))
1558 Table* t = manage (new Table (8, 4));
1559 t->set_spacings (4);
1561 std::stringstream s;
1562 s << "<b>" << _("Video Server") << "</b>";
1563 Label* l = manage (new Label (s.str()));
1564 l->set_use_markup (true);
1565 l->set_alignment (0, 0.5);
1566 t->attach (*l, 0, 4, 0, 1, EXPAND | FILL, FILL | EXPAND, 0, 8);
1568 t->attach (_video_advanced_setup_button, 1, 4, 1, 2);
1569 _video_advanced_setup_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::video_advanced_setup_toggled));
1570 Gtkmm2ext::UI::instance()->set_tip (_video_advanced_setup_button,
1571 _("<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."));
1573 l = manage (new Label (_("Video Server URL:")));
1574 l->set_alignment (0, 0.5);
1575 t->attach (*l, 1, 2, 2, 3, FILL);
1576 t->attach (_video_server_url_entry, 2, 4, 2, 3, FILL);
1577 Gtkmm2ext::UI::instance()->set_tip (_video_server_url_entry,
1578 _("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"));
1580 l = manage (new Label (_("Video Folder:")));
1581 l->set_alignment (0, 0.5);
1582 t->attach (*l, 1, 2, 3, 4, FILL);
1583 t->attach (_video_server_docroot_entry, 2, 4, 3, 4);
1584 Gtkmm2ext::UI::instance()->set_tip (_video_server_docroot_entry,
1585 _("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."));
1587 t->attach (_show_video_export_info_button, 1, 4, 4, 5);
1588 _show_video_export_info_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_export_info_toggled));
1589 Gtkmm2ext::UI::instance()->set_tip (_show_video_export_info_button,
1590 _("<b>When enabled</b> an information window with details is displayed before the video-export dialog."));
1592 t->attach (_show_video_server_dialog_button, 1, 4, 5, 6);
1593 _show_video_server_dialog_button.signal_toggled().connect (sigc::mem_fun (*this, &VideoTimelineOptions::show_video_server_dialog_toggled));
1594 Gtkmm2ext::UI::instance()->set_tip (_show_video_server_dialog_button,
1595 _("<b>When enabled</b> the video server is never launched automatically without confirmation"));
1597 s.str (std::string ());
1598 s << "<b>" << _("Video Monitor") << "</b>";
1599 l = manage (new Label (s.str()));
1600 l->set_use_markup (true);
1601 l->set_alignment (0, 0.5);
1602 t->attach (*l, 0, 4, 6, 7, EXPAND | FILL, FILL | EXPAND, 0, 8);
1604 l = manage (new Label (string_compose (_("Custom Path to Video Monitor (%1) - leave empty for default:"),
1607 #elif defined PLATFORM_WINDOWS
1613 l->set_alignment (0, 0.5);
1614 t->attach (*l, 1, 4, 7, 8, FILL);
1615 t->attach (_custom_xjadeo_path, 2, 3, 8, 9);
1616 Gtkmm2ext::UI::instance()->set_tip (_custom_xjadeo_path, _("Set a custom path to the Video Monitor Executable, changing this requires a restart."));
1617 t->attach (_xjadeo_browse_button, 3, 4, 8, 9, FILL);
1619 _video_server_url_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1620 _video_server_url_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_url_changed));
1621 _video_server_docroot_entry.signal_changed().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1622 _video_server_docroot_entry.signal_activate().connect (sigc::mem_fun(*this, &VideoTimelineOptions::server_docroot_changed));
1623 _custom_xjadeo_path.signal_changed().connect (sigc::mem_fun (*this, &VideoTimelineOptions::custom_xjadeo_path_changed));
1624 _xjadeo_browse_button.signal_clicked ().connect (sigc::mem_fun (*this, &VideoTimelineOptions::xjadeo_browse_clicked));
1626 // xjadeo-path is a UIConfig parameter
1627 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &VideoTimelineOptions::parameter_changed));
1629 _box->pack_start (*t,true,true);
1632 void server_url_changed ()
1634 _rc_config->set_video_server_url (_video_server_url_entry.get_text());
1637 void server_docroot_changed ()
1639 _rc_config->set_video_server_docroot (_video_server_docroot_entry.get_text());
1642 void show_video_export_info_toggled ()
1644 bool const x = _show_video_export_info_button.get_active ();
1645 _rc_config->set_show_video_export_info (x);
1648 void show_video_server_dialog_toggled ()
1650 bool const x = _show_video_server_dialog_button.get_active ();
1651 _rc_config->set_show_video_server_dialog (x);
1654 void video_advanced_setup_toggled ()
1656 bool const x = _video_advanced_setup_button.get_active ();
1657 _rc_config->set_video_advanced_setup(x);
1660 void custom_xjadeo_path_changed ()
1662 UIConfiguration::instance().set_xjadeo_binary (_custom_xjadeo_path.get_text());
1665 void xjadeo_browse_clicked ()
1667 Gtk::FileChooserDialog dialog(_("Set Video Monitor Executable"), Gtk::FILE_CHOOSER_ACTION_OPEN);
1668 dialog.set_filename (UIConfiguration::instance().get_xjadeo_binary());
1669 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
1670 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
1671 if (dialog.run () == Gtk::RESPONSE_OK) {
1672 const std::string& filename = dialog.get_filename();
1673 if (!filename.empty() && (
1675 Glib::file_test (filename + "/Contents/MacOS/xjadeo", Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE) ||
1677 Glib::file_test (filename, Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)
1679 UIConfiguration::instance().set_xjadeo_binary (filename);
1684 void parameter_changed (string const & p)
1686 if (p == "video-server-url") {
1687 _video_server_url_entry.set_text (_rc_config->get_video_server_url());
1688 } else if (p == "video-server-docroot") {
1689 _video_server_docroot_entry.set_text (_rc_config->get_video_server_docroot());
1690 } else if (p == "show-video-export-info") {
1691 bool const x = _rc_config->get_show_video_export_info();
1692 _show_video_export_info_button.set_active (x);
1693 } else if (p == "show-video-server-dialog") {
1694 bool const x = _rc_config->get_show_video_server_dialog();
1695 _show_video_server_dialog_button.set_active (x);
1696 } else if (p == "video-advanced-setup") {
1697 bool const x = _rc_config->get_video_advanced_setup();
1698 _video_advanced_setup_button.set_active(x);
1699 _video_server_docroot_entry.set_sensitive(x);
1700 _video_server_url_entry.set_sensitive(x);
1701 } else if (p == "xjadeo-binary") {
1702 _custom_xjadeo_path.set_text (UIConfiguration::instance().get_xjadeo_binary());
1706 void set_state_from_config ()
1708 parameter_changed ("video-server-url");
1709 parameter_changed ("video-server-docroot");
1710 parameter_changed ("video-monitor-setup-dialog");
1711 parameter_changed ("show-video-export-info");
1712 parameter_changed ("show-video-server-dialog");
1713 parameter_changed ("video-advanced-setup");
1714 parameter_changed ("xjadeo-binary");
1718 RCConfiguration* _rc_config;
1719 Entry _video_server_url_entry;
1720 Entry _video_server_docroot_entry;
1721 Entry _custom_xjadeo_path;
1722 CheckButton _show_video_export_info_button;
1723 CheckButton _show_video_server_dialog_button;
1724 CheckButton _video_advanced_setup_button;
1725 Button _xjadeo_browse_button;
1728 class ColumVisibilityOption : public Option
1731 ColumVisibilityOption (string id, string name, uint32_t n_col, sigc::slot<uint32_t> get, sigc::slot<bool, uint32_t> set)
1738 cb = (CheckButton**) malloc (sizeof (CheckButton*) * n_col);
1739 for (uint32_t i = 0; i < n_col; ++i) {
1740 CheckButton* col = manage (new CheckButton (string_compose (_("Column %1"), i + 1)));
1741 col->signal_toggled().connect (sigc::bind (sigc::mem_fun (*this, &ColumVisibilityOption::column_toggled), i));
1742 _hbox.pack_start (*col);
1745 parameter_changed (id);
1748 ~ColumVisibilityOption () {
1752 Gtk::Widget& tip_widget() { return _hbox; }
1754 void set_state_from_config ()
1756 uint32_t c = _get();
1757 for (uint32_t i = 0; i < _n_col; ++i) {
1758 bool en = (c & (1<<i)) ? true : false;
1759 if (cb[i]->get_active () != en) {
1760 cb[i]->set_active (en);
1765 void add_to_page (OptionEditorPage* p)
1767 _heading.add_to_page (p);
1768 add_widget_to_page (p, &_hbox);
1772 void column_toggled (int b) {
1773 uint32_t c = _get();
1775 if (cb[b]->get_active ()) {
1786 OptionEditorHeading _heading;
1790 sigc::slot<uint32_t> _get;
1791 sigc::slot<bool, uint32_t> _set;
1795 /** A class which allows control of visibility of some editor components usign
1796 * a VisibilityGroup. The caller should pass in a `dummy' VisibilityGroup
1797 * which has the correct members, but with null widget pointers. This
1798 * class allows the user to set visibility of the members, the details
1799 * of which are stored in a configuration variable which can be watched
1800 * by parts of the editor that actually contain the widgets whose visibility
1801 * is being controlled.
1804 class VisibilityOption : public Option
1807 /** @param name User-visible name for this group.
1808 * @param g `Dummy' VisibilityGroup (as described above).
1809 * @param get Method to get the value of the appropriate configuration variable.
1810 * @param set Method to set the value of the appropriate configuration variable.
1812 VisibilityOption (string name, VisibilityGroup* g, sigc::slot<string> get, sigc::slot<bool, string> set)
1813 : Option (g->get_state_name(), name)
1815 , _visibility_group (g)
1819 /* Watch for changes made by the user to our members */
1820 _visibility_group->VisibilityChanged.connect_same_thread (
1821 _visibility_group_connection, sigc::bind (&VisibilityOption::changed, this)
1825 void set_state_from_config ()
1827 /* Set our state from the current configuration */
1828 _visibility_group->set_state (_get ());
1831 void add_to_page (OptionEditorPage* p)
1833 _heading.add_to_page (p);
1834 add_widget_to_page (p, _visibility_group->list_view ());
1837 Gtk::Widget& tip_widget() { return *_visibility_group->list_view (); }
1842 /* The user has changed something, so reflect this change
1843 in the RCConfiguration.
1845 _set (_visibility_group->get_state_value ());
1848 OptionEditorHeading _heading;
1849 VisibilityGroup* _visibility_group;
1850 sigc::slot<std::string> _get;
1851 sigc::slot<bool, std::string> _set;
1852 PBD::ScopedConnection _visibility_group_connection;
1857 RCOptionEditor::RCOptionEditor ()
1858 : OptionEditorContainer (Config, string_compose (_("%1 Preferences"), PROGRAM_NAME))
1859 , Tabbable (*this, _("Preferences")) /* pack self-as-vbox into tabbable */
1860 , _rc_config (Config)
1861 , _mixer_strip_visibility ("mixer-element-visibility")
1863 UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &RCOptionEditor::parameter_changed));
1867 uint32_t hwcpus = hardware_concurrency ();
1869 BoolComboOption* bco;
1872 add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
1874 ComboOption<int32_t>* procs = new ComboOption<int32_t> (
1876 _("Signal processing uses"),
1877 sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
1878 sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
1881 procs->add (-1, _("all but one processor"));
1882 procs->add (0, _("all available processors"));
1884 for (uint32_t i = 1; i <= hwcpus; ++i) {
1885 procs->add (i, string_compose (P_("%1 processor", "%1 processors", i), i));
1888 procs->set_note (string_compose (_("This setting will only take effect when %1 is restarted."), PROGRAM_NAME));
1890 add_option (_("Misc"), procs);
1893 add_option (_("Misc"), new OptionEditorHeading (S_("Options|Undo")));
1895 add_option (_("Misc"), new UndoOptions (_rc_config));
1897 add_option (_("Misc"),
1899 "verify-remove-last-capture",
1900 _("Verify removal of last capture"),
1901 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verify_remove_last_capture),
1902 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verify_remove_last_capture)
1905 add_option (_("Misc"), new OptionEditorHeading (_("Session Management")));
1907 add_option (_("Misc"),
1909 "periodic-safety-backups",
1910 _("Make periodic backups of the session file"),
1911 sigc::mem_fun (*_rc_config, &RCConfiguration::get_periodic_safety_backups),
1912 sigc::mem_fun (*_rc_config, &RCConfiguration::set_periodic_safety_backups)
1915 add_option (_("Misc"),
1917 "only-copy-imported-files",
1918 _("Always copy imported files"),
1919 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_only_copy_imported_files),
1920 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_only_copy_imported_files)
1923 add_option (_("Misc"), new DirectoryOption (
1924 X_("default-session-parent-dir"),
1925 _("Default folder for new sessions:"),
1926 sigc::mem_fun (*_rc_config, &RCConfiguration::get_default_session_parent_dir),
1927 sigc::mem_fun (*_rc_config, &RCConfiguration::set_default_session_parent_dir)
1930 add_option (_("Misc"),
1931 new SpinOption<uint32_t> (
1932 "max-recent-sessions",
1933 _("Maximum number of recent sessions"),
1934 sigc::mem_fun (*_rc_config, &RCConfiguration::get_max_recent_sessions),
1935 sigc::mem_fun (*_rc_config, &RCConfiguration::set_max_recent_sessions),
1939 add_option (_("Misc/Click"), new OptionEditorHeading (_("Click")));
1941 add_option (_("Misc/Click"), new ClickOptions (_rc_config));
1943 add_option (_("Misc/Click"),
1946 _("Click gain level"),
1947 sigc::mem_fun (*_rc_config, &RCConfiguration::get_click_gain),
1948 sigc::mem_fun (*_rc_config, &RCConfiguration::set_click_gain)
1951 add_option (_("Misc"), new OptionEditorHeading (_("Automation")));
1953 add_option (_("Misc"),
1954 new SpinOption<double> (
1955 "automation-thinning-factor",
1956 _("Thinning factor (larger value => less data)"),
1957 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_thinning_factor),
1958 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_thinning_factor),
1962 add_option (_("Misc"),
1963 new SpinOption<double> (
1964 "automation-interval-msecs",
1965 _("Automation sampling interval (milliseconds)"),
1966 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_interval_msecs),
1967 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_interval_msecs),
1973 add_option (_("Transport"), new OptionEditorHeading (S_("Transport Options")));
1977 tsf = new BoolOption (
1978 "latched-record-enable",
1979 _("Keep record-enable engaged on stop"),
1980 sigc::mem_fun (*_rc_config, &RCConfiguration::get_latched_record_enable),
1981 sigc::mem_fun (*_rc_config, &RCConfiguration::set_latched_record_enable)
1983 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
1984 add_option (_("Transport"), tsf);
1986 tsf = new BoolOption (
1988 _("Play loop is a transport mode"),
1989 sigc::mem_fun (*_rc_config, &RCConfiguration::get_loop_is_mode),
1990 sigc::mem_fun (*_rc_config, &RCConfiguration::set_loop_is_mode)
1992 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
1993 (_("<b>When enabled</b> the loop button does not start playback but forces playback to always play the loop\n\n"
1994 "<b>When disabled</b> the loop button starts playing the loop, but stop then cancels loop playback")));
1995 add_option (_("Transport"), tsf);
1997 tsf = new BoolOption (
1998 "stop-recording-on-xrun",
1999 _("Stop recording when an xrun occurs"),
2000 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_recording_on_xrun),
2001 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_recording_on_xrun)
2003 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2004 string_compose (_("<b>When enabled</b> %1 will stop recording if an over- or underrun is detected by the audio engine"),
2006 add_option (_("Transport"), tsf);
2008 tsf = new BoolOption (
2009 "create-xrun-marker",
2010 _("Create markers where xruns occur"),
2011 sigc::mem_fun (*_rc_config, &RCConfiguration::get_create_xrun_marker),
2012 sigc::mem_fun (*_rc_config, &RCConfiguration::set_create_xrun_marker)
2014 // Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _(""));
2015 add_option (_("Transport"), tsf);
2017 tsf = new BoolOption (
2018 "stop-at-session-end",
2019 _("Stop at the end of the session"),
2020 sigc::mem_fun (*_rc_config, &RCConfiguration::get_stop_at_session_end),
2021 sigc::mem_fun (*_rc_config, &RCConfiguration::set_stop_at_session_end)
2023 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2024 string_compose (_("<b>When enabled</b> if %1 is <b>not recording</b>, it will stop the transport "
2025 "when it reaches the current session end marker\n\n"
2026 "<b>When disabled</b> %1 will continue to roll past the session end marker at all times"),
2028 add_option (_("Transport"), tsf);
2030 tsf = new BoolOption (
2032 _("Do seamless looping (not possible when slaved to MTC, LTC etc)"),
2033 sigc::mem_fun (*_rc_config, &RCConfiguration::get_seamless_loop),
2034 sigc::mem_fun (*_rc_config, &RCConfiguration::set_seamless_loop)
2036 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(),
2037 string_compose (_("<b>When enabled</b> this will loop by reading ahead and wrapping around at the loop point, "
2038 "preventing any need to do a transport locate at the end of the loop\n\n"
2039 "<b>When disabled</b> looping is done by locating back to the start of the loop when %1 reaches the end "
2040 "which will often cause a small click or delay"), PROGRAM_NAME));
2041 add_option (_("Transport"), tsf);
2043 tsf = new BoolOption (
2044 "disable-disarm-during-roll",
2045 _("Disable per-track record disarm while rolling"),
2046 sigc::mem_fun (*_rc_config, &RCConfiguration::get_disable_disarm_during_roll),
2047 sigc::mem_fun (*_rc_config, &RCConfiguration::set_disable_disarm_during_roll)
2049 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"));
2050 add_option (_("Transport"), tsf);
2052 tsf = new BoolOption (
2054 _("12dB gain reduction during fast-forward and fast-rewind"),
2055 sigc::mem_fun (*_rc_config, &RCConfiguration::get_quieten_at_speed),
2056 sigc::mem_fun (*_rc_config, &RCConfiguration::set_quieten_at_speed)
2058 Gtkmm2ext::UI::instance()->set_tip (tsf->tip_widget(), _("This will reduce the unpleasant increase in perceived volume "
2059 "that occurs when fast-forwarding or rewinding through some kinds of audio"));
2060 add_option (_("Transport"), tsf);
2062 ComboOption<float>* psc = new ComboOption<float> (
2065 sigc::mem_fun (*_rc_config, &RCConfiguration::get_preroll_seconds),
2066 sigc::mem_fun (*_rc_config, &RCConfiguration::set_preroll_seconds)
2068 Gtkmm2ext::UI::instance()->set_tip (psc->tip_widget(),
2069 (_("The amount of preroll (in seconds) to apply when <b>Play with Preroll</b> is initiated.\n\n"
2070 "If <b>Follow Edits</b> is enabled, the preroll is applied to the playhead position when a region is selected or trimmed.")));
2071 psc->add (0.0, _("0 (no pre-roll)"));
2072 psc->add (0.1, _("0.1 second"));
2073 psc->add (0.25, _("0.25 second"));
2074 psc->add (0.5, _("0.5 second"));
2075 psc->add (1.0, _("1.0 second"));
2076 psc->add (2.0, _("2.0 seconds"));
2077 add_option (_("Transport"), psc);
2079 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("Synchronization and Slave Options")));
2081 _sync_source = new ComboOption<SyncSource> (
2083 _("External timecode source"),
2084 sigc::mem_fun (*_rc_config, &RCConfiguration::get_sync_source),
2085 sigc::mem_fun (*_rc_config, &RCConfiguration::set_sync_source)
2088 add_option (_("Transport/Sync"), _sync_source);
2090 _sync_framerate = new BoolOption (
2091 "timecode-sync-frame-rate",
2092 _("Match session video frame rate to external timecode"),
2093 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_sync_frame_rate),
2094 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_sync_frame_rate)
2096 Gtkmm2ext::UI::instance()->set_tip
2097 (_sync_framerate->tip_widget(),
2098 string_compose (_("This option controls the value of the video frame rate <i>while chasing</i> an external timecode source.\n\n"
2099 "<b>When enabled</b> the session video frame rate will be changed to match that of the selected external timecode source.\n\n"
2100 "<b>When disabled</b> the session video frame rate will not be changed to match that of the selected external timecode source."
2101 "Instead the frame rate indication in the main clock will flash red and %1 will convert between the external "
2102 "timecode standard and the session standard."), PROGRAM_NAME));
2104 add_option (_("Transport/Sync"), _sync_framerate);
2106 _sync_genlock = new BoolOption (
2107 "timecode-source-is-synced",
2108 _("Sync-lock timecode to clock (disable drift compensation)"),
2109 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_is_synced),
2110 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_is_synced)
2112 Gtkmm2ext::UI::instance()->set_tip
2113 (_sync_genlock->tip_widget(),
2114 string_compose (_("<b>When enabled</b> %1 will never varispeed when slaved to external timecode. "
2115 "Sync Lock indicates that the selected external timecode source shares clock-sync "
2116 "(Black & Burst, Wordclock, etc) with the audio interface. "
2117 "This option disables drift compensation. The transport speed is fixed at 1.0. "
2118 "Vari-speed LTC will be ignored and cause drift."
2120 "<b>When disabled</b> %1 will compensate for potential drift, regardless if the "
2121 "timecode sources shares clock sync."
2125 add_option (_("Transport/Sync"), _sync_genlock);
2127 _sync_source_2997 = new BoolOption (
2128 "timecode-source-2997",
2129 _("Lock to 29.9700 fps instead of 30000/1001"),
2130 sigc::mem_fun (*_rc_config, &RCConfiguration::get_timecode_source_2997),
2131 sigc::mem_fun (*_rc_config, &RCConfiguration::set_timecode_source_2997)
2133 Gtkmm2ext::UI::instance()->set_tip
2134 (_sync_source_2997->tip_widget(),
2135 _("<b>When enabled</b> the external timecode source is assumed to use 29.97 fps instead of 30000/1001.\n"
2136 "SMPTE 12M-1999 specifies 29.97df as 30000/1001. The spec further mentions that "
2137 "drop-frame timecode has an accumulated error of -86ms over a 24-hour period.\n"
2138 "Drop-frame timecode would compensate exactly for a NTSC color frame rate of 30 * 0.9990 (ie 29.970000). "
2139 "That is not the actual rate. However, some vendors use that rate - despite it being against the specs - "
2140 "because the variant of using exactly 29.97 fps has zero timecode drift.\n"
2143 add_option (_("Transport/Sync"), _sync_source_2997);
2145 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("LTC Reader")));
2147 _ltc_port = new ComboStringOption (
2149 _("LTC incoming port"),
2150 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_source_port),
2151 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_source_port)
2154 vector<string> physical_inputs;
2155 physical_inputs.push_back (_("None"));
2156 AudioEngine::instance()->get_physical_inputs (DataType::AUDIO, physical_inputs);
2157 _ltc_port->set_popdown_strings (physical_inputs);
2159 populate_sync_options ();
2160 AudioEngine::instance()->Running.connect (engine_started_connection, MISSING_INVALIDATOR, boost::bind (&RCOptionEditor::populate_sync_options, this), gui_context());
2162 add_option (_("Transport/Sync"), _ltc_port);
2164 // TODO; rather disable this button than not compile it..
2165 add_option (_("Transport/Sync"), new OptionEditorHeading (S_("LTC Generator")));
2167 add_option (_("Transport/Sync"),
2170 _("Enable LTC generator"),
2171 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_ltc),
2172 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_ltc)
2175 _ltc_send_continuously = new BoolOption (
2176 "ltc-send-continuously",
2177 _("Send LTC while stopped"),
2178 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ltc_send_continuously),
2179 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ltc_send_continuously)
2181 Gtkmm2ext::UI::instance()->set_tip
2182 (_ltc_send_continuously->tip_widget(),
2183 string_compose (_("<b>When enabled</b> %1 will continue to send LTC information even when the transport (playhead) is not moving"), PROGRAM_NAME));
2184 add_option (_("Transport"), _ltc_send_continuously);
2186 _ltc_volume_adjustment = new Gtk::Adjustment(-18, -50, 0, .5, 5);
2187 _ltc_volume_adjustment->set_value (20 * log10(_rc_config->get_ltc_output_volume()));
2188 _ltc_volume_adjustment->signal_value_changed().connect (sigc::mem_fun (*this, &RCOptionEditor::ltc_generator_volume_changed));
2189 _ltc_volume_slider = new HSliderOption("ltcvol", _("LTC generator level"), *_ltc_volume_adjustment);
2191 Gtkmm2ext::UI::instance()->set_tip
2192 (_ltc_volume_slider->tip_widget(),
2193 _("Specify the Peak Volume of the generated LTC signal in dBFS. A good value is 0dBu ^= -18dBFS in an EBU calibrated system"));
2195 add_option (_("Transport/Sync"), _ltc_volume_slider);
2199 add_option (_("Editor"),
2201 "rubberbanding-snaps-to-grid",
2202 _("Make rubberband selection rectangle snap to the grid"),
2203 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_rubberbanding_snaps_to_grid),
2204 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_rubberbanding_snaps_to_grid)
2207 bo = new BoolOption (
2209 _("Name new markers"),
2210 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_name_new_markers),
2211 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_name_new_markers)
2213 add_option (_("Editor"), bo);
2214 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."
2215 "\n\nYou can always rename markers by right-clicking on them"));
2217 add_option (S_("Editor"),
2219 "draggable-playhead",
2220 _("Allow dragging of playhead"),
2221 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_draggable_playhead),
2222 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_draggable_playhead)
2225 add_option (_("Editor"),
2227 "show-editor-meter",
2228 _("Display master-meter in the toolbar"),
2229 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_editor_meter),
2230 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_editor_meter)
2233 if (!Profile->get_mixbus()) {
2234 add_option (_("Editor"),
2237 _("Show zoom toolbar (if torn off)"),
2238 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_zoom_tools),
2239 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_zoom_tools)
2242 add_option (_("Editor"),
2244 "use-mouse-position-as-zoom-focus-on-scroll",
2245 _("Always use mouse cursor position as zoom focus when zooming using mouse scroll wheel"),
2246 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_mouse_position_as_zoom_focus_on_scroll),
2247 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_mouse_position_as_zoom_focus_on_scroll)
2251 add_option (_("Editor"),
2253 "update-editor-during-summary-drag",
2254 _("Update editor window during drags of the summary"),
2255 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_update_editor_during_summary_drag),
2256 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_update_editor_during_summary_drag)
2259 add_option (_("Editor"),
2261 "autoscroll-editor",
2262 _("Auto-scroll editor window when dragging near its edges"),
2263 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_autoscroll_editor),
2264 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_autoscroll_editor)
2267 add_option (_("Editor"),
2268 new BoolComboOption (
2269 "show-region-gain-envelopes",
2270 _("Show gain envelopes in audio regions"),
2272 _("only in Draw and Internal Edit modes"),
2273 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_region_gain),
2274 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_region_gain)
2277 add_option (_("Editor"), new OptionEditorHeading (_("Editor Behavior")));
2279 add_option (_("Editor"),
2281 "automation-follows-regions",
2282 _("Move relevant automation when audio regions are moved"),
2283 sigc::mem_fun (*_rc_config, &RCConfiguration::get_automation_follows_regions),
2284 sigc::mem_fun (*_rc_config, &RCConfiguration::set_automation_follows_regions)
2287 ComboOption<FadeShape>* fadeshape = new ComboOption<FadeShape> (
2288 "default-fade-shape",
2289 _("Default fade shape"),
2290 sigc::mem_fun (*_rc_config,
2291 &RCConfiguration::get_default_fade_shape),
2292 sigc::mem_fun (*_rc_config,
2293 &RCConfiguration::set_default_fade_shape)
2296 fadeshape->add (FadeLinear,
2297 _("Linear (for highly correlated material)"));
2298 fadeshape->add (FadeConstantPower, _("Constant power"));
2299 fadeshape->add (FadeSymmetric, _("Symmetric"));
2300 fadeshape->add (FadeSlow, _("Slow"));
2301 fadeshape->add (FadeFast, _("Fast"));
2303 add_option (_("Editor"), fadeshape);
2306 bco = new BoolComboOption (
2307 "use-overlap-equivalency",
2308 _("Regions in active edit groups are edited together"),
2309 _("whenever they overlap in time"),
2310 _("only if they have identical length, position and origin"),
2311 sigc::mem_fun (*_rc_config, &RCConfiguration::get_use_overlap_equivalency),
2312 sigc::mem_fun (*_rc_config, &RCConfiguration::set_use_overlap_equivalency)
2315 add_option (_("Editor"), bco);
2317 ComboOption<LayerModel>* lm = new ComboOption<LayerModel> (
2319 _("Layering model"),
2320 sigc::mem_fun (*_rc_config, &RCConfiguration::get_layer_model),
2321 sigc::mem_fun (*_rc_config, &RCConfiguration::set_layer_model)
2324 lm->add (LaterHigher, _("later is higher"));
2325 lm->add (Manual, _("manual layering"));
2326 add_option (_("Editor"), lm);
2328 ComboOption<RegionSelectionAfterSplit> *rsas = new ComboOption<RegionSelectionAfterSplit> (
2329 "region-selection-after-split",
2330 _("After splitting selected regions, select"),
2331 sigc::mem_fun (*_rc_config, &RCConfiguration::get_region_selection_after_split),
2332 sigc::mem_fun (*_rc_config, &RCConfiguration::set_region_selection_after_split));
2334 // TODO: decide which of these modes are really useful
2335 rsas->add(None, _("no regions"));
2336 // rsas->add(NewlyCreatedLeft, _("newly-created regions before the split"));
2337 // rsas->add(NewlyCreatedRight, _("newly-created regions after the split"));
2338 rsas->add(NewlyCreatedBoth, _("newly-created regions"));
2339 // rsas->add(Existing, _("unmodified regions in the existing selection"));
2340 // rsas->add(ExistingNewlyCreatedLeft, _("existing selection and newly-created regions before the split"));
2341 // rsas->add(ExistingNewlyCreatedRight, _("existing selection and newly-created regions after the split"));
2342 rsas->add(ExistingNewlyCreatedBoth, _("existing selection and newly-created regions"));
2344 add_option (_("Editor"), rsas);
2346 add_option (_("Editor/Waveforms"), new OptionEditorHeading (_("Waveforms")));
2348 if (!Profile->get_mixbus()) {
2349 add_option (_("Editor/Waveforms"),
2352 _("Show waveforms in regions"),
2353 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms),
2354 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms)
2358 add_option (_("Editor/Waveforms"),
2360 "show-waveforms-while-recording",
2361 _("Show waveforms for audio while it is being recorded"),
2362 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_waveforms_while_recording),
2363 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_waveforms_while_recording)
2366 ComboOption<WaveformScale>* wfs = new ComboOption<WaveformScale> (
2368 _("Waveform scale"),
2369 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_scale),
2370 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_scale)
2373 wfs->add (Linear, _("linear"));
2374 wfs->add (Logarithmic, _("logarithmic"));
2376 add_option (_("Editor/Waveforms"), wfs);
2378 ComboOption<WaveformShape>* wfsh = new ComboOption<WaveformShape> (
2380 _("Waveform shape"),
2381 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_shape),
2382 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_shape)
2385 wfsh->add (Traditional, _("traditional"));
2386 wfsh->add (Rectified, _("rectified"));
2388 add_option (_("Editor/Waveforms"), wfsh);
2390 add_option (_("Editor/Waveforms"), new ClipLevelOptions ());
2395 add_option (_("Audio"), new OptionEditorHeading (_("Buffering")));
2397 add_option (_("Audio"), new BufferingOptions (_rc_config));
2399 add_option (_("Audio"), new OptionEditorHeading (_("Monitoring")));
2401 ComboOption<MonitorModel>* mm = new ComboOption<MonitorModel> (
2403 _("Record monitoring handled by"),
2404 sigc::mem_fun (*_rc_config, &RCConfiguration::get_monitoring_model),
2405 sigc::mem_fun (*_rc_config, &RCConfiguration::set_monitoring_model)
2408 if (AudioEngine::instance()->port_engine().can_monitor_input()) {
2409 mm->add (HardwareMonitoring, _("via Audio Driver"));
2412 string prog (PROGRAM_NAME);
2413 boost::algorithm::to_lower (prog);
2414 mm->add (SoftwareMonitoring, string_compose (_("%1"), prog));
2415 mm->add (ExternalMonitoring, _("audio hardware"));
2417 add_option (_("Audio"), mm);
2419 add_option (_("Audio"),
2421 "tape-machine-mode",
2422 _("Tape machine mode"),
2423 sigc::mem_fun (*_rc_config, &RCConfiguration::get_tape_machine_mode),
2424 sigc::mem_fun (*_rc_config, &RCConfiguration::set_tape_machine_mode)
2427 add_option (_("Audio"), new OptionEditorHeading (_("Connection of tracks and busses")));
2428 if (!Profile->get_mixbus()) {
2430 add_option (_("Audio"),
2432 "auto-connect-standard-busses",
2433 _("Auto-connect master/monitor busses"),
2434 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_connect_standard_busses),
2435 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_connect_standard_busses)
2438 ComboOption<AutoConnectOption>* iac = new ComboOption<AutoConnectOption> (
2439 "input-auto-connect",
2440 _("Connect track inputs"),
2441 sigc::mem_fun (*_rc_config, &RCConfiguration::get_input_auto_connect),
2442 sigc::mem_fun (*_rc_config, &RCConfiguration::set_input_auto_connect)
2445 iac->add (AutoConnectPhysical, _("automatically to physical inputs"));
2446 iac->add (ManualConnect, _("manually"));
2448 add_option (_("Audio"), iac);
2450 ComboOption<AutoConnectOption>* oac = new ComboOption<AutoConnectOption> (
2451 "output-auto-connect",
2452 _("Connect track and bus outputs"),
2453 sigc::mem_fun (*_rc_config, &RCConfiguration::get_output_auto_connect),
2454 sigc::mem_fun (*_rc_config, &RCConfiguration::set_output_auto_connect)
2457 oac->add (AutoConnectPhysical, _("automatically to physical outputs"));
2458 oac->add (AutoConnectMaster, _("automatically to master bus"));
2459 oac->add (ManualConnect, _("manually"));
2461 add_option (_("Audio"), oac);
2463 bo = new BoolOption (
2465 _("Use 'Strict-I/O' for new tracks or Busses"),
2466 sigc::mem_fun (*_rc_config, &RCConfiguration::get_strict_io),
2467 sigc::mem_fun (*_rc_config, &RCConfiguration::set_strict_io)
2470 add_option (_("Audio"), bo);
2471 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2472 _("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."));
2476 add_option (_("Audio"), new OptionEditorHeading (_("Denormals")));
2478 add_option (_("Audio"),
2480 "denormal-protection",
2481 _("Use DC bias to protect against denormals"),
2482 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_protection),
2483 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_protection)
2486 ComboOption<DenormalModel>* dm = new ComboOption<DenormalModel> (
2488 _("Processor handling"),
2489 sigc::mem_fun (*_rc_config, &RCConfiguration::get_denormal_model),
2490 sigc::mem_fun (*_rc_config, &RCConfiguration::set_denormal_model)
2494 dm->add (DenormalNone, _("no processor handling"));
2496 FPU* fpu = FPU::instance();
2498 if (fpu->has_flush_to_zero()) {
2500 dm->add (DenormalFTZ, _("use FlushToZero"));
2501 } else if (_rc_config->get_denormal_model() == DenormalFTZ) {
2502 _rc_config->set_denormal_model(DenormalNone);
2505 if (fpu->has_denormals_are_zero()) {
2507 dm->add (DenormalDAZ, _("use DenormalsAreZero"));
2508 } else if (_rc_config->get_denormal_model() == DenormalDAZ) {
2509 _rc_config->set_denormal_model(DenormalNone);
2512 if (fpu->has_flush_to_zero() && fpu->has_denormals_are_zero()) {
2514 dm->add (DenormalFTZDAZ, _("use FlushToZero and DenormalsAreZero"));
2515 } else if (_rc_config->get_denormal_model() == DenormalFTZDAZ) {
2516 _rc_config->set_denormal_model(DenormalNone);
2520 dm->set_sensitive(false);
2523 add_option (_("Audio"), dm);
2525 add_option (_("Audio"), new OptionEditorHeading (_("Regions")));
2527 add_option (_("Audio"),
2529 "auto-analyse-audio",
2530 _("Enable automatic analysis of audio"),
2531 sigc::mem_fun (*_rc_config, &RCConfiguration::get_auto_analyse_audio),
2532 sigc::mem_fun (*_rc_config, &RCConfiguration::set_auto_analyse_audio)
2535 add_option (_("Audio"),
2537 "replicate-missing-region-channels",
2538 _("Replicate missing region channels"),
2539 sigc::mem_fun (*_rc_config, &RCConfiguration::get_replicate_missing_region_channels),
2540 sigc::mem_fun (*_rc_config, &RCConfiguration::set_replicate_missing_region_channels)
2545 add_option (_("Solo & mute"), new OptionEditorHeading (_("Solo")));
2547 _solo_control_is_listen_control = new BoolOption (
2548 "solo-control-is-listen-control",
2549 _("Solo controls are Listen controls"),
2550 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_control_is_listen_control),
2551 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_control_is_listen_control)
2554 add_option (_("Solo & mute"), _solo_control_is_listen_control);
2556 add_option (_("Solo & mute"),
2559 _("Exclusive solo"),
2560 sigc::mem_fun (*_rc_config, &RCConfiguration::get_exclusive_solo),
2561 sigc::mem_fun (*_rc_config, &RCConfiguration::set_exclusive_solo)
2564 add_option (_("Solo & mute"),
2567 _("Show solo muting"),
2568 sigc::mem_fun (*_rc_config, &RCConfiguration::get_show_solo_mutes),
2569 sigc::mem_fun (*_rc_config, &RCConfiguration::set_show_solo_mutes)
2572 add_option (_("Solo & mute"),
2574 "solo-mute-override",
2575 _("Soloing overrides muting"),
2576 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_override),
2577 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_override)
2580 add_option (_("Solo & mute"),
2583 _("Solo-in-place mute cut (dB)"),
2584 sigc::mem_fun (*_rc_config, &RCConfiguration::get_solo_mute_gain),
2585 sigc::mem_fun (*_rc_config, &RCConfiguration::set_solo_mute_gain)
2588 _listen_position = new ComboOption<ListenPosition> (
2590 _("Listen Position"),
2591 sigc::mem_fun (*_rc_config, &RCConfiguration::get_listen_position),
2592 sigc::mem_fun (*_rc_config, &RCConfiguration::set_listen_position)
2595 _listen_position->add (AfterFaderListen, _("after-fader (AFL)"));
2596 _listen_position->add (PreFaderListen, _("pre-fader (PFL)"));
2598 add_option (_("Solo & mute"), _listen_position);
2600 ComboOption<PFLPosition>* pp = new ComboOption<PFLPosition> (
2602 _("PFL signals come from"),
2603 sigc::mem_fun (*_rc_config, &RCConfiguration::get_pfl_position),
2604 sigc::mem_fun (*_rc_config, &RCConfiguration::set_pfl_position)
2607 pp->add (PFLFromBeforeProcessors, _("before pre-fader processors"));
2608 pp->add (PFLFromAfterProcessors, _("pre-fader but after pre-fader processors"));
2610 add_option (_("Solo & mute"), pp);
2612 ComboOption<AFLPosition>* pa = new ComboOption<AFLPosition> (
2614 _("AFL signals come from"),
2615 sigc::mem_fun (*_rc_config, &RCConfiguration::get_afl_position),
2616 sigc::mem_fun (*_rc_config, &RCConfiguration::set_afl_position)
2619 pa->add (AFLFromBeforeProcessors, _("immediately post-fader"));
2620 pa->add (AFLFromAfterProcessors, _("after post-fader processors (before pan)"));
2622 add_option (_("Solo & mute"), pa);
2624 add_option (_("Solo & mute"), new OptionEditorHeading (_("Default track / bus muting options")));
2626 add_option (_("Solo & mute"),
2628 "mute-affects-pre-fader",
2629 _("Mute affects pre-fader sends"),
2630 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_pre_fader),
2631 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_pre_fader)
2634 add_option (_("Solo & mute"),
2636 "mute-affects-post-fader",
2637 _("Mute affects post-fader sends"),
2638 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_post_fader),
2639 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_post_fader)
2642 add_option (_("Solo & mute"),
2644 "mute-affects-control-outs",
2645 _("Mute affects control outputs"),
2646 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_control_outs),
2647 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_control_outs)
2650 add_option (_("Solo & mute"),
2652 "mute-affects-main-outs",
2653 _("Mute affects main outputs"),
2654 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mute_affects_main_outs),
2655 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mute_affects_main_outs)
2659 if (!ARDOUR::Profile->get_mixbus()) {
2660 add_option (_("Solo & mute"), new OptionEditorHeading (_("Send Routing")));
2661 add_option (_("Solo & mute"),
2663 "link-send-and-route-panner",
2664 _("Link panners of Aux and External Sends with main panner by default"),
2665 sigc::mem_fun (*_rc_config, &RCConfiguration::get_link_send_and_route_panner),
2666 sigc::mem_fun (*_rc_config, &RCConfiguration::set_link_send_and_route_panner)
2670 add_option (_("MIDI"), new OptionEditorHeading (_("MIDI Preferences")));
2672 add_option (_("MIDI"),
2673 new SpinOption<float> (
2675 _("MIDI read-ahead time (seconds)"),
2676 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_readahead),
2677 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_readahead),
2682 add_option (_("MIDI"),
2683 new SpinOption<int32_t> (
2684 "initial-program-change",
2685 _("Initial program change"),
2686 sigc::mem_fun (*_rc_config, &RCConfiguration::get_initial_program_change),
2687 sigc::mem_fun (*_rc_config, &RCConfiguration::set_initial_program_change),
2691 add_option (_("MIDI"),
2693 "display-first-midi-bank-as-zero",
2694 _("Display first MIDI bank/program as 0"),
2695 sigc::mem_fun (*_rc_config, &RCConfiguration::get_first_midi_bank_is_zero),
2696 sigc::mem_fun (*_rc_config, &RCConfiguration::set_first_midi_bank_is_zero)
2699 add_option (_("MIDI"),
2701 "never-display-periodic-midi",
2702 _("Never display periodic MIDI messages (MTC, MIDI Clock)"),
2703 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_never_display_periodic_midi),
2704 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_never_display_periodic_midi)
2707 add_option (_("MIDI"),
2710 _("Sound MIDI notes as they are selected in the editor"),
2711 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_sound_midi_notes),
2712 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_sound_midi_notes)
2715 add_option (_("MIDI"),
2718 _("Send MIDI control feedback"),
2719 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_feedback),
2720 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_feedback)
2723 add_option (_("MIDI/Sync"), new OptionEditorHeading (_("MIDI Clock")));
2725 add_option (_("MIDI/Sync"),
2728 _("Send MIDI Clock"),
2729 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_midi_clock),
2730 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_midi_clock)
2733 add_option (_("MIDI/Sync"), new OptionEditorHeading (_("MIDI Time Code (MTC)")));
2735 add_option (_("MIDI/Sync"),
2738 _("Send MIDI Time Code"),
2739 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mtc),
2740 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mtc)
2743 add_option (_("MIDI/Sync"),
2744 new SpinOption<int> (
2745 "mtc-qf-speed-tolerance",
2746 _("Percentage either side of normal transport speed to transmit MTC"),
2747 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mtc_qf_speed_tolerance),
2748 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mtc_qf_speed_tolerance),
2752 add_option (_("MIDI/Sync"), new OptionEditorHeading (_("Midi Machine Control (MMC)")));
2754 add_option (_("MIDI/Sync"),
2757 _("Obey MIDI Machine Control commands"),
2758 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_control),
2759 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_control)
2762 add_option (_("MIDI/Sync"),
2765 _("Send MIDI Machine Control commands"),
2766 sigc::mem_fun (*_rc_config, &RCConfiguration::get_send_mmc),
2767 sigc::mem_fun (*_rc_config, &RCConfiguration::set_send_mmc)
2770 add_option (_("MIDI/Sync"),
2771 new SpinOption<uint8_t> (
2772 "mmc-receive-device-id",
2773 _("Inbound MMC device ID"),
2774 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_receive_device_id),
2775 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_receive_device_id),
2779 add_option (_("MIDI/Sync"),
2780 new SpinOption<uint8_t> (
2781 "mmc-send-device-id",
2782 _("Outbound MMC device ID"),
2783 sigc::mem_fun (*_rc_config, &RCConfiguration::get_mmc_send_device_id),
2784 sigc::mem_fun (*_rc_config, &RCConfiguration::set_mmc_send_device_id),
2788 add_option (_("MIDI"), new OptionEditorHeading (_("Midi Audition")));
2790 ComboOption<std::string>* audition_synth = new ComboOption<std::string> (
2791 "midi-audition-synth-uri",
2792 _("Midi Audition Synth (LV2)"),
2793 sigc::mem_fun (*_rc_config, &RCConfiguration::get_midi_audition_synth_uri),
2794 sigc::mem_fun (*_rc_config, &RCConfiguration::set_midi_audition_synth_uri)
2797 audition_synth->add(X_(""), _("None"));
2798 PluginInfoList all_plugs;
2799 PluginManager& manager (PluginManager::instance());
2801 all_plugs.insert (all_plugs.end(), manager.lv2_plugin_info().begin(), manager.lv2_plugin_info().end());
2803 for (PluginInfoList::const_iterator i = all_plugs.begin(); i != all_plugs.end(); ++i) {
2804 if (manager.get_status (*i) == PluginManager::Hidden) continue;
2805 if (!(*i)->is_instrument()) continue;
2806 if ((*i)->type != ARDOUR::LV2) continue;
2807 audition_synth->add((*i)->unique_id, (*i)->name);
2811 add_option (_("MIDI"), audition_synth);
2813 /* USER INTERACTION */
2816 #ifdef PLATFORM_WINDOWS
2819 getenv ("ARDOUR_BUNDLED")
2823 add_option (_("User interaction"),
2825 "enable-translation",
2826 string_compose (_("Use translations of %1 messages\n"
2827 " <i>(requires a restart of %1 to take effect)</i>\n"
2828 " <i>(if available for your language preferences)</i>"), PROGRAM_NAME),
2829 sigc::ptr_fun (ARDOUR::translations_are_enabled),
2830 sigc::ptr_fun (ARDOUR::set_translations_enabled)));
2833 add_option (_("User interaction"), new OptionEditorHeading (_("Keyboard")));
2835 add_option (_("User interaction"), new KeyboardOptions);
2837 /* Control Surfaces */
2839 add_option (_("Control Surfaces"), new ControlSurfacesOptions);
2841 /* VIDEO Timeline */
2842 add_option (_("Video"), new VideoTimelineOptions (_rc_config));
2844 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2845 add_option (_("Plugins"),
2846 new RcActionButton (_("Scan for Plugins"),
2847 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
2851 add_option (_("Plugins"), new OptionEditorHeading (_("General")));
2853 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT)
2854 bo = new BoolOption (
2855 "show-plugin-scan-window",
2856 _("Always Display Plugin Scan Progress"),
2857 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_plugin_scan_window),
2858 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_plugin_scan_window)
2860 add_option (_("Plugins"), bo);
2861 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2862 _("<b>When enabled</b> a popup window showing plugin scan progress is displayed for indexing (cache load) and discovery (detect new plugins)"));
2865 bo = new BoolOption (
2866 "plugins-stop-with-transport",
2867 _("Silence plugins when the transport is stopped"),
2868 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugins_stop_with_transport),
2869 sigc::mem_fun (*_rc_config, &RCConfiguration::set_plugins_stop_with_transport)
2871 add_option (_("Plugins"), bo);
2872 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2873 _("<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."));
2875 bo = new BoolOption (
2876 "new-plugins-active",
2877 _("Make new plugins active"),
2878 sigc::mem_fun (*_rc_config, &RCConfiguration::get_new_plugins_active),
2879 sigc::mem_fun (*_rc_config, &RCConfiguration::set_new_plugins_active)
2881 add_option (_("Plugins"), bo);
2882 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2883 _("<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"));
2885 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
2886 add_option (_("Plugins/VST"), new OptionEditorHeading (_("VST")));
2887 add_option (_("Plugins/VST"),
2888 new RcActionButton (_("Scan for Plugins"),
2889 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
2891 bo = new BoolOption (
2892 "discover-vst-on-start",
2893 _("Scan for [new] VST Plugins on Application Start"),
2894 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_vst_on_start),
2895 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_vst_on_start)
2897 add_option (_("Plugins/VST"), bo);
2898 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2899 _("<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"));
2901 #ifdef WINDOWS_VST_SUPPORT
2902 // currently verbose logging is only implemented for Windows VST.
2903 bo = new BoolOption (
2904 "verbose-plugin-scan",
2905 _("Verbose Plugin Scan"),
2906 sigc::mem_fun (*_rc_config, &RCConfiguration::get_verbose_plugin_scan),
2907 sigc::mem_fun (*_rc_config, &RCConfiguration::set_verbose_plugin_scan)
2909 add_option (_("Plugins/VST"), bo);
2910 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2911 _("<b>When enabled</b> additional information for every plugin is added to the Log Window."));
2914 add_option (_("Plugins/VST"), new VstTimeOutSliderOption (_rc_config));
2916 add_option (_("Plugins/VST"),
2917 new RcActionButton (_("Clear"),
2918 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_cache),
2921 add_option (_("Plugins/VST"),
2922 new RcActionButton (_("Clear"),
2923 sigc::mem_fun (*this, &RCOptionEditor::clear_vst_blacklist),
2924 _("VST Blacklist:")));
2927 #ifdef LXVST_SUPPORT
2928 add_option (_("Plugins/VST"),
2929 new RcActionButton (_("Edit"),
2930 sigc::mem_fun (*this, &RCOptionEditor::edit_lxvst_path),
2931 _("Linux VST Path:")));
2933 add_option (_("Plugins/VST"),
2934 new RcConfigDisplay (
2935 "plugin-path-lxvst",
2937 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_lxvst),
2941 #ifdef WINDOWS_VST_SUPPORT
2942 add_option (_("Plugins/VST"),
2943 new RcActionButton (_("Edit"),
2944 sigc::mem_fun (*this, &RCOptionEditor::edit_vst_path),
2945 _("Windows VST Path:")));
2946 add_option (_("Plugins"),
2947 new RcConfigDisplay (
2950 sigc::mem_fun (*_rc_config, &RCConfiguration::get_plugin_path_vst),
2954 #ifdef AUDIOUNIT_SUPPORT
2956 add_option (_("Plugins/Audio Unit"), new OptionEditorHeading (_("Audio Unit")));
2957 add_option (_("Plugins/Audio Unit"),
2958 new RcActionButton (_("Scan for Plugins"),
2959 sigc::mem_fun (*this, &RCOptionEditor::plugin_scan_refresh)));
2961 bo = new BoolOption (
2962 "discover-audio-units",
2963 _("Scan for AudioUnit Plugins on Application Start"),
2964 sigc::mem_fun (*_rc_config, &RCConfiguration::get_discover_audio_units),
2965 sigc::mem_fun (*_rc_config, &RCConfiguration::set_discover_audio_units)
2967 add_option (_("Plugins"), bo);
2968 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
2969 _("<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."));
2971 add_option (_("Plugins/Audio Unit"),
2972 new RcActionButton (_("Clear"),
2973 sigc::mem_fun (*this, &RCOptionEditor::clear_au_cache),
2976 add_option (_("Plugins/Audio Unit"),
2977 new RcActionButton (_("Clear"),
2978 sigc::mem_fun (*this, &RCOptionEditor::clear_au_blacklist),
2979 _("AU Blacklist:")));
2982 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined AUDIOUNIT_SUPPORT || defined HAVE_LV2)
2983 add_option (_("Plugins"), new OptionEditorHeading (_("Plugin GUI")));
2984 add_option (_("Plugins"),
2986 "open-gui-after-adding-plugin",
2987 _("Automatically open the plugin GUI when adding a new plugin"),
2988 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_open_gui_after_adding_plugin),
2989 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_open_gui_after_adding_plugin)
2992 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
2993 add_option (_("Plugins"),
2995 "show-inline-display-by-default",
2996 _("Show Plugin Inline Display on Mixerstrip by default"),
2997 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_inline_display_by_default),
2998 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_inline_display_by_default)
3001 _plugin_prefer_inline = new BoolOption (
3002 "prefer-inline-over-gui",
3003 _("Don't automatically open the plugin GUI when the plugin has an inline display mode"),
3004 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_prefer_inline_over_gui),
3005 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_prefer_inline_over_gui)
3007 add_option (_("Plugins"), _plugin_prefer_inline);
3010 add_option (_("Plugins"), new OptionEditorHeading (_("Instrument")));
3012 bo = new BoolOption (
3013 "ask-replace-instrument",
3014 _("Ask to replace existing instrument plugin"),
3015 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_replace_instrument),
3016 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_replace_instrument)
3018 add_option (_("Plugins"), bo);
3020 bo = new BoolOption (
3021 "ask-setup_instrument",
3022 _("Interactively configure instrument plugins on insert"),
3023 sigc::mem_fun (*_rc_config, &RCConfiguration::get_ask_setup_instrument),
3024 sigc::mem_fun (*_rc_config, &RCConfiguration::set_ask_setup_instrument)
3026 add_option (_("Plugins"), bo);
3027 Gtkmm2ext::UI::instance()->set_tip (bo->tip_widget(),
3028 _("<b>When enabled</b> show a dialog to select instrument channel configuration before adding a multichannel plugin."));
3034 #ifdef OPTIONAL_CAIRO_IMAGE_SURFACE
3035 BoolOption* bgc = new BoolOption (
3036 "cairo-image-surface",
3037 _("Disable Graphics Hardware Acceleration (requires restart)"),
3038 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_cairo_image_surface),
3039 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_cairo_image_surface)
3042 Gtkmm2ext::UI::instance()->set_tip (bgc->tip_widget(), string_compose (
3043 _("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));
3044 add_option (S_("Preferences|GUI"), bgc);
3047 #ifdef CAIRO_SUPPORTS_FORCE_BUGGY_GRADIENTS_ENVIRONMENT_VARIABLE
3048 BoolOption* bgo = new BoolOption (
3050 _("Possibly improve slow graphical performance (requires restart)"),
3051 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_buggy_gradients),
3052 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_buggy_gradients)
3055 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));
3056 add_option (S_("Preferences|GUI"), bgo);
3059 add_option (S_("Preferences|GUI"),
3061 "use-wm-visibility",
3062 _("Use Window Manager/Desktop visibility information"),
3063 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_wm_visibility),
3064 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_wm_visibility)
3067 add_option (S_("Preferences|GUI"),
3070 _("Graphically indicate mouse pointer hovering over various widgets"),
3071 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_widget_prelight),
3072 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_widget_prelight)
3075 add_option (S_("Preferences|GUI"),
3078 _("Show tooltips if mouse hovers over a control"),
3079 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_use_tooltips),
3080 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_use_tooltips)
3083 add_option (S_("Preferences|GUI"),
3085 "show-name-highlight",
3086 _("Use name highlight bars in region displays (requires a restart)"),
3087 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_name_highlight),
3088 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_name_highlight)
3091 add_option (S_("Preferences|GUI"),
3093 "super-rapid-clock-update",
3094 _("Update transport clock display at FPS instead of every 100ms"),
3095 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_super_rapid_clock_update),
3096 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_super_rapid_clock_update)
3101 /* font scaling does nothing with GDK/Quartz */
3102 add_option (S_("Preferences|GUI"), new FontScalingOptions ());
3105 /* Image cache size */
3107 Gtk::Adjustment *ics = manage (new Gtk::Adjustment(0, 1, 1024, 10)); /* 1 MB to 1GB in steps of 10MB */
3108 HSliderOption *sics = new HSliderOption("waveform-cache-size",
3109 _("Waveform image cache size (megabytes)"),
3111 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_waveform_cache_size),
3112 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_waveform_cache_size)
3114 sics->scale().set_digits (0);
3115 Gtkmm2ext::UI::instance()->set_tip
3116 (sics->tip_widget(),
3117 _("Increasing the cache size uses more memory to store waveform images, which can improve graphical performance."));
3118 add_option (S_("Preferences|GUI"), sics);
3120 if (!ARDOUR::Profile->get_mixbus()) {
3121 /* Lock GUI timeout */
3123 Gtk::Adjustment *lts = manage (new Gtk::Adjustment(0, 0, 1000, 1, 10));
3124 HSliderOption *slts = new HSliderOption("lock-gui-after-seconds",
3125 _("Lock timeout (seconds)"),
3127 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_lock_gui_after_seconds),
3128 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_lock_gui_after_seconds)
3130 slts->scale().set_digits (0);
3131 Gtkmm2ext::UI::instance()->set_tip
3132 (slts->tip_widget(),
3133 _("Lock GUI after this many idle seconds (zero to never lock)"));
3134 add_option (S_("Preferences|GUI"), slts);
3137 /* The names of these controls must be the same as those given in MixerStrip
3138 for the actual widgets being controlled.
3140 _mixer_strip_visibility.add (0, X_("Input"), _("Input"));
3141 _mixer_strip_visibility.add (0, X_("PhaseInvert"), _("Phase Invert"));
3142 _mixer_strip_visibility.add (0, X_("RecMon"), _("Record & Monitor"));
3143 _mixer_strip_visibility.add (0, X_("SoloIsoLock"), _("Solo Iso / Lock"));
3144 _mixer_strip_visibility.add (0, X_("Output"), _("Output"));
3145 _mixer_strip_visibility.add (0, X_("Comments"), _("Comments"));
3146 _mixer_strip_visibility.add (0, X_("VCA"), _("VCA Assigns"));
3149 S_("Preferences|GUI"),
3150 new VisibilityOption (
3152 &_mixer_strip_visibility,
3153 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_mixer_strip_visibility),
3154 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_mixer_strip_visibility)
3158 add_option (S_("Preferences|GUI"),
3160 "default-narrow_ms",
3161 _("Use narrow strips in the mixer by default"),
3162 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_default_narrow_ms),
3163 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_default_narrow_ms)
3166 add_option (S_("Preferences|GUI"),
3167 new ColumVisibilityOption (
3168 "action-table-columns", _("Action Script Button Visibility"), 3,
3169 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_action_table_columns),
3170 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_action_table_columns)
3174 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Metering")));
3176 ComboOption<float>* mht = new ComboOption<float> (
3178 _("Peak hold time"),
3179 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_hold),
3180 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_hold)
3183 mht->add (MeterHoldOff, _("off"));
3184 mht->add (MeterHoldShort, _("short"));
3185 mht->add (MeterHoldMedium, _("medium"));
3186 mht->add (MeterHoldLong, _("long"));
3188 add_option (S_("Preferences|Metering"), mht);
3190 ComboOption<float>* mfo = new ComboOption<float> (
3193 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_falloff),
3194 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_falloff)
3197 mfo->add (METER_FALLOFF_OFF, _("off"));
3198 mfo->add (METER_FALLOFF_SLOWEST, _("slowest [6.6dB/sec]"));
3199 mfo->add (METER_FALLOFF_SLOW, _("slow [8.6dB/sec] (BBC PPM, EBU PPM)"));
3200 mfo->add (METER_FALLOFF_SLOWISH, _("moderate [12.0dB/sec] (DIN)"));
3201 mfo->add (METER_FALLOFF_MODERATE, _("medium [13.3dB/sec] (EBU Digi PPM, IRT Digi PPM)"));
3202 mfo->add (METER_FALLOFF_MEDIUM, _("fast [20dB/sec]"));
3203 mfo->add (METER_FALLOFF_FAST, _("very fast [32dB/sec]"));
3205 add_option (S_("Preferences|Metering"), mfo);
3207 ComboOption<MeterLineUp>* mlu = new ComboOption<MeterLineUp> (
3208 "meter-line-up-level",
3209 _("Meter line-up level; 0dBu"),
3210 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_level),
3211 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_level)
3214 mlu->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3215 mlu->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3216 mlu->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3217 mlu->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3219 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."));
3221 add_option (S_("Preferences|Metering"), mlu);
3223 ComboOption<MeterLineUp>* mld = new ComboOption<MeterLineUp> (
3224 "meter-line-up-din",
3225 _("IEC1/DIN Meter line-up level; 0dBu"),
3226 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_line_up_din),
3227 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_line_up_din)
3230 mld->add (MeteringLineUp24, _("-24dBFS (SMPTE US: 4dBu = -20dBFS)"));
3231 mld->add (MeteringLineUp20, _("-20dBFS (SMPTE RP.0155)"));
3232 mld->add (MeteringLineUp18, _("-18dBFS (EBU, BBC)"));
3233 mld->add (MeteringLineUp15, _("-15dBFS (DIN)"));
3235 Gtkmm2ext::UI::instance()->set_tip (mld->tip_widget(), _("Reference level for IEC1/DIN meter."));
3237 add_option (S_("Preferences|Metering"), mld);
3239 ComboOption<VUMeterStandard>* mvu = new ComboOption<VUMeterStandard> (
3240 "meter-vu-standard",
3241 _("VU Meter standard"),
3242 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_vu_standard),
3243 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_vu_standard)
3246 mvu->add (MeteringVUfrench, _("0VU = -2dBu (France)"));
3247 mvu->add (MeteringVUamerican, _("0VU = 0dBu (North America, Australia)"));
3248 mvu->add (MeteringVUstandard, _("0VU = +4dBu (standard)"));
3249 mvu->add (MeteringVUeight, _("0VU = +8dBu"));
3251 add_option (S_("Preferences|Metering"), mvu);
3253 Gtk::Adjustment *mpk = manage (new Gtk::Adjustment(0, -10, 0, .1, .1));
3254 HSliderOption *mpks = new HSliderOption("meter-peak",
3255 _("Peak threshold [dBFS]"),
3257 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_peak),
3258 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_peak)
3262 ComboOption<MeterType>* mtm = new ComboOption<MeterType> (
3263 "meter-type-master",
3264 _("Default Meter Type for Master Bus"),
3265 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_master),
3266 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_master)
3268 mtm->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3269 mtm->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3270 mtm->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3271 mtm->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3272 mtm->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3273 mtm->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3274 mtm->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3275 mtm->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3277 add_option (S_("Preferences|Metering"), mtm);
3280 ComboOption<MeterType>* mtb = new ComboOption<MeterType> (
3282 _("Default Meter Type for Busses"),
3283 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_bus),
3284 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_bus)
3286 mtb->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3287 mtb->add (MeterK20, ArdourMeter::meter_type_string(MeterK20));
3288 mtb->add (MeterK14, ArdourMeter::meter_type_string(MeterK14));
3289 mtb->add (MeterK12, ArdourMeter::meter_type_string(MeterK12));
3290 mtb->add (MeterIEC1DIN, ArdourMeter::meter_type_string(MeterIEC1DIN));
3291 mtb->add (MeterIEC1NOR, ArdourMeter::meter_type_string(MeterIEC1NOR));
3292 mtb->add (MeterIEC2BBC, ArdourMeter::meter_type_string(MeterIEC2BBC));
3293 mtb->add (MeterIEC2EBU, ArdourMeter::meter_type_string(MeterIEC2EBU));
3295 add_option (S_("Preferences|Metering"), mtb);
3297 ComboOption<MeterType>* mtt = new ComboOption<MeterType> (
3299 _("Default Meter Type for Tracks"),
3300 sigc::mem_fun (*_rc_config, &RCConfiguration::get_meter_type_track),
3301 sigc::mem_fun (*_rc_config, &RCConfiguration::set_meter_type_track)
3303 mtt->add (MeterPeak, ArdourMeter::meter_type_string(MeterPeak));
3304 mtt->add (MeterPeak0dB, ArdourMeter::meter_type_string(MeterPeak0dB));
3306 add_option (S_("Preferences|Metering"), mtt);
3309 Gtkmm2ext::UI::instance()->set_tip
3310 (mpks->tip_widget(),
3311 _("Specify the audio signal level in dBFS at and above which the meter-peak indicator will flash red."));
3313 add_option (S_("Preferences|Metering"), mpks);
3315 add_option (S_("Preferences|Metering"),
3318 _("LED meter style"),
3319 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_meter_style_led),
3320 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_meter_style_led)
3323 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Editor Meters")));
3325 add_option (S_("Preferences|Metering"),
3327 "show-track-meters",
3328 _("Show meters on tracks in the editor"),
3329 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_show_track_meters),
3330 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_show_track_meters)
3333 add_option (S_("Preferences|Metering"),
3335 "editor-stereo-only-meters",
3336 _("Show at most stereo meters in the track-header"),
3337 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_editor_stereo_only_meters),
3338 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_editor_stereo_only_meters)
3341 add_option (S_("Preferences|Metering"), new OptionEditorHeading (_("Post Export Analysis")));
3343 add_option (S_("Preferences|Metering"),
3345 "save-export-analysis-image",
3346 _("Save loudness analysis as image file"),
3347 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::get_save_export_analysis_image),
3348 sigc::mem_fun (UIConfiguration::instance(), &UIConfiguration::set_save_export_analysis_image)
3351 /* and now the theme manager */
3353 ThemeManager* tm = manage (new ThemeManager);
3354 add_page (_("Theme"), *tm);
3356 add_option (_("Theme/Colors"), new ColorThemeManager);
3358 //trigger some parameter-changed messages which affect widget-visibility or -sensitivity
3359 parameter_changed ("send-ltc");
3360 parameter_changed ("sync-source");
3361 parameter_changed ("use-monitor-bus");
3362 parameter_changed ("open-gui-after-adding-plugin");
3364 XMLNode* node = ARDOUR_UI::instance()->preferences_settings();
3366 /* gcc4 complains about ambiguity with Gtk::Widget::set_state
3367 (Gtk::StateType) here !!!
3369 Tabbable::set_state (*node, Stateful::loading_state_version);
3374 RCOptionEditor::parameter_changed (string const & p)
3376 OptionEditor::parameter_changed (p);
3378 if (p == "use-monitor-bus") {
3379 bool const s = Config->get_use_monitor_bus ();
3381 /* we can't use this if we don't have a monitor bus */
3382 Config->set_solo_control_is_listen_control (false);
3384 _solo_control_is_listen_control->set_sensitive (s);
3385 _listen_position->set_sensitive (s);
3386 } else if (p == "sync-source") {
3387 _sync_source->set_sensitive (true);
3389 _sync_source->set_sensitive (!_session->config.get_external_sync());
3391 switch(Config->get_sync_source()) {
3394 _sync_genlock->set_sensitive (true);
3395 _sync_framerate->set_sensitive (true);
3396 _sync_source_2997->set_sensitive (true);
3399 _sync_genlock->set_sensitive (false);
3400 _sync_framerate->set_sensitive (false);
3401 _sync_source_2997->set_sensitive (false);
3404 } else if (p == "send-ltc") {
3405 bool const s = Config->get_send_ltc ();
3406 _ltc_send_continuously->set_sensitive (s);
3407 _ltc_volume_slider->set_sensitive (s);
3408 } else if (p == "open-gui-after-adding-plugin" || p == "show-inline-display-by-default") {
3409 #if (defined LV2_SUPPORT && defined LV2_EXTENDED)
3410 _plugin_prefer_inline->set_sensitive (UIConfiguration::instance().get_open_gui_after_adding_plugin() && UIConfiguration::instance().get_show_inline_display_by_default());
3415 void RCOptionEditor::ltc_generator_volume_changed () {
3416 _rc_config->set_ltc_output_volume (pow(10, _ltc_volume_adjustment->get_value() / 20));
3419 void RCOptionEditor::plugin_scan_refresh () {
3420 PluginManager::instance().refresh();
3423 void RCOptionEditor::clear_vst_cache () {
3424 PluginManager::instance().clear_vst_cache();
3427 void RCOptionEditor::clear_vst_blacklist () {
3428 PluginManager::instance().clear_vst_blacklist();
3431 void RCOptionEditor::clear_au_cache () {
3432 PluginManager::instance().clear_au_cache();
3435 void RCOptionEditor::clear_au_blacklist () {
3436 PluginManager::instance().clear_au_blacklist();
3439 void RCOptionEditor::edit_lxvst_path () {
3440 Glib::RefPtr<Gdk::Window> win = get_parent_window ();
3441 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3442 *current_toplevel(), _("Set Linux VST Search Path"),
3443 _rc_config->get_plugin_path_lxvst(),
3444 PluginManager::instance().get_default_lxvst_path()
3446 ResponseType r = (ResponseType) pd->run ();
3448 if (r == RESPONSE_ACCEPT) {
3449 _rc_config->set_plugin_path_lxvst(pd->get_serialized_paths());
3454 void RCOptionEditor::edit_vst_path () {
3455 Gtkmm2ext::PathsDialog *pd = new Gtkmm2ext::PathsDialog (
3456 *current_toplevel(), _("Set Windows VST Search Path"),
3457 _rc_config->get_plugin_path_vst(),
3458 PluginManager::instance().get_default_windows_vst_path()
3460 ResponseType r = (ResponseType) pd->run ();
3462 if (r == RESPONSE_ACCEPT) {
3463 _rc_config->set_plugin_path_vst(pd->get_serialized_paths());
3470 RCOptionEditor::populate_sync_options ()
3472 vector<SyncSource> sync_opts = ARDOUR::get_available_sync_options ();
3474 _sync_source->clear ();
3476 for (vector<SyncSource>::iterator i = sync_opts.begin(); i != sync_opts.end(); ++i) {
3477 _sync_source->add (*i, sync_source_to_string (*i));
3480 if (sync_opts.empty()) {
3481 _sync_source->set_sensitive(false);
3483 if (std::find(sync_opts.begin(), sync_opts.end(), _rc_config->get_sync_source()) == sync_opts.end()) {
3484 _rc_config->set_sync_source(sync_opts.front());
3488 parameter_changed ("sync-source");
3492 RCOptionEditor::use_own_window (bool and_fill_it)
3494 bool new_window = !own_window ();
3496 Gtk::Window* win = Tabbable::use_own_window (and_fill_it);
3498 if (win && new_window) {
3499 win->set_name ("PreferencesWindow");
3500 ARDOUR_UI::instance()->setup_toplevel_window (*win, _("Preferences"), this);
3507 RCOptionEditor::get_state ()
3509 XMLNode* node = new XMLNode (X_("Preferences"));
3510 node->add_child_nocopy (Tabbable::get_state());